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_tun.h> 54 #include <linux/limits.h> 55 #include <linux/sysctl.h> 56 #include <linux/time_types.h> 57 #include <linux/net_tstamp.h> 58 #include <net/if.h> 59 #include <stdbool.h> 60 #include <stdio.h> 61 #include <sys/stat.h> 62 #include <unistd.h> 63 64 #include "test_progs.h" 65 #include "network_helpers.h" 66 #include "test_tunnel_kern.skel.h" 67 68 #define IP4_ADDR_VETH0 "172.16.1.100" 69 #define IP4_ADDR1_VETH1 "172.16.1.200" 70 #define IP4_ADDR2_VETH1 "172.16.1.20" 71 #define IP4_ADDR_TUNL_DEV0 "10.1.1.100" 72 #define IP4_ADDR_TUNL_DEV1 "10.1.1.200" 73 74 #define IP6_ADDR_VETH0 "::11" 75 #define IP6_ADDR1_VETH1 "::22" 76 #define IP6_ADDR2_VETH1 "::bb" 77 78 #define IP4_ADDR1_HEX_VETH1 0xac1001c8 79 #define IP4_ADDR2_HEX_VETH1 0xac100114 80 #define IP6_ADDR1_HEX_VETH1 0x22 81 #define IP6_ADDR2_HEX_VETH1 0xbb 82 83 #define MAC_TUNL_DEV0 "52:54:00:d9:01:00" 84 #define MAC_TUNL_DEV1 "52:54:00:d9:02:00" 85 #define MAC_VETH1 "52:54:00:d9:03:00" 86 87 #define VXLAN_TUNL_DEV0 "vxlan00" 88 #define VXLAN_TUNL_DEV1 "vxlan11" 89 #define IP6VXLAN_TUNL_DEV0 "ip6vxlan00" 90 #define IP6VXLAN_TUNL_DEV1 "ip6vxlan11" 91 92 #define IPIP_TUNL_DEV0 "ipip00" 93 #define IPIP_TUNL_DEV1 "ipip11" 94 95 #define PING_ARGS "-i 0.01 -c 3 -w 10 -q" 96 97 static int config_device(void) 98 { 99 SYS(fail, "ip netns add at_ns0"); 100 SYS(fail, "ip link add veth0 address " MAC_VETH1 " type veth peer name veth1"); 101 SYS(fail, "ip link set veth0 netns at_ns0"); 102 SYS(fail, "ip addr add " IP4_ADDR1_VETH1 "/24 dev veth1"); 103 SYS(fail, "ip link set dev veth1 up mtu 1500"); 104 SYS(fail, "ip netns exec at_ns0 ip addr add " IP4_ADDR_VETH0 "/24 dev veth0"); 105 SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up mtu 1500"); 106 107 return 0; 108 fail: 109 return -1; 110 } 111 112 static void cleanup(void) 113 { 114 SYS_NOFAIL("test -f /var/run/netns/at_ns0 && ip netns delete at_ns0"); 115 SYS_NOFAIL("ip link del veth1 2> /dev/null"); 116 SYS_NOFAIL("ip link del %s 2> /dev/null", VXLAN_TUNL_DEV1); 117 SYS_NOFAIL("ip link del %s 2> /dev/null", IP6VXLAN_TUNL_DEV1); 118 } 119 120 static int add_vxlan_tunnel(void) 121 { 122 /* at_ns0 namespace */ 123 SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external gbp dstport 4789", 124 VXLAN_TUNL_DEV0); 125 SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up", 126 VXLAN_TUNL_DEV0, MAC_TUNL_DEV0); 127 SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24", 128 VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0); 129 SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev %s", 130 IP4_ADDR_TUNL_DEV1, MAC_TUNL_DEV1, VXLAN_TUNL_DEV0); 131 SYS(fail, "ip netns exec at_ns0 ip neigh add %s lladdr %s dev veth0", 132 IP4_ADDR2_VETH1, MAC_VETH1); 133 134 /* root namespace */ 135 SYS(fail, "ip link add dev %s type vxlan external gbp dstport 4789", 136 VXLAN_TUNL_DEV1); 137 SYS(fail, "ip link set dev %s address %s up", VXLAN_TUNL_DEV1, MAC_TUNL_DEV1); 138 SYS(fail, "ip addr add dev %s %s/24", VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1); 139 SYS(fail, "ip neigh add %s lladdr %s dev %s", 140 IP4_ADDR_TUNL_DEV0, MAC_TUNL_DEV0, VXLAN_TUNL_DEV1); 141 142 return 0; 143 fail: 144 return -1; 145 } 146 147 static void delete_vxlan_tunnel(void) 148 { 149 SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s", 150 VXLAN_TUNL_DEV0); 151 SYS_NOFAIL("ip link delete dev %s", VXLAN_TUNL_DEV1); 152 } 153 154 static int add_ip6vxlan_tunnel(void) 155 { 156 SYS(fail, "ip netns exec at_ns0 ip -6 addr add %s/96 dev veth0", 157 IP6_ADDR_VETH0); 158 SYS(fail, "ip netns exec at_ns0 ip link set dev veth0 up"); 159 SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR1_VETH1); 160 SYS(fail, "ip -6 addr add %s/96 dev veth1", IP6_ADDR2_VETH1); 161 SYS(fail, "ip link set dev veth1 up"); 162 163 /* at_ns0 namespace */ 164 SYS(fail, "ip netns exec at_ns0 ip link add dev %s type vxlan external dstport 4789", 165 IP6VXLAN_TUNL_DEV0); 166 SYS(fail, "ip netns exec at_ns0 ip addr add dev %s %s/24", 167 IP6VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0); 168 SYS(fail, "ip netns exec at_ns0 ip link set dev %s address %s up", 169 IP6VXLAN_TUNL_DEV0, MAC_TUNL_DEV0); 170 171 /* root namespace */ 172 SYS(fail, "ip link add dev %s type vxlan external dstport 4789", 173 IP6VXLAN_TUNL_DEV1); 174 SYS(fail, "ip addr add dev %s %s/24", IP6VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1); 175 SYS(fail, "ip link set dev %s address %s up", 176 IP6VXLAN_TUNL_DEV1, MAC_TUNL_DEV1); 177 178 return 0; 179 fail: 180 return -1; 181 } 182 183 static void delete_ip6vxlan_tunnel(void) 184 { 185 SYS_NOFAIL("ip netns exec at_ns0 ip -6 addr delete %s/96 dev veth0", 186 IP6_ADDR_VETH0); 187 SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR1_VETH1); 188 SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR2_VETH1); 189 SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s", 190 IP6VXLAN_TUNL_DEV0); 191 SYS_NOFAIL("ip link delete dev %s", IP6VXLAN_TUNL_DEV1); 192 } 193 194 enum ipip_encap { 195 NONE = 0, 196 FOU = 1, 197 GUE = 2, 198 }; 199 200 static int set_ipip_encap(const char *ipproto, const char *type) 201 { 202 SYS(fail, "ip -n at_ns0 fou add port 5555 %s", ipproto); 203 SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap %s", 204 IPIP_TUNL_DEV0, type); 205 SYS(fail, "ip -n at_ns0 link set dev %s type ipip encap-dport 5555", 206 IPIP_TUNL_DEV0); 207 208 return 0; 209 fail: 210 return -1; 211 } 212 213 static int add_ipip_tunnel(enum ipip_encap encap) 214 { 215 int err; 216 const char *ipproto, *type; 217 218 switch (encap) { 219 case FOU: 220 ipproto = "ipproto 4"; 221 type = "fou"; 222 break; 223 case GUE: 224 ipproto = "gue"; 225 type = ipproto; 226 break; 227 default: 228 ipproto = NULL; 229 type = ipproto; 230 } 231 232 /* at_ns0 namespace */ 233 SYS(fail, "ip -n at_ns0 link add dev %s type ipip local %s remote %s", 234 IPIP_TUNL_DEV0, IP4_ADDR_VETH0, IP4_ADDR1_VETH1); 235 236 if (type && ipproto) { 237 err = set_ipip_encap(ipproto, type); 238 if (!ASSERT_OK(err, "set_ipip_encap")) 239 goto fail; 240 } 241 242 SYS(fail, "ip -n at_ns0 link set dev %s up", IPIP_TUNL_DEV0); 243 SYS(fail, "ip -n at_ns0 addr add dev %s %s/24", 244 IPIP_TUNL_DEV0, IP4_ADDR_TUNL_DEV0); 245 246 /* root namespace */ 247 if (type && ipproto) 248 SYS(fail, "ip fou add port 5555 %s", ipproto); 249 SYS(fail, "ip link add dev %s type ipip external", IPIP_TUNL_DEV1); 250 SYS(fail, "ip link set dev %s up", IPIP_TUNL_DEV1); 251 SYS(fail, "ip addr add dev %s %s/24", IPIP_TUNL_DEV1, 252 IP4_ADDR_TUNL_DEV1); 253 254 return 0; 255 fail: 256 return -1; 257 } 258 259 static void delete_ipip_tunnel(void) 260 { 261 SYS_NOFAIL("ip -n at_ns0 link delete dev %s", IPIP_TUNL_DEV0); 262 SYS_NOFAIL("ip -n at_ns0 fou del port 5555 2> /dev/null"); 263 SYS_NOFAIL("ip link delete dev %s", IPIP_TUNL_DEV1); 264 SYS_NOFAIL("ip fou del port 5555 2> /dev/null"); 265 } 266 267 static int test_ping(int family, const char *addr) 268 { 269 SYS(fail, "%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr); 270 return 0; 271 fail: 272 return -1; 273 } 274 275 static int attach_tc_prog(struct bpf_tc_hook *hook, int igr_fd, int egr_fd) 276 { 277 DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1, 278 .priority = 1, .prog_fd = igr_fd); 279 DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1, 280 .priority = 1, .prog_fd = egr_fd); 281 int ret; 282 283 ret = bpf_tc_hook_create(hook); 284 if (!ASSERT_OK(ret, "create tc hook")) 285 return ret; 286 287 if (igr_fd >= 0) { 288 hook->attach_point = BPF_TC_INGRESS; 289 ret = bpf_tc_attach(hook, &opts1); 290 if (!ASSERT_OK(ret, "bpf_tc_attach")) { 291 bpf_tc_hook_destroy(hook); 292 return ret; 293 } 294 } 295 296 if (egr_fd >= 0) { 297 hook->attach_point = BPF_TC_EGRESS; 298 ret = bpf_tc_attach(hook, &opts2); 299 if (!ASSERT_OK(ret, "bpf_tc_attach")) { 300 bpf_tc_hook_destroy(hook); 301 return ret; 302 } 303 } 304 305 return 0; 306 } 307 308 static void test_vxlan_tunnel(void) 309 { 310 struct test_tunnel_kern *skel = NULL; 311 struct nstoken *nstoken; 312 int local_ip_map_fd = -1; 313 int set_src_prog_fd, get_src_prog_fd; 314 int set_dst_prog_fd; 315 int key = 0, ifindex = -1; 316 uint local_ip; 317 int err; 318 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook, 319 .attach_point = BPF_TC_INGRESS); 320 321 /* add vxlan tunnel */ 322 err = add_vxlan_tunnel(); 323 if (!ASSERT_OK(err, "add vxlan tunnel")) 324 goto done; 325 326 /* load and attach bpf prog to tunnel dev tc hook point */ 327 skel = test_tunnel_kern__open_and_load(); 328 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load")) 329 goto done; 330 ifindex = if_nametoindex(VXLAN_TUNL_DEV1); 331 if (!ASSERT_NEQ(ifindex, 0, "vxlan11 ifindex")) 332 goto done; 333 tc_hook.ifindex = ifindex; 334 get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src); 335 set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src); 336 if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd")) 337 goto done; 338 if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd")) 339 goto done; 340 if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd)) 341 goto done; 342 343 /* load and attach bpf prog to veth dev tc hook point */ 344 ifindex = if_nametoindex("veth1"); 345 if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex")) 346 goto done; 347 tc_hook.ifindex = ifindex; 348 set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst); 349 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd")) 350 goto done; 351 if (attach_tc_prog(&tc_hook, set_dst_prog_fd, -1)) 352 goto done; 353 354 /* load and attach prog set_md to tunnel dev tc hook point at_ns0 */ 355 nstoken = open_netns("at_ns0"); 356 if (!ASSERT_OK_PTR(nstoken, "setns src")) 357 goto done; 358 ifindex = if_nametoindex(VXLAN_TUNL_DEV0); 359 if (!ASSERT_NEQ(ifindex, 0, "vxlan00 ifindex")) 360 goto done; 361 tc_hook.ifindex = ifindex; 362 set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst); 363 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd")) 364 goto done; 365 if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd)) 366 goto done; 367 close_netns(nstoken); 368 369 /* use veth1 ip 2 as tunnel source ip */ 370 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map); 371 if (!ASSERT_GE(local_ip_map_fd, 0, "bpf_map__fd")) 372 goto done; 373 local_ip = IP4_ADDR2_HEX_VETH1; 374 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY); 375 if (!ASSERT_OK(err, "update bpf local_ip_map")) 376 goto done; 377 378 /* ping test */ 379 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0); 380 if (!ASSERT_OK(err, "test_ping")) 381 goto done; 382 383 done: 384 /* delete vxlan tunnel */ 385 delete_vxlan_tunnel(); 386 if (local_ip_map_fd >= 0) 387 close(local_ip_map_fd); 388 if (skel) 389 test_tunnel_kern__destroy(skel); 390 } 391 392 static void test_ip6vxlan_tunnel(void) 393 { 394 struct test_tunnel_kern *skel = NULL; 395 struct nstoken *nstoken; 396 int local_ip_map_fd = -1; 397 int set_src_prog_fd, get_src_prog_fd; 398 int set_dst_prog_fd; 399 int key = 0, ifindex = -1; 400 uint local_ip; 401 int err; 402 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook, 403 .attach_point = BPF_TC_INGRESS); 404 405 /* add vxlan tunnel */ 406 err = add_ip6vxlan_tunnel(); 407 if (!ASSERT_OK(err, "add_ip6vxlan_tunnel")) 408 goto done; 409 410 /* load and attach bpf prog to tunnel dev tc hook point */ 411 skel = test_tunnel_kern__open_and_load(); 412 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load")) 413 goto done; 414 ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV1); 415 if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan11 ifindex")) 416 goto done; 417 tc_hook.ifindex = ifindex; 418 get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src); 419 set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src); 420 if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd")) 421 goto done; 422 if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd")) 423 goto done; 424 if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd)) 425 goto done; 426 427 /* load and attach prog set_md to tunnel dev tc hook point at_ns0 */ 428 nstoken = open_netns("at_ns0"); 429 if (!ASSERT_OK_PTR(nstoken, "setns src")) 430 goto done; 431 ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV0); 432 if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan00 ifindex")) 433 goto done; 434 tc_hook.ifindex = ifindex; 435 set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst); 436 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd")) 437 goto done; 438 if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd)) 439 goto done; 440 close_netns(nstoken); 441 442 /* use veth1 ip 2 as tunnel source ip */ 443 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map); 444 if (!ASSERT_GE(local_ip_map_fd, 0, "get local_ip_map fd")) 445 goto done; 446 local_ip = IP6_ADDR2_HEX_VETH1; 447 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY); 448 if (!ASSERT_OK(err, "update bpf local_ip_map")) 449 goto done; 450 451 /* ping test */ 452 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0); 453 if (!ASSERT_OK(err, "test_ping")) 454 goto done; 455 456 done: 457 /* delete ipv6 vxlan tunnel */ 458 delete_ip6vxlan_tunnel(); 459 if (local_ip_map_fd >= 0) 460 close(local_ip_map_fd); 461 if (skel) 462 test_tunnel_kern__destroy(skel); 463 } 464 465 static void test_ipip_tunnel(enum ipip_encap encap) 466 { 467 struct test_tunnel_kern *skel = NULL; 468 struct nstoken *nstoken; 469 int set_src_prog_fd, get_src_prog_fd; 470 int ifindex = -1; 471 int err; 472 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook, 473 .attach_point = BPF_TC_INGRESS); 474 475 /* add ipip tunnel */ 476 err = add_ipip_tunnel(encap); 477 if (!ASSERT_OK(err, "add_ipip_tunnel")) 478 goto done; 479 480 /* load and attach bpf prog to tunnel dev tc hook point */ 481 skel = test_tunnel_kern__open_and_load(); 482 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load")) 483 goto done; 484 ifindex = if_nametoindex(IPIP_TUNL_DEV1); 485 if (!ASSERT_NEQ(ifindex, 0, "ipip11 ifindex")) 486 goto done; 487 tc_hook.ifindex = ifindex; 488 489 switch (encap) { 490 case FOU: 491 get_src_prog_fd = bpf_program__fd( 492 skel->progs.ipip_encap_get_tunnel); 493 set_src_prog_fd = bpf_program__fd( 494 skel->progs.ipip_fou_set_tunnel); 495 break; 496 case GUE: 497 get_src_prog_fd = bpf_program__fd( 498 skel->progs.ipip_encap_get_tunnel); 499 set_src_prog_fd = bpf_program__fd( 500 skel->progs.ipip_gue_set_tunnel); 501 break; 502 default: 503 get_src_prog_fd = bpf_program__fd( 504 skel->progs.ipip_get_tunnel); 505 set_src_prog_fd = bpf_program__fd( 506 skel->progs.ipip_set_tunnel); 507 } 508 509 if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd")) 510 goto done; 511 if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd")) 512 goto done; 513 if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd)) 514 goto done; 515 516 /* ping from root namespace test */ 517 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0); 518 if (!ASSERT_OK(err, "test_ping")) 519 goto done; 520 521 /* ping from at_ns0 namespace test */ 522 nstoken = open_netns("at_ns0"); 523 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1); 524 if (!ASSERT_OK(err, "test_ping")) 525 goto done; 526 close_netns(nstoken); 527 528 done: 529 /* delete ipip tunnel */ 530 delete_ipip_tunnel(); 531 if (skel) 532 test_tunnel_kern__destroy(skel); 533 } 534 535 #define RUN_TEST(name, ...) \ 536 ({ \ 537 if (test__start_subtest(#name)) { \ 538 test_ ## name(__VA_ARGS__); \ 539 } \ 540 }) 541 542 static void *test_tunnel_run_tests(void *arg) 543 { 544 cleanup(); 545 config_device(); 546 547 RUN_TEST(vxlan_tunnel); 548 RUN_TEST(ip6vxlan_tunnel); 549 RUN_TEST(ipip_tunnel, NONE); 550 RUN_TEST(ipip_tunnel, FOU); 551 RUN_TEST(ipip_tunnel, GUE); 552 553 cleanup(); 554 555 return NULL; 556 } 557 558 void test_tunnel(void) 559 { 560 pthread_t test_thread; 561 int err; 562 563 /* Run the tests in their own thread to isolate the namespace changes 564 * so they do not affect the environment of other tests. 565 * (specifically needed because of unshare(CLONE_NEWNS) in open_netns()) 566 */ 567 err = pthread_create(&test_thread, NULL, &test_tunnel_run_tests, NULL); 568 if (ASSERT_OK(err, "pthread_create")) 569 ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join"); 570 } 571