diff options
Diffstat (limited to 'net/core/rtnetlink.c')
| -rw-r--r-- | net/core/rtnetlink.c | 31 | 
1 files changed, 19 insertions, 12 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 393b1bc9a618..120eecc0f5a4 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -374,7 +374,7 @@ static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev)  	if (!master_dev)  		return 0;  	ops = master_dev->rtnl_link_ops; -	if (!ops->get_slave_size) +	if (!ops || !ops->get_slave_size)  		return 0;  	/* IFLA_INFO_SLAVE_DATA + nested data */  	return nla_total_size(sizeof(struct nlattr)) + @@ -1963,16 +1963,21 @@ replay:  		dev->ifindex = ifm->ifi_index; -		if (ops->newlink) +		if (ops->newlink) {  			err = ops->newlink(net, dev, tb, data); -		else +			/* Drivers should call free_netdev() in ->destructor +			 * and unregister it on failure so that device could be +			 * finally freed in rtnl_unlock. +			 */ +			if (err < 0) +				goto out; +		} else {  			err = register_netdevice(dev); - -		if (err < 0) { -			free_netdev(dev); -			goto out; +			if (err < 0) { +				free_netdev(dev); +				goto out; +			}  		} -  		err = rtnl_configure_link(dev, ifm);  		if (err < 0)  			unregister_netdevice(dev); @@ -2116,12 +2121,13 @@ EXPORT_SYMBOL(rtmsg_ifinfo);  static int nlmsg_populate_fdb_fill(struct sk_buff *skb,  				   struct net_device *dev,  				   u8 *addr, u32 pid, u32 seq, -				   int type, unsigned int flags) +				   int type, unsigned int flags, +				   int nlflags)  {  	struct nlmsghdr *nlh;  	struct ndmsg *ndm; -	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI); +	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags);  	if (!nlh)  		return -EMSGSIZE; @@ -2159,7 +2165,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type)  	if (!skb)  		goto errout; -	err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF); +	err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0);  	if (err < 0) {  		kfree_skb(skb);  		goto errout; @@ -2384,7 +2390,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb,  		err = nlmsg_populate_fdb_fill(skb, dev, ha->addr,  					      portid, seq, -					      RTM_NEWNEIGH, NTF_SELF); +					      RTM_NEWNEIGH, NTF_SELF, +					      NLM_F_MULTI);  		if (err < 0)  			return err;  skip:  | 
