Files
linux-cryptodev-2.6/tools/testing/selftests/drivers/net/hw/rss_input_xfrm.py
Jakub Kicinski c4df070a57 selftests: hw-net: rss-input-xfrm: try to enable the xfrm at the start
The test currently SKIPs if the symmetric RSS xfrm is not enabled
by default. This leads to spurious SKIPs in the Intel CI reporting
results to NIPA.

Testing on CX7:

 # ./drivers/net/hw/rss_input_xfrm.py
  TAP version 13
  1..2
  ok 1 rss_input_xfrm.test_rss_input_xfrm_ipv4 # SKIP Test requires IPv4 connectivity
  # Sym input xfrm already enabled: {'sym-or-xor'}
  ok 2 rss_input_xfrm.test_rss_input_xfrm_ipv6
  # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:1 error:0

 # ethtool -X eth0 xfrm none

 # ./drivers/net/hw/rss_input_xfrm.py
  TAP version 13
  1..2
  ok 1 rss_input_xfrm.test_rss_input_xfrm_ipv4 # SKIP Test requires IPv4 connectivity
  # Sym input xfrm configured: {'sym-or-xor'}
  ok 2 rss_input_xfrm.test_rss_input_xfrm_ipv6
  # Totals: pass:1 fail:0 xfail:0 xpass:0 skip:1 error:0

Link: https://patch.msgid.link/20260104184600.795280-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2026-01-06 16:54:10 -08:00

125 lines
3.8 KiB
Python
Executable File

#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0
import multiprocessing
import socket
from lib.py import ksft_run, ksft_exit, ksft_eq, ksft_ge, cmd, fd_read_timeout
from lib.py import NetDrvEpEnv
from lib.py import EthtoolFamily, NetdevFamily, NlError
from lib.py import KsftSkipEx, KsftFailEx
from lib.py import defer, ksft_pr, rand_port
def traffic(cfg, local_port, remote_port, ipver):
af_inet = socket.AF_INET if ipver == "4" else socket.AF_INET6
sock = socket.socket(af_inet, socket.SOCK_DGRAM)
sock.bind(("", local_port))
sock.connect((cfg.remote_addr_v[ipver], remote_port))
tgt = f"{ipver}:[{cfg.addr_v[ipver]}]:{local_port},sourceport={remote_port}"
cmd("echo a | socat - UDP" + tgt, host=cfg.remote)
fd_read_timeout(sock.fileno(), 5)
return sock.getsockopt(socket.SOL_SOCKET, socket.SO_INCOMING_CPU)
def _rss_input_xfrm_try_enable(cfg):
"""
Check if symmetric input-xfrm is already enabled, if not try to enable it
and register a cleanup.
"""
rss = cfg.ethnl.rss_get({'header': {'dev-name': cfg.ifname}})
orig_xfrm = rss.get('input-xfrm', set())
sym_xfrm = set(filter(lambda x: 'sym' in x, orig_xfrm))
if sym_xfrm:
ksft_pr("Sym input xfrm already enabled:", sym_xfrm)
return sym_xfrm
for xfrm in cfg.ethnl.consts["input-xfrm"].entries:
# Skip non-symmetric transforms
if "sym" not in xfrm:
continue
try_xfrm = {xfrm} | orig_xfrm
try:
cfg.ethnl.rss_set({"header": {"dev-index": cfg.ifindex},
"input-xfrm": try_xfrm})
except NlError:
continue
ksft_pr("Sym input xfrm configured:", try_xfrm)
defer(cfg.ethnl.rss_set,
{"header": {"dev-index": cfg.ifindex},
"input-xfrm": orig_xfrm})
return {xfrm}
return set()
def test_rss_input_xfrm(cfg, ipver):
"""
Test symmetric input_xfrm.
If symmetric RSS hash is configured, send traffic twice, swapping the
src/dst UDP ports, and verify that the same queue is receiving the traffic
in both cases (IPs are constant).
"""
if multiprocessing.cpu_count() < 2:
raise KsftSkipEx("Need at least two CPUs to test symmetric RSS hash")
cfg.require_cmd("socat", local=False, remote=True)
if not hasattr(socket, "SO_INCOMING_CPU"):
raise KsftSkipEx("socket.SO_INCOMING_CPU was added in Python 3.11")
# Check for symmetric xor/or-xor
input_xfrm = _rss_input_xfrm_try_enable(cfg)
if not input_xfrm:
raise KsftSkipEx("Symmetric RSS hash not supported by device")
cpus = set()
successful = 0
for _ in range(100):
try:
port1 = rand_port(socket.SOCK_DGRAM)
port2 = rand_port(socket.SOCK_DGRAM)
cpu1 = traffic(cfg, port1, port2, ipver)
cpu2 = traffic(cfg, port2, port1, ipver)
cpus.update([cpu1, cpu2])
ksft_eq(
cpu1, cpu2, comment=f"Received traffic on different cpus with ports ({port1 = }, {port2 = }) while symmetric hash is configured")
successful += 1
if successful == 10:
break
except:
continue
else:
raise KsftFailEx("Failed to run traffic")
ksft_ge(len(cpus), 2,
comment=f"Received traffic on less than two cpus {cpus = }")
def test_rss_input_xfrm_ipv4(cfg):
cfg.require_ipver("4")
test_rss_input_xfrm(cfg, "4")
def test_rss_input_xfrm_ipv6(cfg):
cfg.require_ipver("6")
test_rss_input_xfrm(cfg, "6")
def main() -> None:
with NetDrvEpEnv(__file__, nsim_test=False) as cfg:
cfg.ethnl = EthtoolFamily()
cfg.netdevnl = NetdevFamily()
ksft_run([test_rss_input_xfrm_ipv4, test_rss_input_xfrm_ipv6],
args=(cfg, ))
ksft_exit()
if __name__ == "__main__":
main()