All of lore.kernel.org
 help / color / mirror / Atom feed
From: Stephen Hemminger <stephen@networkplumber.org>
To: Frank Dressler <frank@dressler.pro>
Cc: dev@dpdk.org
Subject: Re: [PATCH v5 0/3] net/af_packet: do not return outgoing packets from rte_eth_rx_burst
Date: Fri, 9 Oct 2026 13:03:59 -0700	[thread overview]
Message-ID: <20261009130359.0dc2eec4@phoenix.local> (raw)
In-Reply-To: <20261009151015.742011-1-frank@dressler.pro>

On Fri,  9 Oct 2026 16:10:12 +0100
Frank Dressler <frank@dressler.pro> wrote:

> In contrast to other PMDs, the AF_PACKET PMD does not only return
> incoming but also outgoing packets from rte_eth_rx_burst(). This is
> fine for applications similar to tcpdump which usually want to see
> both. But it is not always the desired behavior. For example, the
> AF_PACKET PMD might be used in a testing environment in which no
> regular ethernet PMD works. In such an environment, the AF_PACKET
> PMD must behave like a regular one, i.e. not return sent packets
> from rte_eth_rx_burst(). One could use the AF_XDP PMD for this but
> it has different dependencies than the AF_PACKET PMD because it
> requires the ``bpf()`` syscall, for example, which might not be
> available.
> 
> For this reason, this series adds the ignore_outgoing=<0|1> devarg.
> When set, the PMD ensures that rte_eth_rx_burst() only returns
> incoming traffic. The default is 0 so that existing software works
> as before.
> 
> The first patch does this filtering in the PMD because this works
> in all supported kernel versions and for all queue counts.
> 
> The second patch adds PACKET_IGNORE_OUTGOING which moves the
> filtering into the kernel. It is supported since v4.20 but only
> works for single-queue AF_PACKET scenarios. Multi-queue AF_PACKET
> is still filtered in the PMD.  
> 
> The third patch adds PACKET_FANOUT_FLAG_IGNORE_OUTGOING which is
> supported since kernel v6.2 and moves the filtering into the kernel
> for the multi-queue scenarios. The kernel does not expose a direct
> way to check whether it supports PACKET_FANOUT_FLAG_IGNORE_OUTGOING
> but it also does not return an error when the sockopt is set on
> kernels that do not support it. Because of that the sockopt is set
> opportunistically. For kernels v6.2 the filtering will then happen
> in the kernel and for earlier versions the PMD does the filtering
> for the multi-queue scenario.
> 
> Overall we get the following:
> 
>               | Single Queue | Multi-Queue
>   ------------+--------------+-------------
>   Kernel 5.4+ |  in kernel   | in PMD
>   Kernel 6.2+ |  in kernel   | in kernel
> 
> I tested this on both, kernel 7.2.8 and kernel 5.4.0 with both single
> and multiple queues. My results, strace'ing testpmd 7.2.8, with the
> variants of ignore_outgoing=0|1 and single/multi-queue:
> 
> Kernel 5.4.0:
> 	qpairs=1,ignore_outgoing=0: -
> 	qpairs=1,ignore_outgoing=1: setsockopt(14, SOL_PACKET, 0x17 /* PACKET_??? */, [1], 4) = 0
> 	// 0x17 is PACKET_IGNORE_OUTGOING
> 
> 	qpairs=2,ignore_outgoing=0: setsockopt(14, SOL_PACKET, PACKET_FANOUT, [-1878917532], 4) = 0
> 	// -1878917532 does NOT contain PACKET_FANOUT_FLAG_IGNORE_OUTGOING<<16
> 	qpairs=2,ignore_outgoing=1: setsockopt(14, SOL_PACKET, PACKET_FANOUT, [-805175699], 4) = 0
> 	// -805175699 does contain PACKET_FANOUT_FLAG_IGNORE_OUTGOING<<16
> 
> Kernel 7.2.8:
> 	qpairs=1,ignore_outgoing=0: -
> 	qpairs=1,ignore_outgoing=1: setsockopt(13, SOL_PACKET, PACKET_IGNORE_OUTGOING, [1], 4) = 0
> 
> 	qpairs=2,ignore_outgoing=0: setsockopt(13, SOL_PACKET, PACKET_FANOUT, [-1878978899], 4) = 0
> 	// -1878978899 does NOT contain PACKET_FANOUT_FLAG_IGNORE_OUTGOING<<16
> 	qpairs=2,ignore_outgoing=1: setsockopt(13, SOL_PACKET, PACKET_FANOUT, [-805236964], 4) = 0
> 	// -805236964 does contain PACKET_FANOUT_FLAG_IGNORE_OUTGOING<<16
> 
> They show that the setsockopt succeeeds even on the old kernel that
> does not support PACKET_FANOUT_FLAG_IGNORE_OUTGOING, so setting it
> opportunistically is fine. They also show that the code only tries to
> set PACKET_FANOUT_FLAG_IGNORE_OUTGOING or PACKET_IGNORE_OUTGOING when
> requested by ignore_outgoing=1. And it shows that
> PACKET_IGNORE_OUTGOING is used for single and
> PACKET_FANOUT_FLAG_IGNORE_OUTGOING for multi-queue.
> 
> I have also manually ran testpmd in all modes and both kernels to
> verify that ignore_outgoing works as expected, sending packets and
> checking what testpmd was receiving (``set verbose 1``).

I see one warning from AI review worth fixing.

Series applies to main (1d020e1) and builds at each commit with
-Dwerror=true. Kernel filtering is right in both cases now: single
queue uses per-socket PACKET_IGNORE_OUTGOING (no fanout group), multi
queue sets PACKET_FANOUT_FLAG_IGNORE_OUTGOING on the group with the
sll_pkttype check as fallback for pre-6.2 kernels. The v3 fanout
problem is resolved.

The test still cannot tell a working filter from a dead port.


[PATCH v5 1/3] net/af_packet: filter Rx of outgoing packets in the PMD

Warning

1. ignore_outgoing=1 test passes if the port receives nothing.

     if (ignore_outgoing)
             TEST_ASSERT(rx_pkts == 0, ...

   Only outgoing traffic is generated, so a queue that drops
   everything passes. Echo the transmitted frames back through
   tap_fd, as test_af_packet_loopback() does, so they arrive as
   incoming. The kernel only ever transmits on the tap, so for
   ignore_outgoing=1 the count is exact:

     ignore_outgoing=1: rx_pkts == nb_tx      (echoes only)
     ignore_outgoing=0: rx_pkts >= 2 * nb_tx  (sent + echoes)

   After do_tx_burst(), with tap_fd set O_NONBLOCK:

     while (echoed < nb_tx && elapsed < LOOPBACK_TIMEOUT_US) {
             n = read(tap_fd, tap_buf, sizeof(tap_buf));
             if (n > 0) {
                     if (write(tap_fd, tap_buf, n) == n)
                             echoed++;
                     continue;
             }
             rte_delay_us_block(STATS_POLL_INTERVAL_US);
             elapsed += STATS_POLL_INTERVAL_US;
     }

   then poll all Rx queues and check the counts. With qpairs=2
   this also covers the fanout path.

Info

2. Use ``rte_eth_rx_burst()`` (double backticks) in af_packet.rst
   and release_26_11.rst. Single backticks are RST interpreted text,
   not literal; both files use double elsewhere. Also in 2/3, 3/3.


[PATCH v5 3/3] net/af_packet: use kernel to filter multi-queue Rx

Info

3. Commit message says the PMD "does not need to do this anymore",
   but rx_queue->ignore_outgoing stays set for nb_queues > 1, so the
   sll_pkttype check runs per frame on 6.2+ as well. Keeping it is
   correct (the flag cannot be probed, and sll is in the same cache
   line as the tpacket2_hdr). Fix the text, not the code:

     The PMD check is kept, since older kernels accept the flag
     without effect and support cannot be detected.

4. Release note "filtered in the kernel since v6.2" reads as a DPDK
   version. Say "Linux 6.2". The kernel version detail fits better
   in af_packet.rst next to the devarg than in the release notes.

PS: AI review also mentioned pre-existing bug.


A separate, older bug turned up while checking fanout_add() in the kernel. get_fanout_mode() always ORs in PACKET_FANOUT_FLAG_ROLLOVER, and the kernel returns -EINVAL for PACKET_FANOUT_ROLLOVER combined with that flag. So fanout_mode=rollover with qpairs > 1 always fails setsockopt. It’s not part of this series, but it deserves its own Fixes patch.

      parent reply	other threads:[~2026-10-09 20:04 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-04  4:22 [PATCH] net/af_packet: add capture direction option Frank Dressler
2026-10-04 16:10 ` Stephen Hemminger
2026-10-05  0:26   ` Frank Dressler
2026-10-05  0:28 ` [PATCH v2] net/af_packet: add option to ignore outgoing packets Frank Dressler
2026-10-05 16:41   ` Stephen Hemminger
2026-10-06  6:42   ` [PATCH v3] " Frank Dressler
2026-10-06 13:41     ` Stephen Hemminger
2026-10-09 15:02   ` [PATCH v4 0/3] net/af_packet: do not return outgoing packets from rte_eth_rx_burst Frank Dressler
2026-10-09 15:02     ` [PATCH v4 1/3] net/af_packet: filter Rx of outgoing packets in the PMD Frank Dressler
2026-10-09 15:02     ` [PATCH v4 2/3] net/af_packet: use kernel to filter single-queue Rx Frank Dressler
2026-10-09 15:02     ` [PATCH v4 3/3] net/af_packet: use kernel to filter multi-queue Rx Frank Dressler
2026-10-09 15:10   ` [PATCH v5 0/3] net/af_packet: do not return outgoing packets from rte_eth_rx_burst Frank Dressler
2026-10-09 15:10     ` [PATCH v5 1/3] net/af_packet: filter Rx of outgoing packets in the PMD Frank Dressler
2026-10-09 15:10     ` [PATCH v5 2/3] net/af_packet: use kernel to filter single-queue Rx Frank Dressler
2026-10-09 15:10     ` [PATCH v5 3/3] net/af_packet: use kernel to filter multi-queue Rx Frank Dressler
2026-10-09 20:03     ` Stephen Hemminger [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261009130359.0dc2eec4@phoenix.local \
    --to=stephen@networkplumber.org \
    --cc=dev@dpdk.org \
    --cc=frank@dressler.pro \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.