From: Stephen Hemminger <stephen@networkplumber.org>
To: Frank Dressler <frank@dressler.pro>
Cc: dev@dpdk.org
Subject: Re: [PATCH v6 0/4] net/af_packet: do not return outgoing packets from rte_eth_rx_burst
Date: Thu, 15 Oct 2026 12:28:13 -0700 [thread overview]
Message-ID: <20261015122813.66f6df2c@phoenix.local> (raw)
In-Reply-To: <20261015111434.1470973-1-frank@dressler.pro>
On Thu, 15 Oct 2026 12:14:30 +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 ignore_outgoing test tags the frames it injects so that it can
> distinguish them from stray frames, which would otherwise be counted
> as well and could lead to a wrong result. As the pre-existing
> loopback test could suffer from stray frames as well, the first patch
> changes it to use tagged frames.
>
> The second patch adds filtering of outgoing packets in the PMD
> because that works in all supported kernel versions and for all
> queue counts. The test creates an AF_PACKET vdev and injects frames
> at the fd end of the TAP device and via a second AF_PACKET vdev.
> Frames from the fd end arrive as incoming traffic and frames from
> the second vdev as outgoing traffic, so with ignore_outgoing=1 the
> first vdev should return only the incoming frames. The frames from
> the fd end are required to distinguish a dead device from one which
> dropped the outgoing frames.
>
> The third patch adds PACKET_IGNORE_OUTGOING which moves the
> filtering into the kernel. It is supported since Linux 4.20 but only
> works for single-queue AF_PACKET scenarios. Multi-queue AF_PACKET
> is still filtered in the PMD.
>
> The fourth patch adds PACKET_FANOUT_FLAG_IGNORE_OUTGOING which is
> supported since Linux 6.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. The PMD check is kept, since older kernels accept
> the flag without effect and support cannot be detected.
>
> 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 succeeds 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``).
>
>
> v6:
> - add tags to frames to distinguish injected ones from stray ones
> - update the loopback and ignore_outgoing tests to count only tagged
> frames
> - inject frames as incoming to distinguish a dead port from a
> working one in ignore_outgoing=1
> - bound the receive flush so a continuous stream cannot hang the test
> - quote rte_eth_rx_burst() with double backticks in the docs
> - use Linux 6.2 instead of v6.2 throughout the code and the docs
> - add a paragraph to af_packet.rst on single-queue and multi-queue
> filtering
Still see minor issues in AI reviews that need fix before it gets merged.
Subject: Re: [PATCH v6 0/4] net/af_packet: ignore_outgoing devarg
Series applies cleanly to main and builds at every commit with
-Dwerror=true (driver and dpdk-test).
Kernel side checks out: sockaddr_ll is at
TPACKET_ALIGN(sizeof(struct tpacket2_hdr)) as the kernel lays it out,
PACKET_IGNORE_OUTGOING has no effect once a socket joins a fanout
group (the group prot_hook replaces the per-socket one), and pre-6.2
fanout_add() does not validate unknown flag bits, so setting
PACKET_FANOUT_FLAG_IGNORE_OUTGOING unconditionally is safe and the
PMD-side check remains the correct fallback.
Only minor items below.
Patch 2/4 net/af_packet: filter Rx of outgoing packets in the PMD
-----------------------------------------------------------------
Info: ignore_outgoing is unsigned, log it with %u.
- PMD_LOG(DEBUG, "%s:\tignore outgoing %d", name, ignore_outgoing);
+ PMD_LOG(DEBUG, "%s:\tignore outgoing %u", name, ignore_outgoing);
Info: test_af_packet_ignore_outgoing() defines n_inject for the TAP
side but hardcodes 4 for the af_packet side. Use one constant for
both:
- allocated = alloc_tx_mbufs(bufs, 4);
+ allocated = alloc_tx_mbufs(bufs, n_inject);
Patch 3/4 net/af_packet: use kernel to filter single-queue Rx
-------------------------------------------------------------
Info: commit message states the 4.20 availability twice. Drop the
last paragraph and fold "DPDK requires at least Linux 5.4, so no
feature check is needed" into the second one.
Info: release notes should say what the user gets, not how it is
done. Where filtering happens (and the 6.2 dependency added in 4/4)
is already in doc/guides/nics/af_packet.rst. Suggest leaving the
release note entry as added in 2/4:
Added ``ignore_outgoing`` devarg so ``rte_eth_rx_burst()``
returns only incoming packets.
Info: PACKET_QDISC_BYPASS is guarded with #if defined() and 4/4 adds
a fallback define for PACKET_FANOUT_FLAG_IGNORE_OUTGOING, but
PACKET_IGNORE_OUTGOING is used bare. Fine against any 4.20+ uapi
headers; add a matching #ifndef fallback (value 23) only if you want
it consistent with 4/4.
Reviewed-by: Stephen Hemminger <stephen@networkplumber.org>
prev parent reply other threads:[~2026-10-15 19:28 UTC|newest]
Thread overview: 23+ 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 ` [PATCH v5 0/3] net/af_packet: do not return outgoing packets from rte_eth_rx_burst Stephen Hemminger
2026-10-15 11:55 ` Frank Dressler
2026-10-15 11:14 ` [PATCH v6 0/4] " Frank Dressler
2026-10-15 11:14 ` [PATCH v6 1/4] test/af_packet: ignore stray packets in loopback test Frank Dressler
2026-10-15 11:14 ` [PATCH v6 2/4] net/af_packet: filter Rx of outgoing packets in the PMD Frank Dressler
2026-10-15 11:14 ` [PATCH v6 3/4] net/af_packet: use kernel to filter single-queue Rx Frank Dressler
2026-10-15 11:14 ` [PATCH v6 4/4] net/af_packet: use kernel to filter multi-queue Rx Frank Dressler
2026-10-15 19:28 ` 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=20261015122813.66f6df2c@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