diff options
| author | Robert Navarro <crshman@gmail.com> | 2026-06-18 19:13:04 -0700 |
|---|---|---|
| committer | Robert Navarro <crshman@gmail.com> | 2026-06-23 21:49:41 -0700 |
| commit | 368b0468bf4f1eaac8e0b61d0790206048eeb79a (patch) | |
| tree | c202480d379046f19adb6736d6791f182295d3e7 /src/conf_mode | |
| parent | e0114625c08a2a9826822958f53724995580716d (diff) | |
| download | vyos-1x-368b0468bf4f1eaac8e0b61d0790206048eeb79a.tar.gz vyos-1x-368b0468bf4f1eaac8e0b61d0790206048eeb79a.zip | |
ipsec: T8975: lock vti-up-down state DB to prevent lost updates under concurrent rekey
The vti-up-down hook and vpn_ipsec.py modify a flat-file DB
(/tmp/ipsec_vti_interfaces) through three context managers that do an
unlocked read-modify-write. During a coordinated rekey, strongSwan fires
the hook for many VTIs concurrently, so the writers lost-update each
other: an interface whose up-client add is overwritten is left admin-down
while its CHILD_SA stays installed.
Serialise all DB access by reusing vyos.utils.locking.Lock. A new
_vti_updown_db_lock() context manager wraps the three public context
managers, and remove_vti_updown_db() holds the lock across both the DB
processing and the os.unlink() to close the create/delete race.
Make the helpers absence-safe under the lock so callers no longer compose
a separate existence check with a locked operation:
open_vti_updown_db_readonly() yields None when the DB does not exist and
remove_vti_updown_db() is a no-op when it is absent. Drop the
now-redundant unlocked vti_updown_db_exists() pre-checks in vti.py and
vpn_ipsec.py and handle the None yield.
Diffstat (limited to 'src/conf_mode')
| -rwxr-xr-x | src/conf_mode/vpn_ipsec.py | 6 |
1 files changed, 2 insertions, 4 deletions
diff --git a/src/conf_mode/vpn_ipsec.py b/src/conf_mode/vpn_ipsec.py index 78d5cbe83..be8eeca13 100755 --- a/src/conf_mode/vpn_ipsec.py +++ b/src/conf_mode/vpn_ipsec.py @@ -50,7 +50,6 @@ from vyos.utils.network import interface_exists from vyos.utils.dict import dict_search from vyos.utils.dict import dict_search_args from vyos.utils.process import call -from vyos.utils.vti_updown_db import vti_updown_db_exists from vyos.utils.vti_updown_db import open_vti_updown_db_for_create_or_update from vyos.utils.vti_updown_db import remove_vti_updown_db from vyos import ConfigError @@ -900,8 +899,7 @@ def apply(ipsec): systemd_service = 'strongswan.service' if not ipsec or 'deleted' in ipsec: call(f'systemctl stop {systemd_service}') - if vti_updown_db_exists(): - remove_vti_updown_db() + remove_vti_updown_db() else: call(f'systemctl reload-or-restart {systemd_service}') if ipsec['enabled_vti_interfaces']: @@ -909,7 +907,7 @@ def apply(ipsec): db.removeAllOtherInterfaces(ipsec['enabled_vti_interfaces']) db.setPersistentInterfaces(ipsec['persistent_vti_interfaces']) db.commit(lambda interface: ipsec['vti_interface_dicts'][interface]) - elif vti_updown_db_exists(): + else: remove_vti_updown_db() if ipsec: if ipsec.get('nhrp_exists', False): |
