net/core/net-procfs.c

Source file repositories/reference/linux-study-clean/net/core/net-procfs.c

File Facts

System
Linux kernel
Corpus path
net/core/net-procfs.c
Extension
.c
Size
9882 bytes
Lines
418
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source 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 ptype_iter_state {
	struct seq_net_private	p;
	struct net_device	*dev;
};

static void *ptype_get_idx(struct seq_file *seq, loff_t pos)
{
	struct ptype_iter_state *iter = seq->private;
	struct list_head *ptype_list = NULL;
	struct packet_type *pt = NULL;
	struct net_device *dev;
	loff_t i = 0;
	int t;

	for_each_netdev_rcu(seq_file_net(seq), dev) {
		ptype_list = &dev->ptype_all;
		list_for_each_entry_rcu(pt, ptype_list, list) {
			if (i == pos) {
				iter->dev = dev;
				return pt;
			}
			++i;
		}
	}

	iter->dev = NULL;

	list_for_each_entry_rcu(pt, &seq_file_net(seq)->ptype_all, list) {
		if (i == pos)
			return pt;
		++i;
	}

	list_for_each_entry_rcu(pt, &seq_file_net(seq)->ptype_specific, list) {
		if (i == pos)
			return pt;
		++i;
	}

	for (t = 0; t < PTYPE_HASH_SIZE; t++) {
		list_for_each_entry_rcu(pt, &ptype_base[t], list) {
			if (i == pos)
				return pt;
			++i;
		}
	}
	return NULL;
}

static void *ptype_seq_start(struct seq_file *seq, loff_t *pos)
	__acquires(RCU)
{
	rcu_read_lock();
	return *pos ? ptype_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
}

static void *ptype_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct ptype_iter_state *iter = seq->private;
	struct net *net = seq_file_net(seq);
	struct net_device *dev;
	struct packet_type *pt;
	struct list_head *nxt;
	int hash;

	++*pos;
	if (v == SEQ_START_TOKEN)
		return ptype_get_idx(seq, 0);

	pt = v;
	nxt = READ_ONCE(pt->list.next);
	dev = iter->dev;
	if (dev) {
		if (nxt != &dev->ptype_all)
			goto found;

		for_each_netdev_continue_rcu(seq_file_net(seq), dev) {
			nxt = READ_ONCE(dev->ptype_all.next);
			if (nxt != &dev->ptype_all) {
				iter->dev = dev;
				goto found;
			}
		}
		iter->dev = NULL;
		nxt = READ_ONCE(net->ptype_all.next);
		goto net_ptype_all;
	}

	if (pt->af_packet_net) {
net_ptype_all:

Annotation

Implementation Notes