diff --git a/version/distro/distro.go b/version/distro/distro.go index 970b8c1ae..0724265a4 100644 --- a/version/distro/distro.go +++ b/version/distro/distro.go @@ -32,6 +32,7 @@ const ( ) var distro lazy.SyncValue[Distro] +var isWSL lazy.SyncValue[bool] // Get returns the current distro, or the empty string if unknown. func Get() Distro { @@ -47,6 +48,15 @@ func Get() Distro { }) } +// IsWSL reports whether we're running in the Windows Subsystem for Linux. +func IsWSL() bool { + return runtime.GOOS == "linux" && isWSL.Get(func() bool { + // We could look for $WSL_INTEROP instead, however that may be missing if + // the user has started to use systemd in WSL2. + return have("/proc/sys/fs/binfmt_misc/WSLInterop") || have("/mnt/wsl") + }) +} + func have(file string) bool { _, err := os.Stat(file) return err == nil diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go index 4afdaf7fb..1fd733fa0 100644 --- a/wgengine/router/router_linux.go +++ b/wgengine/router/router_linux.go @@ -7,6 +7,7 @@ import ( "bytes" "errors" "fmt" + "net" "net/netip" "os" "os/exec" @@ -224,6 +225,8 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monit r.logf("mwan3 on openWRT detected, switching policy base priority to 1300") } + r.fixupWSLMTU() + return r, nil } @@ -891,6 +894,45 @@ func (r *linuxRouter) downInterface() error { return netlink.LinkSetDown(link) } +// fixupWSLMTU sets the MTU on the eth0 interface to 1360 bytes if running under +// WSL, eth0 is the default route, and has the MTU 1280 bytes. +func (r *linuxRouter) fixupWSLMTU() { + if !distro.IsWSL() { + return + } + + if r.useIPCommand() { + r.logf("fixupWSLMTU: not implemented by ip command") + return + } + + link, err := netlink.LinkByName("eth0") + if err != nil { + r.logf("warning: fixupWSLMTU: could not open eth0: %v", err) + return + } + + routes, err := netlink.RouteGet(net.IPv4(8, 8, 8, 8)) + if err != nil || len(routes) == 0 { + if err == nil { + err = fmt.Errorf("none found") + } + r.logf("fixupWSLMTU: could not get default route: %v", err) + return + } + + if routes[0].LinkIndex != link.Attrs().Index { + r.logf("fixupWSLMTU: default route is not via eth0") + return + } + + if link.Attrs().MTU == 1280 { + if err := netlink.LinkSetMTU(link, 1360); err != nil { + r.logf("warning: fixupWSLMTU: could not raise eth0 MTU: %v", err) + } + } +} + // addrFamily is an address family: IPv4 or IPv6. type addrFamily byte