[PATCH bpf-next 2/5] selftests/bpf: add tc helpers

Alexis Lothoré (eBPF Foundation) posted 5 patches 3 months, 3 weeks ago
There is a newer version of this series
[PATCH bpf-next 2/5] selftests/bpf: add tc helpers
Posted by Alexis Lothoré (eBPF Foundation) 3 months, 3 weeks ago
The test_tunnel.c file defines small fonctions to easily attach eBPF
programs to tc hooks, either on egress, ingress or both.

Move those helpers in a dedicated file so that other tests can benefit
from it.

Signed-off-by: Alexis Lothoré (eBPF Foundation) <alexis.lothore@bootlin.com>
---
 tools/testing/selftests/bpf/Makefile               |  1 +
 .../testing/selftests/bpf/prog_tests/test_tunnel.c | 80 +-------------------
 tools/testing/selftests/bpf/tc_helpers.c           | 87 ++++++++++++++++++++++
 tools/testing/selftests/bpf/tc_helpers.h           |  9 +++
 4 files changed, 98 insertions(+), 79 deletions(-)

diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index f00587d4ede68ef08419bdd545f0ce8e6c3fcfd2..2f248dab922f57e2c14053cb0bdfbb547efe1292 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -737,6 +737,7 @@ TRUNNER_EXTRA_SOURCES := test_progs.c		\
 			 netlink_helpers.c	\
 			 jit_disasm_helpers.c	\
 			 io_helpers.c		\
+			 tc_helpers.c		\
 			 test_loader.c		\
 			 xsk.c			\
 			 disasm.c		\
diff --git a/tools/testing/selftests/bpf/prog_tests/test_tunnel.c b/tools/testing/selftests/bpf/prog_tests/test_tunnel.c
index bae0e9de277d24c34938de30b42f3418ecb6fba8..9e5577c74d60b02a7d39158967112805111b69d8 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_tunnel.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_tunnel.c
@@ -64,6 +64,7 @@
 
 #include "test_progs.h"
 #include "network_helpers.h"
+#include "tc_helpers.h"
 #include "test_tunnel_kern.skel.h"
 
 #define IP4_ADDR_VETH0 "172.16.1.100"
@@ -534,85 +535,6 @@ static void ping6_dev1(void)
 	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);
-	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);
-		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
-			bpf_tc_hook_destroy(&hook);
-			return ret;
-		}
-	}
-
-	if (egr_fd >= 0) {
-		hook.attach_point = BPF_TC_EGRESS;
-		ret = bpf_tc_attach(&hook, &opts2);
-		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
-			bpf_tc_hook_destroy(&hook);
-			return ret;
-		}
-	}
-
-	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;
diff --git a/tools/testing/selftests/bpf/tc_helpers.c b/tools/testing/selftests/bpf/tc_helpers.c
new file mode 100644
index 0000000000000000000000000000000000000000..d668e10e3ebad8f8e04862f5c2b3ccd487fe8fa6
--- /dev/null
+++ b/tools/testing/selftests/bpf/tc_helpers.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#define _GNU_SOURCE
+
+#include <net/if.h>
+#include "tc_helpers.h"
+#include "test_progs.h"
+
+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);
+	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);
+		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
+			bpf_tc_hook_destroy(&hook);
+			return ret;
+		}
+	}
+
+	if (egr_fd >= 0) {
+		hook.attach_point = BPF_TC_EGRESS;
+		ret = bpf_tc_attach(&hook, &opts2);
+		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
+			bpf_tc_hook_destroy(&hook);
+			return ret;
+		}
+	}
+
+	return 0;
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+
diff --git a/tools/testing/selftests/bpf/tc_helpers.h b/tools/testing/selftests/bpf/tc_helpers.h
new file mode 100644
index 0000000000000000000000000000000000000000..d31abe33f9d80dadd8f829bcf9a68cfd744c3b99
--- /dev/null
+++ b/tools/testing/selftests/bpf/tc_helpers.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __TC_HELPERS_H
+#define __TC_HELPERS_H
+
+
+int generic_attach(const char *dev, int igr_fd, int egr_fd);
+int generic_attach_igr(const char *dev, int igr_fd);
+int generic_attach_egr(const char *dev, int egr_fd);
+#endif

-- 
2.51.0

Re: [PATCH bpf-next 2/5] selftests/bpf: add tc helpers
Posted by Martin KaFai Lau 3 months, 3 weeks ago

On 10/17/25 7:29 AM, Alexis Lothoré (eBPF Foundation) wrote:
> diff --git a/tools/testing/selftests/bpf/tc_helpers.c b/tools/testing/selftests/bpf/tc_helpers.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..d668e10e3ebad8f8e04862f5c2b3ccd487fe8fa6
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/tc_helpers.c
> @@ -0,0 +1,87 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#define _GNU_SOURCE
> +
> +#include <net/if.h>
> +#include "tc_helpers.h"
> +#include "test_progs.h"
> +
> +static int attach_tc_prog(int ifindex, int igr_fd, int egr_fd)

This one looks good but change it to "int tc_prog_attach(const char 
*dev, int ingress_fd, int egress_fd)". Remove static. Take "const char 
*dev" as the arg. Add it to network_helpers.[ch] instead of creating a 
new source file.

> +{
> +	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);
> +	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);
> +		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
> +			bpf_tc_hook_destroy(&hook);
> +			return ret;
> +		}
> +	}
> +
> +	if (egr_fd >= 0) {
> +		hook.attach_point = BPF_TC_EGRESS;
> +		ret = bpf_tc_attach(&hook, &opts2);
> +		if (!ASSERT_OK(ret, "bpf_tc_attach")) {
> +			bpf_tc_hook_destroy(&hook);
> +			return ret;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +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);
> +}
> +
> +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);
> +}
> +
> +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);
> +}

These three generic_attach_* is a bit overkill for network_helpers.c.

Change test_tunnel.c to directly use tc_prog_attach().

> +
> +
> diff --git a/tools/testing/selftests/bpf/tc_helpers.h b/tools/testing/selftests/bpf/tc_helpers.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..d31abe33f9d80dadd8f829bcf9a68cfd744c3b99
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/tc_helpers.h

This new file is not needed also. Use the network_helpers.h.

Re: [PATCH bpf-next 2/5] selftests/bpf: add tc helpers
Posted by Alexis Lothoré 3 months, 3 weeks ago
On Sat Oct 18, 2025 at 1:26 AM CEST, Martin KaFai Lau wrote:
>
>
> On 10/17/25 7:29 AM, Alexis Lothoré (eBPF Foundation) wrote:
>> diff --git a/tools/testing/selftests/bpf/tc_helpers.c b/tools/testing/selftests/bpf/tc_helpers.c
>> new file mode 100644
>> index 0000000000000000000000000000000000000000..d668e10e3ebad8f8e04862f5c2b3ccd487fe8fa6
>> --- /dev/null
>> +++ b/tools/testing/selftests/bpf/tc_helpers.c
>> @@ -0,0 +1,87 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +#define _GNU_SOURCE
>> +
>> +#include <net/if.h>
>> +#include "tc_helpers.h"
>> +#include "test_progs.h"
>> +
>> +static int attach_tc_prog(int ifindex, int igr_fd, int egr_fd)
>
> This one looks good but change it to "int tc_prog_attach(const char 
> *dev, int ingress_fd, int egress_fd)". Remove static. Take "const char 
> *dev" as the arg. Add it to network_helpers.[ch] instead of creating a 
> new source file.

Nice, thanks for the hint, I missed this header

Alexis

-- 
Alexis Lothoré, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com