diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-24 20:42:21 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-24 20:42:21 -0400 |
commit | 436c3b66ec9824a633724ae42de1c416af4f2063 (patch) | |
tree | 8da6452386b6e900c4226c9b67694d1ea21e847e /include/net/ip_fib.h | |
parent | f7594d42944c0dfca90318f50978a4bdf8504086 (diff) |
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 <ja@ssi.bg>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/ip_fib.h')
-rw-r--r-- | include/net/ip_fib.h | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index a1a858035913..cd92b923a578 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h | |||
@@ -62,6 +62,7 @@ struct fib_nh { | |||
62 | int nh_oif; | 62 | int nh_oif; |
63 | __be32 nh_gw; | 63 | __be32 nh_gw; |
64 | __be32 nh_saddr; | 64 | __be32 nh_saddr; |
65 | int nh_saddr_genid; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* | 68 | /* |
@@ -141,12 +142,19 @@ struct fib_result_nl { | |||
141 | 142 | ||
142 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ | 143 | #endif /* CONFIG_IP_ROUTE_MULTIPATH */ |
143 | 144 | ||
144 | #define FIB_RES_SADDR(res) (FIB_RES_NH(res).nh_saddr) | 145 | extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh); |
146 | |||
147 | #define FIB_RES_SADDR(net, res) \ | ||
148 | ((FIB_RES_NH(res).nh_saddr_genid == \ | ||
149 | atomic_read(&(net)->ipv4.dev_addr_genid)) ? \ | ||
150 | FIB_RES_NH(res).nh_saddr : \ | ||
151 | fib_info_update_nh_saddr((net), &FIB_RES_NH(res))) | ||
145 | #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) | 152 | #define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) |
146 | #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) | 153 | #define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) |
147 | #define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) | 154 | #define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) |
148 | 155 | ||
149 | #define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : FIB_RES_SADDR(res)) | 156 | #define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \ |
157 | FIB_RES_SADDR(net, res)) | ||
150 | 158 | ||
151 | struct fib_table { | 159 | struct fib_table { |
152 | struct hlist_node tb_hlist; | 160 | struct hlist_node tb_hlist; |