@@ -337,22 +337,96 @@ func bindRoutesToListeners(
337
337
bindL7RouteToListeners (r , gw , namespaces )
338
338
}
339
339
340
- var routes []* L4Route
341
- for _ , r := range l4Routes {
340
+ routes := make ( []* L7Route , 0 , len ( l7Routes ))
341
+ for _ , r := range l7Routes {
342
342
routes = append (routes , r )
343
343
}
344
344
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
+
345
352
// 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 )
348
355
})
349
356
350
357
// portHostnamesMap exists to detect duplicate hostnames on the same port
351
358
portHostnamesMap := make (map [string ]struct {})
352
359
353
- for _ , r := range routes {
360
+ for _ , r := range l4RouteSlice {
354
361
bindL4RouteToListeners (r , gw , namespaces , portHostnamesMap )
355
362
}
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
356
430
}
357
431
358
432
func validateParentRef (
0 commit comments