Netdev List
 help / color / mirror / Atom feed
* [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP
@ 2026-11-03 20:00 Tianyi Gao
  2026-11-03 20:00 ` [PATCH net 1/2] " Tianyi Gao
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Tianyi Gao @ 2026-11-03 20:00 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Andrew Lunn, Shuah Khan, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Lorenzo Bianconi, Toke Hoiland-Jorgensen,
	linux-kselftest, bpf, kernel-team, Tianyi Gao

Generic XDP copies the skb before it runs a program with frags support.
The copy happens when the skb is cloned, nonlinear, or has less than 256
bytes of headroom. skb_pp_cow_data() makes the copy, but it does not
copy mac_len. After XDP, the skb has mac_len 0.

Two places after generic XDP move skb->data by mac_len:
- On XDP_REDIRECT to a cpumap, cpu_map_generic_redirect() pulls mac_len
  bytes, the length of the Ethernet header. Then it queues the skb to
  the target CPU. With mac_len 0, the IP layer on that CPU sees the
  Ethernet header and drops the packet.
- On XDP_PASS, the skb can go on to tc ingress with a BPF program
  attached (tcx, cls_bpf or act_bpf). Before it runs the program, tc
  pushes mac_len bytes, the length of the Ethernet header. With
  mac_len 0, skb->data stays at the IP header. Therefore, the program
  reads the IP header as the Ethernet header.

Patch 1 copies mac_len in skb_pp_cow_data(). Patch 2 adds a test to
drivers/net/ping.py. The test redirects packets to a cpumap in generic
XDP. On netdevsim, the test fails without patch 1.

---
Copying mac_len in __copy_skb_header() would cover every caller. But it
would also change skb_copy(), pskb_copy() and skb_copy_expand().
Commit 6001896f0098 ("bpf: Run generic devmap egress prog on private
skb") hit a similar problem. It copies mac_len right after skb_copy() in
dev_map_generic_redirect() [1]. We followed that approach.

The bug can be reproduced on veth, virtio_net and netdevsim. The fix was
tested on all three. Native XDP is not affected.

[1] https://lore.kernel.org/all/CABFUUZFQXxYVdi_QqhGG8WTTf=F1BqOmroYj50mv0w70Acf5Bw@mail.gmail.com/

Tianyi Gao (2):
  net: fix mac_len of skbs copied by generic XDP
  selftests: drv-net: ping: test generic XDP redirect to cpumap

 net/core/skbuff.c                             |  1 +
 tools/testing/selftests/drivers/net/ping.py   | 27 ++++++++++++++++---
 .../selftests/net/lib/xdp_cpumap.bpf.c        | 19 +++++++++++++
 3 files changed, 44 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/net/lib/xdp_cpumap.bpf.c


base-commit: 647b81ddefc6364290e67bf33c89d54971f8995e
-- 
2.55.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH net 1/2] net: fix mac_len of skbs copied by generic XDP
  2026-11-03 20:00 [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP Tianyi Gao
@ 2026-11-03 20:00 ` Tianyi Gao
  2026-11-03 20:00 ` [PATCH net 2/2] selftests: drv-net: ping: test generic XDP redirect to cpumap Tianyi Gao
  2026-11-03 20:04 ` [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP netdev-bot+sinfo
  2 siblings, 0 replies; 5+ messages in thread
From: Tianyi Gao @ 2026-11-03 20:00 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Andrew Lunn, Shuah Khan, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Lorenzo Bianconi, Toke Hoiland-Jorgensen,
	linux-kselftest, bpf, kernel-team, Tianyi Gao

skb_pp_cow_data() copies the header fields of the old skb with
skb_copy_header(). skb_copy_header() does not copy mac_len.

Generic XDP uses skb_pp_cow_data() for programs with frags support.
After such a program, the skb can have mac_len 0.
cpu_map_generic_redirect() and tc ingress then get the position of the
Ethernet header wrong.

Copy mac_len in skb_pp_cow_data(), as dev_map_generic_redirect() does
after skb_copy().

Fixes: e6d5dbdd20aa ("xdp: add multi-buff support for xdp running in generic mode")
Signed-off-by: Tianyi Gao <tianyi@cloudflare.com>
---
 net/core/skbuff.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 48f676411724..aa0b11204708 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -967,6 +967,7 @@ int skb_pp_cow_data(struct page_pool *pool, struct sk_buff **pskb,
 
 	skb_reserve(nskb, headroom);
 	skb_copy_header(nskb, skb);
+	nskb->mac_len = skb->mac_len;
 	skb_mark_for_recycle(nskb);
 
 	err = skb_copy_bits(skb, 0, nskb->data, size);
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH net 2/2] selftests: drv-net: ping: test generic XDP redirect to cpumap
  2026-11-03 20:00 [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP Tianyi Gao
  2026-11-03 20:00 ` [PATCH net 1/2] " Tianyi Gao
@ 2026-11-03 20:00 ` Tianyi Gao
  2026-11-03 20:04 ` [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP netdev-bot+sinfo
  2 siblings, 0 replies; 5+ messages in thread
From: Tianyi Gao @ 2026-11-03 20:00 UTC (permalink / raw)
  To: netdev
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Andrew Lunn, Shuah Khan, Alexei Starovoitov,
	Daniel Borkmann, Jesper Dangaard Brouer, John Fastabend,
	Stanislav Fomichev, Lorenzo Bianconi, Toke Hoiland-Jorgensen,
	linux-kselftest, bpf, kernel-team, Tianyi Gao

The generic XDP tests in ping.py only cover XDP_PASS. Add a test that
redirects all packets to a cpumap with an xdp.frags program. It runs
the same ping and TCP checks as the other tests.

xdp_cpumap.bpf.c is a new program. It redirects every packet to entry 0
of a cpumap. It is not added to xdp_dummy.bpf.c. test_xdp_offload loads
xdp_dummy.bpf.o in offload mode, which would fail on a cpumap.

The new test extends _set_xdp_generic_mb_on() with two optional
arguments. The first argument, prog, is the XDP program file name, with
default "xdp_dummy.bpf.o". The second argument, on_attach, is a
callback function, with default None. on_attach runs right after the
program is attached. The new test passes "xdp_cpumap.bpf.o" to prog and
a lambda that adds the cpumap entry to on_attach.

Without the previous patch, the new test fails on netdevsim because ping
gets no reply.

Signed-off-by: Tianyi Gao <tianyi@cloudflare.com>
---
 tools/testing/selftests/drivers/net/ping.py   | 27 ++++++++++++++++---
 .../selftests/net/lib/xdp_cpumap.bpf.c        | 19 +++++++++++++
 2 files changed, 43 insertions(+), 3 deletions(-)
 create mode 100644 tools/testing/selftests/net/lib/xdp_cpumap.bpf.c

diff --git a/tools/testing/selftests/drivers/net/ping.py b/tools/testing/selftests/drivers/net/ping.py
index da3623c5e8a9..a0de9a98d906 100755
--- a/tools/testing/selftests/drivers/net/ping.py
+++ b/tools/testing/selftests/drivers/net/ping.py
@@ -7,7 +7,7 @@ from lib.py import ksft_run, ksft_exit
 from lib.py import ksft_eq, KsftSkipEx, KsftFailEx
 from lib.py import EthtoolFamily, NetDrvEpEnv
 from lib.py import bkg, cmd, wait_port_listen, rand_port
-from lib.py import defer, ethtool, ip
+from lib.py import bpf_map_set, defer, ethtool, ip
 
 no_sleep=False
 
@@ -75,16 +75,23 @@ def _set_xdp_generic_sb_on(cfg) -> None:
     if no_sleep != True:
         time.sleep(10)
 
-def _set_xdp_generic_mb_on(cfg) -> None:
-    prog = cfg.net_lib_dir / "xdp_dummy.bpf.o"
+def _set_xdp_generic_mb_on(cfg, prog="xdp_dummy.bpf.o", on_attach=None) -> None:
+    prog = cfg.net_lib_dir / prog
     cmd(f"ip link set dev {cfg.remote_ifname} mtu 9000", shell=True, host=cfg.remote)
     defer(ip, f"link set dev {cfg.remote_ifname} mtu 1500", host=cfg.remote)
     ip("link set dev %s mtu 9000 xdpgeneric obj %s sec xdp.frags" % (cfg.ifname, prog))
     defer(ip, f"link set dev {cfg.ifname} mtu 1500 xdpgeneric off")
+    if on_attach:
+        on_attach()
 
     if no_sleep != True:
         time.sleep(10)
 
+def _set_xdp_generic_cpumap_mb_on(cfg) -> None:
+    cfg.require_cmd("bpftool")
+    _set_xdp_generic_mb_on(cfg, "xdp_cpumap.bpf.o",
+                           on_attach=lambda: bpf_map_set("map_cpumap", 0, 2048))
+
 def _set_xdp_native_sb_on(cfg) -> None:
     prog = cfg.net_lib_dir / "xdp_dummy.bpf.o"
     cmd(f"ip link set dev {cfg.remote_ifname} mtu 1500", shell=True, host=cfg.remote)
@@ -192,6 +199,19 @@ def test_xdp_generic_mb(cfg, netnl) -> None:
     _test_v6(cfg)
     _test_tcp(cfg)
 
+def test_xdp_generic_cpumap_mb(cfg, netnl) -> None:
+    """Redirect all packets to a cpumap from a generic xdp.frags program."""
+    _schedule_checksum_reset(cfg, netnl)
+    _set_xdp_generic_cpumap_mb_on(cfg)
+    _set_offload_checksum(cfg, netnl, "off")
+    _test_v4(cfg)
+    _test_v6(cfg)
+    _test_tcp(cfg)
+    _set_offload_checksum(cfg, netnl, "on")
+    _test_v4(cfg)
+    _test_v6(cfg)
+    _test_tcp(cfg)
+
 def test_xdp_native_sb(cfg, netnl) -> None:
     _schedule_checksum_reset(cfg, netnl)
     _set_xdp_native_sb_on(cfg)
@@ -230,6 +250,7 @@ def main() -> None:
                   test_default_v6,
                   test_xdp_generic_sb,
                   test_xdp_generic_mb,
+                  test_xdp_generic_cpumap_mb,
                   test_xdp_native_sb,
                   test_xdp_native_mb,
                   test_xdp_offload],
diff --git a/tools/testing/selftests/net/lib/xdp_cpumap.bpf.c b/tools/testing/selftests/net/lib/xdp_cpumap.bpf.c
new file mode 100644
index 000000000000..150352343114
--- /dev/null
+++ b/tools/testing/selftests/net/lib/xdp_cpumap.bpf.c
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+
+struct {
+	__uint(type, BPF_MAP_TYPE_CPUMAP);
+	__uint(max_entries, 1);
+	__type(key, __u32);
+	__type(value, __u32);
+} map_cpumap SEC(".maps");
+
+SEC("xdp.frags")
+int xdp_cpumap_prog_frags(struct xdp_md *ctx)
+{
+	return bpf_redirect_map(&map_cpumap, 0, XDP_DROP);
+}
+
+char _license[] SEC("license") = "GPL";
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP
  2026-11-03 20:00 [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP Tianyi Gao
  2026-11-03 20:00 ` [PATCH net 1/2] " Tianyi Gao
  2026-11-03 20:00 ` [PATCH net 2/2] selftests: drv-net: ping: test generic XDP redirect to cpumap Tianyi Gao
@ 2026-11-03 20:04 ` netdev-bot+sinfo
  2026-11-03 20:53   ` Tianyi Gao
  2 siblings, 1 reply; 5+ messages in thread
From: netdev-bot+sinfo @ 2026-11-03 20:04 UTC (permalink / raw)
  To: Tianyi Gao
  Cc: netdev, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Andrew Lunn, Shuah Khan,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Lorenzo Bianconi,
	Toke Hoiland-Jorgensen, linux-kselftest, bpf, kernel-team

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP
  2026-11-03 20:04 ` [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP netdev-bot+sinfo
@ 2026-11-03 20:53   ` Tianyi Gao
  0 siblings, 0 replies; 5+ messages in thread
From: Tianyi Gao @ 2026-11-03 20:53 UTC (permalink / raw)
  To: netdev-bot+sinfo
  Cc: netdev, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, Andrew Lunn, Shuah Khan,
	Alexei Starovoitov, Daniel Borkmann, Jesper Dangaard Brouer,
	John Fastabend, Stanislav Fomichev, Lorenzo Bianconi,
	Toke Hoiland-Jorgensen, linux-kselftest, bpf, kernel-team

Hi,

I hit this while benchmarking generic XDP with an xdp.frags program
that redirects to a cpumap. TCP throughput dropped to almost zero.

Cheers,
Tianyi

On Tue, Nov 3, 2026 at 8:04 PM <netdev-bot+sinfo@kernel.org> wrote:
>
> Hi!
>
> This is an automated message. This series looks like a fix, but its
> commit messages seem to be missing some information:
>
>  - How the issue was discovered, e.g. hit in production, hit during
>    development, syzbot report, manual code inspection, LLM or static
>    analysis tool scan.
>
> Please do not repost the series just to address the above. Instead,
> reply to this email with the missing information, so that reviewers
> can take it into account. If the series needs another revision for
> other reasons, please include the information in the commit messages
> then.
>
> The evaluation is done by an LLM so it may be wrong, if you think
> that is the case please reply and explain.



-- 
Cheers,
Tianyi

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-11-03 20:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03 20:00 [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP Tianyi Gao
2026-11-03 20:00 ` [PATCH net 1/2] " Tianyi Gao
2026-11-03 20:00 ` [PATCH net 2/2] selftests: drv-net: ping: test generic XDP redirect to cpumap Tianyi Gao
2026-11-03 20:04 ` [PATCH net 0/2] net: fix mac_len of skbs copied by generic XDP netdev-bot+sinfo
2026-11-03 20:53   ` Tianyi Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox