Message ID | 20191220123542.26315-3-jiri@resnulli.us |
---|---|
State | Changes Requested |
Delegated to: | David Miller |
Headers | show |
Series | [net-next,1/4] net: call call_netdevice_unregister_net_notifiers from unregister | expand |
On 12/20/19 5:35 AM, Jiri Pirko wrote: > @@ -1784,6 +1784,42 @@ int unregister_netdevice_notifier(struct notifier_block *nb) > } > EXPORT_SYMBOL(unregister_netdevice_notifier); > > +static int __register_netdevice_notifier_net(struct net *net, > + struct notifier_block *nb, > + bool ignore_call_fail) > +{ > + int err; > + > + err = raw_notifier_chain_register(&net->netdev_chain, nb); > + if (err) > + return err; > + if (dev_boot_phase) > + return 0; > + > + err = call_netdevice_register_net_notifiers(nb, net); > + if (err && !ignore_call_fail) > + goto chain_unregister; > + > + return 0; > + > +chain_unregister: > + raw_notifier_chain_unregister(&netdev_chain, nb); why is the error path using the global netdev_chain when the register is relative to a namespace? yes, I realize existing code does that and this is maintaining that behavior.
Fri, Dec 20, 2019 at 07:07:59PM CET, dsahern@gmail.com wrote: >On 12/20/19 5:35 AM, Jiri Pirko wrote: >> @@ -1784,6 +1784,42 @@ int unregister_netdevice_notifier(struct notifier_block *nb) >> } >> EXPORT_SYMBOL(unregister_netdevice_notifier); >> >> +static int __register_netdevice_notifier_net(struct net *net, >> + struct notifier_block *nb, >> + bool ignore_call_fail) >> +{ >> + int err; >> + >> + err = raw_notifier_chain_register(&net->netdev_chain, nb); >> + if (err) >> + return err; >> + if (dev_boot_phase) >> + return 0; >> + >> + err = call_netdevice_register_net_notifiers(nb, net); >> + if (err && !ignore_call_fail) >> + goto chain_unregister; >> + >> + return 0; >> + >> +chain_unregister: >> + raw_notifier_chain_unregister(&netdev_chain, nb); > >why is the error path using the global netdev_chain when the register is >relative to a namespace? yes, I realize existing code does that and this A bug. Will fix. Thanks! >is maintaining that behavior. >
diff --git a/net/core/dev.c b/net/core/dev.c index 2c90722195f8..932ee131c8c9 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1784,6 +1784,42 @@ int unregister_netdevice_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_netdevice_notifier); +static int __register_netdevice_notifier_net(struct net *net, + struct notifier_block *nb, + bool ignore_call_fail) +{ + int err; + + err = raw_notifier_chain_register(&net->netdev_chain, nb); + if (err) + return err; + if (dev_boot_phase) + return 0; + + err = call_netdevice_register_net_notifiers(nb, net); + if (err && !ignore_call_fail) + goto chain_unregister; + + return 0; + +chain_unregister: + raw_notifier_chain_unregister(&netdev_chain, nb); + return err; +} + +static int __unregister_netdevice_notifier_net(struct net *net, + struct notifier_block *nb) +{ + int err; + + err = raw_notifier_chain_unregister(&net->netdev_chain, nb); + if (err) + return err; + + call_netdevice_unregister_net_notifiers(nb, net); + return 0; +} + /** * register_netdevice_notifier_net - register a per-netns network notifier block * @net: network namespace @@ -1804,23 +1840,9 @@ int register_netdevice_notifier_net(struct net *net, struct notifier_block *nb) int err; rtnl_lock(); - err = raw_notifier_chain_register(&net->netdev_chain, nb); - if (err) - goto unlock; - if (dev_boot_phase) - goto unlock; - - err = call_netdevice_register_net_notifiers(nb, net); - if (err) - goto chain_unregister; - -unlock: + err = __register_netdevice_notifier_net(net, nb, false); rtnl_unlock(); return err; - -chain_unregister: - raw_notifier_chain_unregister(&netdev_chain, nb); - goto unlock; } EXPORT_SYMBOL(register_netdevice_notifier_net); @@ -1846,13 +1868,7 @@ int unregister_netdevice_notifier_net(struct net *net, int err; rtnl_lock(); - err = raw_notifier_chain_unregister(&net->netdev_chain, nb); - if (err) - goto unlock; - - call_netdevice_unregister_net_notifiers(nb, net); - -unlock: + err = __unregister_netdevice_notifier_net(net, nb); rtnl_unlock(); return err; }