|
@@ -774,7 +774,8 @@ failure:
|
|
|
* Delete a VIF entry
|
|
|
*/
|
|
|
|
|
|
-static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
|
|
|
+static int mif6_delete(struct mr6_table *mrt, int vifi, int notify,
|
|
|
+ struct list_head *head)
|
|
|
{
|
|
|
struct mif_device *v;
|
|
|
struct net_device *dev;
|
|
@@ -820,7 +821,7 @@ static int mif6_delete(struct mr6_table *mrt, int vifi, struct list_head *head)
|
|
|
dev->ifindex, &in6_dev->cnf);
|
|
|
}
|
|
|
|
|
|
- if (v->flags & MIFF_REGISTER)
|
|
|
+ if ((v->flags & MIFF_REGISTER) && !notify)
|
|
|
unregister_netdevice_queue(dev, head);
|
|
|
|
|
|
dev_put(dev);
|
|
@@ -1331,7 +1332,6 @@ static int ip6mr_device_event(struct notifier_block *this,
|
|
|
struct mr6_table *mrt;
|
|
|
struct mif_device *v;
|
|
|
int ct;
|
|
|
- LIST_HEAD(list);
|
|
|
|
|
|
if (event != NETDEV_UNREGISTER)
|
|
|
return NOTIFY_DONE;
|
|
@@ -1340,10 +1340,9 @@ static int ip6mr_device_event(struct notifier_block *this,
|
|
|
v = &mrt->vif6_table[0];
|
|
|
for (ct = 0; ct < mrt->maxvif; ct++, v++) {
|
|
|
if (v->dev == dev)
|
|
|
- mif6_delete(mrt, ct, &list);
|
|
|
+ mif6_delete(mrt, ct, 1, NULL);
|
|
|
}
|
|
|
}
|
|
|
- unregister_netdevice_many(&list);
|
|
|
|
|
|
return NOTIFY_DONE;
|
|
|
}
|
|
@@ -1552,7 +1551,7 @@ static void mroute_clean_tables(struct mr6_table *mrt, bool all)
|
|
|
for (i = 0; i < mrt->maxvif; i++) {
|
|
|
if (!all && (mrt->vif6_table[i].flags & VIFF_STATIC))
|
|
|
continue;
|
|
|
- mif6_delete(mrt, i, &list);
|
|
|
+ mif6_delete(mrt, i, 0, &list);
|
|
|
}
|
|
|
unregister_netdevice_many(&list);
|
|
|
|
|
@@ -1707,7 +1706,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(mrt, mifi, NULL);
|
|
|
+ ret = mif6_delete(mrt, mifi, 0, NULL);
|
|
|
rtnl_unlock();
|
|
|
return ret;
|
|
|
|