0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 #include <arpa/inet.h>
0053 #include <linux/if_tun.h>
0054 #include <linux/limits.h>
0055 #include <linux/sysctl.h>
0056 #include <linux/time_types.h>
0057 #include <linux/net_tstamp.h>
0058 #include <net/if.h>
0059 #include <stdbool.h>
0060 #include <stdio.h>
0061 #include <sys/stat.h>
0062 #include <unistd.h>
0063
0064 #include "test_progs.h"
0065 #include "network_helpers.h"
0066 #include "test_tunnel_kern.skel.h"
0067
0068 #define IP4_ADDR_VETH0 "172.16.1.100"
0069 #define IP4_ADDR1_VETH1 "172.16.1.200"
0070 #define IP4_ADDR2_VETH1 "172.16.1.20"
0071 #define IP4_ADDR_TUNL_DEV0 "10.1.1.100"
0072 #define IP4_ADDR_TUNL_DEV1 "10.1.1.200"
0073
0074 #define IP6_ADDR_VETH0 "::11"
0075 #define IP6_ADDR1_VETH1 "::22"
0076 #define IP6_ADDR2_VETH1 "::bb"
0077
0078 #define IP4_ADDR1_HEX_VETH1 0xac1001c8
0079 #define IP4_ADDR2_HEX_VETH1 0xac100114
0080 #define IP6_ADDR1_HEX_VETH1 0x22
0081 #define IP6_ADDR2_HEX_VETH1 0xbb
0082
0083 #define MAC_TUNL_DEV0 "52:54:00:d9:01:00"
0084 #define MAC_TUNL_DEV1 "52:54:00:d9:02:00"
0085 #define MAC_VETH1 "52:54:00:d9:03:00"
0086
0087 #define VXLAN_TUNL_DEV0 "vxlan00"
0088 #define VXLAN_TUNL_DEV1 "vxlan11"
0089 #define IP6VXLAN_TUNL_DEV0 "ip6vxlan00"
0090 #define IP6VXLAN_TUNL_DEV1 "ip6vxlan11"
0091
0092 #define PING_ARGS "-i 0.01 -c 3 -w 10 -q"
0093
0094 #define SYS(fmt, ...) \
0095 ({ \
0096 char cmd[1024]; \
0097 snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \
0098 if (!ASSERT_OK(system(cmd), cmd)) \
0099 goto fail; \
0100 })
0101
0102 #define SYS_NOFAIL(fmt, ...) \
0103 ({ \
0104 char cmd[1024]; \
0105 snprintf(cmd, sizeof(cmd), fmt, ##__VA_ARGS__); \
0106 system(cmd); \
0107 })
0108
0109 static int config_device(void)
0110 {
0111 SYS("ip netns add at_ns0");
0112 SYS("ip link add veth0 address " MAC_VETH1 " type veth peer name veth1");
0113 SYS("ip link set veth0 netns at_ns0");
0114 SYS("ip addr add " IP4_ADDR1_VETH1 "/24 dev veth1");
0115 SYS("ip link set dev veth1 up mtu 1500");
0116 SYS("ip netns exec at_ns0 ip addr add " IP4_ADDR_VETH0 "/24 dev veth0");
0117 SYS("ip netns exec at_ns0 ip link set dev veth0 up mtu 1500");
0118
0119 return 0;
0120 fail:
0121 return -1;
0122 }
0123
0124 static void cleanup(void)
0125 {
0126 SYS_NOFAIL("test -f /var/run/netns/at_ns0 && ip netns delete at_ns0");
0127 SYS_NOFAIL("ip link del veth1 2> /dev/null");
0128 SYS_NOFAIL("ip link del %s 2> /dev/null", VXLAN_TUNL_DEV1);
0129 SYS_NOFAIL("ip link del %s 2> /dev/null", IP6VXLAN_TUNL_DEV1);
0130 }
0131
0132 static int add_vxlan_tunnel(void)
0133 {
0134
0135 SYS("ip netns exec at_ns0 ip link add dev %s type vxlan external gbp dstport 4789",
0136 VXLAN_TUNL_DEV0);
0137 SYS("ip netns exec at_ns0 ip link set dev %s address %s up",
0138 VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);
0139 SYS("ip netns exec at_ns0 ip addr add dev %s %s/24",
0140 VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);
0141 SYS("ip netns exec at_ns0 ip neigh add %s lladdr %s dev %s",
0142 IP4_ADDR_TUNL_DEV1, MAC_TUNL_DEV1, VXLAN_TUNL_DEV0);
0143 SYS("ip netns exec at_ns0 ip neigh add %s lladdr %s dev veth0",
0144 IP4_ADDR2_VETH1, MAC_VETH1);
0145
0146
0147 SYS("ip link add dev %s type vxlan external gbp dstport 4789",
0148 VXLAN_TUNL_DEV1);
0149 SYS("ip link set dev %s address %s up", VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);
0150 SYS("ip addr add dev %s %s/24", VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);
0151 SYS("ip neigh add %s lladdr %s dev %s",
0152 IP4_ADDR_TUNL_DEV0, MAC_TUNL_DEV0, VXLAN_TUNL_DEV1);
0153
0154 return 0;
0155 fail:
0156 return -1;
0157 }
0158
0159 static void delete_vxlan_tunnel(void)
0160 {
0161 SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",
0162 VXLAN_TUNL_DEV0);
0163 SYS_NOFAIL("ip link delete dev %s", VXLAN_TUNL_DEV1);
0164 }
0165
0166 static int add_ip6vxlan_tunnel(void)
0167 {
0168 SYS("ip netns exec at_ns0 ip -6 addr add %s/96 dev veth0",
0169 IP6_ADDR_VETH0);
0170 SYS("ip netns exec at_ns0 ip link set dev veth0 up");
0171 SYS("ip -6 addr add %s/96 dev veth1", IP6_ADDR1_VETH1);
0172 SYS("ip -6 addr add %s/96 dev veth1", IP6_ADDR2_VETH1);
0173 SYS("ip link set dev veth1 up");
0174
0175
0176 SYS("ip netns exec at_ns0 ip link add dev %s type vxlan external dstport 4789",
0177 IP6VXLAN_TUNL_DEV0);
0178 SYS("ip netns exec at_ns0 ip addr add dev %s %s/24",
0179 IP6VXLAN_TUNL_DEV0, IP4_ADDR_TUNL_DEV0);
0180 SYS("ip netns exec at_ns0 ip link set dev %s address %s up",
0181 IP6VXLAN_TUNL_DEV0, MAC_TUNL_DEV0);
0182
0183
0184 SYS("ip link add dev %s type vxlan external dstport 4789",
0185 IP6VXLAN_TUNL_DEV1);
0186 SYS("ip addr add dev %s %s/24", IP6VXLAN_TUNL_DEV1, IP4_ADDR_TUNL_DEV1);
0187 SYS("ip link set dev %s address %s up",
0188 IP6VXLAN_TUNL_DEV1, MAC_TUNL_DEV1);
0189
0190 return 0;
0191 fail:
0192 return -1;
0193 }
0194
0195 static void delete_ip6vxlan_tunnel(void)
0196 {
0197 SYS_NOFAIL("ip netns exec at_ns0 ip -6 addr delete %s/96 dev veth0",
0198 IP6_ADDR_VETH0);
0199 SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR1_VETH1);
0200 SYS_NOFAIL("ip -6 addr delete %s/96 dev veth1", IP6_ADDR2_VETH1);
0201 SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s",
0202 IP6VXLAN_TUNL_DEV0);
0203 SYS_NOFAIL("ip link delete dev %s", IP6VXLAN_TUNL_DEV1);
0204 }
0205
0206 static int test_ping(int family, const char *addr)
0207 {
0208 SYS("%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr);
0209 return 0;
0210 fail:
0211 return -1;
0212 }
0213
0214 static int attach_tc_prog(struct bpf_tc_hook *hook, int igr_fd, int egr_fd)
0215 {
0216 DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,
0217 .priority = 1, .prog_fd = igr_fd);
0218 DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,
0219 .priority = 1, .prog_fd = egr_fd);
0220 int ret;
0221
0222 ret = bpf_tc_hook_create(hook);
0223 if (!ASSERT_OK(ret, "create tc hook"))
0224 return ret;
0225
0226 if (igr_fd >= 0) {
0227 hook->attach_point = BPF_TC_INGRESS;
0228 ret = bpf_tc_attach(hook, &opts1);
0229 if (!ASSERT_OK(ret, "bpf_tc_attach")) {
0230 bpf_tc_hook_destroy(hook);
0231 return ret;
0232 }
0233 }
0234
0235 if (egr_fd >= 0) {
0236 hook->attach_point = BPF_TC_EGRESS;
0237 ret = bpf_tc_attach(hook, &opts2);
0238 if (!ASSERT_OK(ret, "bpf_tc_attach")) {
0239 bpf_tc_hook_destroy(hook);
0240 return ret;
0241 }
0242 }
0243
0244 return 0;
0245 }
0246
0247 static void test_vxlan_tunnel(void)
0248 {
0249 struct test_tunnel_kern *skel = NULL;
0250 struct nstoken *nstoken;
0251 int local_ip_map_fd = -1;
0252 int set_src_prog_fd, get_src_prog_fd;
0253 int set_dst_prog_fd;
0254 int key = 0, ifindex = -1;
0255 uint local_ip;
0256 int err;
0257 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
0258 .attach_point = BPF_TC_INGRESS);
0259
0260
0261 err = add_vxlan_tunnel();
0262 if (!ASSERT_OK(err, "add vxlan tunnel"))
0263 goto done;
0264
0265
0266 skel = test_tunnel_kern__open_and_load();
0267 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
0268 goto done;
0269 ifindex = if_nametoindex(VXLAN_TUNL_DEV1);
0270 if (!ASSERT_NEQ(ifindex, 0, "vxlan11 ifindex"))
0271 goto done;
0272 tc_hook.ifindex = ifindex;
0273 get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);
0274 set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);
0275 if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))
0276 goto done;
0277 if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))
0278 goto done;
0279 if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))
0280 goto done;
0281
0282
0283 ifindex = if_nametoindex("veth1");
0284 if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
0285 goto done;
0286 tc_hook.ifindex = ifindex;
0287 set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);
0288 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
0289 goto done;
0290 if (attach_tc_prog(&tc_hook, set_dst_prog_fd, -1))
0291 goto done;
0292
0293
0294 nstoken = open_netns("at_ns0");
0295 if (!ASSERT_OK_PTR(nstoken, "setns src"))
0296 goto done;
0297 ifindex = if_nametoindex(VXLAN_TUNL_DEV0);
0298 if (!ASSERT_NEQ(ifindex, 0, "vxlan00 ifindex"))
0299 goto done;
0300 tc_hook.ifindex = ifindex;
0301 set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);
0302 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
0303 goto done;
0304 if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))
0305 goto done;
0306 close_netns(nstoken);
0307
0308
0309 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
0310 if (!ASSERT_GE(local_ip_map_fd, 0, "bpf_map__fd"))
0311 goto done;
0312 local_ip = IP4_ADDR2_HEX_VETH1;
0313 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
0314 if (!ASSERT_OK(err, "update bpf local_ip_map"))
0315 goto done;
0316
0317
0318 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
0319 if (!ASSERT_OK(err, "test_ping"))
0320 goto done;
0321
0322 done:
0323
0324 delete_vxlan_tunnel();
0325 if (local_ip_map_fd >= 0)
0326 close(local_ip_map_fd);
0327 if (skel)
0328 test_tunnel_kern__destroy(skel);
0329 }
0330
0331 static void test_ip6vxlan_tunnel(void)
0332 {
0333 struct test_tunnel_kern *skel = NULL;
0334 struct nstoken *nstoken;
0335 int local_ip_map_fd = -1;
0336 int set_src_prog_fd, get_src_prog_fd;
0337 int set_dst_prog_fd;
0338 int key = 0, ifindex = -1;
0339 uint local_ip;
0340 int err;
0341 DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
0342 .attach_point = BPF_TC_INGRESS);
0343
0344
0345 err = add_ip6vxlan_tunnel();
0346 if (!ASSERT_OK(err, "add_ip6vxlan_tunnel"))
0347 goto done;
0348
0349
0350 skel = test_tunnel_kern__open_and_load();
0351 if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
0352 goto done;
0353 ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV1);
0354 if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan11 ifindex"))
0355 goto done;
0356 tc_hook.ifindex = ifindex;
0357 get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);
0358 set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);
0359 if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))
0360 goto done;
0361 if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))
0362 goto done;
0363 if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))
0364 goto done;
0365
0366
0367 nstoken = open_netns("at_ns0");
0368 if (!ASSERT_OK_PTR(nstoken, "setns src"))
0369 goto done;
0370 ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV0);
0371 if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan00 ifindex"))
0372 goto done;
0373 tc_hook.ifindex = ifindex;
0374 set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);
0375 if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
0376 goto done;
0377 if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))
0378 goto done;
0379 close_netns(nstoken);
0380
0381
0382 local_ip_map_fd = bpf_map__fd(skel->maps.local_ip_map);
0383 if (!ASSERT_GE(local_ip_map_fd, 0, "get local_ip_map fd"))
0384 goto done;
0385 local_ip = IP6_ADDR2_HEX_VETH1;
0386 err = bpf_map_update_elem(local_ip_map_fd, &key, &local_ip, BPF_ANY);
0387 if (!ASSERT_OK(err, "update bpf local_ip_map"))
0388 goto done;
0389
0390
0391 err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
0392 if (!ASSERT_OK(err, "test_ping"))
0393 goto done;
0394
0395 done:
0396
0397 delete_ip6vxlan_tunnel();
0398 if (local_ip_map_fd >= 0)
0399 close(local_ip_map_fd);
0400 if (skel)
0401 test_tunnel_kern__destroy(skel);
0402 }
0403
0404 #define RUN_TEST(name) \
0405 ({ \
0406 if (test__start_subtest(#name)) { \
0407 test_ ## name(); \
0408 } \
0409 })
0410
0411 static void *test_tunnel_run_tests(void *arg)
0412 {
0413 cleanup();
0414 config_device();
0415
0416 RUN_TEST(vxlan_tunnel);
0417 RUN_TEST(ip6vxlan_tunnel);
0418
0419 cleanup();
0420
0421 return NULL;
0422 }
0423
0424 void serial_test_tunnel(void)
0425 {
0426 pthread_t test_thread;
0427 int err;
0428
0429
0430
0431
0432
0433 err = pthread_create(&test_thread, NULL, &test_tunnel_run_tests, NULL);
0434 if (ASSERT_OK(err, "pthread_create"))
0435 ASSERT_OK(pthread_join(test_thread, NULL), "pthread_join");
0436 }