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 tunnel implementation.
6  *
7  * Topology:
8  * ---------
9  *     root namespace   |     at_ns0 namespace
10  *                       |
11  *       -----------     |     -----------
12  *       | tnl dev |     |     | tnl dev |  (overlay network)
13  *       -----------     |     -----------
14  *       metadata-mode   |     metadata-mode
15  *        with bpf       |       with bpf
16  *                       |
17  *       ----------      |     ----------
18  *       |  veth1  | --------- |  veth0  |  (underlay network)
19  *       ----------    peer    ----------
20  *
21  *
22  *  Device Configuration
23  *  --------------------
24  *  root namespace with metadata-mode tunnel + BPF
25  *  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 tunnel
31  *  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 flow
37  *  ---------------------------
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 choose
44  *     the primary or secondary ip of veth1 as the local ip of tunnel. The
45  *     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 #define IP6_ADDR_TUNL_DEV0 "fc80::100"
75 #define IP6_ADDR_TUNL_DEV1 "fc80::200"
76 
77 #define IP6_ADDR_VETH0 "::11"
78 #define IP6_ADDR1_VETH1 "::22"
79 #define IP6_ADDR2_VETH1 "::bb"
80 
81 #define IP4_ADDR1_HEX_VETH1 0xac1001c8
82 #define IP4_ADDR2_HEX_VETH1 0xac100114
83 #define IP6_ADDR1_HEX_VETH1 0x22
84 #define IP6_ADDR2_HEX_VETH1 0xbb
85 
86 #define MAC_TUNL_DEV0 "52:54:00:d9:01:00"
87 #define MAC_TUNL_DEV1 "52:54:00:d9:02:00"
88 #define MAC_VETH1 "52:54:00:d9:03:00"
89 
90 #define VXLAN_TUNL_DEV0 "vxlan00"
91 #define VXLAN_TUNL_DEV1 "vxlan11"
92 #define IP6VXLAN_TUNL_DEV0 "ip6vxlan00"
93 #define IP6VXLAN_TUNL_DEV1 "ip6vxlan11"
94 
95 #define IPIP_TUNL_DEV0 "ipip00"
96 #define IPIP_TUNL_DEV1 "ipip11"
97 
98 #define XFRM_AUTH "0x1111111111111111111111111111111111111111"
99 #define XFRM_ENC "0x22222222222222222222222222222222"
100 #define XFRM_SPI_IN_TO_OUT 0x1
101 #define XFRM_SPI_OUT_TO_IN 0x2
102 
103 #define GRE_TUNL_DEV0 "gre00"
104 #define GRE_TUNL_DEV1 "gre11"
105 
106 #define IP6GRE_TUNL_DEV0 "ip6gre00"
107 #define IP6GRE_TUNL_DEV1 "ip6gre11"
108 
109 #define ERSPAN_TUNL_DEV0 "erspan00"
110 #define ERSPAN_TUNL_DEV1 "erspan11"
111 
112 #define IP6ERSPAN_TUNL_DEV0 "ip6erspan00"
113 #define IP6ERSPAN_TUNL_DEV1 "ip6erspan11"
114 
115 #define GENEVE_TUNL_DEV0 "geneve00"
116 #define GENEVE_TUNL_DEV1 "geneve11"
117 
118 #define IP6GENEVE_TUNL_DEV0 "ip6geneve00"
119 #define IP6GENEVE_TUNL_DEV1 "ip6geneve11"
120 
121 #define IP6TNL_TUNL_DEV0 "ip6tnl00"
122 #define IP6TNL_TUNL_DEV1 "ip6tnl11"
123 
124 #define PING_ARGS "-i 0.01 -c 3 -w 10 -q"
125 
config_device(void)126 static int config_device(void)
127 {
128 	SYS(fail, "ip netns add at_ns0");
129 	SYS(fail, "ip link add veth0 address " MAC_VETH1 " type veth peer name veth1");
130 	SYS(fail, "ip link set veth0 netns at_ns0");
131 	SYS(fail, "ip addr add " IP4_ADDR1_VETH1 "/24 dev veth1");
132 	SYS(fail, "ip link set dev veth1 up mtu 1500");
133 	SYS(fail, "ip netns exec at_ns0 ip addr add " IP4_ADDR_VETH0 "/24 dev veth0");
134 	SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up mtu 1500");
135 
136 	return 0;
137 fail:
138 	return -1;
139 }
140 
cleanup(void)141 static void cleanup(void)
142 {
143 	SYS_NOFAIL("test -f /var/run/netns/at_ns0 && ip netns delete at_ns0");
144 	SYS_NOFAIL("ip link del veth1");
145 	SYS_NOFAIL("ip link del %s", VXLAN_TUNL_DEV1);
146 	SYS_NOFAIL("ip link del %s", IP6VXLAN_TUNL_DEV1);
147 }
148 
add_vxlan_tunnel(void)149 static int add_vxlan_tunnel(void)
150 {
151 	/* at_ns0 namespace */
152 	SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external gbp dstport 4789",
153 	    VXLAN_TUNL_DEV0);
154 	SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up",
155 	    VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);
156 	SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24",
157 	    VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);
158 	SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev %s",
159 	    IP4_ADDR_TUNL_DEV1, MAC_TUNL_DEV1, VXLAN_TUNL_DEV0);
160 	SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev veth0",
161 	    IP4_ADDR2_VETH1, MAC_VETH1);
162 
163 	/* root namespace */
164 	SYS(fail, "ip link add dev %s type vxlan external gbp dstport 4789",
165 	    VXLAN_TUNL_DEV1);
166 	SYS(fail, "ip link set dev %s address %s up", VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);
167 	SYS(fail, "ip addr add dev %s %s/24", VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);
168 	SYS(fail, "ip neigh add %s lladdr %s dev %s",
169 	    IP4_ADDR_TUNL_DEV0, MAC_TUNL_DEV0, VXLAN_TUNL_DEV1);
170 
171 	return 0;
172 fail:
173 	return -1;
174 }
175 
delete_vxlan_tunnel(void)176 static void delete_vxlan_tunnel(void)
177 {
178 	SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",
179 		   VXLAN_TUNL_DEV0);
180 	SYS_NOFAIL("ip link delete dev %s", VXLAN_TUNL_DEV1);
181 }
182 
add_ip6vxlan_tunnel(void)183 static int add_ip6vxlan_tunnel(void)
184 {
185 	SYS(fail, "ip netns exec at_ns0 ip -6 addr add %s/96 dev veth0",
186 	    IP6_ADDR_VETH0);
187 	SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up");
188 	SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR1_VETH1);
189 	SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR2_VETH1);
190 	SYS(fail, "ip link set dev veth1 up");
191 
192 	/* at_ns0 namespace */
193 	SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external dstport 4789",
194 	    IP6VXLAN_TUNL_DEV0);
195 	SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24",
196 	    IP6VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);
197 	SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up",
198 	    IP6VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);
199 
200 	/* root namespace */
201 	SYS(fail, "ip link add dev %s type vxlan external dstport 4789",
202 	    IP6VXLAN_TUNL_DEV1);
203 	SYS(fail, "ip addr add dev %s %s/24", IP6VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);
204 	SYS(fail, "ip link set dev %s address %s up",
205 	    IP6VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);
206 
207 	return 0;
208 fail:
209 	return -1;
210 }
211 
delete_ip6vxlan_tunnel(void)212 static void delete_ip6vxlan_tunnel(void)
213 {
214 	SYS_NOFAIL("ip netns exec at_ns0 ip -6 addr delete %s/96 dev veth0",
215 		   IP6_ADDR_VETH0);
216 	SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR1_VETH1);
217 	SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR2_VETH1);
218 	SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",
219 		   IP6VXLAN_TUNL_DEV0);
220 	SYS_NOFAIL("ip link delete dev %s", IP6VXLAN_TUNL_DEV1);
221 }
222 
223 enum ipip_encap {
224 	NONE	= 0,
225 	FOU	= 1,
226 	GUE	= 2,
227 };
228 
set_ipip_encap(const char * ipproto,const char * type)229 static int set_ipip_encap(const char *ipproto, const char *type)
230 {
231 	SYS(fail, "ip -n at_ns0 fou add port 5555 %s", ipproto);
232 	SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap %s",
233 	    IPIP_TUNL_DEV0, type);
234 	SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap-dport 5555",
235 	    IPIP_TUNL_DEV0);
236 
237 	return 0;
238 fail:
239 	return -1;
240 }
241 
set_ipv4_addr(const char * dev0,const char * dev1)242 static int set_ipv4_addr(const char *dev0, const char *dev1)
243 {
244 	SYS(fail, "ip -n at_ns0 link set dev %s up", dev0);
245 	SYS(fail, "ip -n at_ns0 addr add dev %s %s/24", dev0, IP4_ADDR_TUNL_DEV0);
246 	SYS(fail, "ip link set dev %s up", dev1);
247 	SYS(fail, "ip addr add dev %s %s/24", dev1, IP4_ADDR_TUNL_DEV1);
248 
249 	return 0;
250 fail:
251 	return 1;
252 }
253 
add_ipip_tunnel(enum ipip_encap encap)254 static int add_ipip_tunnel(enum ipip_encap encap)
255 {
256 	int err;
257 	const char *ipproto, *type;
258 
259 	switch (encap) {
260 	case FOU:
261 		ipproto = "ipproto 4";
262 		type = "fou";
263 		break;
264 	case GUE:
265 		ipproto = "gue";
266 		type = ipproto;
267 		break;
268 	default:
269 		ipproto = NULL;
270 		type = ipproto;
271 	}
272 
273 	/* at_ns0 namespace */
274 	SYS(fail, "ip -n at_ns0 link add dev %s type ipip local %s remote %s",
275 	    IPIP_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
276 
277 	if (type && ipproto) {
278 		err = set_ipip_encap(ipproto, type);
279 		if (!ASSERT_OK(err, "set_ipip_encap"))
280 			goto fail;
281 	}
282 
283 	SYS(fail, "ip -n at_ns0 link set dev %s up", IPIP_TUNL_DEV0);
284 	SYS(fail, "ip -n at_ns0 addr add dev %s %s/24",
285 	    IPIP_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);
286 
287 	/* root namespace */
288 	if (type && ipproto)
289 		SYS(fail, "ip fou add port 5555 %s", ipproto);
290 	SYS(fail, "ip link add dev %s type ipip external", IPIP_TUNL_DEV1);
291 	SYS(fail, "ip link set dev %s up", IPIP_TUNL_DEV1);
292 	SYS(fail, "ip addr add dev %s %s/24", IPIP_TUNL_DEV1,
293 	    IP4_ADDR_TUNL_DEV1);
294 
295 	return 0;
296 fail:
297 	return -1;
298 }
299 
delete_ipip_tunnel(void)300 static void delete_ipip_tunnel(void)
301 {
302 	SYS_NOFAIL("ip -n at_ns0 link delete dev %s", IPIP_TUNL_DEV0);
303 	SYS_NOFAIL("ip -n at_ns0 fou del port 5555");
304 	SYS_NOFAIL("ip link delete dev %s", IPIP_TUNL_DEV1);
305 	SYS_NOFAIL("ip fou del port 5555");
306 }
307 
add_xfrm_tunnel(void)308 static int add_xfrm_tunnel(void)
309 {
310 	/* at_ns0 namespace
311 	 * at_ns0 -> root
312 	 */
313 	SYS(fail,
314 	    "ip netns exec at_ns0 "
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 netns exec at_ns0 "
321 		"ip xfrm policy add src %s/32 dst %s/32 dir out "
322 			"tmpl src %s dst %s proto esp reqid 1 "
323 			"mode tunnel",
324 	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
325 
326 	/* root -> at_ns0 */
327 	SYS(fail,
328 	    "ip netns exec at_ns0 "
329 		"ip xfrm state add src %s dst %s proto esp "
330 			"spi %d reqid 2 mode tunnel "
331 			"auth-trunc 'hmac(sha1)' %s 96 enc 'cbc(aes)' %s",
332 	    IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
333 	SYS(fail,
334 	    "ip netns exec at_ns0 "
335 		"ip xfrm policy add src %s/32 dst %s/32 dir in "
336 			"tmpl src %s dst %s proto esp reqid 2 "
337 			"mode tunnel",
338 	    IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
339 
340 	/* address & route */
341 	SYS(fail, "ip netns exec at_ns0 ip addr add dev veth0 %s/32",
342 	    IP4_ADDR_TUNL_DEV0);
343 	SYS(fail, "ip netns exec at_ns0 ip route add %s dev veth0 via %s src %s",
344 	    IP4_ADDR_TUNL_DEV1, IP4_ADDR1_VETH1, IP4_ADDR_TUNL_DEV0);
345 
346 	/* root namespace
347 	 * at_ns0 -> root
348 	 */
349 	SYS(fail,
350 	    "ip xfrm state add src %s dst %s proto esp "
351 		    "spi %d reqid 1 mode tunnel replay-window 42 "
352 		    "auth-trunc 'hmac(sha1)' %s 96  enc 'cbc(aes)' %s",
353 	    IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT, XFRM_AUTH, XFRM_ENC);
354 	SYS(fail,
355 	    "ip xfrm policy add src %s/32 dst %s/32 dir in "
356 		    "tmpl src %s dst %s proto esp reqid 1 "
357 		    "mode tunnel",
358 	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
359 
360 	/* root -> at_ns0 */
361 	SYS(fail,
362 	    "ip xfrm state add src %s dst %s proto esp "
363 		    "spi %d reqid 2 mode tunnel "
364 		    "auth-trunc 'hmac(sha1)' %s 96  enc 'cbc(aes)' %s",
365 	    IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN, XFRM_AUTH, XFRM_ENC);
366 	SYS(fail,
367 	    "ip xfrm policy add src %s/32 dst %s/32 dir out "
368 		    "tmpl src %s dst %s proto esp reqid 2 "
369 		    "mode tunnel",
370 	    IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0, IP4_ADDR1_VETH1, IP4_ADDR_VETH0);
371 
372 	/* address & route */
373 	SYS(fail, "ip addr add dev veth1 %s/32", IP4_ADDR_TUNL_DEV1);
374 	SYS(fail, "ip route add %s dev veth1 via %s src %s",
375 	    IP4_ADDR_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR_TUNL_DEV1);
376 
377 	return 0;
378 fail:
379 	return -1;
380 }
381 
delete_xfrm_tunnel(void)382 static void delete_xfrm_tunnel(void)
383 {
384 	SYS_NOFAIL("ip xfrm policy delete dir out src %s/32 dst %s/32",
385 		   IP4_ADDR_TUNL_DEV1, IP4_ADDR_TUNL_DEV0);
386 	SYS_NOFAIL("ip xfrm policy delete dir in src %s/32 dst %s/32",
387 		   IP4_ADDR_TUNL_DEV0, IP4_ADDR_TUNL_DEV1);
388 	SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d",
389 		   IP4_ADDR_VETH0, IP4_ADDR1_VETH1, XFRM_SPI_IN_TO_OUT);
390 	SYS_NOFAIL("ip xfrm state delete src %s dst %s proto esp spi %d",
391 		   IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN);
392 }
393 
add_ipv4_tunnel(const char * dev0,const char * dev1,const char * type,const char * opt)394 static int add_ipv4_tunnel(const char *dev0, const char *dev1,
395 			   const char *type, const char *opt)
396 {
397 	if (!type || !opt || !dev0 || !dev1)
398 		return -1;
399 
400 	SYS(fail, "ip -n at_ns0 link add dev %s type %s %s local %s remote %s",
401 	    dev0, type, opt, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
402 
403 	SYS(fail, "ip link add dev %s type %s external", dev1, type);
404 
405 	return set_ipv4_addr(dev0, dev1);
406 fail:
407 	return -1;
408 }
409 
delete_tunnel(const char * dev0,const char * dev1)410 static void delete_tunnel(const char *dev0, const char *dev1)
411 {
412 	if (!dev0 || !dev1)
413 		return;
414 
415 	SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s", dev0);
416 	SYS_NOFAIL("ip link delete dev %s", dev1);
417 }
418 
set_ipv6_addr(const char * dev0,const char * dev1)419 static int set_ipv6_addr(const char *dev0, const char *dev1)
420 {
421 	/* disable IPv6 DAD because it might take too long and fail tests */
422 	SYS(fail, "ip -n at_ns0 addr add %s/96 dev veth0 nodad", IP6_ADDR_VETH0);
423 	SYS(fail, "ip -n at_ns0 link set dev veth0 up");
424 	SYS(fail, "ip addr add %s/96 dev veth1 nodad", IP6_ADDR1_VETH1);
425 	SYS(fail, "ip link set dev veth1 up");
426 
427 	SYS(fail, "ip -n at_ns0 addr add dev %s %s/24", dev0, IP4_ADDR_TUNL_DEV0);
428 	SYS(fail, "ip -n at_ns0 addr add dev %s %s/96 nodad", dev0, IP6_ADDR_TUNL_DEV0);
429 	SYS(fail, "ip -n at_ns0 link set dev %s up", dev0);
430 
431 	SYS(fail, "ip addr add dev %s %s/24", dev1, IP4_ADDR_TUNL_DEV1);
432 	SYS(fail, "ip addr add dev %s %s/96 nodad", dev1, IP6_ADDR_TUNL_DEV1);
433 	SYS(fail, "ip link set dev %s up", dev1);
434 	return 0;
435 fail:
436 	return 1;
437 }
438 
add_ipv6_tunnel(const char * dev0,const char * dev1,const char * type,const char * opt)439 static int add_ipv6_tunnel(const char *dev0, const char *dev1,
440 			   const char *type, const char *opt)
441 {
442 	if (!type || !opt || !dev0 || !dev1)
443 		return -1;
444 
445 	SYS(fail, "ip -n at_ns0 link add dev %s type %s %s local %s remote %s",
446 	    dev0, type, opt, IP6_ADDR_VETH0, IP6_ADDR1_VETH1);
447 
448 	SYS(fail, "ip link add dev %s type %s external", dev1, type);
449 
450 	return set_ipv6_addr(dev0, dev1);
451 fail:
452 	return -1;
453 }
454 
add_geneve_tunnel(const char * dev0,const char * dev1,const char * type,const char * opt)455 static int add_geneve_tunnel(const char *dev0, const char *dev1,
456 			     const char *type, const char *opt)
457 {
458 	if (!type || !opt || !dev0 || !dev1)
459 		return -1;
460 
461 	SYS(fail, "ip -n at_ns0 link add dev %s type %s id 2 %s remote %s",
462 	    dev0, type, opt, IP4_ADDR1_VETH1);
463 
464 	SYS(fail, "ip link add dev %s type %s %s external", dev1, type, opt);
465 
466 	return set_ipv4_addr(dev0, dev1);
467 fail:
468 	return -1;
469 }
470 
add_ip6geneve_tunnel(const char * dev0,const char * dev1,const char * type,const char * opt)471 static int add_ip6geneve_tunnel(const char *dev0, const char *dev1,
472 			     const char *type, const char *opt)
473 {
474 	if (!type || !opt || !dev0 || !dev1)
475 		return -1;
476 
477 	SYS(fail, "ip -n at_ns0 link add dev %s type %s id 22 %s remote %s",
478 	    dev0, type, opt, IP6_ADDR1_VETH1);
479 
480 	SYS(fail, "ip link add dev %s type %s %s external", dev1, type, opt);
481 
482 	return set_ipv6_addr(dev0, dev1);
483 fail:
484 	return -1;
485 }
486 
test_ping(int family,const char * addr)487 static int test_ping(int family, const char *addr)
488 {
489 	SYS(fail, "%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr);
490 	return 0;
491 fail:
492 	return -1;
493 }
494 
ping_dev0(void)495 static void ping_dev0(void)
496 {
497 	/* ping from root namespace test */
498 	test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
499 }
500 
ping_dev1(void)501 static void ping_dev1(void)
502 {
503 	struct nstoken *nstoken;
504 
505 	/* ping from at_ns0 namespace test */
506 	nstoken = open_netns("at_ns0");
507 	if (!ASSERT_OK_PTR(nstoken, "setns"))
508 		return;
509 
510 	test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
511 	close_netns(nstoken);
512 }
513 
ping6_veth0(void)514 static void ping6_veth0(void)
515 {
516 	test_ping(AF_INET6, IP6_ADDR_VETH0);
517 }
518 
ping6_dev0(void)519 static void ping6_dev0(void)
520 {
521 	test_ping(AF_INET6, IP6_ADDR_TUNL_DEV0);
522 }
523 
ping6_dev1(void)524 static void ping6_dev1(void)
525 {
526 	struct nstoken *nstoken;
527 
528 	/* ping from at_ns0 namespace test */
529 	nstoken = open_netns("at_ns0");
530 	if (!ASSERT_OK_PTR(nstoken, "setns"))
531 		return;
532 
533 	test_ping(AF_INET, IP6_ADDR_TUNL_DEV1);
534 	close_netns(nstoken);
535 }
536 
attach_tc_prog(int ifindex,int igr_fd,int egr_fd)537 static int attach_tc_prog(int ifindex, int igr_fd, int egr_fd)
538 {
539 	DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = ifindex,
540 			    .attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS);
541 	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,
542 			    .priority = 1, .prog_fd = igr_fd);
543 	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,
544 			    .priority = 1, .prog_fd = egr_fd);
545 	int ret;
546 
547 	ret = bpf_tc_hook_create(&hook);
548 	if (!ASSERT_OK(ret, "create tc hook"))
549 		return ret;
550 
551 	if (igr_fd >= 0) {
552 		hook.attach_point = BPF_TC_INGRESS;
553 		ret = bpf_tc_attach(&hook, &opts1);
554 		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
555 			bpf_tc_hook_destroy(&hook);
556 			return ret;
557 		}
558 	}
559 
560 	if (egr_fd >= 0) {
561 		hook.attach_point = BPF_TC_EGRESS;
562 		ret = bpf_tc_attach(&hook, &opts2);
563 		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
564 			bpf_tc_hook_destroy(&hook);
565 			return ret;
566 		}
567 	}
568 
569 	return 0;
570 }
571 
generic_attach(const char * dev,int igr_fd,int egr_fd)572 static int generic_attach(const char *dev, int igr_fd, int egr_fd)
573 {
574 	int ifindex;
575 
576 	if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
577 		return -1;
578 	if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
579 		return -1;
580 
581 	ifindex = if_nametoindex(dev);
582 	if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
583 		return -1;
584 
585 	return attach_tc_prog(ifindex, igr_fd, egr_fd);
586 }
587 
generic_attach_igr(const char * dev,int igr_fd)588 static int generic_attach_igr(const char *dev, int igr_fd)
589 {
590 	int ifindex;
591 
592 	if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
593 		return -1;
594 
595 	ifindex = if_nametoindex(dev);
596 	if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
597 		return -1;
598 
599 	return attach_tc_prog(ifindex, igr_fd, -1);
600 }
601 
generic_attach_egr(const char * dev,int egr_fd)602 static int generic_attach_egr(const char *dev, int egr_fd)
603 {
604 	int ifindex;
605 
606 	if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
607 		return -1;
608 
609 	ifindex = if_nametoindex(dev);
610 	if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
611 		return -1;
612 
613 	return attach_tc_prog(ifindex, -1, egr_fd);
614 }
615 
test_vxlan_tunnel(void)616 static void test_vxlan_tunnel(void)
617 {
618 	struct test_tunnel_kern *skel = NULL;
619 	struct nstoken *nstoken;
620 	int local_ip_map_fd = -1;
621 	int set_src_prog_fd, get_src_prog_fd;
622 	int set_dst_prog_fd;
623 	int key = 0;
624 	uint local_ip;
625 	int err;
626 
627 	/* add vxlan tunnel */
628 	err = add_vxlan_tunnel();
629 	if (!ASSERT_OK(err, "add vxlan tunnel"))
630 		goto done;
631 
632 	/* load and attach bpf prog to tunnel dev tc hook point */
633 	skel = test_tunnel_kern__open_and_load();
634 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
635 		goto done;
636 	get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);
637 	set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);
638 	if (generic_attach(VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
639 		goto done;
640 
641 	/* load and attach bpf prog to veth dev tc hook point */
642 	set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);
643 	if (generic_attach_igr("veth1", set_dst_prog_fd))
644 		goto done;
645 
646 	/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
647 	nstoken = open_netns("at_ns0");
648 	if (!ASSERT_OK_PTR(nstoken, "setns src"))
649 		goto done;
650 	set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);
651 	if (generic_attach_egr(VXLAN_TUNL_DEV0, set_dst_prog_fd))
652 		goto done;
653 	close_netns(nstoken);
654 
655 	/* use veth1 ip 2 as tunnel source ip */
656 	local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
657 	if (!ASSERT_GE(local_ip_map_fd, 0, "bpf_map__fd"))
658 		goto done;
659 	local_ip = IP4_ADDR2_HEX_VETH1;
660 	err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
661 	if (!ASSERT_OK(err, "update bpf local_ip_map"))
662 		goto done;
663 
664 	/* ping test */
665 	ping_dev0();
666 
667 done:
668 	/* delete vxlan tunnel */
669 	delete_vxlan_tunnel();
670 	if (local_ip_map_fd >= 0)
671 		close(local_ip_map_fd);
672 	if (skel)
673 		test_tunnel_kern__destroy(skel);
674 }
675 
test_ip6vxlan_tunnel(void)676 static void test_ip6vxlan_tunnel(void)
677 {
678 	struct test_tunnel_kern *skel = NULL;
679 	struct nstoken *nstoken;
680 	int local_ip_map_fd = -1;
681 	int set_src_prog_fd, get_src_prog_fd;
682 	int set_dst_prog_fd;
683 	int key = 0;
684 	uint local_ip;
685 	int err;
686 
687 	/* add vxlan tunnel */
688 	err = add_ip6vxlan_tunnel();
689 	if (!ASSERT_OK(err, "add_ip6vxlan_tunnel"))
690 		goto done;
691 
692 	/* load and attach bpf prog to tunnel dev tc hook point */
693 	skel = test_tunnel_kern__open_and_load();
694 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
695 		goto done;
696 	get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);
697 	set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);
698 	if (generic_attach(IP6VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
699 		goto done;
700 
701 	/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
702 	nstoken = open_netns("at_ns0");
703 	if (!ASSERT_OK_PTR(nstoken, "setns src"))
704 		goto done;
705 	set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);
706 	if (generic_attach_egr(IP6VXLAN_TUNL_DEV0, set_dst_prog_fd))
707 		goto done;
708 	close_netns(nstoken);
709 
710 	/* use veth1 ip 2 as tunnel source ip */
711 	local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
712 	if (!ASSERT_GE(local_ip_map_fd, 0, "get local_ip_map fd"))
713 		goto done;
714 	local_ip = IP6_ADDR2_HEX_VETH1;
715 	err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
716 	if (!ASSERT_OK(err, "update bpf local_ip_map"))
717 		goto done;
718 
719 	/* ping test */
720 	ping_dev0();
721 
722 done:
723 	/* delete ipv6 vxlan tunnel */
724 	delete_ip6vxlan_tunnel();
725 	if (local_ip_map_fd >= 0)
726 		close(local_ip_map_fd);
727 	if (skel)
728 		test_tunnel_kern__destroy(skel);
729 }
730 
test_ipip_tunnel(enum ipip_encap encap)731 static void test_ipip_tunnel(enum ipip_encap encap)
732 {
733 	struct test_tunnel_kern *skel = NULL;
734 	int set_src_prog_fd, get_src_prog_fd;
735 	int err;
736 
737 	/* add ipip tunnel */
738 	err = add_ipip_tunnel(encap);
739 	if (!ASSERT_OK(err, "add_ipip_tunnel"))
740 		goto done;
741 
742 	/* load and attach bpf prog to tunnel dev tc hook point */
743 	skel = test_tunnel_kern__open_and_load();
744 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
745 		goto done;
746 
747 	switch (encap) {
748 	case FOU:
749 		get_src_prog_fd = bpf_program__fd(
750 			skel->progs.ipip_encap_get_tunnel);
751 		set_src_prog_fd = bpf_program__fd(
752 			skel->progs.ipip_fou_set_tunnel);
753 		break;
754 	case GUE:
755 		get_src_prog_fd = bpf_program__fd(
756 			skel->progs.ipip_encap_get_tunnel);
757 		set_src_prog_fd = bpf_program__fd(
758 			skel->progs.ipip_gue_set_tunnel);
759 		break;
760 	default:
761 		get_src_prog_fd = bpf_program__fd(
762 			skel->progs.ipip_get_tunnel);
763 		set_src_prog_fd = bpf_program__fd(
764 			skel->progs.ipip_set_tunnel);
765 	}
766 
767 	if (generic_attach(IPIP_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
768 		goto done;
769 
770 	ping_dev0();
771 	ping_dev1();
772 
773 done:
774 	/* delete ipip tunnel */
775 	delete_ipip_tunnel();
776 	if (skel)
777 		test_tunnel_kern__destroy(skel);
778 }
779 
test_xfrm_tunnel(void)780 static void test_xfrm_tunnel(void)
781 {
782 	LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
783 	struct test_tunnel_kern *skel = NULL;
784 	int xdp_prog_fd;
785 	int tc_prog_fd;
786 	int ifindex;
787 	int err;
788 
789 	err = add_xfrm_tunnel();
790 	if (!ASSERT_OK(err, "add_xfrm_tunnel"))
791 		return;
792 
793 	skel = test_tunnel_kern__open_and_load();
794 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
795 		goto done;
796 
797 
798 	/* attach tc prog to tunnel dev */
799 	tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
800 	if (generic_attach_igr("veth1", tc_prog_fd))
801 		goto done;
802 
803 	/* attach xdp prog to tunnel dev */
804 	ifindex = if_nametoindex("veth1");
805 	if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
806 		goto done;
807 	xdp_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state_xdp);
808 	if (!ASSERT_GE(xdp_prog_fd, 0, "bpf_program__fd"))
809 		goto done;
810 	err = bpf_xdp_attach(ifindex, xdp_prog_fd, XDP_FLAGS_REPLACE, &opts);
811 	if (!ASSERT_OK(err, "bpf_xdp_attach"))
812 		goto done;
813 
814 	ping_dev1();
815 
816 	if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))
817 		goto done;
818 	if (!ASSERT_EQ(skel->bss->xfrm_spi, XFRM_SPI_IN_TO_OUT, "spi"))
819 		goto done;
820 	if (!ASSERT_EQ(skel->bss->xfrm_remote_ip, 0xac100164, "remote_ip"))
821 		goto done;
822 	if (!ASSERT_EQ(skel->bss->xfrm_replay_window, 42, "replay_window"))
823 		goto done;
824 
825 done:
826 	delete_xfrm_tunnel();
827 	if (skel)
828 		test_tunnel_kern__destroy(skel);
829 }
830 
831 enum gre_test {
832 	GRE,
833 	GRE_NOKEY,
834 	GRETAP,
835 	GRETAP_NOKEY,
836 };
837 
test_gre_tunnel(enum gre_test test)838 static void test_gre_tunnel(enum gre_test test)
839 {
840 	struct test_tunnel_kern *skel;
841 	int set_fd, get_fd;
842 	int err;
843 
844 	skel = test_tunnel_kern__open_and_load();
845 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
846 		return;
847 
848 	switch (test) {
849 	case GRE:
850 		err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq");
851 		set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
852 		get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
853 		break;
854 	case GRE_NOKEY:
855 		err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq key 2");
856 		set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
857 		get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
858 		break;
859 	case GRETAP:
860 		err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq");
861 		set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
862 		get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
863 		break;
864 	case GRETAP_NOKEY:
865 		err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq key 2");
866 		set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
867 		get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
868 		break;
869 	}
870 	if (!ASSERT_OK(err, "add tunnel"))
871 		goto done;
872 
873 	if (generic_attach(GRE_TUNL_DEV1, get_fd, set_fd))
874 		goto done;
875 
876 	ping_dev0();
877 	ping_dev1();
878 
879 done:
880 	delete_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1);
881 	test_tunnel_kern__destroy(skel);
882 }
883 
884 enum ip6gre_test {
885 	IP6GRE,
886 	IP6GRETAP
887 };
888 
test_ip6gre_tunnel(enum ip6gre_test test)889 static void test_ip6gre_tunnel(enum ip6gre_test test)
890 {
891 	struct test_tunnel_kern *skel;
892 	int set_fd, get_fd;
893 	int err;
894 
895 	skel = test_tunnel_kern__open_and_load();
896 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
897 		return;
898 
899 	switch (test) {
900 	case IP6GRE:
901 		err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
902 				      "ip6gre", "flowlabel 0xbcdef key 2");
903 		break;
904 	case IP6GRETAP:
905 		err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
906 				      "ip6gretap", "flowlabel 0xbcdef key 2");
907 		break;
908 	}
909 	if (!ASSERT_OK(err, "add tunnel"))
910 		goto done;
911 
912 	set_fd = bpf_program__fd(skel->progs.ip6gretap_set_tunnel);
913 	get_fd = bpf_program__fd(skel->progs.ip6gretap_get_tunnel);
914 	if (generic_attach(IP6GRE_TUNL_DEV1, get_fd, set_fd))
915 		goto done;
916 
917 	ping6_veth0();
918 	ping6_dev1();
919 	ping_dev0();
920 	ping_dev1();
921 done:
922 	delete_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1);
923 	test_tunnel_kern__destroy(skel);
924 }
925 
926 enum erspan_test {
927 	V1,
928 	V2
929 };
930 
test_erspan_tunnel(enum erspan_test test)931 static void test_erspan_tunnel(enum erspan_test test)
932 {
933 	struct test_tunnel_kern *skel;
934 	int set_fd, get_fd;
935 	int err;
936 
937 	skel = test_tunnel_kern__open_and_load();
938 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
939 		return;
940 
941 	switch (test) {
942 	case V1:
943 		err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
944 				      "erspan", "seq key 2 erspan_ver 1 erspan 123");
945 		break;
946 	case V2:
947 		err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
948 				      "erspan",
949 				      "seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 3");
950 		break;
951 	}
952 	if (!ASSERT_OK(err, "add tunnel"))
953 		goto done;
954 
955 	set_fd = bpf_program__fd(skel->progs.erspan_set_tunnel);
956 	get_fd = bpf_program__fd(skel->progs.erspan_get_tunnel);
957 	if (generic_attach(ERSPAN_TUNL_DEV1, get_fd, set_fd))
958 		goto done;
959 
960 	ping_dev0();
961 	ping_dev1();
962 done:
963 	delete_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1);
964 	test_tunnel_kern__destroy(skel);
965 }
966 
test_ip6erspan_tunnel(enum erspan_test test)967 static void test_ip6erspan_tunnel(enum erspan_test test)
968 {
969 	struct test_tunnel_kern *skel;
970 	int set_fd, get_fd;
971 	int err;
972 
973 	skel = test_tunnel_kern__open_and_load();
974 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
975 		return;
976 
977 	switch (test) {
978 	case V1:
979 		err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
980 				      "ip6erspan", "seq key 2 erspan_ver 1 erspan 123");
981 		break;
982 	case V2:
983 		err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
984 				      "ip6erspan",
985 				      "seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 7");
986 		break;
987 	}
988 	if (!ASSERT_OK(err, "add tunnel"))
989 		goto done;
990 
991 	set_fd = bpf_program__fd(skel->progs.ip4ip6erspan_set_tunnel);
992 	get_fd = bpf_program__fd(skel->progs.ip4ip6erspan_get_tunnel);
993 	if (generic_attach(IP6ERSPAN_TUNL_DEV1, get_fd, set_fd))
994 		goto done;
995 
996 	ping6_veth0();
997 	ping_dev1();
998 done:
999 	delete_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1);
1000 	test_tunnel_kern__destroy(skel);
1001 }
1002 
test_geneve_tunnel(void)1003 static void test_geneve_tunnel(void)
1004 {
1005 	struct test_tunnel_kern *skel;
1006 	int set_fd, get_fd;
1007 	int err;
1008 
1009 	skel = test_tunnel_kern__open_and_load();
1010 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
1011 		return;
1012 
1013 	err = add_geneve_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1,
1014 				"geneve", "dstport 6081");
1015 	if (!ASSERT_OK(err, "add tunnel"))
1016 		goto done;
1017 
1018 	set_fd = bpf_program__fd(skel->progs.geneve_set_tunnel);
1019 	get_fd = bpf_program__fd(skel->progs.geneve_get_tunnel);
1020 	if (generic_attach(GENEVE_TUNL_DEV1, get_fd, set_fd))
1021 		goto done;
1022 
1023 	ping_dev0();
1024 	ping_dev1();
1025 done:
1026 	delete_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1);
1027 	test_tunnel_kern__destroy(skel);
1028 }
1029 
test_ip6geneve_tunnel(void)1030 static void test_ip6geneve_tunnel(void)
1031 {
1032 	struct test_tunnel_kern *skel;
1033 	int set_fd, get_fd;
1034 	int err;
1035 
1036 	skel = test_tunnel_kern__open_and_load();
1037 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
1038 		return;
1039 
1040 	err = add_ip6geneve_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1,
1041 				   "geneve", "");
1042 	if (!ASSERT_OK(err, "add tunnel"))
1043 		goto done;
1044 
1045 	set_fd = bpf_program__fd(skel->progs.ip6geneve_set_tunnel);
1046 	get_fd = bpf_program__fd(skel->progs.ip6geneve_get_tunnel);
1047 	if (generic_attach(IP6GENEVE_TUNL_DEV1, get_fd, set_fd))
1048 		goto done;
1049 
1050 	ping_dev0();
1051 	ping_dev1();
1052 done:
1053 	delete_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1);
1054 	test_tunnel_kern__destroy(skel);
1055 }
1056 
1057 enum ip6tnl_test {
1058 	IPIP6,
1059 	IP6IP6
1060 };
1061 
test_ip6tnl_tunnel(enum ip6tnl_test test)1062 static void test_ip6tnl_tunnel(enum ip6tnl_test test)
1063 {
1064 	struct test_tunnel_kern *skel;
1065 	int set_fd, get_fd;
1066 	int err;
1067 
1068 	skel = test_tunnel_kern__open_and_load();
1069 	if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
1070 		return;
1071 
1072 	err = add_ipv6_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1, "ip6tnl", "");
1073 	if (!ASSERT_OK(err, "add tunnel"))
1074 		goto done;
1075 
1076 	switch (test) {
1077 	case IPIP6:
1078 		set_fd = bpf_program__fd(skel->progs.ipip6_set_tunnel);
1079 		get_fd = bpf_program__fd(skel->progs.ipip6_get_tunnel);
1080 		break;
1081 	case IP6IP6:
1082 		set_fd = bpf_program__fd(skel->progs.ip6ip6_set_tunnel);
1083 		get_fd = bpf_program__fd(skel->progs.ip6ip6_get_tunnel);
1084 		break;
1085 	}
1086 	if (generic_attach(IP6TNL_TUNL_DEV1, get_fd, set_fd))
1087 		goto done;
1088 
1089 	ping6_veth0();
1090 	switch (test) {
1091 	case IPIP6:
1092 		ping_dev0();
1093 		ping_dev1();
1094 		break;
1095 	case IP6IP6:
1096 		ping6_dev0();
1097 		ping6_dev1();
1098 		break;
1099 	}
1100 
1101 done:
1102 	delete_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1);
1103 	test_tunnel_kern__destroy(skel);
1104 }
1105 
1106 #define RUN_TEST(name, ...)						\
1107 	({								\
1108 		if (test__start_subtest(#name)) {			\
1109 			config_device();				\
1110 			test_ ## name(__VA_ARGS__);			\
1111 			cleanup();					\
1112 		}							\
1113 	})
1114 
test_tunnel_run_tests(void * arg)1115 static void *test_tunnel_run_tests(void *arg)
1116 {
1117 	RUN_TEST(vxlan_tunnel);
1118 	RUN_TEST(ip6vxlan_tunnel);
1119 	RUN_TEST(ipip_tunnel, NONE);
1120 	RUN_TEST(ipip_tunnel, FOU);
1121 	RUN_TEST(ipip_tunnel, GUE);
1122 	RUN_TEST(xfrm_tunnel);
1123 	RUN_TEST(gre_tunnel, GRE);
1124 	RUN_TEST(gre_tunnel, GRE_NOKEY);
1125 	RUN_TEST(gre_tunnel, GRETAP);
1126 	RUN_TEST(gre_tunnel, GRETAP_NOKEY);
1127 	RUN_TEST(ip6gre_tunnel, IP6GRE);
1128 	RUN_TEST(ip6gre_tunnel, IP6GRETAP);
1129 	RUN_TEST(erspan_tunnel, V1);
1130 	RUN_TEST(erspan_tunnel, V2);
1131 	RUN_TEST(ip6erspan_tunnel, V1);
1132 	RUN_TEST(ip6erspan_tunnel, V2);
1133 	RUN_TEST(geneve_tunnel);
1134 	RUN_TEST(ip6geneve_tunnel);
1135 	RUN_TEST(ip6tnl_tunnel, IPIP6);
1136 	RUN_TEST(ip6tnl_tunnel, IP6IP6);
1137 
1138 	return NULL;
1139 }
1140 
test_tunnel(void)1141 void test_tunnel(void)
1142 {
1143 	pthread_t test_thread;
1144 	int err;
1145 
1146 	/* Run the tests in their own thread to isolate the namespace changes
1147 	 * so they do not affect the environment of other tests.
1148 	 * (specifically needed because of unshare(CLONE_NEWNS) in open_netns())
1149 	 */
1150 	err = pthread_create(&test_thread, NULL, &test_tunnel_run_tests, NULL);
1151 	if (ASSERT_OK(err, "pthread_create"))
1152 		ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join");
1153 }
1154