ipn/ipnlocal: update netmap cache after peer deltas are applied (#20111)
Add an UpdatePeers method to the cache. This allows us to support netmap peer deltas, by allowing just the peers to be updated in an existing cache. As a safety check, reject an update if there was no base netmap data to apply a change to. Then, when processing peer mutations in the backend, capture any changes that should be applied to the cache and update it, if one is enabled. Updates #12542 Change-Id: I2f8790a8fdc5e85fce6700ba4821a8cb10dddffa Signed-off-by: M. J. Fromberger <fromberger@tailscale.com>
This commit is contained in:
@@ -2422,6 +2422,12 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
needsAuthReconfig := netmapDeltaNeedsAuthReconfig(cn, muts)
|
||||
cn.UpdateNetmapDelta(muts)
|
||||
|
||||
// In order that we can update the cache, keep track of which nodes are
|
||||
// updated and removed. The nodeBackend has already applied any deltas, so
|
||||
// we just need to know which nodes need updating.
|
||||
updateIDs := set.Of[tailcfg.NodeID]()
|
||||
removeIDs := set.Of[tailcfg.NodeID]()
|
||||
|
||||
// Dispatch Upsert/Remove per-peer to magicsock, and any per-field
|
||||
// patches via the existing UpdateNetmapDelta path. The per-peer
|
||||
// methods take c.mu themselves, so we can't call them from inside
|
||||
@@ -2434,12 +2440,15 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
ms.UpsertPeer(m.Node)
|
||||
peersUpsertedOrRemoved = true
|
||||
metricNetmapDeltaPeerUpserted.Add(1)
|
||||
updateIDs.Add(m.Node.ID())
|
||||
case netmap.NodeMutationRemove:
|
||||
ms.RemovePeer(m.NodeIDBeingMutated())
|
||||
peersUpsertedOrRemoved = true
|
||||
metricNetmapDeltaPeerRemoved.Add(1)
|
||||
removeIDs.Add(m.NodeIDBeingMutated())
|
||||
default:
|
||||
metricNetmapDeltaPeerPatched.Add(1)
|
||||
updateIDs.Add(m.NodeIDBeingMutated())
|
||||
}
|
||||
}
|
||||
ms.UpdateNetmapDelta(muts)
|
||||
@@ -2476,6 +2485,30 @@ func (b *LocalBackend) UpdateNetmapDelta(muts []netmap.NodeMutation) (handled bo
|
||||
return true
|
||||
}
|
||||
|
||||
// Reaching here, apply any peer changes to the netmap cache (if relevant).
|
||||
// Note we do this AFTER the updates are applied in the nodeBackend, so that
|
||||
// we can get its updated views to put back into the cache.
|
||||
if buildfeatures.HasCacheNetMap &&
|
||||
cn.SelfHasCap(tailcfg.NodeAttrCacheNetworkMaps) &&
|
||||
envknob.BoolDefaultTrue("TS_USE_CACHED_NETMAP") {
|
||||
|
||||
var peersToUpdate []tailcfg.NodeView
|
||||
for id := range updateIDs {
|
||||
if n, ok := cn.NodeByID(id); ok {
|
||||
peersToUpdate = append(peersToUpdate, n)
|
||||
}
|
||||
}
|
||||
var peersToRemove []tailcfg.StableNodeID
|
||||
for id := range removeIDs {
|
||||
if n, ok := cn.NodeByID(id); ok {
|
||||
peersToRemove = append(peersToRemove, n.StableID())
|
||||
}
|
||||
}
|
||||
if err := b.writePeerDeltaToDiskLocked(peersToUpdate, peersToRemove); err != nil {
|
||||
b.logf("update netmap cache for peer deltas: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// A single MapResponse can carry upserts/removes (full Nodes) AND
|
||||
// per-field patches in the same delta. Build one Notify that
|
||||
// reflects all of them; per-session stripping in [sendToLocked]
|
||||
|
||||
Reference in New Issue
Block a user