The EC25/Koodo GSM connection is QMI raw-ip with an on-link /29 and no
gateway at all (nh 0.0.0.0), not a normal DHCP WAN with a temporarily
unknown gateway. enforce_route() required a gw and silently gave up
when none was found, so cellular could be reported up/healthy/preferred
in state.json while never actually getting a default route (Prefer
button had no effect since it only touches metric, not this bailout).
Now falls back to installing a gateway-less `ip route ... dev DEV`
default when the device genuinely has an IPv4 address (carrier truly
up), mirroring what NM itself would install without never-default.
Also fixes stale-route pruning to handle gateway-less old routes,
which the previous gw-only check skipped.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
van-failover is now the sole owner of default-route selection: netplan/NM
profiles get ipv4.never-default so NM's own DHCP/lease renewals stop
reinstalling competing default routes (was racing van-failover's enforce_route
on Starlink's 16s lease). set_profile_metric() also pins never-default on
NM-managed connections it doesn't own the netplan source for (e.g. cellular),
and nm_gateway() falls back to the raw DHCP4 lease's `routers` option since NM
stops populating IP4.GATEWAY once never-default is set.
Probing moved from one shared round to independent per-WAN retry scheduling,
so a flaky WAN retries on its own clock instead of dragging healthy WANs into
extra probes or throttling a failing one to the slow steady-state cadence.
config.json: probe_interval 4->60, fail/ok_threshold 3/2->2/1, single probe
URL — verified live across this reboot (cellular took ~2min after NM reported
"activated" to actually pass traffic; van-failover correctly withheld/
deprioritized the default route until then, then installed it automatically).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
NM reports a gsm connection's device as the control port (cdc-wdm0), but
IP + routes live on the wwan netdev (wwu1u2i4 on the Quectel EC25-AF), so
probes and route enforcement silently saw nothing (cellular stuck "down",
no metric). Map connection-keyed WANs through GENERAL.IP-IFACE, and let
the gateway fallback query the connection since the netdev isn't an NM
device.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>