aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6mr.c')
-rw-r--r--net/ipv6/ip6mr.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index d9843e5a667f..8361d73ab653 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -774,7 +774,8 @@ failure:
774 * Delete a VIF entry 774 * Delete a VIF entry
775 */ 775 */
776 776
777static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head) 777static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
778 struct list_head *head)
778{ 779{
779 struct mif_device *v; 780 struct mif_device *v;
780 struct net_device *dev; 781 struct net_device *dev;
@@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
820 dev->ifindex, &in6_dev->cnf); 821 dev->ifindex, &in6_dev->cnf);
821 } 822 }
822 823
823 if (v->flags & MIFF_REGISTER) 824 if ((v->flags & MIFF_REGISTER) && !notify)
824 unregister_netdevice_queue(dev, head); 825 unregister_netdevice_queue(dev, head);
825 826
826 dev_put(dev); 827 dev_put(dev);
@@ -1330,7 +1331,6 @@ static int ip6mr_device_event(struct notifier_block *this,
1330 struct mr6_table *mrt; 1331 struct mr6_table *mrt;
1331 struct mif_device *v; 1332 struct mif_device *v;
1332 int ct; 1333 int ct;
1333 LIST_HEAD(list);
1334 1334
1335 if (event != NETDEV_UNREGISTER) 1335 if (event != NETDEV_UNREGISTER)
1336 return NOTIFY_DONE; 1336 return NOTIFY_DONE;
@@ -1339,10 +1339,9 @@ static int ip6mr_device_event(struct notifier_block *this,
1339 v = &mrt->vif6_table[0]; 1339 v = &mrt->vif6_table[0];
1340 for (ct = 0; ct < mrt->maxvif; ct++, v++) { 1340 for (ct = 0; ct < mrt->maxvif; ct++, v++) {
1341 if (v->dev == dev) 1341 if (v->dev == dev)
1342 mif6_delete(mrt, ct, &list); 1342 mif6_delete(mrt, ct, 1, NULL);
1343 } 1343 }
1344 } 1344 }
1345 unregister_netdevice_many(&list);
1346 1345
1347 return NOTIFY_DONE; 1346 return NOTIFY_DONE;
1348} 1347}
@@ -1551,7 +1550,7 @@ static void mroute_clean_tables(struct mr6_table *mrt, bool all)
1551 for (i = 0; i < mrt->maxvif; i++) { 1550 for (i = 0; i < mrt->maxvif; i++) {
1552 if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC)) 1551 if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
1553 continue; 1552 continue;
1554 mif6_delete(mrt, i, &list); 1553 mif6_delete(mrt, i, 0, &list);
1555 } 1554 }
1556 unregister_netdevice_many(&list); 1555 unregister_netdevice_many(&list);
1557 1556
@@ -1704,7 +1703,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, uns
1704 if (copy_from_user(&mifi, optval, sizeof(mifi_t))) 1703 if (copy_from_user(&mifi, optval, sizeof(mifi_t)))
1705 return -EFAULT; 1704 return -EFAULT;
1706 rtnl_lock(); 1705 rtnl_lock();
1707 ret = mif6_delete(mrt, mifi, NULL); 1706 ret = mif6_delete(mrt, mifi, 0, NULL);
1708 rtnl_unlock(); 1707 rtnl_unlock();
1709 return ret; 1708 return ret;
1710 1709