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

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/xdp_pull_data.c
Extension
.c
Size
5380 bytes
Lines
182
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// 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 headroom and tailroom occupied by struct xdp_frame and struct
 * skb_shared_info so that we can calculate the maximum pull lengths for
 * test cases. They might not be the real size of the structures due to
 * cache alignment.
 */
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_sizes can infer the size of struct skb_shared_info
	 */
	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;
		pull_len += headroom + tailroom + data_len;
	}

Annotation

Implementation Notes