diff options
Diffstat (limited to 'net/ipv4/route.c')
| -rw-r--r-- | net/ipv4/route.c | 22 |
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 | ||
| 1099 | static int rt_intern_hash(unsigned hash, struct rtable *rt, | 1100 | static 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 | ||
| 1936 | e_nobufs: | 1942 | e_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 | ||
| 2261 | no_route: | 2267 | no_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; |
