Skip to content

Commit 75fce00

Browse files
TropicaoKernel Patches Daemon
authored andcommitted
selftests/bpf: add tc helpers
The test_tunnel.c file defines small fonctions to easily attach eBPF programs to tc hooks, either on egress, ingress or both. Create a shared helper in network_helpers.c so that other tests can benefit from it. Signed-off-by: Alexis Lothoré (eBPF Foundation) <[email protected]>
1 parent 4d1f3ab commit 75fce00

File tree

3 files changed

+75
-93
lines changed

3 files changed

+75
-93
lines changed

tools/testing/selftests/bpf/network_helpers.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -766,6 +766,51 @@ int send_recv_data(int lfd, int fd, uint32_t total_bytes)
766766
return err;
767767
}
768768

769+
int tc_prog_attach(const char *dev, int ingress_fd, int egress_fd)
770+
{
771+
int ifindex;
772+
773+
if (!ASSERT_TRUE(ingress_fd >= 0 || egress_fd >= 0,
774+
"at least one program fd is valid"))
775+
return -1;
776+
777+
ifindex = if_nametoindex(dev);
778+
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
779+
return -1;
780+
781+
DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = ifindex,
782+
.attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS);
783+
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,
784+
.priority = 1, .prog_fd = ingress_fd);
785+
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,
786+
.priority = 1, .prog_fd = egress_fd);
787+
int ret;
788+
789+
ret = bpf_tc_hook_create(&hook);
790+
if (!ASSERT_OK(ret, "create tc hook"))
791+
return ret;
792+
793+
if (ingress_fd >= 0) {
794+
hook.attach_point = BPF_TC_INGRESS;
795+
ret = bpf_tc_attach(&hook, &opts1);
796+
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
797+
bpf_tc_hook_destroy(&hook);
798+
return ret;
799+
}
800+
}
801+
802+
if (egress_fd >= 0) {
803+
hook.attach_point = BPF_TC_EGRESS;
804+
ret = bpf_tc_attach(&hook, &opts2);
805+
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
806+
bpf_tc_hook_destroy(&hook);
807+
return ret;
808+
}
809+
}
810+
811+
return 0;
812+
}
813+
769814
#ifdef TRAFFIC_MONITOR
770815
struct tmonitor_ctx {
771816
pcap_t *pcap;

tools/testing/selftests/bpf/network_helpers.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,22 @@ struct tmonitor_ctx;
255255

256256
typedef int (*tm_print_fn_t)(const char *format, va_list args);
257257

258+
/**
259+
* tc_prog_attach - attach BPF program(s) to an interface
260+
*
261+
* Takes file descriptors pointing to at least one, at most two BPF
262+
* programs, and attach those programs to an interface ingress, egress or
263+
* both.
264+
*
265+
* @dev: string containing the interface name
266+
* @ingress_fd: file descriptor of the program to attach to interface ingress
267+
* @egress_fd: file descriptor of the program to attach to interface egress
268+
*
269+
* Returns 0 on success, -1 if no valid file descriptor has been found, if
270+
* the interface name is invalid or if an error ocurred during attach.
271+
*/
272+
int tc_prog_attach(const char *dev, int ingress_fd, int egress_fd);
273+
258274
#ifdef TRAFFIC_MONITOR
259275
struct tmonitor_ctx *traffic_monitor_start(const char *netns, const char *test_name,
260276
const char *subtest_name);

tools/testing/selftests/bpf/prog_tests/test_tunnel.c

Lines changed: 14 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -534,85 +534,6 @@ static void ping6_dev1(void)
534534
close_netns(nstoken);
535535
}
536536

537-
static int attach_tc_prog(int ifindex, int igr_fd, int egr_fd)
538-
{
539-
DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .ifindex = ifindex,
540-
.attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS);
541-
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts1, .handle = 1,
542-
.priority = 1, .prog_fd = igr_fd);
543-
DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts2, .handle = 1,
544-
.priority = 1, .prog_fd = egr_fd);
545-
int ret;
546-
547-
ret = bpf_tc_hook_create(&hook);
548-
if (!ASSERT_OK(ret, "create tc hook"))
549-
return ret;
550-
551-
if (igr_fd >= 0) {
552-
hook.attach_point = BPF_TC_INGRESS;
553-
ret = bpf_tc_attach(&hook, &opts1);
554-
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
555-
bpf_tc_hook_destroy(&hook);
556-
return ret;
557-
}
558-
}
559-
560-
if (egr_fd >= 0) {
561-
hook.attach_point = BPF_TC_EGRESS;
562-
ret = bpf_tc_attach(&hook, &opts2);
563-
if (!ASSERT_OK(ret, "bpf_tc_attach")) {
564-
bpf_tc_hook_destroy(&hook);
565-
return ret;
566-
}
567-
}
568-
569-
return 0;
570-
}
571-
572-
static int generic_attach(const char *dev, int igr_fd, int egr_fd)
573-
{
574-
int ifindex;
575-
576-
if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
577-
return -1;
578-
if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
579-
return -1;
580-
581-
ifindex = if_nametoindex(dev);
582-
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
583-
return -1;
584-
585-
return attach_tc_prog(ifindex, igr_fd, egr_fd);
586-
}
587-
588-
static int generic_attach_igr(const char *dev, int igr_fd)
589-
{
590-
int ifindex;
591-
592-
if (!ASSERT_OK_FD(igr_fd, "check ingress fd"))
593-
return -1;
594-
595-
ifindex = if_nametoindex(dev);
596-
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
597-
return -1;
598-
599-
return attach_tc_prog(ifindex, igr_fd, -1);
600-
}
601-
602-
static int generic_attach_egr(const char *dev, int egr_fd)
603-
{
604-
int ifindex;
605-
606-
if (!ASSERT_OK_FD(egr_fd, "check egress fd"))
607-
return -1;
608-
609-
ifindex = if_nametoindex(dev);
610-
if (!ASSERT_NEQ(ifindex, 0, "get ifindex"))
611-
return -1;
612-
613-
return attach_tc_prog(ifindex, -1, egr_fd);
614-
}
615-
616537
static void test_vxlan_tunnel(void)
617538
{
618539
struct test_tunnel_kern *skel = NULL;
@@ -635,20 +556,20 @@ static void test_vxlan_tunnel(void)
635556
goto done;
636557
get_src_prog_fd = bpf_program__fd(skel->progs.vxlan_get_tunnel_src);
637558
set_src_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_src);
638-
if (generic_attach(VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
559+
if (tc_prog_attach(VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
639560
goto done;
640561

641562
/* load and attach bpf prog to veth dev tc hook point */
642563
set_dst_prog_fd = bpf_program__fd(skel->progs.veth_set_outer_dst);
643-
if (generic_attach_igr("veth1", set_dst_prog_fd))
564+
if (tc_prog_attach("veth1", set_dst_prog_fd, -1))
644565
goto done;
645566

646567
/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
647568
nstoken = open_netns("at_ns0");
648569
if (!ASSERT_OK_PTR(nstoken, "setns src"))
649570
goto done;
650571
set_dst_prog_fd = bpf_program__fd(skel->progs.vxlan_set_tunnel_dst);
651-
if (generic_attach_egr(VXLAN_TUNL_DEV0, set_dst_prog_fd))
572+
if (tc_prog_attach(VXLAN_TUNL_DEV0, -1, set_dst_prog_fd))
652573
goto done;
653574
close_netns(nstoken);
654575

@@ -695,15 +616,15 @@ static void test_ip6vxlan_tunnel(void)
695616
goto done;
696617
get_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_get_tunnel_src);
697618
set_src_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_src);
698-
if (generic_attach(IP6VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
619+
if (tc_prog_attach(IP6VXLAN_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
699620
goto done;
700621

701622
/* load and attach prog set_md to tunnel dev tc hook point at_ns0 */
702623
nstoken = open_netns("at_ns0");
703624
if (!ASSERT_OK_PTR(nstoken, "setns src"))
704625
goto done;
705626
set_dst_prog_fd = bpf_program__fd(skel->progs.ip6vxlan_set_tunnel_dst);
706-
if (generic_attach_egr(IP6VXLAN_TUNL_DEV0, set_dst_prog_fd))
627+
if (tc_prog_attach(IP6VXLAN_TUNL_DEV0, -1, set_dst_prog_fd))
707628
goto done;
708629
close_netns(nstoken);
709630

@@ -764,7 +685,7 @@ static void test_ipip_tunnel(enum ipip_encap encap)
764685
skel->progs.ipip_set_tunnel);
765686
}
766687

767-
if (generic_attach(IPIP_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
688+
if (tc_prog_attach(IPIP_TUNL_DEV1, get_src_prog_fd, set_src_prog_fd))
768689
goto done;
769690

770691
ping_dev0();
@@ -797,7 +718,7 @@ static void test_xfrm_tunnel(void)
797718

798719
/* attach tc prog to tunnel dev */
799720
tc_prog_fd = bpf_program__fd(skel->progs.xfrm_get_state);
800-
if (generic_attach_igr("veth1", tc_prog_fd))
721+
if (tc_prog_attach("veth1", tc_prog_fd, -1))
801722
goto done;
802723

803724
/* attach xdp prog to tunnel dev */
@@ -870,7 +791,7 @@ static void test_gre_tunnel(enum gre_test test)
870791
if (!ASSERT_OK(err, "add tunnel"))
871792
goto done;
872793

873-
if (generic_attach(GRE_TUNL_DEV1, get_fd, set_fd))
794+
if (tc_prog_attach(GRE_TUNL_DEV1, get_fd, set_fd))
874795
goto done;
875796

876797
ping_dev0();
@@ -911,7 +832,7 @@ static void test_ip6gre_tunnel(enum ip6gre_test test)
911832

912833
set_fd = bpf_program__fd(skel->progs.ip6gretap_set_tunnel);
913834
get_fd = bpf_program__fd(skel->progs.ip6gretap_get_tunnel);
914-
if (generic_attach(IP6GRE_TUNL_DEV1, get_fd, set_fd))
835+
if (tc_prog_attach(IP6GRE_TUNL_DEV1, get_fd, set_fd))
915836
goto done;
916837

917838
ping6_veth0();
@@ -954,7 +875,7 @@ static void test_erspan_tunnel(enum erspan_test test)
954875

955876
set_fd = bpf_program__fd(skel->progs.erspan_set_tunnel);
956877
get_fd = bpf_program__fd(skel->progs.erspan_get_tunnel);
957-
if (generic_attach(ERSPAN_TUNL_DEV1, get_fd, set_fd))
878+
if (tc_prog_attach(ERSPAN_TUNL_DEV1, get_fd, set_fd))
958879
goto done;
959880

960881
ping_dev0();
@@ -990,7 +911,7 @@ static void test_ip6erspan_tunnel(enum erspan_test test)
990911

991912
set_fd = bpf_program__fd(skel->progs.ip4ip6erspan_set_tunnel);
992913
get_fd = bpf_program__fd(skel->progs.ip4ip6erspan_get_tunnel);
993-
if (generic_attach(IP6ERSPAN_TUNL_DEV1, get_fd, set_fd))
914+
if (tc_prog_attach(IP6ERSPAN_TUNL_DEV1, get_fd, set_fd))
994915
goto done;
995916

996917
ping6_veth0();
@@ -1017,7 +938,7 @@ static void test_geneve_tunnel(void)
1017938

1018939
set_fd = bpf_program__fd(skel->progs.geneve_set_tunnel);
1019940
get_fd = bpf_program__fd(skel->progs.geneve_get_tunnel);
1020-
if (generic_attach(GENEVE_TUNL_DEV1, get_fd, set_fd))
941+
if (tc_prog_attach(GENEVE_TUNL_DEV1, get_fd, set_fd))
1021942
goto done;
1022943

1023944
ping_dev0();
@@ -1044,7 +965,7 @@ static void test_ip6geneve_tunnel(void)
1044965

1045966
set_fd = bpf_program__fd(skel->progs.ip6geneve_set_tunnel);
1046967
get_fd = bpf_program__fd(skel->progs.ip6geneve_get_tunnel);
1047-
if (generic_attach(IP6GENEVE_TUNL_DEV1, get_fd, set_fd))
968+
if (tc_prog_attach(IP6GENEVE_TUNL_DEV1, get_fd, set_fd))
1048969
goto done;
1049970

1050971
ping_dev0();
@@ -1083,7 +1004,7 @@ static void test_ip6tnl_tunnel(enum ip6tnl_test test)
10831004
get_fd = bpf_program__fd(skel->progs.ip6ip6_get_tunnel);
10841005
break;
10851006
}
1086-
if (generic_attach(IP6TNL_TUNL_DEV1, get_fd, set_fd))
1007+
if (tc_prog_attach(IP6TNL_TUNL_DEV1, get_fd, set_fd))
10871008
goto done;
10881009

10891010
ping6_veth0();

0 commit comments

Comments
 (0)