diff options
Diffstat (limited to 'net/ipv6/ip6mr.c')
| -rw-r--r-- | net/ipv6/ip6mr.c | 17 | 
1 files changed, 11 insertions, 6 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 716153941fc..52e0f74fdfe 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -477,7 +477,7 @@ failure:   *	Delete a VIF entry   */ -static int mif6_delete(struct net *net, int vifi) +static int mif6_delete(struct net *net, int vifi, struct list_head *head)  {  	struct mif_device *v;  	struct net_device *dev; @@ -519,7 +519,7 @@ static int mif6_delete(struct net *net, int vifi)  		in6_dev->cnf.mc_forwarding--;  	if (v->flags & MIFF_REGISTER) -		unregister_netdevice(dev); +		unregister_netdevice_queue(dev, head);  	dev_put(dev);  	return 0; @@ -976,6 +976,7 @@ static int ip6mr_device_event(struct notifier_block *this,  	struct net *net = dev_net(dev);  	struct mif_device *v;  	int ct; +	LIST_HEAD(list);  	if (event != NETDEV_UNREGISTER)  		return NOTIFY_DONE; @@ -983,8 +984,10 @@ static int ip6mr_device_event(struct notifier_block *this,  	v = &net->ipv6.vif6_table[0];  	for (ct = 0; ct < net->ipv6.maxvif; ct++, v++) {  		if (v->dev == dev) -			mif6_delete(net, ct); +			mif6_delete(net, ct, &list);  	} +	unregister_netdevice_many(&list); +  	return NOTIFY_DONE;  } @@ -1188,14 +1191,16 @@ static int ip6mr_mfc_add(struct net *net, struct mf6cctl *mfc, int mrtsock)  static void mroute_clean_tables(struct net *net)  {  	int i; +	LIST_HEAD(list);  	/*  	 *	Shut down all active vif entries  	 */  	for (i = 0; i < net->ipv6.maxvif; i++) {  		if (!(net->ipv6.vif6_table[i].flags & VIFF_STATIC)) -			mif6_delete(net, i); +			mif6_delete(net, i, &list);  	} +	unregister_netdevice_many(&list);  	/*  	 *	Wipe the cache @@ -1297,7 +1302,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns  	switch (optname) {  	case MRT6_INIT:  		if (sk->sk_type != SOCK_RAW || -		    inet_sk(sk)->num != IPPROTO_ICMPV6) +		    inet_sk(sk)->inet_num != IPPROTO_ICMPV6)  			return -EOPNOTSUPP;  		if (optlen < sizeof(int))  			return -EINVAL; @@ -1325,7 +1330,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns  		if (copy_from_user(&mifi, optval, sizeof(mifi_t)))  			return -EFAULT;  		rtnl_lock(); -		ret = mif6_delete(net, mifi); +		ret = mif6_delete(net, mifi, NULL);  		rtnl_unlock();  		return ret;  |