[PATCH v6 3/4] net/af_packet: use kernel to filter single-queue Rx

Frank Dressler frank at dressler.pro
Thu Oct 15 13:14:33 CEST 2026


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 <frank at dressler.pro>
---
 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



More information about the dev mailing list