[IPV4]: fib_sync_down rework.

fib_sync_down can be called with an address and with a device. In
reality it is called either with address OR with a device. The
codepath inside is completely different, so lets separate it into two
calls for these two cases.

Signed-off-by: Denis V. Lunev <den@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Denis V. Lunev 2008-01-31 18:48:47 -08:00 committed by David S. Miller
parent 4b8aa9abee
commit 85326fa54b
3 changed files with 58 additions and 55 deletions

View File

@ -218,7 +218,8 @@ extern void fib_select_default(struct net *net, const struct flowi *flp,
/* Exported by fib_semantics.c */
extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
extern int fib_sync_down(__be32 local, struct net_device *dev, int force);
extern int fib_sync_down_dev(struct net_device *dev, int force);
extern int fib_sync_down_addr(__be32 local);
extern int fib_sync_up(struct net_device *dev);
extern __be32 __fib_res_prefsrc(struct fib_result *res);
extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);

View File

@ -808,7 +808,7 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
First of all, we scan fib_info list searching
for stray nexthop entries, then ignite fib_flush.
*/
if (fib_sync_down(ifa->ifa_local, NULL, 0))
if (fib_sync_down_addr(ifa->ifa_local))
fib_flush(dev->nd_net);
}
}
@ -898,7 +898,7 @@ static void nl_fib_lookup_exit(struct net *net)
static void fib_disable_ip(struct net_device *dev, int force)
{
if (fib_sync_down(0, dev, force))
if (fib_sync_down_dev(dev, force))
fib_flush(dev->nd_net);
rt_cache_flush(0);
arp_ifdown(dev);

View File

@ -1031,36 +1031,39 @@ nla_put_failure:
referring to it.
- device went down -> we must shutdown all nexthops going via it.
*/
int fib_sync_down(__be32 local, struct net_device *dev, int force)
int fib_sync_down_addr(__be32 local)
{
int ret = 0;
int scope = RT_SCOPE_NOWHERE;
if (force)
scope = -1;
if (local && fib_info_laddrhash) {
unsigned int hash = fib_laddr_hashfn(local);
struct hlist_head *head = &fib_info_laddrhash[hash];
struct hlist_node *node;
struct fib_info *fi;
if (fib_info_laddrhash == NULL || local == 0)
return 0;
hlist_for_each_entry(fi, node, head, fib_lhash) {
if (fi->fib_prefsrc == local) {
fi->fib_flags |= RTNH_F_DEAD;
ret++;
}
}
}
return ret;
}
if (dev) {
int fib_sync_down_dev(struct net_device *dev, int force)
{
int ret = 0;
int scope = RT_SCOPE_NOWHERE;
struct fib_info *prev_fi = NULL;
unsigned int hash = fib_devindex_hashfn(dev->ifindex);
struct hlist_head *head = &fib_info_devhash[hash];
struct hlist_node *node;
struct fib_nh *nh;
if (force)
scope = -1;
hlist_for_each_entry(nh, node, head, nh_hash) {
struct fib_info *fi = nh->nh_parent;
int dead;
@ -1096,7 +1099,6 @@ int fib_sync_down(__be32 local, struct net_device *dev, int force)
ret++;
}
}
}
return ret;
}