diff --git a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml index 7b8319b6376..cacca5bb7c4 100644 --- a/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/default-resources.all.yaml @@ -1041,7 +1041,7 @@ xds: '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: udproute/default/backend/rule/-1 statPrefix: service - name: default/eg/udp/backend + name: default/eg/udp - '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump dynamicRouteConfigs: - routeConfig: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json index 80be0dae629..476f6cdae77 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.json @@ -942,7 +942,7 @@ } } ], - "name": "default/eg/udp/backend" + "name": "default/eg/udp" } } } diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml index 05c22f5ab88..4481d9989ff 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.all.yaml @@ -560,7 +560,7 @@ xds: '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: udproute/default/backend/rule/-1 statPrefix: service - name: default/eg/udp/backend + name: default/eg/udp - '@type': type.googleapis.com/envoy.admin.v3.RoutesConfigDump dynamicRouteConfigs: - routeConfig: diff --git a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml index 61288c6e130..2b1c410cd96 100644 --- a/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml +++ b/internal/cmd/egctl/testdata/translate/out/from-gateway-api-to-xds.listener.yaml @@ -255,4 +255,4 @@ xds: '@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route cluster: udproute/default/backend/rule/-1 statPrefix: service - name: default/eg/udp/backend + name: default/eg/udp diff --git a/internal/gatewayapi/backendtrafficpolicy.go b/internal/gatewayapi/backendtrafficpolicy.go index 1a2df010dae..d29f7d10656 100644 --- a/internal/gatewayapi/backendtrafficpolicy.go +++ b/internal/gatewayapi/backendtrafficpolicy.go @@ -354,9 +354,13 @@ func (t *Translator) translateBackendTrafficPolicyForRoute(policy *egv1a1.Backen } for _, udp := range x.UDP { - if strings.HasPrefix(udp.Destination.Name, prefix) { - udp.LoadBalancer = lb - udp.Timeout = to + if udp.Route != nil { + route := udp.Route + + if strings.HasPrefix(route.Destination.Name, prefix) { + route.LoadBalancer = lb + route.Timeout = to + } } } @@ -490,14 +494,20 @@ func (t *Translator) translateBackendTrafficPolicyForGateway(policy *egv1a1.Back continue } + if udp.Route == nil { + continue + } + + route := udp.Route + // policy(targeting xRoute) has already set it, so we skip it. - if udp.LoadBalancer != nil || udp.Timeout != nil { + if route.LoadBalancer != nil || route.Timeout != nil { continue } - udp.LoadBalancer = lb - if udp.Timeout == nil { - udp.Timeout = ct + route.LoadBalancer = lb + if route.Timeout == nil { + route.Timeout = ct } } diff --git a/internal/gatewayapi/helpers.go b/internal/gatewayapi/helpers.go index 246c1f12251..2dfc04a1842 100644 --- a/internal/gatewayapi/helpers.go +++ b/internal/gatewayapi/helpers.go @@ -347,10 +347,6 @@ func irListenerName(listener *ListenerContext) string { return fmt.Sprintf("%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name) } -func irUDPListenerName(listener *ListenerContext, udpRoute *UDPRouteContext) string { - return fmt.Sprintf("%s/%s/%s/%s", listener.gateway.Namespace, listener.gateway.Name, listener.Name, udpRoute.Name) -} - func irListenerPortName(proto ir.ProtocolType, port int32) string { return strings.ToLower(fmt.Sprintf("%s-%d", proto, port)) } @@ -369,6 +365,10 @@ func irTCPRouteName(route RouteContext) string { return fmt.Sprintf("%s/%s/%s", strings.ToLower(string(GetRouteType(route))), route.GetNamespace(), route.GetName()) } +func irUDPRouteName(route RouteContext) string { + return irTCPRouteName(route) +} + func irRouteDestinationName(route RouteContext, ruleIdx int) string { return fmt.Sprintf("%srule/%d", irRoutePrefix(route), ruleIdx) } diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go index 0d9b04a4027..62d60b75f1f 100644 --- a/internal/gatewayapi/listener.go +++ b/internal/gatewayapi/listener.go @@ -124,6 +124,13 @@ func (t *Translator) ProcessListeners(gateways []*GatewayContext, xdsIR XdsIRMap Port: uint32(containerPort), } xdsIR[irKey].TCP = append(xdsIR[irKey].TCP, irListener) + case gwapiv1.UDPProtocolType: + irListener := &ir.UDPListener{ + Name: irListenerName(listener), + Address: "0.0.0.0", + Port: uint32(containerPort), + } + xdsIR[irKey].UDP = append(xdsIR[irKey].UDP, irListener) } // Add the listener to the Infra IR. Infra IR ports must have a unique port number per layer-4 protocol diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go index 5edcf53af01..aa1d2091b63 100644 --- a/internal/gatewayapi/route.go +++ b/internal/gatewayapi/route.go @@ -929,21 +929,18 @@ func (t *Translator) processUDPRouteParentRefs(udpRoute *UDPRouteContext, resour irKey := t.getIRKey(listener.gateway) - containerPort := servicePortToContainerPort(int32(listener.Port)) - // Create the UDP Listener while parsing the UDPRoute since - // the listener directly links to a routeDestination. - irListener := &ir.UDPListener{ - Name: irUDPListenerName(listener, udpRoute), - Address: "0.0.0.0", - Port: uint32(containerPort), - Destination: &ir.RouteDestination{ - Name: irRouteDestinationName(udpRoute, -1 /*rule index*/), - Settings: destSettings, - }, - } gwXdsIR := xdsIR[irKey] - gwXdsIR.UDP = append(gwXdsIR.UDP, irListener) - + irListener := gwXdsIR.GetUDPListener(irListenerName(listener)) + if irListener != nil { + irRoute := &ir.UDPRoute{ + Name: irUDPRouteName(udpRoute), + Destination: &ir.RouteDestination{ + Name: irRouteDestinationName(udpRoute, -1 /*rule index*/), + Settings: destSettings, + }, + } + irListener.Route = irRoute + } } // If no negative conditions have been set, the route is considered "Accepted=True". diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml index 857ec1e89d1..660c8d7d800 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-gateway.out.yaml @@ -293,23 +293,25 @@ xdsIR: connectTimeout: 15s udp: - address: 0.0.0.0 - destination: - name: udproute/default/udp-app-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - loadBalancer: - consistentHash: - sourceIP: true - name: default/tcp-gateway/foo/udp-app-1 + name: default/tcp-gateway/foo port: 8162 - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s + route: + destination: + name: udproute/default/udp-app-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + loadBalancer: + consistentHash: + sourceIP: true + name: udproute/default/udp-app-1 + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s diff --git a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml index 5c0f2240bd6..d2c691d719d 100644 --- a/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml +++ b/internal/gatewayapi/testdata/backendtrafficpolicy-with-tcp-udp-listeners-apply-on-route.out.yaml @@ -366,23 +366,25 @@ xdsIR: connectTimeout: 15s udp: - address: 0.0.0.0 - destination: - name: udproute/default/udp-app-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - loadBalancer: - consistentHash: - sourceIP: true - name: default/tcp-gateway/foo/udp-app-1 + name: default/tcp-gateway/foo port: 8162 - timeout: - http: - connectionIdleTimeout: 16s - maxConnectionDuration: 17s - tcp: - connectTimeout: 15s + route: + destination: + name: udproute/default/udp-app-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + loadBalancer: + consistentHash: + sourceIP: true + name: udproute/default/udp-app-1 + timeout: + http: + connectionIdleTimeout: 16s + maxConnectionDuration: 17s + tcp: + connectTimeout: 15s diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml index 2fbbe314fa5..2603bbfad7d 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-mismatch-port-protocol.out.yaml @@ -92,9 +92,11 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - weight: 1 - name: envoy-gateway/gateway-1/udp/udproute-1 + name: envoy-gateway/gateway-1/udp port: 10162 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - weight: 1 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml index 7141e821a37..70a5a2a8599 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-backends.out.yaml @@ -96,20 +96,22 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 50 - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 50 - name: envoy-gateway/gateway-1/udp/udproute-1 + name: envoy-gateway/gateway-1/udp port: 10080 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 50 + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 50 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml index 56d9c366b02..850f9e64cba 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-udproute-with-multiple-rules.out.yaml @@ -95,3 +95,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + udp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/udp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml index 27d949d622e..a30d7cf5a5b 100644 --- a/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-listener-with-unmatched-udproute.out.yaml @@ -58,3 +58,7 @@ xdsIR: accessLog: text: - path: /dev/stdout + udp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-1/udp + port: 10080 diff --git a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml index 22e840d232a..4f4555a87e8 100644 --- a/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-single-listener-with-multiple-udproutes.out.yaml @@ -123,14 +123,16 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp/udproute-1 + name: envoy-gateway/gateway-1/udp port: 10162 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml index 68f755e99ab..5f904c3de3e 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-on-same-udp-port.out.yaml @@ -119,14 +119,16 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp1/udproute-1 + name: envoy-gateway/gateway-1/udp1 port: 10162 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml index 88db8d64873..ef9658f0f2a 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-same-port-http-udp-protocol.out.yaml @@ -191,14 +191,16 @@ xdsIR: prefix: / udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp/udproute-1 + name: envoy-gateway/gateway-1/udp port: 10080 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml index 418f7a0ad4e..00a61415035 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-with-sectionname.out.yaml @@ -161,26 +161,30 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp1/udproute-1 + name: envoy-gateway/gateway-1/udp1 port: 10162 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 - address: 0.0.0.0 - destination: - name: udproute/default/udproute-2/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp2/udproute-2 + name: envoy-gateway/gateway-1/udp2 port: 10163 + route: + destination: + name: udproute/default/udproute-2/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-2 diff --git a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml index 17b9d4e2253..f6cb6959c4b 100644 --- a/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml +++ b/internal/gatewayapi/testdata/gateway-with-two-listeners-with-udproutes-without-sectionname.out.yaml @@ -157,26 +157,30 @@ xdsIR: - path: /dev/stdout udp: - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp1/udproute-1 + name: envoy-gateway/gateway-1/udp1 port: 10161 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 - address: 0.0.0.0 - destination: - name: udproute/default/udproute-1/rule/-1 - settings: - - addressType: IP - endpoints: - - host: 7.7.7.7 - port: 8162 - protocol: UDP - weight: 1 - name: envoy-gateway/gateway-1/udp2/udproute-1 + name: envoy-gateway/gateway-1/udp2 port: 10162 + route: + destination: + name: udproute/default/udproute-1/rule/-1 + settings: + - addressType: IP + endpoints: + - host: 7.7.7.7 + port: 8162 + protocol: UDP + weight: 1 + name: udproute/default/udproute-1 diff --git a/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml b/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml index c37bd4038e5..64eba4e494a 100644 --- a/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml +++ b/internal/gatewayapi/testdata/merge-invalid-multiple-gateways.out.yaml @@ -145,3 +145,7 @@ xdsIR: escapedSlashesAction: UnescapeAndRedirect mergeSlashes: true port: 10080 + udp: + - address: 0.0.0.0 + name: envoy-gateway/gateway-2/udp + port: 10080 diff --git a/internal/ir/xds.go b/internal/ir/xds.go index 6d9ac357e73..b77d26cf759 100644 --- a/internal/ir/xds.go +++ b/internal/ir/xds.go @@ -1332,6 +1332,15 @@ type UDPListener struct { Address string `json:"address" yaml:"address"` // Port on which the service can be expected to be accessed by clients. Port uint32 `json:"port" yaml:"port"` + // Route associated with UDP traffic to the listener. + Route *UDPRoute `json:"route,omitempty" yaml:"route,omitempty"` +} + +// UDPRoute holds the route information associated with the UDP Route. +// +k8s:deepcopy-gen=true +type UDPRoute struct { + // Name of the UDPRoute. + Name string `json:"name" yaml:"name"` // Destination associated with UDP traffic to the service. Destination *RouteDestination `json:"destination,omitempty" yaml:"destination,omitempty"` // load balancer policy to use when routing to the backend endpoints. @@ -1352,8 +1361,25 @@ func (h UDPListener) Validate() error { if h.Port == 0 { errs = errors.Join(errs, ErrListenerPortInvalid) } - if h.Destination != nil { - if err := h.Destination.Validate(); err != nil { + + if h.Route != nil { + if err := h.Route.Validate(); err != nil { + errs = errors.Join(errs, err) + } + } + + return errs +} + +func (u UDPRoute) Validate() error { + var errs error + + if u.Name == "" { + errs = errors.Join(errs, ErrRouteNameEmpty) + } + + if u.Destination != nil { + if err := u.Destination.Validate(); err != nil { errs = errors.Join(errs, err) } } diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go index ec1b0f74132..d122f25c6e1 100644 --- a/internal/ir/xds_test.go +++ b/internal/ir/xds_test.go @@ -144,26 +144,32 @@ var ( // UDPListener happyUDPListener = UDPListener{ - Name: "happy", - Address: "0.0.0.0", - Port: 80, - Destination: &happyRouteDestination, + Name: "happy", + Address: "0.0.0.0", + Port: 80, + Route: &happyUDPRoute, } invalidNameUDPListener = UDPListener{ - Address: "0.0.0.0", - Port: 80, - Destination: &happyRouteDestination, + Address: "0.0.0.0", + Port: 80, + Route: &happyUDPRoute, } invalidAddrUDPListener = UDPListener{ - Name: "invalid-addr", - Address: "1.0.0", - Port: 80, - Destination: &happyRouteDestination, + Name: "invalid-addr", + Address: "1.0.0", + Port: 80, + Route: &happyUDPRoute, } invalidPortUDPListenerT = UDPListener{ - Name: "invalid-port", - Address: "0.0.0.0", - Port: 0, + Name: "invalid-port", + Address: "0.0.0.0", + Port: 0, + Route: &happyUDPRoute, + } + + // UDPRoute + happyUDPRoute = UDPRoute{ + Name: "happy", Destination: &happyRouteDestination, } diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go index 172ac9ec493..0024414525f 100644 --- a/internal/ir/zz_generated.deepcopy.go +++ b/internal/ir/zz_generated.deepcopy.go @@ -2445,6 +2445,26 @@ func (in *TrafficFeatures) DeepCopy() *TrafficFeatures { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *UDPListener) DeepCopyInto(out *UDPListener) { + *out = *in + if in.Route != nil { + in, out := &in.Route, &out.Route + *out = new(UDPRoute) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPListener. +func (in *UDPListener) DeepCopy() *UDPListener { + if in == nil { + return nil + } + out := new(UDPListener) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UDPRoute) DeepCopyInto(out *UDPRoute) { *out = *in if in.Destination != nil { in, out := &in.Destination, &out.Destination @@ -2463,12 +2483,12 @@ func (in *UDPListener) DeepCopyInto(out *UDPListener) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPListener. -func (in *UDPListener) DeepCopy() *UDPListener { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UDPRoute. +func (in *UDPRoute) DeepCopy() *UDPRoute { if in == nil { return nil } - out := new(UDPListener) + out := new(UDPRoute) in.DeepCopyInto(out) return out } diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml index 4b5b9982aee..fc597f28928 100644 --- a/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/udp-endpoint-stats.yaml @@ -5,11 +5,13 @@ udp: - name: "udp-route-enable-endpoint-stats" address: "0.0.0.0" port: 10080 - destination: - name: "udp-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + route: + name: "udp-route" + destination: + name: "udp-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-route-invalid.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-route-invalid.yaml index 39ab4e7f403..29841a984b8 100644 --- a/internal/xds/translator/testdata/in/xds-ir/udp-route-invalid.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/udp-route-invalid.yaml @@ -1,10 +1,12 @@ udp: - name: "udp-route" port: 10080 - destination: - name: "udp-reoute-dest" - settings: - - endpoints: - - host: "" - - host: "5.6.7.8" - port: 50001 + route: + name: "udp-route" + destination: + name: "udp-route-dest" + settings: + - endpoints: + - host: "" + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml b/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml index fa4ffafc138..a933bdd78a4 100644 --- a/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml +++ b/internal/xds/translator/testdata/in/xds-ir/udp-route.yaml @@ -2,11 +2,13 @@ udp: - name: "udp-route" address: "0.0.0.0" port: 10080 - destination: - name: "udp-route-dest" - settings: - - endpoints: - - host: "1.2.3.4" - port: 50000 - - host: "5.6.7.8" - port: 50001 + route: + name: "udp-route" + destination: + name: "udp-route-dest" + settings: + - endpoints: + - host: "1.2.3.4" + port: 50000 + - host: "5.6.7.8" + port: 50001 diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go index cab26d1f905..373d4a7530c 100644 --- a/internal/xds/translator/translator.go +++ b/internal/xds/translator/translator.go @@ -529,29 +529,33 @@ func processUDPListenerXdsTranslation(tCtx *types.ResourceVersionTable, udpListe for _, udpListener := range udpListeners { // There won't be multiple UDP listeners on the same port since it's already been checked at the gateway api // translator - xdsListener, err := buildXdsUDPListener(udpListener.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 - } + if udpListener.Route != nil { + route := udpListener.Route - // 1:1 between IR UDPListener and xDS Cluster - if err := addXdsCluster(tCtx, &xdsClusterArgs{ - name: udpListener.Destination.Name, - settings: udpListener.Destination.Settings, - loadBalancer: udpListener.LoadBalancer, - timeout: udpListener.Timeout, - tSocket: nil, - endpointType: buildEndpointType(udpListener.Destination.Settings), - metrics: metrics, - }); err != nil && !errors.Is(err, ErrXdsClusterExists) { - errs = errors.Join(errs, err) + 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 := addXdsCluster(tCtx, &xdsClusterArgs{ + name: route.Destination.Name, + settings: route.Destination.Settings, + loadBalancer: route.LoadBalancer, + timeout: route.Timeout, + tSocket: nil, + endpointType: buildEndpointType(route.Destination.Settings), + metrics: metrics, + }); err != nil && !errors.Is(err, ErrXdsClusterExists) { + errs = errors.Join(errs, err) + } } } return errs