cmd/tailscaled, ipn/ipnlocal, wgengine: shutdown tailscaled if wgdevice is closed

Tailscaled becomes inoperative if the Tailscale Tunnel wintun adapter is abruptly removed.
wireguard-go closes the device in case of a read error, but tailscaled keeps running.
This adds detection of a closed WireGuard device, triggering a graceful shutdown of tailscaled.
It is then restarted by the tailscaled watchdog service process.

Fixes #11222

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2024-02-23 19:55:08 -06:00
committed by Nick Khyl
parent b42b9817b0
commit 7ef1fb113d
6 changed files with 46 additions and 16 deletions

View File

@@ -425,6 +425,21 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
}
}()
go func() {
select {
case <-e.wgdev.Wait():
e.mu.Lock()
closing := e.closing
e.mu.Unlock()
if !closing {
e.logf("Closing the engine because the WireGuard device has been closed...")
e.Close()
}
case <-e.waitCh:
// continue
}
}()
e.logf("Bringing WireGuard device up...")
if err := e.wgdev.Up(); err != nil {
return nil, fmt.Errorf("wgdev.Up: %w", err)
@@ -1112,8 +1127,8 @@ func (e *userspaceEngine) Close() {
}
}
func (e *userspaceEngine) Wait() {
<-e.waitCh
func (e *userspaceEngine) Done() <-chan struct{} {
return e.waitCh
}
func (e *userspaceEngine) linkChange(delta *netmon.ChangeDelta) {