IPsec vti-up-down: DB keyed only by connection name causes admin-down of a VTI still carried by a live IKE_SA
When two IKE_SAs for the same connection exist briefly — which happens whenever a peer re-establishes a tunnel before the local side finishes timing out the old one via DPD — vti_updown_db.py can't tell them apart. Its key is {interface}:{connection}:{protocol}, with no SA identifier, stored in a set.
Sequence of events:
- New IKE_SA comes up → add() finds the key already present (from the old, still-registered SA) → no-op. The interface is never marked up for this SA.
- Old IKE_SA finally times out → remove() deletes the only entry → interface count drops to zero → VTI is administratively downed, even though the new SA's CHILD_SA is INSTALLED and carrying traffic.
The VTI does not recover on its own, since the surviving SA already ran its up-client hook and won't fire it again. Everything downstream (BGP, routing) stays down silently — show vpn ipsec sa and show interfaces vti both look healthy, so the failure is hard to detect (observed: 4.5-hour undetected outage).
Affected files: src/etc/ipsec.d/vti-up-down, python/vyos/utils/vti_updown_db.py
Present since: introduction of the file (T5873), still present in rolling.
Proposed fix: Key the DB entry by IKE_SA identity, not just connection name — include strongSwan's PLUTO_UNIQUEID in the ifspec string ({interface}:{connection}:{protocol}:{uniqueid}). All existing readers split on : and take index 0 for the interface, so this is backward compatible. Note: this changes the failure mode so a missed down event leaks an entry and leaves the interface up (arguably safer than the current bug), which suggests optionally reconciling the DB against swanctl --list-sas on commit as a follow-up.
Reproduction: A new unit test (test_same_connection_multiple_sas) demonstrates the bug against current rolling; on hardware, force the peer to initiate a fresh IKE_SA while the local side is mid-DPD-timeout on the old one.
Workaround: sudo ip link set <vtiN> up (or reset vpn ipsec) — no IPsec-level action needed since the SA is already installed.
Full report with logs, mermaid sequence diagram, and diff:
https://forum.vyos.io/t/ipsec-vti-up-down-db-keyed-by-connection-name-teardown-of-a-stale-ike-sa-admin-downs-a-vti-still-carried-by-a-live-sa/17603