mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 04:28:10 -04:00
Merge branch 'selftests-bpf-migrate-test_tunnel-sh-to-test_progs'
Bastien Curutchet says: ==================== selftests/bpf: Migrate test_tunnel.sh to test_progs Hi all, This patch series continues the work to migrate the *.sh tests into prog_tests framework. The test_tunnel.sh script has already been partly migrated to test_progs in prog_tests/test_tunnel.c so I add my work to it. PATCH 1 & 2 create some helpers to avoid code duplication and ease the migration in the following patches. PATCH 3 to 9 migrate the tests of gre, ip6gre, erspan, ip6erspan, geneve, ip6geneve and ip6tnl tunnels. PATCH 10 removes test_tunnel.sh ==================== Link: https://patch.msgid.link/20250303-tunnels-v2-0-8329f38f0678@bootlin.com Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
@@ -100,7 +100,6 @@ TEST_FILES = xsk_prereqs.sh $(wildcard progs/btf_dump_test_case_*.c)
|
||||
|
||||
# Order correspond to 'make run_tests' order
|
||||
TEST_PROGS := test_kmod.sh \
|
||||
test_tunnel.sh \
|
||||
test_lwt_seg6local.sh \
|
||||
test_lirc_mode2.sh \
|
||||
test_xdp_vlan_mode_generic.sh \
|
||||
|
||||
@@ -71,6 +71,8 @@
|
||||
#define IP4_ADDR2_VETH1 "172.16.1.20"
|
||||
#define IP4_ADDR_TUNL_DEV0 "10.1.1.100"
|
||||
#define IP4_ADDR_TUNL_DEV1 "10.1.1.200"
|
||||
#define IP6_ADDR_TUNL_DEV0 "fc80::100"
|
||||
#define IP6_ADDR_TUNL_DEV1 "fc80::200"
|
||||
|
||||
#define IP6_ADDR_VETH0 "::11"
|
||||
#define IP6_ADDR1_VETH1 "::22"
|
||||
@@ -98,6 +100,27 @@
|
||||
#define XFRM_SPI_IN_TO_OUT 0x1
|
||||
#define XFRM_SPI_OUT_TO_IN 0x2
|
||||
|
||||
#define GRE_TUNL_DEV0 "gre00"
|
||||
#define GRE_TUNL_DEV1 "gre11"
|
||||
|
||||
#define IP6GRE_TUNL_DEV0 "ip6gre00"
|
||||
#define IP6GRE_TUNL_DEV1 "ip6gre11"
|
||||
|
||||
#define ERSPAN_TUNL_DEV0 "erspan00"
|
||||
#define ERSPAN_TUNL_DEV1 "erspan11"
|
||||
|
||||
#define IP6ERSPAN_TUNL_DEV0 "ip6erspan00"
|
||||
#define IP6ERSPAN_TUNL_DEV1 "ip6erspan11"
|
||||
|
||||
#define GENEVE_TUNL_DEV0 "geneve00"
|
||||
#define GENEVE_TUNL_DEV1 "geneve11"
|
||||
|
||||
#define IP6GENEVE_TUNL_DEV0 "ip6geneve00"
|
||||
#define IP6GENEVE_TUNL_DEV1 "ip6geneve11"
|
||||
|
||||
#define IP6TNL_TUNL_DEV0 "ip6tnl00"
|
||||
#define IP6TNL_TUNL_DEV1 "ip6tnl11"
|
||||
|
||||
#define PING_ARGS "-i 0.01 -c 3 -w 10 -q"
|
||||
|
||||
static int config_device(void)
|
||||
@@ -216,6 +239,18 @@ static int set_ipip_encap(const char *ipproto, const char *type)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int set_ipv4_addr(const char *dev0, const char *dev1)
|
||||
{
|
||||
SYS(fail, "ip -n at_ns0 link set dev %s up", dev0);
|
||||
SYS(fail, "ip -n at_ns0 addr add dev %s %s/24", dev0, IP4_ADDR_TUNL_DEV0);
|
||||
SYS(fail, "ip link set dev %s up", dev1);
|
||||
SYS(fail, "ip addr add dev %s %s/24", dev1, IP4_ADDR_TUNL_DEV1);
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_ipip_tunnel(enum ipip_encap encap)
|
||||
{
|
||||
int err;
|
||||
@@ -356,6 +391,99 @@ static void delete_xfrm_tunnel(void)
|
||||
IP4_ADDR1_VETH1, IP4_ADDR_VETH0, XFRM_SPI_OUT_TO_IN);
|
||||
}
|
||||
|
||||
static int add_ipv4_tunnel(const char *dev0, const char *dev1,
|
||||
const char *type, const char *opt)
|
||||
{
|
||||
if (!type || !opt || !dev0 || !dev1)
|
||||
return -1;
|
||||
|
||||
SYS(fail, "ip -n at_ns0 link add dev %s type %s %s local %s remote %s",
|
||||
dev0, type, opt, IP4_ADDR_VETH0, IP4_ADDR1_VETH1);
|
||||
|
||||
SYS(fail, "ip link add dev %s type %s external", dev1, type);
|
||||
|
||||
return set_ipv4_addr(dev0, dev1);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void delete_tunnel(const char *dev0, const char *dev1)
|
||||
{
|
||||
if (!dev0 || !dev1)
|
||||
return;
|
||||
|
||||
SYS_NOFAIL("ip netns exec at_ns0 ip link delete dev %s", dev0);
|
||||
SYS_NOFAIL("ip link delete dev %s", dev1);
|
||||
}
|
||||
|
||||
static int set_ipv6_addr(const char *dev0, const char *dev1)
|
||||
{
|
||||
/* disable IPv6 DAD because it might take too long and fail tests */
|
||||
SYS(fail, "ip -n at_ns0 addr add %s/96 dev veth0 nodad", IP6_ADDR_VETH0);
|
||||
SYS(fail, "ip -n at_ns0 link set dev veth0 up");
|
||||
SYS(fail, "ip addr add %s/96 dev veth1 nodad", IP6_ADDR1_VETH1);
|
||||
SYS(fail, "ip link set dev veth1 up");
|
||||
|
||||
SYS(fail, "ip -n at_ns0 addr add dev %s %s/24", dev0, IP4_ADDR_TUNL_DEV0);
|
||||
SYS(fail, "ip -n at_ns0 addr add dev %s %s/96 nodad", dev0, IP6_ADDR_TUNL_DEV0);
|
||||
SYS(fail, "ip -n at_ns0 link set dev %s up", dev0);
|
||||
|
||||
SYS(fail, "ip addr add dev %s %s/24", dev1, IP4_ADDR_TUNL_DEV1);
|
||||
SYS(fail, "ip addr add dev %s %s/96 nodad", dev1, IP6_ADDR_TUNL_DEV1);
|
||||
SYS(fail, "ip link set dev %s up", dev1);
|
||||
return 0;
|
||||
fail:
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int add_ipv6_tunnel(const char *dev0, const char *dev1,
|
||||
const char *type, const char *opt)
|
||||
{
|
||||
if (!type || !opt || !dev0 || !dev1)
|
||||
return -1;
|
||||
|
||||
SYS(fail, "ip -n at_ns0 link add dev %s type %s %s local %s remote %s",
|
||||
dev0, type, opt, IP6_ADDR_VETH0, IP6_ADDR1_VETH1);
|
||||
|
||||
SYS(fail, "ip link add dev %s type %s external", dev1, type);
|
||||
|
||||
return set_ipv6_addr(dev0, dev1);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int add_geneve_tunnel(const char *dev0, const char *dev1,
|
||||
const char *type, const char *opt)
|
||||
{
|
||||
if (!type || !opt || !dev0 || !dev1)
|
||||
return -1;
|
||||
|
||||
SYS(fail, "ip -n at_ns0 link add dev %s type %s id 2 %s remote %s",
|
||||
dev0, type, opt, IP4_ADDR1_VETH1);
|
||||
|
||||
SYS(fail, "ip link add dev %s type %s %s external", dev1, type, opt);
|
||||
|
||||
return set_ipv4_addr(dev0, dev1);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int add_ip6geneve_tunnel(const char *dev0, const char *dev1,
|
||||
const char *type, const char *opt)
|
||||
{
|
||||
if (!type || !opt || !dev0 || !dev1)
|
||||
return -1;
|
||||
|
||||
SYS(fail, "ip -n at_ns0 link add dev %s type %s id 22 %s remote %s",
|
||||
dev0, type, opt, IP6_ADDR1_VETH1);
|
||||
|
||||
SYS(fail, "ip link add dev %s type %s %s external", dev1, type, opt);
|
||||
|
||||
return set_ipv6_addr(dev0, dev1);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int test_ping(int family, const char *addr)
|
||||
{
|
||||
SYS(fail, "%s %s %s > /dev/null", ping_command(family), PING_ARGS, addr);
|
||||
@@ -364,32 +492,76 @@ static int test_ping(int family, const char *addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int attach_tc_prog(struct bpf_tc_hook *hook, int igr_fd, int egr_fd)
|
||||
static void ping_dev0(void)
|
||||
{
|
||||
/* ping from root namespace test */
|
||||
test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
|
||||
}
|
||||
|
||||
static void ping_dev1(void)
|
||||
{
|
||||
struct nstoken *nstoken;
|
||||
|
||||
/* ping from at_ns0 namespace test */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns"))
|
||||
return;
|
||||
|
||||
test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
|
||||
close_netns(nstoken);
|
||||
}
|
||||
|
||||
static void ping6_veth0(void)
|
||||
{
|
||||
test_ping(AF_INET6, IP6_ADDR_VETH0);
|
||||
}
|
||||
|
||||
static void ping6_dev0(void)
|
||||
{
|
||||
test_ping(AF_INET6, IP6_ADDR_TUNL_DEV0);
|
||||
}
|
||||
|
||||
static void ping6_dev1(void)
|
||||
{
|
||||
struct nstoken *nstoken;
|
||||
|
||||
/* ping from at_ns0 namespace test */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns"))
|
||||
return;
|
||||
|
||||
test_ping(AF_INET, IP6_ADDR_TUNL_DEV1);
|
||||
close_netns(nstoken);
|
||||
}
|
||||
|
||||
static int attach_tc_prog(int ifindex, int igr_fd, int egr_fd)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = ifindex,
|
||||
.attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS);
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,
|
||||
.priority = 1, .prog_fd = igr_fd);
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,
|
||||
.priority = 1, .prog_fd = egr_fd);
|
||||
int ret;
|
||||
|
||||
ret = bpf_tc_hook_create(hook);
|
||||
ret = bpf_tc_hook_create(&hook);
|
||||
if (!ASSERT_OK(ret, "create tc hook"))
|
||||
return ret;
|
||||
|
||||
if (igr_fd >= 0) {
|
||||
hook->attach_point = BPF_TC_INGRESS;
|
||||
ret = bpf_tc_attach(hook, &opts1);
|
||||
hook.attach_point = BPF_TC_INGRESS;
|
||||
ret = bpf_tc_attach(&hook, &opts1);
|
||||
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
|
||||
bpf_tc_hook_destroy(hook);
|
||||
bpf_tc_hook_destroy(&hook);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (egr_fd >= 0) {
|
||||
hook->attach_point = BPF_TC_EGRESS;
|
||||
ret = bpf_tc_attach(hook, &opts2);
|
||||
hook.attach_point = BPF_TC_EGRESS;
|
||||
ret = bpf_tc_attach(&hook, &opts2);
|
||||
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
|
||||
bpf_tc_hook_destroy(hook);
|
||||
bpf_tc_hook_destroy(&hook);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
@@ -397,6 +569,50 @@ static int attach_tc_prog(struct bpf_tc_hook *hook, int igr_fd, int egr_fd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int generic_attach(const char *dev, int igr_fd, int egr_fd)
|
||||
{
|
||||
int ifindex;
|
||||
|
||||
if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
|
||||
return -1;
|
||||
if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
|
||||
return -1;
|
||||
|
||||
ifindex = if_nametoindex(dev);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
|
||||
return -1;
|
||||
|
||||
return attach_tc_prog(ifindex, igr_fd, egr_fd);
|
||||
}
|
||||
|
||||
static int generic_attach_igr(const char *dev, int igr_fd)
|
||||
{
|
||||
int ifindex;
|
||||
|
||||
if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
|
||||
return -1;
|
||||
|
||||
ifindex = if_nametoindex(dev);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
|
||||
return -1;
|
||||
|
||||
return attach_tc_prog(ifindex, igr_fd, -1);
|
||||
}
|
||||
|
||||
static int generic_attach_egr(const char *dev, int egr_fd)
|
||||
{
|
||||
int ifindex;
|
||||
|
||||
if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
|
||||
return -1;
|
||||
|
||||
ifindex = if_nametoindex(dev);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
|
||||
return -1;
|
||||
|
||||
return attach_tc_prog(ifindex, -1, egr_fd);
|
||||
}
|
||||
|
||||
static void test_vxlan_tunnel(void)
|
||||
{
|
||||
struct test_tunnel_kern *skel = NULL;
|
||||
@@ -404,11 +620,9 @@ static void test_vxlan_tunnel(void)
|
||||
int local_ip_map_fd = -1;
|
||||
int set_src_prog_fd, get_src_prog_fd;
|
||||
int set_dst_prog_fd;
|
||||
int key = 0, ifindex = -1;
|
||||
int key = 0;
|
||||
uint local_ip;
|
||||
int err;
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
|
||||
.attach_point = BPF_TC_INGRESS);
|
||||
|
||||
/* add vxlan tunnel */
|
||||
err = add_vxlan_tunnel();
|
||||
@@ -419,42 +633,22 @@ static void test_vxlan_tunnel(void)
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
goto done;
|
||||
ifindex = if_nametoindex(VXLAN_TUNL_DEV1);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "vxlan11 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);
|
||||
set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);
|
||||
if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))
|
||||
if (generic_attach(VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
|
||||
goto done;
|
||||
|
||||
/* load and attach bpf prog to veth dev tc hook point */
|
||||
ifindex = if_nametoindex("veth1");
|
||||
if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);
|
||||
if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, set_dst_prog_fd, -1))
|
||||
if (generic_attach_igr("veth1", set_dst_prog_fd))
|
||||
goto done;
|
||||
|
||||
/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns src"))
|
||||
goto done;
|
||||
ifindex = if_nametoindex(VXLAN_TUNL_DEV0);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "vxlan00 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);
|
||||
if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))
|
||||
if (generic_attach_egr(VXLAN_TUNL_DEV0, set_dst_prog_fd))
|
||||
goto done;
|
||||
close_netns(nstoken);
|
||||
|
||||
@@ -468,9 +662,7 @@ static void test_vxlan_tunnel(void)
|
||||
goto done;
|
||||
|
||||
/* ping test */
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
ping_dev0();
|
||||
|
||||
done:
|
||||
/* delete vxlan tunnel */
|
||||
@@ -488,11 +680,9 @@ static void test_ip6vxlan_tunnel(void)
|
||||
int local_ip_map_fd = -1;
|
||||
int set_src_prog_fd, get_src_prog_fd;
|
||||
int set_dst_prog_fd;
|
||||
int key = 0, ifindex = -1;
|
||||
int key = 0;
|
||||
uint local_ip;
|
||||
int err;
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
|
||||
.attach_point = BPF_TC_INGRESS);
|
||||
|
||||
/* add vxlan tunnel */
|
||||
err = add_ip6vxlan_tunnel();
|
||||
@@ -503,31 +693,17 @@ static void test_ip6vxlan_tunnel(void)
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
goto done;
|
||||
ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV1);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan11 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);
|
||||
set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);
|
||||
if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))
|
||||
if (generic_attach(IP6VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
|
||||
goto done;
|
||||
|
||||
/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns src"))
|
||||
goto done;
|
||||
ifindex = if_nametoindex(IP6VXLAN_TUNL_DEV0);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "ip6vxlan00 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);
|
||||
if (!ASSERT_GE(set_dst_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, -1, set_dst_prog_fd))
|
||||
if (generic_attach_egr(IP6VXLAN_TUNL_DEV0, set_dst_prog_fd))
|
||||
goto done;
|
||||
close_netns(nstoken);
|
||||
|
||||
@@ -541,9 +717,7 @@ static void test_ip6vxlan_tunnel(void)
|
||||
goto done;
|
||||
|
||||
/* ping test */
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
ping_dev0();
|
||||
|
||||
done:
|
||||
/* delete ipv6 vxlan tunnel */
|
||||
@@ -557,12 +731,8 @@ static void test_ip6vxlan_tunnel(void)
|
||||
static void test_ipip_tunnel(enum ipip_encap encap)
|
||||
{
|
||||
struct test_tunnel_kern *skel = NULL;
|
||||
struct nstoken *nstoken;
|
||||
int set_src_prog_fd, get_src_prog_fd;
|
||||
int ifindex = -1;
|
||||
int err;
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
|
||||
.attach_point = BPF_TC_INGRESS);
|
||||
|
||||
/* add ipip tunnel */
|
||||
err = add_ipip_tunnel(encap);
|
||||
@@ -573,10 +743,6 @@ static void test_ipip_tunnel(enum ipip_encap encap)
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
goto done;
|
||||
ifindex = if_nametoindex(IPIP_TUNL_DEV1);
|
||||
if (!ASSERT_NEQ(ifindex, 0, "ipip11 ifindex"))
|
||||
goto done;
|
||||
tc_hook.ifindex = ifindex;
|
||||
|
||||
switch (encap) {
|
||||
case FOU:
|
||||
@@ -598,26 +764,11 @@ static void test_ipip_tunnel(enum ipip_encap encap)
|
||||
skel->progs.ipip_set_tunnel);
|
||||
}
|
||||
|
||||
if (!ASSERT_GE(set_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (!ASSERT_GE(get_src_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, get_src_prog_fd, set_src_prog_fd))
|
||||
if (generic_attach(IPIP_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
|
||||
goto done;
|
||||
|
||||
/* ping from root namespace test */
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV0);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
|
||||
/* ping from at_ns0 namespace test */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns"))
|
||||
goto done;
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
close_netns(nstoken);
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
|
||||
done:
|
||||
/* delete ipip tunnel */
|
||||
@@ -628,11 +779,8 @@ static void test_ipip_tunnel(enum ipip_encap encap)
|
||||
|
||||
static void test_xfrm_tunnel(void)
|
||||
{
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, tc_hook,
|
||||
.attach_point = BPF_TC_INGRESS);
|
||||
LIBBPF_OPTS(bpf_xdp_attach_opts, opts);
|
||||
struct test_tunnel_kern *skel = NULL;
|
||||
struct nstoken *nstoken;
|
||||
int xdp_prog_fd;
|
||||
int tc_prog_fd;
|
||||
int ifindex;
|
||||
@@ -646,19 +794,16 @@ static void test_xfrm_tunnel(void)
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
goto done;
|
||||
|
||||
ifindex = if_nametoindex("veth1");
|
||||
if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
|
||||
goto done;
|
||||
|
||||
/* attach tc prog to tunnel dev */
|
||||
tc_hook.ifindex = ifindex;
|
||||
tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
|
||||
if (!ASSERT_GE(tc_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
if (attach_tc_prog(&tc_hook, tc_prog_fd, -1))
|
||||
if (generic_attach_igr("veth1", tc_prog_fd))
|
||||
goto done;
|
||||
|
||||
/* attach xdp prog to tunnel dev */
|
||||
ifindex = if_nametoindex("veth1");
|
||||
if (!ASSERT_NEQ(ifindex, 0, "veth1 ifindex"))
|
||||
goto done;
|
||||
xdp_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state_xdp);
|
||||
if (!ASSERT_GE(xdp_prog_fd, 0, "bpf_program__fd"))
|
||||
goto done;
|
||||
@@ -666,14 +811,7 @@ static void test_xfrm_tunnel(void)
|
||||
if (!ASSERT_OK(err, "bpf_xdp_attach"))
|
||||
goto done;
|
||||
|
||||
/* ping from at_ns0 namespace test */
|
||||
nstoken = open_netns("at_ns0");
|
||||
if (!ASSERT_OK_PTR(nstoken, "setns"))
|
||||
goto done;
|
||||
err = test_ping(AF_INET, IP4_ADDR_TUNL_DEV1);
|
||||
close_netns(nstoken);
|
||||
if (!ASSERT_OK(err, "test_ping"))
|
||||
goto done;
|
||||
ping_dev1();
|
||||
|
||||
if (!ASSERT_EQ(skel->bss->xfrm_reqid, 1, "req_id"))
|
||||
goto done;
|
||||
@@ -690,6 +828,281 @@ static void test_xfrm_tunnel(void)
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
enum gre_test {
|
||||
GRE,
|
||||
GRE_NOKEY,
|
||||
GRETAP,
|
||||
GRETAP_NOKEY,
|
||||
};
|
||||
|
||||
static void test_gre_tunnel(enum gre_test test)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
switch (test) {
|
||||
case GRE:
|
||||
err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq");
|
||||
set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
|
||||
get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
|
||||
break;
|
||||
case GRE_NOKEY:
|
||||
err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gre", "seq key 2");
|
||||
set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
|
||||
break;
|
||||
case GRETAP:
|
||||
err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq");
|
||||
set_fd = bpf_program__fd(skel->progs.gre_set_tunnel_no_key);
|
||||
get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
|
||||
break;
|
||||
case GRETAP_NOKEY:
|
||||
err = add_ipv4_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1, "gretap", "seq key 2");
|
||||
set_fd = bpf_program__fd(skel->progs.gre_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.gre_get_tunnel);
|
||||
break;
|
||||
}
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
if (generic_attach(GRE_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
|
||||
done:
|
||||
delete_tunnel(GRE_TUNL_DEV0, GRE_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
enum ip6gre_test {
|
||||
IP6GRE,
|
||||
IP6GRETAP
|
||||
};
|
||||
|
||||
static void test_ip6gre_tunnel(enum ip6gre_test test)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
switch (test) {
|
||||
case IP6GRE:
|
||||
err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
|
||||
"ip6gre", "flowlabel 0xbcdef key 2");
|
||||
break;
|
||||
case IP6GRETAP:
|
||||
err = add_ipv6_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1,
|
||||
"ip6gretap", "flowlabel 0xbcdef key 2");
|
||||
break;
|
||||
}
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
set_fd = bpf_program__fd(skel->progs.ip6gretap_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.ip6gretap_get_tunnel);
|
||||
if (generic_attach(IP6GRE_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping6_veth0();
|
||||
ping6_dev1();
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
done:
|
||||
delete_tunnel(IP6GRE_TUNL_DEV0, IP6GRE_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
enum erspan_test {
|
||||
V1,
|
||||
V2
|
||||
};
|
||||
|
||||
static void test_erspan_tunnel(enum erspan_test test)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
switch (test) {
|
||||
case V1:
|
||||
err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
|
||||
"erspan", "seq key 2 erspan_ver 1 erspan 123");
|
||||
break;
|
||||
case V2:
|
||||
err = add_ipv4_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1,
|
||||
"erspan",
|
||||
"seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 3");
|
||||
break;
|
||||
}
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
set_fd = bpf_program__fd(skel->progs.erspan_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.erspan_get_tunnel);
|
||||
if (generic_attach(ERSPAN_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
done:
|
||||
delete_tunnel(ERSPAN_TUNL_DEV0, ERSPAN_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_ip6erspan_tunnel(enum erspan_test test)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
switch (test) {
|
||||
case V1:
|
||||
err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
|
||||
"ip6erspan", "seq key 2 erspan_ver 1 erspan 123");
|
||||
break;
|
||||
case V2:
|
||||
err = add_ipv6_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1,
|
||||
"ip6erspan",
|
||||
"seq key 2 erspan_ver 2 erspan_dir egress erspan_hwid 7");
|
||||
break;
|
||||
}
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
set_fd = bpf_program__fd(skel->progs.ip4ip6erspan_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.ip4ip6erspan_get_tunnel);
|
||||
if (generic_attach(IP6ERSPAN_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping6_veth0();
|
||||
ping_dev1();
|
||||
done:
|
||||
delete_tunnel(IP6ERSPAN_TUNL_DEV0, IP6ERSPAN_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_geneve_tunnel(void)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
err = add_geneve_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1,
|
||||
"geneve", "dstport 6081");
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
set_fd = bpf_program__fd(skel->progs.geneve_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.geneve_get_tunnel);
|
||||
if (generic_attach(GENEVE_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
done:
|
||||
delete_tunnel(GENEVE_TUNL_DEV0, GENEVE_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
static void test_ip6geneve_tunnel(void)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
err = add_ip6geneve_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1,
|
||||
"geneve", "");
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
set_fd = bpf_program__fd(skel->progs.ip6geneve_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.ip6geneve_get_tunnel);
|
||||
if (generic_attach(IP6GENEVE_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
done:
|
||||
delete_tunnel(IP6GENEVE_TUNL_DEV0, IP6GENEVE_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
enum ip6tnl_test {
|
||||
IPIP6,
|
||||
IP6IP6
|
||||
};
|
||||
|
||||
static void test_ip6tnl_tunnel(enum ip6tnl_test test)
|
||||
{
|
||||
struct test_tunnel_kern *skel;
|
||||
int set_fd, get_fd;
|
||||
int err;
|
||||
|
||||
skel = test_tunnel_kern__open_and_load();
|
||||
if (!ASSERT_OK_PTR(skel, "test_tunnel_kern__open_and_load"))
|
||||
return;
|
||||
|
||||
err = add_ipv6_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1, "ip6tnl", "");
|
||||
if (!ASSERT_OK(err, "add tunnel"))
|
||||
goto done;
|
||||
|
||||
switch (test) {
|
||||
case IPIP6:
|
||||
set_fd = bpf_program__fd(skel->progs.ipip6_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.ipip6_get_tunnel);
|
||||
break;
|
||||
case IP6IP6:
|
||||
set_fd = bpf_program__fd(skel->progs.ip6ip6_set_tunnel);
|
||||
get_fd = bpf_program__fd(skel->progs.ip6ip6_get_tunnel);
|
||||
break;
|
||||
}
|
||||
if (generic_attach(IP6TNL_TUNL_DEV1, get_fd, set_fd))
|
||||
goto done;
|
||||
|
||||
ping6_veth0();
|
||||
switch (test) {
|
||||
case IPIP6:
|
||||
ping_dev0();
|
||||
ping_dev1();
|
||||
break;
|
||||
case IP6IP6:
|
||||
ping6_dev0();
|
||||
ping6_dev1();
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
delete_tunnel(IP6TNL_TUNL_DEV0, IP6TNL_TUNL_DEV1);
|
||||
test_tunnel_kern__destroy(skel);
|
||||
}
|
||||
|
||||
#define RUN_TEST(name, ...) \
|
||||
({ \
|
||||
if (test__start_subtest(#name)) { \
|
||||
@@ -707,6 +1120,20 @@ static void *test_tunnel_run_tests(void *arg)
|
||||
RUN_TEST(ipip_tunnel, FOU);
|
||||
RUN_TEST(ipip_tunnel, GUE);
|
||||
RUN_TEST(xfrm_tunnel);
|
||||
RUN_TEST(gre_tunnel, GRE);
|
||||
RUN_TEST(gre_tunnel, GRE_NOKEY);
|
||||
RUN_TEST(gre_tunnel, GRETAP);
|
||||
RUN_TEST(gre_tunnel, GRETAP_NOKEY);
|
||||
RUN_TEST(ip6gre_tunnel, IP6GRE);
|
||||
RUN_TEST(ip6gre_tunnel, IP6GRETAP);
|
||||
RUN_TEST(erspan_tunnel, V1);
|
||||
RUN_TEST(erspan_tunnel, V2);
|
||||
RUN_TEST(ip6erspan_tunnel, V1);
|
||||
RUN_TEST(ip6erspan_tunnel, V2);
|
||||
RUN_TEST(geneve_tunnel);
|
||||
RUN_TEST(ip6geneve_tunnel);
|
||||
RUN_TEST(ip6tnl_tunnel, IPIP6);
|
||||
RUN_TEST(ip6tnl_tunnel, IP6IP6);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1,645 +0,0 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# End-to-end eBPF tunnel test suite
|
||||
# The script tests BPF network tunnel implementation.
|
||||
#
|
||||
# Topology:
|
||||
# ---------
|
||||
# root namespace | at_ns0 namespace
|
||||
# |
|
||||
# ----------- | -----------
|
||||
# | tnl dev | | | tnl dev | (overlay network)
|
||||
# ----------- | -----------
|
||||
# metadata-mode | native-mode
|
||||
# with bpf |
|
||||
# |
|
||||
# ---------- | ----------
|
||||
# | veth1 | --------- | veth0 | (underlay network)
|
||||
# ---------- peer ----------
|
||||
#
|
||||
#
|
||||
# Device Configuration
|
||||
# --------------------
|
||||
# Root namespace with metadata-mode tunnel + BPF
|
||||
# Device names and addresses:
|
||||
# veth1 IP: 172.16.1.200, IPv6: 00::22 (underlay)
|
||||
# tunnel dev <type>11, ex: gre11, IPv4: 10.1.1.200, IPv6: 1::22 (overlay)
|
||||
#
|
||||
# Namespace at_ns0 with native tunnel
|
||||
# Device names and addresses:
|
||||
# veth0 IPv4: 172.16.1.100, IPv6: 00::11 (underlay)
|
||||
# tunnel dev <type>00, ex: gre00, IPv4: 10.1.1.100, IPv6: 1::11 (overlay)
|
||||
#
|
||||
#
|
||||
# End-to-end ping packet flow
|
||||
# ---------------------------
|
||||
# Most of the tests start by namespace creation, device configuration,
|
||||
# then ping the underlay and overlay network. When doing 'ping 10.1.1.100'
|
||||
# from root namespace, the following operations happen:
|
||||
# 1) Route lookup shows 10.1.1.100/24 belongs to tnl dev, fwd to tnl dev.
|
||||
# 2) Tnl device's egress BPF program is triggered and set the tunnel metadata,
|
||||
# with remote_ip=172.16.1.100 and others.
|
||||
# 3) Outer tunnel header is prepended and route the packet to veth1's egress
|
||||
# 4) veth0's ingress queue receive the tunneled packet at namespace at_ns0
|
||||
# 5) Tunnel protocol handler, ex: vxlan_rcv, decap the packet
|
||||
# 6) Forward the packet to the overlay tnl dev
|
||||
|
||||
BPF_FILE="test_tunnel_kern.bpf.o"
|
||||
BPF_PIN_TUNNEL_DIR="/sys/fs/bpf/tc/tunnel"
|
||||
PING_ARG="-c 3 -w 10 -q"
|
||||
ret=0
|
||||
GREEN='\033[0;92m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
config_device()
|
||||
{
|
||||
ip netns add at_ns0
|
||||
ip link add veth0 type veth peer name veth1
|
||||
ip link set veth0 netns at_ns0
|
||||
ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip link set dev veth1 up mtu 1500
|
||||
ip addr add dev veth1 172.16.1.200/24
|
||||
}
|
||||
|
||||
add_gre_tunnel()
|
||||
{
|
||||
tun_key=
|
||||
if [ -n "$1" ]; then
|
||||
tun_key="key $1"
|
||||
fi
|
||||
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq $tun_key \
|
||||
local 172.16.1.100 remote 172.16.1.200
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE $tun_key external
|
||||
ip link set dev $DEV up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
}
|
||||
|
||||
add_ip6gretap_tunnel()
|
||||
{
|
||||
|
||||
# assign ipv6 address
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
|
||||
local ::11 remote ::22
|
||||
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip addr add dev $DEV fc80::200/24
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
add_erspan_tunnel()
|
||||
{
|
||||
# at_ns0 namespace
|
||||
if [ "$1" == "v1" ]; then
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local 172.16.1.100 remote 172.16.1.200 \
|
||||
erspan_ver 1 erspan 123
|
||||
else
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local 172.16.1.100 remote 172.16.1.200 \
|
||||
erspan_ver 2 erspan_dir egress erspan_hwid 3
|
||||
fi
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip link set dev $DEV up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
}
|
||||
|
||||
add_ip6erspan_tunnel()
|
||||
{
|
||||
|
||||
# assign ipv6 address
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# at_ns0 namespace
|
||||
if [ "$1" == "v1" ]; then
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local ::11 remote ::22 \
|
||||
erspan_ver 1 erspan 123
|
||||
else
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE seq key 2 \
|
||||
local ::11 remote ::22 \
|
||||
erspan_ver 2 erspan_dir egress erspan_hwid 7
|
||||
fi
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
add_geneve_tunnel()
|
||||
{
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE \
|
||||
id 2 dstport 6081 remote 172.16.1.200
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE dstport 6081 external
|
||||
ip link set dev $DEV up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
}
|
||||
|
||||
add_ip6geneve_tunnel()
|
||||
{
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE id 22 \
|
||||
remote ::22 # geneve has no local option
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
add_ipip_tunnel()
|
||||
{
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE \
|
||||
local 172.16.1.100 remote 172.16.1.200
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip link set dev $DEV up
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
}
|
||||
|
||||
add_ip6tnl_tunnel()
|
||||
{
|
||||
ip netns exec at_ns0 ip addr add ::11/96 dev veth0
|
||||
ip netns exec at_ns0 ip link set dev veth0 up
|
||||
ip addr add dev veth1 ::22/96
|
||||
ip link set dev veth1 up
|
||||
|
||||
# at_ns0 namespace
|
||||
ip netns exec at_ns0 \
|
||||
ip link add dev $DEV_NS type $TYPE \
|
||||
local ::11 remote ::22
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
|
||||
ip netns exec at_ns0 ip addr add dev $DEV_NS 1::11/96
|
||||
ip netns exec at_ns0 ip link set dev $DEV_NS up
|
||||
|
||||
# root namespace
|
||||
ip link add dev $DEV type $TYPE external
|
||||
ip addr add dev $DEV 10.1.1.200/24
|
||||
ip addr add dev $DEV 1::22/96
|
||||
ip link set dev $DEV up
|
||||
}
|
||||
|
||||
test_gre()
|
||||
{
|
||||
TYPE=gretap
|
||||
DEV_NS=gretap00
|
||||
DEV=gretap11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_gre_tunnel 2
|
||||
attach_bpf $DEV gre_set_tunnel gre_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_gre_no_tunnel_key()
|
||||
{
|
||||
TYPE=gre
|
||||
DEV_NS=gre00
|
||||
DEV=gre11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_gre_tunnel
|
||||
attach_bpf $DEV gre_set_tunnel_no_key gre_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ip6gre()
|
||||
{
|
||||
TYPE=ip6gre
|
||||
DEV_NS=ip6gre00
|
||||
DEV=ip6gre11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
# reuse the ip6gretap function
|
||||
add_ip6gretap_tunnel
|
||||
attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
|
||||
# underlay
|
||||
ping6 $PING_ARG ::11
|
||||
# overlay: ipv4 over ipv6
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
# overlay: ipv6 over ipv6
|
||||
ip netns exec at_ns0 ping6 $PING_ARG fc80::200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ip6gretap()
|
||||
{
|
||||
TYPE=ip6gretap
|
||||
DEV_NS=ip6gretap00
|
||||
DEV=ip6gretap11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ip6gretap_tunnel
|
||||
attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
|
||||
# underlay
|
||||
ping6 $PING_ARG ::11
|
||||
# overlay: ipv4 over ipv6
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
# overlay: ipv6 over ipv6
|
||||
ip netns exec at_ns0 ping6 $PING_ARG fc80::200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_erspan()
|
||||
{
|
||||
TYPE=erspan
|
||||
DEV_NS=erspan00
|
||||
DEV=erspan11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_erspan_tunnel $1
|
||||
attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ip6erspan()
|
||||
{
|
||||
TYPE=ip6erspan
|
||||
DEV_NS=ip6erspan00
|
||||
DEV=ip6erspan11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ip6erspan_tunnel $1
|
||||
attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
|
||||
ping6 $PING_ARG ::11
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_geneve()
|
||||
{
|
||||
TYPE=geneve
|
||||
DEV_NS=geneve00
|
||||
DEV=geneve11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_geneve_tunnel
|
||||
attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ip6geneve()
|
||||
{
|
||||
TYPE=geneve
|
||||
DEV_NS=ip6geneve00
|
||||
DEV=ip6geneve11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ip6geneve_tunnel
|
||||
attach_bpf $DEV ip6geneve_set_tunnel ip6geneve_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: ip6$TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ipip()
|
||||
{
|
||||
TYPE=ipip
|
||||
DEV_NS=ipip00
|
||||
DEV=ipip11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ipip_tunnel
|
||||
ip link set dev veth1 mtu 1500
|
||||
attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ipip6()
|
||||
{
|
||||
TYPE=ip6tnl
|
||||
DEV_NS=ipip6tnl00
|
||||
DEV=ipip6tnl11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ip6tnl_tunnel
|
||||
ip link set dev veth1 mtu 1500
|
||||
attach_bpf $DEV ipip6_set_tunnel ipip6_get_tunnel
|
||||
# underlay
|
||||
ping6 $PING_ARG ::11
|
||||
# ip4 over ip6
|
||||
ping $PING_ARG 10.1.1.100
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: $TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: $TYPE"${NC}
|
||||
}
|
||||
|
||||
test_ip6ip6()
|
||||
{
|
||||
TYPE=ip6tnl
|
||||
DEV_NS=ip6ip6tnl00
|
||||
DEV=ip6ip6tnl11
|
||||
ret=0
|
||||
|
||||
check $TYPE
|
||||
config_device
|
||||
add_ip6tnl_tunnel
|
||||
ip link set dev veth1 mtu 1500
|
||||
attach_bpf $DEV ip6ip6_set_tunnel ip6ip6_get_tunnel
|
||||
# underlay
|
||||
ping6 $PING_ARG ::11
|
||||
# ip6 over ip6
|
||||
ping6 $PING_ARG 1::11
|
||||
check_err $?
|
||||
ip netns exec at_ns0 ping6 $PING_ARG 1::22
|
||||
check_err $?
|
||||
cleanup
|
||||
|
||||
if [ $ret -ne 0 ]; then
|
||||
echo -e ${RED}"FAIL: ip6$TYPE"${NC}
|
||||
return 1
|
||||
fi
|
||||
echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
|
||||
}
|
||||
|
||||
attach_bpf()
|
||||
{
|
||||
DEV=$1
|
||||
SET=$2
|
||||
GET=$3
|
||||
mkdir -p ${BPF_PIN_TUNNEL_DIR}
|
||||
bpftool prog loadall ${BPF_FILE} ${BPF_PIN_TUNNEL_DIR}/
|
||||
tc qdisc add dev $DEV clsact
|
||||
tc filter add dev $DEV egress bpf da object-pinned ${BPF_PIN_TUNNEL_DIR}/$SET
|
||||
tc filter add dev $DEV ingress bpf da object-pinned ${BPF_PIN_TUNNEL_DIR}/$GET
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
rm -rf ${BPF_PIN_TUNNEL_DIR}
|
||||
|
||||
ip netns delete at_ns0 2> /dev/null
|
||||
ip link del veth1 2> /dev/null
|
||||
ip link del ipip11 2> /dev/null
|
||||
ip link del ipip6tnl11 2> /dev/null
|
||||
ip link del ip6ip6tnl11 2> /dev/null
|
||||
ip link del gretap11 2> /dev/null
|
||||
ip link del gre11 2> /dev/null
|
||||
ip link del ip6gre11 2> /dev/null
|
||||
ip link del ip6gretap11 2> /dev/null
|
||||
ip link del geneve11 2> /dev/null
|
||||
ip link del ip6geneve11 2> /dev/null
|
||||
ip link del erspan11 2> /dev/null
|
||||
ip link del ip6erspan11 2> /dev/null
|
||||
}
|
||||
|
||||
cleanup_exit()
|
||||
{
|
||||
echo "CATCH SIGKILL or SIGINT, cleanup and exit"
|
||||
cleanup
|
||||
exit 0
|
||||
}
|
||||
|
||||
check()
|
||||
{
|
||||
ip link help 2>&1 | grep -q "\s$1\s"
|
||||
if [ $? -ne 0 ];then
|
||||
echo "SKIP $1: iproute2 not support"
|
||||
cleanup
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
enable_debug()
|
||||
{
|
||||
echo 'file ip_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
|
||||
echo 'file ip6_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
|
||||
echo 'file geneve.c +p' > /sys/kernel/debug/dynamic_debug/control
|
||||
echo 'file ipip.c +p' > /sys/kernel/debug/dynamic_debug/control
|
||||
}
|
||||
|
||||
check_err()
|
||||
{
|
||||
if [ $ret -eq 0 ]; then
|
||||
ret=$1
|
||||
fi
|
||||
}
|
||||
|
||||
bpf_tunnel_test()
|
||||
{
|
||||
local errors=0
|
||||
|
||||
echo "Testing GRE tunnel..."
|
||||
test_gre
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing GRE tunnel (without tunnel keys)..."
|
||||
test_gre_no_tunnel_key
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IP6GRE tunnel..."
|
||||
test_ip6gre
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IP6GRETAP tunnel..."
|
||||
test_ip6gretap
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing ERSPAN tunnel..."
|
||||
test_erspan v2
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IP6ERSPAN tunnel..."
|
||||
test_ip6erspan v2
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing GENEVE tunnel..."
|
||||
test_geneve
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IP6GENEVE tunnel..."
|
||||
test_ip6geneve
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IPIP tunnel..."
|
||||
test_ipip
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IPIP6 tunnel..."
|
||||
test_ipip6
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
echo "Testing IP6IP6 tunnel..."
|
||||
test_ip6ip6
|
||||
errors=$(( $errors + $? ))
|
||||
|
||||
return $errors
|
||||
}
|
||||
|
||||
trap cleanup 0 3 6
|
||||
trap cleanup_exit 2 9
|
||||
|
||||
cleanup
|
||||
bpf_tunnel_test
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "$(basename $0): ${RED}FAIL${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "$(basename $0): ${GREEN}PASS${NC}"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user