aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d9b40248b97f..54fd68c14c87 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -932,10 +932,8 @@ static void rt_secret_rebuild_oneshot(struct net *net)
932{ 932{
933 del_timer_sync(&net->ipv4.rt_secret_timer); 933 del_timer_sync(&net->ipv4.rt_secret_timer);
934 rt_cache_invalidate(net); 934 rt_cache_invalidate(net);
935 if (ip_rt_secret_interval) { 935 if (ip_rt_secret_interval)
936 net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; 936 mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
937 add_timer(&net->ipv4.rt_secret_timer);
938 }
939} 937}
940 938
941static void rt_emergency_hash_rebuild(struct net *net) 939static void rt_emergency_hash_rebuild(struct net *net)
@@ -1443,7 +1441,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1443 dev_hold(rt->u.dst.dev); 1441 dev_hold(rt->u.dst.dev);
1444 if (rt->idev) 1442 if (rt->idev)
1445 in_dev_hold(rt->idev); 1443 in_dev_hold(rt->idev);
1446 rt->u.dst.obsolete = 0; 1444 rt->u.dst.obsolete = -1;
1447 rt->u.dst.lastuse = jiffies; 1445 rt->u.dst.lastuse = jiffies;
1448 rt->u.dst.path = &rt->u.dst; 1446 rt->u.dst.path = &rt->u.dst;
1449 rt->u.dst.neighbour = NULL; 1447 rt->u.dst.neighbour = NULL;
@@ -1508,11 +1506,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1508 struct dst_entry *ret = dst; 1506 struct dst_entry *ret = dst;
1509 1507
1510 if (rt) { 1508 if (rt) {
1511 if (dst->obsolete) { 1509 if (dst->obsolete > 0) {
1512 ip_rt_put(rt); 1510 ip_rt_put(rt);
1513 ret = NULL; 1511 ret = NULL;
1514 } else if ((rt->rt_flags & RTCF_REDIRECTED) || 1512 } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
1515 rt->u.dst.expires) { 1513 (rt->u.dst.expires &&
1514 time_after_eq(jiffies, rt->u.dst.expires))) {
1516 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, 1515 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
1517 rt->fl.oif, 1516 rt->fl.oif,
1518 rt_genid(dev_net(dst->dev))); 1517 rt_genid(dev_net(dst->dev)));
@@ -1728,7 +1727,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
1728 1727
1729static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) 1728static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
1730{ 1729{
1731 return NULL; 1730 if (rt_is_expired((struct rtable *)dst))
1731 return NULL;
1732 return dst;
1732} 1733}
1733 1734
1734static void ipv4_dst_destroy(struct dst_entry *dst) 1735static void ipv4_dst_destroy(struct dst_entry *dst)
@@ -1890,7 +1891,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1890 if (!rth) 1891 if (!rth)
1891 goto e_nobufs; 1892 goto e_nobufs;
1892 1893
1893 rth->u.dst.output= ip_rt_bug; 1894 rth->u.dst.output = ip_rt_bug;
1895 rth->u.dst.obsolete = -1;
1894 1896
1895 atomic_set(&rth->u.dst.__refcnt, 1); 1897 atomic_set(&rth->u.dst.__refcnt, 1);
1896 rth->u.dst.flags= DST_HOST; 1898 rth->u.dst.flags= DST_HOST;
@@ -2056,6 +2058,7 @@ static int __mkroute_input(struct sk_buff *skb,
2056 rth->fl.oif = 0; 2058 rth->fl.oif = 0;
2057 rth->rt_spec_dst= spec_dst; 2059 rth->rt_spec_dst= spec_dst;
2058 2060
2061 rth->u.dst.obsolete = -1;
2059 rth->u.dst.input = ip_forward; 2062 rth->u.dst.input = ip_forward;
2060 rth->u.dst.output = ip_output; 2063 rth->u.dst.output = ip_output;
2061 rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); 2064 rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
@@ -2220,6 +2223,7 @@ local_input:
2220 goto e_nobufs; 2223 goto e_nobufs;
2221 2224
2222 rth->u.dst.output= ip_rt_bug; 2225 rth->u.dst.output= ip_rt_bug;
2226 rth->u.dst.obsolete = -1;
2223 rth->rt_genid = rt_genid(net); 2227 rth->rt_genid = rt_genid(net);
2224 2228
2225 atomic_set(&rth->u.dst.__refcnt, 1); 2229 atomic_set(&rth->u.dst.__refcnt, 1);
@@ -2446,6 +2450,7 @@ static int __mkroute_output(struct rtable **result,
2446 rth->rt_spec_dst= fl->fl4_src; 2450 rth->rt_spec_dst= fl->fl4_src;
2447 2451
2448 rth->u.dst.output=ip_output; 2452 rth->u.dst.output=ip_output;
2453 rth->u.dst.obsolete = -1;
2449 rth->rt_genid = rt_genid(dev_net(dev_out)); 2454 rth->rt_genid = rt_genid(dev_net(dev_out));
2450 2455
2451 RT_CACHE_STAT_INC(out_slow_tot); 2456 RT_CACHE_STAT_INC(out_slow_tot);
@@ -3103,22 +3108,20 @@ static void rt_secret_reschedule(int old)
3103 rtnl_lock(); 3108 rtnl_lock();
3104 for_each_net(net) { 3109 for_each_net(net) {
3105 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); 3110 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
3111 long time;
3106 3112
3107 if (!new) 3113 if (!new)
3108 continue; 3114 continue;
3109 3115
3110 if (deleted) { 3116 if (deleted) {
3111 long time = net->ipv4.rt_secret_timer.expires - jiffies; 3117 time = net->ipv4.rt_secret_timer.expires - jiffies;
3112 3118
3113 if (time <= 0 || (time += diff) <= 0) 3119 if (time <= 0 || (time += diff) <= 0)
3114 time = 0; 3120 time = 0;
3115
3116 net->ipv4.rt_secret_timer.expires = time;
3117 } else 3121 } else
3118 net->ipv4.rt_secret_timer.expires = new; 3122 time = new;
3119 3123
3120 net->ipv4.rt_secret_timer.expires += jiffies; 3124 mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
3121 add_timer(&net->ipv4.rt_secret_timer);
3122 } 3125 }
3123 rtnl_unlock(); 3126 rtnl_unlock();
3124} 3127}