1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 3 /* 4 * End-to-end eBPF tunnel test suite 5 * The file tests BPF network tunnels implementation. For each tunnel 6 * type, the test validates that: 7 * - basic communication can first be established between the two veths 8 * - when adding a BPF-based encapsulation on client egress, it now fails 9 * to communicate with the server 10 * - when adding a kernel-based decapsulation on server ingress, client 11 * can now connect 12 * - when replacing the kernel-based decapsulation with a BPF-based one, 13 * the client can still connect 14 */ 15 16 #include <stdio.h> 17 #include <unistd.h> 18 #include <fcntl.h> 19 #include <sys/socket.h> 20 #include <bpf/libbpf.h> 21 22 #include "test_progs.h" 23 #include "network_helpers.h" 24 #include "test_tc_tunnel.skel.h" 25 26 #define SERVER_NS "tc-tunnel-server-ns" 27 #define CLIENT_NS "tc-tunnel-client-ns" 28 #define MAC_ADDR_VETH1 "00:11:22:33:44:55" 29 #define IP4_ADDR_VETH1 "192.168.1.1" 30 #define IP6_ADDR_VETH1 "fd::1" 31 #define MAC_ADDR_VETH2 "66:77:88:99:AA:BB" 32 #define IP4_ADDR_VETH2 "192.168.1.2" 33 #define IP6_ADDR_VETH2 "fd::2" 34 35 #define TEST_NAME_MAX_LEN 64 36 #define PROG_NAME_MAX_LEN 64 37 #define TUNNEL_ARGS_MAX_LEN 128 38 #define BUFFER_LEN 2000 39 #define DEFAULT_TEST_DATA_SIZE 100 40 #define GSO_TEST_DATA_SIZE BUFFER_LEN 41 42 #define TIMEOUT_MS 1000 43 #define TEST_PORT 8000 44 #define UDP_PORT 5555 45 #define MPLS_UDP_PORT 6635 46 #define FOU_MPLS_PROTO 137 47 #define VXLAN_ID 1 48 #define VXLAN_PORT 8472 49 #define MPLS_TABLE_ENTRIES_COUNT 65536 50 51 static char tx_buffer[BUFFER_LEN], rx_buffer[BUFFER_LEN]; 52 53 struct subtest_cfg { 54 char *ebpf_tun_type; 55 char *iproute_tun_type; 56 char *mac_tun_type; 57 int ipproto; 58 void (*extra_decap_mod_args_cb)(struct subtest_cfg *cfg, char *dst); 59 bool tunnel_need_veth_mac; 60 bool configure_fou_rx_port; 61 char *tmode; 62 bool expect_kern_decap_failure; 63 bool configure_mpls; 64 bool test_gso; 65 char *tunnel_client_addr; 66 char *tunnel_server_addr; 67 char name[TEST_NAME_MAX_LEN]; 68 char *server_addr; 69 int client_egress_prog_fd; 70 int server_ingress_prog_fd; 71 char extra_decap_mod_args[TUNNEL_ARGS_MAX_LEN]; 72 int server_fd; 73 }; 74 75 struct connection { 76 int client_fd; 77 int server_fd; 78 }; 79 80 static int build_subtest_name(struct subtest_cfg *cfg, char *dst, size_t size) 81 { 82 int ret; 83 84 ret = snprintf(dst, size, "%s_%s", cfg->ebpf_tun_type, 85 cfg->mac_tun_type); 86 87 return ret < 0 ? ret : 0; 88 } 89 90 static int set_subtest_progs(struct subtest_cfg *cfg, struct test_tc_tunnel *skel) 91 { 92 char prog_name[PROG_NAME_MAX_LEN]; 93 struct bpf_program *prog; 94 int ret; 95 96 ret = snprintf(prog_name, PROG_NAME_MAX_LEN, "__encap_"); 97 if (ret < 0) 98 return ret; 99 ret = build_subtest_name(cfg, prog_name + ret, PROG_NAME_MAX_LEN - ret); 100 if (ret < 0) 101 return ret; 102 prog = bpf_object__find_program_by_name(skel->obj, prog_name); 103 if (!prog) 104 return -1; 105 106 cfg->client_egress_prog_fd = bpf_program__fd(prog); 107 cfg->server_ingress_prog_fd = bpf_program__fd(skel->progs.decap_f); 108 return 0; 109 } 110 111 static void set_subtest_addresses(struct subtest_cfg *cfg) 112 { 113 if (cfg->ipproto == 6) 114 cfg->server_addr = IP6_ADDR_VETH2; 115 else 116 cfg->server_addr = IP4_ADDR_VETH2; 117 118 /* Some specific tunnel types need specific addressing, it then 119 * has been already set in the configuration table. Otherwise, 120 * deduce the relevant addressing from the ipproto 121 */ 122 if (cfg->tunnel_client_addr && cfg->tunnel_server_addr) 123 return; 124 125 if (cfg->ipproto == 6) { 126 cfg->tunnel_client_addr = IP6_ADDR_VETH1; 127 cfg->tunnel_server_addr = IP6_ADDR_VETH2; 128 } else { 129 cfg->tunnel_client_addr = IP4_ADDR_VETH1; 130 cfg->tunnel_server_addr = IP4_ADDR_VETH2; 131 } 132 } 133 134 static int run_server(struct subtest_cfg *cfg) 135 { 136 int family = cfg->ipproto == 6 ? AF_INET6 : AF_INET; 137 struct nstoken *nstoken; 138 struct network_helper_opts opts = { 139 .timeout_ms = TIMEOUT_MS 140 }; 141 142 nstoken = open_netns(SERVER_NS); 143 if (!ASSERT_OK_PTR(nstoken, "open server ns")) 144 return -1; 145 146 cfg->server_fd = start_server_str(family, SOCK_STREAM, cfg->server_addr, 147 TEST_PORT, &opts); 148 close_netns(nstoken); 149 if (!ASSERT_OK_FD(cfg->server_fd, "start server")) 150 return -1; 151 152 return 0; 153 } 154 155 static int check_server_rx_data(struct subtest_cfg *cfg, 156 struct connection *conn, int len) 157 { 158 int err; 159 160 memset(rx_buffer, 0, BUFFER_LEN); 161 err = recv(conn->server_fd, rx_buffer, len, 0); 162 if (!ASSERT_EQ(err, len, "check rx data len")) 163 return 1; 164 if (!ASSERT_MEMEQ(tx_buffer, rx_buffer, len, "check received data")) 165 return 1; 166 return 0; 167 } 168 169 static struct connection *connect_client_to_server(struct subtest_cfg *cfg) 170 { 171 struct network_helper_opts opts = {.timeout_ms = 1000}; 172 int family = cfg->ipproto == 6 ? AF_INET6 : AF_INET; 173 struct connection *conn = NULL; 174 int client_fd, server_fd; 175 176 conn = malloc(sizeof(struct connection)); 177 if (!conn) 178 return conn; 179 180 client_fd = connect_to_addr_str(family, SOCK_STREAM, cfg->server_addr, 181 TEST_PORT, &opts); 182 183 if (client_fd < 0) { 184 free(conn); 185 return NULL; 186 } 187 188 server_fd = accept(cfg->server_fd, NULL, NULL); 189 if (server_fd < 0) { 190 close(client_fd); 191 free(conn); 192 return NULL; 193 } 194 195 conn->server_fd = server_fd; 196 conn->client_fd = client_fd; 197 198 return conn; 199 } 200 201 static void disconnect_client_from_server(struct subtest_cfg *cfg, 202 struct connection *conn) 203 { 204 close(conn->server_fd); 205 close(conn->client_fd); 206 free(conn); 207 } 208 209 static int send_and_test_data(struct subtest_cfg *cfg) 210 { 211 struct connection *conn; 212 int err, res = -1; 213 214 conn = connect_client_to_server(cfg); 215 if (!ASSERT_OK_PTR(conn, "connect to server")) 216 return -1; 217 218 err = send(conn->client_fd, tx_buffer, DEFAULT_TEST_DATA_SIZE, 0); 219 if (!ASSERT_EQ(err, DEFAULT_TEST_DATA_SIZE, "send data from client")) 220 goto end; 221 if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE)) 222 goto end; 223 224 if (!cfg->test_gso) { 225 res = 0; 226 goto end; 227 } 228 229 err = send(conn->client_fd, tx_buffer, GSO_TEST_DATA_SIZE, 0); 230 if (!ASSERT_EQ(err, GSO_TEST_DATA_SIZE, "send (large) data from client")) 231 goto end; 232 if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE)) 233 goto end; 234 235 res = 0; 236 end: 237 disconnect_client_from_server(cfg, conn); 238 return res; 239 } 240 241 static void vxlan_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst) 242 { 243 snprintf(dst, TUNNEL_ARGS_MAX_LEN, "id %d dstport %d udp6zerocsumrx", 244 VXLAN_ID, VXLAN_PORT); 245 } 246 247 static void udp_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst) 248 { 249 bool is_mpls = !strcmp(cfg->mac_tun_type, "mpls"); 250 251 snprintf(dst, TUNNEL_ARGS_MAX_LEN, 252 "encap fou encap-sport auto encap-dport %d", 253 is_mpls ? MPLS_UDP_PORT : UDP_PORT); 254 } 255 256 static int configure_fou_rx_port(struct subtest_cfg *cfg, bool add) 257 { 258 bool is_mpls = strcmp(cfg->mac_tun_type, "mpls") == 0; 259 int fou_proto; 260 261 if (is_mpls) 262 fou_proto = FOU_MPLS_PROTO; 263 else 264 fou_proto = cfg->ipproto == 6 ? 41 : 4; 265 266 SYS(fail, "ip fou %s port %d ipproto %d%s", add ? "add" : "del", 267 is_mpls ? MPLS_UDP_PORT : UDP_PORT, fou_proto, 268 cfg->ipproto == 6 ? " -6" : ""); 269 270 return 0; 271 fail: 272 return 1; 273 } 274 275 static int add_fou_rx_port(struct subtest_cfg *cfg) 276 { 277 return configure_fou_rx_port(cfg, true); 278 } 279 280 static int del_fou_rx_port(struct subtest_cfg *cfg) 281 { 282 return configure_fou_rx_port(cfg, false); 283 } 284 285 static int update_tunnel_intf_addr(struct subtest_cfg *cfg) 286 { 287 SYS(fail, "ip link set dev testtun0 address " MAC_ADDR_VETH2); 288 return 0; 289 fail: 290 return -1; 291 } 292 293 static int configure_kernel_for_mpls(struct subtest_cfg *cfg) 294 { 295 SYS(fail, "sysctl -qw net.mpls.platform_labels=%d", 296 MPLS_TABLE_ENTRIES_COUNT); 297 SYS(fail, "ip -f mpls route add 1000 dev lo"); 298 SYS(fail, "ip link set lo up"); 299 SYS(fail, "sysctl -qw net.mpls.conf.testtun0.input=1"); 300 SYS(fail, "sysctl -qw net.ipv4.conf.lo.rp_filter=0"); 301 return 0; 302 fail: 303 return -1; 304 } 305 306 static int configure_encapsulation(struct subtest_cfg *cfg) 307 { 308 int ret; 309 310 ret = tc_prog_attach("veth1", -1, cfg->client_egress_prog_fd); 311 312 return ret; 313 } 314 315 static int configure_kernel_decapsulation(struct subtest_cfg *cfg) 316 { 317 struct nstoken *nstoken = open_netns(SERVER_NS); 318 int ret = -1; 319 320 if (!ASSERT_OK_PTR(nstoken, "open server ns")) 321 return ret; 322 323 if (cfg->configure_fou_rx_port && 324 !ASSERT_OK(add_fou_rx_port(cfg), "configure FOU RX port")) 325 goto fail; 326 SYS(fail, "ip link add name testtun0 type %s %s remote %s local %s %s", 327 cfg->iproute_tun_type, cfg->tmode ? cfg->tmode : "", 328 cfg->tunnel_client_addr, cfg->tunnel_server_addr, 329 cfg->extra_decap_mod_args); 330 if (cfg->tunnel_need_veth_mac && 331 !ASSERT_OK(update_tunnel_intf_addr(cfg), "update testtun0 mac")) 332 goto fail; 333 if (cfg->configure_mpls && 334 (!ASSERT_OK(configure_kernel_for_mpls(cfg), 335 "configure MPLS decap"))) 336 goto fail; 337 SYS(fail, "sysctl -qw net.ipv4.conf.all.rp_filter=0"); 338 SYS(fail, "sysctl -qw net.ipv4.conf.testtun0.rp_filter=0"); 339 SYS(fail, "ip link set dev testtun0 up"); 340 341 ret = 0; 342 fail: 343 close_netns(nstoken); 344 return ret; 345 } 346 347 static void remove_kernel_decapsulation(struct subtest_cfg *cfg) 348 { 349 SYS_NOFAIL("ip link del testtun0"); 350 if (cfg->configure_mpls) 351 SYS_NOFAIL("ip -f mpls route del 1000 dev lo"); 352 if (cfg->configure_fou_rx_port) 353 del_fou_rx_port(cfg); 354 } 355 356 static int configure_ebpf_decapsulation(struct subtest_cfg *cfg) 357 { 358 struct nstoken *nstoken = open_netns(SERVER_NS); 359 int ret = -1; 360 361 if (!ASSERT_OK_PTR(nstoken, "open server ns")) 362 return ret; 363 364 if (!cfg->expect_kern_decap_failure) 365 SYS(fail, "ip link del testtun0"); 366 367 if (!ASSERT_OK(tc_prog_attach("veth2", cfg->server_ingress_prog_fd, -1), 368 "attach_program")) 369 goto fail; 370 371 ret = 0; 372 fail: 373 close_netns(nstoken); 374 return ret; 375 } 376 377 static void run_test(struct subtest_cfg *cfg) 378 { 379 struct nstoken *nstoken; 380 381 if (!ASSERT_OK(run_server(cfg), "run server")) 382 return; 383 384 nstoken = open_netns(CLIENT_NS); 385 if (!ASSERT_OK_PTR(nstoken, "open client ns")) 386 goto fail; 387 388 /* Basic communication must work */ 389 if (!ASSERT_OK(send_and_test_data(cfg), "connect without any encap")) 390 goto fail; 391 392 /* Attach encapsulation program to client */ 393 if (!ASSERT_OK(configure_encapsulation(cfg), "configure encapsulation")) 394 goto fail; 395 396 /* If supported, insert kernel decap module, connection must succeed */ 397 if (!cfg->expect_kern_decap_failure) { 398 if (!ASSERT_OK(configure_kernel_decapsulation(cfg), 399 "configure kernel decapsulation")) 400 goto fail; 401 if (!ASSERT_OK(send_and_test_data(cfg), 402 "connect with encap prog and kern decap")) 403 goto fail; 404 } 405 406 /* Replace kernel decapsulation with BPF decapsulation, test must pass */ 407 if (!ASSERT_OK(configure_ebpf_decapsulation(cfg), "configure ebpf decapsulation")) 408 goto fail; 409 ASSERT_OK(send_and_test_data(cfg), "connect with encap and decap progs"); 410 411 fail: 412 close_netns(nstoken); 413 close(cfg->server_fd); 414 } 415 416 static int setup(void) 417 { 418 struct nstoken *nstoken_client, *nstoken_server; 419 int fd, err; 420 421 fd = open("/dev/urandom", O_RDONLY); 422 if (!ASSERT_OK_FD(fd, "open urandom")) 423 goto fail; 424 err = read(fd, tx_buffer, BUFFER_LEN); 425 close(fd); 426 427 if (!ASSERT_EQ(err, BUFFER_LEN, "read random bytes")) 428 goto fail; 429 430 /* Configure the testing network */ 431 if (!ASSERT_OK(make_netns(CLIENT_NS), "create client ns") || 432 !ASSERT_OK(make_netns(SERVER_NS), "create server ns")) 433 goto fail; 434 435 nstoken_client = open_netns(CLIENT_NS); 436 if (!ASSERT_OK_PTR(nstoken_client, "open client ns")) 437 goto fail_delete_ns; 438 SYS(fail_close_ns_client, "ip link add %s type veth peer name %s", 439 "veth1 mtu 1500 netns " CLIENT_NS " address " MAC_ADDR_VETH1, 440 "veth2 mtu 1500 netns " SERVER_NS " address " MAC_ADDR_VETH2); 441 SYS(fail_close_ns_client, "ethtool -K veth1 tso off"); 442 SYS(fail_close_ns_client, "ip link set veth1 up"); 443 nstoken_server = open_netns(SERVER_NS); 444 if (!ASSERT_OK_PTR(nstoken_server, "open server ns")) 445 goto fail_close_ns_client; 446 SYS(fail_close_ns_server, "ip link set veth2 up"); 447 448 close_netns(nstoken_server); 449 close_netns(nstoken_client); 450 return 0; 451 452 fail_close_ns_server: 453 close_netns(nstoken_server); 454 fail_close_ns_client: 455 close_netns(nstoken_client); 456 fail_delete_ns: 457 SYS_NOFAIL("ip netns del " CLIENT_NS); 458 SYS_NOFAIL("ip netns del " SERVER_NS); 459 fail: 460 return -1; 461 } 462 463 static int subtest_setup(struct test_tc_tunnel *skel, struct subtest_cfg *cfg) 464 { 465 struct nstoken *nstoken_client, *nstoken_server; 466 int ret = -1; 467 468 set_subtest_addresses(cfg); 469 if (!ASSERT_OK(set_subtest_progs(cfg, skel), 470 "find subtest progs")) 471 goto fail; 472 if (cfg->extra_decap_mod_args_cb) 473 cfg->extra_decap_mod_args_cb(cfg, cfg->extra_decap_mod_args); 474 475 nstoken_client = open_netns(CLIENT_NS); 476 if (!ASSERT_OK_PTR(nstoken_client, "open client ns")) 477 goto fail; 478 SYS(fail_close_client_ns, 479 "ip -4 addr add " IP4_ADDR_VETH1 "/24 dev veth1"); 480 SYS(fail_close_client_ns, "ip -4 route flush table main"); 481 SYS(fail_close_client_ns, 482 "ip -4 route add " IP4_ADDR_VETH2 " mtu 1450 dev veth1"); 483 SYS(fail_close_client_ns, 484 "ip -6 addr add " IP6_ADDR_VETH1 "/64 dev veth1 nodad"); 485 SYS(fail_close_client_ns, "ip -6 route flush table main"); 486 SYS(fail_close_client_ns, 487 "ip -6 route add " IP6_ADDR_VETH2 " mtu 1430 dev veth1"); 488 nstoken_server = open_netns(SERVER_NS); 489 if (!ASSERT_OK_PTR(nstoken_server, "open server ns")) 490 goto fail_close_client_ns; 491 SYS(fail_close_server_ns, 492 "ip -4 addr add " IP4_ADDR_VETH2 "/24 dev veth2"); 493 SYS(fail_close_server_ns, 494 "ip -6 addr add " IP6_ADDR_VETH2 "/64 dev veth2 nodad"); 495 496 ret = 0; 497 498 fail_close_server_ns: 499 close_netns(nstoken_server); 500 fail_close_client_ns: 501 close_netns(nstoken_client); 502 fail: 503 return ret; 504 } 505 506 507 static void subtest_cleanup(struct subtest_cfg *cfg) 508 { 509 struct nstoken *nstoken; 510 511 nstoken = open_netns(CLIENT_NS); 512 if (ASSERT_OK_PTR(nstoken, "open clien ns")) { 513 SYS_NOFAIL("tc qdisc delete dev veth1 parent ffff:fff1"); 514 SYS_NOFAIL("ip a flush veth1"); 515 close_netns(nstoken); 516 } 517 nstoken = open_netns(SERVER_NS); 518 if (ASSERT_OK_PTR(nstoken, "open clien ns")) { 519 SYS_NOFAIL("tc qdisc delete dev veth2 parent ffff:fff1"); 520 SYS_NOFAIL("ip a flush veth2"); 521 if (!cfg->expect_kern_decap_failure) 522 remove_kernel_decapsulation(cfg); 523 close_netns(nstoken); 524 } 525 } 526 527 static void cleanup(void) 528 { 529 remove_netns(CLIENT_NS); 530 remove_netns(SERVER_NS); 531 } 532 533 static struct subtest_cfg subtests_cfg[] = { 534 { 535 .ebpf_tun_type = "ipip", 536 .mac_tun_type = "none", 537 .iproute_tun_type = "ipip", 538 .ipproto = 4, 539 }, 540 { 541 .ebpf_tun_type = "ipip6", 542 .mac_tun_type = "none", 543 .iproute_tun_type = "ip6tnl", 544 .ipproto = 4, 545 .tunnel_client_addr = IP6_ADDR_VETH1, 546 .tunnel_server_addr = IP6_ADDR_VETH2, 547 }, 548 { 549 .ebpf_tun_type = "ip6tnl", 550 .iproute_tun_type = "ip6tnl", 551 .mac_tun_type = "none", 552 .ipproto = 6, 553 }, 554 { 555 .mac_tun_type = "none", 556 .ebpf_tun_type = "sit", 557 .iproute_tun_type = "sit", 558 .ipproto = 6, 559 .tunnel_client_addr = IP4_ADDR_VETH1, 560 .tunnel_server_addr = IP4_ADDR_VETH2, 561 }, 562 { 563 .ebpf_tun_type = "vxlan", 564 .mac_tun_type = "eth", 565 .iproute_tun_type = "vxlan", 566 .ipproto = 4, 567 .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb, 568 .tunnel_need_veth_mac = true 569 }, 570 { 571 .ebpf_tun_type = "ip6vxlan", 572 .mac_tun_type = "eth", 573 .iproute_tun_type = "vxlan", 574 .ipproto = 6, 575 .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb, 576 .tunnel_need_veth_mac = true 577 }, 578 { 579 .ebpf_tun_type = "gre", 580 .mac_tun_type = "none", 581 .iproute_tun_type = "gre", 582 .ipproto = 4, 583 .test_gso = true 584 }, 585 { 586 .ebpf_tun_type = "gre", 587 .mac_tun_type = "eth", 588 .iproute_tun_type = "gretap", 589 .ipproto = 4, 590 .tunnel_need_veth_mac = true, 591 .test_gso = true 592 }, 593 { 594 .ebpf_tun_type = "gre", 595 .mac_tun_type = "mpls", 596 .iproute_tun_type = "gre", 597 .ipproto = 4, 598 .configure_mpls = true, 599 .test_gso = true 600 }, 601 { 602 .ebpf_tun_type = "ip6gre", 603 .mac_tun_type = "none", 604 .iproute_tun_type = "ip6gre", 605 .ipproto = 6, 606 .test_gso = true, 607 }, 608 { 609 .ebpf_tun_type = "ip6gre", 610 .mac_tun_type = "eth", 611 .iproute_tun_type = "ip6gretap", 612 .ipproto = 6, 613 .tunnel_need_veth_mac = true, 614 .test_gso = true 615 }, 616 { 617 .ebpf_tun_type = "ip6gre", 618 .mac_tun_type = "mpls", 619 .iproute_tun_type = "ip6gre", 620 .ipproto = 6, 621 .configure_mpls = true, 622 .test_gso = true 623 }, 624 { 625 .ebpf_tun_type = "udp", 626 .mac_tun_type = "none", 627 .iproute_tun_type = "ipip", 628 .ipproto = 4, 629 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 630 .configure_fou_rx_port = true, 631 .test_gso = true 632 }, 633 { 634 .ebpf_tun_type = "udp", 635 .mac_tun_type = "eth", 636 .iproute_tun_type = "ipip", 637 .ipproto = 4, 638 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 639 .configure_fou_rx_port = true, 640 .expect_kern_decap_failure = true, 641 .test_gso = true 642 }, 643 { 644 .ebpf_tun_type = "udp", 645 .mac_tun_type = "mpls", 646 .iproute_tun_type = "ipip", 647 .ipproto = 4, 648 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 649 .configure_fou_rx_port = true, 650 .tmode = "mode any ttl 255", 651 .configure_mpls = true, 652 .test_gso = true 653 }, 654 { 655 .ebpf_tun_type = "ip6udp", 656 .mac_tun_type = "none", 657 .iproute_tun_type = "ip6tnl", 658 .ipproto = 6, 659 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 660 .configure_fou_rx_port = true, 661 .test_gso = true 662 }, 663 { 664 .ebpf_tun_type = "ip6udp", 665 .mac_tun_type = "eth", 666 .iproute_tun_type = "ip6tnl", 667 .ipproto = 6, 668 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 669 .configure_fou_rx_port = true, 670 .expect_kern_decap_failure = true, 671 .test_gso = true 672 }, 673 { 674 .ebpf_tun_type = "ip6udp", 675 .mac_tun_type = "mpls", 676 .iproute_tun_type = "ip6tnl", 677 .ipproto = 6, 678 .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 679 .configure_fou_rx_port = true, 680 .tmode = "mode any ttl 255", 681 .expect_kern_decap_failure = true, 682 .test_gso = true 683 }, 684 }; 685 686 void test_tc_tunnel(void) 687 { 688 struct test_tc_tunnel *skel; 689 struct subtest_cfg *cfg; 690 int i, ret; 691 692 skel = test_tc_tunnel__open_and_load(); 693 if (!ASSERT_OK_PTR(skel, "skel open and load")) 694 return; 695 696 if (!ASSERT_OK(setup(), "global setup")) 697 goto out; 698 699 for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) { 700 cfg = &subtests_cfg[i]; 701 ret = build_subtest_name(cfg, cfg->name, TEST_NAME_MAX_LEN); 702 if (ret < 0 || !test__start_subtest(cfg->name)) 703 continue; 704 if (subtest_setup(skel, cfg) == 0) 705 run_test(cfg); 706 subtest_cleanup(cfg); 707 } 708 cleanup(); 709 710 out: 711 test_tc_tunnel__destroy(skel); 712 } 713