net/l3mdev/l3mdev.c

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

File Facts

System
Linux kernel
Corpus path
net/l3mdev/l3mdev.c
Extension
.c
Size
6796 bytes
Lines
304
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 l3mdev_handler {
	lookup_by_table_id_t dev_lookup;
};

static struct l3mdev_handler l3mdev_handlers[L3MDEV_TYPE_MAX + 1];

static int l3mdev_check_type(enum l3mdev_type l3type)
{
	if (l3type <= L3MDEV_TYPE_UNSPEC || l3type > L3MDEV_TYPE_MAX)
		return -EINVAL;

	return 0;
}

int l3mdev_table_lookup_register(enum l3mdev_type l3type,
				 lookup_by_table_id_t fn)
{
	struct l3mdev_handler *hdlr;
	int res;

	res = l3mdev_check_type(l3type);
	if (res)
		return res;

	hdlr = &l3mdev_handlers[l3type];

	spin_lock(&l3mdev_lock);

	if (hdlr->dev_lookup) {
		res = -EBUSY;
		goto unlock;
	}

	hdlr->dev_lookup = fn;
	res = 0;

unlock:
	spin_unlock(&l3mdev_lock);

	return res;
}
EXPORT_SYMBOL_GPL(l3mdev_table_lookup_register);

void l3mdev_table_lookup_unregister(enum l3mdev_type l3type,
				    lookup_by_table_id_t fn)
{
	struct l3mdev_handler *hdlr;

	if (l3mdev_check_type(l3type))
		return;

	hdlr = &l3mdev_handlers[l3type];

	spin_lock(&l3mdev_lock);

	if (hdlr->dev_lookup == fn)
		hdlr->dev_lookup = NULL;

	spin_unlock(&l3mdev_lock);
}
EXPORT_SYMBOL_GPL(l3mdev_table_lookup_unregister);

int l3mdev_ifindex_lookup_by_table_id(enum l3mdev_type l3type,
				      struct net *net, u32 table_id)
{
	lookup_by_table_id_t lookup;
	struct l3mdev_handler *hdlr;
	int ifindex = -EINVAL;
	int res;

	res = l3mdev_check_type(l3type);
	if (res)
		return res;

	hdlr = &l3mdev_handlers[l3type];

	spin_lock(&l3mdev_lock);

	lookup = hdlr->dev_lookup;
	if (!lookup)
		goto unlock;

	ifindex = lookup(net, table_id);

unlock:
	spin_unlock(&l3mdev_lock);

	return ifindex;
}
EXPORT_SYMBOL_GPL(l3mdev_ifindex_lookup_by_table_id);

Annotation

Implementation Notes