[PATCH v4 2/3] net/af_packet: use kernel to filter single-queue Rx
Frank Dressler
frank at dressler.pro
Fri Oct 9 17:02:39 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 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 <frank at dressler.pro>
Co-authored-by: Cursor <cursoragent at cursor.com>
---
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
More information about the dev
mailing list