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 0607ee3a0eac..d1ddbc6ddac5 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -226,7 +226,7 @@ static const 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 const 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 const 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}
@@ -1022,6 +1023,13 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
1022 1023
1023 rt = (struct rt6_info *) dst; 1024 rt = (struct rt6_info *) dst;
1024 1025
1026 /* All IPV6 dsts are created with ->obsolete set to the value
1027 * DST_OBSOLETE_FORCE_CHK which forces validation calls down
1028 * into this function always.
1029 */
1030 if (rt->rt6i_genid != rt_genid(dev_net(rt->dst.dev)))
1031 return NULL;
1032
1025 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) { 1033 if (rt->rt6i_node && (rt->rt6i_node->fn_sernum == cookie)) {
1026 if (rt->rt6i_peer_genid != rt6_peer_genid()) { 1034 if (rt->rt6i_peer_genid != rt6_peer_genid()) {
1027 if (!rt6_has_peer(rt)) 1035 if (!rt6_has_peer(rt))
@@ -1388,8 +1396,6 @@ int ip6_route_add(struct fib6_config *cfg)
1388 goto out; 1396 goto out;
1389 } 1397 }
1390 1398
1391 rt->dst.obsolete = -1;
1392
1393 if (cfg->fc_flags & RTF_EXPIRES) 1399 if (cfg->fc_flags & RTF_EXPIRES)
1394 rt6_set_expires(rt, jiffies + 1400 rt6_set_expires(rt, jiffies +
1395 clock_t_to_jiffies(cfg->fc_expires)); 1401 clock_t_to_jiffies(cfg->fc_expires));
@@ -2084,7 +2090,6 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
2084 rt->dst.input = ip6_input; 2090 rt->dst.input = ip6_input;
2085 rt->dst.output = ip6_output; 2091 rt->dst.output = ip6_output;
2086 rt->rt6i_idev = idev; 2092 rt->rt6i_idev = idev;
2087 rt->dst.obsolete = -1;
2088 2093
2089 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP; 2094 rt->rt6i_flags = RTF_UP | RTF_NONEXTHOP;
2090 if (anycast) 2095 if (anycast)