aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/route.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-07-18 03:40:17 -0400
committerDavid S. Miller <davem@davemloft.net>2011-07-18 03:40:17 -0400
commitd3aaeb38c40e5a6c08dd31a1b64da65c4352be36 (patch)
tree1c17b41d11edc7a7b3477a294cba440f2a14796c /net/ipv4/route.c
parent69cce1d1404968f78b177a0314f5822d5afdbbfb (diff)
net: Add ->neigh_lookup() operation to dst_ops
In the future dst entries will be neigh-less. In that environment we need to have an easy transition point for current users of dst->neighbour outside of the packet output fast path. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r--net/ipv4/route.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1d4cd3b4fd69..33137307d52a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -185,6 +185,8 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
185 return p; 185 return p;
186} 186}
187 187
188static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr);
189
188static struct dst_ops ipv4_dst_ops = { 190static struct dst_ops ipv4_dst_ops = {
189 .family = AF_INET, 191 .family = AF_INET,
190 .protocol = cpu_to_be16(ETH_P_IP), 192 .protocol = cpu_to_be16(ETH_P_IP),
@@ -199,6 +201,7 @@ static struct dst_ops ipv4_dst_ops = {
199 .link_failure = ipv4_link_failure, 201 .link_failure = ipv4_link_failure,
200 .update_pmtu = ip_rt_update_pmtu, 202 .update_pmtu = ip_rt_update_pmtu,
201 .local_out = __ip_local_out, 203 .local_out = __ip_local_out,
204 .neigh_lookup = ipv4_neigh_lookup,
202}; 205};
203 206
204#define ECN_OR_COST(class) TC_PRIO_##class 207#define ECN_OR_COST(class) TC_PRIO_##class
@@ -1008,22 +1011,30 @@ static int slow_chain_length(const struct rtable *head)
1008 return length >> FRACT_BITS; 1011 return length >> FRACT_BITS;
1009} 1012}
1010 1013
1011static int rt_bind_neighbour(struct rtable *rt) 1014static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr)
1012{ 1015{
1013 static const __be32 inaddr_any = 0;
1014 struct net_device *dev = rt->dst.dev;
1015 struct neigh_table *tbl = &arp_tbl; 1016 struct neigh_table *tbl = &arp_tbl;
1016 const __be32 *nexthop; 1017 static const __be32 inaddr_any = 0;
1018 struct net_device *dev = dst->dev;
1019 const __be32 *pkey = daddr;
1017 struct neighbour *n; 1020 struct neighbour *n;
1018 1021
1019#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) 1022#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
1020 if (dev->type == ARPHRD_ATM) 1023 if (dev->type == ARPHRD_ATM)
1021 tbl = clip_tbl_hook; 1024 tbl = clip_tbl_hook;
1022#endif 1025#endif
1023 nexthop = &rt->rt_gateway;
1024 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) 1026 if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
1025 nexthop = &inaddr_any; 1027 pkey = &inaddr_any;
1026 n = ipv4_neigh_lookup(tbl, dev, nexthop); 1028
1029 n = __ipv4_neigh_lookup(tbl, dev, *(__force u32 *)pkey);
1030 if (n)
1031 return n;
1032 return neigh_create(tbl, pkey, dev);
1033}
1034
1035static int rt_bind_neighbour(struct rtable *rt)
1036{
1037 struct neighbour *n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway);
1027 if (IS_ERR(n)) 1038 if (IS_ERR(n))
1028 return PTR_ERR(n); 1039 return PTR_ERR(n);
1029 dst_set_neighbour(&rt->dst, n); 1040 dst_set_neighbour(&rt->dst, n);
@@ -2734,6 +2745,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
2734 .default_advmss = ipv4_default_advmss, 2745 .default_advmss = ipv4_default_advmss,
2735 .update_pmtu = ipv4_rt_blackhole_update_pmtu, 2746 .update_pmtu = ipv4_rt_blackhole_update_pmtu,
2736 .cow_metrics = ipv4_rt_blackhole_cow_metrics, 2747 .cow_metrics = ipv4_rt_blackhole_cow_metrics,
2748 .neigh_lookup = ipv4_neigh_lookup,
2737}; 2749};
2738 2750
2739struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) 2751struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig)