Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aee2387d6e | ||
|
|
6f99ad1630 | ||
|
|
c654662250 | ||
|
|
bcb979f8bf | ||
|
|
6db09061bc | ||
|
|
1b9fbdc057 | ||
|
|
71f1dd5aa2 |
@@ -1 +1 @@
|
||||
1.17.0
|
||||
1.18.1
|
||||
|
||||
@@ -440,14 +440,14 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
|
||||
log.Printf("Connecting to BIRD at %s ...", args.birdSocketPath)
|
||||
conf.BIRDClient, err = createBIRDClient(args.birdSocketPath)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("createBIRDClient: %w", err)
|
||||
}
|
||||
}
|
||||
if !useNetstack {
|
||||
dev, devName, err := tstun.New(logf, name)
|
||||
if err != nil {
|
||||
tstun.Diagnose(logf, name)
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("tstun.New(%q): %w", name, err)
|
||||
}
|
||||
conf.Tun = dev
|
||||
if strings.HasPrefix(name, "tap:") {
|
||||
@@ -459,11 +459,11 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
|
||||
r, err := router.New(logf, dev, linkMon)
|
||||
if err != nil {
|
||||
dev.Close()
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("creating router: %w", err)
|
||||
}
|
||||
d, err := dns.NewOSConfigurator(logf, devName)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
return nil, false, fmt.Errorf("dns.NewOSConfigurator: %w", err)
|
||||
}
|
||||
conf.DNS = d
|
||||
conf.Router = r
|
||||
|
||||
@@ -99,7 +99,7 @@ type linuxRouter struct {
|
||||
ipRuleFixLimiter *rate.Limiter
|
||||
|
||||
// Various feature checks for the network stack.
|
||||
ipRuleAvailable bool
|
||||
ipRuleAvailable bool // whether kernel was built with IP_MULTIPLE_TABLES
|
||||
v6Available bool
|
||||
v6NATAvailable bool
|
||||
|
||||
@@ -119,7 +119,7 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mo
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v6err := checkIPv6()
|
||||
v6err := checkIPv6(logf)
|
||||
if v6err != nil {
|
||||
logf("disabling tunneled IPv6 due to system IPv6 config: %v", v6err)
|
||||
}
|
||||
@@ -165,8 +165,13 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monit
|
||||
if r.useIPCommand() {
|
||||
r.ipRuleAvailable = (cmd.run("ip", "rule") == nil)
|
||||
} else {
|
||||
// Pretend it is.
|
||||
r.ipRuleAvailable = true
|
||||
if rules, err := netlink.RuleList(netlink.FAMILY_V4); err != nil {
|
||||
r.logf("error querying IP rules (does kernel have IP_MULTIPLE_TABLES?): %v", err)
|
||||
r.logf("warning: running without policy routing")
|
||||
} else {
|
||||
r.logf("[v1] policy routing available; found %d rules", len(rules))
|
||||
r.ipRuleAvailable = true
|
||||
}
|
||||
}
|
||||
|
||||
return r, nil
|
||||
@@ -245,13 +250,13 @@ func (r *linuxRouter) Up() error {
|
||||
return err
|
||||
}
|
||||
if err := r.addIPRules(); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("adding IP rules: %w", err)
|
||||
}
|
||||
if err := r.setNetfilterMode(netfilterOff); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("setting netfilter mode: %w", err)
|
||||
}
|
||||
if err := r.upInterface(); err != nil {
|
||||
return err
|
||||
return fmt.Errorf("bringing interface up: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -1487,7 +1492,7 @@ func cleanup(logf logger.Logf, interfaceName string) {
|
||||
// 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() error {
|
||||
func checkIPv6(logf logger.Logf) error {
|
||||
_, err := os.Stat("/proc/sys/net/ipv6")
|
||||
if os.IsNotExist(err) {
|
||||
return err
|
||||
@@ -1519,7 +1524,7 @@ func checkIPv6() error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := checkIPRuleSupportsV6(); err != nil {
|
||||
if err := checkIPRuleSupportsV6(logf); err != nil {
|
||||
return fmt.Errorf("kernel doesn't support IPv6 policy routing: %w", err)
|
||||
}
|
||||
|
||||
@@ -1547,11 +1552,24 @@ func supportsV6NAT() bool {
|
||||
return bytes.Contains(bs, []byte("nat\n"))
|
||||
}
|
||||
|
||||
func checkIPRuleSupportsV6() error {
|
||||
func checkIPRuleSupportsV6(logf logger.Logf) error {
|
||||
// First try just a read-only operation to ideally avoid
|
||||
// having to modify any state.
|
||||
if rules, err := netlink.RuleList(netlink.FAMILY_V6); err != nil {
|
||||
return fmt.Errorf("querying IPv6 policy routing rules: %w", err)
|
||||
} else {
|
||||
if len(rules) > 0 {
|
||||
logf("[v1] kernel supports IPv6 policy routing (found %d rules)", len(rules))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Try to actually create & delete one as a test.
|
||||
rule := netlink.NewRule()
|
||||
rule.Priority = 1234
|
||||
rule.Mark = tailscaleBypassMarkNum
|
||||
rule.Table = tailscaleRouteTable.num
|
||||
rule.Family = netlink.FAMILY_V6
|
||||
// First delete the rule unconditionally, and don't check for
|
||||
// errors. This is just cleaning up anything that might be already
|
||||
// there.
|
||||
|
||||
@@ -793,7 +793,7 @@ func TestDebugListRules(t *testing.T) {
|
||||
t.Run(famName[fam], func(t *testing.T) {
|
||||
rules, err := netlink.RuleList(fam)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
t.Skipf("skip; RuleList fails with: %v", err)
|
||||
}
|
||||
for _, r := range rules {
|
||||
t.Logf("Rule: %+v", r)
|
||||
@@ -803,7 +803,7 @@ func TestDebugListRules(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCheckIPRuleSupportsV6(t *testing.T) {
|
||||
err := checkIPRuleSupportsV6()
|
||||
err := checkIPRuleSupportsV6(t.Logf)
|
||||
if err != nil && os.Getuid() != 0 {
|
||||
t.Skipf("skipping, error when not root: %v", err)
|
||||
}
|
||||
|
||||
@@ -389,11 +389,11 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
|
||||
e.logf("Bringing wireguard device up...")
|
||||
if err := e.wgdev.Up(); err != nil {
|
||||
return nil, fmt.Errorf("wgdev.Up(): %w", err)
|
||||
return nil, fmt.Errorf("wgdev.Up: %w", err)
|
||||
}
|
||||
e.logf("Bringing router up...")
|
||||
if err := e.router.Up(); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("router.Up: %w", err)
|
||||
}
|
||||
|
||||
// It's a little pointless to apply no-op settings here (they
|
||||
@@ -401,7 +401,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
||||
// router implementation early on.
|
||||
e.logf("Clearing router settings...")
|
||||
if err := e.router.Set(nil); err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("router.Set(nil): %w", err)
|
||||
}
|
||||
e.logf("Starting link monitor...")
|
||||
e.linkMon.Start()
|
||||
|
||||
Reference in New Issue
Block a user