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:
M. J. Fromberger
2026-06-12 09:41:00 -07:00
committed by GitHub
parent b23089a5ef
commit 9cb071666c
4 changed files with 135 additions and 0 deletions
+15
View File
@@ -10,6 +10,7 @@ import (
"tailscale.com/feature/buildfeatures"
"tailscale.com/ipn/ipnlocal/netmapcache"
"tailscale.com/tailcfg"
"tailscale.com/types/netmap"
)
@@ -21,6 +22,20 @@ type diskCache struct {
cache *netmapcache.Cache
}
// writePeerDeltaToDiskLocked applies the specified peer delta to the cache,
// leaving other existing cached fields (self, profiles, other peers not
// mentioned in the arguments) unchanged. It does nothing (without error) if
// both slices are empty.
func (b *LocalBackend) writePeerDeltaToDiskLocked(update []tailcfg.NodeView, remove []tailcfg.StableNodeID) error {
if !buildfeatures.HasCacheNetMap || (len(update) == 0 && len(remove) == 0) {
return nil
} else if err := b.ensureDiskCacheLocked(); err != nil {
return err
}
b.logf("updating netmap peers in disk cache (%d to update, %d to remove)", len(update), len(remove))
return b.diskCache.cache.UpdatePeers(b.currentNode().Context(), update, remove)
}
// writeNetmapToDiskLockedWithoutPeers updates nm in the cache, excluding peers and profiles.
func (b *LocalBackend) writeNetmapToDiskLockedWithoutPeers(nm *netmap.NetworkMap) error {
if !buildfeatures.HasCacheNetMap || nm == nil || nm.Cached {