diff options
Diffstat (limited to 'net/ipv4/route.c')
| -rw-r--r-- | net/ipv4/route.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d62b05d33384..b2ba5581d2ae 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -287,12 +287,12 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq) | |||
| 287 | if (!rt_hash_table[st->bucket].chain) | 287 | if (!rt_hash_table[st->bucket].chain) |
| 288 | continue; | 288 | continue; |
| 289 | rcu_read_lock_bh(); | 289 | rcu_read_lock_bh(); |
| 290 | r = rcu_dereference(rt_hash_table[st->bucket].chain); | 290 | r = rcu_dereference_bh(rt_hash_table[st->bucket].chain); |
| 291 | while (r) { | 291 | while (r) { |
| 292 | if (dev_net(r->u.dst.dev) == seq_file_net(seq) && | 292 | if (dev_net(r->u.dst.dev) == seq_file_net(seq) && |
| 293 | r->rt_genid == st->genid) | 293 | r->rt_genid == st->genid) |
| 294 | return r; | 294 | return r; |
| 295 | r = rcu_dereference(r->u.dst.rt_next); | 295 | r = rcu_dereference_bh(r->u.dst.rt_next); |
| 296 | } | 296 | } |
| 297 | rcu_read_unlock_bh(); | 297 | rcu_read_unlock_bh(); |
| 298 | } | 298 | } |
| @@ -314,7 +314,7 @@ static struct rtable *__rt_cache_get_next(struct seq_file *seq, | |||
| 314 | rcu_read_lock_bh(); | 314 | rcu_read_lock_bh(); |
| 315 | r = rt_hash_table[st->bucket].chain; | 315 | r = rt_hash_table[st->bucket].chain; |
| 316 | } | 316 | } |
| 317 | return rcu_dereference(r); | 317 | return rcu_dereference_bh(r); |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | static struct rtable *rt_cache_get_next(struct seq_file *seq, | 320 | static struct rtable *rt_cache_get_next(struct seq_file *seq, |
| @@ -1990,8 +1990,13 @@ static int __mkroute_input(struct sk_buff *skb, | |||
| 1990 | if (skb->protocol != htons(ETH_P_IP)) { | 1990 | if (skb->protocol != htons(ETH_P_IP)) { |
| 1991 | /* Not IP (i.e. ARP). Do not create route, if it is | 1991 | /* Not IP (i.e. ARP). Do not create route, if it is |
| 1992 | * invalid for proxy arp. DNAT routes are always valid. | 1992 | * invalid for proxy arp. DNAT routes are always valid. |
| 1993 | * | ||
| 1994 | * Proxy arp feature have been extended to allow, ARP | ||
| 1995 | * replies back to the same interface, to support | ||
| 1996 | * Private VLAN switch technologies. See arp.c. | ||
| 1993 | */ | 1997 | */ |
| 1994 | if (out_dev == in_dev) { | 1998 | if (out_dev == in_dev && |
| 1999 | IN_DEV_PROXY_ARP_PVLAN(in_dev) == 0) { | ||
| 1995 | err = -EINVAL; | 2000 | err = -EINVAL; |
| 1996 | goto cleanup; | 2001 | goto cleanup; |
| 1997 | } | 2002 | } |
| @@ -2689,8 +2694,8 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, | |||
| 2689 | hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif, rt_genid(net)); | 2694 | hash = rt_hash(flp->fl4_dst, flp->fl4_src, flp->oif, rt_genid(net)); |
| 2690 | 2695 | ||
| 2691 | rcu_read_lock_bh(); | 2696 | rcu_read_lock_bh(); |
| 2692 | for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; | 2697 | for (rth = rcu_dereference_bh(rt_hash_table[hash].chain); rth; |
| 2693 | rth = rcu_dereference(rth->u.dst.rt_next)) { | 2698 | rth = rcu_dereference_bh(rth->u.dst.rt_next)) { |
| 2694 | if (rth->fl.fl4_dst == flp->fl4_dst && | 2699 | if (rth->fl.fl4_dst == flp->fl4_dst && |
| 2695 | rth->fl.fl4_src == flp->fl4_src && | 2700 | rth->fl.fl4_src == flp->fl4_src && |
| 2696 | rth->fl.iif == 0 && | 2701 | rth->fl.iif == 0 && |
| @@ -3008,8 +3013,8 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
| 3008 | if (!rt_hash_table[h].chain) | 3013 | if (!rt_hash_table[h].chain) |
| 3009 | continue; | 3014 | continue; |
| 3010 | rcu_read_lock_bh(); | 3015 | rcu_read_lock_bh(); |
| 3011 | for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; | 3016 | for (rt = rcu_dereference_bh(rt_hash_table[h].chain), idx = 0; rt; |
| 3012 | rt = rcu_dereference(rt->u.dst.rt_next), idx++) { | 3017 | rt = rcu_dereference_bh(rt->u.dst.rt_next), idx++) { |
| 3013 | if (!net_eq(dev_net(rt->u.dst.dev), net) || idx < s_idx) | 3018 | if (!net_eq(dev_net(rt->u.dst.dev), net) || idx < s_idx) |
| 3014 | continue; | 3019 | continue; |
| 3015 | if (rt_is_expired(rt)) | 3020 | if (rt_is_expired(rt)) |
| @@ -3329,7 +3334,7 @@ static __net_initdata struct pernet_operations rt_secret_timer_ops = { | |||
| 3329 | 3334 | ||
| 3330 | 3335 | ||
| 3331 | #ifdef CONFIG_NET_CLS_ROUTE | 3336 | #ifdef CONFIG_NET_CLS_ROUTE |
| 3332 | struct ip_rt_acct *ip_rt_acct __read_mostly; | 3337 | struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; |
| 3333 | #endif /* CONFIG_NET_CLS_ROUTE */ | 3338 | #endif /* CONFIG_NET_CLS_ROUTE */ |
| 3334 | 3339 | ||
| 3335 | static __initdata unsigned long rhash_entries; | 3340 | static __initdata unsigned long rhash_entries; |
