aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2008-01-23 02:50:25 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:11:13 -0500
commitb5921910a1de4ba82add59154976c3dc7352c8c2 (patch)
treec1de2c3734219548c2883777597247caa5450dc5
parenteee80592c3c1f7381c04913d9d3eb6e3c3c87628 (diff)
[NETNS]: Routing cache virtualization.
Basically, this piece looks relatively easy. Namespace is already available on the dst entry via device and the device is safe to dereferrence. Compare it with one of a searcher and skip entry if appropriate. The only exception is ip_rt_frag_needed. So, add namespace parameter to it. Signed-off-by: Denis V. Lunev <den@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-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();