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 Linux 6.2, the kernel filters outgoing packets for a fanout group when PACKET_FANOUT_FLAG_IGNORE_OUTGOING is set. This change opportunistically sets this flag for all kernel versions in multi-queue scenarios. Kernels before Linux 6.2 ignore the flag and have no way to detect support. The PMD filtering is kept as a fallback for kernels that do not support the flag. Signed-off-by: Frank Dressler <[email protected]> --- doc/guides/nics/af_packet.rst | 3 +++ doc/guides/rel_notes/release_26_11.rst | 3 ++- drivers/net/af_packet/rte_eth_af_packet.c | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/af_packet.rst b/doc/guides/nics/af_packet.rst index 6df14c510d..702822a428 100644 --- a/doc/guides/nics/af_packet.rst +++ b/doc/guides/nics/af_packet.rst @@ -45,6 +45,9 @@ of AF_PACKET for frame reception. When ``ignore_outgoing`` is set, ``PACKET_IGNORE_OUTGOING`` is set for single-queue ports, which moves the filtering from the PMD to the kernel. +For multi-queue ports ``PACKET_FANOUT_FLAG_IGNORE_OUTGOING`` is set to +achieve the same but this only works from Linux 6.2. For earlier Linux +versions, the PMD does the filtering for multi-queue ports. Because this implementation is based on PACKET_MMAP, and PACKET_MMAP has its own pre-requisites, it should be noted that the inner workings of PACKET_MMAP diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index e83cb9854f..9740e9fdce 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -118,7 +118,8 @@ New Features Added ``ignore_outgoing`` so ``rte_eth_rx_burst()`` returns only incoming packets. The single-queue scenario is accelerated, as the kernel does - the filtering. + the filtering. Multi-queue ports are also filtered in the kernel since + Linux 6.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 44b91502fb..0d044ab661 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 6.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

