@@ -61,26 +61,39 @@ func (t *Translator) ProcessSecurityPolicies(securityPolicies []*egv1a1.Security
6161
6262 // First build a map out of the routes and gateways for faster lookup since users might have thousands of routes or more.
6363 // For gateways this probably isn't quite as necessary.
64- routeMap := map [policyTargetRouteKey ]* policyRouteTargetContext {}
64+ routeMapSize := len (routes )
65+ gatewayMapSize := len (gateways )
66+ policyMapSize := len (securityPolicies )
67+
68+ // Pre-allocate result slice and maps with estimated capacity to reduce memory allocations
69+ res = make ([]* egv1a1.SecurityPolicy , 0 , len (securityPolicies ))
70+ routeMap := make (map [policyTargetRouteKey ]* policyRouteTargetContext , routeMapSize )
6571 for _ , route := range routes {
6672 key := policyTargetRouteKey {
6773 Kind : string (route .GetRouteType ()),
6874 Name : route .GetName (),
6975 Namespace : route .GetNamespace (),
7076 }
71- routeMap [key ] = & policyRouteTargetContext {RouteContext : route , attachedToRouteRules : make (sets.Set [string ])}
77+ routeMap [key ] = & policyRouteTargetContext {
78+ RouteContext : route ,
79+ attachedToRouteRules : make (sets.Set [string ]),
80+ }
7281 }
73- gatewayMap := map [types.NamespacedName ]* policyGatewayTargetContext {}
82+
83+ gatewayMap := make (map [types.NamespacedName ]* policyGatewayTargetContext , gatewayMapSize )
7484 for _ , gw := range gateways {
7585 key := utils .NamespacedName (gw )
76- gatewayMap [key ] = & policyGatewayTargetContext {GatewayContext : gw , attachedToListeners : make (sets.Set [string ])}
86+ gatewayMap [key ] = & policyGatewayTargetContext {
87+ GatewayContext : gw ,
88+ attachedToListeners : make (sets.Set [string ]),
89+ }
7790 }
7891
7992 // Map of Gateway to the routes attached to it.
8093 // The routes are grouped by sectionNames of their targetRefs
81- gatewayRouteMap := make (map [string ]map [string ]sets.Set [string ])
94+ gatewayRouteMap := make (map [string ]map [string ]sets.Set [string ], gatewayMapSize )
8295
83- handledPolicies := make (map [types.NamespacedName ]* egv1a1.SecurityPolicy )
96+ handledPolicies := make (map [types.NamespacedName ]* egv1a1.SecurityPolicy , policyMapSize )
8497
8598 // Translate
8699 // 1. First translate Policies targeting RouteRules
@@ -623,10 +636,33 @@ func (t *Translator) translateSecurityPolicyForRoute(
623636 }
624637 }
625638
639+ // Pre-create security features to avoid repeated allocations
640+ securityFeatures := & ir.SecurityFeatures {
641+ CORS : cors ,
642+ JWT : jwt ,
643+ OIDC : oidc ,
644+ APIKeyAuth : apiKeyAuth ,
645+ BasicAuth : basicAuth ,
646+ ExtAuth : extAuth ,
647+ Authorization : authorization ,
648+ }
649+
650+ // Pre-create error response to avoid repeated allocations
651+ var errorResponse * ir.CustomResponse
652+ if errs != nil {
653+ shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
654+ if ! shouldFailOpen {
655+ errorResponse = & ir.CustomResponse {
656+ StatusCode : ptr .To (uint32 (500 )),
657+ }
658+ }
659+ }
660+
626661 irKey := t .getIRKey (gtwCtx .Gateway )
627662 for _ , listener := range parentRefCtx .listeners {
628663 irListener := xdsIR [irKey ].GetHTTPListener (irListenerName (listener ))
629664 if irListener != nil {
665+
630666 for _ , r := range irListener .Routes {
631667 // If specified the sectionName must match route rule from ir route metadata.
632668 if target .SectionName != nil && string (* target .SectionName ) != r .Metadata .SectionName {
@@ -641,26 +677,10 @@ func (t *Translator) translateSecurityPolicyForRoute(
641677 continue
642678 }
643679
644- r .Security = & ir.SecurityFeatures {
645- CORS : cors ,
646- JWT : jwt ,
647- OIDC : oidc ,
648- APIKeyAuth : apiKeyAuth ,
649- BasicAuth : basicAuth ,
650- ExtAuth : extAuth ,
651- Authorization : authorization ,
652- }
653- if errs != nil {
654- // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
655- // and allow the request to go through.
656- // Otherwise, return a 500 direct response to avoid unauthorized access.
657- shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
658- if ! shouldFailOpen {
659- // Return a 500 direct response to avoid unauthorized access
660- r .DirectResponse = & ir.CustomResponse {
661- StatusCode : ptr .To (uint32 (500 )),
662- }
663- }
680+ r .Security = securityFeatures
681+ if errorResponse != nil {
682+ // Return a 500 direct response to avoid unauthorized access
683+ r .DirectResponse = errorResponse
664684 }
665685 }
666686 }
@@ -761,6 +781,30 @@ func (t *Translator) translateSecurityPolicyForGateway(
761781 // Should exist since we've validated this
762782 x := xdsIR [irKey ]
763783
784+ // Pre-create security features and error response to avoid repeated allocations
785+ securityFeatures := & ir.SecurityFeatures {
786+ CORS : cors ,
787+ JWT : jwt ,
788+ OIDC : oidc ,
789+ APIKeyAuth : apiKeyAuth ,
790+ BasicAuth : basicAuth ,
791+ ExtAuth : extAuth ,
792+ Authorization : authorization ,
793+ }
794+
795+ var errorResponse * ir.CustomResponse
796+ if errs != nil {
797+ // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
798+ // and allow the request to go through.
799+ // Otherwise, return a 500 direct response to avoid unauthorized access.
800+ shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
801+ if ! shouldFailOpen {
802+ errorResponse = & ir.CustomResponse {
803+ StatusCode : ptr .To (uint32 (500 )),
804+ }
805+ }
806+ }
807+
764808 policyTarget := irStringKey (policy .Namespace , string (target .Name ))
765809 for _ , h := range x .HTTP {
766810 // A HTTPListener name has the format namespace/gatewayName/listenerName
@@ -773,32 +817,17 @@ func (t *Translator) translateSecurityPolicyForGateway(
773817 if target .SectionName != nil && string (* target .SectionName ) != h .Metadata .SectionName {
774818 continue
775819 }
820+
776821 // A Policy targeting the specific scope(xRoute rule, xRoute, Gateway listener) wins over a policy
777822 // targeting a lesser specific scope(Gateway).
778823 for _ , r := range h .Routes {
779824 // if already set - there's a specific level policy, so skip.
780825 if r .Security != nil {
781826 continue
782827 }
783- r .Security = & ir.SecurityFeatures {
784- CORS : cors ,
785- JWT : jwt ,
786- OIDC : oidc ,
787- APIKeyAuth : apiKeyAuth ,
788- BasicAuth : basicAuth ,
789- ExtAuth : extAuth ,
790- Authorization : authorization ,
791- }
792- if errs != nil {
793- // If there is only error for ext auth and ext auth is set to fail open, then skip the ext auth
794- // and allow the request to go through.
795- // Otherwise, return a 500 direct response to avoid unauthorized access.
796- shouldFailOpen := extAuthErr != nil && ! hasNonExtAuthError && ptr .Deref (policy .Spec .ExtAuth .FailOpen , false )
797- if ! shouldFailOpen {
798- r .DirectResponse = & ir.CustomResponse {
799- StatusCode : ptr .To (uint32 (500 )),
800- }
801- }
828+ r .Security = securityFeatures
829+ if errorResponse != nil {
830+ r .DirectResponse = errorResponse
802831 }
803832 }
804833 }
0 commit comments