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.
prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox