net/routemanager: add incremental route manager
Add a new RouteManager type that tracks per-peer self addresses and
advertised routes and incrementally maintains two read-only
snapshots: an IP-to-outbound-peer bart table carrying the per-peer
attributes the data plane needs (jailed state, masquerade addresses),
and a coarsened OS route set (including OneCGNAT consolidation).
Mutations are staged in a transaction (Begin/Commit) and applied to
the snapshots via bart's Persist methods, which path-copy only the
few trie nodes along the affected prefix, so a single-peer delta
costs a bounded amount of work independent of the number of peers,
instead of the O(n) full-world rebuild done today. Snapshots are
published via atomic pointer swap for lock-free reads on the hot
path, and Commit reports which peers' allowed IPs changed so callers
can sync wireguard-go incrementally. This is the same immutable value
snapshot pattern as used in the recent containerboot change,
364b952d62.
Nothing uses it yet; this is pulled out of a future change that wires
it into ipnlocal and wgengine, to make that PR smaller.
Updates #12542
Change-Id: Iccc5258024e6f90311835b79fd2d83b2adb0d09d
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
committed by
Brad Fitzpatrick
parent
045c979802
commit
a5102d3fcb
@@ -0,0 +1,23 @@
|
||||
// Copyright (c) Tailscale Inc & contributors
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package routemanager
|
||||
|
||||
import "tailscale.com/util/testenv"
|
||||
|
||||
// forTest is an unexported type to hide the test-only methods on
|
||||
// [RouteManager] from godoc.
|
||||
type forTest struct{ rm *RouteManager }
|
||||
|
||||
// ForTest returns a handle to test-only methods on rm. The resulting
|
||||
// type is unexported to make it very obvious in godoc that this is
|
||||
// not stable API. This method panics if called outside of tests,
|
||||
// which also centralizes all must-be-in-tests validation.
|
||||
func (rm *RouteManager) ForTest() forTest {
|
||||
testenv.AssertInTest()
|
||||
return forTest{rm}
|
||||
}
|
||||
|
||||
// PeerCount returns the number of peers currently tracked. Callers
|
||||
// must serialize it with mutations like any other write-path access.
|
||||
func (f forTest) PeerCount() int { return len(f.rm.peers) }
|
||||
Reference in New Issue
Block a user