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.c105
1 files changed, 70 insertions, 35 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index b2ba5581d2ae..cb562fdd9b9a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -90,6 +90,7 @@
90#include <linux/jhash.h> 90#include <linux/jhash.h>
91#include <linux/rcupdate.h> 91#include <linux/rcupdate.h>
92#include <linux/times.h> 92#include <linux/times.h>
93#include <linux/slab.h>
93#include <net/dst.h> 94#include <net/dst.h>
94#include <net/net_namespace.h> 95#include <net/net_namespace.h>
95#include <net/protocol.h> 96#include <net/protocol.h>
@@ -146,7 +147,6 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
146static void ipv4_link_failure(struct sk_buff *skb); 147static void ipv4_link_failure(struct sk_buff *skb);
147static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu); 148static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
148static int rt_garbage_collect(struct dst_ops *ops); 149static int rt_garbage_collect(struct dst_ops *ops);
149static void rt_emergency_hash_rebuild(struct net *net);
150 150
151 151
152static struct dst_ops ipv4_dst_ops = { 152static struct dst_ops ipv4_dst_ops = {
@@ -780,11 +780,30 @@ static void rt_do_flush(int process_context)
780#define FRACT_BITS 3 780#define FRACT_BITS 3
781#define ONE (1UL << FRACT_BITS) 781#define ONE (1UL << FRACT_BITS)
782 782
783/*
784 * Given a hash chain and an item in this hash chain,
785 * find if a previous entry has the same hash_inputs
786 * (but differs on tos, mark or oif)
787 * Returns 0 if an alias is found.
788 * Returns ONE if rth has no alias before itself.
789 */
790static int has_noalias(const struct rtable *head, const struct rtable *rth)
791{
792 const struct rtable *aux = head;
793
794 while (aux != rth) {
795 if (compare_hash_inputs(&aux->fl, &rth->fl))
796 return 0;
797 aux = aux->u.dst.rt_next;
798 }
799 return ONE;
800}
801
783static void rt_check_expire(void) 802static void rt_check_expire(void)
784{ 803{
785 static unsigned int rover; 804 static unsigned int rover;
786 unsigned int i = rover, goal; 805 unsigned int i = rover, goal;
787 struct rtable *rth, *aux, **rthp; 806 struct rtable *rth, **rthp;
788 unsigned long samples = 0; 807 unsigned long samples = 0;
789 unsigned long sum = 0, sum2 = 0; 808 unsigned long sum = 0, sum2 = 0;
790 unsigned long delta; 809 unsigned long delta;
@@ -835,15 +854,7 @@ nofree:
835 * attributes don't unfairly skew 854 * attributes don't unfairly skew
836 * the length computation 855 * the length computation
837 */ 856 */
838 for (aux = rt_hash_table[i].chain;;) { 857 length += has_noalias(rt_hash_table[i].chain, rth);
839 if (aux == rth) {
840 length += ONE;
841 break;
842 }
843 if (compare_hash_inputs(&aux->fl, &rth->fl))
844 break;
845 aux = aux->u.dst.rt_next;
846 }
847 continue; 858 continue;
848 } 859 }
849 } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout)) 860 } else if (!rt_may_expire(rth, tmo, ip_rt_gc_timeout))
@@ -922,10 +933,8 @@ static void rt_secret_rebuild_oneshot(struct net *net)
922{ 933{
923 del_timer_sync(&net->ipv4.rt_secret_timer); 934 del_timer_sync(&net->ipv4.rt_secret_timer);
924 rt_cache_invalidate(net); 935 rt_cache_invalidate(net);
925 if (ip_rt_secret_interval) { 936 if (ip_rt_secret_interval)
926 net->ipv4.rt_secret_timer.expires += ip_rt_secret_interval; 937 mod_timer(&net->ipv4.rt_secret_timer, jiffies + ip_rt_secret_interval);
927 add_timer(&net->ipv4.rt_secret_timer);
928 }
929} 938}
930 939
931static void rt_emergency_hash_rebuild(struct net *net) 940static void rt_emergency_hash_rebuild(struct net *net)
@@ -1073,8 +1082,23 @@ work_done:
1073out: return 0; 1082out: return 0;
1074} 1083}
1075 1084
1085/*
1086 * Returns number of entries in a hash chain that have different hash_inputs
1087 */
1088static int slow_chain_length(const struct rtable *head)
1089{
1090 int length = 0;
1091 const struct rtable *rth = head;
1092
1093 while (rth) {
1094 length += has_noalias(head, rth);
1095 rth = rth->u.dst.rt_next;
1096 }
1097 return length >> FRACT_BITS;
1098}
1099
1076static int rt_intern_hash(unsigned hash, struct rtable *rt, 1100static int rt_intern_hash(unsigned hash, struct rtable *rt,
1077 struct rtable **rp, struct sk_buff *skb) 1101 struct rtable **rp, struct sk_buff *skb, int ifindex)
1078{ 1102{
1079 struct rtable *rth, **rthp; 1103 struct rtable *rth, **rthp;
1080 unsigned long now; 1104 unsigned long now;
@@ -1185,14 +1209,20 @@ restart:
1185 rt_free(cand); 1209 rt_free(cand);
1186 } 1210 }
1187 } else { 1211 } else {
1188 if (chain_length > rt_chain_length_max) { 1212 if (chain_length > rt_chain_length_max &&
1213 slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
1189 struct net *net = dev_net(rt->u.dst.dev); 1214 struct net *net = dev_net(rt->u.dst.dev);
1190 int num = ++net->ipv4.current_rt_cache_rebuild_count; 1215 int num = ++net->ipv4.current_rt_cache_rebuild_count;
1191 if (!rt_caching(dev_net(rt->u.dst.dev))) { 1216 if (!rt_caching(net)) {
1192 printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n", 1217 printk(KERN_WARNING "%s: %d rebuilds is over limit, route caching disabled\n",
1193 rt->u.dst.dev->name, num); 1218 rt->u.dst.dev->name, num);
1194 } 1219 }
1195 rt_emergency_hash_rebuild(dev_net(rt->u.dst.dev)); 1220 rt_emergency_hash_rebuild(net);
1221 spin_unlock_bh(rt_hash_lock_addr(hash));
1222
1223 hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
1224 ifindex, rt_genid(net));
1225 goto restart;
1196 } 1226 }
1197 } 1227 }
1198 1228
@@ -1417,7 +1447,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1417 dev_hold(rt->u.dst.dev); 1447 dev_hold(rt->u.dst.dev);
1418 if (rt->idev) 1448 if (rt->idev)
1419 in_dev_hold(rt->idev); 1449 in_dev_hold(rt->idev);
1420 rt->u.dst.obsolete = 0; 1450 rt->u.dst.obsolete = -1;
1421 rt->u.dst.lastuse = jiffies; 1451 rt->u.dst.lastuse = jiffies;
1422 rt->u.dst.path = &rt->u.dst; 1452 rt->u.dst.path = &rt->u.dst;
1423 rt->u.dst.neighbour = NULL; 1453 rt->u.dst.neighbour = NULL;
@@ -1453,7 +1483,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1453 &netevent); 1483 &netevent);
1454 1484
1455 rt_del(hash, rth); 1485 rt_del(hash, rth);
1456 if (!rt_intern_hash(hash, rt, &rt, NULL)) 1486 if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif))
1457 ip_rt_put(rt); 1487 ip_rt_put(rt);
1458 goto do_next; 1488 goto do_next;
1459 } 1489 }
@@ -1482,11 +1512,12 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
1482 struct dst_entry *ret = dst; 1512 struct dst_entry *ret = dst;
1483 1513
1484 if (rt) { 1514 if (rt) {
1485 if (dst->obsolete) { 1515 if (dst->obsolete > 0) {
1486 ip_rt_put(rt); 1516 ip_rt_put(rt);
1487 ret = NULL; 1517 ret = NULL;
1488 } else if ((rt->rt_flags & RTCF_REDIRECTED) || 1518 } else if ((rt->rt_flags & RTCF_REDIRECTED) ||
1489 rt->u.dst.expires) { 1519 (rt->u.dst.expires &&
1520 time_after_eq(jiffies, rt->u.dst.expires))) {
1490 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src, 1521 unsigned hash = rt_hash(rt->fl.fl4_dst, rt->fl.fl4_src,
1491 rt->fl.oif, 1522 rt->fl.oif,
1492 rt_genid(dev_net(dst->dev))); 1523 rt_genid(dev_net(dst->dev)));
@@ -1702,7 +1733,9 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
1702 1733
1703static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) 1734static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
1704{ 1735{
1705 return NULL; 1736 if (rt_is_expired((struct rtable *)dst))
1737 return NULL;
1738 return dst;
1706} 1739}
1707 1740
1708static void ipv4_dst_destroy(struct dst_entry *dst) 1741static void ipv4_dst_destroy(struct dst_entry *dst)
@@ -1864,7 +1897,8 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1864 if (!rth) 1897 if (!rth)
1865 goto e_nobufs; 1898 goto e_nobufs;
1866 1899
1867 rth->u.dst.output= ip_rt_bug; 1900 rth->u.dst.output = ip_rt_bug;
1901 rth->u.dst.obsolete = -1;
1868 1902
1869 atomic_set(&rth->u.dst.__refcnt, 1); 1903 atomic_set(&rth->u.dst.__refcnt, 1);
1870 rth->u.dst.flags= DST_HOST; 1904 rth->u.dst.flags= DST_HOST;
@@ -1903,7 +1937,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1903 1937
1904 in_dev_put(in_dev); 1938 in_dev_put(in_dev);
1905 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); 1939 hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
1906 return rt_intern_hash(hash, rth, NULL, skb); 1940 return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);
1907 1941
1908e_nobufs: 1942e_nobufs:
1909 in_dev_put(in_dev); 1943 in_dev_put(in_dev);
@@ -2030,6 +2064,7 @@ static int __mkroute_input(struct sk_buff *skb,
2030 rth->fl.oif = 0; 2064 rth->fl.oif = 0;
2031 rth->rt_spec_dst= spec_dst; 2065 rth->rt_spec_dst= spec_dst;
2032 2066
2067 rth->u.dst.obsolete = -1;
2033 rth->u.dst.input = ip_forward; 2068 rth->u.dst.input = ip_forward;
2034 rth->u.dst.output = ip_output; 2069 rth->u.dst.output = ip_output;
2035 rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev)); 2070 rth->rt_genid = rt_genid(dev_net(rth->u.dst.dev));
@@ -2069,7 +2104,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
2069 /* put it into the cache */ 2104 /* put it into the cache */
2070 hash = rt_hash(daddr, saddr, fl->iif, 2105 hash = rt_hash(daddr, saddr, fl->iif,
2071 rt_genid(dev_net(rth->u.dst.dev))); 2106 rt_genid(dev_net(rth->u.dst.dev)));
2072 return rt_intern_hash(hash, rth, NULL, skb); 2107 return rt_intern_hash(hash, rth, NULL, skb, fl->iif);
2073} 2108}
2074 2109
2075/* 2110/*
@@ -2194,6 +2229,7 @@ local_input:
2194 goto e_nobufs; 2229 goto e_nobufs;
2195 2230
2196 rth->u.dst.output= ip_rt_bug; 2231 rth->u.dst.output= ip_rt_bug;
2232 rth->u.dst.obsolete = -1;
2197 rth->rt_genid = rt_genid(net); 2233 rth->rt_genid = rt_genid(net);
2198 2234
2199 atomic_set(&rth->u.dst.__refcnt, 1); 2235 atomic_set(&rth->u.dst.__refcnt, 1);
@@ -2225,7 +2261,7 @@ local_input:
2225 } 2261 }
2226 rth->rt_type = res.type; 2262 rth->rt_type = res.type;
2227 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); 2263 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
2228 err = rt_intern_hash(hash, rth, NULL, skb); 2264 err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
2229 goto done; 2265 goto done;
2230 2266
2231no_route: 2267no_route:
@@ -2420,6 +2456,7 @@ static int __mkroute_output(struct rtable **result,
2420 rth->rt_spec_dst= fl->fl4_src; 2456 rth->rt_spec_dst= fl->fl4_src;
2421 2457
2422 rth->u.dst.output=ip_output; 2458 rth->u.dst.output=ip_output;
2459 rth->u.dst.obsolete = -1;
2423 rth->rt_genid = rt_genid(dev_net(dev_out)); 2460 rth->rt_genid = rt_genid(dev_net(dev_out));
2424 2461
2425 RT_CACHE_STAT_INC(out_slow_tot); 2462 RT_CACHE_STAT_INC(out_slow_tot);
@@ -2471,7 +2508,7 @@ static int ip_mkroute_output(struct rtable **rp,
2471 if (err == 0) { 2508 if (err == 0) {
2472 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, 2509 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
2473 rt_genid(dev_net(dev_out))); 2510 rt_genid(dev_net(dev_out)));
2474 err = rt_intern_hash(hash, rth, rp, NULL); 2511 err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif);
2475 } 2512 }
2476 2513
2477 return err; 2514 return err;
@@ -3077,22 +3114,20 @@ static void rt_secret_reschedule(int old)
3077 rtnl_lock(); 3114 rtnl_lock();
3078 for_each_net(net) { 3115 for_each_net(net) {
3079 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer); 3116 int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
3117 long time;
3080 3118
3081 if (!new) 3119 if (!new)
3082 continue; 3120 continue;
3083 3121
3084 if (deleted) { 3122 if (deleted) {
3085 long time = net->ipv4.rt_secret_timer.expires - jiffies; 3123 time = net->ipv4.rt_secret_timer.expires - jiffies;
3086 3124
3087 if (time <= 0 || (time += diff) <= 0) 3125 if (time <= 0 || (time += diff) <= 0)
3088 time = 0; 3126 time = 0;
3089
3090 net->ipv4.rt_secret_timer.expires = time;
3091 } else 3127 } else
3092 net->ipv4.rt_secret_timer.expires = new; 3128 time = new;
3093 3129
3094 net->ipv4.rt_secret_timer.expires += jiffies; 3130 mod_timer(&net->ipv4.rt_secret_timer, jiffies + time);
3095 add_timer(&net->ipv4.rt_secret_timer);
3096 } 3131 }
3097 rtnl_unlock(); 3132 rtnl_unlock();
3098} 3133}