Commit d3aaeb38c40e5a6c08dd31a1b64da65c4352be36
1 parent
69cce1d140
Exists in
master
and in
38 other branches
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>
Showing 8 changed files with 52 additions and 16 deletions Side-by-side Diff
include/net/arp.h
... | ... | @@ -38,15 +38,6 @@ |
38 | 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 | 41 | extern void arp_init(void); |
51 | 42 | extern int arp_find(unsigned char *haddr, struct sk_buff *skb); |
52 | 43 | extern int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg); |
include/net/dst.h
... | ... | @@ -387,6 +387,11 @@ |
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 | 395 | static inline void dst_link_failure(struct sk_buff *skb) |
391 | 396 | { |
392 | 397 | struct dst_entry *dst = skb_dst(skb); |
include/net/dst_ops.h
... | ... | @@ -26,6 +26,7 @@ |
26 | 26 | void (*link_failure)(struct sk_buff *); |
27 | 27 | void (*update_pmtu)(struct dst_entry *dst, u32 mtu); |
28 | 28 | int (*local_out)(struct sk_buff *skb); |
29 | + struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, const void *daddr); | |
29 | 30 | |
30 | 31 | struct kmem_cache *kmem_cachep; |
31 | 32 |
net/bridge/br_netfilter.c
... | ... | @@ -109,11 +109,17 @@ |
109 | 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 | 117 | static struct dst_ops fake_dst_ops = { |
113 | 118 | .family = AF_INET, |
114 | 119 | .protocol = cpu_to_be16(ETH_P_IP), |
115 | 120 | .update_pmtu = fake_update_pmtu, |
116 | 121 | .cow_metrics = fake_cow_metrics, |
122 | + .neigh_lookup = fake_neigh_lookup, | |
117 | 123 | }; |
118 | 124 | |
119 | 125 | /* |
net/decnet/dn_route.c
... | ... | @@ -116,6 +116,7 @@ |
116 | 116 | static struct dst_entry *dn_dst_negative_advice(struct dst_entry *); |
117 | 117 | static void dn_dst_link_failure(struct sk_buff *); |
118 | 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 | 120 | static int dn_route_input(struct sk_buff *); |
120 | 121 | static void dn_run_flush(unsigned long dummy); |
121 | 122 | |
... | ... | @@ -139,6 +140,7 @@ |
139 | 140 | .negative_advice = dn_dst_negative_advice, |
140 | 141 | .link_failure = dn_dst_link_failure, |
141 | 142 | .update_pmtu = dn_dst_update_pmtu, |
143 | + .neigh_lookup = dn_dst_neigh_lookup, | |
142 | 144 | }; |
143 | 145 | |
144 | 146 | static void dn_dst_destroy(struct dst_entry *dst) |
... | ... | @@ -825,6 +827,11 @@ |
825 | 827 | static unsigned int dn_dst_default_mtu(const struct dst_entry *dst) |
826 | 828 | { |
827 | 829 | return dst->dev->mtu; |
830 | +} | |
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); | |
828 | 835 | } |
829 | 836 | |
830 | 837 | static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) |
net/ipv4/route.c
... | ... | @@ -185,6 +185,8 @@ |
185 | 185 | return p; |
186 | 186 | } |
187 | 187 | |
188 | +static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst, const void *daddr); | |
189 | + | |
188 | 190 | static struct dst_ops ipv4_dst_ops = { |
189 | 191 | .family = AF_INET, |
190 | 192 | .protocol = cpu_to_be16(ETH_P_IP), |
... | ... | @@ -199,6 +201,7 @@ |
199 | 201 | .link_failure = ipv4_link_failure, |
200 | 202 | .update_pmtu = ip_rt_update_pmtu, |
201 | 203 | .local_out = __ip_local_out, |
204 | + .neigh_lookup = ipv4_neigh_lookup, | |
202 | 205 | }; |
203 | 206 | |
204 | 207 | #define ECN_OR_COST(class) TC_PRIO_##class |
205 | 208 | |
206 | 209 | |
207 | 210 | |
208 | 211 | |
... | ... | @@ -1008,22 +1011,30 @@ |
1008 | 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 | 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 | 1020 | struct neighbour *n; |
1018 | 1021 | |
1019 | 1022 | #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) |
1020 | 1023 | if (dev->type == ARPHRD_ATM) |
1021 | 1024 | tbl = clip_tbl_hook; |
1022 | 1025 | #endif |
1023 | - nexthop = &rt->rt_gateway; | |
1024 | 1026 | if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) |
1025 | - nexthop = &inaddr_any; | |
1026 | - n = ipv4_neigh_lookup(tbl, dev, nexthop); | |
1027 | + pkey = &inaddr_any; | |
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 | 1038 | if (IS_ERR(n)) |
1028 | 1039 | return PTR_ERR(n); |
1029 | 1040 | dst_set_neighbour(&rt->dst, n); |
... | ... | @@ -2734,6 +2745,7 @@ |
2734 | 2745 | .default_advmss = ipv4_default_advmss, |
2735 | 2746 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2736 | 2747 | .cow_metrics = ipv4_rt_blackhole_cow_metrics, |
2748 | + .neigh_lookup = ipv4_neigh_lookup, | |
2737 | 2749 | }; |
2738 | 2750 | |
2739 | 2751 | struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig) |
net/ipv6/route.c
... | ... | @@ -127,6 +127,11 @@ |
127 | 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 | 135 | static struct dst_ops ip6_dst_ops_template = { |
131 | 136 | .family = AF_INET6, |
132 | 137 | .protocol = cpu_to_be16(ETH_P_IPV6), |
... | ... | @@ -142,6 +147,7 @@ |
142 | 147 | .link_failure = ip6_link_failure, |
143 | 148 | .update_pmtu = ip6_rt_update_pmtu, |
144 | 149 | .local_out = __ip6_local_out, |
150 | + .neigh_lookup = ip6_neigh_lookup, | |
145 | 151 | }; |
146 | 152 | |
147 | 153 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) |
... | ... | @@ -168,6 +174,7 @@ |
168 | 174 | .default_advmss = ip6_default_advmss, |
169 | 175 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
170 | 176 | .cow_metrics = ip6_rt_blackhole_cow_metrics, |
177 | + .neigh_lookup = ip6_neigh_lookup, | |
171 | 178 | }; |
172 | 179 | |
173 | 180 | static const u32 ip6_template_metrics[RTAX_MAX] = { |
net/xfrm/xfrm_policy.c
... | ... | @@ -2385,6 +2385,11 @@ |
2385 | 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 | 2393 | int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) |
2389 | 2394 | { |
2390 | 2395 | struct net *net; |
... | ... | @@ -2410,6 +2415,8 @@ |
2410 | 2415 | dst_ops->negative_advice = xfrm_negative_advice; |
2411 | 2416 | if (likely(dst_ops->link_failure == NULL)) |
2412 | 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 | 2420 | if (likely(afinfo->garbage_collect == NULL)) |
2414 | 2421 | afinfo->garbage_collect = __xfrm_garbage_collect; |
2415 | 2422 | xfrm_policy_afinfo[afinfo->family] = afinfo; |
-
mentioned in commit 8a5336