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.
DPDK requires at least Linux 5.4, so no feature check is needed for
this option.

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.

Signed-off-by: Frank Dressler <[email protected]>
---
 doc/guides/nics/af_packet.rst             |  3 +++
 doc/guides/rel_notes/release_26_11.rst    |  4 ++--
 drivers/net/af_packet/rte_eth_af_packet.c | 14 +++++++++++++-
 3 files changed, 18 insertions(+), 3 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 f06d883abb..e1c7318514 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -125,8 +125,8 @@ New Features
 
 * **Updated AF_PACKET driver.**
 
-  Added ``ignore_outgoing`` so ``rte_eth_rx_burst()`` returns only incoming
-  packets.
+  Added ``ignore_outgoing`` devarg so ``rte_eth_rx_burst()``
+  returns only incoming packets.
 
 * **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 bf8016cdd3..859c817842 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

Reply via email to