diff options
Diffstat (limited to 'net/ipv6/datagram.c')
-rw-r--r-- | net/ipv6/datagram.c | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index cf2dfb222230..56528e9f3e01 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -76,18 +76,22 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a | |||
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | addr_type = ipv6_addr_type(&usin->sin6_addr); | 79 | if (ipv6_addr_any(&usin->sin6_addr)) { |
80 | |||
81 | if (addr_type == IPV6_ADDR_ANY) { | ||
82 | /* | 80 | /* |
83 | * connect to self | 81 | * connect to self |
84 | */ | 82 | */ |
85 | usin->sin6_addr.s6_addr[15] = 0x01; | 83 | if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)) |
84 | ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK), | ||
85 | &usin->sin6_addr); | ||
86 | else | ||
87 | usin->sin6_addr = in6addr_loopback; | ||
86 | } | 88 | } |
87 | 89 | ||
90 | addr_type = ipv6_addr_type(&usin->sin6_addr); | ||
91 | |||
88 | daddr = &usin->sin6_addr; | 92 | daddr = &usin->sin6_addr; |
89 | 93 | ||
90 | if (addr_type == IPV6_ADDR_MAPPED) { | 94 | if (addr_type & IPV6_ADDR_MAPPED) { |
91 | struct sockaddr_in sin; | 95 | struct sockaddr_in sin; |
92 | 96 | ||
93 | if (__ipv6_only_sock(sk)) { | 97 | if (__ipv6_only_sock(sk)) { |