brintos

brintos / linux-shallow public Read only

0
0
Text · 21.4 KiB · cec746e Raw
727 lines · c
1// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause2 3/*4 * End-to-end eBPF tunnel test suite5 *   The file tests BPF network tunnel implementation.6 *7 * Topology:8 * ---------9 *     root namespace   |     at_ns0 namespace10 *                       |11 *       -----------     |     -----------12 *       | tnl dev |     |     | tnl dev |  (overlay network)13 *       -----------     |     -----------14 *       metadata-mode   |     metadata-mode15 *        with bpf       |       with bpf16 *                       |17 *       ----------      |     ----------18 *       |  veth1  | --------- |  veth0  |  (underlay network)19 *       ----------    peer    ----------20 *21 *22 *  Device Configuration23 *  --------------------24 *  root namespace with metadata-mode tunnel + BPF25 *  Device names and addresses:26 *	veth1 IP 1: 172.16.1.200, IPv6: 00::22 (underlay)27 *		IP 2: 172.16.1.20, IPv6: 00::bb (underlay)28 *	tunnel dev <type>11, ex: gre11, IPv4: 10.1.1.200, IPv6: 1::22 (overlay)29 *30 *  Namespace at_ns0 with native tunnel31 *  Device names and addresses:32 *	veth0 IPv4: 172.16.1.100, IPv6: 00::11 (underlay)33 *	tunnel dev <type>00, ex: gre00, IPv4: 10.1.1.100, IPv6: 1::11 (overlay)34 *35 *36 * End-to-end ping packet flow37 *  ---------------------------38 *  Most of the tests start by namespace creation, device configuration,39 *  then ping the underlay and overlay network.  When doing 'ping 10.1.1.100'40 *  from root namespace, the following operations happen:41 *  1) Route lookup shows 10.1.1.100/24 belongs to tnl dev, fwd to tnl dev.42 *  2) Tnl device's egress BPF program is triggered and set the tunnel metadata,43 *     with local_ip=172.16.1.200, remote_ip=172.16.1.100. BPF program choose44 *     the primary or secondary ip of veth1 as the local ip of tunnel. The45 *     choice is made based on the value of bpf map local_ip_map.46 *  3) Outer tunnel header is prepended and route the packet to veth1's egress.47 *  4) veth0's ingress queue receive the tunneled packet at namespace at_ns0.48 *  5) Tunnel protocol handler, ex: vxlan_rcv, decap the packet.49 *  6) Forward the packet to the overlay tnl dev.50 */51 52#include <arpa/inet.h>53#include <linux/if_link.h>54#include <linux/if_tun.h>55#include <linux/limits.h>56#include <linux/sysctl.h>57#include <linux/time_types.h>58#include <linux/net_tstamp.h>59#include <net/if.h>60#include <stdbool.h>61#include <stdio.h>62#include <sys/stat.h>63#include <unistd.h>64 65#include "test_progs.h"66#include "network_helpers.h"67#include "test_tunnel_kern.skel.h"68 69#define IP4_ADDR_VETH0 "172.16.1.100"70#define IP4_ADDR1_VETH1 "172.16.1.200"71#define IP4_ADDR2_VETH1 "172.16.1.20"72#define IP4_ADDR_TUNL_DEV0 "10.1.1.100"73#define IP4_ADDR_TUNL_DEV1 "10.1.1.200"74 75#define IP6_ADDR_VETH0 "::11"76#define IP6_ADDR1_VETH1 "::22"77#define IP6_ADDR2_VETH1 "::bb"78 79#define IP4_ADDR1_HEX_VETH1 0xac1001c880#define IP4_ADDR2_HEX_VETH1 0xac10011481#define IP6_ADDR1_HEX_VETH1 0x2282#define IP6_ADDR2_HEX_VETH1 0xbb83 84#define MAC_TUNL_DEV0 "52:54:00:d9:01:00"85#define MAC_TUNL_DEV1 "52:54:00:d9:02:00"86#define MAC_VETH1 "52:54:00:d9:03:00"87 88#define VXLAN_TUNL_DEV0 "vxlan00"89#define VXLAN_TUNL_DEV1 "vxlan11"90#define IP6VXLAN_TUNL_DEV0 "ip6vxlan00"91#define IP6VXLAN_TUNL_DEV1 "ip6vxlan11"92 93#define IPIP_TUNL_DEV0 "ipip00"94#define IPIP_TUNL_DEV1 "ipip11"95 96#define XFRM_AUTH "0x1111111111111111111111111111111111111111"97#define XFRM_ENC "0x22222222222222222222222222222222"98#define XFRM_SPI_IN_TO_OUT 0x199#define XFRM_SPI_OUT_TO_IN 0x2100 101#define PING_ARGS "-i 0.01 -c 3 -w 10 -q"102 103static int config_device(void)104{105	SYS(fail, "ip netns add at_ns0");106	SYS(fail, "ip link add veth0 address " MAC_VETH1 " type veth peer name veth1");107	SYS(fail, "ip link set veth0 netns at_ns0");108	SYS(fail, "ip addr add " IP4_ADDR1_VETH1 "/24 dev veth1");109	SYS(fail, "ip link set dev veth1 up mtu 1500");110	SYS(fail, "ip netns exec at_ns0 ip addr add " IP4_ADDR_VETH0 "/24 dev veth0");111	SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up mtu 1500");112 113	return 0;114fail:115	return -1;116}117 118static void cleanup(void)119{120	SYS_NOFAIL("test -f /var/run/netns/at_ns0 && ip netns delete at_ns0");121	SYS_NOFAIL("ip link del veth1");122	SYS_NOFAIL("ip link del %s", VXLAN_TUNL_DEV1);123	SYS_NOFAIL("ip link del %s", IP6VXLAN_TUNL_DEV1);124}125 126static int add_vxlan_tunnel(void)127{128	/* at_ns0 namespace */129	SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external gbp dstport 4789",130	    VXLAN_TUNL_DEV0);131	SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up",132	    VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);133	SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24",134	    VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);135	SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev %s",136	    IP4_ADDR_TUNL_DEV1, MAC_TUNL_DEV1, VXLAN_TUNL_DEV0);137	SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev veth0",138	    IP4_ADDR2_VETH1, MAC_VETH1);139 140	/* root namespace */141	SYS(fail, "ip link add dev %s type vxlan external gbp dstport 4789",142	    VXLAN_TUNL_DEV1);143	SYS(fail, "ip link set dev %s address %s up", VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);144	SYS(fail, "ip addr add dev %s %s/24", VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);145	SYS(fail, "ip neigh add %s lladdr %s dev %s",146	    IP4_ADDR_TUNL_DEV0, MAC_TUNL_DEV0, VXLAN_TUNL_DEV1);147 148	return 0;149fail:150	return -1;151}152 153static void delete_vxlan_tunnel(void)154{155	SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",156		   VXLAN_TUNL_DEV0);157	SYS_NOFAIL("ip link delete dev %s", VXLAN_TUNL_DEV1);158}159 160static int add_ip6vxlan_tunnel(void)161{162	SYS(fail, "ip netns exec at_ns0 ip -6 addr add %s/96 dev veth0",163	    IP6_ADDR_VETH0);164	SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up");165	SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR1_VETH1);166	SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR2_VETH1);167	SYS(fail, "ip link set dev veth1 up");168 169	/* at_ns0 namespace */170	SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external dstport 4789",171	    IP6VXLAN_TUNL_DEV0);172	SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24",173	    IP6VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);174	SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up",175	    IP6VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);176 177	/* root namespace */178	SYS(fail, "ip link add dev %s type vxlan external dstport 4789",179	    IP6VXLAN_TUNL_DEV1);180	SYS(fail, "ip addr add dev %s %s/24", IP6VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);181	SYS(fail, "ip link set dev %s address %s up",182	    IP6VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);183 184	return 0;185fail:186	return -1;187}188 189static void delete_ip6vxlan_tunnel(void)190{191	SYS_NOFAIL("ip netns exec at_ns0 ip -6 addr delete %s/96 dev veth0",192		   IP6_ADDR_VETH0);193	SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR1_VETH1);194	SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR2_VETH1);195	SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",196		   IP6VXLAN_TUNL_DEV0);197	SYS_NOFAIL("ip link delete dev %s", IP6VXLAN_TUNL_DEV1);198}199 200enum ipip_encap {201	NONE	= 0,202	FOU	= 1,203	GUE	= 2,204};205 206static int set_ipip_encap(const char *ipproto, const char *type)207{208	SYS(fail, "ip -n at_ns0 fou add port 5555 %s", ipproto);209	SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap %s",210	    IPIP_TUNL_DEV0, type);211	SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap-dport 5555",212	    IPIP_TUNL_DEV0);213 214	return 0;215fail:216	return -1;217}218 219static int add_ipip_tunnel(enum ipip_encap encap)220{221	int err;222	const char *ipproto, *type;223 224	switch (encap) {225	case FOU:226		ipproto = "ipproto 4";227		type = "fou";228		break;229	case GUE:230		ipproto = "gue";231		type = ipproto;232		break;233	default:234		ipproto = NULL;235		type = ipproto;236	}237 238	/* at_ns0 namespace */239	SYS(fail, "ip -n at_ns0 link add dev %s type ipip local %s remote %s",240	    IPIP_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);241 242	if (type && ipproto) {243		err = set_ipip_encap(ipproto, type);244		if (!ASSERT_OK(err, "set_ipip_encap"))245			goto fail;246	}247 248	SYS(fail, "ip -n at_ns0 link set dev %s up", IPIP_TUNL_DEV0);249	SYS(fail, "ip -n at_ns0 addr add dev %s %s/24",250	    IPIP_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);251 252	/* root namespace */253	if (type && ipproto)254		SYS(fail, "ip fou add port 5555 %s", ipproto);255	SYS(fail, "ip link add dev %s type ipip external", IPIP_TUNL_DEV1);256	SYS(fail, "ip link set dev %s up", IPIP_TUNL_DEV1);257	SYS(fail, "ip addr add dev %s %s/24", IPIP_TUNL_DEV1,258	    IP4_ADDR_TUNL_DEV1);259 260	return 0;261fail:262	return -1;263}264 265static void delete_ipip_tunnel(void)266{267	SYS_NOFAIL("ip -n at_ns0 link delete dev %s", IPIP_TUNL_DEV0);268	SYS_NOFAIL("ip -n at_ns0 fou del port 5555");269	SYS_NOFAIL("ip link delete dev %s", IPIP_TUNL_DEV1);270	SYS_NOFAIL("ip fou del port 5555");271}272 273static int add_xfrm_tunnel(void)274{275	/* at_ns0 namespace276	 * at_ns0 -> root277	 */278	SYS(fail,279	    "ip netns exec at_ns0 "280		"ip xfrm state add src %s dst %s proto esp "281			"spi %d reqid 1 mode tunnel replay-window 42 "282			"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",283	    IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);284	SYS(fail,285	    "ip netns exec at_ns0 "286		"ip xfrm policy add src %s/32 dst %s/32 dir out "287			"tmpl src %s dst %s proto esp reqid 1 "288			"mode tunnel",289	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);290 291	/* root -> at_ns0 */292	SYS(fail,293	    "ip netns exec at_ns0 "294		"ip xfrm state add src %s dst %s proto esp "295			"spi %d reqid 2 mode tunnel "296			"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",297	    IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);298	SYS(fail,299	    "ip netns exec at_ns0 "300		"ip xfrm policy add src %s/32 dst %s/32 dir in "301			"tmpl src %s dst %s proto esp reqid 2 "302			"mode tunnel",303	    IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);304 305	/* address & route */306	SYS(fail, "ip netns exec at_ns0 ip addr add dev veth0 %s/32",307	    IP4_ADDR_TUNL_DEV0);308	SYS(fail, "ip netns exec at_ns0 ip route add %s dev veth0 via %s src %s",309	    IP4_ADDR_TUNL_DEV1, IP4_ADDR1_VETH1, IP4_ADDR_TUNL_DEV0);310 311	/* root namespace312	 * at_ns0 -> root313	 */314	SYS(fail,315	    "ip xfrm state add src %s dst %s proto esp "316		    "spi %d reqid 1 mode tunnel replay-window 42 "317		    "auth-trunc 'hmac(sha1)' %s 96  enc 'cbc(aes)' %s",318	    IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);319	SYS(fail,320	    "ip xfrm policy add src %s/32 dst %s/32 dir in "321		    "tmpl src %s dst %s proto esp reqid 1 "322		    "mode tunnel",323	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);324 325	/* root -> at_ns0 */326	SYS(fail,327	    "ip xfrm state add src %s dst %s proto esp "328		    "spi %d reqid 2 mode tunnel "329		    "auth-trunc 'hmac(sha1)' %s 96  enc 'cbc(aes)' %s",330	    IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);331	SYS(fail,332	    "ip xfrm policy add src %s/32 dst %s/32 dir out "333		    "tmpl src %s dst %s proto esp reqid 2 "334		    "mode tunnel",335	    IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);336 337	/* address & route */338	SYS(fail, "ip addr add dev veth1 %s/32", IP4_ADDR_TUNL_DEV1);339	SYS(fail, "ip route add %s dev veth1 via %s src %s",340	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR_TUNL_DEV1);341 342	return 0;343fail:344	return -1;345}346 347static void delete_xfrm_tunnel(void)348{349	SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32",350		   IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0);351	SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32",352		   IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1);353	SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d",354		   IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT);355	SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d",356		   IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN);357}358 359static int test_ping(int family, const char *addr)360{361	SYS(fail, "%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr);362	return 0;363fail:364	return -1;365}366 367static int attach_tc_prog(struct bpf_tc_hook *hook, int igr_fd, int egr_fd)368{369	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,370			    .priority = 1, .prog_fd = igr_fd);371	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,372			    .priority = 1, .prog_fd = egr_fd);373	int ret;374 375	ret = bpf_tc_hook_create(hook);376	if (!ASSERT_OK(ret, "create tc hook"))377		return ret;378 379	if (igr_fd >= 0) {380		hook->attach_point = BPF_TC_INGRESS;381		ret = bpf_tc_attach(hook, &opts1);382		if (!ASSERT_OK(ret, "bpf_tc_attach")) {383			bpf_tc_hook_destroy(hook);384			return ret;385		}386	}387 388	if (egr_fd >= 0) {389		hook->attach_point = BPF_TC_EGRESS;390		ret = bpf_tc_attach(hook, &opts2);391		if (!ASSERT_OK(ret, "bpf_tc_attach")) {392			bpf_tc_hook_destroy(hook);393			return ret;394		}395	}396 397	return 0;398}399 400static void test_vxlan_tunnel(void)401{402	struct test_tunnel_kern *skel = NULL;403	struct nstoken *nstoken;404	int local_ip_map_fd = -1;405	int set_src_prog_fd, get_src_prog_fd;406	int set_dst_prog_fd;407	int key = 0, ifindex = -1;408	uint local_ip;409	int err;410	DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,411			    .attach_point = BPF_TC_INGRESS);412 413	/* add vxlan tunnel */414	err = add_vxlan_tunnel();415	if (!ASSERT_OK(err, "add vxlan tunnel"))416		goto done;417 418	/* load and attach bpf prog to tunnel dev tc hook point */419	skel = test_tunnel_kern__open_and_load();420	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))421		goto done;422	ifindex = if_nametoindex(VXLAN_TUNL_DEV1);423	if (!ASSERT_NEQ(ifindex, 0, "vxlan11 ifindex"))424		goto done;425	tc_hook.ifindex = ifindex;426	get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);427	set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);428	if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))429		goto done;430	if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))431		goto done;432	if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))433		goto done;434 435	/* load and attach bpf prog to veth dev tc hook point */436	ifindex = if_nametoindex("veth1");437	if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))438		goto done;439	tc_hook.ifindex = ifindex;440	set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);441	if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))442		goto done;443	if (attach_tc_prog(&tc_hook, set_dst_prog_fd, -1))444		goto done;445 446	/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */447	nstoken = open_netns("at_ns0");448	if (!ASSERT_OK_PTR(nstoken, "setns src"))449		goto done;450	ifindex = if_nametoindex(VXLAN_TUNL_DEV0);451	if (!ASSERT_NEQ(ifindex, 0, "vxlan00 ifindex"))452		goto done;453	tc_hook.ifindex = ifindex;454	set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);455	if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))456		goto done;457	if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))458		goto done;459	close_netns(nstoken);460 461	/* use veth1 ip 2 as tunnel source ip */462	local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);463	if (!ASSERT_GE(local_ip_map_fd, 0, "bpf_map__fd"))464		goto done;465	local_ip = IP4_ADDR2_HEX_VETH1;466	err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);467	if (!ASSERT_OK(err, "update bpf local_ip_map"))468		goto done;469 470	/* ping test */471	err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);472	if (!ASSERT_OK(err, "test_ping"))473		goto done;474 475done:476	/* delete vxlan tunnel */477	delete_vxlan_tunnel();478	if (local_ip_map_fd >= 0)479		close(local_ip_map_fd);480	if (skel)481		test_tunnel_kern__destroy(skel);482}483 484static void test_ip6vxlan_tunnel(void)485{486	struct test_tunnel_kern *skel = NULL;487	struct nstoken *nstoken;488	int local_ip_map_fd = -1;489	int set_src_prog_fd, get_src_prog_fd;490	int set_dst_prog_fd;491	int key = 0, ifindex = -1;492	uint local_ip;493	int err;494	DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,495			    .attach_point = BPF_TC_INGRESS);496 497	/* add vxlan tunnel */498	err = add_ip6vxlan_tunnel();499	if (!ASSERT_OK(err, "add_ip6vxlan_tunnel"))500		goto done;501 502	/* load and attach bpf prog to tunnel dev tc hook point */503	skel = test_tunnel_kern__open_and_load();504	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))505		goto done;506	ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV1);507	if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan11 ifindex"))508		goto done;509	tc_hook.ifindex = ifindex;510	get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);511	set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);512	if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))513		goto done;514	if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))515		goto done;516	if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))517		goto done;518 519	/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */520	nstoken = open_netns("at_ns0");521	if (!ASSERT_OK_PTR(nstoken, "setns src"))522		goto done;523	ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV0);524	if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan00 ifindex"))525		goto done;526	tc_hook.ifindex = ifindex;527	set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);528	if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))529		goto done;530	if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))531		goto done;532	close_netns(nstoken);533 534	/* use veth1 ip 2 as tunnel source ip */535	local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);536	if (!ASSERT_GE(local_ip_map_fd, 0, "get local_ip_map fd"))537		goto done;538	local_ip = IP6_ADDR2_HEX_VETH1;539	err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);540	if (!ASSERT_OK(err, "update bpf local_ip_map"))541		goto done;542 543	/* ping test */544	err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);545	if (!ASSERT_OK(err, "test_ping"))546		goto done;547 548done:549	/* delete ipv6 vxlan tunnel */550	delete_ip6vxlan_tunnel();551	if (local_ip_map_fd >= 0)552		close(local_ip_map_fd);553	if (skel)554		test_tunnel_kern__destroy(skel);555}556 557static void test_ipip_tunnel(enum ipip_encap encap)558{559	struct test_tunnel_kern *skel = NULL;560	struct nstoken *nstoken;561	int set_src_prog_fd, get_src_prog_fd;562	int ifindex = -1;563	int err;564	DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,565			    .attach_point = BPF_TC_INGRESS);566 567	/* add ipip tunnel */568	err = add_ipip_tunnel(encap);569	if (!ASSERT_OK(err, "add_ipip_tunnel"))570		goto done;571 572	/* load and attach bpf prog to tunnel dev tc hook point */573	skel = test_tunnel_kern__open_and_load();574	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))575		goto done;576	ifindex = if_nametoindex(IPIP_TUNL_DEV1);577	if (!ASSERT_NEQ(ifindex, 0, "ipip11 ifindex"))578		goto done;579	tc_hook.ifindex = ifindex;580 581	switch (encap) {582	case FOU:583		get_src_prog_fd = bpf_program__fd(584			skel->progs.ipip_encap_get_tunnel);585		set_src_prog_fd = bpf_program__fd(586			skel->progs.ipip_fou_set_tunnel);587		break;588	case GUE:589		get_src_prog_fd = bpf_program__fd(590			skel->progs.ipip_encap_get_tunnel);591		set_src_prog_fd = bpf_program__fd(592			skel->progs.ipip_gue_set_tunnel);593		break;594	default:595		get_src_prog_fd = bpf_program__fd(596			skel->progs.ipip_get_tunnel);597		set_src_prog_fd = bpf_program__fd(598			skel->progs.ipip_set_tunnel);599	}600 601	if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))602		goto done;603	if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))604		goto done;605	if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))606		goto done;607 608	/* ping from root namespace test */609	err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);610	if (!ASSERT_OK(err, "test_ping"))611		goto done;612 613	/* ping from at_ns0 namespace test */614	nstoken = open_netns("at_ns0");615	if (!ASSERT_OK_PTR(nstoken, "setns"))616		goto done;617	err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);618	if (!ASSERT_OK(err, "test_ping"))619		goto done;620	close_netns(nstoken);621 622done:623	/* delete ipip tunnel */624	delete_ipip_tunnel();625	if (skel)626		test_tunnel_kern__destroy(skel);627}628 629static void test_xfrm_tunnel(void)630{631	DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,632			    .attach_point = BPF_TC_INGRESS);633	LIBBPF_OPTS(bpf_xdp_attach_opts, opts);634	struct test_tunnel_kern *skel = NULL;635	struct nstoken *nstoken;636	int xdp_prog_fd;637	int tc_prog_fd;638	int ifindex;639	int err;640 641	err = add_xfrm_tunnel();642	if (!ASSERT_OK(err, "add_xfrm_tunnel"))643		return;644 645	skel = test_tunnel_kern__open_and_load();646	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))647		goto done;648 649	ifindex = if_nametoindex("veth1");650	if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))651		goto done;652 653	/* attach tc prog to tunnel dev */654	tc_hook.ifindex = ifindex;655	tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);656	if (!ASSERT_GE(tc_prog_fd, 0, "bpf_program__fd"))657		goto done;658	if (attach_tc_prog(&tc_hook, tc_prog_fd, -1))659		goto done;660 661	/* attach xdp prog to tunnel dev */662	xdp_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state_xdp);663	if (!ASSERT_GE(xdp_prog_fd, 0, "bpf_program__fd"))664		goto done;665	err = bpf_xdp_attach(ifindex, xdp_prog_fd, XDP_FLAGS_REPLACE, &opts);666	if (!ASSERT_OK(err, "bpf_xdp_attach"))667		goto done;668 669	/* ping from at_ns0 namespace test */670	nstoken = open_netns("at_ns0");671	if (!ASSERT_OK_PTR(nstoken, "setns"))672		goto done;673	err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);674	close_netns(nstoken);675	if (!ASSERT_OK(err, "test_ping"))676		goto done;677 678	if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))679		goto done;680	if (!ASSERT_EQ(skel->bss->xfrm_spi, XFRM_SPI_IN_TO_OUT, "spi"))681		goto done;682	if (!ASSERT_EQ(skel->bss->xfrm_remote_ip, 0xac100164, "remote_ip"))683		goto done;684	if (!ASSERT_EQ(skel->bss->xfrm_replay_window, 42, "replay_window"))685		goto done;686 687done:688	delete_xfrm_tunnel();689	if (skel)690		test_tunnel_kern__destroy(skel);691}692 693#define RUN_TEST(name, ...)						\694	({								\695		if (test__start_subtest(#name)) {			\696			config_device();				\697			test_ ## name(__VA_ARGS__);			\698			cleanup();					\699		}							\700	})701 702static void *test_tunnel_run_tests(void *arg)703{704	RUN_TEST(vxlan_tunnel);705	RUN_TEST(ip6vxlan_tunnel);706	RUN_TEST(ipip_tunnel, NONE);707	RUN_TEST(ipip_tunnel, FOU);708	RUN_TEST(ipip_tunnel, GUE);709	RUN_TEST(xfrm_tunnel);710 711	return NULL;712}713 714void test_tunnel(void)715{716	pthread_t test_thread;717	int err;718 719	/* Run the tests in their own thread to isolate the namespace changes720	 * so they do not affect the environment of other tests.721	 * (specifically needed because of unshare(CLONE_NEWNS) in open_netns())722	 */723	err = pthread_create(&test_thread, NULL, &test_tunnel_run_tests, NULL);724	if (ASSERT_OK(err, "pthread_create"))725		ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join");726}727