net: push loops and nb calls into helper functions
Push iterations over net namespaces and netdevices from register_netdevice_notifier() and unregister_netdevice_notifier() into helper functions. Along with that introduce continue_reverse macros to make the code a bit nicer allowing to get rid of "last" marks. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
c01ebd6c46
commit
afa0df5998
@@ -1725,6 +1725,62 @@ static int call_netdevice_notifier(struct notifier_block *nb, unsigned long val,
|
||||
return nb->notifier_call(nb, val, &info);
|
||||
}
|
||||
|
||||
static int call_netdevice_register_notifiers(struct notifier_block *nb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = call_netdevice_notifier(nb, NETDEV_REGISTER, dev);
|
||||
err = notifier_to_errno(err);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!(dev->flags & IFF_UP))
|
||||
return 0;
|
||||
|
||||
call_netdevice_notifier(nb, NETDEV_UP, dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void call_netdevice_unregister_notifiers(struct notifier_block *nb,
|
||||
struct net_device *dev)
|
||||
{
|
||||
if (dev->flags & IFF_UP) {
|
||||
call_netdevice_notifier(nb, NETDEV_GOING_DOWN,
|
||||
dev);
|
||||
call_netdevice_notifier(nb, NETDEV_DOWN, dev);
|
||||
}
|
||||
call_netdevice_notifier(nb, NETDEV_UNREGISTER, dev);
|
||||
}
|
||||
|
||||
static int call_netdevice_register_net_notifiers(struct notifier_block *nb,
|
||||
struct net *net)
|
||||
{
|
||||
struct net_device *dev;
|
||||
int err;
|
||||
|
||||
for_each_netdev(net, dev) {
|
||||
err = call_netdevice_register_notifiers(nb, dev);
|
||||
if (err)
|
||||
goto rollback;
|
||||
}
|
||||
return 0;
|
||||
|
||||
rollback:
|
||||
for_each_netdev_continue_reverse(net, dev)
|
||||
call_netdevice_unregister_notifiers(nb, dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void call_netdevice_unregister_net_notifiers(struct notifier_block *nb,
|
||||
struct net *net)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev(net, dev)
|
||||
call_netdevice_unregister_notifiers(nb, dev);
|
||||
}
|
||||
|
||||
static int dev_boot_phase = 1;
|
||||
|
||||
/**
|
||||
@@ -1743,8 +1799,6 @@ static int dev_boot_phase = 1;
|
||||
|
||||
int register_netdevice_notifier(struct notifier_block *nb)
|
||||
{
|
||||
struct net_device *dev;
|
||||
struct net_device *last;
|
||||
struct net *net;
|
||||
int err;
|
||||
|
||||
@@ -1757,17 +1811,9 @@ int register_netdevice_notifier(struct notifier_block *nb)
|
||||
if (dev_boot_phase)
|
||||
goto unlock;
|
||||
for_each_net(net) {
|
||||
for_each_netdev(net, dev) {
|
||||
err = call_netdevice_notifier(nb, NETDEV_REGISTER, dev);
|
||||
err = notifier_to_errno(err);
|
||||
if (err)
|
||||
goto rollback;
|
||||
|
||||
if (!(dev->flags & IFF_UP))
|
||||
continue;
|
||||
|
||||
call_netdevice_notifier(nb, NETDEV_UP, dev);
|
||||
}
|
||||
err = call_netdevice_register_net_notifiers(nb, net);
|
||||
if (err)
|
||||
goto rollback;
|
||||
}
|
||||
|
||||
unlock:
|
||||
@@ -1776,22 +1822,9 @@ unlock:
|
||||
return err;
|
||||
|
||||
rollback:
|
||||
last = dev;
|
||||
for_each_net(net) {
|
||||
for_each_netdev(net, dev) {
|
||||
if (dev == last)
|
||||
goto outroll;
|
||||
for_each_net_continue_reverse(net)
|
||||
call_netdevice_unregister_net_notifiers(nb, net);
|
||||
|
||||
if (dev->flags & IFF_UP) {
|
||||
call_netdevice_notifier(nb, NETDEV_GOING_DOWN,
|
||||
dev);
|
||||
call_netdevice_notifier(nb, NETDEV_DOWN, dev);
|
||||
}
|
||||
call_netdevice_notifier(nb, NETDEV_UNREGISTER, dev);
|
||||
}
|
||||
}
|
||||
|
||||
outroll:
|
||||
raw_notifier_chain_unregister(&netdev_chain, nb);
|
||||
goto unlock;
|
||||
}
|
||||
|
Reference in New Issue
Block a user