net/netlink/genetlink.c

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

File Facts

System
Linux kernel
Corpus path
net/netlink/genetlink.c
Extension
.c
Size
46106 bytes
Lines
2001
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

core_initcall(genl_init);

static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group)
{
	struct sk_buff *tmp;
	struct net *net, *prev = NULL;
	bool delivered = false;
	int err;

	rcu_read_lock();
	for_each_net_rcu(net) {
		if (prev) {
			tmp = skb_clone(skb, GFP_ATOMIC);
			if (!tmp) {
				err = -ENOMEM;
				goto error;
			}
			err = nlmsg_multicast(prev->genl_sock, tmp,
					      portid, group, GFP_ATOMIC);
			if (!err)
				delivered = true;
			else if (err != -ESRCH)
				goto error;
		}

		prev = net;
	}
	err = nlmsg_multicast(prev->genl_sock, skb, portid, group, GFP_ATOMIC);

	rcu_read_unlock();

	if (!err)
		delivered = true;
	else if (err != -ESRCH)
		return err;
	return delivered ? 0 : -ESRCH;
 error:
	rcu_read_unlock();

	kfree_skb(skb);
	return err;
}

int genlmsg_multicast_allns(const struct genl_family *family,
			    struct sk_buff *skb, u32 portid,
			    unsigned int group)
{
	if (WARN_ON_ONCE(group >= family->n_mcgrps)) {
		kfree_skb(skb);
		return -EINVAL;
	}

	group = family->mcgrp_offset + group;
	return genlmsg_mcast(skb, portid, group);
}
EXPORT_SYMBOL(genlmsg_multicast_allns);

void genl_notify(const struct genl_family *family, struct sk_buff *skb,
		 struct genl_info *info, u32 group, gfp_t flags)
{
	struct net *net = genl_info_net(info);
	struct sock *sk = net->genl_sock;

	if (WARN_ON_ONCE(group >= family->n_mcgrps)) {
		kfree_skb(skb);
		return;
	}

	group = family->mcgrp_offset + group;
	nlmsg_notify(sk, skb, info->snd_portid, group,
		     nlmsg_report(info->nlhdr), flags);
}
EXPORT_SYMBOL(genl_notify);

Annotation

Implementation Notes