|
|
|
|
@ -32,6 +32,8 @@ import ( |
|
|
|
|
"tailscale.com/version/distro" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var getDistroFunc = distro.Get |
|
|
|
|
|
|
|
|
|
const ( |
|
|
|
|
netfilterOff = preftype.NetfilterOff |
|
|
|
|
netfilterNoDivert = preftype.NetfilterNoDivert |
|
|
|
|
@ -222,7 +224,7 @@ func busyboxParseVersion(output string) (major, minor, patch int, err error) { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func useAmbientCaps() bool { |
|
|
|
|
if distro.Get() != distro.Synology { |
|
|
|
|
if getDistroFunc() != distro.Synology { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
return distro.DSMVersion() >= 7 |
|
|
|
|
@ -438,7 +440,7 @@ func (r *linuxRouter) Set(cfg *Config) error { |
|
|
|
|
|
|
|
|
|
// Issue 11405: enable IP forwarding on gokrazy.
|
|
|
|
|
advertisingRoutes := len(cfg.SubnetRoutes) > 0 |
|
|
|
|
if distro.Get() == distro.Gokrazy && advertisingRoutes { |
|
|
|
|
if getDistroFunc() == distro.Gokrazy && advertisingRoutes { |
|
|
|
|
r.enableIPForwarding() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1181,7 +1183,9 @@ var ( |
|
|
|
|
tailscaleRouteTable = newRouteTable("tailscale", 52) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// ipRules are the policy routing rules that Tailscale uses.
|
|
|
|
|
// baseIPRules are the policy routing rules that Tailscale uses, when not
|
|
|
|
|
// running on a UDM-Pro.
|
|
|
|
|
//
|
|
|
|
|
// The priority is the value represented here added to r.ipPolicyPrefBase,
|
|
|
|
|
// which is usually 5200.
|
|
|
|
|
//
|
|
|
|
|
@ -1196,7 +1200,7 @@ var ( |
|
|
|
|
// and 'ip rule' implementations (including busybox), don't support
|
|
|
|
|
// checking for the lack of a fwmark, only the presence. The technique
|
|
|
|
|
// below works even on very old kernels.
|
|
|
|
|
var ipRules = []netlink.Rule{ |
|
|
|
|
var baseIPRules = []netlink.Rule{ |
|
|
|
|
// Packets from us, tagged with our fwmark, first try the kernel's
|
|
|
|
|
// main routing table.
|
|
|
|
|
{ |
|
|
|
|
@ -1232,6 +1236,34 @@ var ipRules = []netlink.Rule{ |
|
|
|
|
// usual rules (pref 32766 and 32767, ie. main and default).
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// udmProIPRules are the policy routing rules that Tailscale uses, when running
|
|
|
|
|
// on a UDM-Pro.
|
|
|
|
|
//
|
|
|
|
|
// The priority is the value represented here added to
|
|
|
|
|
// r.ipPolicyPrefBase, which is usually 5200.
|
|
|
|
|
//
|
|
|
|
|
// This represents an experiment that will be used to gather more information.
|
|
|
|
|
// If this goes well, Tailscale may opt to use this for all of Linux.
|
|
|
|
|
var udmProIPRules = []netlink.Rule{ |
|
|
|
|
// non-fwmark packets fall through to the usual rules (pref 32766 and 32767,
|
|
|
|
|
// ie. main and default).
|
|
|
|
|
{ |
|
|
|
|
Priority: 70, |
|
|
|
|
Invert: true, |
|
|
|
|
Mark: linuxfw.TailscaleBypassMarkNum, |
|
|
|
|
Table: tailscaleRouteTable.Num, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ipRules returns the appropriate list of ip rules to be used by Tailscale. See
|
|
|
|
|
// comments on baseIPRules and udmProIPRules for more details.
|
|
|
|
|
func ipRules() []netlink.Rule { |
|
|
|
|
if getDistroFunc() == distro.UDMPro { |
|
|
|
|
return udmProIPRules |
|
|
|
|
} |
|
|
|
|
return baseIPRules |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// justAddIPRules adds policy routing rule without deleting any first.
|
|
|
|
|
func (r *linuxRouter) justAddIPRules() error { |
|
|
|
|
if !r.ipRuleAvailable { |
|
|
|
|
@ -1243,7 +1275,7 @@ func (r *linuxRouter) justAddIPRules() error { |
|
|
|
|
var errAcc error |
|
|
|
|
for _, family := range r.addrFamilies() { |
|
|
|
|
|
|
|
|
|
for _, ru := range ipRules { |
|
|
|
|
for _, ru := range ipRules() { |
|
|
|
|
// Note: r is a value type here; safe to mutate it.
|
|
|
|
|
ru.Family = family.netlinkInt() |
|
|
|
|
if ru.Mark != 0 { |
|
|
|
|
@ -1272,7 +1304,7 @@ func (r *linuxRouter) addIPRulesWithIPCommand() error { |
|
|
|
|
rg := newRunGroup(nil, r.cmd) |
|
|
|
|
|
|
|
|
|
for _, family := range r.addrFamilies() { |
|
|
|
|
for _, rule := range ipRules { |
|
|
|
|
for _, rule := range ipRules() { |
|
|
|
|
args := []string{ |
|
|
|
|
"ip", family.dashArg(), |
|
|
|
|
"rule", "add", |
|
|
|
|
@ -1320,7 +1352,7 @@ func (r *linuxRouter) delIPRules() error { |
|
|
|
|
} |
|
|
|
|
var errAcc error |
|
|
|
|
for _, family := range r.addrFamilies() { |
|
|
|
|
for _, ru := range ipRules { |
|
|
|
|
for _, ru := range ipRules() { |
|
|
|
|
// Note: r is a value type here; safe to mutate it.
|
|
|
|
|
// When deleting rules, we want to be a bit specific (mention which
|
|
|
|
|
// table we were routing to) but not *too* specific (fwmarks, etc).
|
|
|
|
|
@ -1363,7 +1395,7 @@ func (r *linuxRouter) delIPRulesWithIPCommand() error { |
|
|
|
|
// That leaves us some flexibility to change these values in later
|
|
|
|
|
// versions without having ongoing hacks for every possible
|
|
|
|
|
// combination.
|
|
|
|
|
for _, rule := range ipRules { |
|
|
|
|
for _, rule := range ipRules() { |
|
|
|
|
args := []string{ |
|
|
|
|
"ip", family.dashArg(), |
|
|
|
|
"rule", "del", |
|
|
|
|
@ -1500,7 +1532,7 @@ func normalizeCIDR(cidr netip.Prefix) string { |
|
|
|
|
// platformCanNetfilter reports whether the current distro/environment supports
|
|
|
|
|
// running iptables/nftables commands.
|
|
|
|
|
func platformCanNetfilter() bool { |
|
|
|
|
switch distro.Get() { |
|
|
|
|
switch getDistroFunc() { |
|
|
|
|
case distro.Synology: |
|
|
|
|
// Synology doesn't support iptables or nftables. Attempting to run it
|
|
|
|
|
// just blocks for a long time while it logs about failures.
|
|
|
|
|
@ -1526,7 +1558,7 @@ func cleanUp(logf logger.Logf, interfaceName string) { |
|
|
|
|
// of the config file being present as well as a policy rule with a specific
|
|
|
|
|
// priority (2000 + 1 - first interface mwan3 manages) and non-zero mark.
|
|
|
|
|
func checkOpenWRTUsingMWAN3() (bool, error) { |
|
|
|
|
if distro.Get() != distro.OpenWrt { |
|
|
|
|
if getDistroFunc() != distro.OpenWrt { |
|
|
|
|
return false, nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|