* [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 an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.