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 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 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.