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(); |