samples/bpf/test_lwt_bpf.c

Source file repositories/reference/linux-study-clean/samples/bpf/test_lwt_bpf.c

File Facts

System
Linux kernel
Corpus path
samples/bpf/test_lwt_bpf.c
Extension
.c
Size
5966 bytes
Lines
246
Domain
Support Tooling And Documentation
Bucket
samples
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

if (ret < 0) {
			printk("bpf_l4_csum_replace failed: %d");
			return BPF_DROP;
		}
	}

	ret = bpf_l3_csum_replace(skb, IP_CSUM_OFF, old_ip, new_ip, sizeof(new_ip));
	if (ret < 0) {
		printk("bpf_l3_csum_replace failed: %d", ret);
		return BPF_DROP;
	}

	if (rw_daddr)
		ret = bpf_skb_store_bytes(skb, IP_DST_OFF, &new_ip, sizeof(new_ip), 0);
	else
		ret = bpf_skb_store_bytes(skb, IP_SRC_OFF, &new_ip, sizeof(new_ip), 0);

	if (ret < 0) {
		printk("bpf_skb_store_bytes() failed: %d", ret);
		return BPF_DROP;
	}

	return BPF_OK;
}

/* Test: Verify skb data can be modified */
SEC("test_rewrite")
int do_test_rewrite(struct __sk_buff *skb)
{
	uint32_t old_ip, new_ip = 0x3fea8c0;
	int ret;

	ret = bpf_skb_load_bytes(skb, IP_DST_OFF, &old_ip, 4);
	if (ret < 0) {
		printk("bpf_skb_load_bytes failed: %d", ret);
		return BPF_DROP;
	}

	if (old_ip == 0x2fea8c0) {
		printk("out: rewriting from %x to %x", old_ip, new_ip);
		return rewrite(skb, old_ip, new_ip, 1);
	}

	return BPF_OK;
}

static inline int __do_push_ll_and_redirect(struct __sk_buff *skb)
{
	uint64_t smac = SRC_MAC, dmac = DST_MAC;
	int ret, ifindex = DST_IFINDEX;
	struct ethhdr ehdr;

	ret = bpf_skb_change_head(skb, 14, 0);
	if (ret < 0) {
		printk("skb_change_head() failed: %d", ret);
	}

	ehdr.h_proto = bpf_htons(ETH_P_IP);
	memcpy(&ehdr.h_source, &smac, 6);
	memcpy(&ehdr.h_dest, &dmac, 6);

	ret = bpf_skb_store_bytes(skb, 0, &ehdr, sizeof(ehdr), 0);
	if (ret < 0) {
		printk("skb_store_bytes() failed: %d", ret);
		return BPF_DROP;
	}

	return bpf_redirect(ifindex, 0);
}

SEC("push_ll_and_redirect_silent")
int do_push_ll_and_redirect_silent(struct __sk_buff *skb)
{
	return __do_push_ll_and_redirect(skb);
}

SEC("push_ll_and_redirect")
int do_push_ll_and_redirect(struct __sk_buff *skb)
{
	int ret, ifindex = DST_IFINDEX;

	ret = __do_push_ll_and_redirect(skb);
	if (ret >= 0)
		printk("redirected to %d", ifindex);

	return ret;
}

static inline void __fill_garbage(struct __sk_buff *skb)
{

Annotation

Implementation Notes