probeEthernet looked for a "DHCP-assigned" address using the `dynamic`
flag or a finite `valid_lft`. udhcpc (BusyBox) installs the leased
address with a plain `ip addr add` and no lease lifetime, so the address
shows `valid_lft forever` and no `dynamic` flag — indistinguishable from
a static LAN/hotspot address on the same interface. The uplink was never
recognized and wpa_supplicant was started despite working connectivity.
Detect the uplink via the interface's default route instead, which is
reliable across udhcpc and full iproute2, and report the uplink source
address from `ip route get` so the UI shows the DHCP address rather than
a co-located static one.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A static IPv4 (e.g. the hotspot gateway address on eth0) was wrongly
classified as a DHCP uplink on stacks where ip(8) omits the "dynamic"
flag, and a NO-CARRIER interface with any address was reported as up.
Gate probeEthernet on /sys/class/net/<iface>/carrier == 1, and accept
either the dynamic flag or a finite valid_lft as the DHCP signal so
BusyBox's ip output is handled too.
When the configured Ethernet interface holds a DHCP-assigned IPv4 at
startup, the app now skips wifi.Initialize / StartEventMonitoring and
guards every wifi.* wrapper against a nil backend. This prevents D-Bus
calls to fi.w1.wpa_supplicant1 from re-activating the daemon via
dbus-activation, honoring the "do nothing" intent of the Ethernet path.
The probed state is exposed in SystemStatus and rendered in the header
as a third pill ("Ethernet · <IP>"); a new "disabled" connectionState
covers the WiFi pill in this mode.
Probe the configured Ethernet interface (default eth0, overridable via
-ethernet-interface) at startup. If no DHCP-assigned IPv4 is present,
start the wpa_supplicant service so the WiFi backend has something to
talk to; otherwise leave it alone and rely on the wired uplink.