aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/inet_hashtables.h40
-rw-r--r--net/ipv4/inet_hashtables.c38
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 */
377static inline struct sock * 377extern 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;
407out:
408 read_unlock(lock);
409 return sk;
410hit:
411 sock_hold(sk);
412 goto out;
413}
414 380
415static inline struct sock * 381static 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}
191EXPORT_SYMBOL_GPL(__inet_lookup_listener); 191EXPORT_SYMBOL_GPL(__inet_lookup_listener);
192 192
193struct 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;
222out:
223 read_unlock(lock);
224 return sk;
225hit:
226 sock_hold(sk);
227 goto out;
228}
229EXPORT_SYMBOL_GPL(__inet_lookup_established);
230
193/* called with local bh disabled */ 231/* called with local bh disabled */
194static int __inet_check_established(struct inet_timewait_death_row *death_row, 232static int __inet_check_established(struct inet_timewait_death_row *death_row,
195 struct sock *sk, __u16 lport, 233 struct sock *sk, __u16 lport,