[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