File Index
Files and directories
Sign in
FILE

test_tc_tunnel.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/test_tc_tunnel.c 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
 51static char tx_buffer[BUFFER_LEN], rx_buffer[BUFFER_LEN];
 52
 53struct 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
 75struct connection {
 76	int client_fd;
 77	int server_fd;
 78};
 79
 80static 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
 90static 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
111static 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
134static 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
155static 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
169static struct connection *connect_client_to_server(struct subtest_cfg *cfg)
170{
171	struct network_helper_opts opts = {.timeout_ms = 500};
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
201static 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
209static int send_and_test_data(struct subtest_cfg *cfg, bool must_succeed)
210{
211	struct connection *conn;
212	int err, res = -1;
213
214	conn = connect_client_to_server(cfg);
215	if (!must_succeed && !ASSERT_ERR_PTR(conn, "connection that must fail"))
216		goto end;
217	else if (!must_succeed)
218		return 0;
219
220	if (!ASSERT_OK_PTR(conn, "connection that must succeed"))
221		return -1;
222
223	err = send(conn->client_fd, tx_buffer, DEFAULT_TEST_DATA_SIZE, 0);
224	if (!ASSERT_EQ(err, DEFAULT_TEST_DATA_SIZE, "send data from client"))
225		goto end;
226	if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE))
227		goto end;
228
229	if (!cfg->test_gso) {
230		res = 0;
231		goto end;
232	}
233
234	err = send(conn->client_fd, tx_buffer, GSO_TEST_DATA_SIZE, 0);
235	if (!ASSERT_EQ(err, GSO_TEST_DATA_SIZE, "send (large) data from client"))
236		goto end;
237	if (check_server_rx_data(cfg, conn, DEFAULT_TEST_DATA_SIZE))
238		goto end;
239
240	res = 0;
241end:
242	disconnect_client_from_server(cfg, conn);
243	return res;
244}
245
246static void vxlan_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst)
247{
248	snprintf(dst, TUNNEL_ARGS_MAX_LEN, "id %d dstport %d udp6zerocsumrx",
249		 VXLAN_ID, VXLAN_PORT);
250}
251
252static void udp_decap_mod_args_cb(struct subtest_cfg *cfg, char *dst)
253{
254	bool is_mpls = !strcmp(cfg->mac_tun_type, "mpls");
255
256	snprintf(dst, TUNNEL_ARGS_MAX_LEN,
257		 "encap fou encap-sport auto encap-dport %d",
258		 is_mpls ? MPLS_UDP_PORT : UDP_PORT);
259}
260
261static int configure_fou_rx_port(struct subtest_cfg *cfg, bool add)
262{
263	bool is_mpls = strcmp(cfg->mac_tun_type, "mpls") == 0;
264	int fou_proto;
265
266	if (is_mpls)
267		fou_proto = FOU_MPLS_PROTO;
268	else
269		fou_proto = cfg->ipproto == 6 ? 41 : 4;
270
271	SYS(fail, "ip fou %s port %d ipproto %d%s", add ? "add" : "del",
272	    is_mpls ? MPLS_UDP_PORT : UDP_PORT, fou_proto,
273	    cfg->ipproto == 6 ? " -6" : "");
274
275	return 0;
276fail:
277	return 1;
278}
279
280static int add_fou_rx_port(struct subtest_cfg *cfg)
281{
282	return configure_fou_rx_port(cfg, true);
283}
284
285static int del_fou_rx_port(struct subtest_cfg *cfg)
286{
287	return configure_fou_rx_port(cfg, false);
288}
289
290static int update_tunnel_intf_addr(struct subtest_cfg *cfg)
291{
292	SYS(fail, "ip link set dev testtun0 address " MAC_ADDR_VETH2);
293	return 0;
294fail:
295	return -1;
296}
297
298static int configure_kernel_for_mpls(struct subtest_cfg *cfg)
299{
300	SYS(fail, "sysctl -qw net.mpls.platform_labels=%d",
301	    MPLS_TABLE_ENTRIES_COUNT);
302	SYS(fail, "ip -f mpls route add 1000 dev lo");
303	SYS(fail, "ip link set lo up");
304	SYS(fail, "sysctl -qw net.mpls.conf.testtun0.input=1");
305	SYS(fail, "sysctl -qw net.ipv4.conf.lo.rp_filter=0");
306	return 0;
307fail:
308	return -1;
309}
310
311static int configure_encapsulation(struct subtest_cfg *cfg)
312{
313	int ret;
314
315	ret = tc_prog_attach("veth1", -1, cfg->client_egress_prog_fd);
316
317	return ret;
318}
319
320static int configure_kernel_decapsulation(struct subtest_cfg *cfg)
321{
322	struct nstoken *nstoken = open_netns(SERVER_NS);
323	int ret = -1;
324
325	if (!ASSERT_OK_PTR(nstoken, "open server ns"))
326		return ret;
327
328	if (cfg->configure_fou_rx_port &&
329	    !ASSERT_OK(add_fou_rx_port(cfg), "configure FOU RX port"))
330		goto fail;
331	SYS(fail, "ip link add name testtun0 type %s %s remote %s local %s %s",
332	    cfg->iproute_tun_type, cfg->tmode ? cfg->tmode : "",
333	    cfg->tunnel_client_addr, cfg->tunnel_server_addr,
334	    cfg->extra_decap_mod_args);
335	if (cfg->tunnel_need_veth_mac &&
336	    !ASSERT_OK(update_tunnel_intf_addr(cfg), "update testtun0 mac"))
337		goto fail;
338	if (cfg->configure_mpls &&
339	    (!ASSERT_OK(configure_kernel_for_mpls(cfg),
340			"configure MPLS decap")))
341		goto fail;
342	SYS(fail, "sysctl -qw net.ipv4.conf.all.rp_filter=0");
343	SYS(fail, "sysctl -qw net.ipv4.conf.testtun0.rp_filter=0");
344	SYS(fail, "ip link set dev testtun0 up");
345
346	ret = 0;
347fail:
348	close_netns(nstoken);
349	return ret;
350}
351
352static void remove_kernel_decapsulation(struct subtest_cfg *cfg)
353{
354	SYS_NOFAIL("ip link del testtun0");
355	if (cfg->configure_mpls)
356		SYS_NOFAIL("ip -f mpls route del 1000 dev lo");
357	if (cfg->configure_fou_rx_port)
358		del_fou_rx_port(cfg);
359}
360
361static int configure_ebpf_decapsulation(struct subtest_cfg *cfg)
362{
363	struct nstoken *nstoken = open_netns(SERVER_NS);
364	int ret = -1;
365
366	if (!ASSERT_OK_PTR(nstoken, "open server ns"))
367		return ret;
368
369	if (!cfg->expect_kern_decap_failure)
370		SYS(fail, "ip link del testtun0");
371
372	if (!ASSERT_OK(tc_prog_attach("veth2", cfg->server_ingress_prog_fd, -1),
373		       "attach_program"))
374		goto fail;
375
376	ret = 0;
377fail:
378	close_netns(nstoken);
379	return ret;
380}
381
382static void run_test(struct subtest_cfg *cfg)
383{
384	struct nstoken *nstoken;
385
386	if (!ASSERT_OK(run_server(cfg), "run server"))
387		return;
388
389	nstoken = open_netns(CLIENT_NS);
390	if (!ASSERT_OK_PTR(nstoken, "open client ns"))
391		goto fail;
392
393	/* Basic communication must work */
394	if (!ASSERT_OK(send_and_test_data(cfg, true), "connect without any encap"))
395		goto fail;
396
397	/* Attach encapsulation program to client */
398	if (!ASSERT_OK(configure_encapsulation(cfg), "configure encapsulation"))
399		goto fail;
400
401	/* If supported, insert kernel decap module, connection must succeed */
402	if (!cfg->expect_kern_decap_failure) {
403		if (!ASSERT_OK(configure_kernel_decapsulation(cfg),
404					"configure kernel decapsulation"))
405			goto fail;
406		if (!ASSERT_OK(send_and_test_data(cfg, true),
407			       "connect with encap prog and kern decap"))
408			goto fail;
409	}
410
411	/* Replace kernel decapsulation with BPF decapsulation, test must pass */
412	if (!ASSERT_OK(configure_ebpf_decapsulation(cfg), "configure ebpf decapsulation"))
413		goto fail;
414	ASSERT_OK(send_and_test_data(cfg, true), "connect with encap and decap progs");
415
416fail:
417	close_netns(nstoken);
418	close(cfg->server_fd);
419}
420
421static int setup(void)
422{
423	struct nstoken *nstoken_client, *nstoken_server;
424	int fd, err;
425
426	fd = open("/dev/urandom", O_RDONLY);
427	if (!ASSERT_OK_FD(fd, "open urandom"))
428		goto fail;
429	err = read(fd, tx_buffer, BUFFER_LEN);
430	close(fd);
431
432	if (!ASSERT_EQ(err, BUFFER_LEN, "read random bytes"))
433		goto fail;
434
435	/* Configure the testing network */
436	if (!ASSERT_OK(make_netns(CLIENT_NS), "create client ns") ||
437	    !ASSERT_OK(make_netns(SERVER_NS), "create server ns"))
438		goto fail;
439
440	nstoken_client = open_netns(CLIENT_NS);
441	if (!ASSERT_OK_PTR(nstoken_client, "open client ns"))
442		goto fail_delete_ns;
443	SYS(fail_close_ns_client, "ip link add %s type veth peer name %s",
444	    "veth1 mtu 1500 netns " CLIENT_NS " address " MAC_ADDR_VETH1,
445	    "veth2 mtu 1500 netns " SERVER_NS " address " MAC_ADDR_VETH2);
446	SYS(fail_close_ns_client, "ethtool -K veth1 tso off");
447	SYS(fail_close_ns_client, "ip link set veth1 up");
448	nstoken_server = open_netns(SERVER_NS);
449	if (!ASSERT_OK_PTR(nstoken_server, "open server ns"))
450		goto fail_close_ns_client;
451	SYS(fail_close_ns_server, "ip link set veth2 up");
452
453	close_netns(nstoken_server);
454	close_netns(nstoken_client);
455	return 0;
456
457fail_close_ns_server:
458	close_netns(nstoken_server);
459fail_close_ns_client:
460	close_netns(nstoken_client);
461fail_delete_ns:
462	SYS_NOFAIL("ip netns del " CLIENT_NS);
463	SYS_NOFAIL("ip netns del " SERVER_NS);
464fail:
465	return -1;
466}
467
468static int subtest_setup(struct test_tc_tunnel *skel, struct subtest_cfg *cfg)
469{
470	struct nstoken *nstoken_client, *nstoken_server;
471	int ret = -1;
472
473	set_subtest_addresses(cfg);
474	if (!ASSERT_OK(set_subtest_progs(cfg, skel),
475		       "find subtest progs"))
476		goto fail;
477	if (cfg->extra_decap_mod_args_cb)
478		cfg->extra_decap_mod_args_cb(cfg, cfg->extra_decap_mod_args);
479
480	nstoken_client = open_netns(CLIENT_NS);
481	if (!ASSERT_OK_PTR(nstoken_client, "open client ns"))
482		goto fail;
483	SYS(fail_close_client_ns,
484	    "ip -4 addr add " IP4_ADDR_VETH1 "/24 dev veth1");
485	SYS(fail_close_client_ns, "ip -4 route flush table main");
486	SYS(fail_close_client_ns,
487	    "ip -4 route add " IP4_ADDR_VETH2 " mtu 1450 dev veth1");
488	SYS(fail_close_client_ns,
489	    "ip -6 addr add " IP6_ADDR_VETH1 "/64 dev veth1 nodad");
490	SYS(fail_close_client_ns, "ip -6 route flush table main");
491	SYS(fail_close_client_ns,
492	    "ip -6 route add " IP6_ADDR_VETH2 " mtu 1430 dev veth1");
493	nstoken_server = open_netns(SERVER_NS);
494	if (!ASSERT_OK_PTR(nstoken_server, "open server ns"))
495		goto fail_close_client_ns;
496	SYS(fail_close_server_ns,
497	    "ip -4 addr add " IP4_ADDR_VETH2 "/24 dev veth2");
498	SYS(fail_close_server_ns,
499	    "ip -6 addr add " IP6_ADDR_VETH2 "/64 dev veth2 nodad");
500
501	ret = 0;
502
503fail_close_server_ns:
504	close_netns(nstoken_server);
505fail_close_client_ns:
506	close_netns(nstoken_client);
507fail:
508	return ret;
509}
510
511
512static void subtest_cleanup(struct subtest_cfg *cfg)
513{
514	struct nstoken *nstoken;
515
516	nstoken = open_netns(CLIENT_NS);
517	if (ASSERT_OK_PTR(nstoken, "open clien ns")) {
518		SYS_NOFAIL("tc qdisc delete dev veth1 parent ffff:fff1");
519		SYS_NOFAIL("ip a flush veth1");
520		close_netns(nstoken);
521	}
522	nstoken = open_netns(SERVER_NS);
523	if (ASSERT_OK_PTR(nstoken, "open clien ns")) {
524		SYS_NOFAIL("tc qdisc delete dev veth2 parent ffff:fff1");
525		SYS_NOFAIL("ip a flush veth2");
526		if (!cfg->expect_kern_decap_failure)
527			remove_kernel_decapsulation(cfg);
528		close_netns(nstoken);
529	}
530}
531
532static void cleanup(void)
533{
534	remove_netns(CLIENT_NS);
535	remove_netns(SERVER_NS);
536}
537
538static struct subtest_cfg subtests_cfg[] = {
539	{
540		.ebpf_tun_type = "ipip",
541		.mac_tun_type = "none",
542		.iproute_tun_type = "ipip",
543		.ipproto = 4,
544	},
545	{
546		.ebpf_tun_type = "ipip6",
547		.mac_tun_type = "none",
548		.iproute_tun_type = "ip6tnl",
549		.ipproto = 4,
550		.tunnel_client_addr = IP6_ADDR_VETH1,
551		.tunnel_server_addr = IP6_ADDR_VETH2,
552	},
553	{
554		.ebpf_tun_type = "ip6tnl",
555		.iproute_tun_type = "ip6tnl",
556		.mac_tun_type = "none",
557		.ipproto = 6,
558	},
559	{
560		.mac_tun_type = "none",
561		.ebpf_tun_type = "sit",
562		.iproute_tun_type = "sit",
563		.ipproto = 6,
564		.tunnel_client_addr = IP4_ADDR_VETH1,
565		.tunnel_server_addr = IP4_ADDR_VETH2,
566	},
567	{
568		.ebpf_tun_type = "vxlan",
569		.mac_tun_type = "eth",
570		.iproute_tun_type = "vxlan",
571		.ipproto = 4,
572		.extra_decap_mod_args_cb = vxlan_decap_mod_args_cb,
573		.tunnel_need_veth_mac = true
574	},
575	{
576		.ebpf_tun_type = "ip6vxlan",
577		.mac_tun_type = "eth",
578		.iproute_tun_type = "vxlan",
579		.ipproto = 6,
580		.extra_decap_mod_args_cb = vxlan_decap_mod_args_cb,
581		.tunnel_need_veth_mac = true
582	},
583	{
584		.ebpf_tun_type = "gre",
585		.mac_tun_type = "none",
586		.iproute_tun_type = "gre",
587		.ipproto = 4,
588		.test_gso = true
589	},
590	{
591		.ebpf_tun_type = "gre",
592		.mac_tun_type = "eth",
593		.iproute_tun_type = "gretap",
594		.ipproto = 4,
595		.tunnel_need_veth_mac = true,
596		.test_gso = true
597	},
598	{
599		.ebpf_tun_type = "gre",
600		.mac_tun_type = "mpls",
601		.iproute_tun_type = "gre",
602		.ipproto = 4,
603		.configure_mpls = true,
604		.test_gso = true
605	},
606	{
607		.ebpf_tun_type = "ip6gre",
608		.mac_tun_type = "none",
609		.iproute_tun_type = "ip6gre",
610		.ipproto = 6,
611		.test_gso = true,
612	},
613	{
614		.ebpf_tun_type = "ip6gre",
615		.mac_tun_type = "eth",
616		.iproute_tun_type = "ip6gretap",
617		.ipproto = 6,
618		.tunnel_need_veth_mac = true,
619		.test_gso = true
620	},
621	{
622		.ebpf_tun_type = "ip6gre",
623		.mac_tun_type = "mpls",
624		.iproute_tun_type = "ip6gre",
625		.ipproto = 6,
626		.configure_mpls = true,
627		.test_gso = true
628	},
629	{
630		.ebpf_tun_type = "udp",
631		.mac_tun_type = "none",
632		.iproute_tun_type = "ipip",
633		.ipproto = 4,
634		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
635		.configure_fou_rx_port = true,
636		.test_gso = true
637	},
638	{
639		.ebpf_tun_type = "udp",
640		.mac_tun_type = "eth",
641		.iproute_tun_type = "ipip",
642		.ipproto = 4,
643		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
644		.configure_fou_rx_port = true,
645		.expect_kern_decap_failure = true,
646		.test_gso = true
647	},
648	{
649		.ebpf_tun_type = "udp",
650		.mac_tun_type = "mpls",
651		.iproute_tun_type = "ipip",
652		.ipproto = 4,
653		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
654		.configure_fou_rx_port = true,
655		.tmode = "mode any ttl 255",
656		.configure_mpls = true,
657		.test_gso = true
658	},
659	{
660		.ebpf_tun_type = "ip6udp",
661		.mac_tun_type = "none",
662		.iproute_tun_type = "ip6tnl",
663		.ipproto = 6,
664		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
665		.configure_fou_rx_port = true,
666		.test_gso = true
667	},
668	{
669		.ebpf_tun_type = "ip6udp",
670		.mac_tun_type = "eth",
671		.iproute_tun_type = "ip6tnl",
672		.ipproto = 6,
673		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
674		.configure_fou_rx_port = true,
675		.expect_kern_decap_failure = true,
676		.test_gso = true
677	},
678	{
679		.ebpf_tun_type = "ip6udp",
680		.mac_tun_type = "mpls",
681		.iproute_tun_type = "ip6tnl",
682		.ipproto = 6,
683		.extra_decap_mod_args_cb = udp_decap_mod_args_cb,
684		.configure_fou_rx_port = true,
685		.tmode = "mode any ttl 255",
686		.expect_kern_decap_failure = true,
687		.test_gso = true
688	},
689};
690
691void test_tc_tunnel(void)
692{
693	struct test_tc_tunnel *skel;
694	struct subtest_cfg *cfg;
695	int i, ret;
696
697	skel = test_tc_tunnel__open_and_load();
698	if (!ASSERT_OK_PTR(skel, "skel open and load"))
699		return;
700
701	if (!ASSERT_OK(setup(), "global setup"))
702		return;
703
704	for (i = 0; i < ARRAY_SIZE(subtests_cfg); i++) {
705		cfg = &subtests_cfg[i];
706		ret = build_subtest_name(cfg, cfg->name, TEST_NAME_MAX_LEN);
707		if (ret < 0 || !test__start_subtest(cfg->name))
708			continue;
709		if (subtest_setup(skel, cfg) == 0)
710			run_test(cfg);
711		subtest_cleanup(cfg);
712	}
713	cleanup();
714}
~/ Read-only file preview.