aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 8e80fd279100..854e4018d205 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -226,7 +226,7 @@ static struct rt6_info ip6_null_entry_template = {
226 .dst = { 226 .dst = {
227 .__refcnt = ATOMIC_INIT(1), 227 .__refcnt = ATOMIC_INIT(1),
228 .__use = 1, 228 .__use = 1,
229 .obsolete = -1, 229 .obsolete = DST_OBSOLETE_FORCE_CHK,
230 .error = -ENETUNREACH, 230 .error = -ENETUNREACH,
231 .input = ip6_pkt_discard, 231 .input = ip6_pkt_discard,
232 .output = ip6_pkt_discard_out, 232 .output = ip6_pkt_discard_out,
@@ -246,7 +246,7 @@ static struct rt6_info ip6_prohibit_entry_template = {
246 .dst = { 246 .dst = {
247 .__refcnt = ATOMIC_INIT(1), 247 .__refcnt = ATOMIC_INIT(1),
248 .__use = 1, 248 .__use = 1,
249 .obsolete = -1, 249 .obsolete = DST_OBSOLETE_FORCE_CHK,
250 .error = -EACCES, 250 .error = -EACCES,
251 .input = ip6_pkt_prohibit, 251 .input = ip6_pkt_prohibit,
252 .output = ip6_pkt_prohibit_out, 252 .output = ip6_pkt_prohibit_out,
@@ -261,7 +261,7 @@ static struct rt6_info ip6_blk_hole_entry_template = {
261 .dst = { 261 .dst = {
262 .__refcnt = ATOMIC_INIT(1), 262 .__refcnt = ATOMIC_INIT(1),
263 .__use = 1, 263 .__use = 1,
264 .obsolete = -1, 264 .obsolete = DST_OBSOLETE_FORCE_CHK,
265 .error = -EINVAL, 265 .error = -EINVAL,
266 .input = dst_discard, 266 .input = dst_discard,
267 .output = dst_discard, 267 .output = dst_discard,
@@ -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)