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
test_vxlan_tunnel(void)537 static void test_vxlan_tunnel(void)
538 {
539 struct test_tunnel_kern *skel = NULL;
540 struct nstoken *nstoken;
541 int local_ip_map_fd = -1;
542 int set_src_prog_fd, get_src_prog_fd;
543 int set_dst_prog_fd;
544 int key = 0;
545 uint local_ip;
546 int err;
547
548 /* add vxlan tunnel */
549 err = add_vxlan_tunnel();
550 if (!ASSERT_OK(err, "add vxlan tunnel"))
551 goto done;
552
553 /* load and attach bpf prog to tunnel dev tc hook point */
554 skel = test_tunnel_kern__open_and_load();
555 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
556 goto done;
557 get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);
558 set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);
559 if (tc_prog_attach(VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
560 goto done;
561
562 /* load and attach bpf prog to veth dev tc hook point */
563 set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);
564 if (tc_prog_attach("veth1", set_dst_prog_fd, -1))
565 goto done;
566
567 /* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
568 nstoken = open_netns("at_ns0");
569 if (!ASSERT_OK_PTR(nstoken, "setns src"))
570 goto done;
571 set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);
572 if (tc_prog_attach(VXLAN_TUNL_DEV0, -1, set_dst_prog_fd))
573 goto done;
574 close_netns(nstoken);
575
576 /* use veth1 ip 2 as tunnel source ip */
577 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
578 if (!ASSERT_GE(local_ip_map_fd, 0, "bpf_map__fd"))
579 goto done;
580 local_ip = IP4_ADDR2_HEX_VETH1;
581 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
582 if (!ASSERT_OK(err, "update bpf local_ip_map"))
583 goto done;
584
585 /* ping test */
586 ping_dev0();
587
588 done:
589 /* delete vxlan tunnel */
590 delete_vxlan_tunnel();
591 if (local_ip_map_fd >= 0)
592 close(local_ip_map_fd);
593 if (skel)
594 test_tunnel_kern__destroy(skel);
595 }
596
test_ip6vxlan_tunnel(void)597 static void test_ip6vxlan_tunnel(void)
598 {
599 struct test_tunnel_kern *skel = NULL;
600 struct nstoken *nstoken;
601 int local_ip_map_fd = -1;
602 int set_src_prog_fd, get_src_prog_fd;
603 int set_dst_prog_fd;
604 int key = 0;
605 uint local_ip;
606 int err;
607
608 /* add vxlan tunnel */
609 err = add_ip6vxlan_tunnel();
610 if (!ASSERT_OK(err, "add_ip6vxlan_tunnel"))
611 goto done;
612
613 /* load and attach bpf prog to tunnel dev tc hook point */
614 skel = test_tunnel_kern__open_and_load();
615 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
616 goto done;
617 get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);
618 set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);
619 if (tc_prog_attach(IP6VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
620 goto done;
621
622 /* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
623 nstoken = open_netns("at_ns0");
624 if (!ASSERT_OK_PTR(nstoken, "setns src"))
625 goto done;
626 set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);
627 if (tc_prog_attach(IP6VXLAN_TUNL_DEV0, -1, set_dst_prog_fd))
628 goto done;
629 close_netns(nstoken);
630
631 /* use veth1 ip 2 as tunnel source ip */
632 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
633 if (!ASSERT_GE(local_ip_map_fd, 0, "get local_ip_map fd"))
634 goto done;
635 local_ip = IP6_ADDR2_HEX_VETH1;
636 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
637 if (!ASSERT_OK(err, "update bpf local_ip_map"))
638 goto done;
639
640 /* ping test */
641 ping_dev0();
642
643 done:
644 /* delete ipv6 vxlan tunnel */
645 delete_ip6vxlan_tunnel();
646 if (local_ip_map_fd >= 0)
647 close(local_ip_map_fd);
648 if (skel)
649 test_tunnel_kern__destroy(skel);
650 }
651
test_ipip_tunnel(enum ipip_encap encap)652 static void test_ipip_tunnel(enum ipip_encap encap)
653 {
654 struct test_tunnel_kern *skel = NULL;
655 int set_src_prog_fd, get_src_prog_fd;
656 int err;
657
658 /* add ipip tunnel */
659 err = add_ipip_tunnel(encap);
660 if (!ASSERT_OK(err, "add_ipip_tunnel"))
661 goto done;
662
663 /* load and attach bpf prog to tunnel dev tc hook point */
664 skel = test_tunnel_kern__open_and_load();
665 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
666 goto done;
667
668 switch (encap) {
669 case FOU:
670 get_src_prog_fd = bpf_program__fd(
671 skel->progs.ipip_encap_get_tunnel);
672 set_src_prog_fd = bpf_program__fd(
673 skel->progs.ipip_fou_set_tunnel);
674 break;
675 case GUE:
676 get_src_prog_fd = bpf_program__fd(
677 skel->progs.ipip_encap_get_tunnel);
678 set_src_prog_fd = bpf_program__fd(
679 skel->progs.ipip_gue_set_tunnel);
680 break;
681 default:
682 get_src_prog_fd = bpf_program__fd(
683 skel->progs.ipip_get_tunnel);
684 set_src_prog_fd = bpf_program__fd(
685 skel->progs.ipip_set_tunnel);
686 }
687
688 if (tc_prog_attach(IPIP_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
689 goto done;
690
691 ping_dev0();
692 ping_dev1();
693
694 done:
695 /* delete ipip tunnel */
696 delete_ipip_tunnel();
697 if (skel)
698 test_tunnel_kern__destroy(skel);
699 }
700
test_xfrm_tunnel(void)701 static void test_xfrm_tunnel(void)
702 {
703 LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
704 struct test_tunnel_kern *skel = NULL;
705 int xdp_prog_fd;
706 int tc_prog_fd;
707 int ifindex;
708 int err;
709
710 err = add_xfrm_tunnel();
711 if (!ASSERT_OK(err, "add_xfrm_tunnel"))
712 return;
713
714 skel = test_tunnel_kern__open_and_load();
715 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
716 goto done;
717
718
719 /* attach tc prog to tunnel dev */
720 tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
721 if (tc_prog_attach("veth1", tc_prog_fd, -1))
722 goto done;
723
724 /* attach xdp prog to tunnel dev */
725 ifindex = if_nametoindex("veth1");
726 if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
727 goto done;
728 xdp_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state_xdp);
729 if (!ASSERT_GE(xdp_prog_fd, 0, "bpf_program__fd"))
730 goto done;
731 err = bpf_xdp_attach(ifindex, xdp_prog_fd, XDP_FLAGS_REPLACE, &opts);
732 if (!ASSERT_OK(err, "bpf_xdp_attach"))
733 goto done;
734
735 ping_dev1();
736
737 if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))
738 goto done;
739 if (!ASSERT_EQ(skel->bss->xfrm_spi, XFRM_SPI_IN_TO_OUT, "spi"))
740 goto done;
741 if (!ASSERT_EQ(skel->bss->xfrm_remote_ip, 0xac100164, "remote_ip"))
742 goto done;
743 if (!ASSERT_EQ(skel->bss->xfrm_replay_window, 42, "replay_window"))
744 goto done;
745
746 done:
747 delete_xfrm_tunnel();
748 if (skel)
749 test_tunnel_kern__destroy(skel);
750 }
751
752 enum gre_test {
753 GRE,
754 GRE_NOKEY,
755 GRETAP,
756 GRETAP_NOKEY,
757 };
758
test_gre_tunnel(enum gre_test test)759 static void test_gre_tunnel(enum gre_test test)
760 {
761 struct test_tunnel_kern *skel;
762 int set_fd, get_fd;
763 int err;
764
765 skel = test_tunnel_kern__open_and_load();
766 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
767 return;
768
769 switch (test) {
770 case GRE:
771 err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq");
772 set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
773 get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
774 break;
775 case GRE_NOKEY:
776 err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq key 2");
777 set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
778 get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
779 break;
780 case GRETAP:
781 err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq");
782 set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
783 get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
784 break;
785 case GRETAP_NOKEY:
786 err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq key 2");
787 set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
788 get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
789 break;
790 }
791 if (!ASSERT_OK(err, "add tunnel"))
792 goto done;
793
794 if (tc_prog_attach(GRE_TUNL_DEV1, get_fd, set_fd))
795 goto done;
796
797 ping_dev0();
798 ping_dev1();
799
800 done:
801 delete_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1);
802 test_tunnel_kern__destroy(skel);
803 }
804
805 enum ip6gre_test {
806 IP6GRE,
807 IP6GRETAP
808 };
809
test_ip6gre_tunnel(enum ip6gre_test test)810 static void test_ip6gre_tunnel(enum ip6gre_test test)
811 {
812 struct test_tunnel_kern *skel;
813 int set_fd, get_fd;
814 int err;
815
816 skel = test_tunnel_kern__open_and_load();
817 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
818 return;
819
820 switch (test) {
821 case IP6GRE:
822 err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
823 "ip6gre", "flowlabel 0xbcdef key 2");
824 break;
825 case IP6GRETAP:
826 err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
827 "ip6gretap", "flowlabel 0xbcdef key 2");
828 break;
829 }
830 if (!ASSERT_OK(err, "add tunnel"))
831 goto done;
832
833 set_fd = bpf_program__fd(skel->progs.ip6gretap_set_tunnel);
834 get_fd = bpf_program__fd(skel->progs.ip6gretap_get_tunnel);
835 if (tc_prog_attach(IP6GRE_TUNL_DEV1, get_fd, set_fd))
836 goto done;
837
838 ping6_veth0();
839 ping6_dev1();
840 ping_dev0();
841 ping_dev1();
842 done:
843 delete_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1);
844 test_tunnel_kern__destroy(skel);
845 }
846
847 enum erspan_test {
848 V1,
849 V2
850 };
851
test_erspan_tunnel(enum erspan_test test)852 static void test_erspan_tunnel(enum erspan_test test)
853 {
854 struct test_tunnel_kern *skel;
855 int set_fd, get_fd;
856 int err;
857
858 skel = test_tunnel_kern__open_and_load();
859 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
860 return;
861
862 switch (test) {
863 case V1:
864 err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
865 "erspan", "seq key 2 erspan_ver 1 erspan 123");
866 break;
867 case V2:
868 err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
869 "erspan",
870 "seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 3");
871 break;
872 }
873 if (!ASSERT_OK(err, "add tunnel"))
874 goto done;
875
876 set_fd = bpf_program__fd(skel->progs.erspan_set_tunnel);
877 get_fd = bpf_program__fd(skel->progs.erspan_get_tunnel);
878 if (tc_prog_attach(ERSPAN_TUNL_DEV1, get_fd, set_fd))
879 goto done;
880
881 ping_dev0();
882 ping_dev1();
883 done:
884 delete_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1);
885 test_tunnel_kern__destroy(skel);
886 }
887
test_ip6erspan_tunnel(enum erspan_test test)888 static void test_ip6erspan_tunnel(enum erspan_test test)
889 {
890 struct test_tunnel_kern *skel;
891 int set_fd, get_fd;
892 int err;
893
894 skel = test_tunnel_kern__open_and_load();
895 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
896 return;
897
898 switch (test) {
899 case V1:
900 err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
901 "ip6erspan", "seq key 2 erspan_ver 1 erspan 123");
902 break;
903 case V2:
904 err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
905 "ip6erspan",
906 "seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 7");
907 break;
908 }
909 if (!ASSERT_OK(err, "add tunnel"))
910 goto done;
911
912 set_fd = bpf_program__fd(skel->progs.ip4ip6erspan_set_tunnel);
913 get_fd = bpf_program__fd(skel->progs.ip4ip6erspan_get_tunnel);
914 if (tc_prog_attach(IP6ERSPAN_TUNL_DEV1, get_fd, set_fd))
915 goto done;
916
917 ping6_veth0();
918 ping_dev1();
919 done:
920 delete_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1);
921 test_tunnel_kern__destroy(skel);
922 }
923
test_geneve_tunnel(void)924 static void test_geneve_tunnel(void)
925 {
926 struct test_tunnel_kern *skel;
927 int set_fd, get_fd;
928 int err;
929
930 skel = test_tunnel_kern__open_and_load();
931 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
932 return;
933
934 err = add_geneve_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1,
935 "geneve", "dstport 6081");
936 if (!ASSERT_OK(err, "add tunnel"))
937 goto done;
938
939 set_fd = bpf_program__fd(skel->progs.geneve_set_tunnel);
940 get_fd = bpf_program__fd(skel->progs.geneve_get_tunnel);
941 if (tc_prog_attach(GENEVE_TUNL_DEV1, get_fd, set_fd))
942 goto done;
943
944 ping_dev0();
945 ping_dev1();
946 done:
947 delete_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1);
948 test_tunnel_kern__destroy(skel);
949 }
950
test_ip6geneve_tunnel(void)951 static void test_ip6geneve_tunnel(void)
952 {
953 struct test_tunnel_kern *skel;
954 int set_fd, get_fd;
955 int err;
956
957 skel = test_tunnel_kern__open_and_load();
958 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
959 return;
960
961 err = add_ip6geneve_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1,
962 "geneve", "");
963 if (!ASSERT_OK(err, "add tunnel"))
964 goto done;
965
966 set_fd = bpf_program__fd(skel->progs.ip6geneve_set_tunnel);
967 get_fd = bpf_program__fd(skel->progs.ip6geneve_get_tunnel);
968 if (tc_prog_attach(IP6GENEVE_TUNL_DEV1, get_fd, set_fd))
969 goto done;
970
971 ping_dev0();
972 ping_dev1();
973 done:
974 delete_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1);
975 test_tunnel_kern__destroy(skel);
976 }
977
978 enum ip6tnl_test {
979 IPIP6,
980 IP6IP6
981 };
982
test_ip6tnl_tunnel(enum ip6tnl_test test)983 static void test_ip6tnl_tunnel(enum ip6tnl_test test)
984 {
985 struct test_tunnel_kern *skel;
986 int set_fd, get_fd;
987 int err;
988
989 skel = test_tunnel_kern__open_and_load();
990 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
991 return;
992
993 err = add_ipv6_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1, "ip6tnl", "");
994 if (!ASSERT_OK(err, "add tunnel"))
995 goto done;
996
997 switch (test) {
998 case IPIP6:
999 set_fd = bpf_program__fd(skel->progs.ipip6_set_tunnel);
1000 get_fd = bpf_program__fd(skel->progs.ipip6_get_tunnel);
1001 break;
1002 case IP6IP6:
1003 set_fd = bpf_program__fd(skel->progs.ip6ip6_set_tunnel);
1004 get_fd = bpf_program__fd(skel->progs.ip6ip6_get_tunnel);
1005 break;
1006 }
1007 if (tc_prog_attach(IP6TNL_TUNL_DEV1, get_fd, set_fd))
1008 goto done;
1009
1010 ping6_veth0();
1011 switch (test) {
1012 case IPIP6:
1013 ping_dev0();
1014 ping_dev1();
1015 break;
1016 case IP6IP6:
1017 ping6_dev0();
1018 ping6_dev1();
1019 break;
1020 }
1021
1022 done:
1023 delete_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1);
1024 test_tunnel_kern__destroy(skel);
1025 }
1026
1027 #define RUN_TEST(name, ...) \
1028 ({ \
1029 if (test__start_subtest(#name)) { \
1030 config_device(); \
1031 test_ ## name(__VA_ARGS__); \
1032 cleanup(); \
1033 } \
1034 })
1035
test_tunnel_run_tests(void * arg)1036 static void *test_tunnel_run_tests(void *arg)
1037 {
1038 RUN_TEST(vxlan_tunnel);
1039 RUN_TEST(ip6vxlan_tunnel);
1040 RUN_TEST(ipip_tunnel, NONE);
1041 RUN_TEST(ipip_tunnel, FOU);
1042 RUN_TEST(ipip_tunnel, GUE);
1043 RUN_TEST(xfrm_tunnel);
1044 RUN_TEST(gre_tunnel, GRE);
1045 RUN_TEST(gre_tunnel, GRE_NOKEY);
1046 RUN_TEST(gre_tunnel, GRETAP);
1047 RUN_TEST(gre_tunnel, GRETAP_NOKEY);
1048 RUN_TEST(ip6gre_tunnel, IP6GRE);
1049 RUN_TEST(ip6gre_tunnel, IP6GRETAP);
1050 RUN_TEST(erspan_tunnel, V1);
1051 RUN_TEST(erspan_tunnel, V2);
1052 RUN_TEST(ip6erspan_tunnel, V1);
1053 RUN_TEST(ip6erspan_tunnel, V2);
1054 RUN_TEST(geneve_tunnel);
1055 RUN_TEST(ip6geneve_tunnel);
1056 RUN_TEST(ip6tnl_tunnel, IPIP6);
1057 RUN_TEST(ip6tnl_tunnel, IP6IP6);
1058
1059 return NULL;
1060 }
1061
test_tunnel(void)1062 void test_tunnel(void)
1063 {
1064 pthread_t test_thread;
1065 int err;
1066
1067 /* Run the tests in their own thread to isolate the namespace changes
1068 * so they do not affect the environment of other tests.
1069 * (specifically needed because of unshare(CLONE_NEWNS) in open_netns())
1070 */
1071 err = pthread_create(&test_thread, NULL, &test_tunnel_run_tests, NULL);
1072 if (ASSERT_OK(err, "pthread_create"))
1073 ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join");
1074 }
1075