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
build_subtest_name(struct subtest_cfg * cfg,char * dst,size_t size)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
set_subtest_progs(struct subtest_cfg * cfg,struct test_tc_tunnel * skel)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
set_subtest_addresses(struct subtest_cfg * cfg)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
run_server(struct subtest_cfg * cfg)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
check_server_rx_data(struct subtest_cfg * cfg,struct connection * conn,int len)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
connect_client_to_server(struct subtest_cfg * cfg)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
disconnect_client_from_server(struct subtest_cfg * cfg,struct connection * conn)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
send_and_test_data(struct subtest_cfg * cfg)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
vxlan_decap_mod_args_cb(struct subtest_cfg * cfg,char * dst)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
udp_decap_mod_args_cb(struct subtest_cfg * cfg,char * dst)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
configure_fou_rx_port(struct subtest_cfg * cfg,bool add)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
add_fou_rx_port(struct subtest_cfg * cfg)275 static int add_fou_rx_port(struct subtest_cfg *cfg)
276 {
277 return configure_fou_rx_port(cfg, true);
278 }
279
del_fou_rx_port(struct subtest_cfg * cfg)280 static int del_fou_rx_port(struct subtest_cfg *cfg)
281 {
282 return configure_fou_rx_port(cfg, false);
283 }
284
update_tunnel_intf_addr(struct subtest_cfg * cfg)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
configure_kernel_for_mpls(struct subtest_cfg * cfg)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
configure_encapsulation(struct subtest_cfg * cfg)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
configure_kernel_decapsulation(struct subtest_cfg * cfg)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
remove_kernel_decapsulation(struct subtest_cfg * cfg)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
configure_ebpf_decapsulation(struct subtest_cfg * cfg)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
run_test(struct subtest_cfg * cfg)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
setup(void)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, "ip link set veth1 up");
442 nstoken_server = open_netns(SERVER_NS);
443 if (!ASSERT_OK_PTR(nstoken_server, "open server ns"))
444 goto fail_close_ns_client;
445 SYS(fail_close_ns_server, "ip link set veth2 up");
446
447 close_netns(nstoken_server);
448 close_netns(nstoken_client);
449 return 0;
450
451 fail_close_ns_server:
452 close_netns(nstoken_server);
453 fail_close_ns_client:
454 close_netns(nstoken_client);
455 fail_delete_ns:
456 SYS_NOFAIL("ip netns del " CLIENT_NS);
457 SYS_NOFAIL("ip netns del " SERVER_NS);
458 fail:
459 return -1;
460 }
461
subtest_setup(struct test_tc_tunnel * skel,struct subtest_cfg * cfg)462 static int subtest_setup(struct test_tc_tunnel *skel, struct subtest_cfg *cfg)
463 {
464 struct nstoken *nstoken_client, *nstoken_server;
465 int ret = -1;
466
467 set_subtest_addresses(cfg);
468 if (!ASSERT_OK(set_subtest_progs(cfg, skel),
469 "find subtest progs"))
470 goto fail;
471 if (cfg->extra_decap_mod_args_cb)
472 cfg->extra_decap_mod_args_cb(cfg, cfg->extra_decap_mod_args);
473
474 nstoken_client = open_netns(CLIENT_NS);
475 if (!ASSERT_OK_PTR(nstoken_client, "open client ns"))
476 goto fail;
477 SYS(fail_close_client_ns,
478 "ip -4 addr add " IP4_ADDR_VETH1 "/24 dev veth1");
479 SYS(fail_close_client_ns, "ip -4 route flush table main");
480 SYS(fail_close_client_ns,
481 "ip -4 route add " IP4_ADDR_VETH2 " mtu 1450 dev veth1");
482 SYS(fail_close_client_ns,
483 "ip -6 addr add " IP6_ADDR_VETH1 "/64 dev veth1 nodad");
484 SYS(fail_close_client_ns, "ip -6 route flush table main");
485 SYS(fail_close_client_ns,
486 "ip -6 route add " IP6_ADDR_VETH2 " mtu 1430 dev veth1");
487 nstoken_server = open_netns(SERVER_NS);
488 if (!ASSERT_OK_PTR(nstoken_server, "open server ns"))
489 goto fail_close_client_ns;
490 SYS(fail_close_server_ns,
491 "ip -4 addr add " IP4_ADDR_VETH2 "/24 dev veth2");
492 SYS(fail_close_server_ns,
493 "ip -6 addr add " IP6_ADDR_VETH2 "/64 dev veth2 nodad");
494
495 ret = 0;
496
497 fail_close_server_ns:
498 close_netns(nstoken_server);
499 fail_close_client_ns:
500 close_netns(nstoken_client);
501 fail:
502 return ret;
503 }
504
505
subtest_cleanup(struct subtest_cfg * cfg)506 static void subtest_cleanup(struct subtest_cfg *cfg)
507 {
508 struct nstoken *nstoken;
509
510 nstoken = open_netns(CLIENT_NS);
511 if (ASSERT_OK_PTR(nstoken, "open clien ns")) {
512 SYS_NOFAIL("tc qdisc delete dev veth1 parent ffff:fff1");
513 SYS_NOFAIL("ip a flush veth1");
514 close_netns(nstoken);
515 }
516 nstoken = open_netns(SERVER_NS);
517 if (ASSERT_OK_PTR(nstoken, "open clien ns")) {
518 SYS_NOFAIL("tc qdisc delete dev veth2 parent ffff:fff1");
519 SYS_NOFAIL("ip a flush veth2");
520 if (!cfg->expect_kern_decap_failure)
521 remove_kernel_decapsulation(cfg);
522 close_netns(nstoken);
523 }
524 }
525
cleanup(void)526 static void cleanup(void)
527 {
528 remove_netns(CLIENT_NS);
529 remove_netns(SERVER_NS);
530 }
531
532 static struct subtest_cfg subtests_cfg[] = {
533 {
534 .ebpf_tun_type = "ipip",
535 .mac_tun_type = "none",
536 .iproute_tun_type = "ipip",
537 .ipproto = 4,
538 },
539 {
540 .ebpf_tun_type = "ipip6",
541 .mac_tun_type = "none",
542 .iproute_tun_type = "ip6tnl",
543 .ipproto = 4,
544 .tunnel_client_addr = IP6_ADDR_VETH1,
545 .tunnel_server_addr = IP6_ADDR_VETH2,
546 },
547 {
548 .ebpf_tun_type = "ip6tnl",
549 .iproute_tun_type = "ip6tnl",
550 .mac_tun_type = "none",
551 .ipproto = 6,
552 },
553 {
554 .mac_tun_type = "none",
555 .ebpf_tun_type = "sit",
556 .iproute_tun_type = "sit",
557 .ipproto = 6,
558 .tunnel_client_addr = IP4_ADDR_VETH1,
559 .tunnel_server_addr = IP4_ADDR_VETH2,
560 },
561 {
562 .ebpf_tun_type = "vxlan",
563 .mac_tun_type = "eth",
564 .iproute_tun_type = "vxlan",
565 .ipproto = 4,
566 .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb,
567 .tunnel_need_veth_mac = true
568 },
569 {
570 .ebpf_tun_type = "ip6vxlan",
571 .mac_tun_type = "eth",
572 .iproute_tun_type = "vxlan",
573 .ipproto = 6,
574 .extra_decap_mod_args_cb = vxlan_decap_mod_args_cb,
575 .tunnel_need_veth_mac = true
576 },
577 {
578 .ebpf_tun_type = "gre",
579 .mac_tun_type = "none",
580 .iproute_tun_type = "gre",
581 .ipproto = 4,
582 .test_gso = true
583 },
584 {
585 .ebpf_tun_type = "gre",
586 .mac_tun_type = "eth",
587 .iproute_tun_type = "gretap",
588 .ipproto = 4,
589 .tunnel_need_veth_mac = true,
590 .test_gso = true
591 },
592 {
593 .ebpf_tun_type = "gre",
594 .mac_tun_type = "mpls",
595 .iproute_tun_type = "gre",
596 .ipproto = 4,
597 .configure_mpls = true,
598 .test_gso = true
599 },
600 {
601 .ebpf_tun_type = "ip6gre",
602 .mac_tun_type = "none",
603 .iproute_tun_type = "ip6gre",
604 .ipproto = 6,
605 .test_gso = true,
606 },
607 {
608 .ebpf_tun_type = "ip6gre",
609 .mac_tun_type = "eth",
610 .iproute_tun_type = "ip6gretap",
611 .ipproto = 6,
612 .tunnel_need_veth_mac = true,
613 .test_gso = true
614 },
615 {
616 .ebpf_tun_type = "ip6gre",
617 .mac_tun_type = "mpls",
618 .iproute_tun_type = "ip6gre",
619 .ipproto = 6,
620 .configure_mpls = true,
621 .test_gso = true
622 },
623 {
624 .ebpf_tun_type = "udp",
625 .mac_tun_type = "none",
626 .iproute_tun_type = "ipip",
627 .ipproto = 4,
628 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
629 .configure_fou_rx_port = true,
630 .test_gso = true
631 },
632 {
633 .ebpf_tun_type = "udp",
634 .mac_tun_type = "eth",
635 .iproute_tun_type = "ipip",
636 .ipproto = 4,
637 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
638 .configure_fou_rx_port = true,
639 .expect_kern_decap_failure = true,
640 .test_gso = true
641 },
642 {
643 .ebpf_tun_type = "udp",
644 .mac_tun_type = "mpls",
645 .iproute_tun_type = "ipip",
646 .ipproto = 4,
647 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
648 .configure_fou_rx_port = true,
649 .tmode = "mode any ttl 255",
650 .configure_mpls = true,
651 .test_gso = true
652 },
653 {
654 .ebpf_tun_type = "ip6udp",
655 .mac_tun_type = "none",
656 .iproute_tun_type = "ip6tnl",
657 .ipproto = 6,
658 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
659 .configure_fou_rx_port = true,
660 .test_gso = true
661 },
662 {
663 .ebpf_tun_type = "ip6udp",
664 .mac_tun_type = "eth",
665 .iproute_tun_type = "ip6tnl",
666 .ipproto = 6,
667 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
668 .configure_fou_rx_port = true,
669 .expect_kern_decap_failure = true,
670 .test_gso = true
671 },
672 {
673 .ebpf_tun_type = "ip6udp",
674 .mac_tun_type = "mpls",
675 .iproute_tun_type = "ip6tnl",
676 .ipproto = 6,
677 .extra_decap_mod_args_cb = udp_decap_mod_args_cb,
678 .configure_fou_rx_port = true,
679 .tmode = "mode any ttl 255",
680 .expect_kern_decap_failure = true,
681 .test_gso = true
682 },
683 };
684
test_tc_tunnel(void)685 void test_tc_tunnel(void)
686 {
687 struct test_tc_tunnel *skel;
688 struct subtest_cfg *cfg;
689 int i, ret;
690
691 skel = test_tc_tunnel__open_and_load();
692 if (!ASSERT_OK_PTR(skel, "skel open and load"))
693 return;
694
695 if (!ASSERT_OK(setup(), "global setup"))
696 goto out;
697
698 for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) {
699 cfg = &subtests_cfg[i];
700 ret = build_subtest_name(cfg, cfg->name, TEST_NAME_MAX_LEN);
701 if (ret < 0 || !test__start_subtest(cfg->name))
702 continue;
703 if (subtest_setup(skel, cfg) == 0)
704 run_test(cfg);
705 subtest_cleanup(cfg);
706 }
707 cleanup();
708
709 out:
710 test_tc_tunnel__destroy(skel);
711 }
712