@@ -337,22 +337,96 @@ func bindRoutesToListeners(
337337 bindL7RouteToListeners (r , gw , namespaces )
338338 }
339339
340- var routes []* L4Route
341- for _ , r := range l4Routes {
340+ routes := make ( []* L7Route , 0 , len ( l7Routes ))
341+ for _ , r := range l7Routes {
342342 routes = append (routes , r )
343343 }
344344
345+ isolateL7RouteListeners (routes , gw .Listeners )
346+
347+ l4RouteSlice := make ([]* L4Route , 0 , len (l4Routes ))
348+ for _ , r := range l4Routes {
349+ l4RouteSlice = append (l4RouteSlice , r )
350+ }
351+
345352 // Sort the slice by timestamp and name so that we process the routes in the priority order
346- sort .Slice (routes , func (i , j int ) bool {
347- return ngfSort .LessClientObject (routes [i ].Source , routes [j ].Source )
353+ sort .Slice (l4RouteSlice , func (i , j int ) bool {
354+ return ngfSort .LessClientObject (l4RouteSlice [i ].Source , l4RouteSlice [j ].Source )
348355 })
349356
350357 // portHostnamesMap exists to detect duplicate hostnames on the same port
351358 portHostnamesMap := make (map [string ]struct {})
352359
353- for _ , r := range routes {
360+ for _ , r := range l4RouteSlice {
354361 bindL4RouteToListeners (r , gw , namespaces , portHostnamesMap )
355362 }
363+
364+ isolateL4RouteListeners (l4RouteSlice , gw .Listeners )
365+ }
366+
367+ // isolateL7RouteListeners ensures listener isolation for all L7Routes.
368+ func isolateL7RouteListeners (routes []* L7Route , listeners []* Listener ) {
369+ listenerHostnameMap := make (map [string ]string , len (listeners ))
370+ for _ , l := range listeners {
371+ listenerHostnameMap [l .Name ] = getHostname (l .Source .Hostname )
372+ }
373+
374+ for _ , route := range routes {
375+ isolateHostnamesForParentRefs (route .ParentRefs , listenerHostnameMap )
376+ }
377+ }
378+
379+ // isolateL4RouteListeners ensures listener isolation for all L4Routes.
380+ func isolateL4RouteListeners (routes []* L4Route , listeners []* Listener ) {
381+ listenerHostnameMap := make (map [string ]string , len (listeners ))
382+ for _ , l := range listeners {
383+ listenerHostnameMap [l .Name ] = getHostname (l .Source .Hostname )
384+ }
385+
386+ for _ , route := range routes {
387+ isolateHostnamesForParentRefs (route .ParentRefs , listenerHostnameMap )
388+ }
389+ }
390+
391+ // isolateHostnamesForParentRefs iterates through the parentRefs of a route to identify the list of accepted hostnames
392+ // for each listener. If any accepted hostname belongs to another listener,
393+ // it removes those hostnames to ensure listener isolation.
394+ func isolateHostnamesForParentRefs (parentRef []ParentRef , listenerHostnameMap map [string ]string ) {
395+ for _ , ref := range parentRef {
396+ acceptedHostnames := ref .Attachment .AcceptedHostnames
397+
398+ hostnamesToRemoves := make (map [string ]struct {})
399+ for listenerName , hostnames := range acceptedHostnames {
400+ if len (hostnames ) == 0 {
401+ continue
402+ }
403+ for _ , h := range hostnames {
404+ for lName , lHostname := range listenerHostnameMap {
405+ // skip comparison if it is a catch all listener block
406+ if lHostname == "" {
407+ continue
408+ }
409+ if h == lHostname && listenerName != lName {
410+ hostnamesToRemoves [h ] = struct {}{}
411+ }
412+ }
413+ }
414+
415+ isolatedHostnames := removeHostnames (hostnames , hostnamesToRemoves )
416+ ref .Attachment .AcceptedHostnames [listenerName ] = isolatedHostnames
417+ }
418+ }
419+ }
420+
421+ // removeHostnames removes the hostnames that are part of toRemove slice.
422+ func removeHostnames (hostnames []string , toRemove map [string ]struct {}) []string {
423+ result := make ([]string , 0 , len (hostnames ))
424+ for _ , hostname := range hostnames {
425+ if _ , exists := toRemove [hostname ]; ! exists {
426+ result = append (result , hostname )
427+ }
428+ }
429+ return result
356430}
357431
358432func validateParentRef (
0 commit comments