* [PATCH 0/2] IPv4-mapped on wire, :: dst address issue
@ 2017-02-12 22:26 Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Jonathan T. Leighton @ 2017-02-12 22:26 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] 4+ messages in thread
* [PATCH 1/2] ipv6: Inhibit IPv4-mapped src address on the wire.
2017-02-12 22:26 [PATCH 0/2] IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton
@ 2017-02-12 22:26 ` Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton
2017-02-14 17:14 ` [PATCH 0/2] IPv4-mapped on wire, :: dst address issue David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Jonathan T. Leighton @ 2017-02-12 22:26 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 a75871c..d0f51b4 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1022,6 +1022,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] 4+ messages in thread
* [PATCH 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst.
2017-02-12 22:26 [PATCH 0/2] IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton
@ 2017-02-12 22:26 ` Jonathan T. Leighton
2017-02-14 17:14 ` [PATCH 0/2] IPv4-mapped on wire, :: dst address issue David Miller
2 siblings, 0 replies; 4+ messages in thread
From: Jonathan T. Leighton @ 2017-02-12 22:26 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..eec27f8 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(htonl(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 b5d2721..21c7199 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(htonl(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 df71ba0..4e4c401 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1046,6 +1046,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(htonl(INADDR_LOOPBACK),
+ daddr);
break;
case AF_INET:
goto do_udp_sendmsg;
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] IPv4-mapped on wire, :: dst address issue
2017-02-12 22:26 [PATCH 0/2] IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton
@ 2017-02-14 17:14 ` David Miller
2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2017-02-14 17:14 UTC (permalink / raw)
To: jtleight; +Cc: netdev
From: "Jonathan T. Leighton" <jtleight@udel.edu>
Date: Sun, 12 Feb 2017 17:26:05 -0500
> 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.
Series applied, thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-02-14 17:14 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-12 22:26 [PATCH 0/2] IPv4-mapped on wire, :: dst address issue Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 1/2] ipv6: Inhibit IPv4-mapped src address on the wire Jonathan T. Leighton
2017-02-12 22:26 ` [PATCH 2/2] ipv6: Handle IPv4-mapped src to in6addr_any dst Jonathan T. Leighton
2017-02-14 17:14 ` [PATCH 0/2] IPv4-mapped on wire, :: dst address issue David Miller
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.