diff options
| author | David S. Miller <davem@davemloft.net> | 2011-07-18 03:40:17 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-07-18 03:40:17 -0400 |
| commit | d3aaeb38c40e5a6c08dd31a1b64da65c4352be36 (patch) | |
| tree | 1c17b41d11edc7a7b3477a294cba440f2a14796c | |
| parent | 69cce1d1404968f78b177a0314f5822d5afdbbfb (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>
| -rw-r--r-- | include/net/arp.h | 9 | ||||
| -rw-r--r-- | include/net/dst.h | 5 | ||||
| -rw-r--r-- | include/net/dst_ops.h | 1 | ||||
| -rw-r--r-- | net/bridge/br_netfilter.c | 6 | ||||
| -rw-r--r-- | net/decnet/dn_route.c | 7 | ||||
| -rw-r--r-- | net/ipv4/route.c | 26 | ||||
| -rw-r--r-- | net/ipv6/route.c | 7 | ||||
| -rw-r--r-- | net/xfrm/xfrm_policy.c | 7 |
8 files changed, 52 insertions, 16 deletions
diff --git a/include/net/arp.h b/include/net/arp.h index 5e669e6ffb42..4979af8b1559 100644 --- a/include/net/arp.h +++ b/include/net/arp.h | |||
| @@ -38,15 +38,6 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct neigh_table *tbl, str | |||
| 38 | return n; | 38 | return n; |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | static inline struct neighbour *ipv4_neigh_lookup(struct neigh_table *tbl, struct net_device *dev, const __be32 *pkey) | ||
| 42 | { | ||
| 43 | struct neighbour *n = __ipv4_neigh_lookup(tbl, dev, | ||
| 44 | *(__force u32 *)pkey); | ||
| 45 | if (n) | ||
| 46 | return n; | ||
| 47 | return neigh_create(tbl, pkey, dev); | ||
| 48 | } | ||
| 49 | |||
| 50 | extern void arp_init(void); | 41 | extern void arp_init(void); |
| 51 | extern int arp_find(unsigned char *haddr, struct sk_buff *skb); | 42 | extern int arp_find(unsigned char *haddr, struct sk_buff *skb); |
| 52 | extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); | 43 | extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); |
diff --git a/include/net/dst.h b/include/net/dst.h index 8147206eefb9..29e255796ce1 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
| @@ -387,6 +387,11 @@ static inline void dst_confirm(struct dst_entry *dst) | |||
| 387 | } | 387 | } |
| 388 | } | 388 | } |
| 389 | 389 | ||
| 390 | static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
| 391 | { | ||
| 392 | return dst->ops->neigh_lookup(dst, daddr); | ||
| 393 | } | ||
| 394 | |||
| 390 | static inline void dst_link_failure(struct sk_buff *skb) | 395 | static inline void dst_link_failure(struct sk_buff *skb) |
| 391 | { | 396 | { |
| 392 | struct dst_entry *dst = skb_dst(skb); | 397 | struct dst_entry *dst = skb_dst(skb); |
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index dc0746328947..9adb99845a56 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h | |||
| @@ -26,6 +26,7 @@ struct dst_ops { | |||
| 26 | void (*link_failure)(struct sk_buff *); | 26 | void (*link_failure)(struct sk_buff *); |
| 27 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); | 27 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); |
| 28 | int (*local_out)(struct sk_buff *skb); | 28 | int (*local_out)(struct sk_buff *skb); |
| 29 | struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, const void *daddr); | ||
| 29 | 30 | ||
| 30 | struct kmem_cache *kmem_cachep; | 31 | struct kmem_cache *kmem_cachep; |
| 31 | 32 | ||
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index b1a5f9777b7e..d6ec3720c77e 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c | |||
| @@ -109,11 +109,17 @@ static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old) | |||
| 109 | return NULL; | 109 | return NULL; |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
| 113 | { | ||
| 114 | return NULL; | ||
| 115 | } | ||
| 116 | |||
| 112 | static struct dst_ops fake_dst_ops = { | 117 | static struct dst_ops fake_dst_ops = { |
| 113 | .family = AF_INET, | 118 | .family = AF_INET, |
| 114 | .protocol = cpu_to_be16(ETH_P_IP), | 119 | .protocol = cpu_to_be16(ETH_P_IP), |
| 115 | .update_pmtu = fake_update_pmtu, | 120 | .update_pmtu = fake_update_pmtu, |
| 116 | .cow_metrics = fake_cow_metrics, | 121 | .cow_metrics = fake_cow_metrics, |
| 122 | .neigh_lookup = fake_neigh_lookup, | ||
| 117 | }; | 123 | }; |
| 118 | 124 | ||
| 119 | /* | 125 | /* |
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 9bd45fcb3b8e..43450c100226 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
| @@ -116,6 +116,7 @@ static void dn_dst_destroy(struct dst_entry *); | |||
| 116 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); | 116 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
| 117 | static void dn_dst_link_failure(struct sk_buff *); | 117 | static void dn_dst_link_failure(struct sk_buff *); |
| 118 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); | 118 | static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu); |
| 119 | static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr); | ||
| 119 | static int dn_route_input(struct sk_buff *); | 120 | static int dn_route_input(struct sk_buff *); |
| 120 | static void dn_run_flush(unsigned long dummy); | 121 | static void dn_run_flush(unsigned long dummy); |
| 121 | 122 | ||
| @@ -139,6 +140,7 @@ static struct dst_ops dn_dst_ops = { | |||
| 139 | .negative_advice = dn_dst_negative_advice, | 140 | .negative_advice = dn_dst_negative_advice, |
| 140 | .link_failure = dn_dst_link_failure, | 141 | .link_failure = dn_dst_link_failure, |
| 141 | .update_pmtu = dn_dst_update_pmtu, | 142 | .update_pmtu = dn_dst_update_pmtu, |
| 143 | .neigh_lookup = dn_dst_neigh_lookup, | ||
| 142 | }; | 144 | }; |
| 143 | 145 | ||
| 144 | static void dn_dst_destroy(struct dst_entry *dst) | 146 | static void dn_dst_destroy(struct dst_entry *dst) |
| @@ -827,6 +829,11 @@ static unsigned int dn_dst_default_mtu(const struct dst_entry *dst) | |||
| 827 | return dst->dev->mtu; | 829 | return dst->dev->mtu; |
| 828 | } | 830 | } |
| 829 | 831 | ||
| 832 | static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
| 833 | { | ||
| 834 | return __neigh_lookup_errno(&dn_neigh_table, daddr, dst->dev); | ||
| 835 | } | ||
| 836 | |||
| 830 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) | 837 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) |
| 831 | { | 838 | { |
| 832 | struct dn_fib_info *fi = res->fi; | 839 | struct dn_fib_info *fi = res->fi; |
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 | ||
| 188 | static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr); | ||
| 189 | |||
| 188 | static struct dst_ops ipv4_dst_ops = { | 190 | static 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 | ||
| 1011 | static int rt_bind_neighbour(struct rtable *rt) | 1014 | static 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 | |||
| 1035 | static 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 | ||
| 2739 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) | 2751 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 2998cb5be90b..ddef80f568b0 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -127,6 +127,11 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old) | |||
| 127 | return p; | 127 | return p; |
| 128 | } | 128 | } |
| 129 | 129 | ||
| 130 | static struct neighbour *ip6_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
| 131 | { | ||
| 132 | return __neigh_lookup_errno(&nd_tbl, daddr, dst->dev); | ||
| 133 | } | ||
| 134 | |||
| 130 | static struct dst_ops ip6_dst_ops_template = { | 135 | static struct dst_ops ip6_dst_ops_template = { |
| 131 | .family = AF_INET6, | 136 | .family = AF_INET6, |
| 132 | .protocol = cpu_to_be16(ETH_P_IPV6), | 137 | .protocol = cpu_to_be16(ETH_P_IPV6), |
| @@ -142,6 +147,7 @@ static struct dst_ops ip6_dst_ops_template = { | |||
| 142 | .link_failure = ip6_link_failure, | 147 | .link_failure = ip6_link_failure, |
| 143 | .update_pmtu = ip6_rt_update_pmtu, | 148 | .update_pmtu = ip6_rt_update_pmtu, |
| 144 | .local_out = __ip6_local_out, | 149 | .local_out = __ip6_local_out, |
| 150 | .neigh_lookup = ip6_neigh_lookup, | ||
| 145 | }; | 151 | }; |
| 146 | 152 | ||
| 147 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | 153 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) |
| @@ -168,6 +174,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
| 168 | .default_advmss = ip6_default_advmss, | 174 | .default_advmss = ip6_default_advmss, |
| 169 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 175 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
| 170 | .cow_metrics = ip6_rt_blackhole_cow_metrics, | 176 | .cow_metrics = ip6_rt_blackhole_cow_metrics, |
| 177 | .neigh_lookup = ip6_neigh_lookup, | ||
| 171 | }; | 178 | }; |
| 172 | 179 | ||
| 173 | static const u32 ip6_template_metrics[RTAX_MAX] = { | 180 | static const u32 ip6_template_metrics[RTAX_MAX] = { |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 7803eb6af414..94fdcc7f1030 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -2385,6 +2385,11 @@ static unsigned int xfrm_default_mtu(const struct dst_entry *dst) | |||
| 2385 | return dst_mtu(dst->path); | 2385 | return dst_mtu(dst->path); |
| 2386 | } | 2386 | } |
| 2387 | 2387 | ||
| 2388 | static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr) | ||
| 2389 | { | ||
| 2390 | return dst_neigh_lookup(dst->path, daddr); | ||
| 2391 | } | ||
| 2392 | |||
| 2388 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | 2393 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
| 2389 | { | 2394 | { |
| 2390 | struct net *net; | 2395 | struct net *net; |
| @@ -2410,6 +2415,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) | |||
| 2410 | dst_ops->negative_advice = xfrm_negative_advice; | 2415 | dst_ops->negative_advice = xfrm_negative_advice; |
| 2411 | if (likely(dst_ops->link_failure == NULL)) | 2416 | if (likely(dst_ops->link_failure == NULL)) |
| 2412 | dst_ops->link_failure = xfrm_link_failure; | 2417 | dst_ops->link_failure = xfrm_link_failure; |
| 2418 | if (likely(dst_ops->neigh_lookup == NULL)) | ||
| 2419 | dst_ops->neigh_lookup = xfrm_neigh_lookup; | ||
| 2413 | if (likely(afinfo->garbage_collect == NULL)) | 2420 | if (likely(afinfo->garbage_collect == NULL)) |
| 2414 | afinfo->garbage_collect = __xfrm_garbage_collect; | 2421 | afinfo->garbage_collect = __xfrm_garbage_collect; |
| 2415 | xfrm_policy_afinfo[afinfo->family] = afinfo; | 2422 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
