All of lore.kernel.org
 help / color / mirror / Atom feed
From: Maciej Fijalkowski <maciej.fijalkowski@intel.com>
To: Amery Hung <ameryhung@gmail.com>
Cc: <bpf@vger.kernel.org>, <netdev@vger.kernel.org>,
	<alexei.starovoitov@gmail.com>, <andrii@kernel.org>,
	<daniel@iogearbox.net>, <paul.chaignon@gmail.com>,
	<kuba@kernel.org>, <stfomichev@gmail.com>,
	<martin.lau@kernel.org>, <mohsin.bashr@gmail.com>,
	<noren@nvidia.com>, <dtatulea@nvidia.com>, <saeedm@nvidia.com>,
	<tariqt@nvidia.com>, <mbloch@nvidia.com>, <kernel-team@meta.com>
Subject: Re: [PATCH bpf-next v4 5/6] selftests/bpf: Test bpf_xdp_pull_data
Date: Thu, 18 Sep 2025 13:33:48 +0200	[thread overview]
Message-ID: <aMvuHBb0+IIiXXuG@boxer> (raw)
In-Reply-To: <20250917225513.3388199-6-ameryhung@gmail.com>

On Wed, Sep 17, 2025 at 03:55:12PM -0700, Amery Hung wrote:
> Test bpf_xdp_pull_data() with xdp packets with different layouts. The
> xdp bpf program first checks if the layout is as expected. Then, it
> calls bpf_xdp_pull_data(). Finally, it checks the 0xbb marker at offset
> 1024 using directly packet access.
> 
> Signed-off-by: Amery Hung <ameryhung@gmail.com>
> ---
>  .../selftests/bpf/prog_tests/xdp_pull_data.c  | 176 ++++++++++++++++++
>  .../selftests/bpf/progs/test_xdp_pull_data.c  |  48 +++++
>  2 files changed, 224 insertions(+)
>  create mode 100644 tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
>  create mode 100644 tools/testing/selftests/bpf/progs/test_xdp_pull_data.c
> 
> diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> new file mode 100644
> index 000000000000..c16801b73fed
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
> @@ -0,0 +1,176 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <test_progs.h>
> +#include <network_helpers.h>
> +#include "test_xdp_pull_data.skel.h"
> +
> +#define PULL_MAX	(1 << 31)
> +#define PULL_PLUS_ONE	(1 << 30)
> +
> +#define XDP_PACKET_HEADROOM 256
> +
> +/* Find sizes of struct skb_shared_info and struct xdp_frame so that
> + * we can calculate the maximum pull lengths for test cases

do you really need this hack? Wouldn't it be possible to find these sizes
via BTF?

> + */
> +static int find_xdp_sizes(struct test_xdp_pull_data *skel, int frame_sz)
> +{
> +	LIBBPF_OPTS(bpf_test_run_opts, topts);
> +	struct xdp_md ctx = {};
> +	int prog_fd, err;
> +	__u8 *buf;
> +
> +	buf = calloc(frame_sz, sizeof(__u8));
> +	if (!ASSERT_OK_PTR(buf, "calloc buf"))
> +		return -ENOMEM;
> +
> +	topts.data_in = buf;
> +	topts.data_out = buf;
> +	topts.data_size_in = frame_sz;
> +	topts.data_size_out = frame_sz;
> +	/* Pass a data_end larger than the linear space available to make sure
> +	 * bpf_prog_test_run_xdp() will fill the linear data area so that
> +	 * xdp_find_data_hard_end can infer the size of struct skb_shared_info

what is xdp_find_data_hard_end ?

> +	 */
> +	ctx.data_end = frame_sz;
> +	topts.ctx_in = &ctx;
> +	topts.ctx_out = &ctx;
> +	topts.ctx_size_in = sizeof(ctx);
> +	topts.ctx_size_out = sizeof(ctx);
> +
> +	prog_fd = bpf_program__fd(skel->progs.xdp_find_sizes);
> +	err = bpf_prog_test_run_opts(prog_fd, &topts);
> +	ASSERT_OK(err, "bpf_prog_test_run_opts");
> +
> +	free(buf);
> +
> +	return err;
> +}
> +
> +/* xdp_pull_data_prog will directly read a marker 0xbb stored at buf[1024]
> + * so caller expecting XDP_PASS should always pass pull_len no less than 1024
> + */
> +static void run_test(struct test_xdp_pull_data *skel, int retval,
> +		     int frame_sz, int buff_len, int meta_len, int data_len,
> +		     int pull_len)
> +{
> +	LIBBPF_OPTS(bpf_test_run_opts, topts);
> +	struct xdp_md ctx = {};
> +	int prog_fd, err;
> +	__u8 *buf;
> +
> +	buf = calloc(buff_len, sizeof(__u8));
> +	if (!ASSERT_OK_PTR(buf, "calloc buf"))
> +		return;
> +
> +	buf[meta_len + 1023] = 0xaa;
> +	buf[meta_len + 1024] = 0xbb;
> +	buf[meta_len + 1025] = 0xcc;
> +
> +	topts.data_in = buf;
> +	topts.data_out = buf;
> +	topts.data_size_in = buff_len;
> +	topts.data_size_out = buff_len;
> +	ctx.data = meta_len;
> +	ctx.data_end = meta_len + data_len;
> +	topts.ctx_in = &ctx;
> +	topts.ctx_out = &ctx;
> +	topts.ctx_size_in = sizeof(ctx);
> +	topts.ctx_size_out = sizeof(ctx);
> +
> +	skel->bss->data_len = data_len;
> +	if (pull_len & PULL_MAX) {
> +		int headroom = XDP_PACKET_HEADROOM - meta_len - skel->bss->xdpf_sz;
> +		int tailroom = frame_sz - XDP_PACKET_HEADROOM -
> +			       data_len - skel->bss->sinfo_sz;
> +
> +		pull_len = pull_len & PULL_PLUS_ONE ? 1 : 0;

nit: pull_len = !!(pull_len & PULL_PLUS_ONE);

> +		pull_len += headroom + tailroom + data_len;
> +	}
> +	skel->bss->pull_len = pull_len;
> +
> +	prog_fd = bpf_program__fd(skel->progs.xdp_pull_data_prog);
> +	err = bpf_prog_test_run_opts(prog_fd, &topts);
> +	ASSERT_OK(err, "bpf_prog_test_run_opts");
> +	ASSERT_EQ(topts.retval, retval, "xdp_pull_data_prog retval");
> +
> +	if (retval == XDP_DROP)
> +		goto out;
> +
> +	ASSERT_EQ(ctx.data_end, meta_len + pull_len, "linear data size");
> +	ASSERT_EQ(topts.data_size_out, buff_len, "linear + non-linear data size");
> +	/* Make sure data around xdp->data_end was not messed up by
> +	 * bpf_xdp_pull_data()
> +	 */
> +	ASSERT_EQ(buf[meta_len + 1023], 0xaa, "data[1023]");
> +	ASSERT_EQ(buf[meta_len + 1024], 0xbb, "data[1024]");
> +	ASSERT_EQ(buf[meta_len + 1025], 0xcc, "data[1025]");
> +out:
> +	free(buf);
> +}
> +
> +static void test_xdp_pull_data_basic(void)
> +{
> +	u32 pg_sz, max_meta_len, max_data_len;
> +	struct test_xdp_pull_data *skel;
> +
> +	skel = test_xdp_pull_data__open_and_load();
> +	if (!ASSERT_OK_PTR(skel, "test_xdp_pull_data__open_and_load"))
> +		return;
> +
> +	pg_sz = sysconf(_SC_PAGE_SIZE);
> +
> +	if (find_xdp_sizes(skel, pg_sz))
> +		goto out;
> +
> +	max_meta_len = XDP_PACKET_HEADROOM - skel->bss->xdpf_sz;
> +	max_data_len = pg_sz - XDP_PACKET_HEADROOM - skel->bss->sinfo_sz;
> +
> +	/* linear xdp pkt, pull 0 byte */
> +	run_test(skel, XDP_PASS, pg_sz, 2048, 0, 2048, 2048);

you're passing pg_sz to avoid repeated syscalls I assume? Is it worth to pass
prog_fd as well?

> +
> +	/* multi-buf pkt, pull results in linear xdp pkt */
> +	run_test(skel, XDP_PASS, pg_sz, 2048, 0, 1024, 2048);
> +
> +	/* multi-buf pkt, pull 1 byte to linear data area */
> +	run_test(skel, XDP_PASS, pg_sz, 9000, 0, 1024, 1025);
> +
> +	/* multi-buf pkt, pull 0 byte to linear data area */
> +	run_test(skel, XDP_PASS, pg_sz, 9000, 0, 1025, 1025);
> +
> +	/* multi-buf pkt, empty linear data area, pull requires memmove */
> +	run_test(skel, XDP_PASS, pg_sz, 9000, 0, 0, PULL_MAX);
> +
> +	/* multi-buf pkt, no headroom */
> +	run_test(skel, XDP_PASS, pg_sz, 9000, max_meta_len, 1024, PULL_MAX);
> +
> +	/* multi-buf pkt, no tailroom, pull requires memmove */
> +	run_test(skel, XDP_PASS, pg_sz, 9000, 0, max_data_len, PULL_MAX);
> +

nit: double empty line

> +
> +	/* linear xdp pkt, pull more than total data len */
> +	run_test(skel, XDP_DROP, pg_sz, 2048, 0, 2048, 2049);
> +
> +	/* multi-buf pkt with no space left in linear data area */
> +	run_test(skel, XDP_DROP, pg_sz, 9000, max_meta_len, max_data_len,
> +		 PULL_MAX | PULL_PLUS_ONE);
> +
> +	/* multi-buf pkt, empty linear data area */
> +	run_test(skel, XDP_DROP, pg_sz, 9000, 0, 0, PULL_MAX | PULL_PLUS_ONE);
> +
> +	/* multi-buf pkt, no headroom */
> +	run_test(skel, XDP_DROP, pg_sz, 9000, max_meta_len, 1024,
> +		 PULL_MAX | PULL_PLUS_ONE);
> +
> +	/* multi-buf pkt, no tailroom */
> +	run_test(skel, XDP_DROP, pg_sz, 9000, 0, max_data_len,
> +		 PULL_MAX | PULL_PLUS_ONE);
> +
> +out:
> +	test_xdp_pull_data__destroy(skel);
> +}
> +
> +void test_xdp_pull_data(void)
> +{
> +	if (test__start_subtest("xdp_pull_data"))
> +		test_xdp_pull_data_basic();
> +}
> diff --git a/tools/testing/selftests/bpf/progs/test_xdp_pull_data.c b/tools/testing/selftests/bpf/progs/test_xdp_pull_data.c
> new file mode 100644
> index 000000000000..dd901bb109b6
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/test_xdp_pull_data.c
> @@ -0,0 +1,48 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include  "vmlinux.h"
> +#include <bpf/bpf_helpers.h>
> +
> +int xdpf_sz;
> +int sinfo_sz;
> +int data_len;
> +int pull_len;
> +
> +#define XDP_PACKET_HEADROOM 256
> +
> +SEC("xdp.frags")
> +int xdp_find_sizes(struct xdp_md *ctx)
> +{
> +	xdpf_sz = sizeof(struct xdp_frame);
> +	sinfo_sz = __PAGE_SIZE - XDP_PACKET_HEADROOM -
> +		   (ctx->data_end - ctx->data);
> +
> +	return XDP_PASS;
> +}
> +
> +SEC("xdp.frags")
> +int xdp_pull_data_prog(struct xdp_md *ctx)
> +{
> +	__u8 *data_end = (void *)(long)ctx->data_end;
> +	__u8 *data = (void *)(long)ctx->data;
> +	__u8 *val_p;
> +	int err;
> +
> +	if (data_len != data_end - data)
> +		return XDP_DROP;
> +
> +	err = bpf_xdp_pull_data(ctx, pull_len);
> +	if (err)
> +		return XDP_DROP;
> +
> +	val_p = (void *)(long)ctx->data + 1024;
> +	if (val_p + 1 > (void *)(long)ctx->data_end)
> +		return XDP_DROP;
> +
> +	if (*val_p != 0xbb)
> +		return XDP_DROP;
> +
> +	return XDP_PASS;
> +}
> +
> +char _license[] SEC("license") = "GPL";
> -- 
> 2.47.3
> 

  reply	other threads:[~2025-09-18 11:34 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-17 22:55 [PATCH bpf-next v4 0/6] Add kfunc bpf_xdp_pull_data Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 1/6] bpf: Allow bpf_xdp_shrink_data to shrink a frag from head and tail Amery Hung
2025-09-18  8:52   ` Maciej Fijalkowski
2025-09-18 17:50     ` Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 2/6] bpf: Support pulling non-linear xdp data Amery Hung
2025-09-18  9:11   ` Maciej Fijalkowski
2025-09-18 17:56     ` Amery Hung
2025-09-18 20:19       ` Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 3/6] bpf: Clear packet pointers after changing packet data in kfuncs Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 4/6] bpf: Support specifying linear xdp packet data size for BPF_PROG_TEST_RUN Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 5/6] selftests/bpf: Test bpf_xdp_pull_data Amery Hung
2025-09-18 11:33   ` Maciej Fijalkowski [this message]
2025-09-18 19:43     ` Amery Hung
2025-09-17 22:55 ` [PATCH bpf-next v4 6/6] selftests: drv-net: Pull data before parsing headers Amery Hung
  -- strict thread matches above, loose matches on Subject: below --
2025-09-19 18:09 [PATCH bpf-next v4 0/6] Add kfunc bpf_xdp_pull_data Amery Hung
2025-09-19 18:09 ` [PATCH bpf-next v4 5/6] selftests/bpf: Test bpf_xdp_pull_data Amery Hung

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aMvuHBb0+IIiXXuG@boxer \
    --to=maciej.fijalkowski@intel.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=ameryhung@gmail.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=dtatulea@nvidia.com \
    --cc=kernel-team@meta.com \
    --cc=kuba@kernel.org \
    --cc=martin.lau@kernel.org \
    --cc=mbloch@nvidia.com \
    --cc=mohsin.bashr@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=noren@nvidia.com \
    --cc=paul.chaignon@gmail.com \
    --cc=saeedm@nvidia.com \
    --cc=stfomichev@gmail.com \
    --cc=tariqt@nvidia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.