change: give each tunnel role its own WireGuard device #212

Merged
mysticalsoap merged 1 commit from change/wireguard-roles-176 into trunk 2026-08-30 12:17:23 -04:00
Owner

Stage 2 of #176 (stage 1 was #211).

Problem: wireguard.py is built around one module-level device (DEV = wg_aqomui) - the concrete reason WireGuard cannot join a double hop: a second leg has no device to exist on.

Change:

  • The device becomes instance state: the role, fixed at construction, binds wg_aqomui / wg_aqomui_h / wg_aqomui_b (new config.WG_DEVICES, next to TUN_DEVICES).
  • Every module function (link_up, link_down, firewall_rules, _setconf, _routes) takes the device it operates on; handshake_age reads the instance's.
  • The service's startup sweep tears down all three WG devices, matching what it already does for the OpenVPN trio.
  • Secondary roles are still refused - now at construction, before any side effect - until the chain routing lands in stage 3.

Behavior is otherwise unchanged - a single WireGuard connect does exactly what it did.

Verification: suite 523 passed; the secondary-refusal, per-role-device, and IFNAMSIZ/disjoint-names invariants are pinned by new tests. Live check before merge is just a normal WireGuard connect/disconnect (a Proton or Mullvad -WireGuard entry) confirming nothing regressed.

Stage 3 next: chain routing for WG legs via the shared hop_routes model, MTU stacking, TUNNEL_SECONDARY flip, README.

Part of #176.

🤖 Generated with Claude Code

Stage 2 of #176 (stage 1 was #211). **Problem**: wireguard.py is built around one module-level device (`DEV = wg_aqomui`) - the concrete reason WireGuard cannot join a double hop: a second leg has no device to exist on. **Change**: - The device becomes instance state: the role, fixed at construction, binds `wg_aqomui` / `wg_aqomui_h` / `wg_aqomui_b` (new `config.WG_DEVICES`, next to `TUN_DEVICES`). - Every module function (`link_up`, `link_down`, `firewall_rules`, `_setconf`, `_routes`) takes the device it operates on; `handshake_age` reads the instance's. - The service's startup sweep tears down all three WG devices, matching what it already does for the OpenVPN trio. - Secondary roles are still refused - now at construction, before any side effect - until the chain routing lands in stage 3. **Behavior is otherwise unchanged** - a single WireGuard connect does exactly what it did. **Verification**: suite 523 passed; the secondary-refusal, per-role-device, and IFNAMSIZ/disjoint-names invariants are pinned by new tests. Live check before merge is just a normal WireGuard connect/disconnect (a Proton or Mullvad `-WireGuard` entry) confirming nothing regressed. Stage 3 next: chain routing for WG legs via the shared hop_routes model, MTU stacking, `TUNNEL_SECONDARY` flip, README. Part of #176. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
change: give each tunnel role its own WireGuard device
All checks were successful
ci / test (pull_request) Successful in 24s
ci / test (push) Successful in 26s
659929a1f2
wireguard.py was built around one module-level device, which is the
concrete reason WireGuard cannot join a double hop: a second leg has
no device to exist on. The device becomes instance state - the role,
fixed at construction, binds wg_aqomui / wg_aqomui_h / wg_aqomui_b
(config.WG_DEVICES) - and every module function takes the device it
operates on. The service's startup sweep covers all three.

Behavior is unchanged: secondary roles are still refused (now at
construction, before any side effect) until the chain routing lands.

Part of #176

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
mysticalsoap deleted branch change/wireguard-roles-176 2026-08-30 12:17:23 -04:00
Sign in to join this conversation.
No description provided.