Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Integrate test_tc_tunnel.sh tests into test_progs

The test_tc_tunnel.sh script checks that a large variety of tunneling
mechanisms handled by the kernel can be handled as well by eBPF
programs. While this test shares similarities with test_tunnel.c (which
is already integrated in test_progs), those are testing slightly
different things:
- test_tunnel.c creates a tunnel interface, and then get and set tunnel
keys in packet metadata, from BPF programs.
- test_tc_tunnels.sh manually parses/crafts packets content

Bring the tests covered by test_tc_tunnel.sh into the test_progs
framework, by creating a dedicated test_tc_tunnel.sh. This new test
defines a "generic" runner which, for each test configuration:
- will configure the relevant veth pair, each of those isolated in a
dedicated namespace
- will check that traffic will fail if there is only an encapsulating
program attached to one veth egress
- will check that traffic succeed if we enable some decapsulation module
on kernel side
- will check that traffic still succeeds if we replace the kernel
decapsulation with some eBPF ingress decapsulation.

Example of the new test execution:

# ./test_progs -a tc_tunnel
#447/1 tc_tunnel/ipip_none:OK
#447/2 tc_tunnel/ipip6_none:OK
#447/3 tc_tunnel/ip6tnl_none:OK
#447/4 tc_tunnel/sit_none:OK
#447/5 tc_tunnel/vxlan_eth:OK
#447/6 tc_tunnel/ip6vxlan_eth:OK
#447/7 tc_tunnel/gre_none:OK
#447/8 tc_tunnel/gre_eth:OK
#447/9 tc_tunnel/gre_mpls:OK
#447/10 tc_tunnel/ip6gre_none:OK
#447/11 tc_tunnel/ip6gre_eth:OK
#447/12 tc_tunnel/ip6gre_mpls:OK
#447/13 tc_tunnel/udp_none:OK
#447/14 tc_tunnel/udp_eth:OK
#447/15 tc_tunnel/udp_mpls:OK
#447/16 tc_tunnel/ip6udp_none:OK
#447/17 tc_tunnel/ip6udp_eth:OK
#447/18 tc_tunnel/ip6udp_mpls:OK
#447 tc_tunnel:OK
Summary: 1/18 PASSED, 0 SKIPPED, 0 FAILED

Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20251027-tc_tunnel-v3-3-505c12019f9d@bootlin.com

authored by

Alexis Lothoré (eBPF Foundation) and committed by
Martin KaFai Lau
8517b1ab 86433db9

+693 -19
+674
tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c
··· 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 + struct nstoken *nstoken = open_netns(SERVER_NS); 137 + int family = cfg->ipproto == 6 ? AF_INET6 : AF_INET; 138 + 139 + cfg->server_fd = start_reuseport_server(family, SOCK_STREAM, 140 + cfg->server_addr, TEST_PORT, 141 + TIMEOUT_MS, 1); 142 + close_netns(nstoken); 143 + if (!ASSERT_OK_PTR(cfg->server_fd, "start server")) 144 + return -1; 145 + 146 + return 0; 147 + } 148 + 149 + static void stop_server(struct subtest_cfg *cfg) 150 + { 151 + free_fds(cfg->server_fd, 1); 152 + } 153 + 154 + static int check_server_rx_data(struct subtest_cfg *cfg, 155 + struct connection *conn, int len) 156 + { 157 + int err; 158 + 159 + memset(rx_buffer, 0, BUFFER_LEN); 160 + err = recv(conn->server_fd, rx_buffer, len, 0); 161 + if (!ASSERT_EQ(err, len, "check rx data len")) 162 + return 1; 163 + if (!ASSERT_MEMEQ(tx_buffer, rx_buffer, len, "check received data")) 164 + return 1; 165 + return 0; 166 + } 167 + 168 + static struct connection *connect_client_to_server(struct subtest_cfg *cfg) 169 + { 170 + struct network_helper_opts opts = {.timeout_ms = 500}; 171 + int family = cfg->ipproto == 6 ? AF_INET6 : AF_INET; 172 + struct connection *conn = NULL; 173 + int client_fd, server_fd; 174 + 175 + conn = malloc(sizeof(struct connection)); 176 + if (!conn) 177 + return conn; 178 + 179 + client_fd = connect_to_addr_str(family, SOCK_STREAM, cfg->server_addr, 180 + TEST_PORT, &opts); 181 + 182 + if (client_fd < 0) { 183 + free(conn); 184 + return NULL; 185 + } 186 + 187 + server_fd = accept(*cfg->server_fd, NULL, NULL); 188 + if (server_fd < 0) { 189 + close(client_fd); 190 + free(conn); 191 + return NULL; 192 + } 193 + 194 + conn->server_fd = server_fd; 195 + conn->client_fd = client_fd; 196 + 197 + return conn; 198 + } 199 + 200 + static void disconnect_client_from_server(struct subtest_cfg *cfg, 201 + struct connection *conn) 202 + { 203 + close(conn->server_fd); 204 + close(conn->client_fd); 205 + free(conn); 206 + } 207 + 208 + static int send_and_test_data(struct subtest_cfg *cfg, bool must_succeed) 209 + { 210 + struct connection *conn; 211 + int err, res = -1; 212 + 213 + conn = connect_client_to_server(cfg); 214 + if (!must_succeed && !ASSERT_ERR_PTR(conn, "connection that must fail")) 215 + goto end; 216 + else if (!must_succeed) 217 + return 0; 218 + 219 + if (!ASSERT_OK_PTR(conn, "connection that must succeed")) 220 + return -1; 221 + 222 + err = send(conn->client_fd, tx_buffer, DEFAULT_TEST_DATA_SIZE, 0); 223 + if (!ASSERT_EQ(err, DEFAULT_TEST_DATA_SIZE, "send data from client")) 224 + goto end; 225 + if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE)) 226 + goto end; 227 + 228 + if (!cfg->test_gso) { 229 + res = 0; 230 + goto end; 231 + } 232 + 233 + err = send(conn->client_fd, tx_buffer, GSO_TEST_DATA_SIZE, 0); 234 + if (!ASSERT_EQ(err, GSO_TEST_DATA_SIZE, "send (large) data from client")) 235 + goto end; 236 + if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE)) 237 + goto end; 238 + 239 + res = 0; 240 + end: 241 + disconnect_client_from_server(cfg, conn); 242 + return res; 243 + } 244 + 245 + static void vxlan_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst) 246 + { 247 + snprintf(dst, TUNNEL_ARGS_MAX_LEN, "id %d dstport %d udp6zerocsumrx", 248 + VXLAN_ID, VXLAN_PORT); 249 + } 250 + 251 + static void udp_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst) 252 + { 253 + bool is_mpls = !strcmp(cfg->mac_tun_type, "mpls"); 254 + 255 + snprintf(dst, TUNNEL_ARGS_MAX_LEN, 256 + "encap fou encap-sport auto encap-dport %d", 257 + is_mpls ? MPLS_UDP_PORT : UDP_PORT); 258 + } 259 + 260 + static int configure_fou_rx_port(struct subtest_cfg *cfg, bool add) 261 + { 262 + bool is_mpls = strcmp(cfg->mac_tun_type, "mpls") == 0; 263 + int fou_proto; 264 + 265 + if (is_mpls) 266 + fou_proto = FOU_MPLS_PROTO; 267 + else 268 + fou_proto = cfg->ipproto == 6 ? 41 : 4; 269 + 270 + SYS(fail, "ip fou %s port %d ipproto %d%s", add ? "add" : "del", 271 + is_mpls ? MPLS_UDP_PORT : UDP_PORT, fou_proto, 272 + cfg->ipproto == 6 ? " -6" : ""); 273 + 274 + return 0; 275 + fail: 276 + return 1; 277 + } 278 + 279 + static int add_fou_rx_port(struct subtest_cfg *cfg) 280 + { 281 + return configure_fou_rx_port(cfg, true); 282 + } 283 + 284 + static int del_fou_rx_port(struct subtest_cfg *cfg) 285 + { 286 + return configure_fou_rx_port(cfg, false); 287 + } 288 + 289 + static int update_tunnel_intf_addr(struct subtest_cfg *cfg) 290 + { 291 + SYS(fail, "ip link set dev testtun0 address " MAC_ADDR_VETH2); 292 + return 0; 293 + fail: 294 + return -1; 295 + } 296 + 297 + static int configure_kernel_for_mpls(struct subtest_cfg *cfg) 298 + { 299 + SYS(fail, "sysctl -qw net.mpls.platform_labels=%d", 300 + MPLS_TABLE_ENTRIES_COUNT); 301 + SYS(fail, "ip -f mpls route add 1000 dev lo"); 302 + SYS(fail, "ip link set lo up"); 303 + SYS(fail, "sysctl -qw net.mpls.conf.testtun0.input=1"); 304 + SYS(fail, "sysctl -qw net.ipv4.conf.lo.rp_filter=0"); 305 + return 0; 306 + fail: 307 + return -1; 308 + } 309 + 310 + static int configure_encapsulation(struct subtest_cfg *cfg) 311 + { 312 + int ret; 313 + 314 + ret = tc_prog_attach("veth1", -1, cfg->client_egress_prog_fd); 315 + 316 + return ret; 317 + } 318 + 319 + static int configure_kernel_decapsulation(struct subtest_cfg *cfg) 320 + { 321 + struct nstoken *nstoken = open_netns(SERVER_NS); 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 + close_netns(nstoken); 341 + return 0; 342 + fail: 343 + close_netns(nstoken); 344 + return -1; 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 + 360 + if (!cfg->expect_kern_decap_failure) 361 + SYS(fail, "ip link del testtun0"); 362 + 363 + if (!ASSERT_OK(tc_prog_attach("veth2", cfg->server_ingress_prog_fd, -1), 364 + "attach_program")) 365 + goto fail; 366 + close_netns(nstoken); 367 + return 0; 368 + fail: 369 + close_netns(nstoken); 370 + return -1; 371 + } 372 + 373 + static void run_test(struct subtest_cfg *cfg) 374 + { 375 + struct nstoken *nstoken = open_netns(CLIENT_NS); 376 + 377 + if (!ASSERT_OK(run_server(cfg), "run server")) 378 + goto fail; 379 + 380 + /* Basic communication must work */ 381 + if (!ASSERT_OK(send_and_test_data(cfg, true), "connect without any encap")) 382 + goto fail; 383 + 384 + /* Attach encapsulation program to client */ 385 + if (!ASSERT_OK(configure_encapsulation(cfg), "configure encapsulation")) 386 + goto fail; 387 + 388 + /* If supported, insert kernel decap module, connection must succeed */ 389 + if (!cfg->expect_kern_decap_failure) { 390 + if (!ASSERT_OK(configure_kernel_decapsulation(cfg), 391 + "configure kernel decapsulation")) 392 + goto fail; 393 + if (!ASSERT_OK(send_and_test_data(cfg, true), 394 + "connect with encap prog and kern decap")) 395 + goto fail; 396 + } 397 + 398 + /* Replace kernel decapsulation with BPF decapsulation, test must pass */ 399 + if (!ASSERT_OK(configure_ebpf_decapsulation(cfg), "configure ebpf decapsulation")) 400 + goto fail; 401 + ASSERT_OK(send_and_test_data(cfg, true), "connect with encap and decap progs"); 402 + 403 + fail: 404 + stop_server(cfg); 405 + close_netns(nstoken); 406 + } 407 + 408 + static int setup(void) 409 + { 410 + struct nstoken *nstoken = NULL; 411 + int fd, err; 412 + 413 + fd = open("/dev/urandom", O_RDONLY); 414 + if (!ASSERT_OK_FD(fd, "open urandom")) 415 + goto fail; 416 + err = read(fd, tx_buffer, BUFFER_LEN); 417 + close(fd); 418 + 419 + if (!ASSERT_EQ(err, BUFFER_LEN, "read random bytes")) 420 + goto fail; 421 + 422 + /* Configure the testing network */ 423 + if (!ASSERT_OK(make_netns(CLIENT_NS), "create client ns") || 424 + !ASSERT_OK(make_netns(SERVER_NS), "create server ns")) 425 + goto fail; 426 + 427 + nstoken = open_netns(CLIENT_NS); 428 + SYS(fail, "ip link add %s type veth peer name %s", 429 + "veth1 mtu 1500 netns " CLIENT_NS " address " MAC_ADDR_VETH1, 430 + "veth2 mtu 1500 netns " SERVER_NS " address " MAC_ADDR_VETH2); 431 + SYS(fail, "ethtool -K veth1 tso off"); 432 + SYS(fail, "ip link set veth1 up"); 433 + close_netns(nstoken); 434 + nstoken = open_netns(SERVER_NS); 435 + SYS(fail, "ip link set veth2 up"); 436 + close_netns(nstoken); 437 + 438 + return 0; 439 + fail: 440 + close_netns(nstoken); 441 + return 1; 442 + } 443 + 444 + static int subtest_setup(struct test_tc_tunnel *skel, struct subtest_cfg *cfg) 445 + { 446 + struct nstoken *nstoken; 447 + 448 + set_subtest_addresses(cfg); 449 + if (!ASSERT_OK(set_subtest_progs(cfg, skel), 450 + "find subtest progs")) 451 + return -1; 452 + if (cfg->extra_decap_mod_args_cb) 453 + cfg->extra_decap_mod_args_cb(cfg, cfg->extra_decap_mod_args); 454 + 455 + nstoken = open_netns(CLIENT_NS); 456 + SYS(fail, "ip -4 addr add " IP4_ADDR_VETH1 "/24 dev veth1"); 457 + SYS(fail, "ip -4 route flush table main"); 458 + SYS(fail, "ip -4 route add " IP4_ADDR_VETH2 " mtu 1450 dev veth1"); 459 + SYS(fail, "ip -6 addr add " IP6_ADDR_VETH1 "/64 dev veth1 nodad"); 460 + SYS(fail, "ip -6 route flush table main"); 461 + SYS(fail, "ip -6 route add " IP6_ADDR_VETH2 " mtu 1430 dev veth1"); 462 + close_netns(nstoken); 463 + 464 + nstoken = open_netns(SERVER_NS); 465 + SYS(fail, "ip -4 addr add " IP4_ADDR_VETH2 "/24 dev veth2"); 466 + SYS(fail, "ip -6 addr add " IP6_ADDR_VETH2 "/64 dev veth2 nodad"); 467 + close_netns(nstoken); 468 + 469 + return 0; 470 + fail: 471 + close_netns(nstoken); 472 + return -1; 473 + } 474 + 475 + 476 + static void subtest_cleanup(struct subtest_cfg *cfg) 477 + { 478 + struct nstoken *nstoken; 479 + 480 + nstoken = open_netns(CLIENT_NS); 481 + SYS_NOFAIL("tc qdisc delete dev veth1 parent ffff:fff1"); 482 + SYS_NOFAIL("ip a flush veth1"); 483 + close_netns(nstoken); 484 + nstoken = open_netns(SERVER_NS); 485 + SYS_NOFAIL("tc qdisc delete dev veth2 parent ffff:fff1"); 486 + SYS_NOFAIL("ip a flush veth2"); 487 + if (!cfg->expect_kern_decap_failure) 488 + remove_kernel_decapsulation(cfg); 489 + close_netns(nstoken); 490 + } 491 + 492 + static void cleanup(void) 493 + { 494 + remove_netns(CLIENT_NS); 495 + remove_netns(SERVER_NS); 496 + } 497 + 498 + static struct subtest_cfg subtests_cfg[] = { 499 + { 500 + .ebpf_tun_type = "ipip", 501 + .mac_tun_type = "none", 502 + .iproute_tun_type = "ipip", 503 + .ipproto = 4, 504 + }, 505 + { 506 + .ebpf_tun_type = "ipip6", 507 + .mac_tun_type = "none", 508 + .iproute_tun_type = "ip6tnl", 509 + .ipproto = 4, 510 + .tunnel_client_addr = IP6_ADDR_VETH1, 511 + .tunnel_server_addr = IP6_ADDR_VETH2, 512 + }, 513 + { 514 + .ebpf_tun_type = "ip6tnl", 515 + .iproute_tun_type = "ip6tnl", 516 + .mac_tun_type = "none", 517 + .ipproto = 6, 518 + }, 519 + { 520 + .mac_tun_type = "none", 521 + .ebpf_tun_type = "sit", 522 + .iproute_tun_type = "sit", 523 + .ipproto = 6, 524 + .tunnel_client_addr = IP4_ADDR_VETH1, 525 + .tunnel_server_addr = IP4_ADDR_VETH2, 526 + }, 527 + { 528 + .ebpf_tun_type = "vxlan", 529 + .mac_tun_type = "eth", 530 + .iproute_tun_type = "vxlan", 531 + .ipproto = 4, 532 + .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb, 533 + .tunnel_need_veth_mac = true 534 + }, 535 + { 536 + .ebpf_tun_type = "ip6vxlan", 537 + .mac_tun_type = "eth", 538 + .iproute_tun_type = "vxlan", 539 + .ipproto = 6, 540 + .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb, 541 + .tunnel_need_veth_mac = true 542 + }, 543 + { 544 + .ebpf_tun_type = "gre", 545 + .mac_tun_type = "none", 546 + .iproute_tun_type = "gre", 547 + .ipproto = 4, 548 + .test_gso = true 549 + }, 550 + { 551 + .ebpf_tun_type = "gre", 552 + .mac_tun_type = "eth", 553 + .iproute_tun_type = "gretap", 554 + .ipproto = 4, 555 + .tunnel_need_veth_mac = true, 556 + .test_gso = true 557 + }, 558 + { 559 + .ebpf_tun_type = "gre", 560 + .mac_tun_type = "mpls", 561 + .iproute_tun_type = "gre", 562 + .ipproto = 4, 563 + .configure_mpls = true, 564 + .test_gso = true 565 + }, 566 + { 567 + .ebpf_tun_type = "ip6gre", 568 + .mac_tun_type = "none", 569 + .iproute_tun_type = "ip6gre", 570 + .ipproto = 6, 571 + .test_gso = true, 572 + }, 573 + { 574 + .ebpf_tun_type = "ip6gre", 575 + .mac_tun_type = "eth", 576 + .iproute_tun_type = "ip6gretap", 577 + .ipproto = 6, 578 + .tunnel_need_veth_mac = true, 579 + .test_gso = true 580 + }, 581 + { 582 + .ebpf_tun_type = "ip6gre", 583 + .mac_tun_type = "mpls", 584 + .iproute_tun_type = "ip6gre", 585 + .ipproto = 6, 586 + .configure_mpls = true, 587 + .test_gso = true 588 + }, 589 + { 590 + .ebpf_tun_type = "udp", 591 + .mac_tun_type = "none", 592 + .iproute_tun_type = "ipip", 593 + .ipproto = 4, 594 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 595 + .configure_fou_rx_port = true, 596 + .test_gso = true 597 + }, 598 + { 599 + .ebpf_tun_type = "udp", 600 + .mac_tun_type = "eth", 601 + .iproute_tun_type = "ipip", 602 + .ipproto = 4, 603 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 604 + .configure_fou_rx_port = true, 605 + .expect_kern_decap_failure = true, 606 + .test_gso = true 607 + }, 608 + { 609 + .ebpf_tun_type = "udp", 610 + .mac_tun_type = "mpls", 611 + .iproute_tun_type = "ipip", 612 + .ipproto = 4, 613 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 614 + .configure_fou_rx_port = true, 615 + .tmode = "mode any ttl 255", 616 + .configure_mpls = true, 617 + .test_gso = true 618 + }, 619 + { 620 + .ebpf_tun_type = "ip6udp", 621 + .mac_tun_type = "none", 622 + .iproute_tun_type = "ip6tnl", 623 + .ipproto = 6, 624 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 625 + .configure_fou_rx_port = true, 626 + .test_gso = true 627 + }, 628 + { 629 + .ebpf_tun_type = "ip6udp", 630 + .mac_tun_type = "eth", 631 + .iproute_tun_type = "ip6tnl", 632 + .ipproto = 6, 633 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 634 + .configure_fou_rx_port = true, 635 + .expect_kern_decap_failure = true, 636 + .test_gso = true 637 + }, 638 + { 639 + .ebpf_tun_type = "ip6udp", 640 + .mac_tun_type = "mpls", 641 + .iproute_tun_type = "ip6tnl", 642 + .ipproto = 6, 643 + .extra_decap_mod_args_cb = udp_decap_mod_args_cb, 644 + .configure_fou_rx_port = true, 645 + .tmode = "mode any ttl 255", 646 + .expect_kern_decap_failure = true, 647 + .test_gso = true 648 + }, 649 + }; 650 + 651 + void test_tc_tunnel(void) 652 + { 653 + struct test_tc_tunnel *skel; 654 + struct subtest_cfg *cfg; 655 + int i, ret; 656 + 657 + skel = test_tc_tunnel__open_and_load(); 658 + if (!ASSERT_OK_PTR(skel, "skel open and load")) 659 + return; 660 + 661 + if (!ASSERT_OK(setup(), "global setup")) 662 + return; 663 + 664 + for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) { 665 + cfg = &subtests_cfg[i]; 666 + ret = build_subtest_name(cfg, cfg->name, TEST_NAME_MAX_LEN); 667 + if (ret < 0 || !test__start_subtest(cfg->name)) 668 + continue; 669 + subtest_setup(skel, cfg); 670 + run_test(cfg); 671 + subtest_cleanup(cfg); 672 + } 673 + cleanup(); 674 + }
+19 -19
tools/testing/selftests/bpf/progs/test_tc_tunnel.c
··· 418 418 return __encap_ipv6(skb, encap_proto, l2_proto, 0); 419 419 } 420 420 421 - SEC("encap_ipip_none") 421 + SEC("tc") 422 422 int __encap_ipip_none(struct __sk_buff *skb) 423 423 { 424 424 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 427 427 return TC_ACT_OK; 428 428 } 429 429 430 - SEC("encap_gre_none") 430 + SEC("tc") 431 431 int __encap_gre_none(struct __sk_buff *skb) 432 432 { 433 433 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 436 436 return TC_ACT_OK; 437 437 } 438 438 439 - SEC("encap_gre_mpls") 439 + SEC("tc") 440 440 int __encap_gre_mpls(struct __sk_buff *skb) 441 441 { 442 442 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 445 445 return TC_ACT_OK; 446 446 } 447 447 448 - SEC("encap_gre_eth") 448 + SEC("tc") 449 449 int __encap_gre_eth(struct __sk_buff *skb) 450 450 { 451 451 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 454 454 return TC_ACT_OK; 455 455 } 456 456 457 - SEC("encap_udp_none") 457 + SEC("tc") 458 458 int __encap_udp_none(struct __sk_buff *skb) 459 459 { 460 460 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 463 463 return TC_ACT_OK; 464 464 } 465 465 466 - SEC("encap_udp_mpls") 466 + SEC("tc") 467 467 int __encap_udp_mpls(struct __sk_buff *skb) 468 468 { 469 469 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 472 472 return TC_ACT_OK; 473 473 } 474 474 475 - SEC("encap_udp_eth") 475 + SEC("tc") 476 476 int __encap_udp_eth(struct __sk_buff *skb) 477 477 { 478 478 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 481 481 return TC_ACT_OK; 482 482 } 483 483 484 - SEC("encap_vxlan_eth") 484 + SEC("tc") 485 485 int __encap_vxlan_eth(struct __sk_buff *skb) 486 486 { 487 487 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 492 492 return TC_ACT_OK; 493 493 } 494 494 495 - SEC("encap_sit_none") 495 + SEC("tc") 496 496 int __encap_sit_none(struct __sk_buff *skb) 497 497 { 498 498 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 501 501 return TC_ACT_OK; 502 502 } 503 503 504 - SEC("encap_ip6tnl_none") 504 + SEC("tc") 505 505 int __encap_ip6tnl_none(struct __sk_buff *skb) 506 506 { 507 507 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 510 510 return TC_ACT_OK; 511 511 } 512 512 513 - SEC("encap_ipip6_none") 513 + SEC("tc") 514 514 int __encap_ipip6_none(struct __sk_buff *skb) 515 515 { 516 516 if (skb->protocol == __bpf_constant_htons(ETH_P_IP)) ··· 519 519 return TC_ACT_OK; 520 520 } 521 521 522 - SEC("encap_ip6gre_none") 522 + SEC("tc") 523 523 int __encap_ip6gre_none(struct __sk_buff *skb) 524 524 { 525 525 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 528 528 return TC_ACT_OK; 529 529 } 530 530 531 - SEC("encap_ip6gre_mpls") 531 + SEC("tc") 532 532 int __encap_ip6gre_mpls(struct __sk_buff *skb) 533 533 { 534 534 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 537 537 return TC_ACT_OK; 538 538 } 539 539 540 - SEC("encap_ip6gre_eth") 540 + SEC("tc") 541 541 int __encap_ip6gre_eth(struct __sk_buff *skb) 542 542 { 543 543 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 546 546 return TC_ACT_OK; 547 547 } 548 548 549 - SEC("encap_ip6udp_none") 549 + SEC("tc") 550 550 int __encap_ip6udp_none(struct __sk_buff *skb) 551 551 { 552 552 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 555 555 return TC_ACT_OK; 556 556 } 557 557 558 - SEC("encap_ip6udp_mpls") 558 + SEC("tc") 559 559 int __encap_ip6udp_mpls(struct __sk_buff *skb) 560 560 { 561 561 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 564 564 return TC_ACT_OK; 565 565 } 566 566 567 - SEC("encap_ip6udp_eth") 567 + SEC("tc") 568 568 int __encap_ip6udp_eth(struct __sk_buff *skb) 569 569 { 570 570 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 573 573 return TC_ACT_OK; 574 574 } 575 575 576 - SEC("encap_ip6vxlan_eth") 576 + SEC("tc") 577 577 int __encap_ip6vxlan_eth(struct __sk_buff *skb) 578 578 { 579 579 if (skb->protocol == __bpf_constant_htons(ETH_P_IPV6)) ··· 680 680 iph_outer.nexthdr); 681 681 } 682 682 683 - SEC("decap") 683 + SEC("tc") 684 684 int decap_f(struct __sk_buff *skb) 685 685 { 686 686 switch (skb->protocol) {