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 <[email protected]> --- 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
