mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
Merge branch 'selftests-drv-net-run-xdp-tests-with-both-ip-versions'
Nimrod Oren says: ==================== selftests: drv-net: run XDP tests with both IP versions The driver selftest environment picks a single address family for tests which use the generic address fields. When both IPv4 and IPv6 are available it prefers IPv6, which can leave IPv4 paths untested and hide IPv4-only bugs. This happened recently in the XDP selftest, where an IPv4 checksum bug was missed when IPv6 was also configured. XDP traffic handling has IP-version-specific code paths, and the follow-up discussion concluded that the XDP tests should run against both IP versions [1]. This series changes NetDrvEpEnv from exposing only the initially selected address family to allowing tests to switch the generic address fields between IP versions. xdp.py uses this to run the XDP traffic cases over both IPv4 and IPv6. Test variants whose required IP version is not configured are skipped. [1] https://lore.kernel.org/20260518143138.74839bf9@kernel.org/ ==================== Link: https://patch.msgid.link/20260702062348.2123960-1-noren@nvidia.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
2f1671d452
|
|
@ -159,13 +159,7 @@ class NetDrvEpEnv(NetDrvEnvBase):
|
|||
|
||||
self.remote = Remote(kind, args, src_path)
|
||||
|
||||
self.addr_ipver = "6" if self.addr_v["6"] else "4"
|
||||
self.addr = self.addr_v[self.addr_ipver]
|
||||
self.remote_addr = self.remote_addr_v[self.addr_ipver]
|
||||
|
||||
# Bracketed addresses, some commands need IPv6 to be inside []
|
||||
self.baddr = f"[{self.addr_v['6']}]" if self.addr_v["6"] else self.addr_v["4"]
|
||||
self.remote_baddr = f"[{self.remote_addr_v['6']}]" if self.remote_addr_v["6"] else self.remote_addr_v["4"]
|
||||
self.set_ipver("6" if self.addr_v["6"] else "4")
|
||||
|
||||
self.ifname = self.dev['ifname']
|
||||
self.ifindex = self.dev['ifindex']
|
||||
|
|
@ -252,6 +246,25 @@ class NetDrvEpEnv(NetDrvEnvBase):
|
|||
if not self.addr_v[ipver] or not self.remote_addr_v[ipver]:
|
||||
raise KsftSkipEx(f"Test requires IPv{ipver} connectivity")
|
||||
|
||||
def set_ipver(self, ipver):
|
||||
"""
|
||||
Modify the IP version used by the generic address fields.
|
||||
"""
|
||||
if ipver == getattr(self, "addr_ipver", None):
|
||||
return
|
||||
|
||||
self.require_ipver(ipver)
|
||||
|
||||
self.addr_ipver = ipver
|
||||
self.addr = self.addr_v[ipver]
|
||||
self.remote_addr = self.remote_addr_v[ipver]
|
||||
|
||||
# Bracketed addresses, some commands need IPv6 to be inside []
|
||||
self.baddr = (f"[{self.addr_v['6']}]" if ipver == "6"
|
||||
else self.addr_v["4"])
|
||||
self.remote_baddr = (f"[{self.remote_addr_v['6']}]" if ipver == "6"
|
||||
else self.remote_addr_v["4"])
|
||||
|
||||
def require_nsim(self, nsim_test=True):
|
||||
"""Require or exclude netdevsim for this test"""
|
||||
if nsim_test and self._ns is None:
|
||||
|
|
|
|||
|
|
@ -172,25 +172,45 @@ def _test_pass(cfg, bpf_info, msg_sz):
|
|||
ksft_eq(stats[XDPStats.RX.value], stats[XDPStats.PASS.value], "RX and PASS stats mismatch")
|
||||
|
||||
|
||||
def test_xdp_native_pass_sb(cfg):
|
||||
_ipvers = [
|
||||
KsftNamedVariant("ipv4", "4"),
|
||||
KsftNamedVariant("ipv6", "6"),
|
||||
]
|
||||
|
||||
|
||||
def _set_ipver_defer_restore(cfg, ipver):
|
||||
old_ipver = cfg.addr_ipver
|
||||
cfg.set_ipver(ipver)
|
||||
defer(cfg.set_ipver, old_ipver)
|
||||
|
||||
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_pass_sb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_PASS action for single buffer case.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog", "xdp_native.bpf.o", "xdp", 1500)
|
||||
|
||||
_test_pass(cfg, bpf_info, 256)
|
||||
|
||||
|
||||
def test_xdp_native_pass_mb(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_pass_mb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_PASS action for a multi-buff size.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog_frags", "xdp_native.bpf.o", "xdp.frags", 9000)
|
||||
|
||||
_test_pass(cfg, bpf_info, 8000)
|
||||
|
|
@ -219,25 +239,33 @@ def _test_drop(cfg, bpf_info, msg_sz):
|
|||
ksft_eq(stats[XDPStats.RX.value], stats[XDPStats.DROP.value], "RX and DROP stats mismatch")
|
||||
|
||||
|
||||
def test_xdp_native_drop_sb(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_drop_sb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_DROP action for a signle-buff case.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog", "xdp_native.bpf.o", "xdp", 1500)
|
||||
|
||||
_test_drop(cfg, bpf_info, 256)
|
||||
|
||||
|
||||
def test_xdp_native_drop_mb(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_drop_mb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_DROP action for a multi-buff case.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog_frags", "xdp_native.bpf.o", "xdp.frags", 9000)
|
||||
|
||||
_test_drop(cfg, bpf_info, 8000)
|
||||
|
|
@ -287,13 +315,17 @@ def _test_xdp_native_tx(cfg, bpf_info, payload_lens):
|
|||
ksft_eq(stats[XDPStats.TX.value], expected_pkts, "TX stats mismatch")
|
||||
|
||||
|
||||
def test_xdp_native_tx_sb(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_tx_sb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_TX action for a single-buff case.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog", "xdp_native.bpf.o", "xdp", 1500)
|
||||
|
||||
# Ensure there's enough room for an ETH / IP / UDP header
|
||||
|
|
@ -302,13 +334,17 @@ def test_xdp_native_tx_sb(cfg):
|
|||
_test_xdp_native_tx(cfg, bpf_info, [0, 1500 // 2, 1500 - pkt_hdr_len])
|
||||
|
||||
|
||||
def test_xdp_native_tx_mb(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_tx_mb(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP_TX action for a multi-buff case.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog_frags", "xdp_native.bpf.o",
|
||||
"xdp.frags", 9000)
|
||||
# The first packet ensures we exercise the fragmented code path.
|
||||
|
|
@ -447,13 +483,17 @@ def _test_xdp_native_tail_adjst(cfg, pkt_sz_lst, offset_lst):
|
|||
return {"status": "pass"}
|
||||
|
||||
|
||||
def test_xdp_native_adjst_tail_grow_data(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_adjst_tail_grow_data(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP tail adjustment by growing packet data.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
pkt_sz_lst = [512, 1024, 2048]
|
||||
offset_lst = [1, 16, 32, 64, 128, 256]
|
||||
res = _test_xdp_native_tail_adjst(
|
||||
|
|
@ -465,13 +505,17 @@ def test_xdp_native_adjst_tail_grow_data(cfg):
|
|||
_validate_res(res, offset_lst, pkt_sz_lst)
|
||||
|
||||
|
||||
def test_xdp_native_adjst_tail_shrnk_data(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_adjst_tail_shrnk_data(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP tail adjustment by shrinking packet data.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
pkt_sz_lst = [512, 1024, 2048]
|
||||
offset_lst = [-16, -32, -64, -128, -256]
|
||||
res = _test_xdp_native_tail_adjst(
|
||||
|
|
@ -535,7 +579,7 @@ def _test_xdp_native_head_adjst(cfg, prog, pkt_sz_lst, offset_lst):
|
|||
# after we eat into it. We send large-enough packets, but if HDS
|
||||
# is enabled head will only contain headers. Don't try to eat
|
||||
# more than 28 bytes (UDPv4 + eth hdr left: (14 + 20 + 8) - 14)
|
||||
l2_cut_off = 28 if cfg.addr_ipver == 4 else 48
|
||||
l2_cut_off = 28 if cfg.addr_ipver == "4" else 48
|
||||
if pkt_sz > hds_thresh and offset > l2_cut_off:
|
||||
ksft_pr(
|
||||
f"Failed run: pkt_sz ({pkt_sz}) > HDS threshold ({hds_thresh}) and "
|
||||
|
|
@ -579,18 +623,22 @@ def _test_xdp_native_head_adjst(cfg, prog, pkt_sz_lst, offset_lst):
|
|||
return {"status": "pass"}
|
||||
|
||||
|
||||
def test_xdp_native_adjst_head_grow_data(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_adjst_head_grow_data(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP headroom growth support.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
|
||||
This function sets up the packet size and offset lists, then calls the
|
||||
_test_xdp_native_head_adjst_mb function to perform the actual test. The
|
||||
test is passed if the headroom is successfully extended for given packet
|
||||
sizes and offsets.
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
pkt_sz_lst = [512, 1024, 2048]
|
||||
|
||||
# Negative values result in headroom shrinking, resulting in growing of payload
|
||||
|
|
@ -600,18 +648,22 @@ def test_xdp_native_adjst_head_grow_data(cfg):
|
|||
_validate_res(res, offset_lst, pkt_sz_lst)
|
||||
|
||||
|
||||
def test_xdp_native_adjst_head_shrnk_data(cfg):
|
||||
@ksft_variants(_ipvers)
|
||||
def test_xdp_native_adjst_head_shrnk_data(cfg, ipver):
|
||||
"""
|
||||
Tests the XDP headroom shrinking support.
|
||||
|
||||
Args:
|
||||
cfg: Configuration object containing network settings.
|
||||
ipver: IP version to use ("4" or "6").
|
||||
|
||||
This function sets up the packet size and offset lists, then calls the
|
||||
_test_xdp_native_head_adjst_mb function to perform the actual test. The
|
||||
test is passed if the headroom is successfully shrunk for given packet
|
||||
sizes and offsets.
|
||||
"""
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
pkt_sz_lst = [512, 1024, 2048]
|
||||
|
||||
# Positive values result in headroom growing, resulting in shrinking of payload
|
||||
|
|
@ -621,12 +673,19 @@ def test_xdp_native_adjst_head_shrnk_data(cfg):
|
|||
_validate_res(res, offset_lst, pkt_sz_lst)
|
||||
|
||||
|
||||
@ksft_variants([
|
||||
KsftNamedVariant("pass", XDPAction.PASS),
|
||||
KsftNamedVariant("drop", XDPAction.DROP),
|
||||
KsftNamedVariant("tx", XDPAction.TX),
|
||||
])
|
||||
def test_xdp_native_qstats(cfg, act):
|
||||
def _qstats_variants():
|
||||
actions = [
|
||||
("pass", XDPAction.PASS),
|
||||
("drop", XDPAction.DROP),
|
||||
("tx", XDPAction.TX),
|
||||
]
|
||||
for ipver in ["4", "6"]:
|
||||
for name, act in actions:
|
||||
yield KsftNamedVariant(f"{name}_ipv{ipver}", act, ipver)
|
||||
|
||||
|
||||
@ksft_variants(_qstats_variants())
|
||||
def test_xdp_native_qstats(cfg, act, ipver):
|
||||
"""
|
||||
Send 1000 messages. Expect XDP action specified in @act.
|
||||
Make sure the packets were counted to interface level qstats
|
||||
|
|
@ -634,6 +693,7 @@ def test_xdp_native_qstats(cfg, act):
|
|||
"""
|
||||
|
||||
cfg.require_cmd("socat")
|
||||
_set_ipver_defer_restore(cfg, ipver)
|
||||
|
||||
bpf_info = BPFProgInfo("xdp_prog", "xdp_native.bpf.o", "xdp", 1500)
|
||||
prog_info = _load_xdp_prog(cfg, bpf_info)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user