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.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 54fd68c14c87..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>
@@ -1097,7 +1098,7 @@ static int slow_chain_length(const struct rtable *head)
1097} 1098}
1098 1099
1099static int rt_intern_hash(unsigned hash, struct rtable *rt, 1100static int rt_intern_hash(unsigned hash, struct rtable *rt,
1100 struct rtable **rp, struct sk_buff *skb) 1101 struct rtable **rp, struct sk_buff *skb, int ifindex)
1101{ 1102{
1102 struct rtable *rth, **rthp; 1103 struct rtable *rth, **rthp;
1103 unsigned long now; 1104 unsigned long now;
@@ -1212,11 +1213,16 @@ restart:
1212 slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) { 1213 slow_chain_length(rt_hash_table[hash].chain) > rt_chain_length_max) {
1213 struct net *net = dev_net(rt->u.dst.dev); 1214 struct net *net = dev_net(rt->u.dst.dev);
1214 int num = ++net->ipv4.current_rt_cache_rebuild_count; 1215 int num = ++net->ipv4.current_rt_cache_rebuild_count;
1215 if (!rt_caching(dev_net(rt->u.dst.dev))) { 1216 if (!rt_caching(net)) {
1216 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",
1217 rt->u.dst.dev->name, num); 1218 rt->u.dst.dev->name, num);
1218 } 1219 }
1219 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;
1220 } 1226 }
1221 } 1227 }
1222 1228
@@ -1477,7 +1483,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1477 &netevent); 1483 &netevent);
1478 1484
1479 rt_del(hash, rth); 1485 rt_del(hash, rth);
1480 if (!rt_intern_hash(hash, rt, &rt, NULL)) 1486 if (!rt_intern_hash(hash, rt, &rt, NULL, rt->fl.oif))
1481 ip_rt_put(rt); 1487 ip_rt_put(rt);
1482 goto do_next; 1488 goto do_next;
1483 } 1489 }
@@ -1931,7 +1937,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1931 1937
1932 in_dev_put(in_dev); 1938 in_dev_put(in_dev);
1933 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)));
1934 return rt_intern_hash(hash, rth, NULL, skb); 1940 return rt_intern_hash(hash, rth, NULL, skb, dev->ifindex);
1935 1941
1936e_nobufs: 1942e_nobufs:
1937 in_dev_put(in_dev); 1943 in_dev_put(in_dev);
@@ -2098,7 +2104,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
2098 /* put it into the cache */ 2104 /* put it into the cache */
2099 hash = rt_hash(daddr, saddr, fl->iif, 2105 hash = rt_hash(daddr, saddr, fl->iif,
2100 rt_genid(dev_net(rth->u.dst.dev))); 2106 rt_genid(dev_net(rth->u.dst.dev)));
2101 return rt_intern_hash(hash, rth, NULL, skb); 2107 return rt_intern_hash(hash, rth, NULL, skb, fl->iif);
2102} 2108}
2103 2109
2104/* 2110/*
@@ -2255,7 +2261,7 @@ local_input:
2255 } 2261 }
2256 rth->rt_type = res.type; 2262 rth->rt_type = res.type;
2257 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); 2263 hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
2258 err = rt_intern_hash(hash, rth, NULL, skb); 2264 err = rt_intern_hash(hash, rth, NULL, skb, fl.iif);
2259 goto done; 2265 goto done;
2260 2266
2261no_route: 2267no_route:
@@ -2502,7 +2508,7 @@ static int ip_mkroute_output(struct rtable **rp,
2502 if (err == 0) { 2508 if (err == 0) {
2503 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, 2509 hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
2504 rt_genid(dev_net(dev_out))); 2510 rt_genid(dev_net(dev_out)));
2505 err = rt_intern_hash(hash, rth, rp, NULL); 2511 err = rt_intern_hash(hash, rth, rp, NULL, oldflp->oif);
2506 } 2512 }
2507 2513
2508 return err; 2514 return err;