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, shuah@kernel.org,
willemb@google.com, petrm@nvidia.com, anubhavsinggh@google.com,
richardbgobert@gmail.com, linux-kselftest@vger.kernel.org,
Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 5/6] selftests: drv-net: gro: test ip6ip6
Date: Wed, 1 Apr 2026 11:26:24 -0700 [thread overview]
Message-ID: <20260401182625.372605-6-kuba@kernel.org> (raw)
In-Reply-To: <20260401182625.372605-1-kuba@kernel.org>
We explicitly test ipip encap. Let's add ip6ip6, too. Having
just ipip seems like favoring IPv4 which we should not do :)
Testing all combinations is left for future work, not sure
it's actually worth it.
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
tools/testing/selftests/net/lib/gro.c | 29 ++++++++++++++++------
tools/testing/selftests/drivers/net/gro.py | 19 ++++++++------
2 files changed, 34 insertions(+), 14 deletions(-)
diff --git a/tools/testing/selftests/net/lib/gro.c b/tools/testing/selftests/net/lib/gro.c
index 57080ecc3df8..762e88932ed2 100644
--- a/tools/testing/selftests/net/lib/gro.c
+++ b/tools/testing/selftests/net/lib/gro.c
@@ -94,11 +94,14 @@
#define START_SEQ 100
#define START_ACK 100
#define ETH_P_NONE 0
-#define TOTAL_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
+#define TOTAL_HDR_LEN \
+ (ETH_HLEN + sizeof(struct ipv6hdr) * 2 + sizeof(struct tcphdr))
#define MSS (4096 - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))
-#define MAX_PAYLOAD (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))
+#define MAX_PAYLOAD \
+ (IP_MAXPACKET - sizeof(struct tcphdr) - sizeof(struct ipv6hdr))
#define NUM_LARGE_PKT (MAX_PAYLOAD / MSS)
-#define MAX_HDR_LEN (ETH_HLEN + sizeof(struct ipv6hdr) + sizeof(struct tcphdr))
+#define MAX_HDR_LEN \
+ (ETH_HLEN + sizeof(struct ipv6hdr) * 2 + sizeof(struct tcphdr))
#define MIN_EXTHDR_SIZE 8
#define EXT_PAYLOAD_1 "\x00\x00\x00\x00\x00\x00"
#define EXT_PAYLOAD_2 "\x11\x11\x11\x11\x11\x11"
@@ -131,6 +134,7 @@ static int tcp_offset = -1;
static int total_hdr_len = -1;
static int ethhdr_proto = -1;
static bool ipip;
+static bool ip6ip6;
static uint64_t txtime_ns;
static int num_flows = 4;
static bool order_check;
@@ -1113,7 +1117,8 @@ static void check_recv_pkts(int fd, int *correct_payload,
if (iph->version == 4)
ip_ext_len = (iph->ihl - 5) * 4;
- else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP)
+ else if (ip6h->version == 6 && !ip6ip6 &&
+ ip6h->nexthdr != IPPROTO_TCP)
ip_ext_len = MIN_EXTHDR_SIZE;
tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
@@ -1175,7 +1180,8 @@ static void check_capacity_pkts(int fd)
if (iph->version == 4)
ip_ext_len = (iph->ihl - 5) * 4;
- else if (ip6h->version == 6 && ip6h->nexthdr != IPPROTO_TCP)
+ else if (ip6h->version == 6 && !ip6ip6 &&
+ ip6h->nexthdr != IPPROTO_TCP)
ip_ext_len = MIN_EXTHDR_SIZE;
tcph = (struct tcphdr *)(buffer + tcp_offset + ip_ext_len);
@@ -1688,6 +1694,7 @@ static void parse_args(int argc, char **argv)
{ "ipv4", no_argument, NULL, '4' },
{ "ipv6", no_argument, NULL, '6' },
{ "ipip", no_argument, NULL, 'e' },
+ { "ip6ip6", no_argument, NULL, 'E' },
{ "num-flows", required_argument, NULL, 'n' },
{ "rx", no_argument, NULL, 'r' },
{ "saddr", required_argument, NULL, 's' },
@@ -1699,7 +1706,7 @@ static void parse_args(int argc, char **argv)
};
int c;
- while ((c = getopt_long(argc, argv, "46d:D:ei:n:rs:S:t:ov", opts, NULL)) != -1) {
+ while ((c = getopt_long(argc, argv, "46d:D:eEi:n:rs:S:t:ov", opts, NULL)) != -1) {
switch (c) {
case '4':
proto = PF_INET;
@@ -1714,6 +1721,11 @@ static void parse_args(int argc, char **argv)
proto = PF_INET;
ethhdr_proto = htons(ETH_P_IP);
break;
+ case 'E':
+ ip6ip6 = true;
+ proto = PF_INET6;
+ ethhdr_proto = htons(ETH_P_IPV6);
+ break;
case 'd':
addr4_dst = addr6_dst = optarg;
break;
@@ -1758,12 +1770,15 @@ int main(int argc, char **argv)
if (ipip) {
tcp_offset = ETH_HLEN + sizeof(struct iphdr) * 2;
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
+ } else if (ip6ip6) {
+ tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr) * 2;
+ total_hdr_len = tcp_offset + sizeof(struct tcphdr);
} else if (proto == PF_INET) {
tcp_offset = ETH_HLEN + sizeof(struct iphdr);
total_hdr_len = tcp_offset + sizeof(struct tcphdr);
} else if (proto == PF_INET6) {
tcp_offset = ETH_HLEN + sizeof(struct ipv6hdr);
- total_hdr_len = MAX_HDR_LEN;
+ total_hdr_len = tcp_offset + sizeof(struct tcphdr);
} else {
error(1, 0, "Protocol family is not ipv4 or ipv6");
}
diff --git a/tools/testing/selftests/drivers/net/gro.py b/tools/testing/selftests/drivers/net/gro.py
index 73436d16b40d..68b7b29ea2ee 100755
--- a/tools/testing/selftests/drivers/net/gro.py
+++ b/tools/testing/selftests/drivers/net/gro.py
@@ -213,7 +213,7 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None,
return rx_proc
-def _setup(cfg, mode, test_name):
+def _setup(cfg, mode, test_name, protocol):
""" Setup hardware loopback mode for GRO testing. """
if not hasattr(cfg, "bin_remote"):
@@ -225,10 +225,15 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None,
cfg.remote_feat = ethtool(f"-k {cfg.remote_ifname}",
host=cfg.remote, json=True)[0]
- # "large_*" tests need at least 4k MTU
+ # "large_*" tests need at least 4k MTU, bump more for encapsulation
if test_name.startswith("large_"):
- _set_mtu_restore(cfg.dev, 4096, None)
- _set_mtu_restore(cfg.remote_dev, 4096, cfg.remote)
+ mtu = 4096
+ if protocol == "ipip":
+ mtu += 20 # outer IPv4 header
+ elif protocol == "ip6ip6":
+ mtu += 40 # outer IPv6 header
+ _set_mtu_restore(cfg.dev, mtu, None)
+ _set_mtu_restore(cfg.remote_dev, mtu, cfg.remote)
if mode == "sw":
flush_path = f"/sys/class/net/{cfg.ifname}/gro_flush_timeout"
@@ -313,7 +318,7 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None,
]
for mode in ["sw", "hw", "lro"]:
- for protocol in ["ipv4", "ipv6", "ipip"]:
+ for protocol in ["ipv4", "ipv6", "ipip", "ip6ip6"]:
for test_name in common_tests:
yield mode, protocol, test_name
@@ -332,7 +337,7 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None,
ipver = "6" if protocol[-1] == "6" else "4"
cfg.require_ipver(ipver)
- _setup(cfg, mode, test_name)
+ _setup(cfg, mode, test_name, protocol)
# Each test is run 6 times to deflake, because given the receive timing,
# not all packets that should coalesce will be considered in the same flow
@@ -382,7 +387,7 @@ def _run_gro_bin(cfg, test_name, protocol=None, num_flows=None,
"""
max_retries = 3
- _setup(cfg, mode, "capacity")
+ _setup(cfg, mode, "capacity", None)
queue_id = setup_func(cfg)
num_flows = 8
--
2.53.0
next prev parent reply other threads:[~2026-04-01 18:26 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-01 18:26 [PATCH net-next 0/6] selftests: drv-net: gro: more test cases Jakub Kicinski
2026-04-01 18:26 ` [PATCH net-next 1/6] selftests: drv-net: gro: add data burst test case Jakub Kicinski
2026-04-01 18:26 ` [PATCH net-next 2/6] selftests: drv-net: gro: add 1 byte payload test Jakub Kicinski
2026-04-01 18:26 ` [PATCH net-next 3/6] selftests: drv-net: gro: always wait for FIN in the capacity test Jakub Kicinski
2026-04-01 18:26 ` [PATCH net-next 4/6] selftests: drv-net: gro: prepare for ip6ip6 support Jakub Kicinski
2026-04-01 18:26 ` Jakub Kicinski [this message]
2026-04-02 0:20 ` [PATCH net-next 5/6] selftests: drv-net: gro: test ip6ip6 Willem de Bruijn
2026-04-01 18:26 ` [PATCH net-next 6/6] selftests: drv-net: gro: add a test for bad IPv4 csum Jakub Kicinski
2026-04-02 0:28 ` Willem de Bruijn
2026-04-02 2:10 ` Jakub Kicinski
2026-04-02 2:39 ` Willem de Bruijn
2026-04-02 0:19 ` [PATCH net-next 0/6] selftests: drv-net: gro: more test cases Willem de Bruijn
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=20260401182625.372605-6-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=andrew+netdev@lunn.ch \
--cc=anubhavsinggh@google.com \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=petrm@nvidia.com \
--cc=richardbgobert@gmail.com \
--cc=shuah@kernel.org \
--cc=willemb@google.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