diff --git a/wgengine/userspace.go b/wgengine/userspace.go index 8e461c479..4b03c9bb9 100644 --- a/wgengine/userspace.go +++ b/wgengine/userspace.go @@ -164,6 +164,20 @@ func NewFakeUserspaceEngine(logf logger.Logf, listenPort uint16) (Engine, error) }) } +// IsNetstack reports whether e is a netstack-based TUN-free engine. +func IsNetstack(e Engine) bool { + ig, ok := e.(InternalsGetter) + if !ok { + return false + } + tw, _, ok := ig.GetInternals() + if !ok { + return false + } + name, err := tw.Name() + return err == nil && name == "FakeTUN" +} + // NewUserspaceEngine creates the named tun device and returns a // Tailscale Engine running on it. func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error) { diff --git a/wgengine/userspace_test.go b/wgengine/userspace_test.go index ac081d83e..222e183b1 100644 --- a/wgengine/userspace_test.go +++ b/wgengine/userspace_test.go @@ -186,3 +186,14 @@ func BenchmarkGenLocalAddrFunc(b *testing.B) { }) b.Logf("x = %v", x) } + +func TestIsNetstack(t *testing.T) { + e, err := NewUserspaceEngine(t.Logf, Config{}) + if err != nil { + t.Fatal(err) + } + defer e.Close() + if !IsNetstack(e) { + t.Errorf("IsNetstack = false; want true") + } +}