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