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:
Martin KaFai Lau
2025-03-03 13:35:45 -08:00
committed by Alexei Starovoitov
3 changed files with 530 additions and 749 deletions

View File

@@ -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 \

View File

@@ -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;
}

View File

@@ -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