forked from Minki/linux
[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:
parent
4b8aa9abee
commit
85326fa54b
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user