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:
Brad Fitzpatrick
2026-07-14 12:41:11 -07:00
committed by Brad Fitzpatrick
parent e4144230f4
commit f0ce89b715
15 changed files with 318 additions and 245 deletions
+22
View File
@@ -7,6 +7,7 @@ package tsaddr
import (
"encoding/binary"
"errors"
"iter"
"net/netip"
"slices"
"sync"
@@ -317,3 +318,24 @@ func MapVia(siteID uint32, v4 netip.Prefix) (via netip.Prefix, err error) {
copy(a[12:], ip4a[:])
return netip.PrefixFrom(netip.AddrFrom16(a), v4.Bits()+64+32), nil
}
// FirstTailscaleAddrs returns the first Tailscale IPv4 address and
// the first Tailscale IPv6 address among the addresses of addrs'
// prefixes, if any. The addrs sequence is typically a node's own
// address list, either a slice (via [slices.All]) or a view (via
// [views.Slice.All]).
func FirstTailscaleAddrs(addrs iter.Seq2[int, netip.Prefix]) (a4, a6 netip.Addr) {
for _, pfx := range addrs {
a := pfx.Addr()
switch {
case a.Is4() && !a4.IsValid() && IsTailscaleIP(a):
a4 = a
case a.Is6() && !a6.IsValid() && IsTailscaleIP(a):
a6 = a
}
if a4.IsValid() && a6.IsValid() {
break
}
}
return a4, a6
}