aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/rtnetlink.h1
-rw-r--r--net/core/rtnetlink.c29
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
75extern int __rtnl_link_register(struct rtnl_link_ops *ops); 75extern int __rtnl_link_register(struct rtnl_link_ops *ops);
76extern void __rtnl_link_unregister(struct rtnl_link_ops *ops); 76extern void __rtnl_link_unregister(struct rtnl_link_ops *ops);
77extern void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops);
77 78
78extern int rtnl_link_register(struct rtnl_link_ops *ops); 79extern int rtnl_link_register(struct rtnl_link_ops *ops);
79extern void rtnl_link_unregister(struct rtnl_link_ops *ops); 80extern 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
270EXPORT_SYMBOL_GPL(rtnl_link_register); 270EXPORT_SYMBOL_GPL(rtnl_link_register);
271 271
272static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
273{
274 struct net_device *dev;
275restart:
276 for_each_netdev(net, dev) {
277 if (dev->rtnl_link_ops == ops) {
278 ops->dellink(dev);
279 goto restart;
280 }
281 }
282}
283
284void 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}
290EXPORT_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 */
278void __rtnl_link_unregister(struct rtnl_link_ops *ops) 298void __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) {
284restart: 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}