Currently, when the ignore_outgoing devarg is 1, the PMD still receives outgoing packets from the kernel but skips over them so that rte_eth_rx_burst() only returns incoming packets.
Since Linux 4.20, the PACKET_IGNORE_OUTGOING socket option prevents the kernel from delivering outgoing packets to an AF_PACKET socket. This change sets this socket option so that the PMD does not need to filter out outgoing packets anymore. However, this socket option does not work for packet sockets which are in a fanout group, so it is only set in the single-queue scenario. When multiple queues are used, the PMD-side filtering serves as a fallback. This flag is supported since Linux 4.20, and DPDK requires at least Linux 5.4, so no feature check has been added. 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 | 14 +++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/af_packet.rst b/doc/guides/nics/af_packet.rst index 45adbbf8b2..6df14c510d 100644 --- a/doc/guides/nics/af_packet.rst +++ b/doc/guides/nics/af_packet.rst @@ -43,6 +43,9 @@ Only one ``fanout_mode`` can be chosen. If left unspecified, the default is to use the ``PACKET_FANOUT_HASH`` behavior 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. + 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 should be carefully considered before modifying some of these options (namely, diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst index 4bbb3333ce..e83cb9854f 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -117,7 +117,8 @@ New Features * **Updated AF_PACKET driver.** Added ``ignore_outgoing`` so ``rte_eth_rx_burst()`` returns only incoming - packets. + packets. The single-queue scenario is accelerated, as the kernel does + the filtering. * **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 b744305e00..44b91502fb 100644 --- a/drivers/net/af_packet/rte_eth_af_packet.c +++ b/drivers/net/af_packet/rte_eth_af_packet.c @@ -1038,6 +1038,18 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, #endif } + if (ignore_outgoing != 0 && nb_queues == 1) { + rc = setsockopt(qsockfd, SOL_PACKET, PACKET_IGNORE_OUTGOING, + &ignore_outgoing, sizeof(ignore_outgoing)); + if (rc == -1) { + PMD_LOG_ERRNO(ERR, + "%s: could not set PACKET_IGNORE_OUTGOING " + "on AF_PACKET socket for %s", + name, pair->value); + goto error; + } + } + rc = setsockopt(qsockfd, SOL_PACKET, PACKET_RX_RING, req, sizeof(*req)); if (rc == -1) { PMD_LOG_ERRNO(ERR, @@ -1056,7 +1068,7 @@ rte_pmd_init_internals(struct rte_vdev_device *dev, rx_queue = &((*internals)->rx_queue[q]); rx_queue->framecount = req->tp_frame_nr; - rx_queue->ignore_outgoing = ignore_outgoing != 0; + rx_queue->ignore_outgoing = ignore_outgoing != 0 && nb_queues > 1; rx_queue->map = mmap(NULL, 2 * req->tp_block_size * req->tp_block_nr, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, -- 2.56.0

