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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/xdp_do_redirect.c
Extension
.c
Size
12391 bytes
Lines
422
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

struct udp_packet {
	struct ethhdr eth;
	struct ipv6hdr iph;
	struct udphdr udp;
	__u8 payload[64 - sizeof(struct udphdr)
		     - sizeof(struct ethhdr) - sizeof(struct ipv6hdr)];
} __packed;

static struct udp_packet pkt_udp = {
	.eth.h_proto = __bpf_constant_htons(ETH_P_IPV6),
	.eth.h_dest = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55},
	.eth.h_source = {0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb},
	.iph.version = 6,
	.iph.nexthdr = IPPROTO_UDP,
	.iph.payload_len = bpf_htons(sizeof(struct udp_packet)
				     - offsetof(struct udp_packet, udp)),
	.iph.hop_limit = 2,
	.iph.saddr.s6_addr16 = {bpf_htons(0xfc00), 0, 0, 0, 0, 0, 0, bpf_htons(1)},
	.iph.daddr.s6_addr16 = {bpf_htons(0xfc00), 0, 0, 0, 0, 0, 0, bpf_htons(2)},
	.udp.source = bpf_htons(1),
	.udp.dest = bpf_htons(1),
	.udp.len = bpf_htons(sizeof(struct udp_packet)
			     - offsetof(struct udp_packet, udp)),
	.payload = {0x42}, /* receiver XDP program matches on this */
};

static int attach_tc_prog(struct bpf_tc_hook *hook, int fd)
{
	DECLARE_LIBBPF_OPTS(bpf_tc_opts, opts, .handle = 1, .priority = 1, .prog_fd = fd);
	int ret;

	ret = bpf_tc_hook_create(hook);
	if (!ASSERT_OK(ret, "create tc hook"))
		return ret;

	ret = bpf_tc_attach(hook, &opts);
	if (!ASSERT_OK(ret, "bpf_tc_attach")) {
		bpf_tc_hook_destroy(hook);
		return ret;
	}

	return 0;
}

/* The maximum permissible size is: PAGE_SIZE - sizeof(struct xdp_page_head) -
 * SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) - XDP_PACKET_HEADROOM =
 * 3408 bytes for 64-byte cacheline and 3216 for 256-byte one.
 */
#if defined(__s390x__)
#define MAX_PKT_SIZE 3216
#else
#define MAX_PKT_SIZE 3408
#endif

#define PAGE_SIZE_4K  4096
#define PAGE_SIZE_64K 65536

static void test_max_pkt_size(int fd)
{
	char data[PAGE_SIZE_64K + 1] = {};
	int err;
	DECLARE_LIBBPF_OPTS(bpf_test_run_opts, opts,
			    .data_in = &data,
			    .flags = BPF_F_TEST_XDP_LIVE_FRAMES,
			    .repeat = 1,
		);

	if (getpagesize() == PAGE_SIZE_64K)
		opts.data_size_in = MAX_PKT_SIZE + PAGE_SIZE_64K - PAGE_SIZE_4K;
	else
		opts.data_size_in = MAX_PKT_SIZE;

	err = bpf_prog_test_run_opts(fd, &opts);
	ASSERT_OK(err, "prog_run_max_size");

	opts.data_size_in += 1;
	err = bpf_prog_test_run_opts(fd, &opts);
	ASSERT_EQ(err, -EINVAL, "prog_run_too_big");
}

#define NUM_PKTS 10000
void test_xdp_do_redirect(void)
{
	int err, xdp_prog_fd, tc_prog_fd, ifindex_src, ifindex_dst;
	char data[sizeof(pkt_udp) + sizeof(__u64)];
	struct test_xdp_do_redirect *skel = NULL;
	struct nstoken *nstoken = NULL;
	struct bpf_link *link;
	LIBBPF_OPTS(bpf_xdp_query_opts, query_opts);
	struct xdp_md ctx_in = { .data = sizeof(__u64),

Annotation

Implementation Notes