policy/v2: resolve via-route grants lazily

With a via grant in the policy, ViaRoutesForPeer still resolved every
grant's sources and destinations up front. Non-via grants are only read
once a via grant has matched the peer, which is rare (the peer must
advertise a covered route), and destinations only for grants whose
sources match the viewer. Resolve each grant on first use instead.

BenchmarkViaRoutesForPeer, mean per peer (Apple M3 Pro):

	policy     nodes  before    after
	via-mixed  100    9.5us     2.1us
	via-mixed  1000   69.0us    11.6us
	via        1000   8.1us     8.6us
This commit is contained in:
Jonas Schwartz
2026-10-06 20:35:17 +02:00
committed by Kristoffer Dalby
parent f8018f177a
commit 9d5ce0752f
+22 -11
View File
@@ -1380,16 +1380,23 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
grants = append(grants, aclToGrants(acl)...)
}
// Resolve each grant's sources against the viewer once, and each
// grant's destinations into a flat prefix list. The three passes
// below reuse both results instead of re-resolving per pass.
// matchViewer resolves a grant lazily and at most once: non-via
// grants are only needed once a via grant has matched, and
// destinations only for grants that match the viewer.
viewerIPs := viewer.IPs()
resolved := make([]bool, len(grants))
viewerMatchesGrant := make([]bool, len(grants))
resolvedDstPrefixes := make([][]netip.Prefix, len(grants))
grantHasAutoGroupInternet := make([]bool, len(grants))
for i, grant := range grants {
for _, src := range grant.Sources {
matchViewer := func(i int) bool {
if resolved[i] {
return viewerMatchesGrant[i]
}
resolved[i] = true
for _, src := range grants[i].Sources {
ips, err := src.Resolve(pm.pol, pm.users, pm.nodes)
if err != nil {
continue
@@ -1402,9 +1409,13 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
}
}
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
pm.pol, pm.users, pm.nodes, grant.Destinations,
)
if viewerMatchesGrant[i] {
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
pm.pol, pm.users, pm.nodes, grants[i].Destinations,
)
}
return viewerMatchesGrant[i]
}
for i, grant := range grants {
@@ -1412,7 +1423,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue
}
if !viewerMatchesGrant[i] {
if !matchViewer(i) {
continue
}
@@ -1495,7 +1506,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue
}
if !viewerMatchesGrant[i] {
if !matchViewer(i) {
continue
}
@@ -1545,7 +1556,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue
}
if !viewerMatchesGrant[i] {
if !matchViewer(i) {
continue
}