mirror of
https://github.com/tailscale/tailscale.git
synced 2025-05-05 23:21:00 +00:00
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>
This commit is contained in:
parent
24db1a3c9b
commit
ed8587f90d
@ -349,7 +349,7 @@ func tryEngine(logf logger.Logf, linkMon *monitor.Mon, name string) (e wgengine.
|
|||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
conf.Tun = dev
|
conf.Tun = dev
|
||||||
r, err := router.New(logf, dev)
|
r, err := router.New(logf, dev, linkMon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dev.Close()
|
dev.Close()
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
@ -168,7 +168,7 @@ func startIPNServer(ctx context.Context, logid string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("TUN: %w", err)
|
return nil, fmt.Errorf("TUN: %w", err)
|
||||||
}
|
}
|
||||||
r, err := router.New(logf, dev)
|
r, err := router.New(logf, dev, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
dev.Close()
|
dev.Close()
|
||||||
return nil, fmt.Errorf("router: %w", err)
|
return nil, fmt.Errorf("router: %w", err)
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/preftype"
|
"tailscale.com/types/preftype"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Router is responsible for managing the system network stack.
|
// 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
|
// New returns a new Router for the current platform, using the
|
||||||
// provided tun device.
|
// 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: ")
|
logf = logger.WithPrefix(logf, "router: ")
|
||||||
return newUserspaceRouter(logf, tundev)
|
return newUserspaceRouter(logf, tundev, linkMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup restores the system network configuration to its original state
|
// Cleanup restores the system network configuration to its original state
|
||||||
|
@ -7,10 +7,11 @@ package router
|
|||||||
import (
|
import (
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
|
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
|
||||||
return newUserspaceBSDRouter(logf, tundev)
|
return newUserspaceBSDRouter(logf, tundev, linkMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup(logger.Logf, string) {
|
func cleanup(logger.Logf, string) {
|
||||||
|
@ -7,12 +7,16 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newUserspaceRouter(logf logger.Logf, tunname string, tunDev tun.Device, netChanged func()) Router {
|
func newUserspaceRouter(logf logger.Logf, tunname string, tunDev tun.Device, linkMon *monitor.Mon) Router {
|
||||||
return NewFakeRouter(logf, tunname, tunDev, netChanged)
|
panic(fmt.Sprintf("unsupported OS %q", runtime.GOOS))
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup(logf logger.Logf, interfaceName string) {
|
func cleanup(logf logger.Logf, interfaceName string) {
|
||||||
|
@ -7,6 +7,7 @@ package router
|
|||||||
import (
|
import (
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
// For now this router only supports the userspace WireGuard implementations.
|
// 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
|
// Work is currently underway for an in-kernel FreeBSD implementation of wireguard
|
||||||
// https://svnweb.freebsd.org/base?view=revision&revision=357986
|
// https://svnweb.freebsd.org/base?view=revision&revision=357986
|
||||||
|
|
||||||
func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
|
func newUserspaceRouter(logf logger.Logf, tundev tun.Device, linkMon *monitor.Mon) (Router, error) {
|
||||||
return newUserspaceBSDRouter(logf, tundev)
|
return newUserspaceBSDRouter(logf, tundev, linkMon)
|
||||||
}
|
}
|
||||||
|
|
||||||
func cleanup(logf logger.Logf, interfaceName string) {
|
func cleanup(logf logger.Logf, interfaceName string) {
|
||||||
|
@ -22,6 +22,7 @@ import (
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/preftype"
|
"tailscale.com/types/preftype"
|
||||||
"tailscale.com/version/distro"
|
"tailscale.com/version/distro"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -96,6 +97,7 @@ type netfilterRunner interface {
|
|||||||
type linuxRouter struct {
|
type linuxRouter struct {
|
||||||
logf func(fmt string, args ...interface{})
|
logf func(fmt string, args ...interface{})
|
||||||
tunname string
|
tunname string
|
||||||
|
linkMon *monitor.Mon
|
||||||
addrs map[netaddr.IPPrefix]bool
|
addrs map[netaddr.IPPrefix]bool
|
||||||
routes map[netaddr.IPPrefix]bool
|
routes map[netaddr.IPPrefix]bool
|
||||||
localRoutes map[netaddr.IPPrefix]bool
|
localRoutes map[netaddr.IPPrefix]bool
|
||||||
@ -112,7 +114,7 @@ type linuxRouter struct {
|
|||||||
cmd commandRunner
|
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()
|
tunname, err := tunDev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
ipRuleAvailable := (cmd.run("ip", "rule") == nil)
|
||||||
|
|
||||||
return &linuxRouter{
|
return &linuxRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
netfilterMode: netfilterOff,
|
netfilterMode: netfilterOff,
|
||||||
|
linkMon: linkMon,
|
||||||
|
|
||||||
ipRuleAvailable: ipRuleAvailable,
|
ipRuleAvailable: ipRuleAvailable,
|
||||||
v6Available: supportsV6,
|
v6Available: supportsV6,
|
||||||
|
@ -18,6 +18,8 @@ import (
|
|||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRouterStates(t *testing.T) {
|
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)
|
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 {
|
if err != nil {
|
||||||
t.Fatalf("failed to create router: %v", err)
|
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 {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"golang.zx2c4.com/wireguard/tun"
|
"golang.zx2c4.com/wireguard/tun"
|
||||||
"inet.af/netaddr"
|
"inet.af/netaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
// For now this router only supports the WireGuard userspace implementation.
|
// For now this router only supports the WireGuard userspace implementation.
|
||||||
@ -21,13 +22,14 @@ import (
|
|||||||
|
|
||||||
type openbsdRouter struct {
|
type openbsdRouter struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
|
linkMon *monitor.Mon
|
||||||
tunname string
|
tunname string
|
||||||
local4 netaddr.IPPrefix
|
local4 netaddr.IPPrefix
|
||||||
local6 netaddr.IPPrefix
|
local6 netaddr.IPPrefix
|
||||||
routes map[netaddr.IPPrefix]struct{}
|
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()
|
tunname, err := tundev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -35,6 +37,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
|
|||||||
|
|
||||||
return &openbsdRouter{
|
return &openbsdRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
|
linkMon: linkMon,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,18 @@ import (
|
|||||||
"tailscale.com/net/tsaddr"
|
"tailscale.com/net/tsaddr"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
type userspaceBSDRouter struct {
|
type userspaceBSDRouter struct {
|
||||||
logf logger.Logf
|
logf logger.Logf
|
||||||
|
linkMon *monitor.Mon
|
||||||
tunname string
|
tunname string
|
||||||
local []netaddr.IPPrefix
|
local []netaddr.IPPrefix
|
||||||
routes map[netaddr.IPPrefix]struct{}
|
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()
|
tunname, err := tundev.Name()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -34,6 +36,7 @@ func newUserspaceBSDRouter(logf logger.Logf, tundev tun.Device) (Router, error)
|
|||||||
|
|
||||||
return &userspaceBSDRouter{
|
return &userspaceBSDRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
|
linkMon: linkMon,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
@ -24,16 +24,18 @@ import (
|
|||||||
"tailscale.com/logtail/backoff"
|
"tailscale.com/logtail/backoff"
|
||||||
"tailscale.com/net/dns"
|
"tailscale.com/net/dns"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/wgengine/monitor"
|
||||||
)
|
)
|
||||||
|
|
||||||
type winRouter struct {
|
type winRouter struct {
|
||||||
logf func(fmt string, args ...interface{})
|
logf func(fmt string, args ...interface{})
|
||||||
|
linkMon *monitor.Mon // may be nil
|
||||||
nativeTun *tun.NativeTun
|
nativeTun *tun.NativeTun
|
||||||
routeChangeCallback *winipcfg.RouteChangeCallback
|
routeChangeCallback *winipcfg.RouteChangeCallback
|
||||||
firewall *firewallTweaker
|
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)
|
nativeTun := tundev.(*tun.NativeTun)
|
||||||
luid := winipcfg.LUID(nativeTun.LUID())
|
luid := winipcfg.LUID(nativeTun.LUID())
|
||||||
guid, err := luid.GUID()
|
guid, err := luid.GUID()
|
||||||
@ -43,6 +45,7 @@ func newUserspaceRouter(logf logger.Logf, tundev tun.Device) (Router, error) {
|
|||||||
|
|
||||||
return &winRouter{
|
return &winRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
|
linkMon: linkMon,
|
||||||
nativeTun: nativeTun,
|
nativeTun: nativeTun,
|
||||||
firewall: &firewallTweaker{
|
firewall: &firewallTweaker{
|
||||||
logf: logger.WithPrefix(logf, "firewall: "),
|
logf: logger.WithPrefix(logf, "firewall: "),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user