net/mctp/neigh.c

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

File Facts

System
Linux kernel
Corpus path
net/mctp/neigh.c
Extension
.c
Size
8182 bytes
Lines
355
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

if (neigh->dev == mdev) {
			list_del_rcu(&neigh->list);
			/* TODO: immediate RTM_DELNEIGH */
			call_rcu(&neigh->rcu, __mctp_neigh_free);
		}
	}

	mutex_unlock(&net->mctp.neigh_lock);
}

static int mctp_neigh_remove(struct mctp_dev *mdev, mctp_eid_t eid,
			     enum mctp_neigh_source source)
{
	struct net *net = dev_net(mdev->dev);
	struct mctp_neigh *neigh, *tmp;
	bool dropped = false;

	mutex_lock(&net->mctp.neigh_lock);
	list_for_each_entry_safe(neigh, tmp, &net->mctp.neighbours, list) {
		if (neigh->dev == mdev && neigh->eid == eid &&
		    neigh->source == source) {
			list_del_rcu(&neigh->list);
			/* TODO: immediate RTM_DELNEIGH */
			call_rcu(&neigh->rcu, __mctp_neigh_free);
			dropped = true;
		}
	}

	mutex_unlock(&net->mctp.neigh_lock);
	return dropped ? 0 : -ENOENT;
}

static const struct nla_policy nd_mctp_policy[NDA_MAX + 1] = {
	[NDA_DST]		= { .type = NLA_U8 },
	[NDA_LLADDR]		= { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
};

static int mctp_rtm_newneigh(struct sk_buff *skb, struct nlmsghdr *nlh,
			     struct netlink_ext_ack *extack)
{
	struct net *net = sock_net(skb->sk);
	struct net_device *dev;
	struct mctp_dev *mdev;
	struct ndmsg *ndm;
	struct nlattr *tb[NDA_MAX + 1];
	int rc;
	mctp_eid_t eid;
	void *lladdr;
	int lladdr_len;

	rc = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, nd_mctp_policy,
			 extack);
	if (rc < 0) {
		NL_SET_ERR_MSG(extack, "lladdr too large?");
		return rc;
	}

	if (!tb[NDA_DST]) {
		NL_SET_ERR_MSG(extack, "Neighbour EID must be specified");
		return -EINVAL;
	}

	if (!tb[NDA_LLADDR]) {
		NL_SET_ERR_MSG(extack, "Neighbour lladdr must be specified");
		return -EINVAL;
	}

	eid = nla_get_u8(tb[NDA_DST]);
	if (!mctp_address_unicast(eid)) {
		NL_SET_ERR_MSG(extack, "Invalid neighbour EID");
		return -EINVAL;
	}

	lladdr = nla_data(tb[NDA_LLADDR]);
	lladdr_len = nla_len(tb[NDA_LLADDR]);

	ndm = nlmsg_data(nlh);

	dev = __dev_get_by_index(net, ndm->ndm_ifindex);
	if (!dev)
		return -ENODEV;

	mdev = mctp_dev_get_rtnl(dev);
	if (!mdev)
		return -ENODEV;

	if (lladdr_len != dev->addr_len) {
		NL_SET_ERR_MSG(extack, "Wrong lladdr length");
		return -EINVAL;
	}

Annotation

Implementation Notes