mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-14 13:08:30 +04:00
Some modems raise carrier as soon as the data call is enabled and drop it
again briefly while the connection is finalised. On a Quectel EG060W the drop
is about a second long and lands about two seconds after AT+QNETDEVCTL, with
no configuration command involved at all. Not every modem does it: a Fibocom
FG621-EA sampled at ~90 Hz over three cycles never dropped carrier.
netifd turns that transient into a permanent failure: the DHCP sub-interface
is dynamic and created only once during setup, and a dynamic interface is
removed on carrier loss (IFC_REMOVE in interface_check_state()), so nothing
ever recreates it. udhcpc is usually still sending discovers when the drop
kills it, and the interface is left with no address and no route. If the drop
lands after a lease was granted the lease is stale instead, and a renew does
not recover that either because it unicasts to a server that no longer exists.
Wait for the carrier to stay up for a few seconds before handing the interface
to netifd, so the drop falls outside the window netifd is watching.
directip.sh already waits for carrier for the same class of reason ("wait for
carrier to avoid firmware stability bugs") and qmi.sh sleeps unconditionally
while waiting for registration; unlike those this is tunable, and linksettle 0
keeps the previous behaviour.
The wait gives up after three times linksettle, floored at 30s so it always
outlasts the settle window, and continues anyway. Profiles that only reach
data state at finalize, further down, have nothing to wait for here and skip
it; mtk1 is marked with linkatfinalize for that.
Measured on an EG060W (Cudy LT700 Outdoor), three runs each: with linksettle 0
udhcpc never obtains a lease, the dynamic interface is torn down and the link
stays dead; with the 3s default the lease, route and traffic come up every
time, and netifd logs no carrier loss at all.
On a modem without the drop the wait only adds linksettle seconds to the
bring-up (14s vs 17s on the FG621-EA). It stays on by default anyway: a missed
drop leaves the link permanently dead rather than slow, and it is not known in
advance which modems do it. linksettle 0 turns it off where it is not needed.
Signed-off-by: Carlo Szelinsky <github@szelinsky.de>
Tested-by: Fredrik Hallin <fredappsdev@outlook.com>
Link: https://github.com/openwrt/openwrt/pull/24689
Signed-off-by: Jonas Jelonek <jonas@jonasjelonek.de>