--- type: reference tags: [parking, dev-environment, networking, wsl, troubleshooting] sources: [] updated: 2026-06-15 --- # WSL2 Dev Networking (for device testing) > Dev-environment note, not product architecture. Recorded because reaching real > hardware (the [[uhppote-controller]]) from a dev box running under **WSL2** took > significant debugging. If you test devices from WSL, read this first. ## The problem By default WSL2 uses **NAT networking**: the Linux VM sits on its own virtual subnet (e.g. `172.x`), not the Windows host's LAN. Consequences for device work: - **UDP broadcast (UHPPOTE discovery) cannot leave the VM** — a `get-devices` broadcast gets `EACCES` / never reaches a controller on the physical LAN. The device is reachable from *Windows* but not from *inside WSL*. - Even unicast to a LAN device may not route, depending on setup. ## The fix: mirrored networking Switch WSL to **mirrored** mode so it shares the Windows host's interfaces (and thus the real LAN). Requires **Windows 11 22H2+** and **WSL ≥ 2.0**. `%UserProfile%\.wslconfig` (create it; it doesn't exist by default): ```ini [wsl2] networkingMode=mirrored firewall=false # Windows Firewall otherwise filters WSL traffic (can drop UDP replies) [experimental] hostAddressLoopback=true # host <-> WSL over the host's IP ``` Apply: in **PowerShell** `wsl --shutdown`, wait ~10 s, reopen WSL. Verify with `ip -4 addr` — interfaces should now show the **real LAN subnet** (e.g. `10.0.10.x`) instead of `172.x`. (Microsoft recommends editing via the **WSL Settings** GUI rather than the file by hand.) > `wsl --shutdown` kills the dev servers — restart `pnpm dev` afterward. ## After mirrored mode: app-level gotchas that remained Mirrored networking is necessary but **not sufficient** — these still bit us: - **Multiple interfaces.** Mirrored WSL exposes *all* host NICs (LAN, Tailscale/CGNAT `100.x`, docker bridges). UHPPOTE discovery must broadcast on **every** subnet, not the first one — see [[device-discovery]]. - **Subnet-directed broadcast** (`10.0.10.255`, not `255.255.255.255`) — the lib won't enable `SO_BROADCAST` otherwise. See [[device-discovery]]. - **`localhost` → IPv6 first.** `localhost` resolves to `::1`, but the backend binds IPv4 (`127.0.0.1`). Node's Vite proxy can stall on the v6 attempt before falling back — point the proxy at `127.0.0.1` explicitly. (See [[local-dev-workflow]].) ## Alternative if you can't use mirrored mode Windows 10 / old WSL can't do mirrored mode. Options: run the **backend natively on Windows** (shares the LAN), or use **unicast by IP** instead of broadcast discovery (target the controller's known IP — the driver supports an explicit host). On the real **appliance** (a dedicated hardened Linux box, [[disk-os-hardening]]) none of this applies — it's bare-metal on the device VLAN ([[network-isolation]]).