aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/route.h2
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/route.c21
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
115extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp); 115extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
116extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags); 116extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
117extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin); 117extern int ip_route_input(struct sk_buff*, __be32 dst, __be32 src, u8 tos, struct net_device *devin);
118extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu); 118extern unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, unsigned short new_mtu);
119extern void ip_rt_send_redirect(struct sk_buff *skb); 119extern void ip_rt_send_redirect(struct sk_buff *skb);
120 120
121extern unsigned inet_addr_type(struct net *net, __be32 addr); 121extern 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
651static 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
1418unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu) 1423unsigned 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();