|
@@ -148,8 +148,13 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
|
|
* connect() to INADDR_ANY means loopback (BSD'ism).
|
|
|
*/
|
|
|
|
|
|
- if (ipv6_addr_any(&usin->sin6_addr))
|
|
|
- usin->sin6_addr.s6_addr[15] = 0x1;
|
|
|
+ if (ipv6_addr_any(&usin->sin6_addr)) {
|
|
|
+ if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
|
|
|
+ ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
|
|
|
+ &usin->sin6_addr);
|
|
|
+ else
|
|
|
+ usin->sin6_addr = in6addr_loopback;
|
|
|
+ }
|
|
|
|
|
|
addr_type = ipv6_addr_type(&usin->sin6_addr);
|
|
|
|
|
@@ -188,7 +193,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
|
|
* TCP over IPv4
|
|
|
*/
|
|
|
|
|
|
- if (addr_type == IPV6_ADDR_MAPPED) {
|
|
|
+ if (addr_type & IPV6_ADDR_MAPPED) {
|
|
|
u32 exthdrlen = icsk->icsk_ext_hdr_len;
|
|
|
struct sockaddr_in sin;
|
|
|
|