For #707 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>main
parent
1f99f889e1
commit
d488678fdc
@ -0,0 +1,36 @@ |
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package netstack |
||||
|
||||
import ( |
||||
"reflect" |
||||
|
||||
"tailscale.com/wgengine" |
||||
"tailscale.com/wgengine/router" |
||||
) |
||||
|
||||
func init() { |
||||
wgengine.NetstackRouterType = reflect.TypeOf(&subnetRouter{}) |
||||
} |
||||
|
||||
type subnetRouter struct { |
||||
router.Router |
||||
} |
||||
|
||||
// NewSubnetRouterWrapper returns a Router wrapper that prevents the
|
||||
// underlying Router r from seeing any advertised subnet routes, as
|
||||
// netstack will handle them instead.
|
||||
func NewSubnetRouterWrapper(r router.Router) router.Router { |
||||
return &subnetRouter{ |
||||
Router: r, |
||||
} |
||||
} |
||||
|
||||
func (r *subnetRouter) Set(c *router.Config) error { |
||||
if c != nil { |
||||
c.SubnetRoutes = nil // netstack will handle
|
||||
} |
||||
return r.Router.Set(c) |
||||
} |
||||
@ -0,0 +1,92 @@ |
||||
// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package wgengine_test |
||||
|
||||
import ( |
||||
"testing" |
||||
|
||||
"github.com/tailscale/wireguard-go/tun" |
||||
"tailscale.com/net/tstun" |
||||
"tailscale.com/types/logger" |
||||
"tailscale.com/wgengine" |
||||
"tailscale.com/wgengine/netstack" |
||||
"tailscale.com/wgengine/router" |
||||
) |
||||
|
||||
func TestIsNetstack(t *testing.T) { |
||||
e, err := wgengine.NewUserspaceEngine(t.Logf, wgengine.Config{}) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer e.Close() |
||||
if !wgengine.IsNetstack(e) { |
||||
t.Errorf("IsNetstack = false; want true") |
||||
} |
||||
} |
||||
|
||||
func TestIsNetstackRouter(t *testing.T) { |
||||
tests := []struct { |
||||
name string |
||||
conf wgengine.Config |
||||
want bool |
||||
}{ |
||||
{ |
||||
name: "no_netstack", |
||||
conf: wgengine.Config{ |
||||
Tun: newFakeOSTUN(), |
||||
Router: newFakeOSRouter(), |
||||
}, |
||||
want: false, |
||||
}, |
||||
{ |
||||
name: "netstack", |
||||
conf: wgengine.Config{}, |
||||
want: true, |
||||
}, |
||||
{ |
||||
name: "hybrid_netstack", |
||||
conf: wgengine.Config{ |
||||
Tun: newFakeOSTUN(), |
||||
Router: netstack.NewSubnetRouterWrapper(newFakeOSRouter()), |
||||
}, |
||||
want: true, |
||||
}, |
||||
} |
||||
for _, tt := range tests { |
||||
t.Run(tt.name, func(t *testing.T) { |
||||
e, err := wgengine.NewUserspaceEngine(logger.Discard, tt.conf) |
||||
if err != nil { |
||||
t.Fatal(err) |
||||
} |
||||
defer e.Close() |
||||
if got := wgengine.IsNetstackRouter(e); got != tt.want { |
||||
t.Errorf("IsNetstackRouter = %v; want %v", got, tt.want) |
||||
} |
||||
|
||||
if got := wgengine.IsNetstackRouter(wgengine.NewWatchdog(e)); got != tt.want { |
||||
t.Errorf("IsNetstackRouter(watchdog-wrapped) = %v; want %v", got, tt.want) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
|
||||
func newFakeOSRouter() router.Router { |
||||
return someRandoOSRouter{router.NewFake(logger.Discard)} |
||||
} |
||||
|
||||
type someRandoOSRouter struct { |
||||
router.Router |
||||
} |
||||
|
||||
func newFakeOSTUN() tun.Device { |
||||
return someRandoOSTUN{tstun.NewFake()} |
||||
} |
||||
|
||||
type someRandoOSTUN struct { |
||||
tun.Device |
||||
} |
||||
|
||||
// Name returns something that is not FakeTUN.
|
||||
func (t someRandoOSTUN) Name() (string, error) { return "some_os_tun0", nil } |
||||
Loading…
Reference in new issue