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>
24 lines
836 B
Go
24 lines
836 B
Go
// 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) }
|