aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorNicolas Dichtel <nicolas.dichtel@6wind.com>2012-09-10 18:09:46 -0400
committerDavid S. Miller <davem@davemloft.net>2012-09-18 15:57:03 -0400
commit6f3118b571b8a4c06c7985dc3172c3526cb86253 (patch)
tree4b42d48f7346850618756ee4c26a179c5f7c7c3b /net/ipv6/route.c
parentee8372dd1989287c5eedb69d44bac43f69e496f1 (diff)
ipv6: use net->rt_genid to check dst validity
IPv6 dst should take care of rt_genid too. When a xfrm policy is inserted or deleted, all dst should be invalidated. To force the validation, dst entries should be created with ->obsolete set to DST_OBSOLETE_FORCE_CHK. This was already the case for all functions calling ip6_dst_alloc(), except for ip6_rt_copy(). As a consequence, we can remove the specific code in inet6_connection_sock. Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8e80fd279100..fb29e2215a19 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -281,13 +281,14 @@ static inline struct rt6_info *ip6_dst_alloc(struct net *net,
281 struct fib6_table *table) 281 struct fib6_table *table)
282{ 282{
283 struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev, 283 struct rt6_info *rt = dst_alloc(&net->ipv6.ip6_dst_ops, dev,
284 0, DST_OBSOLETE_NONE, flags); 284 0, DST_OBSOLETE_FORCE_CHK, flags);
285 285
286 if (rt) { 286 if (rt) {
287 struct dst_entry *dst = &rt->dst; 287 struct dst_entry *dst = &rt->dst;
288 288
289 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst)); 289 memset(dst + 1, 0, sizeof(*rt) - sizeof(*dst));
290 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers); 290 rt6_init_peer(rt, table ? &table->tb6_peers : net->ipv6.peers);
291 rt->rt6i_genid = rt_genid(net);
291 } 292 }
292 return rt; 293 return rt;
293} 294}
@@ -1031,6 +1032,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
1031 1032
1032 rt = (struct rt6_info *) dst; 1033 rt = (struct rt6_info *) dst;
1033 1034
1035 /* All IPV6 dsts are created with ->obsolete set to the value
1036 * DST_OBSOLETE_FORCE_CHK which forces validation calls down
1037 * into this function always.
1038 */
1039 if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
1040 return NULL;
1041
1034 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { 1042 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
1035 if (rt->rt6i_peer_genid != rt6_peer_genid()) { 1043 if (rt->rt6i_peer_genid != rt6_peer_genid()) {
1036 if (!rt6_has_peer(rt)) 1044 if (!rt6_has_peer(rt))
@@ -1397,8 +1405,6 @@ int ip6_route_add(struct fib6_config *cfg)
1397 goto out; 1405 goto out;
1398 } 1406 }
1399 1407
1400 rt->dst.obsolete = -1;
1401
1402 if (cfg->fc_flags & RTF_EXPIRES) 1408 if (cfg->fc_flags & RTF_EXPIRES)
1403 rt6_set_expires(rt, jiffies + 1409 rt6_set_expires(rt, jiffies +
1404 clock_t_to_jiffies(cfg->fc_expires)); 1410 clock_t_to_jiffies(cfg->fc_expires));
@@ -2080,7 +2086,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2080 rt->dst.input = ip6_input; 2086 rt->dst.input = ip6_input;
2081 rt->dst.output = ip6_output; 2087 rt->dst.output = ip6_output;
2082 rt->rt6i_idev = idev; 2088 rt->rt6i_idev = idev;
2083 rt->dst.obsolete = -1;
2084 2089
2085 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; 2090 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
2086 if (anycast) 2091 if (anycast)