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 kernel v4.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. The kernel has supported this flag since v4.20, and DPDK requires at least v5.4, so no feature check has been added. Signed-off-by: Frank Dressler <[email protected]> --- doc/guides/rel_notes/release_26_11.rst | 3 ++- drivers/net/af_packet/rte_eth_af_packet.c | 14 +++++++++++++- 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 daf5603a41..0cf7671cbb 100644 --- a/doc/guides/rel_notes/release_26_11.rst +++ b/doc/guides/rel_notes/release_26_11.rst @@ -67,7 +67,8 @@ New Features * **Updated AF_PACKET driver.** Added ``ignore_outgoing`` vdev argument to prevent `rte_eth_rx_burst()` from - returning transmitted packets. + returning transmitted 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 837da9a3af..085bfa9af9 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

