git: 9f7c81eb337a - main - if_ovpn: deal with v4 mapped IPv6 addresses

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Fri, 01 Jul 2022 08:07:50 UTC
The branch main has been updated by kp:

URL: https://cgit.FreeBSD.org/src/commit/?id=9f7c81eb337a04f0416dee600ce7c550c33782bd

commit 9f7c81eb337a04f0416dee600ce7c550c33782bd
Author:     Kristof Provost <kp@FreeBSD.org>
AuthorDate: 2022-06-30 15:28:15 +0000
Commit:     Kristof Provost <kp@FreeBSD.org>
CommitDate: 2022-07-01 08:02:32 +0000

    if_ovpn: deal with v4 mapped IPv6 addresses
    
    Openvpn defaults to binding to IPv6 sockets (with
    setsockopt(IPV6_V6ONLY=0)), which we didn't deal with.
    That resulted in us trying to in6_selectsrc_addr() on a v4 mapped v6
    address, which does not work.
    
    Instead we translate the mapped address to v4 and treat it as an IPv4
    address.
    
    Sponsored by:   Rubicon Communications, LLC ("Netgate")
---
 sys/net/if_ovpn.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/sys/net/if_ovpn.c b/sys/net/if_ovpn.c
index 33ccea02e099..87798c974442 100644
--- a/sys/net/if_ovpn.c
+++ b/sys/net/if_ovpn.c
@@ -531,6 +531,13 @@ ovpn_new_peer(struct ifnet *ifp, const nvlist_t *nvl)
 	free(name, M_SONAME);
 	name = NULL;
 
+	if (peer->local.ss_family == AF_INET6 &&
+	    IN6_IS_ADDR_V4MAPPED(&TO_IN6(&peer->remote)->sin6_addr)) {
+		/* V4 mapped address, so treat this as v4, not v6. */
+		in6_sin6_2_sin_in_sock((struct sockaddr *)&peer->local);
+		in6_sin6_2_sin_in_sock((struct sockaddr *)&peer->remote);
+	}
+
 #ifdef INET6
 	if (peer->local.ss_family == AF_INET6 &&
 	    IN6_IS_ADDR_UNSPECIFIED(&TO_IN6(&peer->local)->sin6_addr)) {