[ovs-dev] [PATCH v2 3/5] ipsec: IPv6 default route support for Libreswan

Mark Gray mark.d.gray at redhat.com
Wed Mar 31 08:05:07 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>
---
v2: refactor address family parsing
 ipsec/ovs-monitor-ipsec.in | 35 +++++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in
index 802f57641cdc..20ab213cc8d4 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
@@ -413,6 +414,11 @@ conn prevent_unencrypted_vxlan
     leftprotoport=udp/4789
     mark={0}
 
+"""
+
+    IPV6_CONN = """\
+    hostaddrfamily=ipv6
+    clientaddrfamily=ipv6
 """
 
     auth_tmpl = {"psk": Template("""\
@@ -534,6 +540,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
@@ -801,6 +810,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
@@ -842,6 +852,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"],
@@ -910,6 +923,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,
@@ -1165,6 +1189,17 @@ class IPsecMonitor(object):
         return m.group(1)
 
 
+def address_family(address):
+    try:
+        ip = ipaddress.ip_address(address)
+        ipstr = str(type(ip))
+    except ValueError:
+        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()
-- 
2.27.0



More information about the dev mailing list