diff mbox series

[bpf-next] selftests/xsk: add xdp populate metadata test

Message ID 20230320102705.306187-1-tushar.vyavahare@intel.com (mailing list archive)
State Accepted
Commit 9a321fd3308e262f2a76761bea86dd0f311e3f86
Delegated to: BPF
Headers show
Series [bpf-next] selftests/xsk: add xdp populate metadata test | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for bpf-next, async
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 20 this patch: 20
netdev/cc_maintainers warning 9 maintainers not CCed: linux-kselftest@vger.kernel.org mykolal@fb.com bjorn@kernel.org shuah@kernel.org jonathan.lemon@gmail.com kuba@kernel.org hawk@kernel.org netdev@vger.kernel.org davem@davemloft.net
netdev/build_clang success Errors and warnings before: 18 this patch: 18
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 20 this patch: 20
netdev/checkpatch warning WARNING: Prefer __aligned(32) over __attribute__((aligned(32))) WARNING: added, moved or deleted file(s), does MAINTAINERS need updating? WARNING: line length of 84 exceeds 80 columns WARNING: line length of 86 exceeds 80 columns WARNING: line length of 99 exceeds 80 columns
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next-VM_Test-1 success Logs for ShellCheck
bpf/vmtest-bpf-next-VM_Test-2 success Logs for build for aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-3 success Logs for build for aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-5 success Logs for build for x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-6 success Logs for build for x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-7 success Logs for llvm-toolchain
bpf/vmtest-bpf-next-VM_Test-8 success Logs for set-matrix
bpf/vmtest-bpf-next-VM_Test-4 success Logs for build for s390x with gcc
bpf/vmtest-bpf-next-VM_Test-9 success Logs for test_maps on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-10 success Logs for test_maps on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-12 success Logs for test_maps on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-13 success Logs for test_maps on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-14 success Logs for test_progs on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-15 success Logs for test_progs on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-17 success Logs for test_progs on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-18 success Logs for test_progs on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-19 success Logs for test_progs_no_alu32 on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-20 success Logs for test_progs_no_alu32 on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-22 success Logs for test_progs_no_alu32 on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-23 success Logs for test_progs_no_alu32 on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-24 success Logs for test_progs_no_alu32_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-25 success Logs for test_progs_no_alu32_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-26 success Logs for test_progs_no_alu32_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-27 success Logs for test_progs_no_alu32_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-28 success Logs for test_progs_parallel on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-29 success Logs for test_progs_parallel on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-30 success Logs for test_progs_parallel on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-31 success Logs for test_progs_parallel on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-32 success Logs for test_verifier on aarch64 with gcc
bpf/vmtest-bpf-next-VM_Test-33 success Logs for test_verifier on aarch64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-35 success Logs for test_verifier on x86_64 with gcc
bpf/vmtest-bpf-next-VM_Test-36 success Logs for test_verifier on x86_64 with llvm-16
bpf/vmtest-bpf-next-VM_Test-21 fail Logs for test_progs_no_alu32 on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-34 success Logs for test_verifier on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-16 success Logs for test_progs on s390x with gcc
bpf/vmtest-bpf-next-VM_Test-11 success Logs for test_maps on s390x with gcc

Commit Message

Tushar Vyavahare March 20, 2023, 10:27 a.m. UTC
Add a new test in copy-mode for testing the copying of metadata from the
buffer in kernel-space to user-space. This is accomplished by adding a
new XDP program and using the bss map to store a counter that is written
to the metadata field. This counter is incremented for every packet so
that the number becomes unique and should be the same as the payload. It
is store in the bss so the value can be reset between runs.

The XDP program populates the metadata and the userspace program checks
the value stored in the metadata field against the payload using the new
is_metadata_correct() function. To turn this verification on or off, add
a new parameter (use_metadata) to the ifobject structure.

Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
---
 .../selftests/bpf/progs/xsk_xdp_progs.c       | 25 ++++++++++
 .../testing/selftests/bpf/xsk_xdp_metadata.h  |  5 ++
 tools/testing/selftests/bpf/xskxceiver.c      | 46 ++++++++++++++++++-
 tools/testing/selftests/bpf/xskxceiver.h      |  2 +
 4 files changed, 77 insertions(+), 1 deletion(-)
 create mode 100644 tools/testing/selftests/bpf/xsk_xdp_metadata.h

Comments

Fijalkowski, Maciej March 20, 2023, 5:44 p.m. UTC | #1
On Mon, Mar 20, 2023 at 03:57:05PM +0530, Tushar Vyavahare wrote:
> Add a new test in copy-mode for testing the copying of metadata from the
> buffer in kernel-space to user-space. This is accomplished by adding a
> new XDP program and using the bss map to store a counter that is written
> to the metadata field. This counter is incremented for every packet so
> that the number becomes unique and should be the same as the payload. It
> is store in the bss so the value can be reset between runs.
> 
> The XDP program populates the metadata and the userspace program checks
> the value stored in the metadata field against the payload using the new
> is_metadata_correct() function. To turn this verification on or off, add
> a new parameter (use_metadata) to the ifobject structure.
> 

Reviewed-by: Maciej Fijalkowski <maciej.fijalkowski@intel.com>

> Signed-off-by: Tushar Vyavahare <tushar.vyavahare@intel.com>
> ---
>  .../selftests/bpf/progs/xsk_xdp_progs.c       | 25 ++++++++++
>  .../testing/selftests/bpf/xsk_xdp_metadata.h  |  5 ++
>  tools/testing/selftests/bpf/xskxceiver.c      | 46 ++++++++++++++++++-
>  tools/testing/selftests/bpf/xskxceiver.h      |  2 +
>  4 files changed, 77 insertions(+), 1 deletion(-)
>  create mode 100644 tools/testing/selftests/bpf/xsk_xdp_metadata.h
> 
> diff --git a/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c b/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
> index 744a01d0e57d..a630c95c7471 100644
> --- a/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
> +++ b/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
> @@ -3,6 +3,7 @@
>  
>  #include <linux/bpf.h>
>  #include <bpf/bpf_helpers.h>
> +#include "xsk_xdp_metadata.h"
>  
>  struct {
>  	__uint(type, BPF_MAP_TYPE_XSKMAP);
> @@ -12,6 +13,7 @@ struct {
>  } xsk SEC(".maps");
>  
>  static unsigned int idx;
> +int count = 0;
>  
>  SEC("xdp") int xsk_def_prog(struct xdp_md *xdp)
>  {
> @@ -27,4 +29,27 @@ SEC("xdp") int xsk_xdp_drop(struct xdp_md *xdp)
>  	return bpf_redirect_map(&xsk, 0, XDP_DROP);
>  }
>  
> +SEC("xdp") int xsk_xdp_populate_metadata(struct xdp_md *xdp)
> +{
> +	void *data, *data_meta;
> +	struct xdp_info *meta;
> +	int err;
> +
> +	/* Reserve enough for all custom metadata. */
> +	err = bpf_xdp_adjust_meta(xdp, -(int)sizeof(struct xdp_info));
> +	if (err)
> +		return XDP_DROP;
> +
> +	data = (void *)(long)xdp->data;
> +	data_meta = (void *)(long)xdp->data_meta;
> +
> +	if (data_meta + sizeof(struct xdp_info) > data)
> +		return XDP_DROP;
> +
> +	meta = data_meta;
> +	meta->count = count++;
> +
> +	return bpf_redirect_map(&xsk, 0, XDP_DROP);
> +}
> +
>  char _license[] SEC("license") = "GPL";
> diff --git a/tools/testing/selftests/bpf/xsk_xdp_metadata.h b/tools/testing/selftests/bpf/xsk_xdp_metadata.h
> new file mode 100644
> index 000000000000..943133da378a
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/xsk_xdp_metadata.h
> @@ -0,0 +1,5 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +struct xdp_info {
> +	__u64 count;
> +} __attribute__((aligned(32)));
> diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
> index a17655107a94..b65e0645b0cd 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.c
> +++ b/tools/testing/selftests/bpf/xskxceiver.c
> @@ -103,6 +103,7 @@
>  #include <bpf/bpf.h>
>  #include <linux/filter.h>
>  #include "../kselftest.h"
> +#include "xsk_xdp_metadata.h"
>  
>  static const char *MAC1 = "\x00\x0A\x56\x9E\xEE\x62";
>  static const char *MAC2 = "\x00\x0A\x56\x9E\xEE\x61";
> @@ -464,6 +465,7 @@ static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
>  		ifobj->use_fill_ring = true;
>  		ifobj->release_rx = true;
>  		ifobj->validation_func = NULL;
> +		ifobj->use_metadata = false;
>  
>  		if (i == 0) {
>  			ifobj->rx_on = false;
> @@ -798,6 +800,20 @@ static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt_stream *pkt
>  	return false;
>  }
>  
> +static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
> +{
> +	void *data = xsk_umem__get_data(buffer, addr);
> +	struct xdp_info *meta = data - sizeof(struct xdp_info);
> +
> +	if (meta->count != pkt->payload) {
> +		ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%d]\n",
> +			       __func__, pkt->payload, meta->count);
> +		return false;
> +	}
> +
> +	return true;
> +}
> +
>  static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
>  {
>  	void *data = xsk_umem__get_data(buffer, addr);
> @@ -959,7 +975,8 @@ static int receive_pkts(struct test_spec *test, struct pollfd *fds)
>  			addr = xsk_umem__add_offset_to_addr(addr);
>  
>  			if (!is_pkt_valid(pkt, umem->buffer, addr, desc->len) ||
> -			    !is_offset_correct(umem, pkt_stream, addr, pkt->addr))
> +			    !is_offset_correct(umem, pkt_stream, addr, pkt->addr) ||
> +			    (ifobj->use_metadata && !is_metadata_correct(pkt, umem->buffer, addr)))
>  				return TEST_FAILURE;
>  
>  			if (ifobj->use_fill_ring)
> @@ -1686,6 +1703,30 @@ static void testapp_xdp_drop(struct test_spec *test)
>  	testapp_validate_traffic(test);
>  }
>  
> +static void testapp_xdp_metadata_count(struct test_spec *test)
> +{
> +	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
> +	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
> +	struct bpf_map *data_map;
> +	int count = 0;
> +	int key = 0;
> +
> +	test_spec_set_name(test, "XDP_METADATA_COUNT");
> +	test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_populate_metadata,
> +			       skel_tx->progs.xsk_xdp_populate_metadata,
> +			       skel_rx->maps.xsk, skel_tx->maps.xsk);
> +	test->ifobj_rx->use_metadata = true;
> +
> +	data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss");
> +	if (!data_map || !bpf_map__is_internal(data_map))
> +		exit_with_error(ENOMEM);
> +
> +	if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
> +		exit_with_error(errno);
> +
> +	testapp_validate_traffic(test);
> +}
> +
>  static void testapp_poll_txq_tmout(struct test_spec *test)
>  {
>  	test_spec_set_name(test, "POLL_TXQ_FULL");
> @@ -1835,6 +1876,9 @@ static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
>  	case TEST_TYPE_XDP_DROP_HALF:
>  		testapp_xdp_drop(test);
>  		break;
> +	case TEST_TYPE_XDP_METADATA_COUNT:
> +		testapp_xdp_metadata_count(test);
> +		break;
>  	default:
>  		break;
>  	}
> diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
> index 3e8ec7d8ec32..bdb4efedf3a9 100644
> --- a/tools/testing/selftests/bpf/xskxceiver.h
> +++ b/tools/testing/selftests/bpf/xskxceiver.h
> @@ -88,6 +88,7 @@ enum test_type {
>  	TEST_TYPE_STATS_FILL_EMPTY,
>  	TEST_TYPE_BPF_RES,
>  	TEST_TYPE_XDP_DROP_HALF,
> +	TEST_TYPE_XDP_METADATA_COUNT,
>  	TEST_TYPE_MAX
>  };
>  
> @@ -158,6 +159,7 @@ struct ifobject {
>  	bool use_fill_ring;
>  	bool release_rx;
>  	bool shared_umem;
> +	bool use_metadata;
>  	u8 dst_mac[ETH_ALEN];
>  	u8 src_mac[ETH_ALEN];
>  };
> -- 
> 2.25.1
>
patchwork-bot+netdevbpf@kernel.org March 22, 2023, 4:20 p.m. UTC | #2
Hello:

This patch was applied to bpf/bpf-next.git (master)
by Alexei Starovoitov <ast@kernel.org>:

On Mon, 20 Mar 2023 15:57:05 +0530 you wrote:
> Add a new test in copy-mode for testing the copying of metadata from the
> buffer in kernel-space to user-space. This is accomplished by adding a
> new XDP program and using the bss map to store a counter that is written
> to the metadata field. This counter is incremented for every packet so
> that the number becomes unique and should be the same as the payload. It
> is store in the bss so the value can be reset between runs.
> 
> [...]

Here is the summary with links:
  - [bpf-next] selftests/xsk: add xdp populate metadata test
    https://git.kernel.org/bpf/bpf-next/c/9a321fd3308e

You are awesome, thank you!
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c b/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
index 744a01d0e57d..a630c95c7471 100644
--- a/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
+++ b/tools/testing/selftests/bpf/progs/xsk_xdp_progs.c
@@ -3,6 +3,7 @@ 
 
 #include <linux/bpf.h>
 #include <bpf/bpf_helpers.h>
+#include "xsk_xdp_metadata.h"
 
 struct {
 	__uint(type, BPF_MAP_TYPE_XSKMAP);
@@ -12,6 +13,7 @@  struct {
 } xsk SEC(".maps");
 
 static unsigned int idx;
+int count = 0;
 
 SEC("xdp") int xsk_def_prog(struct xdp_md *xdp)
 {
@@ -27,4 +29,27 @@  SEC("xdp") int xsk_xdp_drop(struct xdp_md *xdp)
 	return bpf_redirect_map(&xsk, 0, XDP_DROP);
 }
 
+SEC("xdp") int xsk_xdp_populate_metadata(struct xdp_md *xdp)
+{
+	void *data, *data_meta;
+	struct xdp_info *meta;
+	int err;
+
+	/* Reserve enough for all custom metadata. */
+	err = bpf_xdp_adjust_meta(xdp, -(int)sizeof(struct xdp_info));
+	if (err)
+		return XDP_DROP;
+
+	data = (void *)(long)xdp->data;
+	data_meta = (void *)(long)xdp->data_meta;
+
+	if (data_meta + sizeof(struct xdp_info) > data)
+		return XDP_DROP;
+
+	meta = data_meta;
+	meta->count = count++;
+
+	return bpf_redirect_map(&xsk, 0, XDP_DROP);
+}
+
 char _license[] SEC("license") = "GPL";
diff --git a/tools/testing/selftests/bpf/xsk_xdp_metadata.h b/tools/testing/selftests/bpf/xsk_xdp_metadata.h
new file mode 100644
index 000000000000..943133da378a
--- /dev/null
+++ b/tools/testing/selftests/bpf/xsk_xdp_metadata.h
@@ -0,0 +1,5 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+
+struct xdp_info {
+	__u64 count;
+} __attribute__((aligned(32)));
diff --git a/tools/testing/selftests/bpf/xskxceiver.c b/tools/testing/selftests/bpf/xskxceiver.c
index a17655107a94..b65e0645b0cd 100644
--- a/tools/testing/selftests/bpf/xskxceiver.c
+++ b/tools/testing/selftests/bpf/xskxceiver.c
@@ -103,6 +103,7 @@ 
 #include <bpf/bpf.h>
 #include <linux/filter.h>
 #include "../kselftest.h"
+#include "xsk_xdp_metadata.h"
 
 static const char *MAC1 = "\x00\x0A\x56\x9E\xEE\x62";
 static const char *MAC2 = "\x00\x0A\x56\x9E\xEE\x61";
@@ -464,6 +465,7 @@  static void __test_spec_init(struct test_spec *test, struct ifobject *ifobj_tx,
 		ifobj->use_fill_ring = true;
 		ifobj->release_rx = true;
 		ifobj->validation_func = NULL;
+		ifobj->use_metadata = false;
 
 		if (i == 0) {
 			ifobj->rx_on = false;
@@ -798,6 +800,20 @@  static bool is_offset_correct(struct xsk_umem_info *umem, struct pkt_stream *pkt
 	return false;
 }
 
+static bool is_metadata_correct(struct pkt *pkt, void *buffer, u64 addr)
+{
+	void *data = xsk_umem__get_data(buffer, addr);
+	struct xdp_info *meta = data - sizeof(struct xdp_info);
+
+	if (meta->count != pkt->payload) {
+		ksft_print_msg("[%s] expected meta_count [%d], got meta_count [%d]\n",
+			       __func__, pkt->payload, meta->count);
+		return false;
+	}
+
+	return true;
+}
+
 static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
 {
 	void *data = xsk_umem__get_data(buffer, addr);
@@ -959,7 +975,8 @@  static int receive_pkts(struct test_spec *test, struct pollfd *fds)
 			addr = xsk_umem__add_offset_to_addr(addr);
 
 			if (!is_pkt_valid(pkt, umem->buffer, addr, desc->len) ||
-			    !is_offset_correct(umem, pkt_stream, addr, pkt->addr))
+			    !is_offset_correct(umem, pkt_stream, addr, pkt->addr) ||
+			    (ifobj->use_metadata && !is_metadata_correct(pkt, umem->buffer, addr)))
 				return TEST_FAILURE;
 
 			if (ifobj->use_fill_ring)
@@ -1686,6 +1703,30 @@  static void testapp_xdp_drop(struct test_spec *test)
 	testapp_validate_traffic(test);
 }
 
+static void testapp_xdp_metadata_count(struct test_spec *test)
+{
+	struct xsk_xdp_progs *skel_rx = test->ifobj_rx->xdp_progs;
+	struct xsk_xdp_progs *skel_tx = test->ifobj_tx->xdp_progs;
+	struct bpf_map *data_map;
+	int count = 0;
+	int key = 0;
+
+	test_spec_set_name(test, "XDP_METADATA_COUNT");
+	test_spec_set_xdp_prog(test, skel_rx->progs.xsk_xdp_populate_metadata,
+			       skel_tx->progs.xsk_xdp_populate_metadata,
+			       skel_rx->maps.xsk, skel_tx->maps.xsk);
+	test->ifobj_rx->use_metadata = true;
+
+	data_map = bpf_object__find_map_by_name(skel_rx->obj, "xsk_xdp_.bss");
+	if (!data_map || !bpf_map__is_internal(data_map))
+		exit_with_error(ENOMEM);
+
+	if (bpf_map_update_elem(bpf_map__fd(data_map), &key, &count, BPF_ANY))
+		exit_with_error(errno);
+
+	testapp_validate_traffic(test);
+}
+
 static void testapp_poll_txq_tmout(struct test_spec *test)
 {
 	test_spec_set_name(test, "POLL_TXQ_FULL");
@@ -1835,6 +1876,9 @@  static void run_pkt_test(struct test_spec *test, enum test_mode mode, enum test_
 	case TEST_TYPE_XDP_DROP_HALF:
 		testapp_xdp_drop(test);
 		break;
+	case TEST_TYPE_XDP_METADATA_COUNT:
+		testapp_xdp_metadata_count(test);
+		break;
 	default:
 		break;
 	}
diff --git a/tools/testing/selftests/bpf/xskxceiver.h b/tools/testing/selftests/bpf/xskxceiver.h
index 3e8ec7d8ec32..bdb4efedf3a9 100644
--- a/tools/testing/selftests/bpf/xskxceiver.h
+++ b/tools/testing/selftests/bpf/xskxceiver.h
@@ -88,6 +88,7 @@  enum test_type {
 	TEST_TYPE_STATS_FILL_EMPTY,
 	TEST_TYPE_BPF_RES,
 	TEST_TYPE_XDP_DROP_HALF,
+	TEST_TYPE_XDP_METADATA_COUNT,
 	TEST_TYPE_MAX
 };
 
@@ -158,6 +159,7 @@  struct ifobject {
 	bool use_fill_ring;
 	bool release_rx;
 	bool shared_umem;
+	bool use_metadata;
 	u8 dst_mac[ETH_ALEN];
 	u8 src_mac[ETH_ALEN];
 };