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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/progs/test_btf_skc_cls_ingress.c
Extension
.c
Size
4107 bytes
Lines
197
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

if (th->doff * 4 != 40) {
			LOG();
			return;
		}

		if ((void *)th + 40 > data_end) {
			LOG();
			return;
		}

		mss_cookie = bpf_tcp_gen_syncookie(tp, iphdr, iphdr_size,
						   th, 40);
		if (mss_cookie < 0) {
			if (mss_cookie != -ENOENT)
				LOG();
		} else {
			gen_cookie = (__u32)mss_cookie;
			mss = mss_cookie >> 32;
		}
	} else if (gen_cookie) {
		/* It was in cookie mode */
		int ret = bpf_tcp_check_syncookie(tp, iphdr, iphdr_size,
						  th, sizeof(*th));

		if (ret < 0) {
			if (ret != -ENOENT)
				LOG();
		} else {
			recv_cookie = bpf_ntohl(th->ack_seq) - 1;
		}
	}
}

static int handle_ip_tcp(struct ethhdr *eth, struct __sk_buff *skb)
{
	struct bpf_sock_tuple *tuple = NULL;
	unsigned int tuple_len = 0;
	struct bpf_sock *bpf_skc;
	void *data_end, *iphdr;
	struct ipv6hdr *ip6h;
	struct iphdr *ip4h;
	struct tcphdr *th;
	int iphdr_size;

	data_end = (void *)(long)(skb->data_end);

	switch (eth->h_proto) {
	case bpf_htons(ETH_P_IP):
		ip4h = (struct iphdr *)(eth + 1);
		if (ip4h + 1 > data_end)
			return TC_ACT_OK;
		if (ip4h->protocol != IPPROTO_TCP)
			return TC_ACT_OK;
		th = (struct tcphdr *)(ip4h + 1);
		if (th + 1 > data_end)
			return TC_ACT_OK;
		/* Is it the testing traffic? */
		if (th->dest != srv_sa4.sin_port)
			return TC_ACT_OK;
		tuple_len = sizeof(tuple->ipv4);
		tuple = (struct bpf_sock_tuple *)&ip4h->saddr;
		iphdr = ip4h;
		iphdr_size = sizeof(*ip4h);
		break;
	case bpf_htons(ETH_P_IPV6):
		ip6h = (struct ipv6hdr *)(eth + 1);
		if (ip6h + 1 > data_end)
			return TC_ACT_OK;
		if (ip6h->nexthdr != IPPROTO_TCP)
			return TC_ACT_OK;
		th = (struct tcphdr *)(ip6h + 1);
		if (th + 1 > data_end)
			return TC_ACT_OK;
		/* Is it the testing traffic? */
		if (th->dest != srv_sa6.sin6_port)
			return TC_ACT_OK;
		tuple_len = sizeof(tuple->ipv6);
		tuple = (struct bpf_sock_tuple *)&ip6h->saddr;
		iphdr = ip6h;
		iphdr_size = sizeof(*ip6h);
		break;
	default:
		return TC_ACT_OK;
	}

	if ((void *)tuple + tuple_len > data_end) {
		LOG();
		return TC_ACT_OK;
	}

Annotation

Implementation Notes