ipn/ipnlocal, wgengine/wgcfg/nmcfg: stop building peer lists on delta path
Processing a peer add/remove delta still materialized the full netmap (an O(n) slicesx.MapValues plus sort over all peers, at 10k+ peers in a large tailnet) twice per delta: once in UpdateNetmapDelta purely to hand the self node to Engine.SetSelfNode, and once in authReconfigLocked. Neither needs peers anymore. SetSelfNode gets the self node from the existing nodeBackend.Self accessor. authReconfigLocked only reads self-node fields (SelfNode, NodeKey, GetAddresses, HasCap) now that WireGuard peers ride the incremental route manager and per-peer config source, so it can use the peers-free NetMap accessor. That also makes nmcfg.WGCfg vestigial: since wgcfg.Config lost its Peers field, its peer walk existed only to emit the [v1] skip logs (expired peers, unselected exit nodes, unaccepted subnet routes), duplicating filtering the route manager already does. Delete the package and construct the two-field wgcfg.Config inline. The skip logs go away; if they're missed, the route manager can log them incrementally at upsert time instead of rescanning every peer on every reconfig. With this, the runtime.DidRange analysis (see the ts_rangehook test) shows a delta netmap update performing no O(n) range loops except updateRouteManagerExtras, and the delta phase of that test drops from 1.09s to 0.14s for 400 deltas at n=10000 (from 4.79s at the start of this effort, before the incremental route manager work). Updates #12542 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com> Change-Id: Ia0e03ef9db0c988790b2c29de1f0505305e93f58
This commit is contained in:
committed by
Brad Fitzpatrick
parent
3515b009c2
commit
4660a961eb
+13
-9
@@ -107,7 +107,6 @@ import (
|
||||
"tailscale.com/wgengine/magicsock"
|
||||
"tailscale.com/wgengine/router"
|
||||
"tailscale.com/wgengine/wgcfg"
|
||||
"tailscale.com/wgengine/wgcfg/nmcfg"
|
||||
)
|
||||
|
||||
var controlDebugFlags = getControlDebugFlags()
|
||||
@@ -2502,8 +2501,8 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
needsAuthReconfig = needsAuthReconfig || peersUpsertedOrRemoved
|
||||
if needsAuthReconfig {
|
||||
if peersUpsertedOrRemoved {
|
||||
if nm := cn.netMapWithPeers(); nm != nil {
|
||||
b.e.SetSelfNode(nm.SelfNode)
|
||||
if self := cn.Self(); self.Valid() {
|
||||
b.e.SetSelfNode(self)
|
||||
}
|
||||
}
|
||||
b.authReconfigLocked()
|
||||
@@ -6054,7 +6053,10 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
|
||||
cn := b.currentNode()
|
||||
|
||||
nm := cn.netMapWithPeers()
|
||||
// Note this netmap does not have its Peers populated. Nothing
|
||||
// below needs them; per-peer work rides the incremental route
|
||||
// manager and engine paths instead.
|
||||
nm := cn.NetMap()
|
||||
if nm == nil {
|
||||
b.logf("[v1] authReconfig: netmap not yet valid. Skipping.")
|
||||
return
|
||||
@@ -6100,10 +6102,12 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
priv = key.NodePrivate{}
|
||||
}
|
||||
|
||||
cfg, err := nmcfg.WGCfg(priv, nm, b.logf, flags, prefs.ExitNodeID())
|
||||
if err != nil {
|
||||
b.logf("wgcfg: %v", err)
|
||||
return
|
||||
// The config carries no peers; wireguard-go gets those from the
|
||||
// live per-peer config source installed via
|
||||
// [wgengine.Engine.SetPeerConfigFunc], fed by the route manager.
|
||||
cfg := &wgcfg.Config{
|
||||
PrivateKey: priv,
|
||||
Addresses: nm.GetAddresses().AsSlice(),
|
||||
}
|
||||
|
||||
// Note: b.goos (set only by tests) speaks runtime.GOOS while
|
||||
@@ -6146,7 +6150,7 @@ func (b *LocalBackend) authReconfigLocked() {
|
||||
// the new config never see a stale peer table.
|
||||
b.setDataPlanePeerRoutes()
|
||||
|
||||
err = b.e.Reconfig(cfg, rcfg, dcfg)
|
||||
err := b.e.Reconfig(cfg, rcfg, dcfg)
|
||||
if err == wgengine.ErrNoChanges {
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user