diff options
Diffstat (limited to 'net/mctp')
| -rw-r--r-- | net/mctp/af_mctp.c | 3 | ||||
| -rw-r--r-- | net/mctp/device.c | 53 | ||||
| -rw-r--r-- | net/mctp/neigh.c | 9 | ||||
| -rw-r--r-- | net/mctp/route.c | 16 | ||||
| -rw-r--r-- | net/mctp/test/route-test.c | 7 | ||||
| -rw-r--r-- | net/mctp/test/utils.c | 2 | 
6 files changed, 63 insertions, 27 deletions
| diff --git a/net/mctp/af_mctp.c b/net/mctp/af_mctp.c index 871cf6266125..c921de63b494 100644 --- a/net/mctp/af_mctp.c +++ b/net/mctp/af_mctp.c @@ -405,8 +405,7 @@ static void mctp_sk_unhash(struct sock *sk)  		trace_mctp_key_release(key, MCTP_TRACE_KEY_CLOSED);  		spin_lock(&key->lock); -		if (key->reasm_head) -			kfree_skb(key->reasm_head); +		kfree_skb(key->reasm_head);  		key->reasm_head = NULL;  		key->reasm_dead = true;  		key->valid = false; diff --git a/net/mctp/device.c b/net/mctp/device.c index 8799ee77e7b7..ef2755f82f87 100644 --- a/net/mctp/device.c +++ b/net/mctp/device.c @@ -35,14 +35,24 @@ struct mctp_dev *mctp_dev_get_rtnl(const struct net_device *dev)  	return rtnl_dereference(dev->mctp_ptr);  } -static int mctp_fill_addrinfo(struct sk_buff *skb, struct netlink_callback *cb, -			      struct mctp_dev *mdev, mctp_eid_t eid) +static int mctp_addrinfo_size(void) +{ +	return NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +		+ nla_total_size(1) // IFA_LOCAL +		+ nla_total_size(1) // IFA_ADDRESS +		; +} + +/* flag should be NLM_F_MULTI for dump calls */ +static int mctp_fill_addrinfo(struct sk_buff *skb, +			      struct mctp_dev *mdev, mctp_eid_t eid, +			      int msg_type, u32 portid, u32 seq, int flag)  {  	struct ifaddrmsg *hdr;  	struct nlmsghdr *nlh; -	nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, -			RTM_NEWADDR, sizeof(*hdr), NLM_F_MULTI); +	nlh = nlmsg_put(skb, portid, seq, +			msg_type, sizeof(*hdr), flag);  	if (!nlh)  		return -EMSGSIZE; @@ -72,10 +82,14 @@ static int mctp_dump_dev_addrinfo(struct mctp_dev *mdev, struct sk_buff *skb,  				  struct netlink_callback *cb)  {  	struct mctp_dump_cb *mcb = (void *)cb->ctx; +	u32 portid, seq;  	int rc = 0; +	portid = NETLINK_CB(cb->skb).portid; +	seq = cb->nlh->nlmsg_seq;  	for (; mcb->a_idx < mdev->num_addrs; mcb->a_idx++) { -		rc = mctp_fill_addrinfo(skb, cb, mdev, mdev->addrs[mcb->a_idx]); +		rc = mctp_fill_addrinfo(skb, mdev, mdev->addrs[mcb->a_idx], +					RTM_NEWADDR, portid, seq, NLM_F_MULTI);  		if (rc < 0)  			break;  	} @@ -127,6 +141,32 @@ out:  	return skb->len;  } +static void mctp_addr_notify(struct mctp_dev *mdev, mctp_eid_t eid, int msg_type, +			     struct sk_buff *req_skb, struct nlmsghdr *req_nlh) +{ +	u32 portid = NETLINK_CB(req_skb).portid; +	struct net *net = dev_net(mdev->dev); +	struct sk_buff *skb; +	int rc = -ENOBUFS; + +	skb = nlmsg_new(mctp_addrinfo_size(), GFP_KERNEL); +	if (!skb) +		goto out; + +	rc = mctp_fill_addrinfo(skb, mdev, eid, msg_type, +				portid, req_nlh->nlmsg_seq, 0); +	if (rc < 0) { +		WARN_ON_ONCE(rc == -EMSGSIZE); +		goto out; +	} + +	rtnl_notify(skb, net, portid, RTNLGRP_MCTP_IFADDR, req_nlh, GFP_KERNEL); +	return; +out: +	kfree_skb(skb); +	rtnl_set_sk_err(net, RTNLGRP_MCTP_IFADDR, rc); +} +  static const struct nla_policy ifa_mctp_policy[IFA_MAX + 1] = {  	[IFA_ADDRESS]		= { .type = NLA_U8 },  	[IFA_LOCAL]		= { .type = NLA_U8 }, @@ -189,6 +229,7 @@ static int mctp_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,  	kfree(tmp_addrs); +	mctp_addr_notify(mdev, addr->s_addr, RTM_NEWADDR, skb, nlh);  	mctp_route_add_local(mdev, addr->s_addr);  	return 0; @@ -244,6 +285,8 @@ static int mctp_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,  	mdev->num_addrs--;  	spin_unlock_irqrestore(&mdev->addrs_lock, flags); +	mctp_addr_notify(mdev, addr->s_addr, RTM_DELADDR, skb, nlh); +  	return 0;  } diff --git a/net/mctp/neigh.c b/net/mctp/neigh.c index 5cc042121493..6ad3e33bd4d4 100644 --- a/net/mctp/neigh.c +++ b/net/mctp/neigh.c @@ -85,8 +85,8 @@ void mctp_neigh_remove_dev(struct mctp_dev *mdev)  	mutex_unlock(&net->mctp.neigh_lock);  } -// TODO: add a "source" flag so netlink can only delete static neighbours? -static int mctp_neigh_remove(struct mctp_dev *mdev, mctp_eid_t eid) +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; @@ -94,7 +94,8 @@ static int mctp_neigh_remove(struct mctp_dev *mdev, mctp_eid_t eid)  	mutex_lock(&net->mctp.neigh_lock);  	list_for_each_entry_safe(neigh, tmp, &net->mctp.neighbours, list) { -		if (neigh->dev == mdev && neigh->eid == eid) { +		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); @@ -202,7 +203,7 @@ static int mctp_rtm_delneigh(struct sk_buff *skb, struct nlmsghdr *nlh,  	if (!mdev)  		return -ENODEV; -	return mctp_neigh_remove(mdev, eid); +	return mctp_neigh_remove(mdev, eid, MCTP_NEIGH_STATIC);  }  static int mctp_fill_neigh(struct sk_buff *skb, u32 portid, u32 seq, int event, diff --git a/net/mctp/route.c b/net/mctp/route.c index 46c44823edb7..8d9f4ff3e285 100644 --- a/net/mctp/route.c +++ b/net/mctp/route.c @@ -231,9 +231,7 @@ static void __mctp_key_unlock_drop(struct mctp_sk_key *key, struct net *net,  	/* and one for the local reference */  	mctp_key_unref(key); -	if (skb) -		kfree_skb(skb); - +	kfree_skb(skb);  }  #ifdef CONFIG_MCTP_FLOWS @@ -892,8 +890,7 @@ out_release:  	if (!ext_rt)  		mctp_route_release(rt); -	if (dev) -		dev_put(dev); +	dev_put(dev);  	return rc; @@ -952,7 +949,7 @@ static int mctp_route_add(struct mctp_dev *mdev, mctp_eid_t daddr_start,  }  static int mctp_route_remove(struct mctp_dev *mdev, mctp_eid_t daddr_start, -			     unsigned int daddr_extent) +			     unsigned int daddr_extent, unsigned char type)  {  	struct net *net = dev_net(mdev->dev);  	struct mctp_route *rt, *tmp; @@ -969,7 +966,8 @@ static int mctp_route_remove(struct mctp_dev *mdev, mctp_eid_t daddr_start,  	list_for_each_entry_safe(rt, tmp, &net->mctp.routes, list) {  		if (rt->dev == mdev && -		    rt->min == daddr_start && rt->max == daddr_end) { +		    rt->min == daddr_start && rt->max == daddr_end && +		    rt->type == type) {  			list_del_rcu(&rt->list);  			/* TODO: immediate RTM_DELROUTE */  			mctp_route_release(rt); @@ -987,7 +985,7 @@ int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr)  int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr)  { -	return mctp_route_remove(mdev, addr, 0); +	return mctp_route_remove(mdev, addr, 0, RTN_LOCAL);  }  /* removes all entries for a given device */ @@ -1195,7 +1193,7 @@ static int mctp_delroute(struct sk_buff *skb, struct nlmsghdr *nlh,  	if (rtm->rtm_type != RTN_UNICAST)  		return -EINVAL; -	rc = mctp_route_remove(mdev, daddr_start, rtm->rtm_dst_len); +	rc = mctp_route_remove(mdev, daddr_start, rtm->rtm_dst_len, RTN_UNICAST);  	return rc;  } diff --git a/net/mctp/test/route-test.c b/net/mctp/test/route-test.c index 36fac3daf86a..750f9f9b4daf 100644 --- a/net/mctp/test/route-test.c +++ b/net/mctp/test/route-test.c @@ -150,11 +150,6 @@ static void mctp_test_fragment(struct kunit *test)  	rt = mctp_test_create_route(&init_net, NULL, 10, mtu);  	KUNIT_ASSERT_TRUE(test, rt); -	/* The refcount would usually be incremented as part of a route lookup, -	 * but we're setting the route directly here. -	 */ -	refcount_inc(&rt->rt.refs); -  	rc = mctp_do_fragment_route(&rt->rt, skb, mtu, MCTP_TAG_OWNER);  	KUNIT_EXPECT_FALSE(test, rc); @@ -290,7 +285,7 @@ static void __mctp_route_test_init(struct kunit *test,  				   struct mctp_test_route **rtp,  				   struct socket **sockp)  { -	struct sockaddr_mctp addr; +	struct sockaddr_mctp addr = {0};  	struct mctp_test_route *rt;  	struct mctp_test_dev *dev;  	struct socket *sock; diff --git a/net/mctp/test/utils.c b/net/mctp/test/utils.c index cc6b8803aa9d..7b7918702592 100644 --- a/net/mctp/test/utils.c +++ b/net/mctp/test/utils.c @@ -12,7 +12,7 @@  static netdev_tx_t mctp_test_dev_tx(struct sk_buff *skb,  				    struct net_device *ndev)  { -	kfree(skb); +	kfree_skb(skb);  	return NETDEV_TX_OK;  } |