diff options
-rw-r--r-- | include/net/inet_hashtables.h | 40 | ||||
-rw-r--r-- | net/ipv4/inet_hashtables.c | 38 |
2 files changed, 41 insertions, 37 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 982d487751f9..65ddb25d62e8 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -374,43 +374,9 @@ typedef __u64 __bitwise __addrpair; | |||
374 | * | 374 | * |
375 | * Local BH must be disabled here. | 375 | * Local BH must be disabled here. |
376 | */ | 376 | */ |
377 | static inline struct sock * | 377 | extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, |
378 | __inet_lookup_established(struct inet_hashinfo *hashinfo, | 378 | const __be32 saddr, const __be16 sport, |
379 | const __be32 saddr, const __be16 sport, | 379 | const __be32 daddr, const u16 hnum, const int dif); |
380 | const __be32 daddr, const u16 hnum, | ||
381 | const int dif) | ||
382 | { | ||
383 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
384 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); | ||
385 | struct sock *sk; | ||
386 | const struct hlist_node *node; | ||
387 | /* Optimize here for direct hit, only listening connections can | ||
388 | * have wildcards anyways. | ||
389 | */ | ||
390 | unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); | ||
391 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | ||
392 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | ||
393 | |||
394 | prefetch(head->chain.first); | ||
395 | read_lock(lock); | ||
396 | sk_for_each(sk, node, &head->chain) { | ||
397 | if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
398 | goto hit; /* You sunk my battleship! */ | ||
399 | } | ||
400 | |||
401 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
402 | sk_for_each(sk, node, &head->twchain) { | ||
403 | if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
404 | goto hit; | ||
405 | } | ||
406 | sk = NULL; | ||
407 | out: | ||
408 | read_unlock(lock); | ||
409 | return sk; | ||
410 | hit: | ||
411 | sock_hold(sk); | ||
412 | goto out; | ||
413 | } | ||
414 | 380 | ||
415 | static inline struct sock * | 381 | static inline struct sock * |
416 | inet_lookup_established(struct inet_hashinfo *hashinfo, | 382 | inet_lookup_established(struct inet_hashinfo *hashinfo, |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 8dfd5a691e5f..2e5814a84360 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -190,6 +190,44 @@ sherry_cache: | |||
190 | } | 190 | } |
191 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); | 191 | EXPORT_SYMBOL_GPL(__inet_lookup_listener); |
192 | 192 | ||
193 | struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, | ||
194 | const __be32 saddr, const __be16 sport, | ||
195 | const __be32 daddr, const u16 hnum, | ||
196 | const int dif) | ||
197 | { | ||
198 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
199 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); | ||
200 | struct sock *sk; | ||
201 | const struct hlist_node *node; | ||
202 | /* Optimize here for direct hit, only listening connections can | ||
203 | * have wildcards anyways. | ||
204 | */ | ||
205 | unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); | ||
206 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | ||
207 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | ||
208 | |||
209 | prefetch(head->chain.first); | ||
210 | read_lock(lock); | ||
211 | sk_for_each(sk, node, &head->chain) { | ||
212 | if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
213 | goto hit; /* You sunk my battleship! */ | ||
214 | } | ||
215 | |||
216 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
217 | sk_for_each(sk, node, &head->twchain) { | ||
218 | if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
219 | goto hit; | ||
220 | } | ||
221 | sk = NULL; | ||
222 | out: | ||
223 | read_unlock(lock); | ||
224 | return sk; | ||
225 | hit: | ||
226 | sock_hold(sk); | ||
227 | goto out; | ||
228 | } | ||
229 | EXPORT_SYMBOL_GPL(__inet_lookup_established); | ||
230 | |||
193 | /* called with local bh disabled */ | 231 | /* called with local bh disabled */ |
194 | static int __inet_check_established(struct inet_timewait_death_row *death_row, | 232 | static int __inet_check_established(struct inet_timewait_death_row *death_row, |
195 | struct sock *sk, __u16 lport, | 233 | struct sock *sk, __u16 lport, |