From bba09b9cf46d1d99fde21fb4973d2dc1d759ae4b Mon Sep 17 00:00:00 2001 From: kkk777-7 Date: Sun, 25 May 2025 16:22:24 +0900 Subject: [PATCH 1/6] fix: translate udp listener Signed-off-by: kkk777-7 --- internal/xds/translator/translator.go | 54 +++++++++++++++++---------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index a737fe50ff..533d48f6ba 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -38,7 +38,7 @@ import ( const ( AuthorityHeaderKey = ":authority" - // The dummy cluster for TCP listeners that have no routes + // The dummy cluster for TCP/UDP listeners that have no routes emptyClusterName = "EmptyCluster" ) @@ -770,29 +770,38 @@ func processUDPListenerXdsTranslation( // There won't be multiple UDP listeners on the same port since it's already been checked at the gateway api // translator if udpListener.Route != nil { - route := udpListener.Route - - xdsListener, err := buildXdsUDPListener(route.Destination.Name, udpListener, accesslog) - if err != nil { - // skip this listener if failed to build xds listener - errs = errors.Join(errs, err) - continue - } - if err := tCtx.AddXdsResource(resourcev3.ListenerType, xdsListener); err != nil { - // skip this listener if failed to add xds listener to the resource version table - errs = errors.Join(errs, err) - continue - } - // 1:1 between IR UDPRoute and xDS Cluster if err := processXdsCluster(tCtx, - route.Destination.Name, - route.Destination.Settings, - &UDPRouteTranslator{route}, + udpListener.Route.Destination.Name, + udpListener.Route.Destination.Settings, + &UDPRouteTranslator{udpListener.Route}, &ExtraArgs{metrics: metrics}, - route.Destination.Metadata); err != nil { + udpListener.Route.Destination.Metadata); err != nil { errs = errors.Join(errs, err) } + } else { + // Add empty cluster for UDP listener which have no Route, when empty cluster is not found. + emptyRouteCluster := &clusterv3.Cluster{ + Name: emptyClusterName, + ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, + } + if findXdsCluster(tCtx, emptyClusterName) == nil { + if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil { + errs = errors.Join(errs, err) + } + } + } + + xdsListener, err := buildXdsUDPListener(getClusterNameForUDPListener(udpListener), udpListener, accesslog) + if err != nil { + // skip this listener if failed to build xds listener + errs = errors.Join(errs, err) + continue + } + if err := tCtx.AddXdsResource(resourcev3.ListenerType, xdsListener); err != nil { + // skip this listener if failed to add xds listener to the resource version table + errs = errors.Join(errs, err) + continue } } return errs @@ -1124,3 +1133,10 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3. }, }, nil } + +func getClusterNameForUDPListener(listener *ir.UDPListener) string { + if listener.Route == nil || listener.Route.Destination == nil { + return emptyClusterName + } + return listener.Route.Destination.Name +} From afb5ef321c5f0b68dc634d3ecf925394100663bd Mon Sep 17 00:00:00 2001 From: kkk777-7 Date: Sun, 25 May 2025 16:32:03 +0900 Subject: [PATCH 2/6] add: tcp/udp no routes testdata in xds translator Signed-off-by: kkk777-7 --- .../in/xds-ir/tcp-route-with-no-routes.yaml | 4 ++++ .../in/xds-ir/udp-route-with-no-routes.yaml | 4 ++++ .../tcp-route-with-no-routes.clusters.yaml | 2 ++ .../tcp-route-with-no-routes.endpoints.yaml | 1 + .../tcp-route-with-no-routes.listeners.yaml | 14 ++++++++++++++ .../tcp-route-with-no-routes.routes.yaml | 1 + .../udp-route-with-no-routes.clusters.yaml | 2 ++ .../udp-route-with-no-routes.endpoints.yaml | 1 + .../udp-route-with-no-routes.listeners.yaml | 18 ++++++++++++++++++ .../udp-route-with-no-routes.routes.yaml | 1 + 10 files changed, 48 insertions(+) create mode 100644 internal/xds/translator/testdata/in/xds-ir/tcp-route-with-no-routes.yaml create mode 100644 internal/xds/translator/testdata/in/xds-ir/udp-route-with-no-routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.routes.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.clusters.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.endpoints.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.listeners.yaml create mode 100644 internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.routes.yaml diff --git a/internal/xds/translator/testdata/in/xds-ir/tcp-route-with-no-routes.yaml b/internal/xds/translator/testdata/in/xds-ir/tcp-route-with-no-routes.yaml new file mode 100644 index 0000000000..dafca1cf20 --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/tcp-route-with-no-routes.yaml @@ -0,0 +1,4 @@ +tcp: +- name: "tcp-listener-with-no-routes" + address: "::" + port: 10080 diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-route-with-no-routes.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-route-with-no-routes.yaml new file mode 100644 index 0000000000..fc6a647cba --- /dev/null +++ b/internal/xds/translator/testdata/in/xds-ir/udp-route-with-no-routes.yaml @@ -0,0 +1,4 @@ +udp: +- name: "udp-route-with-no-routes" + address: "::" + port: 10080 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.clusters.yaml new file mode 100644 index 0000000000..0764d46f0e --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.clusters.yaml @@ -0,0 +1,2 @@ +- name: EmptyCluster + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.endpoints.yaml new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.endpoints.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.listeners.yaml new file mode 100644 index 0000000000..4250f0a6b5 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.listeners.yaml @@ -0,0 +1,14 @@ +- address: + socketAddress: + address: '::' + portValue: 10080 + filterChains: + - filters: + - name: envoy.filters.network.tcp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy + cluster: EmptyCluster + statPrefix: tcp-10080 + name: EmptyCluster + name: tcp-listener-with-no-routes + perConnectionBufferLimitBytes: 32768 diff --git a/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.routes.yaml new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/tcp-route-with-no-routes.routes.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.clusters.yaml new file mode 100644 index 0000000000..0764d46f0e --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.clusters.yaml @@ -0,0 +1,2 @@ +- name: EmptyCluster + type: STATIC diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.endpoints.yaml new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.endpoints.yaml @@ -0,0 +1 @@ +[] diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.listeners.yaml new file mode 100644 index 0000000000..ce76497d0c --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.listeners.yaml @@ -0,0 +1,18 @@ +- address: + socketAddress: + address: '::' + portValue: 10080 + protocol: UDP + listenerFilters: + - name: envoy.filters.udp_listener.udp_proxy + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig + matcher: + onNoMatch: + action: + name: route + typedConfig: + '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route + cluster: EmptyCluster + statPrefix: service + name: udp-route-with-no-routes diff --git a/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.routes.yaml new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/internal/xds/translator/testdata/out/xds-ir/udp-route-with-no-routes.routes.yaml @@ -0,0 +1 @@ +[] From 6c841547571cd1a62dc452fffa327b6ed67a240e Mon Sep 17 00:00:00 2001 From: kkk777-7 Date: Sun, 25 May 2025 16:39:59 +0900 Subject: [PATCH 3/6] add: release note Signed-off-by: kkk777-7 --- release-notes/current.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/release-notes/current.yaml b/release-notes/current.yaml index 1f4474042f..13d234ca72 100644 --- a/release-notes/current.yaml +++ b/release-notes/current.yaml @@ -18,6 +18,7 @@ new features: | bug fixes: | Fixed issue where WASM cache init failure caused routes with WASM-less EnvoyExtensionPolicies to have 500 direct responses. + Fixed issue which UDP listeners were not created in the Envoy proxy config when Gateway was created. # Enhancements that improve performance. performance improvements: | From 1fbd2157d2599c14ae8aef095025e3723307fc56 Mon Sep 17 00:00:00 2001 From: github kkk777-7 Date: Tue, 27 May 2025 00:49:09 +0900 Subject: [PATCH 4/6] refactor: remove unnecessary functions Signed-off-by: github kkk777-7 --- internal/xds/translator/translator.go | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 533d48f6ba..d830f3b578 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -780,6 +780,14 @@ func processUDPListenerXdsTranslation( errs = errors.Join(errs, err) } } else { + emptyRoute := &ir.UDPRoute{ + Name: emptyClusterName, + Destination: &ir.RouteDestination{ + Name: emptyClusterName, + }, + } + udpListener.Route = emptyRoute + // Add empty cluster for UDP listener which have no Route, when empty cluster is not found. emptyRouteCluster := &clusterv3.Cluster{ Name: emptyClusterName, @@ -792,7 +800,7 @@ func processUDPListenerXdsTranslation( } } - xdsListener, err := buildXdsUDPListener(getClusterNameForUDPListener(udpListener), udpListener, accesslog) + xdsListener, err := buildXdsUDPListener(udpListener.Route.Destination.Name, udpListener, accesslog) if err != nil { // skip this listener if failed to build xds listener errs = errors.Join(errs, err) @@ -1133,10 +1141,3 @@ func buildXdsUpstreamTLSSocketWthCert(tlsConfig *ir.TLSUpstreamConfig) (*corev3. }, }, nil } - -func getClusterNameForUDPListener(listener *ir.UDPListener) string { - if listener.Route == nil || listener.Route.Destination == nil { - return emptyClusterName - } - return listener.Route.Destination.Name -} From cf84bcb5cde794bdc5db97fae7b0955f0f8c8ffd Mon Sep 17 00:00:00 2001 From: github kkk777-7 Date: Tue, 27 May 2025 01:47:32 +0900 Subject: [PATCH 5/6] update: declare global var Signed-off-by: github kkk777-7 --- internal/xds/translator/translator.go | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index d830f3b578..0733ee4977 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -38,10 +38,18 @@ import ( const ( AuthorityHeaderKey = ":authority" - // The dummy cluster for TCP/UDP listeners that have no routes + // The dummy cluster name for TCP/UDP listeners that have no routes emptyClusterName = "EmptyCluster" ) +var ( + // The dummy cluster for TCP/UDP listeners that have no routes + emptyRouteCluster = &clusterv3.Cluster{ + Name: emptyClusterName, + ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, + } +) + // Translator translates the xDS IR into xDS resources. type Translator struct { // ControllerNamespace is the namespace of the Gateway API controller @@ -731,11 +739,6 @@ func (t *Translator) processTCPListenerXdsTranslation( // If there are no routes, add a route without a destination to the listener to create a filter chain // This is needed because Envoy requires a filter chain to be present in the listener, otherwise it will reject the listener and report a warning if len(tcpListener.Routes) == 0 { - emptyRouteCluster := &clusterv3.Cluster{ - Name: emptyClusterName, - ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, - } - if findXdsCluster(tCtx, emptyClusterName) == nil { if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil { errs = errors.Join(errs, err) @@ -780,19 +783,14 @@ func processUDPListenerXdsTranslation( errs = errors.Join(errs, err) } } else { - emptyRoute := &ir.UDPRoute{ + udpListener.Route = &ir.UDPRoute{ Name: emptyClusterName, Destination: &ir.RouteDestination{ Name: emptyClusterName, }, } - udpListener.Route = emptyRoute // Add empty cluster for UDP listener which have no Route, when empty cluster is not found. - emptyRouteCluster := &clusterv3.Cluster{ - Name: emptyClusterName, - ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, - } if findXdsCluster(tCtx, emptyClusterName) == nil { if err := tCtx.AddXdsResource(resourcev3.ClusterType, emptyRouteCluster); err != nil { errs = errors.Join(errs, err) From 81906d8049bc3833f96611f95a2484a849206878 Mon Sep 17 00:00:00 2001 From: github kkk777-7 Date: Tue, 27 May 2025 02:11:37 +0900 Subject: [PATCH 6/6] fix: golint Signed-off-by: github kkk777-7 --- internal/xds/translator/translator.go | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index 0733ee4977..79e59b39ad 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -42,13 +42,11 @@ const ( emptyClusterName = "EmptyCluster" ) -var ( - // The dummy cluster for TCP/UDP listeners that have no routes - emptyRouteCluster = &clusterv3.Cluster{ - Name: emptyClusterName, - ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, - } -) +// The dummy cluster for TCP/UDP listeners that have no routes +var emptyRouteCluster = &clusterv3.Cluster{ + Name: emptyClusterName, + ClusterDiscoveryType: &clusterv3.Cluster_Type{Type: clusterv3.Cluster_STATIC}, +} // Translator translates the xDS IR into xDS resources. type Translator struct {