From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
andrew+netdev@lunn.ch, horms@kernel.org, jv@jvosburgh.net,
hawk@kernel.org, sdf@fomichev.me, emil@etsalapatis.com,
liuhangbin@gmail.com, bpf@vger.kernel.org,
linux-kselftest@vger.kernel.org, willemdebruijn.kernel@gmail.com,
aleksander.lobakin@intel.com, Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 3/5] selftests: drv-net: check tcp-data-split against an already attached XDP
Date: Mon, 28 Sep 2026 15:36:46 -0700 [thread overview]
Message-ID: <20260928223648.2739371-4-kuba@kernel.org> (raw)
In-Reply-To: <20260928223648.2739371-1-kuba@kernel.org>
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
next prev parent reply other threads:[~2026-09-28 22:36 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 22:36 [PATCH net-next 0/5] net: fix a couple of problems with XDP and bonding Jakub Kicinski
2026-09-28 22:36 ` [PATCH net-next 1/5] net: record XDP programs propagated to lower devices Jakub Kicinski
2026-09-29 23:32 ` Stanislav Fomichev
2026-09-30 4:38 ` netdev-bot+sashiko
2026-09-28 22:36 ` [PATCH net-next 2/5] netdevsim: add ndo_xdp_xmit Jakub Kicinski
2026-09-29 23:32 ` Stanislav Fomichev
2026-09-30 4:38 ` netdev-bot+sashiko
2026-09-28 22:36 ` Jakub Kicinski [this message]
2026-09-29 23:32 ` [PATCH net-next 3/5] selftests: drv-net: check tcp-data-split against an already attached XDP Stanislav Fomichev
2026-09-30 4:38 ` netdev-bot+sashiko
2026-09-28 22:36 ` [PATCH net-next 4/5] selftests/bpf: check XDP attach on a nested bond slave Jakub Kicinski
2026-09-29 23:32 ` Stanislav Fomichev
2026-09-30 4:38 ` netdev-bot+sashiko
2026-09-28 22:36 ` [PATCH net-next 5/5] net: drop GSO skbs instead of handing them to XDP Jakub Kicinski
2026-09-29 23:33 ` Stanislav Fomichev
2026-09-30 4:38 ` netdev-bot+sashiko
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=20260928223648.2739371-4-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=aleksander.lobakin@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=bpf@vger.kernel.org \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=emil@etsalapatis.com \
--cc=hawk@kernel.org \
--cc=horms@kernel.org \
--cc=jv@jvosburgh.net \
--cc=linux-kselftest@vger.kernel.org \
--cc=liuhangbin@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=sdf@fomichev.me \
--cc=willemdebruijn.kernel@gmail.com \
/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