* [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.