[ovs-dev] [PATCH 3/4] ipsec: IPv6 default route support for Libreswan
Mark Gray
mark.d.gray at redhat.com
Mon Mar 8 17:57:35 UTC 2021
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.
Signed-off-by: Mark Gray <mark.d.gray at redhat.com>
---
ipsec/ovs-monitor-ipsec.in | 54 +++++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in
index 9f412aaaf25a..b8cfb0a8ae79 100755
--- a/ipsec/ovs-monitor-ipsec.in
+++ b/ipsec/ovs-monitor-ipsec.in
@@ -14,10 +14,11 @@
# limitations under the License.
import argparse
+import copy
+import ipaddress
import re
import subprocess
import sys
-import copy
import os
from string import Template
@@ -413,6 +414,11 @@ conn prevent_unencrypted_vxlan
leftprotoport=udp/4789
mark={0}
+"""
+
+ IPV6_CONN = """\
+ hostaddrfamily=ipv6
+ clientaddrfamily=ipv6
"""
auth_tmpl = {"psk": Template("""\
@@ -528,6 +534,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
@@ -795,6 +804,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
@@ -836,6 +846,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"],
@@ -904,6 +917,24 @@ 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 == "IPv4" and remote == "IPv4":
+ return "IPv4"
+ elif local == "IPv6" and remote == "IPv6":
+ return "IPv6"
+ elif remote == "IPv4" and local_ip is None:
+ return "IPv4"
+ elif remote == "IPv6" and local_ip is None:
+ return "IPv6"
+ elif remote != local:
+ # remote family and local family are mismatched
+ return None
+ else:
+ return None
+
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,
@@ -1160,6 +1191,27 @@ class IPsecMonitor(object):
return m.group(1)
+def is_ipv4(address):
+ try:
+ ipaddress.IPv4Address(address)
+ except ipaddress.AddressValueError:
+ return False
+ return True
+
+def is_ipv6(address):
+ try:
+ ipaddress.IPv6Address(address)
+ except ipaddress.AddressValueError:
+ return False
+ return True
+
+def address_family(address):
+ if is_ipv4(address):
+ return "IPv4"
+ elif is_ipv6(address):
+ return "IPv6"
+ else:
+ return None
def unixctl_xfrm_policies(conn, unused_argv, unused_aux):
global xfrm
--
2.27.0
More information about the dev
mailing list