Skip to content

Commit df7c72a

Browse files
committed
listener isolation for hostnames
1 parent 3b5bece commit df7c72a

File tree

3 files changed

+649
-6
lines changed

3 files changed

+649
-6
lines changed

internal/mode/static/state/graph/route_common.go

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,22 +337,103 @@ func bindRoutesToListeners(
337337
bindL7RouteToListeners(r, gw, namespaces)
338338
}
339339

340-
var routes []*L4Route
340+
l7routes := make([]*L7Route, 0, len(l7Routes))
341+
for _, r := range l7Routes {
342+
l7routes = append(l7routes, r)
343+
}
344+
345+
isolateL7RouteListeners(l7routes, gw.Listeners)
346+
347+
l4routes := make([]*L4Route, 0, len(l4Routes))
341348
for _, r := range l4Routes {
342-
routes = append(routes, r)
349+
l4routes = append(l4routes, r)
343350
}
344351

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(l4routes, func(i, j int) bool {
354+
return ngfSort.LessClientObject(l4routes[i].Source, l4routes[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 l4routes {
354361
bindL4RouteToListeners(r, gw, namespaces, portHostnamesMap)
355362
}
363+
364+
isolateL4RouteListeners(l4routes, 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([]string, 0, len(acceptedHostnames))
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 = append(hostnamesToRemoves, h)
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 []string) []string {
423+
result := make([]string, 0, len(hostnames))
424+
for _, h := range hostnames {
425+
keep := true
426+
for _, r := range toRemove {
427+
if h == r {
428+
keep = false
429+
break
430+
}
431+
}
432+
if keep {
433+
result = append(result, h)
434+
}
435+
}
436+
return result
356437
}
357438

358439
func validateParentRef(
@@ -617,6 +698,11 @@ func tryToAttachL7RouteToListeners(
617698

618699
rk := CreateRouteKey(route.Source)
619700

701+
listenerHostnameMap := make(map[string]string, len(attachableListeners))
702+
for _, l := range attachableListeners {
703+
listenerHostnameMap[l.Name] = getHostname(l.Source.Hostname)
704+
}
705+
620706
bind := func(l *Listener) (allowed, attached bool) {
621707
if !isRouteNamespaceAllowedByListener(l, route.Source.GetNamespace(), gw.Source.Namespace, namespaces) {
622708
return false, false

0 commit comments

Comments
 (0)