diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/inet_hashtables.c | 32 |
1 files changed, 21 insertions, 11 deletions
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 619c63c6948a..b93d40ff6ef4 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -348,11 +348,11 @@ void __inet_hash(struct inet_hashinfo *hashinfo, struct sock *sk) | |||
348 | } | 348 | } |
349 | EXPORT_SYMBOL_GPL(__inet_hash); | 349 | EXPORT_SYMBOL_GPL(__inet_hash); |
350 | 350 | ||
351 | /* | 351 | int __inet_hash_connect(struct inet_timewait_death_row *death_row, |
352 | * Bind a port for a connect operation and hash it. | 352 | struct sock *sk, |
353 | */ | 353 | int (*check_established)(struct inet_timewait_death_row *, |
354 | int inet_hash_connect(struct inet_timewait_death_row *death_row, | 354 | struct sock *, __u16, struct inet_timewait_sock **), |
355 | struct sock *sk) | 355 | void (*hash)(struct inet_hashinfo *, struct sock *)) |
356 | { | 356 | { |
357 | struct inet_hashinfo *hinfo = death_row->hashinfo; | 357 | struct inet_hashinfo *hinfo = death_row->hashinfo; |
358 | const unsigned short snum = inet_sk(sk)->num; | 358 | const unsigned short snum = inet_sk(sk)->num; |
@@ -385,9 +385,8 @@ int inet_hash_connect(struct inet_timewait_death_row *death_row, | |||
385 | BUG_TRAP(!hlist_empty(&tb->owners)); | 385 | BUG_TRAP(!hlist_empty(&tb->owners)); |
386 | if (tb->fastreuse >= 0) | 386 | if (tb->fastreuse >= 0) |
387 | goto next_port; | 387 | goto next_port; |
388 | if (!__inet_check_established(death_row, | 388 | if (!check_established(death_row, sk, |
389 | sk, port, | 389 | port, &tw)) |
390 | &tw)) | ||
391 | goto ok; | 390 | goto ok; |
392 | goto next_port; | 391 | goto next_port; |
393 | } | 392 | } |
@@ -415,7 +414,7 @@ ok: | |||
415 | inet_bind_hash(sk, tb, port); | 414 | inet_bind_hash(sk, tb, port); |
416 | if (sk_unhashed(sk)) { | 415 | if (sk_unhashed(sk)) { |
417 | inet_sk(sk)->sport = htons(port); | 416 | inet_sk(sk)->sport = htons(port); |
418 | __inet_hash_nolisten(hinfo, sk); | 417 | hash(hinfo, sk); |
419 | } | 418 | } |
420 | spin_unlock(&head->lock); | 419 | spin_unlock(&head->lock); |
421 | 420 | ||
@@ -432,17 +431,28 @@ ok: | |||
432 | tb = inet_csk(sk)->icsk_bind_hash; | 431 | tb = inet_csk(sk)->icsk_bind_hash; |
433 | spin_lock_bh(&head->lock); | 432 | spin_lock_bh(&head->lock); |
434 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { | 433 | if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) { |
435 | __inet_hash_nolisten(hinfo, sk); | 434 | hash(hinfo, sk); |
436 | spin_unlock_bh(&head->lock); | 435 | spin_unlock_bh(&head->lock); |
437 | return 0; | 436 | return 0; |
438 | } else { | 437 | } else { |
439 | spin_unlock(&head->lock); | 438 | spin_unlock(&head->lock); |
440 | /* No definite answer... Walk to established hash table */ | 439 | /* No definite answer... Walk to established hash table */ |
441 | ret = __inet_check_established(death_row, sk, snum, NULL); | 440 | ret = check_established(death_row, sk, snum, NULL); |
442 | out: | 441 | out: |
443 | local_bh_enable(); | 442 | local_bh_enable(); |
444 | return ret; | 443 | return ret; |
445 | } | 444 | } |
446 | } | 445 | } |
446 | EXPORT_SYMBOL_GPL(__inet_hash_connect); | ||
447 | |||
448 | /* | ||
449 | * Bind a port for a connect operation and hash it. | ||
450 | */ | ||
451 | int inet_hash_connect(struct inet_timewait_death_row *death_row, | ||
452 | struct sock *sk) | ||
453 | { | ||
454 | return __inet_hash_connect(death_row, sk, | ||
455 | __inet_check_established, __inet_hash_nolisten); | ||
456 | } | ||
447 | 457 | ||
448 | EXPORT_SYMBOL_GPL(inet_hash_connect); | 458 | EXPORT_SYMBOL_GPL(inet_hash_connect); |