* [PATCH RFC 0/2] ipv6: IPv4-mapped on wire, :: dst address issue @ 2017-02-02 18:27 Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton 0 siblings, 2 replies; 3+ messages in thread From: Jonathan T. Leighton @ 2017-02-02 18:27 UTC (permalink / raw) To: netdev; +Cc: Jonathan T. Leighton Under some circumstances IPv6 datagrams are sent with IPv4-mapped IPv6 addresses as the source. Given an IPv6 socket bound to an IPv4-mapped IPv6 address, and an IPv6 destination address, both TCP and UDP will will send packets using the IPv4-mapped IPv6 address as the source. Per RFC 6890 (Table 20), IPv4-mapped IPv6 source addresses are not allowed in an IP datagram. The problem can be observed by attempting to connect() either a TCP or UDP socket, or by using sendmsg() with a UDP socket. The patch is intended to correct this issue for all socket types. linux follows the BSD convention that an IPv6 destination address specified as in6addr_any is converted to the loopback address. Currently, neither TCP nor UDP consider the possibility that the source address is an IPv4-mapped IPv6 address, and assume that the appropriate loopback address is ::1. The patch adds a check on whether or not the source address is an IPv4-mapped IPv6 address and then sets the destination address to either ::ffff:127.0.0.1 or ::1, as appropriate. Jon Jonathan T. Leighton (2): ipv6: Inhibit IPv4-mapped src address on the wire. ipv6: Handle IPv4-mapped src to in6addr_any dst. net/ipv6/datagram.c | 14 +++++++++----- net/ipv6/ip6_output.c | 3 +++ net/ipv6/tcp_ipv6.c | 11 ++++++++--- net/ipv6/udp.c | 4 ++++ 4 files changed, 24 insertions(+), 8 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH RFC 1/2] ipv6: Inhibit IPv4-mapped src address on the wire. 2017-02-02 18:27 [PATCH RFC 0/2] ipv6: IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton @ 2017-02-02 18:27 ` Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton 1 sibling, 0 replies; 3+ messages in thread From: Jonathan T. Leighton @ 2017-02-02 18:27 UTC (permalink / raw) To: netdev; +Cc: Jonathan T. Leighton This patch adds a check for the problematic case of an IPv4-mapped IPv6 source address and a destination address that is neither an IPv4-mapped IPv6 address nor in6addr_any, and returns an appropriate error. The check in done before returning from looking up the route. Signed-off-by: Jonathan T. Leighton <jtleight@udel.edu> --- net/ipv6/ip6_output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 38122d0..7969c1e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -1021,6 +1021,9 @@ static int ip6_dst_lookup_tail(struct net *net, const struct sock *sk, } } #endif + if (ipv6_addr_v4mapped(&fl6->saddr) && + !(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr))) + return -EAFNOSUPPORT; return 0; -- 2.7.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH RFC 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst. 2017-02-02 18:27 [PATCH RFC 0/2] ipv6: IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton @ 2017-02-02 18:27 ` Jonathan T. Leighton 1 sibling, 0 replies; 3+ messages in thread From: Jonathan T. Leighton @ 2017-02-02 18:27 UTC (permalink / raw) To: netdev; +Cc: Jonathan T. Leighton This patch adds a check on the type of the source address, for the case where the destination address is in6addr_any. If the source is an IPv4-mapped IPv6 source address, the destination is changed to ::ffff:127.0.0.1, and otherwise the destination is changed to ::1. This is done in three locations to handle UDP calls to either connect() or sendmsg(), and TCP calls to connect(). Note that udpv6_sendmsg() delays handling an in6addr_any destination until very late, so the patch only needs to handle the case where the source is an IPv4-mapped IPv6 address. Signed-off-by: Jonathan T. Leighton <jtleight@udel.edu> --- net/ipv6/datagram.c | 14 +++++++++----- net/ipv6/tcp_ipv6.c | 11 ++++++++--- net/ipv6/udp.c | 4 ++++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index a3eaafd..678a84e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -167,18 +167,22 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, if (np->sndflow) fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; - addr_type = ipv6_addr_type(&usin->sin6_addr); - - if (addr_type == IPV6_ADDR_ANY) { + if (ipv6_addr_any(&usin->sin6_addr)) { /* * connect to self */ - usin->sin6_addr.s6_addr[15] = 0x01; + if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr)) + ipv6_addr_set_v4mapped(ntohl(INADDR_LOOPBACK), + &usin->sin6_addr); + else + usin->sin6_addr = in6addr_loopback; } + addr_type = ipv6_addr_type(&usin->sin6_addr); + daddr = &usin->sin6_addr; - if (addr_type == IPV6_ADDR_MAPPED) { + if (addr_type & IPV6_ADDR_MAPPED) { struct sockaddr_in sin; if (__ipv6_only_sock(sk)) { diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 228965d..9e91da4 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -149,8 +149,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(ntohl(INADDR_LOOPBACK), + &usin->sin6_addr); + else + usin->sin6_addr = in6addr_loopback; + } addr_type = ipv6_addr_type(&usin->sin6_addr); @@ -189,7 +194,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; diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 4d5c4ee..bbdf7de 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -1033,6 +1033,10 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) if (addr_len < SIN6_LEN_RFC2133) return -EINVAL; daddr = &sin6->sin6_addr; + if (ipv6_addr_any(daddr) && + ipv6_addr_v4mapped(&np->saddr)) + ipv6_addr_set_v4mapped(ntohl(INADDR_LOOPBACK), + daddr); break; case AF_INET: goto do_udp_sendmsg; -- 2.7.4 ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2017-02-02 18:28 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2017-02-02 18:27 [PATCH RFC 0/2] ipv6: IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton 2017-02-02 18:27 ` [PATCH RFC 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).