cmd/tailscaled: add ip-rule-pref-base argument that can override the priority of ip rule

The current IP rule priority setting method is suitable for routing
from mwan3 to tailscale, but conversely, it is not suitable for
routing tailscale traffic using mwan3. For these cases, we make it
possible for users to manually change IP rule priority.

Signed-off-by: Joseph Lee <joseph@jc-lab.net>
pull/12035/head
Joseph Lee 6 months ago
parent 949b15d858
commit 8088334714

@ -129,6 +129,7 @@ var args struct {
socksAddr string // listen address for SOCKS5 server socksAddr string // listen address for SOCKS5 server
httpProxyAddr string // listen address for HTTP proxy server httpProxyAddr string // listen address for HTTP proxy server
disableLogs bool disableLogs bool
ipRulePrefBase int
} }
var ( var (
@ -170,6 +171,7 @@ func main() {
flag.BoolVar(&printVersion, "version", false, "print version information and exit") flag.BoolVar(&printVersion, "version", false, "print version information and exit")
flag.BoolVar(&args.disableLogs, "no-logs-no-support", false, "disable log uploads; this also disables any technical support") flag.BoolVar(&args.disableLogs, "no-logs-no-support", false, "disable log uploads; this also disables any technical support")
flag.StringVar(&args.confFile, "config", "", "path to config file, or 'vm:user-data' to use the VM's user-data (EC2)") flag.StringVar(&args.confFile, "config", "", "path to config file, or 'vm:user-data' to use the VM's user-data (EC2)")
flag.IntVar(&args.ipRulePrefBase, "ip-rule-pref-base", 0, "override ip rule priority base number")
if len(os.Args) > 0 && filepath.Base(os.Args[0]) == "tailscale" && beCLI != nil { if len(os.Args) > 0 && filepath.Base(os.Args[0]) == "tailscale" && beCLI != nil {
beCLI() beCLI()
@ -720,7 +722,7 @@ func tryEngine(logf logger.Logf, sys *tsd.System, name string) (onlyNetstack boo
return false, err return false, err
} }
r, err := router.New(logf, dev, sys.NetMon.Get(), sys.HealthTracker()) r, err := router.New(logf, dev, sys.NetMon.Get(), args.ipRulePrefBase, sys.HealthTracker())
if err != nil { if err != nil {
dev.Close() dev.Close()
return false, fmt.Errorf("creating router: %w", err) return false, fmt.Errorf("creating router: %w", err)

@ -45,9 +45,9 @@ type Router interface {
// //
// If netMon is nil, it's not used. It's currently (2021-07-20) only // If netMon is nil, it's not used. It's currently (2021-07-20) only
// used on Linux in some situations. // used on Linux in some situations.
func New(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { func New(logf logger.Logf, tundev tun.Device, netMon *netmon.Monitor, ipPolicyPrefBase int, health *health.Tracker) (Router, error) {
logf = logger.WithPrefix(logf, "router: ") logf = logger.WithPrefix(logf, "router: ")
return newUserspaceRouter(logf, tundev, netMon, health) return newUserspaceRouter(logf, tundev, netMon, ipPolicyPrefBase, health)
} }
// CleanUp restores the system network configuration to its original state // CleanUp restores the system network configuration to its original state

@ -73,7 +73,7 @@ type linuxRouter struct {
magicsockPortV6 uint16 magicsockPortV6 uint16
} }
func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, health *health.Tracker) (Router, error) { func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Monitor, ipPolicyPrefBase int, health *health.Tracker) (Router, error) {
tunname, err := tunDev.Name() tunname, err := tunDev.Name()
if err != nil { if err != nil {
return nil, err return nil, err
@ -83,10 +83,10 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, netMon *netmon.Moni
ambientCapNetAdmin: useAmbientCaps(), ambientCapNetAdmin: useAmbientCaps(),
} }
return newUserspaceRouterAdvanced(logf, tunname, netMon, cmd, health) return newUserspaceRouterAdvanced(logf, tunname, netMon, cmd, ipPolicyPrefBase, health)
} }
func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon.Monitor, cmd commandRunner, health *health.Tracker) (Router, error) { func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon.Monitor, cmd commandRunner, ipPolicyPrefBase int, health *health.Tracker) (Router, error) {
r := &linuxRouter{ r := &linuxRouter{
logf: logf, logf: logf,
tunname: tunname, tunname: tunname,
@ -99,6 +99,12 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon
ipRuleFixLimiter: rate.NewLimiter(rate.Every(5*time.Second), 10), ipRuleFixLimiter: rate.NewLimiter(rate.Every(5*time.Second), 10),
ipPolicyPrefBase: 5200, ipPolicyPrefBase: 5200,
} }
if ipPolicyPrefBase > 0 {
r.logf("ip-rule-pref-base manually set, switching policy base priority to %d", ipPolicyPrefBase)
r.ipPolicyPrefBase = ipPolicyPrefBase
}
if r.useIPCommand() { if r.useIPCommand() {
r.ipRuleAvailable = (cmd.run("ip", "rule") == nil) r.ipRuleAvailable = (cmd.run("ip", "rule") == nil)
} else { } else {
@ -129,7 +135,7 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, netMon *netmon
isMWAN3, err := checkOpenWRTUsingMWAN3() isMWAN3, err := checkOpenWRTUsingMWAN3()
if err != nil { if err != nil {
r.logf("error checking mwan3 installation: %v", err) r.logf("error checking mwan3 installation: %v", err)
} else if isMWAN3 { } else if isMWAN3 && ipPolicyPrefBase <= 0 {
r.ipPolicyPrefBase = 1300 r.ipPolicyPrefBase = 1300
r.logf("mwan3 on openWRT detected, switching policy base priority to 1300") r.logf("mwan3 on openWRT detected, switching policy base priority to 1300")
} }

@ -371,7 +371,7 @@ ip route add throw 192.168.0.0/24 table 52` + basic,
fake := NewFakeOS(t) fake := NewFakeOS(t)
ht := new(health.Tracker) ht := new(health.Tracker)
router, err := newUserspaceRouterAdvanced(t.Logf, "tailscale0", mon, fake, ht) router, err := newUserspaceRouterAdvanced(t.Logf, "tailscale0", mon, fake, 0, ht)
router.(*linuxRouter).nfr = fake.nfr router.(*linuxRouter).nfr = fake.nfr
if err != nil { if err != nil {
t.Fatalf("failed to create router: %v", err) t.Fatalf("failed to create router: %v", err)
@ -969,7 +969,7 @@ func newLinuxRootTest(t *testing.T) *linuxTest {
mon.Start() mon.Start()
lt.mon = mon lt.mon = mon
r, err := newUserspaceRouter(logf, lt.tun, mon, nil) r, err := newUserspaceRouter(logf, lt.tun, mon, 0, nil)
if err != nil { if err != nil {
lt.Close() lt.Close()
t.Fatal(err) t.Fatal(err)

Loading…
Cancel
Save