diff mbox series

[bpf-next,v3,5/6] selftests/bpf: add test for XDP metadata support in tun driver

Message ID 20250224152909.3911544-6-marcus.wichelmann@hetzner-cloud.de (mailing list archive)
State New
Headers show
Series XDP metadata support for tun driver | expand

Commit Message

Marcus Wichelmann Feb. 24, 2025, 3:29 p.m. UTC
Add a selftest that creates a tap device, attaches XDP and TC programs,
writes a packet with a test payload into the tap device and checks the
test result. This test ensures that the XDP metadata support in the tun
driver is enabled and that the metadata size is correctly passed to the
skb.

See the previous commit ("selftests/bpf: refactor xdp_context_functional
test and bpf program") for details about the test design.

Signed-off-by: Marcus Wichelmann <marcus.wichelmann@hetzner-cloud.de>
---
 .../bpf/prog_tests/xdp_context_test_run.c     | 64 +++++++++++++++++++
 1 file changed, 64 insertions(+)

Comments

Stanislav Fomichev Feb. 24, 2025, 5:14 p.m. UTC | #1
On 02/24, Marcus Wichelmann wrote:
> Add a selftest that creates a tap device, attaches XDP and TC programs,
> writes a packet with a test payload into the tap device and checks the
> test result. This test ensures that the XDP metadata support in the tun
> driver is enabled and that the metadata size is correctly passed to the
> skb.
> 
> See the previous commit ("selftests/bpf: refactor xdp_context_functional
> test and bpf program") for details about the test design.
> 
> Signed-off-by: Marcus Wichelmann <marcus.wichelmann@hetzner-cloud.de>
> ---
>  .../bpf/prog_tests/xdp_context_test_run.c     | 64 +++++++++++++++++++
>  1 file changed, 64 insertions(+)
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
> index 4043f220d7c0..60aad6bd8882 100644
> --- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
> @@ -8,6 +8,7 @@
>  #define TX_NAME "veth1"
>  #define TX_NETNS "xdp_context_tx"
>  #define RX_NETNS "xdp_context_rx"
> +#define TAP_NAME "tap0"
>  
>  #define TEST_PAYLOAD_LEN 32
>  static const __u8 test_payload[TEST_PAYLOAD_LEN] = {
> @@ -251,3 +252,66 @@ void test_xdp_context_veth(void)
>  	netns_free(tx_ns);
>  }
>  
> +void test_xdp_context_tuntap(void)

tap0 is already used by lwt tests, so there is a chance this new test
will clash with it? Should we run your new test in a net namespace
to be safe? Bastien recently added a change where you can make
your test run in a net ns by naming the function test_ns_xxx.
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
index 4043f220d7c0..60aad6bd8882 100644
--- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
+++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
@@ -8,6 +8,7 @@ 
 #define TX_NAME "veth1"
 #define TX_NETNS "xdp_context_tx"
 #define RX_NETNS "xdp_context_rx"
+#define TAP_NAME "tap0"
 
 #define TEST_PAYLOAD_LEN 32
 static const __u8 test_payload[TEST_PAYLOAD_LEN] = {
@@ -251,3 +252,66 @@  void test_xdp_context_veth(void)
 	netns_free(tx_ns);
 }
 
+void test_xdp_context_tuntap(void)
+{
+	LIBBPF_OPTS(bpf_tc_hook, tc_hook, .attach_point = BPF_TC_INGRESS);
+	LIBBPF_OPTS(bpf_tc_opts, tc_opts, .handle = 1, .priority = 1);
+	struct test_xdp_meta *skel = NULL;
+	__u8 packet[sizeof(struct ethhdr) + TEST_PAYLOAD_LEN];
+	int tap_fd = -1;
+	int tap_ifindex;
+	int ret;
+
+	tap_fd = open_tuntap(TAP_NAME, true);
+	if (!ASSERT_GE(tap_fd, 0, "open_tuntap"))
+		goto close;
+
+	/* By default, Linux sends IPv6 multicast listener reports which
+	 * interfere with this test. Set the IFF_NOARP flag to ensure
+	 * silence on the interface.
+	 */
+	SYS(close, "ip link set dev " TAP_NAME " arp off");
+	SYS(close, "ip link set dev " TAP_NAME " up");
+
+	skel = test_xdp_meta__open_and_load();
+	if (!ASSERT_OK_PTR(skel, "open and load skeleton"))
+		goto close;
+
+	tap_ifindex = if_nametoindex(TAP_NAME);
+	if (!ASSERT_GE(tap_ifindex, 0, "if_nametoindex"))
+		goto close;
+
+	tc_hook.ifindex = tap_ifindex;
+	ret = bpf_tc_hook_create(&tc_hook);
+	if (!ASSERT_OK(ret, "bpf_tc_hook_create"))
+		goto close;
+
+	tc_opts.prog_fd = bpf_program__fd(skel->progs.ing_cls);
+	ret = bpf_tc_attach(&tc_hook, &tc_opts);
+	if (!ASSERT_OK(ret, "bpf_tc_attach"))
+		goto close;
+
+	ret = bpf_xdp_attach(tap_ifindex, bpf_program__fd(skel->progs.ing_xdp),
+			     0, NULL);
+	if (!ASSERT_GE(ret, 0, "bpf_xdp_attach"))
+		goto close;
+
+	/* The ethernet header is not relevant for this test and doesn't need to
+	 * be meaningful.
+	 */
+	struct ethhdr eth = { 0 };
+
+	memcpy(packet, &eth, sizeof(eth));
+	memcpy(packet + sizeof(eth), test_payload, TEST_PAYLOAD_LEN);
+
+	ret = write(tap_fd, packet, sizeof(packet));
+	if (!ASSERT_EQ(ret, sizeof(packet), "write packet"))
+		goto close;
+
+	assert_test_result(skel);
+
+close:
+	if (tap_fd >= 0)
+		close(tap_fd);
+	test_xdp_meta__destroy(skel);
+}