diff --git a/cmd/cli/dns_proxy.go b/cmd/cli/dns_proxy.go index d9f124e..0447eef 100644 --- a/cmd/cli/dns_proxy.go +++ b/cmd/cli/dns_proxy.go @@ -1366,7 +1366,7 @@ func (p *prog) monitorNetworkChanges(ctx context.Context) error { changed := false activeInterfaceExists := false - changeIPs := []netip.Prefix{} + var changeIPs []netip.Prefix // Check each valid interface for changes for ifaceName := range validIfaces { oldIface := delta.Old.Interface[ifaceName] diff --git a/cmd/cli/net_linux.go b/cmd/cli/net_linux.go new file mode 100644 index 0000000..ea17d3d --- /dev/null +++ b/cmd/cli/net_linux.go @@ -0,0 +1,52 @@ +package cli + +import ( + "net" + "net/netip" + "os" + "strings" + + "tailscale.com/net/netmon" +) + +func patchNetIfaceName(iface *net.Interface) (bool, error) { return true, nil } + +// validInterface reports whether the *net.Interface is a valid one. +// Only non-virtual interfaces are considered valid. +func validInterface(iface *net.Interface, validIfacesMap map[string]struct{}) bool { + _, ok := validIfacesMap[iface.Name] + return ok +} + +// validInterfacesMap returns a set containing non virtual interfaces. +func validInterfacesMap() map[string]struct{} { + m := make(map[string]struct{}) + vis := virtualInterfaces() + netmon.ForeachInterface(func(i netmon.Interface, prefixes []netip.Prefix) { + if _, existed := vis[i.Name]; existed { + return + } + m[i.Name] = struct{}{} + }) + // Fallback to default route interface if found nothing. + if len(m) == 0 { + defaultRoute, err := netmon.DefaultRoute() + if err != nil { + return m + } + m[defaultRoute.InterfaceName] = struct{}{} + } + return m +} + +// virtualInterfaces returns a map of virtual interfaces on current machine. +func virtualInterfaces() map[string]struct{} { + s := make(map[string]struct{}) + entries, _ := os.ReadDir("/sys/devices/virtual/net") + for _, entry := range entries { + if entry.IsDir() { + s[strings.TrimSpace(entry.Name())] = struct{}{} + } + } + return s +} diff --git a/cmd/cli/net_others.go b/cmd/cli/net_others.go index edd89ec..f347278 100644 --- a/cmd/cli/net_others.go +++ b/cmd/cli/net_others.go @@ -1,11 +1,22 @@ -//go:build !darwin && !windows +//go:build !darwin && !windows && !linux package cli -import "net" +import ( + "net" + + "tailscale.com/net/netmon" +) func patchNetIfaceName(iface *net.Interface) (bool, error) { return true, nil } func validInterface(iface *net.Interface, validIfacesMap map[string]struct{}) bool { return true } -func validInterfacesMap() map[string]struct{} { return nil } +// validInterfacesMap returns a set containing only default route interfaces. +func validInterfacesMap() map[string]struct{} { + defaultRoute, err := netmon.DefaultRoute() + if err != nil { + return nil + } + return map[string]struct{}{defaultRoute.InterfaceName: {}} +}