ipv4: Invalidate nexthop cache nh_saddr more correctly.

Any operation that:

1) Brings up an interface
2) Adds an IP address to an interface
3) Deletes an IP address from an interface

can potentially invalidate the nh_saddr value, requiring
it to be recomputed.

Perform the recomputation lazily using a generation ID.

Reported-by: Julian Anastasov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
David S. Miller 2011-03-24 17:42:21 -07:00
commit 436c3b66ec
5 changed files with 33 additions and 29 deletions

View file

@ -62,6 +62,7 @@ struct fib_nh {
int nh_oif;
__be32 nh_gw;
__be32 nh_saddr;
int nh_saddr_genid;
};
/*
@ -141,12 +142,19 @@ struct fib_result_nl {
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
#define FIB_RES_SADDR(res) (FIB_RES_NH(res).nh_saddr)
extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
#define FIB_RES_SADDR(net, res) \
((FIB_RES_NH(res).nh_saddr_genid == \
atomic_read(&(net)->ipv4.dev_addr_genid)) ? \
FIB_RES_NH(res).nh_saddr : \
fib_info_update_nh_saddr((net), &FIB_RES_NH(res)))
#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : FIB_RES_SADDR(res))
#define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \
FIB_RES_SADDR(net, res))
struct fib_table {
struct hlist_node tb_hlist;

View file

@ -55,6 +55,7 @@ struct netns_ipv4 {
int current_rt_cache_rebuild_count;
atomic_t rt_genid;
atomic_t dev_addr_genid;
#ifdef CONFIG_IP_MROUTE
#ifndef CONFIG_IP_MROUTE_MULTIPLE_TABLES