DPDK-dev Archive on 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 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>

      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