aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/veth.c14
-rw-r--r--net/core/rtnetlink.c5
2 files changed, 5 insertions, 14 deletions
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 43af9e9b265..3f67a29593b 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -459,19 +459,7 @@ static __init int veth_init(void)
static __exit void veth_exit(void)
{
- struct veth_priv *priv, *next;
-
- rtnl_lock();
- /*
- * cannot trust __rtnl_link_unregister() to unregister all
- * devices, as each ->dellink call will remove two devices
- * from the list at once.
- */
- list_for_each_entry_safe(priv, next, &veth_list, list)
- veth_dellink(priv->dev);
-
- __rtnl_link_unregister(&veth_link_ops);
- rtnl_unlock();
+ rtnl_link_unregister(&veth_link_ops);
}
module_init(veth_init);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e1ba26fb4bf..fed95a323b2 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -308,9 +308,12 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops)
struct net *net;
for_each_net(net) {
+restart:
for_each_netdev_safe(net, dev, n) {
- if (dev->rtnl_link_ops == ops)
+ if (dev->rtnl_link_ops == ops) {
ops->dellink(dev);
+ goto restart;
+ }
}
}
list_del(&ops->list);