Thread (16 messages) 16 messages, 3 authors, 11d ago

[PATCH net-next 3/5] selftests: drv-net: check tcp-data-split against an already attached XDP

flat view
COOLING11d

From: Jakub Kicinski <kuba@kernel.org>
Date: 2026-09-28 22:36:52
Also in: bpf, linux-kselftest
Subsystem: kernel selftest framework, networking drivers, the rest · Maintainers: Shuah Khan, Shuah Khan, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds

hds.py only ever tested one direction of the rule: with header-data
split on, installing a single-buffer XDP program must fail. The other
direction was not covered at all, and that is the one which was broken
for a program an upper device pushed down - the device was running XDP
but nothing in the core knew, so enabling tcp-data-split underneath it
succeeded.

xdp_set_hds() covers the direct case, xdp_bond_set_hds() the propagated
one. The latter fails without the preceding fix.

The bond case is disruptive, it takes the device down to enslave it, and
skips on devices bonding will not take as an XDP slave.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 tools/testing/selftests/drivers/net/config |  1 +
 tools/testing/selftests/drivers/net/hds.py | 65 ++++++++++++++++++++++
 2 files changed, 66 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/config b/tools/testing/selftests/drivers/net/config
index 4838adf27fa1..29293e41c3fa 100644
--- a/tools/testing/selftests/drivers/net/config
+++ b/tools/testing/selftests/drivers/net/config
@@ -1,3 +1,4 @@
+CONFIG_BONDING=m
 CONFIG_CONFIGFS_FS=y
 CONFIG_DEBUG_INFO_BTF=y
 CONFIG_DEBUG_INFO_BTF_MODULES=n
diff --git a/tools/testing/selftests/drivers/net/hds.py b/tools/testing/selftests/drivers/net/hds.py
index 606e26d75951..5fe82b98c1fb 100755
--- a/tools/testing/selftests/drivers/net/hds.py
+++ b/tools/testing/selftests/drivers/net/hds.py
@@ -6,6 +6,7 @@ import os
 import random
 from typing import Union
 from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_raises, KsftSkipEx
+from lib.py import ksft_disruptive
 from lib.py import CmdExitFailure, EthtoolFamily, NlError
 from lib.py import NetDrvEnv
 from lib.py import defer, ethtool, ip
@@ -28,6 +29,21 @@ from lib.py import defer, ethtool, ip
     ip("link set dev %s xdp off" % cfg.ifname)
 
 
+def _xdp_attach(cfg, ifname):
+    """Attach a single-buffer XDP program, detach it when the test ends."""
+    prog = cfg.net_lib_dir / "xdp_dummy.bpf.o"
+    ip(f"link set dev {ifname} xdp obj {prog} sec xdp")
+    defer(ip, f"link set dev {ifname} xdp off")
+
+
+def _hds_enable_expect_fail(cfg, netnl):
+    """Enabling HDS must be refused while single-buffer XDP is attached."""
+    with ksft_raises(NlError) as e:
+        netnl.rings_set({'header': {'dev-index': cfg.ifindex},
+                         'tcp-data-split': 'enabled'})
+    ksft_eq(e.exception.nl_msg.error, -errno.EINVAL)
+
+
 def _ioctl_ringparam_modify(cfg, netnl) -> None:
     """
     Helper for performing a hopefully unimportant IOCTL SET.
@@ -240,6 +256,53 @@ from lib.py import defer, ethtool, ip
         _xdp_onoff(cfg)
 
 
+def xdp_set_hds(cfg, netnl) -> None:
+    """
+    Enable single-buffer XDP on the device, then try to enable HDS.
+    The mirror of enabled_set_xdp(): HDS must be refused.
+    """
+    mode = _get_hds_mode(cfg, netnl)
+    _defer_reset_hds(cfg, netnl)
+    if mode == 'enabled':
+        netnl.rings_set({'header': {'dev-index': cfg.ifindex},
+                         'tcp-data-split': 'unknown'})
+
+    _xdp_attach(cfg, cfg.ifname)
+
+    _hds_enable_expect_fail(cfg, netnl)
+
+
+@ksft_disruptive
+def xdp_bond_set_hds(cfg, netnl) -> None:
+    """
+    Like xdp_set_hds(), but the program is installed on a bond and pushed
+    down to the device rather than attached to it directly. The device is
+    running it either way, so HDS must be refused all the same.
+    """
+    mode = _get_hds_mode(cfg, netnl)
+    _defer_reset_hds(cfg, netnl)
+    if mode == 'enabled':
+        netnl.rings_set({'header': {'dev-index': cfg.ifindex},
+                         'tcp-data-split': 'unknown'})
+
+    ip("link add hds-bond type bond mode active-backup")
+    defer(ip, "link del hds-bond")
+
+    # bonding refuses to enslave a device which is up
+    ip(f"link set dev {cfg.ifname} down")
+    defer(ip, f"link set dev {cfg.ifname} up")
+    ip(f"link set dev {cfg.ifname} master hds-bond")
+    defer(ip, f"link set dev {cfg.ifname} nomaster")
+    ip("link set dev hds-bond up")
+
+    try:
+        _xdp_attach(cfg, "hds-bond")
+    except CmdExitFailure:
+        raise KsftSkipEx("device can't be an XDP bond slave")
+
+    _hds_enable_expect_fail(cfg, netnl)
+
+
 def ioctl(cfg, netnl) -> None:
     mode1 = _get_hds_mode(cfg, netnl)
     _ioctl_ringparam_modify(cfg, netnl)
@@ -290,6 +353,8 @@ from lib.py import defer, ethtool, ip
                   set_hds_thresh_gt,
                   set_xdp,
                   enabled_set_xdp,
+                  xdp_set_hds,
+                  xdp_bond_set_hds,
                   ioctl,
                   ioctl_set_xdp,
                   ioctl_enabled_set_xdp],
-- 
2.55.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help