# Plan: Allow re-activating the current gateway from the UI ## Problem The UI shows "active" on a gateway based solely on the UCI `active_gateway` config value, but the switch script (`zt-gateway-switch`) may never have been run — meaning no routing tables, no masquerade, no actual traffic forwarding. The user sees "active" and assumes it works. Two blocking issues prevent fixing this from the UI: 1. **Backend** (`zt-gateway.uc` line 184-187): `switch` method short-circuits with "Already on X" when UCI `active_gateway` matches the requested region — never runs the script 2. **UI** (`overview.js` line 81): radio button for the active gateway is `disabled`, so the user can't even select it to click "Switch to selected" ## Fix Two files, one change each. ### 1. Backend: `root/usr/share/rpcd/ucode/zt-gateway.uc` **Remove the "Already on X" early return** (lines 184-187): ```js // DELETE these lines: const current_region = read_active_region(); if (current_region === region && !drain_active()) { return { success: true, message: `Already on ${region}.` }; } ``` **Why this is safe:** - `do_force()` in the switch script is idempotent: `ip route replace` is a no-op when the route already matches, conntrack flush is harmless, `persist_all` writes the same values - The backend still updates UCI after the script runs (line 198-199) — setting the same value is harmless - If the gateway is unreachable, `preflight_ping` fails with exit 2 and the backend returns the error — same as switching to any other unreachable gateway ### 2. UI: `htdocs/luci-static/resources/view/zt-gateway/overview.js` **Remove the `disabled` attribute from the active gateway's radio** (line 81): Change: ```js disabled: isActive || null ``` To: ```js // Remove this line entirely (or keep disabled only during an active drain) ``` **Why this is safe:** - The user can now select the active gateway and click "Switch to selected" - The backend runs the switch script which sets up routing - If routing is already correct, the script is a harmless idempotent no-op - The "Switch to selected" button text still makes sense — it re-applies the gateway config ### Files to modify | File | Change | |---|---| | `root/usr/share/rpcd/ucode/zt-gateway.uc` | Remove lines 184-187 (early return) | | `htdocs/luci-static/resources/view/zt-gateway/overview.js` | Remove `disabled` on line 81 | ### Verification 1. Deploy to device: `mise run deploy:install` 2. Open UI → amsterdam shows "active" → radio is now enabled 3. Select amsterdam → click "Switch to selected" → should succeed and set up routing 4. Verify routing: `ip route show table 100` should show `default via 10.11.12.3 dev ztk4jpk77j` 5. Verify NAT: `iptables -t mangle -L -n` should show WIBLAN mangle rules (for graceful mode) 6. Test from LAN client: `ping -I br-lan 10.11.12.3` should now work