diff options
| -rw-r--r-- | include/net/route.h | 2 | ||||
| -rw-r--r-- | net/ipv4/icmp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/route.c | 21 |
3 files changed, 18 insertions, 7 deletions
diff --git a/include/net/route.h b/include/net/route.h index 1985d820edea..4eabf008413b 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
| @@ -115,7 +115,7 @@ extern int __ip_route_output_key(struct net *, struct rtable **, const struct f | |||
| 115 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); | 115 | extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); |
| 116 | extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); | 116 | extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); |
| 117 | extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); | 117 | extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); |
| 118 | extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); | 118 | extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu); |
| 119 | extern void ip_rt_send_redirect(struct sk_buff *skb); | 119 | extern void ip_rt_send_redirect(struct sk_buff *skb); |
| 120 | 120 | ||
| 121 | extern unsigned inet_addr_type(struct net *net, __be32 addr); | 121 | extern unsigned inet_addr_type(struct net *net, __be32 addr); |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index a142f19fec45..63ffc7d86f98 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -696,7 +696,7 @@ static void icmp_unreach(struct sk_buff *skb) | |||
| 696 | "and DF set.\n", | 696 | "and DF set.\n", |
| 697 | NIPQUAD(iph->daddr)); | 697 | NIPQUAD(iph->daddr)); |
| 698 | } else { | 698 | } else { |
| 699 | info = ip_rt_frag_needed(iph, | 699 | info = ip_rt_frag_needed(&init_net, iph, |
| 700 | ntohs(icmph->un.frag.mtu)); | 700 | ntohs(icmph->un.frag.mtu)); |
| 701 | if (!info) | 701 | if (!info) |
| 702 | goto out; | 702 | goto out; |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 39a40342142f..896c768e41a2 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -648,6 +648,11 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) | |||
| 648 | (fl1->iif ^ fl2->iif)) == 0; | 648 | (fl1->iif ^ fl2->iif)) == 0; |
| 649 | } | 649 | } |
| 650 | 650 | ||
| 651 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | ||
| 652 | { | ||
| 653 | return rt1->u.dst.dev->nd_net == rt2->u.dst.dev->nd_net; | ||
| 654 | } | ||
| 655 | |||
| 651 | /* | 656 | /* |
| 652 | * Perform a full scan of hash table and free all entries. | 657 | * Perform a full scan of hash table and free all entries. |
| 653 | * Can be called by a softirq or a process. | 658 | * Can be called by a softirq or a process. |
| @@ -961,7 +966,7 @@ restart: | |||
| 961 | 966 | ||
| 962 | spin_lock_bh(rt_hash_lock_addr(hash)); | 967 | spin_lock_bh(rt_hash_lock_addr(hash)); |
| 963 | while ((rth = *rthp) != NULL) { | 968 | while ((rth = *rthp) != NULL) { |
| 964 | if (compare_keys(&rth->fl, &rt->fl)) { | 969 | if (compare_keys(&rth->fl, &rt->fl) && compare_netns(rth, rt)) { |
| 965 | /* Put it first */ | 970 | /* Put it first */ |
| 966 | *rthp = rth->u.dst.rt_next; | 971 | *rthp = rth->u.dst.rt_next; |
| 967 | /* | 972 | /* |
| @@ -1415,7 +1420,8 @@ static __inline__ unsigned short guess_mtu(unsigned short old_mtu) | |||
| 1415 | return 68; | 1420 | return 68; |
| 1416 | } | 1421 | } |
| 1417 | 1422 | ||
| 1418 | unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) | 1423 | unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, |
| 1424 | unsigned short new_mtu) | ||
| 1419 | { | 1425 | { |
| 1420 | int i; | 1426 | int i; |
| 1421 | unsigned short old_mtu = ntohs(iph->tot_len); | 1427 | unsigned short old_mtu = ntohs(iph->tot_len); |
| @@ -1438,7 +1444,8 @@ unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) | |||
| 1438 | rth->rt_dst == daddr && | 1444 | rth->rt_dst == daddr && |
| 1439 | rth->rt_src == iph->saddr && | 1445 | rth->rt_src == iph->saddr && |
| 1440 | rth->fl.iif == 0 && | 1446 | rth->fl.iif == 0 && |
| 1441 | !(dst_metric_locked(&rth->u.dst, RTAX_MTU))) { | 1447 | !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) && |
| 1448 | rth->u.dst.dev->nd_net == net) { | ||
| 1442 | unsigned short mtu = new_mtu; | 1449 | unsigned short mtu = new_mtu; |
| 1443 | 1450 | ||
| 1444 | if (new_mtu < 68 || new_mtu >= old_mtu) { | 1451 | if (new_mtu < 68 || new_mtu >= old_mtu) { |
| @@ -2049,7 +2056,9 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2049 | struct rtable * rth; | 2056 | struct rtable * rth; |
| 2050 | unsigned hash; | 2057 | unsigned hash; |
| 2051 | int iif = dev->ifindex; | 2058 | int iif = dev->ifindex; |
| 2059 | struct net *net; | ||
| 2052 | 2060 | ||
| 2061 | net = skb->dev->nd_net; | ||
| 2053 | tos &= IPTOS_RT_MASK; | 2062 | tos &= IPTOS_RT_MASK; |
| 2054 | hash = rt_hash(daddr, saddr, iif); | 2063 | hash = rt_hash(daddr, saddr, iif); |
| 2055 | 2064 | ||
| @@ -2061,7 +2070,8 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
| 2061 | rth->fl.iif == iif && | 2070 | rth->fl.iif == iif && |
| 2062 | rth->fl.oif == 0 && | 2071 | rth->fl.oif == 0 && |
| 2063 | rth->fl.mark == skb->mark && | 2072 | rth->fl.mark == skb->mark && |
| 2064 | rth->fl.fl4_tos == tos) { | 2073 | rth->fl.fl4_tos == tos && |
| 2074 | rth->u.dst.dev->nd_net == net) { | ||
| 2065 | dst_use(&rth->u.dst, jiffies); | 2075 | dst_use(&rth->u.dst, jiffies); |
| 2066 | RT_CACHE_STAT_INC(in_hit); | 2076 | RT_CACHE_STAT_INC(in_hit); |
| 2067 | rcu_read_unlock(); | 2077 | rcu_read_unlock(); |
| @@ -2460,7 +2470,8 @@ int __ip_route_output_key(struct net *net, struct rtable **rp, | |||
| 2460 | rth->fl.oif == flp->oif && | 2470 | rth->fl.oif == flp->oif && |
| 2461 | rth->fl.mark == flp->mark && | 2471 | rth->fl.mark == flp->mark && |
| 2462 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & | 2472 | !((rth->fl.fl4_tos ^ flp->fl4_tos) & |
| 2463 | (IPTOS_RT_MASK | RTO_ONLINK))) { | 2473 | (IPTOS_RT_MASK | RTO_ONLINK)) && |
| 2474 | rth->u.dst.dev->nd_net == net) { | ||
| 2464 | dst_use(&rth->u.dst, jiffies); | 2475 | dst_use(&rth->u.dst, jiffies); |
| 2465 | RT_CACHE_STAT_INC(out_hit); | 2476 | RT_CACHE_STAT_INC(out_hit); |
| 2466 | rcu_read_unlock_bh(); | 2477 | rcu_read_unlock_bh(); |
