The regex for loaded connections is matching on \d as a first symbol, expecting an IP address. But that doesn't work for IPv6 addresses as there are likely hex symbols and not just digits. This is causing ovs-monitor-ipsec daemon to periodically remove established IPv6 connections thinking they are not properly loaded:
851 | INFO | ovn-e629de-0-in-1 is half-loaded, removing 853 | INFO | ovn-e629de-0-out-1 is half-loaded, removing 855 | INFO | Adding ipsec connection ovn-e629de-0-in-1 857 | INFO | Starting ipsec connection ovn-e629de-0-out-1 Fix the regex to include all the hex characters. This is still not great that we rely on string parsing for this, but there is currently no better interface. Fixes: 25a301822e0d ("ipsec: libreswan: Reconcile missing connections periodically.") Reported-at: https://issues.redhat.com/browse/FDP-1328 Signed-off-by: Ilya Maximets <i.maxim...@ovn.org> --- ipsec/ovs-monitor-ipsec.in | 3 +- tests/system-ipsec.at | 137 +++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 1 deletion(-) diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in index f451fb84a..7309bdf3c 100755 --- a/ipsec/ovs-monitor-ipsec.in +++ b/ipsec/ovs-monitor-ipsec.in @@ -789,7 +789,8 @@ conn prevent_unencrypted_vxlan return self.get_conns_from_status(r"#\d+: .*\"(.*)\".*") def get_loaded_conns(self): - return self.get_conns_from_status(r"\"(.*)\": \d+.*(===|\.\.\.).*") + return self.get_conns_from_status( + r"\"(.*)\": [0-9a-f]+.*(===|\.\.\.).*") def get_conn_names(self, monitor, ifname): conns = [] diff --git a/tests/system-ipsec.at b/tests/system-ipsec.at index 298b14feb..de3ecd361 100644 --- a/tests/system-ipsec.at +++ b/tests/system-ipsec.at @@ -132,6 +132,15 @@ m4_define([CHECK_LIBRESWAN], dnl https://github.com/libreswan/libreswan/issues/428 AT_SKIP_IF([test "${#ovs_base}" -gt "90" ])]) +dnl IPSEC_SA_LIST([namespace], [output-file]) +dnl +dnl Get numbers of all the currently active SAs. +m4_define([IPSEC_SA_LIST], [ + AT_CHECK([ipsec --rundir $ovs_base/$1 status > $2.status]) + AT_CHECK([grep -oE '#[0-9]+:' $2.status | sort -u], [0], [stdout]) + AT_CHECK([mv stdout $2]) +]) + dnl IPSEC_STATUS_LOADED([]) dnl dnl Get number of loaded connections from ipsec status @@ -526,6 +535,134 @@ AT_CHECK([grep -q -E "(ike|ikev2|esp)=" $ovs_base/right/custom.conf], [1]) OVS_TRAFFIC_VSWITCHD_STOP() AT_CLEANUP +AT_SETUP([IPsec -- Libreswan - established conns survive new additions - ipv4]) +AT_KEYWORDS([ipsec libreswan ipv4 geneve psk persistence]) +dnl Note: Geneve test may not work on older kernels due to CVE-2020-25645 +dnl https://bugzilla.redhat.com/show_bug.cgi?id=1883988 + +CHECK_LIBRESWAN() +OVS_TRAFFIC_VSWITCHD_START() +IPSEC_SETUP_UNDERLAY() + +dnl Set up hosts. +IPSEC_ADD_NODE_LEFT([10.1.1.1], [10.1.1.254]) +IPSEC_ADD_NODE_RIGHT([10.1.1.2], [10.1.1.254]) + +m4_define([PSK_OPTIONS], [options:remote_ip=$1 options:psk=swordfish]) + +dnl Set up IPsec tunnel on a 'left' host. +IPSEC_ADD_TUNNEL_LEFT([geneve], PSK_OPTIONS([10.1.1.2])) +dnl Set up IPsec tunnel on a 'right' host. +IPSEC_ADD_TUNNEL_RIGHT([geneve], PSK_OPTIONS([10.1.1.1])) + +CHECK_ESP_TRAFFIC + +dnl Get the numbers of all the current SAs. +IPSEC_SA_LIST([left], [left/sa.before]) +IPSEC_SA_LIST([right], [right/sa.before]) + +dnl Add a third host and wire it up only to the left to avoid creating a loop. +IPSEC_ADD_NODE([third], [p3], [10.1.1.3], [10.1.1.254]) +IPSEC_ADD_TUNNEL([third], [geneve], PSK_OPTIONS([10.1.1.1])) +OVS_VSCTL([left], add-port br-ipsec tun3 \ + -- set Interface tun3 type=geneve PSK_OPTIONS([10.1.1.3])) +dnl Wait for all the expected connections to be loaded into Libreswan. +dnl 2 tunnels == 4 connections. +OVS_WAIT_UNTIL([test $(IPSEC_STATUS_LOADED(left)) -eq 4]) + +dnl Wait for tunnels to become active. +OVS_WAIT_UNTIL([test $(IPSEC_STATUS_LOADED(left)) \ + -eq $(IPSEC_STATUS_ACTIVE(left))]) +OVS_WAIT_UNTIL([test $(IPSEC_STATUS_LOADED(third)) \ + -eq $(IPSEC_STATUS_ACTIVE(third))]) + +dnl Check that the original left-right tunnel still works. +NS_CHECK_EXEC([left], [ping -q -c 3 -i 0.1 -W 2 192.0.0.2 | FORMAT_PING], [0], + [3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) +NS_CHECK_EXEC([right], [ping -q -c 3 -i 0.1 -W 2 192.0.0.1 | FORMAT_PING], [0], + [3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) + +dnl Check that ovs-monitor-ipsec didn't touch the original tunnel. +IPSEC_SA_LIST([left], [left/sa.after]) +IPSEC_SA_LIST([right], [right/sa.after]) + +dnl Right SAs should not change at all. +AT_CHECK([diff -u right/sa.before right/sa.after]) + +dnl Left SAs should be the same, but there will be new ones for the third conn. +AT_CHECK([test $(grep -c ':' left/sa.after) -gt $(grep -c ':' left/sa.before)]) +AT_CHECK([head -n $(grep -c ':' left/sa.before) left/sa.after \ + | diff -u - left/sa.before]) + +OVS_TRAFFIC_VSWITCHD_STOP() +AT_CLEANUP + +AT_SETUP([IPsec -- Libreswan - established conns survive new additions - ipv6]) +AT_KEYWORDS([ipsec libreswan ipv6 geneve psk persistence]) +dnl Note: Geneve test may not work on older kernels due to CVE-2020-25645 +dnl https://bugzilla.redhat.com/show_bug.cgi?id=1883988 + +CHECK_LIBRESWAN() +OVS_TRAFFIC_VSWITCHD_START() +IPSEC_SETUP_UNDERLAY() + +dnl Set up hosts. +IPSEC_ADD_NODE_LEFT([fd01::101], [fd01::254]) +IPSEC_ADD_NODE_RIGHT([fd01::102], [fd01::254]) + +m4_define([PSK_OPTIONS], [options:remote_ip=$1 options:psk=swordfish]) + +dnl Set up IPsec tunnel on a 'left' host. +IPSEC_ADD_TUNNEL_LEFT([geneve], PSK_OPTIONS([fd01::102])) +dnl Set up IPsec tunnel on a 'right' host. +IPSEC_ADD_TUNNEL_RIGHT([geneve], PSK_OPTIONS([fd01::101])) + +CHECK_ESP_TRAFFIC + +dnl Get the numbers of all the current SAs. +IPSEC_SA_LIST([left], [left/sa.before]) +IPSEC_SA_LIST([right], [right/sa.before]) + +dnl Add a third host and wire it up only to the left to avoid creating a loop. +IPSEC_ADD_NODE([third], [p3], [fd01::103], [fd01::254]) +IPSEC_ADD_TUNNEL([third], [geneve], PSK_OPTIONS([fd01::101])) +OVS_VSCTL([left], add-port br-ipsec tun3 \ + -- set Interface tun3 type=geneve PSK_OPTIONS([fd01::103])) +dnl Wait for all the expected connections to be loaded into Libreswan. +dnl 2 tunnels == 4 connections. +OVS_WAIT_UNTIL([test `IPSEC_STATUS_LOADED(left)` -eq 4]) + +dnl Wait for tunnels to become active. +OVS_WAIT_UNTIL([test $(IPSEC_STATUS_LOADED(left)) \ + -eq $(IPSEC_STATUS_ACTIVE(left))]) +OVS_WAIT_UNTIL([test $(IPSEC_STATUS_LOADED(third)) \ + -eq $(IPSEC_STATUS_ACTIVE(third))]) + +dnl Check that the original left-right tunnel still works. +NS_CHECK_EXEC([left], [ping -q -c 3 -i 0.1 -W 2 192.0.0.2 | FORMAT_PING], [0], + [3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) +NS_CHECK_EXEC([right], [ping -q -c 3 -i 0.1 -W 2 192.0.0.1 | FORMAT_PING], [0], + [3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) + +dnl Check that ovs-monitor-ipsec didn't touch the original tunnel. +IPSEC_SA_LIST([left], [left/sa.after]) +IPSEC_SA_LIST([right], [right/sa.after]) + +dnl Right SAs should not change at all. +AT_CHECK([diff -u right/sa.before right/sa.after]) + +dnl Left SAs should be the same, but there will be new ones for the third conn. +AT_CHECK([test $(grep -c ':' left/sa.after) -gt $(grep -c ':' left/sa.before)]) +AT_CHECK([head -n $(grep -c ':' left/sa.before) left/sa.after \ + | diff -u - left/sa.before]) + +OVS_TRAFFIC_VSWITCHD_STOP() +AT_CLEANUP + AT_SETUP([IPsec -- Libreswan NxN geneve tunnels + reconciliation]) AT_KEYWORDS([ipsec libreswan scale reconciliation]) dnl Note: Geneve test may not work on older kernels due to CVE-2020-25645 -- 2.49.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev