mirror of
https://github.com/tailscale/tailscale.git
synced 2025-01-07 08:07:42 +00:00
wgengine: simplify, change some signatures
* make RouterGen return an error, not take both tunname and tundev * also remove RouteGen taking a wireguard/device.Device; currently unused * remove derp parameter (it'll work differently) * unexport NewUserspaceRouter in per-OS impls, add documented wrapper Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
9dbc52bb5b
commit
79295b1138
@ -53,7 +53,6 @@ func main() {
|
|||||||
droutes := getopt.BoolLong("default-routes", 'D', "allow default route on remote node")
|
droutes := getopt.BoolLong("default-routes", 'D', "allow default route on remote node")
|
||||||
routes := getopt.StringLong("routes", 0, "", "list of IP ranges this node can relay")
|
routes := getopt.StringLong("routes", 0, "", "list of IP ranges this node can relay")
|
||||||
aclfile := getopt.StringLong("acl-file", 0, "", "restrict traffic relaying according to json ACL file")
|
aclfile := getopt.StringLong("acl-file", 0, "", "restrict traffic relaying according to json ACL file")
|
||||||
derp := getopt.BoolLong("derp", 0, "enable bypass via Detour Encrypted Routing Protocol (DERP)", "false")
|
|
||||||
debug := getopt.StringLong("debug", 0, "", "Address of debug server")
|
debug := getopt.StringLong("debug", 0, "", "Address of debug server")
|
||||||
getopt.Parse()
|
getopt.Parse()
|
||||||
if len(getopt.Args()) > 0 {
|
if len(getopt.Args()) > 0 {
|
||||||
@ -75,9 +74,9 @@ func main() {
|
|||||||
// controlclient, and runs the actual tunnels and packets.
|
// controlclient, and runs the actual tunnels and packets.
|
||||||
var e wgengine.Engine
|
var e wgengine.Engine
|
||||||
if *fake {
|
if *fake {
|
||||||
e, err = wgengine.NewFakeUserspaceEngine(logf, *listenport, *derp)
|
e, err = wgengine.NewFakeUserspaceEngine(logf, *listenport)
|
||||||
} else {
|
} else {
|
||||||
e, err = wgengine.NewUserspaceEngine(logf, *tunname, *listenport, *derp)
|
e, err = wgengine.NewUserspaceEngine(logf, *tunname, *listenport)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error starting wireguard engine: %v\n", err)
|
log.Fatalf("Error starting wireguard engine: %v\n", err)
|
||||||
|
@ -49,9 +49,9 @@ func main() {
|
|||||||
|
|
||||||
var e wgengine.Engine
|
var e wgengine.Engine
|
||||||
if *fake {
|
if *fake {
|
||||||
e, err = wgengine.NewFakeUserspaceEngine(logf, 0, false)
|
e, err = wgengine.NewFakeUserspaceEngine(logf, 0)
|
||||||
} else {
|
} else {
|
||||||
e, err = wgengine.NewUserspaceEngine(logf, *tunname, *listenport, false)
|
e, err = wgengine.NewUserspaceEngine(logf, *tunname, *listenport)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("wgengine.New: %v\n", err)
|
log.Fatalf("wgengine.New: %v\n", err)
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build linux freebsd
|
||||||
|
|
||||||
// Package monitor provides facilities for monitoring network
|
// Package monitor provides facilities for monitoring network
|
||||||
// interface changes.
|
// interface changes.
|
||||||
package monitor
|
package monitor
|
||||||
|
@ -34,12 +34,15 @@ type bsdRouter struct {
|
|||||||
routes map[wgcfg.CIDR]struct{}
|
routes map[wgcfg.CIDR]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserspaceRouter(logf logger.Logf, tunname string, _ *device.Device, tuntap tun.Device, _ func()) Router {
|
func newUserspaceRouter(logf logger.Logf, _ *device.Device, tundev tun.Device, _ func()) (Router, error) {
|
||||||
r := bsdRouter{
|
tunname, err := tundev.Name()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &bsdRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
}
|
}, nil
|
||||||
return &r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mbaillie): extract as identical to linux version
|
// TODO(mbaillie): extract as identical to linux version
|
||||||
|
@ -14,11 +14,12 @@ type darwinRouter struct {
|
|||||||
tunname string
|
tunname string
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserspaceRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
func newUserspaceRouter(logf logger.Logf, _ *device.Device, tundev tun.Device, netChanged func()) (Router, error) {
|
||||||
r := darwinRouter{
|
tunname, err := tundev.Name()
|
||||||
tunname: tunname,
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
return &r
|
return &darwinRouter{tunname: tunname}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *darwinRouter) Up() error {
|
func (r *darwinRouter) Up() error {
|
||||||
|
@ -12,6 +12,6 @@
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewUserspaceRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
func newUserspaceRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
||||||
return NewFakeRouter(logf, tunname, dev, tuntap, netChanged)
|
return NewFakeRouter(logf, tunname, dev, tuntap, netChanged)
|
||||||
}
|
}
|
||||||
|
@ -10,29 +10,27 @@
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NewFakeRouter returns a new fake Router implementation whose
|
||||||
|
// implementation does nothing and always returns nil errors.
|
||||||
|
func NewFakeRouter(logf logger.Logf, _ *device.Device, _ tun.Device, netChanged func()) (Router, error) {
|
||||||
|
return fakeRouter{logf: logf}, nil
|
||||||
|
}
|
||||||
|
|
||||||
type fakeRouter struct {
|
type fakeRouter struct {
|
||||||
tunname string
|
logf logger.Logf
|
||||||
logf logger.Logf
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFakeRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
func (r fakeRouter) Up() error {
|
||||||
return &fakeRouter{
|
|
||||||
logf: logf,
|
|
||||||
tunname: tunname,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *fakeRouter) Up() error {
|
|
||||||
r.logf("Warning: fakeRouter.Up: not implemented.\n")
|
r.logf("Warning: fakeRouter.Up: not implemented.\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *fakeRouter) SetRoutes(rs RouteSettings) error {
|
func (r fakeRouter) SetRoutes(rs RouteSettings) error {
|
||||||
r.logf("Warning: fakeRouter.SetRoutes: not implemented.\n")
|
r.logf("Warning: fakeRouter.SetRoutes: not implemented.\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *fakeRouter) Close() error {
|
func (r fakeRouter) Close() error {
|
||||||
r.logf("Warning: fakeRouter.Close: not implemented.\n")
|
r.logf("Warning: fakeRouter.Close: not implemented.\n")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -32,19 +32,24 @@ type linuxRouter struct {
|
|||||||
routes map[wgcfg.CIDR]struct{}
|
routes map[wgcfg.CIDR]struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserspaceRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
func newUserspaceRouter(logf logger.Logf, _ *device.Device, tunDev tun.Device, netChanged func()) (Router, error) {
|
||||||
|
// TODO: move monitor out of Router, make it created/owned by Engine
|
||||||
mon, err := monitor.New(logf, netChanged)
|
mon, err := monitor.New(logf, netChanged)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("rtnlmon.New() failed: %v", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
r := linuxRouter{
|
tunname, err := tunDev.Name()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &linuxRouter{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
tunname: tunname,
|
tunname: tunname,
|
||||||
mon: mon,
|
mon: mon,
|
||||||
netChanged: netChanged,
|
netChanged: netChanged,
|
||||||
}
|
}, nil
|
||||||
return &r
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func cmd(args ...string) *exec.Cmd {
|
func cmd(args ...string) *exec.Cmd {
|
||||||
|
@ -16,26 +16,29 @@
|
|||||||
type winRouter struct {
|
type winRouter struct {
|
||||||
logf func(fmt string, args ...interface{})
|
logf func(fmt string, args ...interface{})
|
||||||
tunname string
|
tunname string
|
||||||
dev *device.Device
|
|
||||||
nativeTun *tun.NativeTun
|
nativeTun *tun.NativeTun
|
||||||
|
wgdev *device.Device
|
||||||
routeChangeCallback *winipcfg.RouteChangeCallback
|
routeChangeCallback *winipcfg.RouteChangeCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserspaceRouter(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netChanged func()) Router {
|
func newUserspaceRouter(logf logger.Logf, wgdev *device.Device, tundev tun.Device, netChanged func()) (Router, error) {
|
||||||
r := winRouter{
|
tunname, err := tundev.Name()
|
||||||
logf: logf,
|
if err != nil {
|
||||||
tunname: tunname,
|
return nil, err
|
||||||
dev: dev,
|
|
||||||
nativeTun: tuntap.(*tun.NativeTun),
|
|
||||||
}
|
}
|
||||||
return &r
|
return &winRouter{
|
||||||
|
logf: logf,
|
||||||
|
wgdev: wgdev,
|
||||||
|
tunname: tunname,
|
||||||
|
nativeTun: tundev.(*tun.NativeTun),
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *winRouter) Up() error {
|
func (r *winRouter) Up() error {
|
||||||
// MonitorDefaultRoutes handles making sure our wireguard UDP
|
// MonitorDefaultRoutes handles making sure our wireguard UDP
|
||||||
// traffic goes through the old route, not recursively through the VPN.
|
// traffic goes through the old route, not recursively through the VPN.
|
||||||
var err error
|
var err error
|
||||||
r.routeChangeCallback, err = MonitorDefaultRoutes(r.dev, true, r.nativeTun)
|
r.routeChangeCallback, err = MonitorDefaultRoutes(r.wgdev, true, r.nativeTun)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("MonitorDefaultRoutes: %v\n", err)
|
log.Fatalf("MonitorDefaultRoutes: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ type userspaceEngine struct {
|
|||||||
statusCallback StatusCallback
|
statusCallback StatusCallback
|
||||||
reqCh chan struct{}
|
reqCh chan struct{}
|
||||||
waitCh chan struct{}
|
waitCh chan struct{}
|
||||||
tuntap tun.Device
|
tundev tun.Device
|
||||||
wgdev *device.Device
|
wgdev *device.Device
|
||||||
router Router
|
router Router
|
||||||
magicConn *magicsock.Conn
|
magicConn *magicsock.Conn
|
||||||
@ -51,13 +51,15 @@ func (l *Loggify) Write(b []byte) (int, error) {
|
|||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewFakeUserspaceEngine(logf logger.Logf, listenPort uint16, derp bool) (Engine, error) {
|
func NewFakeUserspaceEngine(logf logger.Logf, listenPort uint16) (Engine, error) {
|
||||||
logf("Starting userspace wireguard engine (FAKE tuntap device).")
|
logf("Starting userspace wireguard engine (FAKE tuntap device).")
|
||||||
tun := NewFakeTun()
|
tun := NewFakeTun()
|
||||||
return NewUserspaceEngineAdvanced(logf, tun, NewFakeRouter, listenPort, derp)
|
return NewUserspaceEngineAdvanced(logf, tun, NewFakeRouter, listenPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewUserspaceEngine(logf logger.Logf, tunname string, listenPort uint16, derp bool) (Engine, error) {
|
// NewUserspaceEngine creates the named tun device and returns a Tailscale Engine
|
||||||
|
// running on it.
|
||||||
|
func NewUserspaceEngine(logf logger.Logf, tunname string, listenPort uint16) (Engine, error) {
|
||||||
logf("Starting userspace wireguard engine.")
|
logf("Starting userspace wireguard engine.")
|
||||||
logf("external packet routing via --tun=%s enabled", tunname)
|
logf("external packet routing via --tun=%s enabled", tunname)
|
||||||
|
|
||||||
@ -65,34 +67,34 @@ func NewUserspaceEngine(logf logger.Logf, tunname string, listenPort uint16, der
|
|||||||
return nil, fmt.Errorf("--tun name must not be blank")
|
return nil, fmt.Errorf("--tun name must not be blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
tuntap, err := tun.CreateTUN(tunname, device.DefaultMTU)
|
tundev, err := tun.CreateTUN(tunname, device.DefaultMTU)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("CreateTUN: %v\n", err)
|
logf("CreateTUN: %v\n", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
logf("CreateTUN ok.\n")
|
logf("CreateTUN ok.\n")
|
||||||
|
|
||||||
e, err := NewUserspaceEngineAdvanced(logf, tuntap, NewUserspaceRouter, listenPort, derp)
|
e, err := NewUserspaceEngineAdvanced(logf, tundev, newUserspaceRouter, listenPort)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logf("NewUserspaceEngineAdv: %v\n", err)
|
logf("NewUserspaceEngineAdv: %v\n", err)
|
||||||
|
tundev.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return e, err
|
return e, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouterGen func(logf logger.Logf, tunname string, dev *device.Device, tuntap tun.Device, netStateChanged func()) Router
|
// NewUserspaceEngineAdvanced is like NewUserspaceEngine but takes a pre-created TUN device and allows specifing
|
||||||
|
// a custom router constructor and listening port.
|
||||||
|
func NewUserspaceEngineAdvanced(logf logger.Logf, tundev tun.Device, routerGen RouterGen, listenPort uint16) (Engine, error) {
|
||||||
|
return newUserspaceEngineAdvanced(logf, tundev, routerGen, listenPort)
|
||||||
|
}
|
||||||
|
|
||||||
func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen RouterGen, listenPort uint16, derp bool) (Engine, error) {
|
func newUserspaceEngineAdvanced(logf logger.Logf, tundev tun.Device, routerGen RouterGen, listenPort uint16) (_ Engine, reterr error) {
|
||||||
e := &userspaceEngine{
|
e := &userspaceEngine{
|
||||||
logf: logf,
|
logf: logf,
|
||||||
reqCh: make(chan struct{}, 1),
|
reqCh: make(chan struct{}, 1),
|
||||||
waitCh: make(chan struct{}),
|
waitCh: make(chan struct{}),
|
||||||
tuntap: tuntap,
|
tundev: tundev,
|
||||||
}
|
|
||||||
|
|
||||||
tunname, err := tuntap.Name()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
endpointsFn := func(endpoints []string) {
|
endpointsFn := func(endpoints []string) {
|
||||||
@ -111,9 +113,7 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
|
|||||||
// TODO(crawshaw): DERP: magicsock.DefaultDERP,
|
// TODO(crawshaw): DERP: magicsock.DefaultDERP,
|
||||||
EndpointsFunc: endpointsFn,
|
EndpointsFunc: endpointsFn,
|
||||||
}
|
}
|
||||||
if derp {
|
var err error
|
||||||
magicsockOpts.DERP = magicsock.DefaultDERP
|
|
||||||
}
|
|
||||||
e.magicConn, err = magicsock.Listen(magicsockOpts)
|
e.magicConn, err = magicsock.Listen(magicsockOpts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("wgengine: %v", err)
|
return nil, fmt.Errorf("wgengine: %v", err)
|
||||||
@ -155,13 +155,23 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
|
|||||||
SkipBindUpdate: true,
|
SkipBindUpdate: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
e.wgdev = device.NewDevice(e.tuntap, opts)
|
e.wgdev = device.NewDevice(e.tundev, opts)
|
||||||
|
defer func() {
|
||||||
|
if reterr != nil {
|
||||||
|
e.wgdev.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
e.router, err = routerGen(logf, e.wgdev, e.tundev, func() { e.LinkChange(false) })
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
up := false
|
up := false
|
||||||
for event := range e.tuntap.Events() {
|
for event := range e.tundev.Events() {
|
||||||
if event&tun.EventMTUUpdate != 0 {
|
if event&tun.EventMTUUpdate != 0 {
|
||||||
mtu, err := e.tuntap.MTU()
|
mtu, err := e.tundev.MTU()
|
||||||
e.logf("external route MTU: %d (%v)", mtu, err)
|
e.logf("external route MTU: %d (%v)", mtu, err)
|
||||||
}
|
}
|
||||||
if event&tun.EventUp != 0 && !up {
|
if event&tun.EventUp != 0 && !up {
|
||||||
@ -177,7 +187,6 @@ func NewUserspaceEngineAdvanced(logf logger.Logf, tuntap tun.Device, routerGen R
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
e.router = routerGen(logf, tunname, e.wgdev, e.tuntap, func() { e.LinkChange(false) })
|
|
||||||
e.wgdev.Up()
|
e.wgdev.Up()
|
||||||
if err := e.router.Up(); err != nil {
|
if err := e.router.Up(); err != nil {
|
||||||
e.wgdev.Close()
|
e.wgdev.Close()
|
||||||
@ -270,7 +279,7 @@ func (e *userspaceEngine) SetFilter(filt *filter.Filter) {
|
|||||||
if filt == nil {
|
if filt == nil {
|
||||||
e.logf("wgengine: nil filter provided; no access restrictions.\n")
|
e.logf("wgengine: nil filter provided; no access restrictions.\n")
|
||||||
} else {
|
} else {
|
||||||
ft, ft_ok := e.tuntap.(*fakeTun)
|
ft, ft_ok := e.tundev.(*fakeTun)
|
||||||
filtin = func(b []byte) device.FilterResult {
|
filtin = func(b []byte) device.FilterResult {
|
||||||
runf := filter.LogDrops
|
runf := filter.LogDrops
|
||||||
//runf |= filter.HexdumpDrops
|
//runf |= filter.HexdumpDrops
|
||||||
|
@ -18,7 +18,7 @@ func TestWatchdog(t *testing.T) {
|
|||||||
t.Run("default watchdog does not fire", func(t *testing.T) {
|
t.Run("default watchdog does not fire", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
tun := NewFakeTun()
|
tun := NewFakeTun()
|
||||||
e, err := NewUserspaceEngineAdvanced(t.Logf, tun, NewFakeRouter, 0, false)
|
e, err := NewUserspaceEngineAdvanced(t.Logf, tun, NewFakeRouter, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ func TestWatchdog(t *testing.T) {
|
|||||||
t.Run("watchdog fires on blocked getStatus", func(t *testing.T) {
|
t.Run("watchdog fires on blocked getStatus", func(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
tun := NewFakeTun()
|
tun := NewFakeTun()
|
||||||
e, err := NewUserspaceEngineAdvanced(t.Logf, tun, NewFakeRouter, 0, false)
|
e, err := NewUserspaceEngineAdvanced(t.Logf, tun, NewFakeRouter, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,11 @@
|
|||||||
"net"
|
"net"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/tailscale/wireguard-go/device"
|
||||||
|
"github.com/tailscale/wireguard-go/tun"
|
||||||
"github.com/tailscale/wireguard-go/wgcfg"
|
"github.com/tailscale/wireguard-go/wgcfg"
|
||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/wgengine/filter"
|
"tailscale.com/wgengine/filter"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -58,6 +61,15 @@ func (rs *RouteSettings) OnlyRelevantParts() string {
|
|||||||
rs.LocalAddr, rs.DNS, rs.DNSDomains, peers)
|
rs.LocalAddr, rs.DNS, rs.DNSDomains, peers)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewUserspaceRouter returns a new Router for the current platform, using the provided tun device.
|
||||||
|
func NewUserspaceRouter(logf logger.Logf, wgdev *device.Device, tundev tun.Device, netChanged func()) (Router, error) {
|
||||||
|
return newUserspaceRouter(logf, wgdev, tundev, netChanged)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RouterGen is the signature for the two funcs that create Router implementations:
|
||||||
|
// NewUserspaceRouter (which varies by operating system) and NewFakeRouter.
|
||||||
|
type RouterGen func(logf logger.Logf, wgdev *device.Device, tundev tun.Device, netStateChanged func()) (Router, error)
|
||||||
|
|
||||||
// Router is responsible for managing the system route table.
|
// Router is responsible for managing the system route table.
|
||||||
//
|
//
|
||||||
// There's only one instance, and one per-OS implementation.
|
// There's only one instance, and one per-OS implementation.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user