diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2015-03-03 18:10:44 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-03-04 00:23:23 -0500 |
commit | 60395a20ffd74166ea373ea91418d6f98fa7fdfb (patch) | |
tree | c4ed2b51ec4f179a48018d86660e6f2bb5b8bd81 /include/net | |
parent | 2f56f6be47dbc6883e28107edfe2f9f98f4d5a24 (diff) |
neigh: Factor out ___neigh_lookup_noref
While looking at the mpls code I found myself writing yet another
version of neigh_lookup_noref. We currently have __ipv4_lookup_noref
and __ipv6_lookup_noref.
So to make my work a little easier and to make it a smidge easier to
verify/maintain the mpls code in the future I stopped and wrote
___neigh_lookup_noref. Then I rewote __ipv4_lookup_noref and
__ipv6_lookup_noref in terms of this new function. I tested my new
version by verifying that the same code is generated in
ip_finish_output2 and ip6_finish_output2 where these functions are
inlined.
To get to ___neigh_lookup_noref I added a new neighbour cache table
function key_eq. So that the static size of the key would be
available.
I also added __neigh_lookup_noref for people who want to to lookup
a neighbour table entry quickly but don't know which neibhgour table
they are going to look up.
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/arp.h | 19 | ||||
-rw-r--r-- | include/net/ndisc.h | 19 | ||||
-rw-r--r-- | include/net/neighbour.h | 52 |
3 files changed, 57 insertions, 33 deletions
diff --git a/include/net/arp.h b/include/net/arp.h index 21ee1860abbc..5e0f891d476c 100644 --- a/include/net/arp.h +++ b/include/net/arp.h | |||
@@ -9,28 +9,17 @@ | |||
9 | 9 | ||
10 | extern struct neigh_table arp_tbl; | 10 | extern struct neigh_table arp_tbl; |
11 | 11 | ||
12 | static inline u32 arp_hashfn(u32 key, const struct net_device *dev, u32 hash_rnd) | 12 | static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd) |
13 | { | 13 | { |
14 | u32 key = *(const u32 *)pkey; | ||
14 | u32 val = key ^ hash32_ptr(dev); | 15 | u32 val = key ^ hash32_ptr(dev); |
15 | 16 | ||
16 | return val * hash_rnd; | 17 | return val * hash_rnd[0]; |
17 | } | 18 | } |
18 | 19 | ||
19 | static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key) | 20 | static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key) |
20 | { | 21 | { |
21 | struct neigh_hash_table *nht = rcu_dereference_bh(arp_tbl.nht); | 22 | return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev); |
22 | struct neighbour *n; | ||
23 | u32 hash_val; | ||
24 | |||
25 | hash_val = arp_hashfn(key, dev, nht->hash_rnd[0]) >> (32 - nht->hash_shift); | ||
26 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | ||
27 | n != NULL; | ||
28 | n = rcu_dereference_bh(n->next)) { | ||
29 | if (n->dev == dev && *(u32 *)n->primary_key == key) | ||
30 | return n; | ||
31 | } | ||
32 | |||
33 | return NULL; | ||
34 | } | 23 | } |
35 | 24 | ||
36 | static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key) | 25 | static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32 key) |
diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 6bbda34d5e59..b3a7751251b4 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h | |||
@@ -156,24 +156,7 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _ | |||
156 | 156 | ||
157 | static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey) | 157 | static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey) |
158 | { | 158 | { |
159 | struct neigh_hash_table *nht; | 159 | return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev); |
160 | const u32 *p32 = pkey; | ||
161 | struct neighbour *n; | ||
162 | u32 hash_val; | ||
163 | |||
164 | nht = rcu_dereference_bh(nd_tbl.nht); | ||
165 | hash_val = ndisc_hashfn(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); | ||
166 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | ||
167 | n != NULL; | ||
168 | n = rcu_dereference_bh(n->next)) { | ||
169 | u32 *n32 = (u32 *) n->primary_key; | ||
170 | if (n->dev == dev && | ||
171 | ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | | ||
172 | (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0) | ||
173 | return n; | ||
174 | } | ||
175 | |||
176 | return NULL; | ||
177 | } | 160 | } |
178 | 161 | ||
179 | static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey) | 162 | static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey) |
diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 9f912e4d4232..14e3f017966b 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h | |||
@@ -197,6 +197,7 @@ struct neigh_table { | |||
197 | __u32 (*hash)(const void *pkey, | 197 | __u32 (*hash)(const void *pkey, |
198 | const struct net_device *dev, | 198 | const struct net_device *dev, |
199 | __u32 *hash_rnd); | 199 | __u32 *hash_rnd); |
200 | bool (*key_eq)(const struct neighbour *, const void *pkey); | ||
200 | int (*constructor)(struct neighbour *); | 201 | int (*constructor)(struct neighbour *); |
201 | int (*pconstructor)(struct pneigh_entry *); | 202 | int (*pconstructor)(struct pneigh_entry *); |
202 | void (*pdestructor)(struct pneigh_entry *); | 203 | void (*pdestructor)(struct pneigh_entry *); |
@@ -247,6 +248,57 @@ static inline void *neighbour_priv(const struct neighbour *n) | |||
247 | #define NEIGH_UPDATE_F_ISROUTER 0x40000000 | 248 | #define NEIGH_UPDATE_F_ISROUTER 0x40000000 |
248 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 | 249 | #define NEIGH_UPDATE_F_ADMIN 0x80000000 |
249 | 250 | ||
251 | |||
252 | static inline bool neigh_key_eq16(const struct neighbour *n, const void *pkey) | ||
253 | { | ||
254 | return *(const u16 *)n->primary_key == *(const u16 *)pkey; | ||
255 | } | ||
256 | |||
257 | static inline bool neigh_key_eq32(const struct neighbour *n, const void *pkey) | ||
258 | { | ||
259 | return *(const u32 *)n->primary_key == *(const u32 *)pkey; | ||
260 | } | ||
261 | |||
262 | static inline bool neigh_key_eq128(const struct neighbour *n, const void *pkey) | ||
263 | { | ||
264 | const u32 *n32 = (const u32 *)n->primary_key; | ||
265 | const u32 *p32 = pkey; | ||
266 | |||
267 | return ((n32[0] ^ p32[0]) | (n32[1] ^ p32[1]) | | ||
268 | (n32[2] ^ p32[2]) | (n32[3] ^ p32[3])) == 0; | ||
269 | } | ||
270 | |||
271 | static inline struct neighbour *___neigh_lookup_noref( | ||
272 | struct neigh_table *tbl, | ||
273 | bool (*key_eq)(const struct neighbour *n, const void *pkey), | ||
274 | __u32 (*hash)(const void *pkey, | ||
275 | const struct net_device *dev, | ||
276 | __u32 *hash_rnd), | ||
277 | const void *pkey, | ||
278 | struct net_device *dev) | ||
279 | { | ||
280 | struct neigh_hash_table *nht = rcu_dereference_bh(tbl->nht); | ||
281 | struct neighbour *n; | ||
282 | u32 hash_val; | ||
283 | |||
284 | hash_val = hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); | ||
285 | for (n = rcu_dereference_bh(nht->hash_buckets[hash_val]); | ||
286 | n != NULL; | ||
287 | n = rcu_dereference_bh(n->next)) { | ||
288 | if (n->dev == dev && key_eq(n, pkey)) | ||
289 | return n; | ||
290 | } | ||
291 | |||
292 | return NULL; | ||
293 | } | ||
294 | |||
295 | static inline struct neighbour *__neigh_lookup_noref(struct neigh_table *tbl, | ||
296 | const void *pkey, | ||
297 | struct net_device *dev) | ||
298 | { | ||
299 | return ___neigh_lookup_noref(tbl, tbl->key_eq, tbl->hash, pkey, dev); | ||
300 | } | ||
301 | |||
250 | void neigh_table_init(int index, struct neigh_table *tbl); | 302 | void neigh_table_init(int index, struct neigh_table *tbl); |
251 | int neigh_table_clear(int index, struct neigh_table *tbl); | 303 | int neigh_table_clear(int index, struct neigh_table *tbl); |
252 | struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, | 304 | struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey, |