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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_tcp_custom_syncookie.c
Extension
.c
Size
13169 bytes
Lines
592
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 tcp_syncookie {
	struct __sk_buff *skb;
	void *data;
	void *data_end;
	struct ethhdr *eth;
	struct iphdr *ipv4;
	struct ipv6hdr *ipv6;
	struct tcphdr *tcp;
	__be32 *ptr32;
	struct bpf_tcp_req_attrs attrs;
	u32 off;
	u32 cookie;
	u64 first;
};

bool handled_syn, handled_ack;

static int tcp_load_headers(struct tcp_syncookie *ctx)
{
	ctx->data = (void *)(long)ctx->skb->data;
	ctx->data_end = (void *)(long)ctx->skb->data_end;
	ctx->eth = (struct ethhdr *)(long)ctx->skb->data;

	if (ctx->eth + 1 > ctx->data_end)
		goto err;

	switch (bpf_ntohs(ctx->eth->h_proto)) {
	case ETH_P_IP:
		ctx->ipv4 = (struct iphdr *)(ctx->eth + 1);

		if (ctx->ipv4 + 1 > ctx->data_end)
			goto err;

		if (ctx->ipv4->ihl != sizeof(*ctx->ipv4) / 4)
			goto err;

		if (ctx->ipv4->version != 4)
			goto err;

		if (ctx->ipv4->protocol != IPPROTO_TCP)
			goto err;

		ctx->tcp = (struct tcphdr *)(ctx->ipv4 + 1);
		break;
	case ETH_P_IPV6:
		ctx->ipv6 = (struct ipv6hdr *)(ctx->eth + 1);

		if (ctx->ipv6 + 1 > ctx->data_end)
			goto err;

		if (ctx->ipv6->version != 6)
			goto err;

		if (ctx->ipv6->nexthdr != NEXTHDR_TCP)
			goto err;

		ctx->tcp = (struct tcphdr *)(ctx->ipv6 + 1);
		break;
	default:
		goto err;
	}

	if (ctx->tcp + 1 > ctx->data_end)
		goto err;

	return 0;
err:
	return -1;
}

static int tcp_reload_headers(struct tcp_syncookie *ctx)
{
	/* Without volatile,
	 * R3 32-bit pointer arithmetic prohibited
	 */
	volatile u64 data_len = ctx->skb->data_end - ctx->skb->data;

	if (ctx->tcp->doff < sizeof(*ctx->tcp) / 4)
		goto err;

	/* Needed to calculate csum and parse TCP options. */
	if (bpf_skb_change_tail(ctx->skb, data_len + 60 - ctx->tcp->doff * 4, 0))
		goto err;

	ctx->data = (void *)(long)ctx->skb->data;
	ctx->data_end = (void *)(long)ctx->skb->data_end;
	ctx->eth = (struct ethhdr *)(long)ctx->skb->data;
	if (ctx->ipv4) {
		ctx->ipv4 = (struct iphdr *)(ctx->eth + 1);
		ctx->ipv6 = NULL;

Annotation

Implementation Notes