aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c11
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