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

Eelco Chaudron echaudro at redhat.com
Tue Mar 30 11:02:26 UTC 2021



On 8 Mar 2021, at 18:57, Mark Gray wrote:

> 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

If you move copy into alphabetical order, you might as well move 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:

I would remove the above 4 lines and just return None below for all the 
error cases.

> +            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
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev



More information about the dev mailing list