diff --git a/util/linuxfw/iptables_runner.go b/util/linuxfw/iptables_runner.go index 090356798..196046ce6 100644 --- a/util/linuxfw/iptables_runner.go +++ b/util/linuxfw/iptables_runner.go @@ -59,7 +59,7 @@ func newIPTablesRunner(logf logger.Logf) (*iptablesRunner, error) { } supportsV6, supportsV6NAT := false, false - v6err := checkIPv6(logf) + v6err := CheckIPv6(logf) ip6terr := checkIP6TablesExists() var ipt6 *iptables.IPTables switch { diff --git a/util/linuxfw/linuxfw.go b/util/linuxfw/linuxfw.go index 152d2eb07..e4b1929cf 100644 --- a/util/linuxfw/linuxfw.go +++ b/util/linuxfw/linuxfw.go @@ -130,7 +130,7 @@ func errCode(err error) int { // missing. It does not check that IPv6 is currently functional or // that there's a global address, just that the system would support // IPv6 if it were on an IPv6 network. -func checkIPv6(logf logger.Logf) error { +func CheckIPv6(logf logger.Logf) error { _, err := os.Stat("/proc/sys/net/ipv6") if os.IsNotExist(err) { return err diff --git a/util/linuxfw/nftables_runner.go b/util/linuxfw/nftables_runner.go index 18d7bd5ae..e3dc2ec0a 100644 --- a/util/linuxfw/nftables_runner.go +++ b/util/linuxfw/nftables_runner.go @@ -546,7 +546,7 @@ func newNfTablesRunner(logf logger.Logf) (*nftablesRunner, error) { } nft4 := &nftable{Proto: nftables.TableFamilyIPv4} - v6err := checkIPv6(logf) + v6err := CheckIPv6(logf) if v6err != nil { logf("disabling tunneled IPv6 due to system IPv6 config: %v", v6err) } diff --git a/wgengine/router/router_linux.go b/wgengine/router/router_linux.go index e9c585d98..2a1443108 100644 --- a/wgengine/router/router_linux.go +++ b/wgengine/router/router_linux.go @@ -56,6 +56,7 @@ type linuxRouter struct { // Various feature checks for the network stack. ipRuleAvailable bool // whether kernel was built with IP_MULTIPLE_TABLES + v6Available bool // whether the kernel supports IPv6 fwmaskWorks bool // whether we can use 'ip rule...fwmark /' // ipPolicyPrefBase is the base priority at which ip rules are installed. @@ -142,6 +143,8 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon r.logf("mwan3 on openWRT detected, switching policy base priority to 1300") } + r.v6Available = linuxfw.CheckIPv6(r.logf) == nil + r.fixupWSLMTU() return r, nil @@ -416,7 +419,7 @@ func (r *linuxRouter) UpdateMagicsockPort(port uint16, network string) error { case "udp4": magicsockPort = &r.magicsockPortV4 case "udp6": - if !r.nfr.HasIPV6() { + if !r.getV6Available() { return nil } magicsockPort = &r.magicsockPortV6 @@ -523,7 +526,7 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error { return fmt.Errorf("could not add magicsock port rule v4: %w", err) } } - if r.magicsockPortV6 != 0 && r.nfr.HasIPV6() { + if r.magicsockPortV6 != 0 && r.getV6Available() { if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil { return fmt.Errorf("could not add magicsock port rule v6: %w", err) } @@ -563,7 +566,7 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error { return fmt.Errorf("could not add magicsock port rule v4: %w", err) } } - if r.magicsockPortV6 != 0 && r.nfr.HasIPV6() { + if r.magicsockPortV6 != 0 && r.getV6Available() { if err := r.nfr.AddMagicsockPortRule(r.magicsockPortV6, "udp6"); err != nil { return fmt.Errorf("could not add magicsock port rule v6: %w", err) } @@ -602,6 +605,9 @@ func (r *linuxRouter) setNetfilterMode(mode preftype.NetfilterMode) error { } func (r *linuxRouter) getV6Available() bool { + if r.netfilterMode == netfilterOff { + return r.v6Available + } return r.nfr.HasIPV6() }