diff options
author | Mark Gray <mark.d.gray@redhat.com> | 2021-04-01 09:58:24 -0400 |
---|---|---|
committer | Ilya Maximets <i.maximets@ovn.org> | 2021-04-01 19:12:52 +0200 |
commit | 58b4146e0baab4780ac77d80dd066ce6caffd586 (patch) | |
tree | fc4adda39a947f8a66943e1dfd718e5b95b641d9 /ipsec | |
parent | ac85cdb38c1f33e7952bc4c0347d6c7873fb56a1 (diff) | |
download | openvswitch-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-x | ipsec/ovs-monitor-ipsec.in | 37 |
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() |