net/tstun,wgengine,ipn/ipnlocal: make tstun's peerConfigTable use RouteManager table
Previously tstun.Wrapper.SetWGConfig walked wgcfg.Config.Peers on every netmap to rebuild its own IP-to-peer table for masquerade NAT rewrites and jailed-peer classification. Now the tun layer instead consumes the route manager's shared immutable outbound snapshot directly, via a new Engine.SetPeerRoutes method: LocalBackend pushes the snapshot (plus this node's native Tailscale addresses) after every route manager commit that can change it, and per-packet lookups read the interned PeerRoute attributes from that table. When no current peer is jailed or masqueraded, LocalBackend installs a nil table (gated on RouteManager.HasDataPlaneAttrs), preserving the per-packet nil-check fast path. The exitNodeRequiresMasq machinery is deleted: its purpose was populating the table with all peers so that more-specific entries shadow an exit node's /0, and the always-full route manager table gives that shadowing inherently. This is the last step before removing the Peers field from wgcfg.Config. Updates #12542 Change-Id: Ifce09ca929a3f2511303ca1d6efdd583739494ce Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
e4144230f4
commit
f0ce89b715
+37
-5
@@ -31,6 +31,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gaissmai/bart"
|
||||
"go4.org/mem"
|
||||
"go4.org/netipx"
|
||||
"golang.org/x/net/dns/dnsmessage"
|
||||
@@ -62,6 +63,7 @@ import (
|
||||
"tailscale.com/net/netns"
|
||||
"tailscale.com/net/netutil"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/routemanager"
|
||||
"tailscale.com/net/traffic"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/net/tsdial"
|
||||
@@ -2516,6 +2518,7 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
for k := range deltaRes.ChangedAllowedIPs {
|
||||
b.e.SyncDevicePeer(k)
|
||||
}
|
||||
b.setDataPlanePeerRoutes()
|
||||
|
||||
// Reset the WireGuard session for peers whose disco key changed in
|
||||
// a way that indicates a restart, flushing their dead session keys;
|
||||
@@ -2530,11 +2533,9 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
// and its lazy peer creation reads live state via
|
||||
// [wgengine.Engine.SetPeerConfigFunc]. What still rides
|
||||
// authReconfig is everything else derived from the full peer set:
|
||||
// OS routes (router.Config), the quad-100 resolver's MagicDNS
|
||||
// hosts map (dnsConfigForNetmap), and tstun's per-peer config
|
||||
// (masquerade addresses and jailed peers, via SetWGConfig). Once
|
||||
// those become delta-aware too, this can be gated on the route
|
||||
// manager's OS-routes changes and the tstun-relevant fields
|
||||
// OS routes (router.Config) and the quad-100 resolver's MagicDNS
|
||||
// hosts map (dnsConfigForNetmap). Once those become delta-aware
|
||||
// too, this can be gated on the route manager's OS-routes changes
|
||||
// instead of firing on every peer change.
|
||||
needsAuthReconfig = needsAuthReconfig || peersUpsertedOrRemoved
|
||||
if needsAuthReconfig {
|
||||
@@ -6183,6 +6184,13 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
cfg.Peers[i].AllowedIPs = extras.AppendTo(cfg.Peers[i].AllowedIPs)
|
||||
}
|
||||
}
|
||||
// The prefs and extras commits above can both change the outbound
|
||||
// table (such as installing the selected exit node's /0 routes),
|
||||
// so refresh the data plane's view of it. This must stay after
|
||||
// updateRouteManagerExtras, so the pushed snapshot includes its
|
||||
// commit, and before the Reconfig below, so packets flowing under
|
||||
// the new config never see a stale peer table.
|
||||
b.setDataPlanePeerRoutes()
|
||||
|
||||
err = b.e.Reconfig(cfg, rcfg, dcfg)
|
||||
if err == wgengine.ErrNoChanges {
|
||||
@@ -6196,6 +6204,29 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
}
|
||||
}
|
||||
|
||||
// setDataPlanePeerRoutes pushes the route manager's outbound table and
|
||||
// this node's native Tailscale addresses into the engine's tun-layer
|
||||
// data plane, which uses them for per-packet NAT rewrites and
|
||||
// jailed-filter selection. It must be called after every route manager
|
||||
// commit that can change the outbound table or the set of peers with
|
||||
// data-plane attributes: netmap updates (full or delta), prefs changes,
|
||||
// and extra-allowed-IP changes.
|
||||
//
|
||||
// When no current peer is jailed or masqueraded, it installs nil, which
|
||||
// keeps the data plane's per-packet fast path to a nil check.
|
||||
func (b *LocalBackend) setDataPlanePeerRoutes() {
|
||||
nb := b.currentNode()
|
||||
var native4, native6 netip.Addr
|
||||
var routes *bart.Table[*routemanager.PeerRoute]
|
||||
if nb.routeMgr.HasDataPlaneAttrs() {
|
||||
routes = nb.routeMgr.Outbound()
|
||||
if nm := nb.NetMap(); nm != nil {
|
||||
native4, native6 = tsaddr.FirstTailscaleAddrs(nm.GetAddresses().All())
|
||||
}
|
||||
}
|
||||
b.e.SetPeerRoutes(native4, native6, routes)
|
||||
}
|
||||
|
||||
// shouldUseOneCGNATRoute reports whether we should prefer to make one big
|
||||
// CGNAT /10 route rather than a /32 per peer.
|
||||
//
|
||||
@@ -7312,6 +7343,7 @@ func (b *LocalBackend) setNetMapLocked(nm *netmap.NetworkMap) {
|
||||
login = cmp.Or(profileFromView(nm.UserProfiles[nm.User()]).LoginName, "<missing-profile>")
|
||||
}
|
||||
discoChanged := b.currentNode().SetNetMap(nm)
|
||||
b.setDataPlanePeerRoutes()
|
||||
if ms, ok := b.sys.MagicSock.GetOK(); ok {
|
||||
if nm != nil {
|
||||
if nm.Cached {
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"time"
|
||||
|
||||
qt "github.com/frankban/quicktest"
|
||||
"github.com/gaissmai/bart"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
|
||||
@@ -29,6 +30,7 @@ import (
|
||||
"tailscale.com/net/dns"
|
||||
"tailscale.com/net/netmon"
|
||||
"tailscale.com/net/packet"
|
||||
"tailscale.com/net/routemanager"
|
||||
"tailscale.com/net/tsdial"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/tsd"
|
||||
@@ -1961,6 +1963,9 @@ func (e *mockEngine) SetJailedFilter(f *filter.Filter) {
|
||||
e.mu.Unlock()
|
||||
}
|
||||
|
||||
func (e *mockEngine) SetPeerRoutes(native4, native6 netip.Addr, routes *bart.Table[*routemanager.PeerRoute]) {
|
||||
}
|
||||
|
||||
func (e *mockEngine) SetStatusCallback(cb wgengine.StatusCallback) {
|
||||
e.mu.Lock()
|
||||
e.statusCb = cb
|
||||
|
||||
Reference in New Issue
Block a user