From 4d8cf28971a4e8e1b3ddfab3576115cbad3df78f Mon Sep 17 00:00:00 2001 From: Saylor Berman Date: Mon, 10 Nov 2025 17:03:02 -0700 Subject: [PATCH 1/2] Deduplicate route status entries Problem: Due to a shared slice pointer, in certain scenarios we could get entries in the status list that don't belong there, and result in duplicate entries when writing the status to the route. Solution: Copy the previous value before adding new entries, to avoid the shared slice. --- internal/controller/status/status_setters.go | 33 ++++++++++++++------ 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/internal/controller/status/status_setters.go b/internal/controller/status/status_setters.go index fc1e1a688b..61aef2f572 100644 --- a/internal/controller/status/status_setters.go +++ b/internal/controller/status/status_setters.go @@ -84,17 +84,22 @@ func newHTTPRouteStatusSetter(status gatewayv1.HTTPRouteStatus, gatewayCtlrName hr := helpers.MustCastObject[*gatewayv1.HTTPRoute](object) // keep all the parent statuses that belong to other controllers + newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) + copy(newParents, status.Parents) for _, os := range hr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { - status.Parents = append(status.Parents, os) + newParents = append(newParents, os) } } - if routeStatusEqual(gatewayCtlrName, hr.Status.Parents, status.Parents) { + fullStatus := status + fullStatus.Parents = newParents + + if routeStatusEqual(gatewayCtlrName, hr.Status.Parents, fullStatus.Parents) { return false } - hr.Status = status + hr.Status = fullStatus return true } @@ -105,17 +110,22 @@ func newTLSRouteStatusSetter(status v1alpha2.TLSRouteStatus, gatewayCtlrName str tr := helpers.MustCastObject[*v1alpha2.TLSRoute](object) // keep all the parent statuses that belong to other controllers + newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) + copy(newParents, status.Parents) for _, os := range tr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { - status.Parents = append(status.Parents, os) + newParents = append(newParents, os) } } - if routeStatusEqual(gatewayCtlrName, tr.Status.Parents, status.Parents) { + fullStatus := status + fullStatus.Parents = newParents + + if routeStatusEqual(gatewayCtlrName, tr.Status.Parents, fullStatus.Parents) { return false } - tr.Status = status + tr.Status = fullStatus return true } @@ -126,17 +136,22 @@ func newGRPCRouteStatusSetter(status gatewayv1.GRPCRouteStatus, gatewayCtlrName gr := helpers.MustCastObject[*gatewayv1.GRPCRoute](object) // keep all the parent statuses that belong to other controllers + newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) + copy(newParents, status.Parents) for _, os := range gr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { - status.Parents = append(status.Parents, os) + newParents = append(newParents, os) } } - if routeStatusEqual(gatewayCtlrName, gr.Status.Parents, status.Parents) { + fullStatus := status + fullStatus.Parents = newParents + + if routeStatusEqual(gatewayCtlrName, gr.Status.Parents, fullStatus.Parents) { return false } - gr.Status = status + gr.Status = fullStatus return true } From 66cc800d08fc922ab74f2158c93fad280259c46a Mon Sep 17 00:00:00 2001 From: Saylor Berman Date: Tue, 11 Nov 2025 08:29:59 -0700 Subject: [PATCH 2/2] Fix slice copying --- internal/controller/status/status_setters.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/controller/status/status_setters.go b/internal/controller/status/status_setters.go index 61aef2f572..085ade1e7e 100644 --- a/internal/controller/status/status_setters.go +++ b/internal/controller/status/status_setters.go @@ -85,7 +85,7 @@ func newHTTPRouteStatusSetter(status gatewayv1.HTTPRouteStatus, gatewayCtlrName // keep all the parent statuses that belong to other controllers newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) - copy(newParents, status.Parents) + newParents = append(newParents, status.Parents...) for _, os := range hr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { newParents = append(newParents, os) @@ -111,7 +111,7 @@ func newTLSRouteStatusSetter(status v1alpha2.TLSRouteStatus, gatewayCtlrName str // keep all the parent statuses that belong to other controllers newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) - copy(newParents, status.Parents) + newParents = append(newParents, status.Parents...) for _, os := range tr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { newParents = append(newParents, os) @@ -137,7 +137,7 @@ func newGRPCRouteStatusSetter(status gatewayv1.GRPCRouteStatus, gatewayCtlrName // keep all the parent statuses that belong to other controllers newParents := make([]gatewayv1.RouteParentStatus, 0, len(status.Parents)) - copy(newParents, status.Parents) + newParents = append(newParents, status.Parents...) for _, os := range gr.Status.Parents { if string(os.ControllerName) != gatewayCtlrName { newParents = append(newParents, os)