wgengine/router: remove last non-test "ip" command usage on Linux
Updates #391 Change-Id: Ic2c3f8460b1e4b8d34b936a1725705fcc1effbae Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>pull/3239/head
parent
ff1954cfd9
commit
408b0923a6
|
@ -147,17 +147,14 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mo
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monitor.Mon, netfilter4, netfilter6 netfilterRunner, cmd commandRunner, supportsV6, supportsV6NAT bool) (Router, error) {
|
func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monitor.Mon, netfilter4, netfilter6 netfilterRunner, cmd commandRunner, supportsV6, supportsV6NAT bool) (Router, error) {
|
||||||
ipRuleAvailable := (cmd.run("ip", "rule") == nil)
|
|
||||||
|
|
||||||
r := &linuxRouter{
|
r := &linuxRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
netfilterMode: netfilterOff,
|
netfilterMode: netfilterOff,
|
||||||
linkMon: linkMon,
|
linkMon: linkMon,
|
||||||
|
|
||||||
ipRuleAvailable: ipRuleAvailable,
|
v6Available: supportsV6,
|
||||||
v6Available: supportsV6,
|
v6NATAvailable: supportsV6NAT,
|
||||||
v6NATAvailable: supportsV6NAT,
|
|
||||||
|
|
||||||
ipt4: netfilter4,
|
ipt4: netfilter4,
|
||||||
ipt6: netfilter6,
|
ipt6: netfilter6,
|
||||||
|
@ -165,6 +162,12 @@ func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, linkMon *monit
|
||||||
|
|
||||||
ipRuleFixLimiter: rate.NewLimiter(rate.Every(5*time.Second), 10),
|
ipRuleFixLimiter: rate.NewLimiter(rate.Every(5*time.Second), 10),
|
||||||
}
|
}
|
||||||
|
if r.useIPCommand() {
|
||||||
|
r.ipRuleAvailable = (cmd.run("ip", "rule") == nil)
|
||||||
|
} else {
|
||||||
|
// Pretend it is.
|
||||||
|
r.ipRuleAvailable = true
|
||||||
|
}
|
||||||
|
|
||||||
return r, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
@ -183,6 +186,9 @@ func useAmbientCaps() bool {
|
||||||
// useIPCommand reports whether r should use the "ip" command (or its
|
// useIPCommand reports whether r should use the "ip" command (or its
|
||||||
// fake commandRunner for tests) instead of netlink.
|
// fake commandRunner for tests) instead of netlink.
|
||||||
func (r *linuxRouter) useIPCommand() bool {
|
func (r *linuxRouter) useIPCommand() bool {
|
||||||
|
if r.cmd == nil {
|
||||||
|
panic("invalid init")
|
||||||
|
}
|
||||||
// In the future we might need to fall back to using the "ip"
|
// In the future we might need to fall back to using the "ip"
|
||||||
// command if, say, netlink is blocked somewhere but the ip
|
// command if, say, netlink is blocked somewhere but the ip
|
||||||
// command is allowed to use netlink. For now we only use the ip
|
// command is allowed to use netlink. For now we only use the ip
|
||||||
|
@ -1537,29 +1543,17 @@ func supportsV6NAT() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkIPRuleSupportsV6() error {
|
func checkIPRuleSupportsV6() error {
|
||||||
add := []string{"-6", "rule", "add", "pref", "1234", "fwmark", tailscaleBypassMark, "table", tailscaleRouteTable.ipCmdArg()}
|
rule := netlink.NewRule()
|
||||||
del := []string{"-6", "rule", "del", "pref", "1234", "fwmark", tailscaleBypassMark, "table", tailscaleRouteTable.ipCmdArg()}
|
rule.Priority = 1234
|
||||||
|
rule.Mark = tailscaleBypassMarkNum
|
||||||
|
rule.Table = tailscaleRouteTable.num
|
||||||
// First delete the rule unconditionally, and don't check for
|
// First delete the rule unconditionally, and don't check for
|
||||||
// errors. This is just cleaning up anything that might be already
|
// errors. This is just cleaning up anything that might be already
|
||||||
// there.
|
// there.
|
||||||
exec.Command("ip", del...).Run()
|
netlink.RuleDel(rule)
|
||||||
|
// And clean up on exit.
|
||||||
// Try adding the rule. This will fail on systems that support
|
defer netlink.RuleDel(rule)
|
||||||
// IPv6, but not IPv6 policy routing.
|
return netlink.RuleAdd(rule)
|
||||||
out, err := exec.Command("ip", add...).CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
out = bytes.TrimSpace(out)
|
|
||||||
var detail interface{} = out
|
|
||||||
if len(out) == 0 {
|
|
||||||
detail = err.Error()
|
|
||||||
}
|
|
||||||
return fmt.Errorf("ip -6 rule failed: %s", detail)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delete again.
|
|
||||||
exec.Command("ip", del...).Run()
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func nlAddrOfPrefix(p netaddr.IPPrefix) *netlink.Addr {
|
func nlAddrOfPrefix(p netaddr.IPPrefix) *netlink.Addr {
|
||||||
|
|
|
@ -801,3 +801,13 @@ func TestDebugListRules(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCheckIPRuleSupportsV6(t *testing.T) {
|
||||||
|
err := checkIPRuleSupportsV6()
|
||||||
|
if err != nil && os.Getuid() != 0 {
|
||||||
|
t.Skipf("skipping, error when not root: %v", err)
|
||||||
|
}
|
||||||
|
// Just log it. For interactive testing only.
|
||||||
|
// Some machines running our tests might not have IPv6.
|
||||||
|
t.Logf("Got: %v", err)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue