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:
parent
c01ebd6c46
commit
afa0df5998
@ -2574,6 +2574,9 @@ extern rwlock_t dev_base_lock; /* Device list lock */
|
||||
list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
|
||||
#define for_each_netdev_continue(net, d) \
|
||||
list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list)
|
||||
#define for_each_netdev_continue_reverse(net, d) \
|
||||
list_for_each_entry_continue_reverse(d, &(net)->dev_base_head, \
|
||||
dev_list)
|
||||
#define for_each_netdev_continue_rcu(net, d) \
|
||||
list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list)
|
||||
#define for_each_netdev_in_bond_rcu(bond, slave) \
|
||||
|
@ -317,7 +317,8 @@ static inline struct net *read_pnet(const possible_net_t *pnet)
|
||||
/* Protected by net_rwsem */
|
||||
#define for_each_net(VAR) \
|
||||
list_for_each_entry(VAR, &net_namespace_list, list)
|
||||
|
||||
#define for_each_net_continue_reverse(VAR) \
|
||||
list_for_each_entry_continue_reverse(VAR, &net_namespace_list, list)
|
||||
#define for_each_net_rcu(VAR) \
|
||||
list_for_each_entry_rcu(VAR, &net_namespace_list, list)
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user