* [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests
@ 2026-04-07 2:45 Xu Du
2026-04-07 2:45 ` [RFC net-next 1/4] selftests: drv-net: tso: retry connect on EHOSTUNREACH Xu Du
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Xu Du @ 2026-04-07 2:45 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, shuah
Cc: netdev, linux-kselftest, linux-kernel
This series extends the TSO selftest (tso.py) to cover double-encapsulated
tunnel scenarios, ensuring that hardware offload and the kernel GSO path
correctly handle packets with two layers of tunnel headers.
Xu Du (4):
selftests: drv-net: tso: retry connect on EHOSTUNREACH
selftests: drv-net: tso: add helpers for double tunneling GSO
selftests: drv-net: tso: add Geneve double tunneling GSO test
selftests: drv-net: tso: expand double tunnel GSO test coverage
.../drivers/net/hw/lib/py/__init__.py | 4 +-
tools/testing/selftests/drivers/net/hw/tso.py | 267 +++++++++++++++---
.../selftests/drivers/net/lib/py/__init__.py | 4 +-
.../testing/selftests/net/lib/py/__init__.py | 4 +-
tools/testing/selftests/net/lib/py/utils.py | 19 +-
5 files changed, 248 insertions(+), 50 deletions(-)
base-commit: 2f60df9e61aa48bf40c36254bf2e839f09cffd98
--
2.53.0
^ permalink raw reply [flat|nested] 5+ messages in thread
* [RFC net-next 1/4] selftests: drv-net: tso: retry connect on EHOSTUNREACH
2026-04-07 2:45 [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests Xu Du
@ 2026-04-07 2:45 ` Xu Du
2026-04-07 2:45 ` [RFC net-next 2/4] selftests: drv-net: tso: add helpers for double tunneling GSO Xu Du
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Xu Du @ 2026-04-07 2:45 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, shuah
Cc: netdev, linux-kselftest, linux-kernel
The TSO test occasionally fails with "No route to host" (EHOSTUNREACH)
when connecting to the remote socat listener. This can happen when the
neighbor resolution has not yet completed by the time the test attempts
to connect, particularly in tunnel setups where neighbor entries may
take slightly longer to establish.
Add a retry loop (up to 5 attempts with 0.5s delay) around the
sock.connect() call to handle this transient condition gracefully.
Signed-off-by: Xu Du <xudu@redhat.com>
---
tools/testing/selftests/drivers/net/hw/tso.py | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/tso.py b/tools/testing/selftests/drivers/net/hw/tso.py
index bb675e3dac88..f792115adfb3 100755
--- a/tools/testing/selftests/drivers/net/hw/tso.py
+++ b/tools/testing/selftests/drivers/net/hw/tso.py
@@ -3,6 +3,7 @@
"""Run the tools/testing/selftests/net/csum testsuite."""
+import errno
import fcntl
import socket
import struct
@@ -47,10 +48,20 @@ def run_one_stream(cfg, ipver, remote_v4, remote_v6, should_lso):
if ipver == "4":
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.connect((remote_v4, port))
+ sockaddr = (remote_v4, port)
else:
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
- sock.connect((remote_v6, port))
+ sockaddr = (remote_v6, port)
+
+ for attempt in range(5):
+ try:
+ sock.connect(sockaddr)
+ break
+ except OSError as e:
+ if e.errno == errno.EHOSTUNREACH and attempt < 4:
+ time.sleep(0.5)
+ else:
+ raise
# Small send to make sure the connection is working.
sock.send("ping".encode())
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC net-next 2/4] selftests: drv-net: tso: add helpers for double tunneling GSO
2026-04-07 2:45 [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests Xu Du
2026-04-07 2:45 ` [RFC net-next 1/4] selftests: drv-net: tso: retry connect on EHOSTUNREACH Xu Du
@ 2026-04-07 2:45 ` Xu Du
2026-04-07 2:45 ` [RFC net-next 3/4] selftests: drv-net: tso: add Geneve double tunneling GSO test Xu Du
2026-04-07 2:45 ` [RFC net-next 4/4] selftests: drv-net: tso: expand double tunnel GSO test coverage Xu Du
3 siblings, 0 replies; 5+ messages in thread
From: Xu Du @ 2026-04-07 2:45 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, shuah
Cc: netdev, linux-kselftest, linux-kernel
Add helper functions to support double tunneling GSO testing. Since certain
tunnel-specific parameters (e.g., gro-hint) are not yet supported by the
standard ip-link tool, this patch adds a new helper function utilizing
the ynl-cli to handle these extended netlink attributes.
As the YNL Python module cannot be invoked across different devices or
environments directly in its current form, the helper abstracts the
YNL CLI calls to ensure proper configuration of the tunneling device
features.
Signed-off-by: Xu Du <xudu@redhat.com>
---
.../drivers/net/hw/lib/py/__init__.py | 4 ++--
.../selftests/drivers/net/lib/py/__init__.py | 4 ++--
.../testing/selftests/net/lib/py/__init__.py | 4 ++--
tools/testing/selftests/net/lib/py/utils.py | 19 +++++++++++++++++--
4 files changed, 23 insertions(+), 8 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py b/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
index df4da5078c48..34a06e1afcb5 100644
--- a/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/hw/lib/py/__init__.py
@@ -24,7 +24,7 @@ try:
from net.lib.py import CmdExitFailure
from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, \
fd_read_timeout, ip, rand_port, rand_ports, wait_port_listen, \
- wait_file, tool
+ wait_file, tool, ynlcli
from net.lib.py import bpf_map_set, bpf_map_dump, bpf_prog_map_ids
from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
from net.lib.py import ksft_disruptive, ksft_exit, ksft_pr, ksft_run, \
@@ -40,7 +40,7 @@ try:
"CmdExitFailure",
"bkg", "cmd", "bpftool", "bpftrace", "defer", "ethtool",
"fd_read_timeout", "ip", "rand_port", "rand_ports",
- "wait_port_listen", "wait_file", "tool",
+ "wait_port_listen", "wait_file", "tool", "ynlcli",
"bpf_map_set", "bpf_map_dump", "bpf_prog_map_ids",
"KsftSkipEx", "KsftFailEx", "KsftXfailEx",
"ksft_disruptive", "ksft_exit", "ksft_pr", "ksft_run",
diff --git a/tools/testing/selftests/drivers/net/lib/py/__init__.py b/tools/testing/selftests/drivers/net/lib/py/__init__.py
index 2b5ec0505672..a9eb1a57fcc4 100644
--- a/tools/testing/selftests/drivers/net/lib/py/__init__.py
+++ b/tools/testing/selftests/drivers/net/lib/py/__init__.py
@@ -22,7 +22,7 @@ try:
from net.lib.py import EthtoolFamily, NetdevFamily, NetshaperFamily, \
NlError, RtnlFamily, DevlinkFamily, PSPFamily, Netlink
from net.lib.py import CmdExitFailure
- from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, \
+ from net.lib.py import bkg, cmd, bpftool, bpftrace, defer, ethtool, ynlcli, \
fd_read_timeout, ip, rand_port, rand_ports, wait_port_listen, wait_file
from net.lib.py import bpf_map_set, bpf_map_dump, bpf_prog_map_ids
from net.lib.py import KsftSkipEx, KsftFailEx, KsftXfailEx
@@ -36,7 +36,7 @@ try:
"NlError", "RtnlFamily", "DevlinkFamily", "PSPFamily", "Netlink",
"CmdExitFailure",
"bkg", "cmd", "bpftool", "bpftrace", "defer", "ethtool",
- "fd_read_timeout", "ip", "rand_port", "rand_ports",
+ "fd_read_timeout", "ip", "rand_port", "rand_ports", "ynlcli",
"wait_port_listen", "wait_file",
"bpf_map_set", "bpf_map_dump", "bpf_prog_map_ids",
"KsftSkipEx", "KsftFailEx", "KsftXfailEx",
diff --git a/tools/testing/selftests/net/lib/py/__init__.py b/tools/testing/selftests/net/lib/py/__init__.py
index 7c81d86a7e97..a3337666a856 100644
--- a/tools/testing/selftests/net/lib/py/__init__.py
+++ b/tools/testing/selftests/net/lib/py/__init__.py
@@ -14,7 +14,7 @@ from .netns import NetNS, NetNSEnter
from .nsim import NetdevSim, NetdevSimDev
from .utils import CmdExitFailure, fd_read_timeout, cmd, bkg, defer, \
bpftool, ip, ethtool, bpftrace, rand_port, rand_ports, wait_port_listen, \
- wait_file, tool
+ wait_file, tool, ynlcli
from .bpf import bpf_map_set, bpf_map_dump, bpf_prog_map_ids
from .ynl import NlError, NlctrlFamily, YnlFamily, \
EthtoolFamily, NetdevFamily, RtnlFamily, RtnlAddrFamily
@@ -29,7 +29,7 @@ __all__ = ["KSRC",
"NetNS", "NetNSEnter",
"CmdExitFailure", "fd_read_timeout", "cmd", "bkg", "defer",
"bpftool", "ip", "ethtool", "bpftrace", "rand_port", "rand_ports",
- "wait_port_listen", "wait_file", "tool",
+ "wait_port_listen", "wait_file", "tool", "ynlcli",
"bpf_map_set", "bpf_map_dump", "bpf_prog_map_ids",
"NetdevSim", "NetdevSimDev",
"NetshaperFamily", "DevlinkFamily", "PSPFamily", "NlError",
diff --git a/tools/testing/selftests/net/lib/py/utils.py b/tools/testing/selftests/net/lib/py/utils.py
index 6c44a3d2bbf7..a14a4b5dd592 100644
--- a/tools/testing/selftests/net/lib/py/utils.py
+++ b/tools/testing/selftests/net/lib/py/utils.py
@@ -8,6 +8,8 @@ import socket
import subprocess
import time
+from .consts import KSRC, KSFT_DIR
+
class CmdInitFailure(Exception):
""" Command failed to start. Only raised by bkg(). """
@@ -217,12 +219,12 @@ class defer:
self.exec_only()
-def tool(name, args, json=None, ns=None, host=None):
+def tool(name, args, json=None, ns=None, host=None, shell=None):
cmd_str = name + ' '
if json:
cmd_str += '--json '
cmd_str += args
- cmd_obj = cmd(cmd_str, ns=ns, host=host)
+ cmd_obj = cmd(cmd_str, ns=ns, host=host, shell=shell)
if json:
return _json.loads(cmd_obj.stdout)
return cmd_obj
@@ -242,6 +244,19 @@ def ethtool(args, json=None, ns=None, host=None):
return tool('ethtool', args, json=json, ns=ns, host=host)
+def ynlcli(family, args, json=None, ns=None, host=None):
+ if (KSFT_DIR / "kselftest-list.txt").exists():
+ cli = KSFT_DIR / "net/lib/ynl/pyynl/cli.py"
+ spec = KSFT_DIR / f"net/lib/specs/{family}.yaml"
+ else:
+ cli = KSRC / "tools/net/ynl/pyynl/cli.py"
+ spec = KSRC / f"Documentation/netlink/specs/{family}.yaml"
+ if not cli.exists():
+ raise FileNotFoundError(f"cli not found at {cli}")
+ args = f"--spec {spec} --no-schema {args}"
+ return tool(cli.as_posix(), args, json=json, ns=ns, host=host, shell=True)
+
+
def bpftrace(expr, json=None, ns=None, host=None, timeout=None):
"""
Run bpftrace and return map data (if json=True).
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC net-next 3/4] selftests: drv-net: tso: add Geneve double tunneling GSO test
2026-04-07 2:45 [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests Xu Du
2026-04-07 2:45 ` [RFC net-next 1/4] selftests: drv-net: tso: retry connect on EHOSTUNREACH Xu Du
2026-04-07 2:45 ` [RFC net-next 2/4] selftests: drv-net: tso: add helpers for double tunneling GSO Xu Du
@ 2026-04-07 2:45 ` Xu Du
2026-04-07 2:45 ` [RFC net-next 4/4] selftests: drv-net: tso: expand double tunnel GSO test coverage Xu Du
3 siblings, 0 replies; 5+ messages in thread
From: Xu Du @ 2026-04-07 2:45 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, shuah
Cc: netdev, linux-kselftest, linux-kernel
Add a new test case to verify GSO behavior for double-encapsulated Geneve
tunnels. This ensures that hardware drivers and the network stack correctly
handle nested tunnel headers during segmentation.
To maintain consistency and avoid complexity in hardware parser logic, the
test case ensures that the IP versions for both the inner and outer headers
remain the same.
Signed-off-by: Xu Du <xudu@redhat.com>
---
tools/testing/selftests/drivers/net/hw/tso.py | 228 +++++++++++++++---
1 file changed, 188 insertions(+), 40 deletions(-)
diff --git a/tools/testing/selftests/drivers/net/hw/tso.py b/tools/testing/selftests/drivers/net/hw/tso.py
index f792115adfb3..6b4639ce6139 100755
--- a/tools/testing/selftests/drivers/net/hw/tso.py
+++ b/tools/testing/selftests/drivers/net/hw/tso.py
@@ -5,6 +5,7 @@
import errno
import fcntl
+import json
import socket
import struct
import termios
@@ -13,7 +14,29 @@ import time
from lib.py import ksft_pr, ksft_run, ksft_exit, KsftSkipEx, KsftXfailEx
from lib.py import ksft_eq, ksft_ge, ksft_lt
from lib.py import EthtoolFamily, NetdevFamily, NetDrvEpEnv
-from lib.py import bkg, cmd, defer, ethtool, ip, rand_port, wait_port_listen
+from lib.py import bkg, ynlcli, defer, ethtool, ip, rand_port, wait_port_listen
+
+
+def _convert_ip(key):
+ def _conv(val):
+ final_key = f"{key}6" if ":" in str(val) else key
+ return final_key, val
+
+ return _conv
+
+
+YNLLINK_PARAM_MAP = {
+ "geneve": {
+ "id": ("id", int),
+ "dstport": ("port", int),
+ "remote": ("", _convert_ip("remote")),
+ "udpcsum": ("udp-csum",),
+ "udp6zerocsumtx": ("udp-zero-csum6-tx",),
+ "udp6zerocsumrx": ("udp-zero-csum6-rx",),
+ "gro-hint": ("gro-hint",),
+ "innerprotoinherit": ("inner-proto-inherit",),
+ },
+}
def sock_wait_drain(sock, max_wait=1000):
@@ -107,29 +130,106 @@ def run_one_stream(cfg, ipver, remote_v4, remote_v6, should_lso):
500, comment="Number of LSO wire-packets with LSO disabled")
-def build_tunnel(cfg, outer_ipver, tun_info):
- local_v4 = NetDrvEpEnv.nsim_v4_pfx + "1"
- local_v6 = NetDrvEpEnv.nsim_v6_pfx + "1"
- remote_v4 = NetDrvEpEnv.nsim_v4_pfx + "2"
- remote_v6 = NetDrvEpEnv.nsim_v6_pfx + "2"
-
- local_addr = cfg.addr_v[outer_ipver]
- remote_addr = cfg.remote_addr_v[outer_ipver]
+def get_tun_ip_address(encap_tun):
+ pfx_v4 = NetDrvEpEnv.nsim_v4_pfx
+ pfx_v6 = NetDrvEpEnv.nsim_v6_pfx.rsplit("::", 1)[0] + ":"
+ v4_offset = 1 if encap_tun == "outer" else 17
+ v6_offset = "1" if encap_tun == "outer" else "2"
+ local_v4 = f"{pfx_v4}{v4_offset}"
+ remote_v4 = f"{pfx_v4}{v4_offset + 1}"
+ local_v6 = f"{pfx_v6}{v6_offset}::1"
+ remote_v6 = f"{pfx_v6}{v6_offset}::2"
+ return local_v4, remote_v4, 28, local_v6, remote_v6, 80
+
+
+def parse_tun_args(tun_arg, tunnel_arg_dict):
+ data = {}
+ args = tun_arg.split()
+ i = 0
+ while i < len(args):
+ negate = False
+ item = tunnel_arg_dict.get(args[i])
+ if item is None and args[i].startswith("no"):
+ item = tunnel_arg_dict.get(args[i][2:])
+ negate = True
+ if item and len(item) == 2:
+ key, conv = item
+ val = conv(args[i + 1])
+ if isinstance(val, tuple) and len(val) == 2:
+ data[val[0]] = val[1]
+ else:
+ data[key] = val
+ i += 2
+ elif item:
+ data[item[0]] = 0 if negate else 1
+ i += 1
+ else:
+ i += 1
+ return data
+
+
+def create_tunnel(tun_type, tun_name, tun_arg, host=None) -> None:
+ tunnel_arg_dict = YNLLINK_PARAM_MAP.get(tun_type)
+ if tunnel_arg_dict:
+ data = parse_tun_args(tun_arg, tunnel_arg_dict)
+ nl_msg = json.dumps({
+ "ifname": tun_name,
+ "linkinfo": {"kind": tun_type, "data": data},
+ })
+ ynlcli("rt-link",
+ f"--create --excl --do newlink --json '{nl_msg}'",
+ host=host)
+ else:
+ ip(f"link add {tun_name} type {tun_type} {tun_arg}", host=host)
+
+
+def build_tunnel(cfg, encap_ipver, encap_tun, tun_info):
+ if encap_tun == "outer":
+ encap_addr = cfg.addr_v[encap_ipver]
+ decap_addr = cfg.remote_addr_v[encap_ipver]
+ else:
+ local_v4, remote_v4, _, local_v6, remote_v6, _ = get_tun_ip_address(
+ "outer")
+ encap_addr = local_v4 if encap_ipver == "4" else local_v6
+ decap_addr = remote_v4 if encap_ipver == "4" else remote_v6
tun_type = tun_info[0]
- tun_arg = tun_info[1]
- ip(f"link add {tun_type}-ksft type {tun_type} {tun_arg} local {local_addr} remote {remote_addr} dev {cfg.ifname}")
- defer(ip, f"link del {tun_type}-ksft")
- ip(f"link set dev {tun_type}-ksft up")
- ip(f"addr add {local_v4}/24 dev {tun_type}-ksft")
- ip(f"addr add {local_v6}/64 dev {tun_type}-ksft")
-
- ip(f"link add {tun_type}-ksft type {tun_type} {tun_arg} local {remote_addr} remote {local_addr} dev {cfg.remote_ifname}",
- host=cfg.remote)
- defer(ip, f"link del {tun_type}-ksft", host=cfg.remote)
- ip(f"link set dev {tun_type}-ksft up", host=cfg.remote)
- ip(f"addr add {remote_v4}/24 dev {tun_type}-ksft", host=cfg.remote)
- ip(f"addr add {remote_v6}/64 dev {tun_type}-ksft", host=cfg.remote)
+ tun_name = f"{tun_type}-ksft" if encap_tun == "outer" else f"in-{tun_type}-ksft"
+ local_v4, remote_v4, mask_v4, local_v6, remote_v6, mask_v6 = get_tun_ip_address(
+ encap_tun
+ )
+ tun_features = " ".join(
+ f + " on" for f in tun_info[2].split()) if tun_info[2] else ""
+
+ tun_dev = cfg.ifname if encap_tun == "outer" else f"{tun_type}-ksft"
+ tun_arg = tun_info[1] + \
+ f" local {encap_addr} remote {decap_addr} dev {tun_dev}"
+
+ create_tunnel(tun_type, tun_name, tun_arg)
+ defer(ip, f"link del {tun_name}")
+ ip(f"link set dev {tun_name} up")
+ ip(f"addr add {local_v4}/{mask_v4} dev {tun_name}")
+ ip(f"addr add {local_v6}/{mask_v6} dev {tun_name}")
+ if tun_features:
+ ethtool(f"-K {tun_name} {tun_features}")
+ # pmtu can't be propagated to upper layer devices; need manual adjust
+ if encap_tun == "inner":
+ tun_mtu = 1392 if encap_ipver == "4" else 1352
+ ip(f"link set dev {tun_name} mtu {tun_mtu}")
+
+ tun_dev = cfg.remote_ifname if encap_tun == "outer" else f"{tun_type}-ksft"
+ tun_arg = tun_info[1] + \
+ f" local {decap_addr} remote {encap_addr} dev {tun_dev}"
+
+ create_tunnel(tun_type, tun_name, tun_arg, host=cfg.remote)
+ defer(ip, f"link del {tun_name}", host=cfg.remote)
+ ip(f"link set dev {tun_name} up", host=cfg.remote)
+ ip(f"addr add {remote_v4}/{mask_v4} dev {tun_name}", host=cfg.remote)
+ ip(f"addr add {remote_v6}/{mask_v6} dev {tun_name}", host=cfg.remote)
+ if tun_features:
+ ethtool(f"-K {tun_name} {tun_features}", host=cfg.remote)
+ if encap_tun == "inner":
+ ip(f"link set dev {tun_name} mtu {tun_mtu}", host=cfg.remote)
return remote_v4, remote_v6
@@ -145,7 +245,10 @@ def restore_wanted_features(cfg):
ksft_pr(f"WARNING: failure restoring wanted features: {e}")
-def test_builder(name, cfg, outer_ipver, feature, tun=None, inner_ipver=None):
+def test_builder(
+ name, cfg, outer_ipver, feature, outer_tun=None,
+ inner_tun=None, inner_ipver=None,
+):
"""Construct specific tests from the common template."""
def f(cfg):
cfg.require_ipver(outer_ipver)
@@ -159,8 +262,12 @@ def test_builder(name, cfg, outer_ipver, feature, tun=None, inner_ipver=None):
raise KsftSkipEx(f"Device does not support {feature}")
ipver = outer_ipver
- if tun:
- remote_v4, remote_v6 = build_tunnel(cfg, ipver, tun)
+ if outer_tun and inner_tun:
+ build_tunnel(cfg, ipver, "outer", outer_tun)
+ remote_v4, remote_v6 = build_tunnel(cfg, ipver, "inner", inner_tun)
+ ipver = inner_ipver
+ elif outer_tun:
+ remote_v4, remote_v6 = build_tunnel(cfg, ipver, "outer", outer_tun)
ipver = inner_ipver
else:
remote_v4 = cfg.remote_addr_v["4"]
@@ -182,7 +289,11 @@ def test_builder(name, cfg, outer_ipver, feature, tun=None, inner_ipver=None):
ethtool(f"-K {cfg.ifname} {feature} on")
run_one_stream(cfg, ipver, remote_v4, remote_v6, should_lso=True)
- f.__name__ = name + ((outer_ipver + "_") if tun else "") + "ipv" + inner_ipver
+ outer_tun_name = f"{outer_tun[0]}{outer_ipver}_" if outer_tun else ""
+ inner_tun_name = f"{inner_tun[0]}{outer_ipver}_" if inner_tun else ""
+ f.__name__ = (
+ name + "_" if name else ""
+ ) + f"{outer_tun_name}{inner_tun_name}ipv{inner_ipver}"
return f
@@ -242,14 +353,43 @@ def main() -> None:
query_nic_features(cfg)
test_info = (
- # name, v4/v6 ethtool_feature tun:(type, args, inner ip versions)
- ("", "4", "tx-tcp-segmentation", None),
- ("", "6", "tx-tcp6-segmentation", None),
- ("vxlan", "4", "tx-udp_tnl-segmentation", ("vxlan", "id 100 dstport 4789 noudpcsum", ("4", "6"))),
- ("vxlan", "6", "tx-udp_tnl-segmentation", ("vxlan", "id 100 dstport 4789 udp6zerocsumtx udp6zerocsumrx", ("4", "6"))),
- ("vxlan_csum", "", "tx-udp_tnl-csum-segmentation", ("vxlan", "id 100 dstport 4789 udpcsum", ("4", "6"))),
- ("gre", "4", "tx-gre-segmentation", ("gre", "", ("4", "6"))),
- ("gre", "6", "tx-gre-segmentation", ("ip6gre","", ("4", "6"))),
+ # name, v4/v6, ethtool_feature,
+ # outer_tun:(type, args, ethtool_feature, inner ip versions),
+ # inner_tun:(type, args, ethtool_feature, inner ip versions)
+ ("", "4", "tx-tcp-segmentation", (), ()),
+ ("", "6", "tx-tcp6-segmentation", (), ()),
+ (
+ "vxlan", "4", "tx-udp_tnl-segmentation",
+ ("vxlan", "id 100 dstport 4789 noudpcsum", "", ("4", "6")), (),
+ ),
+ (
+ "vxlan", "6", "tx-udp_tnl-segmentation",
+ ("vxlan", "id 100 dstport 4789 udp6zerocsumtx udp6zerocsumrx",
+ "", ("4", "6")),
+ (),
+ ),
+ (
+ "vxlan_csum", "", "tx-udp_tnl-csum-segmentation",
+ ("vxlan", "id 100 dstport 4789 udpcsum", "", ("4", "6")),
+ (),
+ ),
+ (
+ "gre", "4", "tx-gre-segmentation",
+ ("gre", "", "", ("4", "6")),
+ (),
+ ),
+ (
+ "gre", "6", "tx-gre-segmentation",
+ ("ip6gre", "", "", ("4", "6")),
+ (),
+ ),
+ (
+ "geneve2", "4", "tx-udp_tnl-segmentation",
+ ("geneve", "id 100 dstport 6081 noudpcsum udp6zerocsumtx udp6zerocsumrx",
+ "tx-gso-partial tx-udp_tnl-segmentation tx-udp_tnl-csum-segmentation", (),),
+ ("geneve", "id 200 dstport 6082 noudpcsum udp6zerocsumtx udp6zerocsumrx",
+ "", ("4", "6"),),
+ ),
)
cases = []
@@ -259,13 +399,21 @@ def main() -> None:
if info[1] and outer_ipver != info[1]:
continue
- if info[3]:
- cases += [
- test_builder(info[0], cfg, outer_ipver, info[2], info[3], inner_ipver)
- for inner_ipver in info[3][2]
- ]
+ outer_tun, inner_tun = info[3], info[4]
+ if outer_tun and inner_tun:
+ inner_ipvers = inner_tun[3]
+ cases += [test_builder(info[0], cfg, outer_ipver, info[2],
+ outer_tun, inner_tun, inner_ipver)
+ for inner_ipver in inner_ipvers]
+ elif outer_tun:
+ inner_ipvers = outer_tun[3]
+ cases += [test_builder(info[0], cfg, outer_ipver, info[2],
+ outer_tun, None, inner_ipver)
+ for inner_ipver in inner_ipvers]
else:
- cases.append(test_builder(info[0], cfg, outer_ipver, info[2], None, outer_ipver))
+ cases.append(
+ test_builder(info[0], cfg, outer_ipver, info[2],
+ None, None, outer_ipver))
ksft_run(cases=cases, args=(cfg, ))
ksft_exit()
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [RFC net-next 4/4] selftests: drv-net: tso: expand double tunnel GSO test coverage
2026-04-07 2:45 [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests Xu Du
` (2 preceding siblings ...)
2026-04-07 2:45 ` [RFC net-next 3/4] selftests: drv-net: tso: add Geneve double tunneling GSO test Xu Du
@ 2026-04-07 2:45 ` Xu Du
3 siblings, 0 replies; 5+ messages in thread
From: Xu Du @ 2026-04-07 2:45 UTC (permalink / raw)
To: davem, edumazet, kuba, pabeni, horms, shuah
Cc: netdev, linux-kselftest, linux-kernel
Add Geneve test variants with GRO hint and TTL inherit options
to exercise additional tunnel configuration paths.
Also add double VXLAN tunnel test cases to complement the existing
double Geneve coverage.
Signed-off-by: Xu Du <xudu@redhat.com>
---
tools/testing/selftests/drivers/net/hw/tso.py | 24 +++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tools/testing/selftests/drivers/net/hw/tso.py b/tools/testing/selftests/drivers/net/hw/tso.py
index 6b4639ce6139..6930eb3fde29 100755
--- a/tools/testing/selftests/drivers/net/hw/tso.py
+++ b/tools/testing/selftests/drivers/net/hw/tso.py
@@ -373,6 +373,12 @@ def main() -> None:
("vxlan", "id 100 dstport 4789 udpcsum", "", ("4", "6")),
(),
),
+ (
+ "vxlan2", "4", "tx-udp_tnl-csum-segmentation",
+ ("vxlan", "id 100 dstport 4789 udpcsum",
+ "tx-gso-partial tx-udp_tnl-segmentation tx-udp_tnl-csum-segmentation", (),),
+ ("vxlan", "id 200 dstport 5789 udpcsum", "", ("4", "6")),
+ ),
(
"gre", "4", "tx-gre-segmentation",
("gre", "", "", ("4", "6")),
@@ -390,6 +396,24 @@ def main() -> None:
("geneve", "id 200 dstport 6082 noudpcsum udp6zerocsumtx udp6zerocsumrx",
"", ("4", "6"),),
),
+ (
+ "geneve2_csum", "", "tx-udp_tnl-csum-segmentation",
+ ("geneve", "id 100 dstport 6081 udpcsum",
+ "tx-gso-partial tx-udp_tnl-segmentation tx-udp_tnl-csum-segmentation", (),),
+ ("geneve", "id 200 dstport 6082 noudpcsum", "", ("4", "6")),
+ ),
+ (
+ "geneve2_grohint", "", "tx-udp_tnl-csum-segmentation",
+ ("geneve", "id 100 dstport 6081 udpcsum gro-hint",
+ "tx-gso-partial tx-udp_tnl-segmentation tx-udp_tnl-csum-segmentation", (),),
+ ("geneve", "id 200 dstport 6082 udpcsum", "", ("4", "6")),
+ ),
+ (
+ "geneve2_inherit", "4", "tx-udp_tnl-csum-segmentation",
+ ("geneve", "id 100 dstport 6081 udpcsum gro-hint",
+ "tx-gso-partial tx-udp_tnl-segmentation tx-udp_tnl-csum-segmentation", (),),
+ ("geneve", "id 200 dstport 6082 udpcsum inner-proto-inherit", "", ("4", "6")),
+ ),
)
cases = []
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-04-07 2:45 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-07 2:45 [RFC net-next 0/4] selftests: drv-net: tso: add double tunneling GSO tests Xu Du
2026-04-07 2:45 ` [RFC net-next 1/4] selftests: drv-net: tso: retry connect on EHOSTUNREACH Xu Du
2026-04-07 2:45 ` [RFC net-next 2/4] selftests: drv-net: tso: add helpers for double tunneling GSO Xu Du
2026-04-07 2:45 ` [RFC net-next 3/4] selftests: drv-net: tso: add Geneve double tunneling GSO test Xu Du
2026-04-07 2:45 ` [RFC net-next 4/4] selftests: drv-net: tso: expand double tunnel GSO test coverage Xu Du
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox