diff options
| author | David Anderson <danderson@tailscale.com> | 2021-03-11 19:24:45 -0800 |
|---|---|---|
| committer | Brad Fitzpatrick <bradfitz@tailscale.com> | 2021-03-12 13:34:14 -0800 |
| commit | bbb0e84cf1faf69556e725a18abf9d6ffc7b8c34 (patch) | |
| tree | b6ad60dbc2722a8f922b864479d945c92d50eb4f | |
| parent | f7ef32da5ff838cc852736207261b5ef19be511c (diff) | |
| download | tailscale-bradfitz/proposed_1.4.6.tar.xz tailscale-bradfitz/proposed_1.4.6.zip | |
wgengine/router: don't touch interface routesbradfitz/proposed_1.4.6
Developed by a cast of dozens.
Fixes #1448
Signed-off-by: David Anderson <danderson@tailscale.com>
(cherry picked from commit fa6110e47bb0f0f5320004a6a8e5ed00fa96eb44)
| -rw-r--r-- | wgengine/router/ifconfig_windows.go | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/wgengine/router/ifconfig_windows.go b/wgengine/router/ifconfig_windows.go index 486915e6e..74b9ae335 100644 --- a/wgengine/router/ifconfig_windows.go +++ b/wgengine/router/ifconfig_windows.go @@ -20,6 +20,7 @@ import ( "github.com/tailscale/wireguard-go/tun" "golang.org/x/sys/windows" "golang.zx2c4.com/wireguard/windows/tunnel/winipcfg" + "inet.af/netaddr" "tailscale.com/net/interfaces" "tailscale.com/wgengine/winnet" ) @@ -378,7 +379,7 @@ func configureInterface(cfg *Config, tun *tun.NativeTun) (retErr error) { } var errAcc error - err = syncRoutes(iface, deduplicatedRoutes) + err = syncRoutes(iface, deduplicatedRoutes, cfg.LocalAddrs) if err != nil && errAcc == nil { log.Printf("setroutes: %v", err) errAcc = err @@ -659,9 +660,29 @@ func getInterfaceRoutes(ifc *winipcfg.IPAdapterAddresses, family winipcfg.Addres return } +// isSingleRouteInPrefixes reports whether r is a single-address +// prefix that appears in pfxs. +func isSingleRouteInPrefixes(r net.IPNet, pfxs []netaddr.IPPrefix) bool { + rr, ok := netaddr.FromStdIPNet(&r) + if !ok { + return false + } + if !rr.IsSingleIP() { + return false + } + for _, pfx := range pfxs { + if pfx == rr { + return true + } + } + return false +} + // syncRoutes incrementally sets multiples routes on an interface. // This avoids a full ifc.FlushRoutes call. -func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*winipcfg.RouteData) error { +// dontDelete is a list of interface address routes that the +// synchronization logic should never delete. +func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*winipcfg.RouteData, dontDelete []netaddr.IPPrefix) error { routes, err := getInterfaceRoutes(ifc, windows.AF_INET) if err != nil { return err @@ -669,6 +690,11 @@ func syncRoutes(ifc *winipcfg.IPAdapterAddresses, want []*winipcfg.RouteData) er got := make([]*winipcfg.RouteData, 0, len(routes)) for _, r := range routes { + if isSingleRouteInPrefixes(r.DestinationPrefix.IPNet(), dontDelete) { + // See issue 1448: we don't want to touch the routes added + // by Windows for our interface addresses. + continue + } got = append(got, &winipcfg.RouteData{ Destination: r.DestinationPrefix.IPNet(), NextHop: r.NextHop.IP(), |
