diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index eaad72c3d746..4c60c6f71cd3 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -148,8 +148,13 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
148 | * connect() to INADDR_ANY means loopback (BSD'ism). | 148 | * connect() to INADDR_ANY means loopback (BSD'ism). |
149 | */ | 149 | */ |
150 | 150 | ||
151 | if (ipv6_addr_any(&usin->sin6_addr)) | 151 | if (ipv6_addr_any(&usin->sin6_addr)) { |
152 | usin->sin6_addr.s6_addr[15] = 0x1; | 152 | if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)) |
153 | ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), | ||
154 | &usin->sin6_addr); | ||
155 | else | ||
156 | usin->sin6_addr = in6addr_loopback; | ||
157 | } | ||
153 | 158 | ||
154 | addr_type = ipv6_addr_type(&usin->sin6_addr); | 159 | addr_type = ipv6_addr_type(&usin->sin6_addr); |
155 | 160 | ||
@@ -188,7 +193,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
188 | * TCP over IPv4 | 193 | * TCP over IPv4 |
189 | */ | 194 | */ |
190 | 195 | ||
191 | if (addr_type == IPV6_ADDR_MAPPED) { | 196 | if (addr_type & IPV6_ADDR_MAPPED) { |
192 | u32 exthdrlen = icsk->icsk_ext_hdr_len; | 197 | u32 exthdrlen = icsk->icsk_ext_hdr_len; |
193 | struct sockaddr_in sin; | 198 | struct sockaddr_in sin; |
194 | 199 | ||