tools/testing/selftests/bpf/progs/test_xdp_meta.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/progs/test_xdp_meta.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_xdp_meta.c
Extension
.c
Size
15288 bytes
Lines
674
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 <vmlinux.h>

#include <bpf/bpf_endian.h>
#include <bpf/bpf_helpers.h>
#include <errno.h>

#include "bpf_kfuncs.h"
#include "bpf_tracing_net.h"

#define META_SIZE 32

#define ctx_ptr(ctx, mem) (void *)(unsigned long)ctx->mem

/* Demonstrate passing metadata from XDP to TC using bpf_xdp_adjust_meta.
 *
 * The XDP program extracts a fixed-size payload following the Ethernet header
 * and stores it as packet metadata to test the driver's metadata support. The
 * TC program then verifies if the passed metadata is correct.
 */

bool test_pass;

static const __u8 smac_want[ETH_ALEN] = {
	0x12, 0x34, 0xDE, 0xAD, 0xBE, 0xEF,
};

static const __u8 meta_want[META_SIZE] = {
	0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
};

static bool check_smac(const struct ethhdr *eth)
{
	return !__builtin_memcmp(eth->h_source, smac_want, ETH_ALEN);
}

static bool check_metadata(const char *file, int line, __u8 *meta_have)
{
	if (!__builtin_memcmp(meta_have, meta_want, META_SIZE))
		return true;

	bpf_stream_printk(BPF_STDERR,
			  "FAIL:%s:%d: metadata mismatch\n"
			  "  have:\n    %pI6\n    %pI6\n"
			  "  want:\n    %pI6\n    %pI6\n",
			  file, line,
			  &meta_have[0x00], &meta_have[0x10],
			  &meta_want[0x00], &meta_want[0x10]);
	return false;
}

#define check_metadata(meta_have) check_metadata(__FILE__, __LINE__, meta_have)

static bool check_skb_metadata(const char *file, int line, struct __sk_buff *skb)
{
	__u8 *data_meta = ctx_ptr(skb, data_meta);
	__u8 *data = ctx_ptr(skb, data);

	return data_meta + META_SIZE <= data && (check_metadata)(file, line, data_meta);
}

#define check_skb_metadata(skb) check_skb_metadata(__FILE__, __LINE__, skb)

SEC("tc")
int ing_cls(struct __sk_buff *ctx)
{
	__u8 *meta_have = ctx_ptr(ctx, data_meta);
	__u8 *data = ctx_ptr(ctx, data);

	if (meta_have + META_SIZE > data)
		goto out;

	if (!check_metadata(meta_have))
		goto out;

	test_pass = true;
out:
	return TC_ACT_SHOT;
}

/* Read from metadata using bpf_dynptr_read helper */
SEC("tc")
int ing_cls_dynptr_read(struct __sk_buff *ctx)
{
	__u8 meta_have[META_SIZE];
	struct bpf_dynptr meta;

Annotation

Implementation Notes