net/ipv4/tcp_ipv4.c

Source file repositories/reference/linux-study-clean/net/ipv4/tcp_ipv4.c

File Facts

System
Linux kernel
Corpus path
net/ipv4/tcp_ipv4.c
Extension
.c
Size
99544 bytes
Lines
3666
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bpf_tcp_iter_state {
	struct tcp_iter_state state;
	unsigned int cur_sk;
	unsigned int end_sk;
	unsigned int max_sk;
	union bpf_tcp_iter_batch_item *batch;
};

struct bpf_iter__tcp {
	__bpf_md_ptr(struct bpf_iter_meta *, meta);
	__bpf_md_ptr(struct sock_common *, sk_common);
	uid_t uid __aligned(8);
};

static int tcp_prog_seq_show(struct bpf_prog *prog, struct bpf_iter_meta *meta,
			     struct sock_common *sk_common, uid_t uid)
{
	struct bpf_iter__tcp ctx;

	meta->seq_num--;  /* skip SEQ_START_TOKEN */
	ctx.meta = meta;
	ctx.sk_common = sk_common;
	ctx.uid = uid;
	return bpf_iter_run_prog(prog, &ctx);
}

static void bpf_iter_tcp_put_batch(struct bpf_tcp_iter_state *iter)
{
	union bpf_tcp_iter_batch_item *item;
	unsigned int cur_sk = iter->cur_sk;
	__u64 cookie;

	/* Remember the cookies of the sockets we haven't seen yet, so we can
	 * pick up where we left off next time around.
	 */
	while (cur_sk < iter->end_sk) {
		item = &iter->batch[cur_sk++];
		cookie = sock_gen_cookie(item->sk);
		sock_gen_put(item->sk);
		item->cookie = cookie;
	}
}

static int bpf_iter_tcp_realloc_batch(struct bpf_tcp_iter_state *iter,
				      unsigned int new_batch_sz, gfp_t flags)
{
	union bpf_tcp_iter_batch_item *new_batch;

	new_batch = kvmalloc(sizeof(*new_batch) * new_batch_sz,
			     flags | __GFP_NOWARN);
	if (!new_batch)
		return -ENOMEM;

	memcpy(new_batch, iter->batch, sizeof(*iter->batch) * iter->end_sk);
	kvfree(iter->batch);
	iter->batch = new_batch;
	iter->max_sk = new_batch_sz;

	return 0;
}

static struct sock *bpf_iter_tcp_resume_bucket(struct sock *first_sk,
					       union bpf_tcp_iter_batch_item *cookies,
					       int n_cookies)
{
	struct hlist_nulls_node *node;
	struct sock *sk;
	int i;

	for (i = 0; i < n_cookies; i++) {
		sk = first_sk;
		sk_nulls_for_each_from(sk, node)
			if (cookies[i].cookie == atomic64_read(&sk->sk_cookie))
				return sk;
	}

	return NULL;
}

static struct sock *bpf_iter_tcp_resume_listening(struct seq_file *seq)
{
	struct inet_hashinfo *hinfo = seq_file_net(seq)->ipv4.tcp_death_row.hashinfo;
	struct bpf_tcp_iter_state *iter = seq->private;
	struct tcp_iter_state *st = &iter->state;
	unsigned int find_cookie = iter->cur_sk;
	unsigned int end_cookie = iter->end_sk;
	int resume_bucket = st->bucket;
	struct sock *sk;

	if (end_cookie && find_cookie == end_cookie)

Annotation

Implementation Notes