summaryrefslogtreecommitdiff
path: root/ipsec
diff options
context:
space:
mode:
authorMark Gray <mark.d.gray@redhat.com>2021-04-01 09:58:24 -0400
committerIlya Maximets <i.maximets@ovn.org>2021-04-01 19:12:52 +0200
commit58b4146e0baab4780ac77d80dd066ce6caffd586 (patch)
treefc4adda39a947f8a66943e1dfd718e5b95b641d9 /ipsec
parentac85cdb38c1f33e7952bc4c0347d6c7873fb56a1 (diff)
downloadopenvswitch-58b4146e0baab4780ac77d80dd066ce6caffd586.tar.gz
ipsec: Fix IPv6 default route support for Libreswan.
When configuring IPsec, "ovs-monitor-ipsec" honours the 'local_ip' option in the 'Interface' table by configuring the 'left' side of the Libreswan connection with 'local_ip'. If 'local_ip' is not specified, "ovs-monitor-ipsec" sets 'left' to '%defaultroute' which is interpreted as the IP address of the default gateway interface. However, when 'remote_ip' is an IPv6 address, Libreswan still interprets '%defaultroute' as the IPv4 address on the default gateway interface (see: https://github.com/libreswan/libreswan/issues/416) giving an "address family inconsistency" error. This patch resolves this issue by specifying the connection as IPv6 when the 'remote_ip' is IPv6 and 'local_ip' has not been set. Fixes: 22c5eafb6efa ("ipsec: reintroduce IPsec support for tunneling") Signed-off-by: Mark Gray <mark.d.gray@redhat.com> Acked-by: Flavio Leitner <fbl@sysclose.org> Acked-by: Aaron Conole <aconole@redhat.com> Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Diffstat (limited to 'ipsec')
-rwxr-xr-xipsec/ovs-monitor-ipsec.in37
1 files changed, 37 insertions, 0 deletions
diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in
index 64111768b..668507fd3 100755
--- a/ipsec/ovs-monitor-ipsec.in
+++ b/ipsec/ovs-monitor-ipsec.in
@@ -14,6 +14,7 @@
# limitations under the License.
import argparse
+import ipaddress
import re
import subprocess
import sys
@@ -415,6 +416,11 @@ conn prevent_unencrypted_vxlan
"""
+ IPV6_CONN = """\
+ hostaddrfamily=ipv6
+ clientaddrfamily=ipv6
+"""
+
auth_tmpl = {"psk": Template("""\
left=$local_ip
right=$remote_ip
@@ -520,6 +526,9 @@ conn prevent_unencrypted_vxlan
else:
auth_section = self.auth_tmpl["pki_ca"].substitute(tunnel.conf)
+ if tunnel.conf["address_family"] == "IPv6":
+ auth_section = self.IPV6_CONN + auth_section
+
vals = tunnel.conf.copy()
vals["auth_section"] = auth_section
vals["version"] = tunnel.version
@@ -756,6 +765,7 @@ class IPsecTunnel(object):
Tunnel Type: $tunnel_type
Local IP: $local_ip
Remote IP: $remote_ip
+ Address Family: $address_family
SKB mark: $skb_mark
Local cert: $certificate
Local name: $local_name
@@ -797,6 +807,9 @@ class IPsecTunnel(object):
"tunnel_type": row.type,
"local_ip": options.get("local_ip", "%defaultroute"),
"remote_ip": options.get("remote_ip"),
+ "address_family": self._get_conn_address_family(
+ options.get("remote_ip"),
+ options.get("local_ip")),
"skb_mark": monitor.conf["skb_mark"],
"certificate": monitor.conf["pki"]["certificate"],
"private_key": monitor.conf["pki"]["private_key"],
@@ -865,6 +878,17 @@ class IPsecTunnel(object):
return header + conf + status + spds + sas + cons + "\n"
+ def _get_conn_address_family(self, remote_ip, local_ip):
+ remote = address_family(remote_ip)
+ local = address_family(local_ip)
+
+ if local is None:
+ return remote
+ elif local != remote:
+ return None
+ else:
+ return remote
+
def _is_valid_tunnel_conf(self):
"""This function verifies if IPsec tunnel has valid configuration
set in 'conf'. If it is valid, then it returns True. Otherwise,
@@ -1120,6 +1144,19 @@ class IPsecMonitor(object):
return m.group(1)
+def address_family(address):
+ try:
+ ip = ipaddress.ip_address(address)
+ ipstr = str(type(ip))
+ # ipaddress has inconsistencies with what exceptions are raised:
+ # https://mail.openvswitch.org/pipermail/ovs-dev/2021-April/381696.html
+ except (ValueError, ipaddress.AddressValueError):
+ return None
+ if ipstr.find('v6') != -1:
+ return "IPv6"
+ return "IPv4"
+
+
def unixctl_xfrm_policies(conn, unused_argv, unused_aux):
global xfrm
policies = xfrm.get_policies()