fix(tollgate): verify br-tollgate's kernel-level IP after restart, retry if missing
Found live again, in a different shape: after a later round of service restarts (dnsmasq restart while debugging), br-tollgate desynced a second time — but this time netifd's own status reported the interface up with 192.168.99.1 assigned, while `ip -4 addr show br-tollgate` was genuinely empty at the kernel level. dnsmasq logged "DHCP packet received on br-tollgate which has no address" and silently dropped every DISCOVER — clients associated to the archipelago SSID fine but never got an IP. A single blind ifdown/ifup (the previous fix) isn't trustworthy against this netifd race — replace it with a loop that checks the actual kernel address after each cycle and retries up to 5 times, failing loudly (rather than silently leaving DHCP broken) if it never converges.
This commit is contained in:
parent
c1f191128f
commit
6060ad23b2
@ -86,12 +86,27 @@ fn restart_services(router: &Router, enabled: bool) -> Result<()> {
|
||||
// Reload wireless so wireless.tollgate.disabled takes effect on the radio —
|
||||
// `network restart` alone doesn't reliably reconfigure wifi interfaces.
|
||||
router.run_ok("wifi down 2>&1; wifi up 2>&1")?;
|
||||
// Observed live: netifd can lose the race to claim br-tollgate as the
|
||||
// wifi vif attaches to it during the restart above, leaving the
|
||||
// interface reported "up: false, DEVICE_CLAIM_FAILED" even though the
|
||||
// bridge device and its member both exist. An explicit down/up of just
|
||||
// this logical interface resolves it — needed before NoDogSplash starts,
|
||||
// since it refuses to start against an interface netifd hasn't brought up.
|
||||
router.run_ok("sleep 2; ifdown tollgate 2>&1; sleep 1; ifup tollgate 2>&1; sleep 2")?;
|
||||
// Observed live, twice, in two different ways: netifd can lose the race
|
||||
// to claim br-tollgate as the wifi vif attaches to it during the restart
|
||||
// above. The first time it showed up as netifd reporting
|
||||
// "up: false, DEVICE_CLAIM_FAILED"; the second time netifd reported the
|
||||
// interface up with its address assigned while the kernel-level device
|
||||
// genuinely had none (`ip -4 addr show br-tollgate` empty) — dnsmasq
|
||||
// logged "DHCP packet received on br-tollgate which has no address" and
|
||||
// silently dropped every DISCOVER. A single blind ifdown/ifup isn't
|
||||
// trustworthy here — verify the address actually landed at the kernel
|
||||
// level (not just what netifd claims) and retry the cycle if not, since
|
||||
// NoDogSplash refuses to start against an interface that isn't really up
|
||||
// and dnsmasq will silently refuse to answer DHCP without erroring loudly.
|
||||
router.run_ok(
|
||||
"sleep 2; \
|
||||
for i in 1 2 3 4 5; do \
|
||||
ifdown tollgate 2>&1; sleep 1; ifup tollgate 2>&1; sleep 2; \
|
||||
ip -4 addr show br-tollgate 2>/dev/null | grep -q 'inet ' && break; \
|
||||
echo \"br-tollgate has no kernel-level IPv4 address after cycle $i, retrying\"; \
|
||||
done; \
|
||||
ip -4 addr show br-tollgate 2>/dev/null | grep -q 'inet ' || \
|
||||
{ echo 'br-tollgate never got a kernel-level IPv4 address after 5 cycles'; exit 1; }"
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user