diff options
-rw-r--r-- | include/net/rtnetlink.h | 1 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 29 |
2 files changed, 22 insertions, 8 deletions
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 793863e09c69..3c1895e54b7f 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h | |||
@@ -74,6 +74,7 @@ struct rtnl_link_ops { | |||
74 | 74 | ||
75 | extern int __rtnl_link_register(struct rtnl_link_ops *ops); | 75 | extern int __rtnl_link_register(struct rtnl_link_ops *ops); |
76 | extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); | 76 | extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); |
77 | extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops); | ||
77 | 78 | ||
78 | extern int rtnl_link_register(struct rtnl_link_ops *ops); | 79 | extern int rtnl_link_register(struct rtnl_link_ops *ops); |
79 | extern void rtnl_link_unregister(struct rtnl_link_ops *ops); | 80 | extern void rtnl_link_unregister(struct rtnl_link_ops *ops); |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index edc6dbfe48f2..bc39e417694a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -269,6 +269,26 @@ int rtnl_link_register(struct rtnl_link_ops *ops) | |||
269 | 269 | ||
270 | EXPORT_SYMBOL_GPL(rtnl_link_register); | 270 | EXPORT_SYMBOL_GPL(rtnl_link_register); |
271 | 271 | ||
272 | static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) | ||
273 | { | ||
274 | struct net_device *dev; | ||
275 | restart: | ||
276 | for_each_netdev(net, dev) { | ||
277 | if (dev->rtnl_link_ops == ops) { | ||
278 | ops->dellink(dev); | ||
279 | goto restart; | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops) | ||
285 | { | ||
286 | rtnl_lock(); | ||
287 | __rtnl_kill_links(net, ops); | ||
288 | rtnl_unlock(); | ||
289 | } | ||
290 | EXPORT_SYMBOL_GPL(rtnl_kill_links); | ||
291 | |||
272 | /** | 292 | /** |
273 | * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. | 293 | * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink. |
274 | * @ops: struct rtnl_link_ops * to unregister | 294 | * @ops: struct rtnl_link_ops * to unregister |
@@ -277,17 +297,10 @@ EXPORT_SYMBOL_GPL(rtnl_link_register); | |||
277 | */ | 297 | */ |
278 | void __rtnl_link_unregister(struct rtnl_link_ops *ops) | 298 | void __rtnl_link_unregister(struct rtnl_link_ops *ops) |
279 | { | 299 | { |
280 | struct net_device *dev; | ||
281 | struct net *net; | 300 | struct net *net; |
282 | 301 | ||
283 | for_each_net(net) { | 302 | for_each_net(net) { |
284 | restart: | 303 | __rtnl_kill_links(net, ops); |
285 | for_each_netdev(net, dev) { | ||
286 | if (dev->rtnl_link_ops == ops) { | ||
287 | ops->dellink(dev); | ||
288 | goto restart; | ||
289 | } | ||
290 | } | ||
291 | } | 304 | } |
292 | list_del(&ops->list); | 305 | list_del(&ops->list); |
293 | } | 306 | } |