Commit afa0df59 authored by Jiri Pirko's avatar Jiri Pirko Committed by David S. Miller

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: default avatarJiri Pirko <jiri@mellanox.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c01ebd6c
...@@ -2574,6 +2574,9 @@ extern rwlock_t dev_base_lock; /* Device list lock */ ...@@ -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) list_for_each_entry_safe(d, n, &(net)->dev_base_head, dev_list)
#define for_each_netdev_continue(net, d) \ #define for_each_netdev_continue(net, d) \
list_for_each_entry_continue(d, &(net)->dev_base_head, dev_list) 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) \ #define for_each_netdev_continue_rcu(net, d) \
list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list) list_for_each_entry_continue_rcu(d, &(net)->dev_base_head, dev_list)
#define for_each_netdev_in_bond_rcu(bond, slave) \ #define for_each_netdev_in_bond_rcu(bond, slave) \
......
...@@ -317,7 +317,8 @@ static inline struct net *read_pnet(const possible_net_t *pnet) ...@@ -317,7 +317,8 @@ static inline struct net *read_pnet(const possible_net_t *pnet)
/* Protected by net_rwsem */ /* Protected by net_rwsem */
#define for_each_net(VAR) \ #define for_each_net(VAR) \
list_for_each_entry(VAR, &net_namespace_list, list) 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) \ #define for_each_net_rcu(VAR) \
list_for_each_entry_rcu(VAR, &net_namespace_list, list) 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, ...@@ -1725,6 +1725,62 @@ static int call_netdevice_notifier(struct notifier_block *nb, unsigned long val,
return nb->notifier_call(nb, val, &info); 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; static int dev_boot_phase = 1;
/** /**
...@@ -1743,8 +1799,6 @@ static int dev_boot_phase = 1; ...@@ -1743,8 +1799,6 @@ static int dev_boot_phase = 1;
int register_netdevice_notifier(struct notifier_block *nb) int register_netdevice_notifier(struct notifier_block *nb)
{ {
struct net_device *dev;
struct net_device *last;
struct net *net; struct net *net;
int err; int err;
...@@ -1757,17 +1811,9 @@ int register_netdevice_notifier(struct notifier_block *nb) ...@@ -1757,17 +1811,9 @@ int register_netdevice_notifier(struct notifier_block *nb)
if (dev_boot_phase) if (dev_boot_phase)
goto unlock; goto unlock;
for_each_net(net) { for_each_net(net) {
for_each_netdev(net, dev) { err = call_netdevice_register_net_notifiers(nb, net);
err = call_netdevice_notifier(nb, NETDEV_REGISTER, dev); if (err)
err = notifier_to_errno(err); goto rollback;
if (err)
goto rollback;
if (!(dev->flags & IFF_UP))
continue;
call_netdevice_notifier(nb, NETDEV_UP, dev);
}
} }
unlock: unlock:
...@@ -1776,22 +1822,9 @@ int register_netdevice_notifier(struct notifier_block *nb) ...@@ -1776,22 +1822,9 @@ int register_netdevice_notifier(struct notifier_block *nb)
return err; return err;
rollback: rollback:
last = dev; for_each_net_continue_reverse(net)
for_each_net(net) { call_netdevice_unregister_net_notifiers(nb, net);
for_each_netdev(net, dev) {
if (dev == last)
goto outroll;
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); raw_notifier_chain_unregister(&netdev_chain, nb);
goto unlock; goto unlock;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment