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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 495 static void ping_dev0(void) 496 { 497 /* ping from root namespace test */ 498 test_ping(AF_INET, IP4_ADDR_TUNL_DEV0); 499 } 500 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 514 static void ping6_veth0(void) 515 { 516 test_ping(AF_INET6, IP6_ADDR_VETH0); 517 } 518 519 static void ping6_dev0(void) 520 { 521 test_ping(AF_INET6, IP6_ADDR_TUNL_DEV0); 522 } 523 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 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 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 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 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 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 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 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 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 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 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 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 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 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