From 9d5ce0752f5bdb24eb92c20da739c770da4bef38 Mon Sep 17 00:00:00 2001 From: Jonas Schwartz Date: Tue, 6 Oct 2026 20:35:17 +0200 Subject: [PATCH] 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 --- hscontrol/policy/v2/policy.go | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/hscontrol/policy/v2/policy.go b/hscontrol/policy/v2/policy.go index ad2238f7e..7f8b47958 100644 --- a/hscontrol/policy/v2/policy.go +++ b/hscontrol/policy/v2/policy.go @@ -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 }