ipn/ipnlocal: unconfigure wgengine when switching profiles

LocalBackend transitions to ipn.NoState when switching to a different (or new) profile.
When this happens, we should unconfigure wgengine to clear routes, DNS configuration,
firewall rules that block all traffic except to the exit node, etc.

In this PR, we update (*LocalBackend).enterStateLockedOnEntry to do just that.

Fixes #15316
Updates tailscale/corp#23967

Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
Nick Khyl
2025-03-14 15:17:26 -05:00
committed by Nick Khyl
parent a8c3490614
commit 272854df41
3 changed files with 494 additions and 12 deletions
+16 -8
View File
@@ -4407,19 +4407,27 @@ func TestNotificationTargetMatch(t *testing.T) {
type newTestControlFn func(tb testing.TB, opts controlclient.Options) controlclient.Client
func newLocalBackendWithTestControl(t *testing.T, enableLogging bool, newControl newTestControlFn) *LocalBackend {
return newLocalBackendWithSysAndTestControl(t, enableLogging, new(tsd.System), newControl)
}
func newLocalBackendWithSysAndTestControl(t *testing.T, enableLogging bool, sys *tsd.System, newControl newTestControlFn) *LocalBackend {
logf := logger.Discard
if enableLogging {
logf = tstest.WhileTestRunningLogger(t)
}
sys := new(tsd.System)
store := new(mem.Store)
sys.Set(store)
e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry())
if err != nil {
t.Fatalf("NewFakeUserspaceEngine: %v", err)
if _, hasStore := sys.StateStore.GetOK(); !hasStore {
store := new(mem.Store)
sys.Set(store)
}
if _, hasEngine := sys.Engine.GetOK(); !hasEngine {
e, err := wgengine.NewFakeUserspaceEngine(logf, sys.Set, sys.HealthTracker(), sys.UserMetricsRegistry())
if err != nil {
t.Fatalf("NewFakeUserspaceEngine: %v", err)
}
t.Cleanup(e.Close)
sys.Set(e)
}
t.Cleanup(e.Close)
sys.Set(e)
b, err := NewLocalBackend(logf, logid.PublicID{}, sys, 0)
if err != nil {