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)...) grants = append(grants, aclToGrants(acl)...)
} }
// Resolve each grant's sources against the viewer once, and each // matchViewer resolves a grant lazily and at most once: non-via
// grant's destinations into a flat prefix list. The three passes // grants are only needed once a via grant has matched, and
// below reuse both results instead of re-resolving per pass. // destinations only for grants that match the viewer.
viewerIPs := viewer.IPs() viewerIPs := viewer.IPs()
resolved := make([]bool, len(grants))
viewerMatchesGrant := make([]bool, len(grants)) viewerMatchesGrant := make([]bool, len(grants))
resolvedDstPrefixes := make([][]netip.Prefix, len(grants)) resolvedDstPrefixes := make([][]netip.Prefix, len(grants))
grantHasAutoGroupInternet := make([]bool, len(grants)) grantHasAutoGroupInternet := make([]bool, len(grants))
for i, grant := range grants { matchViewer := func(i int) bool {
for _, src := range grant.Sources { 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) ips, err := src.Resolve(pm.pol, pm.users, pm.nodes)
if err != nil { if err != nil {
continue continue
@@ -1402,9 +1409,13 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
} }
} }
resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations( if viewerMatchesGrant[i] {
pm.pol, pm.users, pm.nodes, grant.Destinations, resolvedDstPrefixes[i], grantHasAutoGroupInternet[i] = resolveViaDestinations(
) pm.pol, pm.users, pm.nodes, grants[i].Destinations,
)
}
return viewerMatchesGrant[i]
} }
for i, grant := range grants { for i, grant := range grants {
@@ -1412,7 +1423,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue continue
} }
if !viewerMatchesGrant[i] { if !matchViewer(i) {
continue continue
} }
@@ -1495,7 +1506,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue continue
} }
if !viewerMatchesGrant[i] { if !matchViewer(i) {
continue continue
} }
@@ -1545,7 +1556,7 @@ func (pm *PolicyManager) ViaRoutesForPeer(viewer, peer types.NodeView) types.Via
continue continue
} }
if !viewerMatchesGrant[i] { if !matchViewer(i) {
continue continue
} }