wgengine/router: take a link monitor

Prep for #1591 which will need to make Linux's router react to changes
that the link monitor observes.

The router package already depended on the monitor package
transitively. Now it's explicit.

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
pull/2467/head
Brad Fitzpatrick 3 years ago committed by Brad Fitzpatrick
parent 24db1a3c9b
commit ed8587f90d

@ -349,7 +349,7 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
return nil, false, err
}
conf.Tun = dev
r, err := router.New(logf, dev)
r, err := router.New(logf, dev, linkMon)
if err != nil {
dev.Close()
return nil, false, err

@ -168,7 +168,7 @@ func startIPNServer(ctx context.Context, logid string) error {
if err != nil {
return nil, fmt.Errorf("TUN: %w", err)
}
r, err := router.New(logf, dev)
r, err := router.New(logf, dev, nil)
if err != nil {
dev.Close()
return nil, fmt.Errorf("router: %w", err)

@ -11,6 +11,7 @@ import (
"inet.af/netaddr"
"tailscale.com/types/logger"
"tailscale.com/types/preftype"
"tailscale.com/wgengine/monitor"
)
// Router is responsible for managing the system network stack.
@ -31,9 +32,12 @@ type Router interface {
// New returns a new Router for the current platform, using the
// provided tun device.
func New(logf logger.Logf, tundev tun.Device) (Router, error) {
//
// If linkMon is nil, it's not used. It's currently (2021-07-20) only
// used on Linux in some situations.
func New(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
logf = logger.WithPrefix(logf, "router: ")
return newUserspaceRouter(logf, tundev)
return newUserspaceRouter(logf, tundev, linkMon)
}
// Cleanup restores the system network configuration to its original state

@ -7,10 +7,11 @@ package router
import (
"golang.zx2c4.com/wireguard/tun"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return newUserspaceBSDRouter(logf, tundev)
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
return newUserspaceBSDRouter(logf, tundev, linkMon)
}
func cleanup(logger.Logf, string) {

@ -7,12 +7,16 @@
package router
import (
"fmt"
"runtime"
"golang.zx2c4.com/wireguard/tun"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
func newUserspaceRouter(logf logger.Logf, tunname string, tunDev tun.Device, netChanged func()) Router {
return NewFakeRouter(logf, tunname, tunDev, netChanged)
func newUserspaceRouter(logf logger.Logf, tunname string, tunDev tun.Device, linkMon *monitor.Mon) Router {
panic(fmt.Sprintf("unsupported OS %q", runtime.GOOS))
}
func cleanup(logf logger.Logf, interfaceName string) {

@ -7,6 +7,7 @@ package router
import (
"golang.zx2c4.com/wireguard/tun"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
// For now this router only supports the userspace WireGuard implementations.
@ -14,8 +15,8 @@ import (
// Work is currently underway for an in-kernel FreeBSD implementation of wireguard
// https://svnweb.freebsd.org/base?view=revision&revision=357986
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return newUserspaceBSDRouter(logf, tundev)
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
return newUserspaceBSDRouter(logf, tundev, linkMon)
}
func cleanup(logf logger.Logf, interfaceName string) {

@ -22,6 +22,7 @@ import (
"tailscale.com/types/logger"
"tailscale.com/types/preftype"
"tailscale.com/version/distro"
"tailscale.com/wgengine/monitor"
)
const (
@ -96,6 +97,7 @@ type netfilterRunner interface {
type linuxRouter struct {
logf func(fmt string, args ...interface{})
tunname string
linkMon *monitor.Mon
addrs map[netaddr.IPPrefix]bool
routes map[netaddr.IPPrefix]bool
localRoutes map[netaddr.IPPrefix]bool
@ -112,7 +114,7 @@ type linuxRouter struct {
cmd commandRunner
}
func newUserspaceRouter(logf logger.Logf, tunDev tun.Device) (Router, error) {
func newUserspaceRouter(logf logger.Logf, tunDev tun.Device, linkMon *monitor.Mon) (Router, error) {
tunname, err := tunDev.Name()
if err != nil {
return nil, err
@ -143,16 +145,17 @@ func newUserspaceRouter(logf logger.Logf, tunDev tun.Device) (Router, error) {
}
}
return newUserspaceRouterAdvanced(logf, tunname, ipt4, ipt6, osCommandRunner{}, supportsV6, supportsV6NAT)
return newUserspaceRouterAdvanced(logf, tunname, linkMon, ipt4, ipt6, osCommandRunner{}, supportsV6, supportsV6NAT)
}
func newUserspaceRouterAdvanced(logf logger.Logf, tunname string, 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)
return &linuxRouter{
logf: logf,
tunname: tunname,
netfilterMode: netfilterOff,
linkMon: linkMon,
ipRuleAvailable: ipRuleAvailable,
v6Available: supportsV6,

@ -18,6 +18,8 @@ import (
"github.com/google/go-cmp/cmp"
"golang.zx2c4.com/wireguard/tun"
"inet.af/netaddr"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
func TestRouterStates(t *testing.T) {
@ -314,8 +316,15 @@ ip route add throw 192.168.0.0/24 table 52` + basic,
},
}
mon, err := monitor.New(logger.Discard)
if err != nil {
t.Fatal(err)
}
mon.Start()
defer mon.Close()
fake := NewFakeOS(t)
router, err := newUserspaceRouterAdvanced(t.Logf, "tailscale0", fake.netfilter4, fake.netfilter6, fake, true, true)
router, err := newUserspaceRouterAdvanced(t.Logf, "tailscale0", mon, fake.netfilter4, fake.netfilter6, fake, true, true)
if err != nil {
t.Fatalf("failed to create router: %v", err)
}
@ -659,7 +668,14 @@ func TestDelRouteIdempotent(t *testing.T) {
}
}
r, err := newUserspaceRouter(logf, tun)
mon, err := monitor.New(logger.Discard)
if err != nil {
t.Fatal(err)
}
mon.Start()
defer mon.Close()
r, err := newUserspaceRouter(logf, tun, mon)
if err != nil {
t.Fatal(err)
}

@ -13,6 +13,7 @@ import (
"golang.zx2c4.com/wireguard/tun"
"inet.af/netaddr"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
// For now this router only supports the WireGuard userspace implementation.
@ -21,13 +22,14 @@ import (
type openbsdRouter struct {
logf logger.Logf
linkMon *monitor.Mon
tunname string
local4 netaddr.IPPrefix
local6 netaddr.IPPrefix
routes map[netaddr.IPPrefix]struct{}
}
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
tunname, err := tundev.Name()
if err != nil {
return nil, err
@ -35,6 +37,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return &openbsdRouter{
logf: logf,
linkMon: linkMon,
tunname: tunname,
}, nil
}

@ -17,16 +17,18 @@ import (
"tailscale.com/net/tsaddr"
"tailscale.com/types/logger"
"tailscale.com/version"
"tailscale.com/wgengine/monitor"
)
type userspaceBSDRouter struct {
logf logger.Logf
linkMon *monitor.Mon
tunname string
local []netaddr.IPPrefix
routes map[netaddr.IPPrefix]struct{}
}
func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
tunname, err := tundev.Name()
if err != nil {
return nil, err
@ -34,6 +36,7 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error)
return &userspaceBSDRouter{
logf: logf,
linkMon: linkMon,
tunname: tunname,
}, nil
}

@ -24,16 +24,18 @@ import (
"tailscale.com/logtail/backoff"
"tailscale.com/net/dns"
"tailscale.com/types/logger"
"tailscale.com/wgengine/monitor"
)
type winRouter struct {
logf func(fmt string, args ...interface{})
linkMon *monitor.Mon // may be nil
nativeTun *tun.NativeTun
routeChangeCallback *winipcfg.RouteChangeCallback
firewall *firewallTweaker
}
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
nativeTun := tundev.(*tun.NativeTun)
luid := winipcfg.LUID(nativeTun.LUID())
guid, err := luid.GUID()
@ -43,6 +45,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
return &winRouter{
logf: logf,
linkMon: linkMon,
nativeTun: nativeTun,
firewall: &firewallTweaker{
logf: logger.WithPrefix(logf, "firewall: "),

Loading…
Cancel
Save