diff options
Diffstat (limited to 'include/net/inet_hashtables.h')
-rw-r--r-- | include/net/inet_hashtables.h | 71 |
1 files changed, 7 insertions, 64 deletions
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 37f6cb112127..761bdc01425d 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h | |||
@@ -264,37 +264,14 @@ static inline void inet_listen_unlock(struct inet_hashinfo *hashinfo) | |||
264 | wake_up(&hashinfo->lhash_wait); | 264 | wake_up(&hashinfo->lhash_wait); |
265 | } | 265 | } |
266 | 266 | ||
267 | static inline void __inet_hash(struct inet_hashinfo *hashinfo, | 267 | extern void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk); |
268 | struct sock *sk, const int listen_possible) | 268 | extern void __inet_hash_nolisten(struct inet_hashinfo *hinfo, struct sock *sk); |
269 | { | ||
270 | struct hlist_head *list; | ||
271 | rwlock_t *lock; | ||
272 | |||
273 | BUG_TRAP(sk_unhashed(sk)); | ||
274 | if (listen_possible && sk->sk_state == TCP_LISTEN) { | ||
275 | list = &hashinfo->listening_hash[inet_sk_listen_hashfn(sk)]; | ||
276 | lock = &hashinfo->lhash_lock; | ||
277 | inet_listen_wlock(hashinfo); | ||
278 | } else { | ||
279 | struct inet_ehash_bucket *head; | ||
280 | sk->sk_hash = inet_sk_ehashfn(sk); | ||
281 | head = inet_ehash_bucket(hashinfo, sk->sk_hash); | ||
282 | list = &head->chain; | ||
283 | lock = inet_ehash_lockp(hashinfo, sk->sk_hash); | ||
284 | write_lock(lock); | ||
285 | } | ||
286 | __sk_add_node(sk, list); | ||
287 | sock_prot_inc_use(sk->sk_prot); | ||
288 | write_unlock(lock); | ||
289 | if (listen_possible && sk->sk_state == TCP_LISTEN) | ||
290 | wake_up(&hashinfo->lhash_wait); | ||
291 | } | ||
292 | 269 | ||
293 | static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) | 270 | static inline void inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) |
294 | { | 271 | { |
295 | if (sk->sk_state != TCP_CLOSE) { | 272 | if (sk->sk_state != TCP_CLOSE) { |
296 | local_bh_disable(); | 273 | local_bh_disable(); |
297 | __inet_hash(hashinfo, sk, 1); | 274 | __inet_hash(hashinfo, sk); |
298 | local_bh_enable(); | 275 | local_bh_enable(); |
299 | } | 276 | } |
300 | } | 277 | } |
@@ -316,7 +293,7 @@ static inline void inet_unhash(struct inet_hashinfo *hashinfo, struct sock *sk) | |||
316 | } | 293 | } |
317 | 294 | ||
318 | if (__sk_del_node_init(sk)) | 295 | if (__sk_del_node_init(sk)) |
319 | sock_prot_dec_use(sk->sk_prot); | 296 | sock_prot_inuse_add(sk->sk_prot, -1); |
320 | write_unlock_bh(lock); | 297 | write_unlock_bh(lock); |
321 | out: | 298 | out: |
322 | if (sk->sk_state == TCP_LISTEN) | 299 | if (sk->sk_state == TCP_LISTEN) |
@@ -397,43 +374,9 @@ typedef __u64 __bitwise __addrpair; | |||
397 | * | 374 | * |
398 | * Local BH must be disabled here. | 375 | * Local BH must be disabled here. |
399 | */ | 376 | */ |
400 | static inline struct sock * | 377 | extern struct sock * __inet_lookup_established(struct inet_hashinfo *hashinfo, |
401 | __inet_lookup_established(struct inet_hashinfo *hashinfo, | 378 | const __be32 saddr, const __be16 sport, |
402 | const __be32 saddr, const __be16 sport, | 379 | const __be32 daddr, const u16 hnum, const int dif); |
403 | const __be32 daddr, const u16 hnum, | ||
404 | const int dif) | ||
405 | { | ||
406 | INET_ADDR_COOKIE(acookie, saddr, daddr) | ||
407 | const __portpair ports = INET_COMBINED_PORTS(sport, hnum); | ||
408 | struct sock *sk; | ||
409 | const struct hlist_node *node; | ||
410 | /* Optimize here for direct hit, only listening connections can | ||
411 | * have wildcards anyways. | ||
412 | */ | ||
413 | unsigned int hash = inet_ehashfn(daddr, hnum, saddr, sport); | ||
414 | struct inet_ehash_bucket *head = inet_ehash_bucket(hashinfo, hash); | ||
415 | rwlock_t *lock = inet_ehash_lockp(hashinfo, hash); | ||
416 | |||
417 | prefetch(head->chain.first); | ||
418 | read_lock(lock); | ||
419 | sk_for_each(sk, node, &head->chain) { | ||
420 | if (INET_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
421 | goto hit; /* You sunk my battleship! */ | ||
422 | } | ||
423 | |||
424 | /* Must check for a TIME_WAIT'er before going to listener hash. */ | ||
425 | sk_for_each(sk, node, &head->twchain) { | ||
426 | if (INET_TW_MATCH(sk, hash, acookie, saddr, daddr, ports, dif)) | ||
427 | goto hit; | ||
428 | } | ||
429 | sk = NULL; | ||
430 | out: | ||
431 | read_unlock(lock); | ||
432 | return sk; | ||
433 | hit: | ||
434 | sock_hold(sk); | ||
435 | goto out; | ||
436 | } | ||
437 | 380 | ||
438 | static inline struct sock * | 381 | static inline struct sock * |
439 | inet_lookup_established(struct inet_hashinfo *hashinfo, | 382 | inet_lookup_established(struct inet_hashinfo *hashinfo, |