From 9068e1a98e8d74484bc6cadc7b12944515e12191 Mon Sep 17 00:00:00 2001 From: Ruben Herold Date: Sat, 31 Oct 2026 08:21:49 +0100 Subject: ipsec: T9543: start a peer again on reset when connection-type is unset A site-to-site peer without connection-type is started at commit, because the router treats an unset value as initiate. The reset command only started a peer again when initiate was set explicitly in the configuration. After a reset such a peer was terminated and stayed down, including its VTI interface. Make initiate the default value of connection-type in the CLI definition, so every consumer sees the same value, and read the peer configuration with defaults in the reset command. A peer that is disabled, whose name starts with an at sign or whose remote address is any is not started at commit, so reset keeps skipping it instead of reporting a failed initiation. --- src/op_mode/ipsec.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py index 9cb576414..65bfce1bf 100755 --- a/src/op_mode/ipsec.py +++ b/src/op_mode/ipsec.py @@ -666,10 +666,15 @@ def reset_peer(peer: str, tunnel: typing.Optional[str] = None) -> None: """ _terminate_peer(peer, tunnel) peer_config = _get_sitetosite_peer_config(peer) - # initiate SAs only if 'connection-type=initiate' + # initiate SAs only if 'connection-type=initiate', as at commit a disabled + # peer, a peer named '@...' or without a remote address is not started + remote_address = peer_config.get('remote_address', []) if ( - 'connection_type' in peer_config - and peer_config['connection_type'] == 'initiate' + peer_config.get('connection_type') == 'initiate' + and 'disable' not in peer_config + and peer[0:1] != '@' + and remote_address + and 'any' not in remote_address ): _initiate_peer_with_childsas(peer, tunnel) @@ -1069,6 +1074,7 @@ def _get_sitetosite_peer_config(peer: str): key_mangling=('-', '_'), get_first_key=True, no_tag_node_value_mangle=True, + with_recursive_defaults=True, ) return peers_config -- cgit v1.2.3 From a55cf4670f02a14a8582669abacb4fdeb01c7a62 Mon Sep 17 00:00:00 2001 From: Christian Breunig Date: Sat, 31 Oct 2026 12:00:00 +0100 Subject: ipsec: T9543: drop checks for an unset connection-type Since connection-type defaults to initiate, it is always present in the peer configuration. The swanctl template and the reset command still handled an unset value as a separate case, which can no longer happen. Compare against the value directly instead. The reset smoketest only checked for error messages that cannot appear, because a failed reset already aborts the test. It now verifies that reset does not start a peer that is not started at commit. --- data/templates/ipsec/swanctl/peer.j2 | 6 +++--- smoketest/scripts/cli/test_vpn_ipsec.py | 3 +-- src/op_mode/ipsec.py | 7 +++---- 3 files changed, 7 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/data/templates/ipsec/swanctl/peer.j2 b/data/templates/ipsec/swanctl/peer.j2 index d0a51d81a..f38291866 100644 --- a/data/templates/ipsec/swanctl/peer.j2 +++ b/data/templates/ipsec/swanctl/peer.j2 @@ -41,7 +41,7 @@ {% if peer[0:1] == '@' %} keyingtries = 0 reauth_time = 0 -{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} +{% elif peer_conf.connection_type is vyos_defined('initiate') %} keyingtries = 0 {% if reauth and ike.key_exchange is vyos_defined('ikev2') %} reauth_time = {{ ike.lifetime }}s @@ -115,7 +115,7 @@ mode = {{ vti_esp.mode }} {% if peer[0:1] == '@' %} start_action = none -{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} +{% elif peer_conf.connection_type is vyos_defined('initiate') %} start_action = start {% elif peer_conf.connection_type is vyos_defined('trap') %} start_action = trap @@ -179,7 +179,7 @@ mode = {{ tunnel_esp.mode }} {% if peer[0:1] == '@' %} start_action = none -{% elif peer_conf.connection_type is not vyos_defined or peer_conf.connection_type is vyos_defined('initiate') %} +{% elif peer_conf.connection_type is vyos_defined('initiate') %} start_action = start {% elif peer_conf.connection_type is vyos_defined('trap') %} start_action = trap diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py index 93cb085f9..80d9c25c9 100755 --- a/smoketest/scripts/cli/test_vpn_ipsec.py +++ b/smoketest/scripts/cli/test_vpn_ipsec.py @@ -971,8 +971,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase): for name in not_started_peers: out = self.op_mode(['reset', 'vpn', 'ipsec', 'site-to-site', 'peer', name]) - self.assertNotIn('Initiation was failed', out) - self.assertNotIn('Failed to initiate', out) + self.assertNotIn('initiate result', out) def test_dmvpn(self): ike_lifetime = '3600' diff --git a/src/op_mode/ipsec.py b/src/op_mode/ipsec.py index 65bfce1bf..43f3e25d8 100755 --- a/src/op_mode/ipsec.py +++ b/src/op_mode/ipsec.py @@ -668,13 +668,12 @@ def reset_peer(peer: str, tunnel: typing.Optional[str] = None) -> None: peer_config = _get_sitetosite_peer_config(peer) # initiate SAs only if 'connection-type=initiate', as at commit a disabled # peer, a peer named '@...' or without a remote address is not started - remote_address = peer_config.get('remote_address', []) if ( - peer_config.get('connection_type') == 'initiate' + peer_config['connection_type'] == 'initiate' and 'disable' not in peer_config and peer[0:1] != '@' - and remote_address - and 'any' not in remote_address + and 'remote_address' in peer_config + and 'any' not in peer_config['remote_address'] ): _initiate_peer_with_childsas(peer, tunnel) -- cgit v1.2.3