summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/tcp_ipv6.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index f47b4a103..b0e8ee714 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -5,7 +5,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: tcp_ipv6.c,v 1.120 2000/02/27 19:51:49 davem Exp $
+ * $Id: tcp_ipv6.c,v 1.121 2000/03/08 19:36:47 davem Exp $
*
* Based on:
* linux/net/ipv4/tcp.c
@@ -132,7 +132,7 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
break;
}
if (tb != NULL && tb->owners != NULL) {
- if (tb->fastreuse != 0 && sk->reuse != 0) {
+ if (tb->fastreuse != 0 && sk->reuse != 0 && sk->state != TCP_LISTEN) {
goto success;
} else {
struct sock *sk2 = tb->owners;
@@ -141,7 +141,8 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
/* We must walk the whole port owner list in this case. -DaveM */
for( ; sk2 != NULL; sk2 = sk2->bind_next) {
- if (sk->bound_dev_if == sk2->bound_dev_if) {
+ if (sk != sk2 &&
+ sk->bound_dev_if == sk2->bound_dev_if) {
if (!sk_reuse ||
!sk2->reuse ||
sk2->state == TCP_LISTEN) {
@@ -177,11 +178,15 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
success:
sk->num = snum;
- if ((sk->bind_next = tb->owners) != NULL)
- tb->owners->bind_pprev = &sk->bind_next;
- tb->owners = sk;
- sk->bind_pprev = &tb->owners;
- sk->prev = (struct sock *) tb;
+ if (sk->prev == NULL) {
+ if ((sk->bind_next = tb->owners) != NULL)
+ tb->owners->bind_pprev = &sk->bind_next;
+ tb->owners = sk;
+ sk->bind_pprev = &tb->owners;
+ sk->prev = (struct sock *) tb;
+ } else {
+ BUG_TRAP(sk->prev == (struct sock *) tb);
+ }
ret = 0;
fail_unlock: