The AF_PACKET PMD currently needs to filter out outgoing packets in
the PMD when the ignore_outgoing devarg is enabled and multiple queues
are used. Kernel-side filtering is only supported for the single-queue
scenario.

Since v6.2 the Linux kernel supports filtering outgoing packets for
AF_PACKET socket fanout groups via PACKET_FANOUT_FLAG_IGNORE_OUTGOING
which means that the PMD does not need to do this anymore.

Earlier kernels ignore this flag and have no direct way to detect
whether the flag is supported.

This change opportunistically sets this flag for all kernel versions
in multi-queue scenarios. Kernels that do not support this flag
silently ignore it. Filtering outgoing packets then falls back to the
PMD-based approach.

With this change, for all kernels v6.2 or newer, all the filtering of
outgoing packets will happen in the kernel.

Signed-off-by: Frank Dressler <[email protected]>
---
 doc/guides/rel_notes/release_26_11.rst    |  4 ++--
 drivers/net/af_packet/rte_eth_af_packet.c | 13 +++++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/doc/guides/rel_notes/release_26_11.rst 
b/doc/guides/rel_notes/release_26_11.rst
index 0cf7671cbb..c4ef38b362 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -67,8 +67,8 @@ New Features
 * **Updated AF_PACKET driver.**
 
   Added ``ignore_outgoing`` vdev argument to prevent `rte_eth_rx_burst()` from
-  returning transmitted packets. The single-queue scenario is accelerated,
-  as the kernel does the filtering.
+  returning transmitted packets. Single queue is always filtered in the kernel.
+  Multiple queues are filtered in the kernel since v6.2, otherwise in the PMD.
 
 * **Updated AF_XDP driver.**
 
diff --git a/drivers/net/af_packet/rte_eth_af_packet.c 
b/drivers/net/af_packet/rte_eth_af_packet.c
index 085bfa9af9..e3ed511b45 100644
--- a/drivers/net/af_packet/rte_eth_af_packet.c
+++ b/drivers/net/af_packet/rte_eth_af_packet.c
@@ -32,6 +32,11 @@
 #include <unistd.h>
 #include <poll.h>
 
+/* Added in Linux 6.2. Older kernels ignore it. */
+#ifndef PACKET_FANOUT_FLAG_IGNORE_OUTGOING
+#define PACKET_FANOUT_FLAG_IGNORE_OUTGOING 0x4000
+#endif
+
 #define ETH_AF_PACKET_IFACE_ARG                "iface"
 #define ETH_AF_PACKET_NUM_Q_ARG                "qpairs"
 #define ETH_AF_PACKET_BLOCKSIZE_ARG    "blocksz"
@@ -995,6 +1000,14 @@ rte_pmd_init_internals(struct rte_vdev_device *dev,
                goto error;
        }
 
+       /*
+        * Set the flag opportunistically if multiple queues are requested.
+        * It takes effect from Linux v6.2. Older kernels ignore it and the
+        * PMD filters instead.
+        */
+       if (ignore_outgoing != 0 && nb_queues > 1)
+               fanout_arg |= PACKET_FANOUT_FLAG_IGNORE_OUTGOING << 16;
+
        for (q = 0; q < nb_queues; q++) {
                /* Open an AF_PACKET socket for this queue... */
                qsockfd = socket(AF_PACKET, SOCK_RAW, 0);
-- 
2.56.0

Reply via email to