Repository: envoyproxy/gateway

Issue:
Adding HTTPRoutes causes Listener Drains
*Description*:
Adding an HTTPRoute with `sessionPersistence` caused the listener to drain which affects long running requests.

```yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: test
  namespace: default
spec:
  hostnames:
  - www.example.com
  parentRefs:
  - group: gateway.networking.k8s.io
    kind: Gateway
    name: ingress
  rules:
  - backendRefs:
    - name: backend
      port: 8000
    matches:
    - path:
        type: PathPrefix
        value: /
    sessionPersistence:
      sessionName: x-eg-sp
      type: Header
```

```bash
curl http://localhost:19000/stats |grep drain
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Handling connection for 19000
...
listener_manager.total_listeners_draining: 1
```

*Repro steps*:
> Include sample requests, environment, etc. All data and inputs
required to reproduce the bug.

Add an HTTPRoute to a listener, or configure an exiting HTTPRoute with sessionPersistence.

>**Note**: If there are privacy concerns, sanitize the data prior to
sharing.

*Environment*:
>Include the environment like gateway version, envoy version and so on.
EG 1.4.2

*Logs*:
>Include the access logs and the Envoy logs.


Discussion:

Solution patch:
diff --git a/api/v1alpha1/authorization_types.go b/api/v1alpha1/authorization_types.go
index 41b1c3890..0ba7cf9c8 100644
--- a/api/v1alpha1/authorization_types.go
+++ b/api/v1alpha1/authorization_types.go
@@ -82,7 +82,7 @@ type Principal struct {
 	//
 	// The client IP is inferred from the X-Forwarded-For header, a custom header,
 	// or the proxy protocol.
-	// You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
+	// You can use the `ClientIPDetection` or the `ProxyProtocol` field in
 	// the `ClientTrafficPolicy` to configure how the client IP is detected.
 	//
 	// +optional
diff --git a/api/v1alpha1/clienttrafficpolicy_types.go b/api/v1alpha1/clienttrafficpolicy_types.go
index 799386f41..649b4b635 100644
--- a/api/v1alpha1/clienttrafficpolicy_types.go
+++ b/api/v1alpha1/clienttrafficpolicy_types.go
@@ -56,8 +56,17 @@ type ClientTrafficPolicySpec struct {
 	// Note Proxy Protocol must be present when this field is set, else the connection
 	// is closed.
 	//
+	// Deprecated: Use ProxyProtocol instead.
+	//
 	// +optional
 	EnableProxyProtocol *bool `json:"enableProxyProtocol,omitempty"`
+	// ProxyProtocol configures the Proxy Protocol settings. When configured,
+	// the Proxy Protocol header will be interpreted and the Client Address
+	// will be added into the X-Forwarded-For header.
+	// If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+	//
+	// +optional
+	ProxyProtocol *ProxyProtocolSettings `json:"proxyProtocol,omitempty"`
 	// ClientIPDetectionSettings provides configuration for determining the original client IP address for requests.
 	//
 	// +optional
@@ -344,6 +353,25 @@ type HealthCheckSettings struct {
 	Path string `json:"path"`
 }
 
+// ProxyProtocolSettings configures the Proxy Protocol settings. When configured,
+// the Proxy Protocol header will be interpreted and the Client Address
+// will be added into the X-Forwarded-For header.
+// If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+//
+// +kubebuilder:validation:MinProperties=0
+type ProxyProtocolSettings struct {
+	// Optional allows requests without a Proxy Protocol header to be proxied.
+	// If set to true, the listener will accept requests without a Proxy Protocol header.
+	// If set to false, the listener will reject requests without a Proxy Protocol header.
+	// If not set, the default behavior is to reject requests without a Proxy Protocol header.
+	// Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.
+	// For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt
+	//
+	//
+	// +optional
+	Optional *bool `json:"optional,omitempty"`
+}
+
 //+kubebuilder:object:root=true
 
 // ClientTrafficPolicyList contains a list of ClientTrafficPolicy resources.
diff --git a/api/v1alpha1/envoyproxy_tracing_types.go b/api/v1alpha1/envoyproxy_tracing_types.go
index 3dcd63a28..2e25a7b22 100644
--- a/api/v1alpha1/envoyproxy_tracing_types.go
+++ b/api/v1alpha1/envoyproxy_tracing_types.go
@@ -70,6 +70,16 @@ type TracingProvider struct {
 	// +kubebuilder:validation:Minimum=0
 	// +kubebuilder:default=4317
 	Port int32 `json:"port,omitempty"`
+	// ServiceName defines the service name to use in tracing configuration.
+	// If not set, Envoy Gateway will use a default service name set as
+	// "name.namespace" (e.g., "my-gateway.default").
+	// Note: This field is only supported for OpenTelemetry and Datadog tracing providers.
+	// For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag
+	// (typically "namespace/name" format). Setting this field has no effect for Zipkin.
+	//
+	// +optional
+	// +kubebuilder:validation:XValidation:message="serviceName cannot be empty if provided",rule="self != \"\""
+	ServiceName *string `json:"serviceName,omitempty"`
 	// Zipkin defines the Zipkin tracing provider configuration
 	// +optional
 	Zipkin *ZipkinTracingProvider `json:"zipkin,omitempty"`
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index e4aff858b..4c15267a1 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -1090,6 +1090,11 @@ func (in *ClientTrafficPolicySpec) DeepCopyInto(out *ClientTrafficPolicySpec) {
 		*out = new(bool)
 		**out = **in
 	}
+	if in.ProxyProtocol != nil {
+		in, out := &in.ProxyProtocol, &out.ProxyProtocol
+		*out = new(ProxyProtocolSettings)
+		(*in).DeepCopyInto(*out)
+	}
 	if in.ClientIPDetection != nil {
 		in, out := &in.ClientIPDetection, &out.ClientIPDetection
 		*out = new(ClientIPDetectionSettings)
@@ -5440,6 +5445,26 @@ func (in *ProxyProtocol) DeepCopy() *ProxyProtocol {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ProxyProtocolSettings) DeepCopyInto(out *ProxyProtocolSettings) {
+	*out = *in
+	if in.Optional != nil {
+		in, out := &in.Optional, &out.Optional
+		*out = new(bool)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProtocolSettings.
+func (in *ProxyProtocolSettings) DeepCopy() *ProxyProtocolSettings {
+	if in == nil {
+		return nil
+	}
+	out := new(ProxyProtocolSettings)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ProxyTelemetry) DeepCopyInto(out *ProxyTelemetry) {
 	*out = *in
@@ -6697,6 +6722,11 @@ func (in *TracingProvider) DeepCopyInto(out *TracingProvider) {
 		*out = new(string)
 		**out = **in
 	}
+	if in.ServiceName != nil {
+		in, out := &in.ServiceName, &out.ServiceName
+		*out = new(string)
+		**out = **in
+	}
 	if in.Zipkin != nil {
 		in, out := &in.Zipkin, &out.Zipkin
 		*out = new(ZipkinTracingProvider)
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
index 0f1078b7a..311faf9ce 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -182,6 +182,8 @@ spec:
                   Client Address into the X-Forwarded-For header.
                   Note Proxy Protocol must be present when this field is set, else the connection
                   is closed.
+
+                  Deprecated: Use ProxyProtocol instead.
                 type: boolean
               headers:
                 description: HeaderSettings provides configuration for header management.
@@ -514,6 +516,24 @@ spec:
                     - UnescapeAndRedirect
                     type: string
                 type: object
+              proxyProtocol:
+                description: |-
+                  ProxyProtocol configures the Proxy Protocol settings. When configured,
+                  the Proxy Protocol header will be interpreted and the Client Address
+                  will be added into the X-Forwarded-For header.
+                  If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+                minProperties: 0
+                properties:
+                  optional:
+                    description: |-
+                      Optional allows requests without a Proxy Protocol header to be proxied.
+                      If set to true, the listener will accept requests without a Proxy Protocol header.
+                      If set to false, the listener will reject requests without a Proxy Protocol header.
+                      If not set, the default behavior is to reject requests without a Proxy Protocol header.
+                      Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.
+                      For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt
+                    type: boolean
+                type: object
               targetRef:
                 description: |-
                   TargetRef is the name of the resource this policy is being attached to.
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
index c2b518ab3..b88c8c185 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -14929,6 +14929,18 @@ spec:
                             format: int32
                             minimum: 0
                             type: integer
+                          serviceName:
+                            description: |-
+                              ServiceName defines the service name to use in tracing configuration.
+                              If not set, Envoy Gateway will use a default service name set as
+                              "name.namespace" (e.g., "my-gateway.default").
+                              Note: This field is only supported for OpenTelemetry and Datadog tracing providers.
+                              For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag
+                              (typically "namespace/name" format). Setting this field has no effect for Zipkin.
+                            type: string
+                            x-kubernetes-validations:
+                            - message: serviceName cannot be empty if provided
+                              rule: self != ""
                           type:
                             default: OpenTelemetry
                             description: Type defines the tracing provider type.
diff --git a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
index fb947fca1..77fee40bf 100644
--- a/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-crds-helm/templates/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -253,7 +253,7 @@ spec:
 
                                 The client IP is inferred from the X-Forwarded-For header, a custom header,
                                 or the proxy protocol.
-                                You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
+                                You can use the `ClientIPDetection` or the `ProxyProtocol` field in
                                 the `ClientTrafficPolicy` to configure how the client IP is detected.
                               items:
                                 description: |-
diff --git a/charts/gateway-helm/README.md b/charts/gateway-helm/README.md
index 1b296544b..7d9509756 100644
--- a/charts/gateway-helm/README.md
+++ b/charts/gateway-helm/README.md
@@ -59,7 +59,7 @@ helm uninstall eg -n envoy-gateway-system
 
 | Key | Type | Default | Description |
 |-----|------|---------|-------------|
-| certgen | object | `{"job":{"affinity":{},"annotations":{},"args":[],"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65532,"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"args":[],"nodeSelector":{},"pod":{"annotations":{},"labels":{}},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65532,"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
 | config.envoyGateway | object | `{"extensionApis":{},"gateway":{"controllerName":"gateway.envoyproxy.io/gatewayclass-controller"},"logging":{"level":{"default":"info"}},"provider":{"type":"Kubernetes"}}` | EnvoyGateway configuration. Visit https://gateway.envoyproxy.io/docs/api/extension_types/#envoygateway to view all options. |
 | createNamespace | bool | `false` |  |
 | deployment.annotations | object | `{}` |  |
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
index bf1c7e98a..85e91f588 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_clienttrafficpolicies.yaml
@@ -181,6 +181,8 @@ spec:
                   Client Address into the X-Forwarded-For header.
                   Note Proxy Protocol must be present when this field is set, else the connection
                   is closed.
+
+                  Deprecated: Use ProxyProtocol instead.
                 type: boolean
               headers:
                 description: HeaderSettings provides configuration for header management.
@@ -513,6 +515,24 @@ spec:
                     - UnescapeAndRedirect
                     type: string
                 type: object
+              proxyProtocol:
+                description: |-
+                  ProxyProtocol configures the Proxy Protocol settings. When configured,
+                  the Proxy Protocol header will be interpreted and the Client Address
+                  will be added into the X-Forwarded-For header.
+                  If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+                minProperties: 0
+                properties:
+                  optional:
+                    description: |-
+                      Optional allows requests without a Proxy Protocol header to be proxied.
+                      If set to true, the listener will accept requests without a Proxy Protocol header.
+                      If set to false, the listener will reject requests without a Proxy Protocol header.
+                      If not set, the default behavior is to reject requests without a Proxy Protocol header.
+                      Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.
+                      For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt
+                    type: boolean
+                type: object
               targetRef:
                 description: |-
                   TargetRef is the name of the resource this policy is being attached to.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
index ebe9d6c14..d59643e97 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_envoyproxies.yaml
@@ -14928,6 +14928,18 @@ spec:
                             format: int32
                             minimum: 0
                             type: integer
+                          serviceName:
+                            description: |-
+                              ServiceName defines the service name to use in tracing configuration.
+                              If not set, Envoy Gateway will use a default service name set as
+                              "name.namespace" (e.g., "my-gateway.default").
+                              Note: This field is only supported for OpenTelemetry and Datadog tracing providers.
+                              For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag
+                              (typically "namespace/name" format). Setting this field has no effect for Zipkin.
+                            type: string
+                            x-kubernetes-validations:
+                            - message: serviceName cannot be empty if provided
+                              rule: self != ""
                           type:
                             default: OpenTelemetry
                             description: Type defines the tracing provider type.
diff --git a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
index f1a4bf57a..04f43549c 100644
--- a/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
+++ b/charts/gateway-helm/crds/generated/gateway.envoyproxy.io_securitypolicies.yaml
@@ -252,7 +252,7 @@ spec:
 
                                 The client IP is inferred from the X-Forwarded-For header, a custom header,
                                 or the proxy protocol.
-                                You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
+                                You can use the `ClientIPDetection` or the `ProxyProtocol` field in
                                 the `ClientTrafficPolicy` to configure how the client IP is detected.
                               items:
                                 description: |-
diff --git a/charts/gateway-helm/templates/certgen.yaml b/charts/gateway-helm/templates/certgen.yaml
index e0d0c3fc5..7f5f7dc72 100644
--- a/charts/gateway-helm/templates/certgen.yaml
+++ b/charts/gateway-helm/templates/certgen.yaml
@@ -18,6 +18,13 @@ spec:
     metadata:
       labels:
         app: certgen
+        {{- if .Values.certgen.job.pod.labels }}
+          {{- toYaml .Values.certgen.job.pod.labels | nindent 8 -}}
+        {{- end }}
+      {{- if .Values.certgen.job.pod.annotations }}
+      annotations:
+        {{- toYaml .Values.certgen.job.pod.annotations | nindent 8 -}}
+      {{- end }}
     spec:
       containers:
       {{- $args := .Values.certgen.job.args }}
diff --git a/charts/gateway-helm/values.tmpl.yaml b/charts/gateway-helm/values.tmpl.yaml
index a8517afcb..41ec30edc 100644
--- a/charts/gateway-helm/values.tmpl.yaml
+++ b/charts/gateway-helm/values.tmpl.yaml
@@ -114,6 +114,9 @@ certgen:
   job:
     annotations: {}
     args: []
+    pod:
+      annotations: {}
+      labels: {}
     resources: {}
     affinity: {}
     tolerations: []
diff --git a/internal/gatewayapi/clienttrafficpolicy.go b/internal/gatewayapi/clienttrafficpolicy.go
index e8bfd7dac..408f5366d 100644
--- a/internal/gatewayapi/clienttrafficpolicy.go
+++ b/internal/gatewayapi/clienttrafficpolicy.go
@@ -392,12 +392,12 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
 
 	// HTTP and TCP listeners can both be configured by common fields below.
 	var (
-		keepalive           *ir.TCPKeepalive
-		connection          *ir.ClientConnection
-		tlsConfig           *ir.TLSConfig
-		enableProxyProtocol bool
-		timeout             *ir.ClientTimeout
-		err, errs           error
+		keepalive     *ir.TCPKeepalive
+		connection    *ir.ClientConnection
+		tlsConfig     *ir.TLSConfig
+		proxyProtocol *ir.ProxyProtocolSettings
+		timeout       *ir.ClientTimeout
+		err, errs     error
 	)
 
 	// Build common IR shared by HTTP and TCP listeners, return early if some field is invalid.
@@ -416,7 +416,18 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
 	}
 
 	// Translate Proxy Protocol
-	enableProxyProtocol = ptr.Deref(policy.Spec.EnableProxyProtocol, false)
+	if policy.Spec.ProxyProtocol != nil {
+		// ProxyProtocol field takes precedence when configured
+		// Even if it's an empty object {}, we should enable proxy protocol with default settings
+		proxyProtocol = &ir.ProxyProtocolSettings{
+			Optional: ptr.Deref(policy.Spec.ProxyProtocol.Optional, false),
+		}
+	} else if ptr.Deref(policy.Spec.EnableProxyProtocol, false) {
+		// Fallback to legacy EnableProxyProtocol field
+		proxyProtocol = &ir.ProxyProtocolSettings{
+			Optional: false, // Default behavior for legacy field
+		}
+	}
 
 	// Translate Client Timeout Settings
 	timeout, err = buildClientTimeout(policy.Spec.Timeout)
@@ -492,7 +503,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
 
 		httpIR.TCPKeepalive = keepalive
 		httpIR.Connection = connection
-		httpIR.EnableProxyProtocol = enableProxyProtocol
+		httpIR.ProxyProtocol = proxyProtocol
 		httpIR.Timeout = timeout
 		httpIR.TLS = tlsConfig
 	}
@@ -515,7 +526,7 @@ func (t *Translator) translateClientTrafficPolicyForListener(policy *egv1a1.Clie
 
 		tcpIR.TCPKeepalive = keepalive
 		tcpIR.Connection = connection
-		tcpIR.EnableProxyProtocol = enableProxyProtocol
+		tcpIR.ProxyProtocol = proxyProtocol
 		tcpIR.TLS = tlsConfig
 		tcpIR.Timeout = timeout
 	}
diff --git a/internal/gatewayapi/listener.go b/internal/gatewayapi/listener.go
index 6b087d7e8..3aa0e4bb0 100644
--- a/internal/gatewayapi/listener.go
+++ b/internal/gatewayapi/listener.go
@@ -742,6 +742,11 @@ func (t *Translator) processTracing(gw *gwapiv1.Gateway, envoyproxy *egv1a1.Envo
 		serviceName = string(gw.Spec.GatewayClassName)
 	}
 
+	// Use configured service name if provided
+	if tracing.Provider.ServiceName != nil {
+		serviceName = *tracing.Provider.ServiceName
+	}
+
 	return &ir.Tracing{
 		Authority:    authority,
 		ServiceName:  serviceName,
diff --git a/internal/gatewayapi/route.go b/internal/gatewayapi/route.go
index cfc2272a6..584ff4a00 100644
--- a/internal/gatewayapi/route.go
+++ b/internal/gatewayapi/route.go
@@ -1426,7 +1426,7 @@ func (t *Translator) processDestination(name string, backendRefContext BackendRe
 		ds = t.processServiceDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, resources, envoyProxy)
 		svc := resources.GetService(backendNamespace, string(backendRef.Name))
 		ds.IPFamily = getServiceIPFamily(svc)
-		ds.ZoneAwareRouting = processZoneAwareRouting(svc)
+		ds.PreferLocal = processPreferLocalZone(svc)
 
 	case egv1a1.KindBackend:
 		ds = t.processBackendDestinationSetting(name, backendRef.BackendObjectReference, backendNamespace, protocol, resources)
@@ -1599,12 +1599,12 @@ func (t *Translator) processServiceDestinationSetting(
 	}
 
 	return &ir.DestinationSetting{
-		Name:             name,
-		Protocol:         protocol,
-		Endpoints:        endpoints,
-		AddressType:      addrType,
-		ZoneAwareRouting: processZoneAwareRouting(service),
-		Metadata:         buildResourceMetadata(service, ptr.To(gwapiv1.SectionName(strconv.Itoa(int(*backendRef.Port))))),
+		Name:        name,
+		Protocol:    protocol,
+		Endpoints:   endpoints,
+		AddressType: addrType,
+		PreferLocal: processPreferLocalZone(service),
+		Metadata:    buildResourceMetadata(service, ptr.To(gwapiv1.SectionName(strconv.Itoa(int(*backendRef.Port))))),
 	}
 }
 
@@ -1624,14 +1624,17 @@ func getBackendFilters(routeType gwapiv1.Kind, backendRefContext BackendRefConte
 	return nil
 }
 
-func processZoneAwareRouting(svc *corev1.Service) *ir.ZoneAwareRouting {
+func processPreferLocalZone(svc *corev1.Service) *ir.PreferLocalZone {
 	if svc == nil {
 		return nil
 	}
 
 	if trafficDist := svc.Spec.TrafficDistribution; trafficDist != nil {
-		return &ir.ZoneAwareRouting{
-			MinSize: 1,
+		return &ir.PreferLocalZone{
+			MinEndpointsThreshold: ptr.To[uint64](1),
+			Force: &ir.ForceLocalZone{
+				MinEndpointsInZoneThreshold: ptr.To[uint32](1),
+			},
 		}
 	}
 
@@ -1640,8 +1643,11 @@ func processZoneAwareRouting(svc *corev1.Service) *ir.ZoneAwareRouting {
 	// https://kubernetes.io/docs/concepts/services-networking/topology-aware-routing/#enabling-topology-aware-routing
 	// https://github.com/kubernetes/kubernetes/blob/9d9e1afdf78bce0a517cc22557457f942040ca19/staging/src/k8s.io/endpointslice/utils.go#L355-L368
 	if val, ok := svc.Annotations[corev1.AnnotationTopologyMode]; ok && val == "Auto" || val == "auto" {
-		return &ir.ZoneAwareRouting{
-			MinSize: 3,
+		return &ir.PreferLocalZone{
+			MinEndpointsThreshold: ptr.To[uint64](3),
+			Force: &ir.ForceLocalZone{
+				MinEndpointsInZoneThreshold: ptr.To[uint32](3),
+			},
 		}
 	}
 
diff --git a/internal/infrastructure/common/proxy_args.go b/internal/infrastructure/common/proxy_args.go
index 98a7e22cd..4d6a67892 100644
--- a/internal/infrastructure/common/proxy_args.go
+++ b/internal/infrastructure/common/proxy_args.go
@@ -8,6 +8,8 @@ package common
 import (
 	"fmt"
 
+	"k8s.io/utils/ptr"
+
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/ir"
 	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
@@ -29,9 +31,19 @@ func BuildProxyArgs(
 	serviceNode string,
 	gatewayNamespaceMode bool,
 ) ([]string, error) {
-	// If IPFamily is not set, try to determine it from the infrastructure.
-	if bootstrapConfigOptions != nil && bootstrapConfigOptions.IPFamily == nil {
-		bootstrapConfigOptions.IPFamily = getIPFamily(infra)
+	serviceCluster := infra.Name
+	if gatewayNamespaceMode {
+		serviceCluster = fmt.Sprintf("%s/%s", infra.Namespace, infra.Name)
+	}
+
+	if bootstrapConfigOptions != nil {
+		// Configure local Envoy ServiceCluster
+		bootstrapConfigOptions.ServiceClusterName = ptr.To(serviceCluster)
+
+		// If IPFamily is not set, try to determine it from the infrastructure.
+		if bootstrapConfigOptions.IPFamily == nil {
+			bootstrapConfigOptions.IPFamily = getIPFamily(infra)
+		}
 	}
 
 	bootstrapConfigOptions.GatewayNamespaceMode = gatewayNamespaceMode
@@ -51,11 +63,6 @@ func BuildProxyArgs(
 
 	logging := infra.Config.Spec.Logging
 
-	serviceCluster := infra.Name
-	if gatewayNamespaceMode {
-		serviceCluster = fmt.Sprintf("%s/%s", infra.Namespace, infra.Name)
-	}
-
 	args := []string{
 		fmt.Sprintf("--service-cluster %s", serviceCluster),
 		fmt.Sprintf("--service-node %s", serviceNode),
diff --git a/internal/infrastructure/kubernetes/proxy/resource.go b/internal/infrastructure/kubernetes/proxy/resource.go
index 19e906404..a33238774 100644
--- a/internal/infrastructure/kubernetes/proxy/resource.go
+++ b/internal/infrastructure/kubernetes/proxy/resource.go
@@ -108,7 +108,7 @@ func expectedProxyContainers(infra *ir.ProxyInfra,
 			TrustedCA:   filepath.Join("/sds", common.SdsCAFilename),
 		},
 		MaxHeapSizeBytes: maxHeapSizeBytes,
-		XdsServerHost:    ptr.To(fmt.Sprintf("%s.%s.svc.%s", config.EnvoyGatewayServiceName, controllerNamespace, dnsDomain)),
+		XdsServerHost:    ptr.To(fmt.Sprintf("%s.%s.svc.%s.", config.EnvoyGatewayServiceName, controllerNamespace, dnsDomain)),
 	}
 
 	args, err := common.BuildProxyArgs(infra, shutdownConfig, bootstrapConfigOptions, fmt.Sprintf("$(%s)", envoyPodEnvVar), gatewayNamespaceMode)
diff --git a/internal/ir/xds.go b/internal/ir/xds.go
index 695fa6a9d..23b88b2ea 100644
--- a/internal/ir/xds.go
+++ b/internal/ir/xds.go
@@ -309,8 +309,8 @@ type HTTPListener struct {
 	TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"`
 	// Headers configures special header management for the listener
 	Headers *HeaderSettings `json:"headers,omitempty" yaml:"headers,omitempty"`
-	// EnableProxyProtocol enables the listener to interpret proxy protocol header
-	EnableProxyProtocol bool `json:"enableProxyProtocol,omitempty" yaml:"enableProxyProtocol,omitempty"`
+	// ProxyProtocol provides proxy protocol configuration.
+	ProxyProtocol *ProxyProtocolSettings `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"`
 	// ClientIPDetection controls how the original client IP address is determined for requests.
 	ClientIPDetection *ClientIPDetectionSettings `json:"clientIPDetection,omitempty" yaml:"clientIPDetection,omitempty"`
 	// Path contains settings for path URI manipulations
@@ -515,6 +515,16 @@ type PathSettings struct {
 	EscapedSlashesAction PathEscapedSlashAction `json:"escapedSlashesAction" yaml:"escapedSlashesAction"`
 }
 
+// ProxyProtocolSettings holds configuration for proxy protocol
+// +k8s:deepcopy-gen=true
+type ProxyProtocolSettings struct {
+	// Optional allows requests without a Proxy Protocol header to be proxied.
+	// If set to true, the listener will accept requests without a Proxy Protocol header.
+	// If set to false, the listener will reject requests without a Proxy Protocol header.
+	// If not set, the default behavior is to reject requests without a Proxy Protocol header.
+	Optional bool `json:"optional,omitempty" yaml:"optional,omitempty"`
+}
+
 type WithUnderscoresAction egv1a1.WithUnderscoresAction
 
 const (
@@ -822,6 +832,15 @@ func (h *HTTPRoute) GetRetry() *Retry {
 	return nil
 }
 
+func (h *HTTPRoute) NeedsClusterPerSetting() bool {
+	if h.Traffic != nil &&
+		h.Traffic.LoadBalancer != nil &&
+		h.Traffic.LoadBalancer.PreferLocal != nil {
+		return true
+	}
+	return h.Destination.NeedsClusterPerSetting()
+}
+
 // DNS contains configuration options for DNS resolution.
 // +k8s:deepcopy-gen=true
 type DNS struct {
@@ -1153,7 +1172,7 @@ type OIDC struct {
 	// may not be able to handle OIDC redirects and wish to directly supply a token instead.
 	PassThroughAuthHeader bool `json:"passThroughAuthHeader,omitempty"`
 
-	// Any request that matches any of the provided matchers won’t be redirected to OAuth server when tokens are not valid.
+	// Any request that matches any of the provided matchers won't be redirected to OAuth server when tokens are not valid.
 	// Automatic access token refresh will be performed for these requests, if enabled.
 	// This behavior can be useful for AJAX requests.
 	DenyRedirect *egv1a1.OIDCDenyRedirect `json:"denyRedirect,omitempty"`
@@ -1572,7 +1591,7 @@ func (r *RouteDestination) Validate() error {
 func (r *RouteDestination) NeedsClusterPerSetting() bool {
 	return r.HasMixedEndpoints() ||
 		r.HasFiltersInSettings() ||
-		(len(r.Settings) > 1 && r.HasZoneAwareRouting())
+		(len(r.Settings) > 1 && r.HasPreferLocalZone())
 }
 
 // HasMixedEndpoints returns true if the RouteDestination has endpoints of multiple types
@@ -1597,10 +1616,10 @@ func (r *RouteDestination) HasFiltersInSettings() bool {
 	return false
 }
 
-// HasZoneAwareRouting returns true if any setting in the destination has ZoneAwareRoutingEnabled set
-func (r *RouteDestination) HasZoneAwareRouting() bool {
+// HasPreferLocalZone returns true if any setting in the destination has PreferLocalZone set
+func (r *RouteDestination) HasPreferLocalZone() bool {
 	for _, setting := range r.Settings {
-		if setting.ZoneAwareRouting != nil {
+		if setting.PreferLocal != nil {
 			return true
 		}
 	}
@@ -1663,11 +1682,9 @@ type DestinationSetting struct {
 	IPFamily *egv1a1.IPFamily    `json:"ipFamily,omitempty" yaml:"ipFamily,omitempty"`
 	TLS      *TLSUpstreamConfig  `json:"tls,omitempty" yaml:"tls,omitempty"`
 	Filters  *DestinationFilters `json:"filters,omitempty" yaml:"filters,omitempty"`
-	// ZoneAwareRouting specifies whether to enable Zone Aware Routing for this destination's endpoints.
+	// PreferLocal specifies whether to enable Zone Aware Routing for this destination's endpoints.
 	// This is derived from the backend service and depends on having Kubernetes Topology Aware Routing or Traffic Distribution enabled.
-	//
-	// +optional
-	ZoneAwareRouting *ZoneAwareRouting `json:"zoneAwareRouting,omitempty" yaml:"zoneAwareRouting,omitempty"`
+	PreferLocal *PreferLocalZone `json:"preferLocal,omitempty" yaml:"preferLocal,omitempty"`
 	// Metadata is used to enrich envoy route metadata with user and provider-specific information
 	// The primary metadata for DestinationSettings comes from the Backend resource reference in BackendRef
 	Metadata *ResourceMetadata `json:"metadata,omitempty" yaml:"metadata,omitempty"`
@@ -1986,8 +2003,8 @@ type TCPListener struct {
 	TLS *TLSConfig `json:"tls,omitempty" yaml:"tls,omitempty"`
 	// TCPKeepalive configuration for the listener
 	TCPKeepalive *TCPKeepalive `json:"tcpKeepalive,omitempty" yaml:"tcpKeepalive,omitempty"`
-	// EnableProxyProtocol enables the listener to interpret proxy protocol header
-	EnableProxyProtocol bool `json:"enableProxyProtocol,omitempty" yaml:"enableProxyProtocol,omitempty"`
+	// ProxyProtocol provides proxy protocol configuration.
+	ProxyProtocol *ProxyProtocolSettings `json:"proxyProtocol,omitempty" yaml:"proxyProtocol,omitempty"`
 	// ClientTimeout sets the timeout configuration for downstream connections.
 	Timeout *ClientTimeout `json:"timeout,omitempty" yaml:"clientTimeout,omitempty"`
 	// Connection settings for clients
@@ -2513,6 +2530,8 @@ type LoadBalancer struct {
 	Random *Random `json:"random,omitempty" yaml:"random,omitempty"`
 	// ConsistentHash load balancer policy
 	ConsistentHash *ConsistentHash `json:"consistentHash,omitempty" yaml:"consistentHash,omitempty"`
+	// PreferLocal defines the configuration related to the distribution of requests between locality zones.
+	PreferLocal *PreferLocalZone `json:"preferLocal,omitempty" yaml:"preferLocal,omitempty"`
 }
 
 // Validate the fields within the LoadBalancer structure
@@ -3193,8 +3212,21 @@ type RequestBuffer struct {
 	Limit resource.Quantity `json:"limit" yaml:"limit"`
 }
 
-// ZoneAwareRouting holds the zone aware routing configuration
+// PreferLocalZone configures zone-aware routing to prefer sending traffic to the local locality zone.
+// +k8s:deepcopy-gen=true
+type PreferLocalZone struct {
+	// ForceLocalZone defines override configuration for forcing all traffic to stay within the local zone instead of the default behavior
+	// which maintains equal distribution among upstream endpoints while sending as much traffic as possible locally.
+	Force *ForceLocalZone `json:"force,omitempty" yaml:"force,omitempty"`
+	// MinEndpointsThreshold is the minimum number of total upstream endpoints across all zones required to enable zone-aware routing.
+	MinEndpointsThreshold *uint64 `json:"minEndpointsThreshold,omitempty" yaml:"minEndpointsThreshold,omitempty"`
+}
+
+// ForceLocalZone defines override configuration for forcing all traffic to stay within the local zone instead of the default behavior
+// which maintains equal distribution among upstream endpoints while sending as much traffic as possible locally.
 // +k8s:deepcopy-gen=true
-type ZoneAwareRouting struct {
-	MinSize int `json:"minSize" yaml:"minSize"`
+type ForceLocalZone struct {
+	// MinEndpointsInZoneThreshold is the minimum number of upstream endpoints in the local zone required to honor the forceLocalZone
+	// override. This is useful for protecting zones with fewer endpoints.
+	MinEndpointsInZoneThreshold *uint32 `json:"minEndpointsInZoneThreshold,omitempty" yaml:"minEndpointsInZoneThreshold,omitempty"`
 }
diff --git a/internal/ir/zz_generated.deepcopy.go b/internal/ir/zz_generated.deepcopy.go
index c45b5b868..9de0acea3 100644
--- a/internal/ir/zz_generated.deepcopy.go
+++ b/internal/ir/zz_generated.deepcopy.go
@@ -960,10 +960,10 @@ func (in *DestinationSetting) DeepCopyInto(out *DestinationSetting) {
 		*out = new(DestinationFilters)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.ZoneAwareRouting != nil {
-		in, out := &in.ZoneAwareRouting, &out.ZoneAwareRouting
-		*out = new(ZoneAwareRouting)
-		**out = **in
+	if in.PreferLocal != nil {
+		in, out := &in.PreferLocal, &out.PreferLocal
+		*out = new(PreferLocalZone)
+		(*in).DeepCopyInto(*out)
 	}
 	if in.Metadata != nil {
 		in, out := &in.Metadata, &out.Metadata
@@ -1307,6 +1307,26 @@ func (in *FaultInjectionDelay) DeepCopy() *FaultInjectionDelay {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ForceLocalZone) DeepCopyInto(out *ForceLocalZone) {
+	*out = *in
+	if in.MinEndpointsInZoneThreshold != nil {
+		in, out := &in.MinEndpointsInZoneThreshold, &out.MinEndpointsInZoneThreshold
+		*out = new(uint32)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ForceLocalZone.
+func (in *ForceLocalZone) DeepCopy() *ForceLocalZone {
+	if in == nil {
+		return nil
+	}
+	out := new(ForceLocalZone)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GRPCExtAuthService) DeepCopyInto(out *GRPCExtAuthService) {
 	*out = *in
@@ -1610,6 +1630,11 @@ func (in *HTTPListener) DeepCopyInto(out *HTTPListener) {
 		*out = new(HeaderSettings)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ProxyProtocol != nil {
+		in, out := &in.ProxyProtocol, &out.ProxyProtocol
+		*out = new(ProxyProtocolSettings)
+		**out = **in
+	}
 	if in.ClientIPDetection != nil {
 		in, out := &in.ClientIPDetection, &out.ClientIPDetection
 		*out = new(ClientIPDetectionSettings)
@@ -2290,6 +2315,11 @@ func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer) {
 		*out = new(ConsistentHash)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.PreferLocal != nil {
+		in, out := &in.PreferLocal, &out.PreferLocal
+		*out = new(PreferLocalZone)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer.
@@ -2645,6 +2675,31 @@ func (in *PerRetryPolicy) DeepCopy() *PerRetryPolicy {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PreferLocalZone) DeepCopyInto(out *PreferLocalZone) {
+	*out = *in
+	if in.Force != nil {
+		in, out := &in.Force, &out.Force
+		*out = new(ForceLocalZone)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.MinEndpointsThreshold != nil {
+		in, out := &in.MinEndpointsThreshold, &out.MinEndpointsThreshold
+		*out = new(uint64)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PreferLocalZone.
+func (in *PreferLocalZone) DeepCopy() *PreferLocalZone {
+	if in == nil {
+		return nil
+	}
+	out := new(PreferLocalZone)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Principal) DeepCopyInto(out *Principal) {
 	*out = *in
@@ -2769,6 +2824,21 @@ func (in *ProxyProtocol) DeepCopy() *ProxyProtocol {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ProxyProtocolSettings) DeepCopyInto(out *ProxyProtocolSettings) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProxyProtocolSettings.
+func (in *ProxyProtocolSettings) DeepCopy() *ProxyProtocolSettings {
+	if in == nil {
+		return nil
+	}
+	out := new(ProxyProtocolSettings)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Random) DeepCopyInto(out *Random) {
 	*out = *in
@@ -3467,6 +3537,11 @@ func (in *TCPListener) DeepCopyInto(out *TCPListener) {
 		*out = new(TCPKeepalive)
 		(*in).DeepCopyInto(*out)
 	}
+	if in.ProxyProtocol != nil {
+		in, out := &in.ProxyProtocol, &out.ProxyProtocol
+		*out = new(ProxyProtocolSettings)
+		**out = **in
+	}
 	if in.Timeout != nil {
 		in, out := &in.Timeout, &out.Timeout
 		*out = new(ClientTimeout)
@@ -4236,18 +4311,3 @@ func (in *Xds) DeepCopy() *Xds {
 	in.DeepCopyInto(out)
 	return out
 }
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *ZoneAwareRouting) DeepCopyInto(out *ZoneAwareRouting) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ZoneAwareRouting.
-func (in *ZoneAwareRouting) DeepCopy() *ZoneAwareRouting {
-	if in == nil {
-		return nil
-	}
-	out := new(ZoneAwareRouting)
-	in.DeepCopyInto(out)
-	return out
-}
diff --git a/internal/xds/bootstrap/bootstrap.go b/internal/xds/bootstrap/bootstrap.go
index 27fc7b4a2..3986dcf34 100644
--- a/internal/xds/bootstrap/bootstrap.go
+++ b/internal/xds/bootstrap/bootstrap.go
@@ -45,6 +45,8 @@ const (
 
 	defaultSdsTrustedCAPath   = "/sds/xds-trusted-ca.json"
 	defaultSdsCertificatePath = "/sds/xds-certificate.json"
+
+	defaultServiceClusterName = "local_cluster"
 )
 
 //go:embed bootstrap.yaml.tpl
@@ -95,6 +97,8 @@ type bootstrapParameters struct {
 	IPFamily string
 	// GatewayNamespaceMode defines whether to use the Envoy Gateway namespace mode.
 	GatewayNamespaceMode bool
+	// ServiceClusterName is the generated name of the Envoy ServiceCluster.
+	ServiceClusterName string
 }
 
 type serverParameters struct {
@@ -135,6 +139,7 @@ type RenderBootstrapConfigOptions struct {
 	IPFamily             *egv1a1.IPFamily
 	ProxyMetrics         *egv1a1.ProxyMetrics
 	SdsConfig            SdsConfigPath
+	ServiceClusterName   *string
 	XdsServerHost        *string
 	XdsServerPort        *int32
 	AdminServerPort      *int32
@@ -254,6 +259,7 @@ func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, err
 			EnablePrometheusCompression:  enablePrometheusCompression,
 			PrometheusCompressionLibrary: prometheusCompressionLibrary,
 			OtelMetricSinks:              metricSinks,
+			ServiceClusterName:           defaultServiceClusterName,
 		},
 	}
 
@@ -298,6 +304,9 @@ func GetRenderedBootstrapConfig(opts *RenderBootstrapConfigOptions) (string, err
 		}
 		cfg.parameters.GatewayNamespaceMode = opts.GatewayNamespaceMode
 		cfg.parameters.OverloadManager.MaxHeapSizeBytes = opts.MaxHeapSizeBytes
+		if opts.ServiceClusterName != nil {
+			cfg.parameters.ServiceClusterName = *opts.ServiceClusterName
+		}
 	}
 
 	if err := cfg.render(); err != nil {
diff --git a/internal/xds/bootstrap/bootstrap.yaml.tpl b/internal/xds/bootstrap/bootstrap.yaml.tpl
index c6956fe86..d8a3794af 100644
--- a/internal/xds/bootstrap/bootstrap.yaml.tpl
+++ b/internal/xds/bootstrap/bootstrap.yaml.tpl
@@ -9,7 +9,7 @@ admin:
       address: {{ .AdminServer.Address }}
       port_value: {{ .AdminServer.Port }}
 cluster_manager:
-  local_cluster_name: local_cluster
+  local_cluster_name: {{ .ServiceClusterName }}
 node:
   locality:
     zone: $(ENVOY_SERVICE_ZONE)
@@ -174,7 +174,7 @@ static_resources:
   - connect_timeout: 10s
     lb_policy: ROUND_ROBIN
     load_assignment:
-      cluster_name: local_cluster
+      cluster_name: {{ .ServiceClusterName }}
       endpoints:
       - lb_endpoints:
         - endpoint:
@@ -187,7 +187,7 @@ static_resources:
         load_balancing_weight: 1
         locality:
           zone: $(ENVOY_SERVICE_ZONE)
-    name: local_cluster
+    name: {{ .ServiceClusterName }}
     type: STATIC
   - connect_timeout: 10s
     load_assignment:
diff --git a/internal/xds/translator/cluster.go b/internal/xds/translator/cluster.go
index 78378ea08..a17a4b771 100644
--- a/internal/xds/translator/cluster.go
+++ b/internal/xds/translator/cluster.go
@@ -228,25 +228,7 @@ func buildXdsCluster(args *xdsClusterArgs) (*buildClusterResult, error) {
 		cluster.TypedExtensionProtocolOptions = epo
 	}
 
-	// Set default localityLbConfig
-	localityLbConfig := &commonv3.LocalityLbConfig{
-		LocalityConfigSpecifier: &commonv3.LocalityLbConfig_LocalityWeightedLbConfig_{
-			LocalityWeightedLbConfig: &commonv3.LocalityLbConfig_LocalityWeightedLbConfig{},
-		},
-	}
-
-	// Override LocalityWeightedLbConfig if zone aware routing is enabled.
-	// Zone aware enabled backendRefs always have a single DestinationSetting per-cluster.
-	if len(args.settings) == 1 && args.settings[0].ZoneAwareRouting != nil {
-		localityLbConfig.LocalityConfigSpecifier = &commonv3.LocalityLbConfig_ZoneAwareLbConfig_{
-			ZoneAwareLbConfig: &commonv3.LocalityLbConfig_ZoneAwareLbConfig{
-				MinClusterSize: wrapperspb.UInt64(1),
-				ForceLocalZone: &commonv3.LocalityLbConfig_ZoneAwareLbConfig_ForceLocalZone{
-					MinSize: wrapperspb.UInt32(uint32(args.settings[0].ZoneAwareRouting.MinSize)),
-				},
-			},
-		}
-	}
+	localityLbConfig := buildLocalityLbConfig(args)
 
 	// Set Load Balancer policy
 	//nolint:gocritic
@@ -439,6 +421,48 @@ func buildXdsCluster(args *xdsClusterArgs) (*buildClusterResult, error) {
 	}, nil
 }
 
+func buildLocalityLbConfig(args *xdsClusterArgs) *commonv3.LocalityLbConfig {
+	// Default to LocalityWeightedLbConfig
+	localityLbConfig := &commonv3.LocalityLbConfig{
+		LocalityConfigSpecifier: &commonv3.LocalityLbConfig_LocalityWeightedLbConfig_{
+			LocalityWeightedLbConfig: &commonv3.LocalityLbConfig_LocalityWeightedLbConfig{},
+		},
+	}
+
+	// Check for LoadBalancer.PreferLocal configuration or if backendRef enables
+	// PreferLocal (such as Topology Aware Routing or Traffic Distribution)
+	if preferLocal := ptr.Deref(args.loadBalancer, ir.LoadBalancer{}).PreferLocal; preferLocal != nil {
+		if cfg := buildZoneAwareLbConfig(preferLocal); cfg != nil {
+			localityLbConfig.LocalityConfigSpecifier = cfg
+		}
+		// Zone aware enabled backendRefs use weighted clusters and
+		// always have a single DestinationSetting per-cluster.
+	} else if len(args.settings) == 1 && args.settings[0].PreferLocal != nil {
+		if cfg := buildZoneAwareLbConfig(args.settings[0].PreferLocal); cfg != nil {
+			localityLbConfig.LocalityConfigSpecifier = cfg
+		}
+	}
+
+	return localityLbConfig
+}
+
+func buildZoneAwareLbConfig(preferLocal *ir.PreferLocalZone) *commonv3.LocalityLbConfig_ZoneAwareLbConfig_ {
+	if preferLocal == nil {
+		return nil
+	}
+	lbConfig := &commonv3.LocalityLbConfig_ZoneAwareLbConfig_{
+		ZoneAwareLbConfig: &commonv3.LocalityLbConfig_ZoneAwareLbConfig{
+			MinClusterSize: wrapperspb.UInt64(ptr.Deref(preferLocal.MinEndpointsThreshold, 6)),
+		},
+	}
+	if preferLocal.Force != nil {
+		lbConfig.ZoneAwareLbConfig.ForceLocalZone = &commonv3.LocalityLbConfig_ZoneAwareLbConfig_ForceLocalZone{
+			MinSize: wrapperspb.UInt32(ptr.Deref(preferLocal.Force.MinEndpointsInZoneThreshold, 1)),
+		}
+	}
+	return lbConfig
+}
+
 func buildXdsHealthCheck(healthcheck *ir.ActiveHealthCheck) []*corev3.HealthCheck {
 	hc := &corev3.HealthCheck{
 		Timeout:  durationpb.New(healthcheck.Timeout.Duration),
@@ -650,7 +674,7 @@ func buildXdsClusterLoadAssignment(clusterName string, destSettings []*ir.Destin
 		// if multiple backendRefs exist. This pushes part of the routing logic higher up the stack which can
 		// limit host selection controls during retries and session affinity.
 		// For more details see https://github.com/envoyproxy/gateway/issues/5307#issuecomment-2688767482
-		if ds.ZoneAwareRouting != nil {
+		if ds.PreferLocal != nil {
 			localities = append(localities, buildZonalLocalities(metadata, ds)...)
 		} else {
 			localities = append(localities, buildWeightedLocalities(metadata, ds))
diff --git a/internal/xds/translator/listener.go b/internal/xds/translator/listener.go
index b896f3199..9963d5cf0 100644
--- a/internal/xds/translator/listener.go
+++ b/internal/xds/translator/listener.go
@@ -389,7 +389,7 @@ func (t *Translator) addHCMToXDSListener(xdsListener *listenerv3.Listener, irLis
 	}
 
 	// Add the proxy protocol filter if needed
-	patchProxyProtocolFilter(xdsListener, irListener.EnableProxyProtocol)
+	patchProxyProtocolFilter(xdsListener, irListener.ProxyProtocol)
 
 	if irListener.IsHTTP2 {
 		mgr.HttpFilters = append(mgr.HttpFilters, xdsfilters.GRPCWeb)
diff --git a/internal/xds/translator/proxy_protocol.go b/internal/xds/translator/proxy_protocol.go
index c48fa5e2f..453cb0ed2 100644
--- a/internal/xds/translator/proxy_protocol.go
+++ b/internal/xds/translator/proxy_protocol.go
@@ -10,13 +10,15 @@ import (
 	proxyprotocolv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/listener/proxy_protocol/v3"
 	"github.com/envoyproxy/go-control-plane/pkg/wellknown"
 	"google.golang.org/protobuf/types/known/anypb"
+
+	"github.com/envoyproxy/gateway/internal/ir"
 )
 
 // patchProxyProtocolFilter builds and appends the Proxy Protocol Filter to the
 // HTTP Listener's Listener Filters if applicable.
-func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, enableProxyProtocol bool) {
-	// Return early if unset
-	if xdsListener == nil || !enableProxyProtocol {
+func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, proxyProtocolSettings *ir.ProxyProtocolSettings) {
+	// Early return if listener is nil
+	if xdsListener == nil {
 		return
 	}
 
@@ -27,18 +29,27 @@ func patchProxyProtocolFilter(xdsListener *listenerv3.Listener, enableProxyProto
 		}
 	}
 
-	proxyProtocolFilter := buildProxyProtocolFilter()
+	// Early return if proxy protocol is not enabled
+	if proxyProtocolSettings == nil {
+		return
+	}
 
-	if proxyProtocolFilter != nil {
-		// Add the Proxy Protocol filter as first to listeners.
-		xdsListener.ListenerFilters = append([]*listenerv3.ListenerFilter{proxyProtocolFilter}, xdsListener.ListenerFilters...)
+	// Build and patch the Proxy Protocol Filter.
+	filter := buildProxyProtocolFilter(proxyProtocolSettings)
+	if filter != nil {
+		xdsListener.ListenerFilters = append(xdsListener.ListenerFilters, filter)
 	}
 }
 
-// buildProxypProtocolFilter returns a Proxy Protocol listener filter from the provided IR listener.
-func buildProxyProtocolFilter() *listenerv3.ListenerFilter {
+// buildProxyProtocolFilter returns a Proxy Protocol listener filter from the provided IR listener.
+func buildProxyProtocolFilter(proxyProtocolSettings *ir.ProxyProtocolSettings) *listenerv3.ListenerFilter {
 	pp := &proxyprotocolv3.ProxyProtocol{}
 
+	// Configure allow_requests_without_proxy_protocol if ProxyProtocolSettings are provided
+	if proxyProtocolSettings.Optional {
+		pp.AllowRequestsWithoutProxyProtocol = proxyProtocolSettings.Optional
+	}
+
 	ppAny, err := anypb.New(pp)
 	if err != nil {
 		return nil
diff --git a/internal/xds/translator/route.go b/internal/xds/translator/route.go
index 0a49d4461..f07f80d8e 100644
--- a/internal/xds/translator/route.go
+++ b/internal/xds/translator/route.go
@@ -83,8 +83,7 @@ func buildXdsRoute(httpRoute *ir.HTTPRoute, httpListener *ir.HTTPListener) (*rou
 
 		router.Action = &routev3.Route_Route{Route: routeAction}
 	default:
-		backendWeights := httpRoute.Destination.ToBackendWeights()
-		routeAction := buildXdsRouteAction(backendWeights, httpRoute.Destination)
+		routeAction := buildXdsRouteAction(httpRoute)
 		routeAction.IdleTimeout = idleTimeout(httpRoute)
 
 		if httpRoute.Mirrors != nil {
@@ -285,10 +284,11 @@ func buildXdsStringMatcher(irMatch *ir.StringMatch) *matcherv3.StringMatcher {
 	return stringMatcher
 }
 
-func buildXdsRouteAction(backendWeights *ir.BackendWeights, dest *ir.RouteDestination) *routev3.RouteAction {
+func buildXdsRouteAction(route *ir.HTTPRoute) *routev3.RouteAction {
+	backendWeights := route.Destination.ToBackendWeights()
 	// only use weighted cluster when there are invalid weights
-	if dest.NeedsClusterPerSetting() || backendWeights.Invalid != 0 {
-		return buildXdsWeightedRouteAction(backendWeights, dest.Settings)
+	if route.NeedsClusterPerSetting() || backendWeights.Invalid != 0 {
+		return buildXdsWeightedRouteAction(backendWeights, route.Destination.Settings)
 	}
 
 	return &routev3.RouteAction{
diff --git a/internal/xds/translator/session_persistence.go b/internal/xds/translator/session_persistence.go
index c8e64e4ec..f68a18a80 100644
--- a/internal/xds/translator/session_persistence.go
+++ b/internal/xds/translator/session_persistence.go
@@ -17,12 +17,13 @@ import (
 	cookiev3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/cookie/v3"
 	headerv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/http/stateful_session/header/v3"
 	httpv3 "github.com/envoyproxy/go-control-plane/envoy/type/http/v3"
-	"google.golang.org/protobuf/proto"
+	protobuf "google.golang.org/protobuf/proto"
 	"google.golang.org/protobuf/types/known/anypb"
 	"google.golang.org/protobuf/types/known/durationpb"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/ir"
+	"github.com/envoyproxy/gateway/internal/utils/proto"
 	"github.com/envoyproxy/gateway/internal/xds/types"
 )
 
@@ -46,72 +47,112 @@ func (s *sessionPersistence) patchHCM(mgr *hcmv3.HttpConnectionManager, irListen
 	if mgr == nil {
 		return errors.New("hcm is nil")
 	}
-
 	if irListener == nil {
 		return errors.New("ir listener is nil")
 	}
+	if hcmContainsFilter(mgr, egv1a1.EnvoyFilterSessionPersistence.String()) {
+		return nil
+	}
+
+	var (
+		routeWithSessionPersistence *ir.HTTPRoute
+		filter                      *hcmv3.HttpFilter
+		err                         error
+	)
 
 	for _, route := range irListener.Routes {
-		sp := route.SessionPersistence
-		if sp == nil {
-			continue
+		if route.SessionPersistence != nil {
+			routeWithSessionPersistence = route
+			break
 		}
+	}
 
-		if hcmContainsFilter(mgr, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)) {
-			continue
-		}
+	if routeWithSessionPersistence == nil {
+		return nil
+	}
 
-		var sessionCfg proto.Message
-		var configName string
-		switch {
-		case sp.Cookie != nil:
-			configName = cookieConfigName
-			cookieCfg := &cookiev3.CookieBasedSessionState{
-				Cookie: &httpv3.Cookie{
-					Name: sp.Cookie.Name,
-					Path: routePathToCookiePath(route.PathMatch),
-				},
-			}
-
-			if sp.Cookie.TTL != nil {
-				cookieCfg.Cookie.Ttl = durationpb.New(sp.Cookie.TTL.Duration)
-			}
-
-			sessionCfg = cookieCfg
-		case sp.Header != nil:
-			configName = headerConfigName
-			sessionCfg = &headerv3.HeaderBasedSessionState{
-				Name: sp.Header.Name,
-			}
-		}
+	// We use the first route that contains the session persistence config to build the filter.
+	// The HCM-level filter config doesn't matter since it is overridden at the route level.
+	if filter, err = buildHCMStatefulSessionFilter(routeWithSessionPersistence); err != nil {
+		return err
+	}
+	mgr.HttpFilters = append(mgr.HttpFilters, filter)
+	return nil
+}
 
-		sessionCfgAny, err := anypb.New(sessionCfg)
-		if err != nil {
-			return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
-		}
+// buildHCMStatefulSessionFilter returns a stateful_session HTTP filter from the provided IR SessionPersistence.
+func buildHCMStatefulSessionFilter(route *ir.HTTPRoute) (*hcmv3.HttpFilter, error) {
+	statefulSessionProto, err := buildStatefulSessionFilterConfig(route)
+	if err != nil {
+		return nil, fmt.Errorf("failed to build stateful session filter config: %w",
+			err)
+	}
+	statefulSessionAny, err := proto.ToAnyWithValidation(statefulSessionProto)
+	if err != nil {
+		return nil, err
+	}
 
-		cfg := &statefulsessionv3.StatefulSession{
-			SessionState: &corev3.TypedExtensionConfig{
-				Name:        configName,
-				TypedConfig: sessionCfgAny,
+	return &hcmv3.HttpFilter{
+		Name: egv1a1.EnvoyFilterSessionPersistence.String(),
+		ConfigType: &hcmv3.HttpFilter_TypedConfig{
+			TypedConfig: statefulSessionAny,
+		},
+		Disabled: true,
+	}, nil
+}
+
+func buildStatefulSessionFilterConfig(route *ir.HTTPRoute) (*statefulsessionv3.StatefulSession, error) {
+	var (
+		sessionCfg protobuf.Message
+		configName string
+		sp         = route.SessionPersistence
+	)
+
+	switch {
+	case sp.Cookie != nil:
+		configName = cookieConfigName
+		cookieCfg := &cookiev3.CookieBasedSessionState{
+			Cookie: &httpv3.Cookie{
+				Name: sp.Cookie.Name,
+				Path: routePathToCookiePath(route.PathMatch),
 			},
 		}
 
-		cfgAny, err := anypb.New(cfg)
-		if err != nil {
-			return fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+		if sp.Cookie.TTL != nil {
+			cookieCfg.Cookie.Ttl = durationpb.New(sp.Cookie.TTL.Duration)
 		}
 
-		mgr.HttpFilters = append(mgr.HttpFilters, &hcmv3.HttpFilter{
-			Name:     perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name),
-			Disabled: true,
-			ConfigType: &hcmv3.HttpFilter_TypedConfig{
-				TypedConfig: cfgAny,
-			},
-		})
+		sessionCfg = cookieCfg
+	case sp.Header != nil:
+		configName = headerConfigName
+		sessionCfg = &headerv3.HeaderBasedSessionState{
+			Name: sp.Header.Name,
+		}
 	}
 
-	return nil
+	sessionCfgAny, err := anypb.New(sessionCfg)
+	if err != nil {
+		return nil, fmt.Errorf("failed to marshal %s config: %w", egv1a1.EnvoyFilterSessionPersistence.String(), err)
+	}
+
+	return &statefulsessionv3.StatefulSession{
+		SessionState: &corev3.TypedExtensionConfig{
+			Name:        configName,
+			TypedConfig: sessionCfgAny,
+		},
+	}, nil
+}
+
+func buildStatefulSessionFilterPerRouteConfig(route *ir.HTTPRoute) (*statefulsessionv3.StatefulSessionPerRoute, error) {
+	statefulSession, err := buildStatefulSessionFilterConfig(route)
+	if err != nil {
+		return nil, err
+	}
+	return &statefulsessionv3.StatefulSessionPerRoute{
+		Override: &statefulsessionv3.StatefulSessionPerRoute_StatefulSession{
+			StatefulSession: statefulSession,
+		},
+	}, nil
 }
 
 func routePathToCookiePath(path *ir.StringMatch) string {
@@ -160,10 +201,29 @@ func (s *sessionPersistence) patchRoute(route *routev3.Route, irRoute *ir.HTTPRo
 		return nil
 	}
 
-	if err := enableFilterOnRoute(route, perRouteFilterName(egv1a1.EnvoyFilterSessionPersistence, route.Name)); err != nil {
+	perFilterCfg := route.GetTypedPerFilterConfig()
+	if _, ok := perFilterCfg[egv1a1.EnvoyFilterSessionPersistence.String()]; ok {
+		// This should not happen since this is the only place where the filter
+		// config is added in a route.
+		return fmt.Errorf("route already contains filter config: %s, %+v",
+			egv1a1.EnvoyFilterSessionPersistence.String(), route)
+	}
+
+	// Overwrite the HCM level filter config with the per route filter config.
+	statefulSessionProto, err := buildStatefulSessionFilterPerRouteConfig(irRoute)
+	if err != nil {
+		return fmt.Errorf("failed to build stateful session filter config: %w", err)
+	}
+	statefulSessionAny, err := proto.ToAnyWithValidation(statefulSessionProto)
+	if err != nil {
 		return err
 	}
 
+	if perFilterCfg == nil {
+		route.TypedPerFilterConfig = make(map[string]*anypb.Any)
+	}
+	route.TypedPerFilterConfig[egv1a1.EnvoyFilterSessionPersistence.String()] = statefulSessionAny
+
 	return nil
 }
 
diff --git a/internal/xds/translator/translator.go b/internal/xds/translator/translator.go
index 0b3dbe724..acecd45e5 100644
--- a/internal/xds/translator/translator.go
+++ b/internal/xds/translator/translator.go
@@ -245,6 +245,11 @@ func (t *Translator) processHTTPReadyListenerXdsTranslation(tCtx *types.Resource
 	return nil
 }
 
+type listenerKey struct {
+	Address string
+	Port    uint32
+}
+
 func (t *Translator) processHTTPListenerXdsTranslation(
 	tCtx *types.ResourceVersionTable,
 	httpListeners []*ir.HTTPListener,
@@ -254,10 +259,23 @@ func (t *Translator) processHTTPListenerXdsTranslation(
 ) error {
 	// The XDS translation is done in a best-effort manner, so we collect all
 	// errors and return them at the end.
-	var errs error
+	var (
+		http3EnabledListeners = make(map[listenerKey]*ir.HTTP3Settings) // Map to track HTTP3 settings for listeners by address and port
+		errs                  error
+	)
+
+	// HTTP3 is enabled for a xDS listener if one of the HTTPListeners on the same address + port combination has HTTP3 enabled.
+	for _, httpListener := range httpListeners {
+		// If HTTP3 is enabled, we need to track it for the listener
+		if httpListener.HTTP3 != nil {
+			http3EnabledListeners[listenerKey{Address: httpListener.Address, Port: httpListener.Port}] = httpListener.HTTP3
+		}
+	}
+
 	for _, httpListener := range httpListeners {
 		var (
-			http3Enabled                       = httpListener.HTTP3 != nil // Whether HTTP3 is enabled
+			http3Settings                      *ir.HTTP3Settings // HTTP3 settings for the listener, if any
+			http3Enabled                       bool
 			tcpXDSListener                     *listenerv3.Listener        // TCP Listener for HTTP1/HTTP2 traffic
 			quicXDSListener                    *listenerv3.Listener        // UDP(QUIC) Listener for HTTP3 traffic
 			xdsListenerOnSameAddressPortExists bool                        // Whether a listener already exists on the same address + port combination
@@ -267,8 +285,11 @@ func (t *Translator) processHTTPListenerXdsTranslation(
 			err                                error
 		)
 
+		http3Settings, http3Enabled = http3EnabledListeners[listenerKey{Address: httpListener.Address, Port: httpListener.Port}]
+
 		// Search for an existing TCP listener on the same address + port combination.
 		tcpXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_TCP)
+		quicXDSListener = findXdsListenerByHostPort(tCtx, httpListener.Address, httpListener.Port, corev3.SocketAddress_UDP)
 		xdsListenerOnSameAddressPortExists = tcpXDSListener != nil
 		tlsEnabled = httpListener.TLS != nil
 
@@ -316,19 +337,19 @@ func (t *Translator) processHTTPListenerXdsTranslation(
 			// route HTTP traffic to the correct virtual host for all the domains
 			// specified in the Gateway HTTP Listener's routes.
 			var (
-				routeName                  string
+				routeConfigName            string
 				hasHCMInDefaultFilterChain bool
 			)
 
 			// Find the route config associated with this listener that
 			// maps to the default filter chain for http traffic
 			// Routes for this listener will be added to this route config
-			routeName = findXdsHTTPRouteConfigName(tcpXDSListener)
-			hasHCMInDefaultFilterChain = routeName != ""
+			routeConfigName = findXdsHTTPRouteConfigName(tcpXDSListener)
+			hasHCMInDefaultFilterChain = routeConfigName != ""
 			addHCM = !hasHCMInDefaultFilterChain
 
-			if routeName != "" {
-				xdsRouteCfg = findXdsRouteConfig(tCtx, routeName)
+			if routeConfigName != "" {
+				xdsRouteCfg = findXdsRouteConfig(tCtx, routeConfigName)
 				if xdsRouteCfg == nil {
 					// skip this listener if failed to find xds route config
 					errs = errors.Join(errs, errors.New("unable to find xds route config"))
@@ -423,7 +444,7 @@ func (t *Translator) processHTTPListenerXdsTranslation(
 
 		// Generate xDS virtual hosts and routes for the given HTTPListener,
 		// and add them to the xDS route config.
-		if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Enabled); err != nil {
+		if err = t.addRouteToRouteConfig(tCtx, xdsRouteCfg, httpListener, metrics, http3Settings); err != nil {
 			errs = errors.Join(errs, err)
 		}
 
@@ -444,7 +465,7 @@ func (t *Translator) addRouteToRouteConfig(
 	xdsRouteCfg *routev3.RouteConfiguration,
 	httpListener *ir.HTTPListener,
 	metrics *ir.Metrics,
-	http3Enabled bool,
+	http3Settings *ir.HTTP3Settings,
 ) error {
 	var (
 		vHosts    = map[string]*routev3.VirtualHost{} // store virtual hosts by domain
@@ -511,8 +532,8 @@ func (t *Translator) addRouteToRouteConfig(
 			}
 		}
 
-		if http3Enabled {
-			http3AltSvcHeader := buildHTTP3AltSvcHeader(int(httpListener.HTTP3.QUICPort))
+		if http3Settings != nil {
+			http3AltSvcHeader := buildHTTP3AltSvcHeader(int(http3Settings.QUICPort))
 			if xdsRoute.ResponseHeadersToAdd == nil {
 				xdsRoute.ResponseHeadersToAdd = make([]*corev3.HeaderValueOption, 0)
 			}
@@ -545,9 +566,10 @@ func (t *Translator) addRouteToRouteConfig(
 			}
 
 			var err error
-			// If there are no filters in the destination settings we create
-			// a regular xds Cluster
-			if !httpRoute.Destination.NeedsClusterPerSetting() {
+			// If there are no filters in the destination
+			// settings and ZoneAware routing isn't
+			// enabled we create a regular xds Cluster
+			if !httpRoute.NeedsClusterPerSetting() {
 				err = processXdsCluster(
 					tCtx,
 					httpRoute.Destination.Name,
@@ -705,10 +727,10 @@ func (t *Translator) processTCPListenerXdsTranslation(
 
 		// Add the proxy protocol filter if needed
 		// TODO: should make sure all listeners that will be translated into same xDS listener have
-		// same EnableProxyProtocol value, otherwise listeners with EnableProxyProtocol=false will
-		// never accept connection, because listeners with EnableProxyProtocol=true has configured
+		// same proxy protocol configuration, otherwise listeners with proxy protocol disabled will
+		// never accept connection, because listeners with proxy protocol enabled have configured
 		// proxy protocol listener filter for xDS listener, all connection must have ProxyProtocol header.
-		patchProxyProtocolFilter(xdsListener, tcpListener.EnableProxyProtocol)
+		patchProxyProtocolFilter(xdsListener, tcpListener.ProxyProtocol)
 
 		for _, route := range tcpListener.Routes {
 			if err := processXdsCluster(tCtx,
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index 2e6dd8d6e..8db8d464e 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -62,6 +62,7 @@ bug fixes: |
   Skipped ExtProc, Wasm, and ExtAuth when they are configured FailOpen and the configuration is invalid, e.g. missing backendRefs or invalid port.
   Fixed issue that failed to update policy status when there are more than 16 ancestors.
   Fixed race condition in watchable.Map Snapshot subscription.
+  Fixed issue where HTTPRoutes with sessionPersistence caused the Envoy listeners to drain.
 
 # Enhancements that improve performance.
 performance improvements: |
diff --git a/site/content/en/v0.6/user/grafana-integration.md b/site/content/en/v0.6/user/grafana-integration.md
index 62ba4ceaf..6941cf1a0 100644
--- a/site/content/en/v0.6/user/grafana-integration.md
+++ b/site/content/en/v0.6/user/grafana-integration.md
@@ -40,7 +40,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana from the command
 from prerequisites sections, the prometheus datasource should be already configured.
 
-You can also add the data source manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the data source manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
diff --git a/site/content/en/v1.0/tasks/observability/grafana-integration.md b/site/content/en/v1.0/tasks/observability/grafana-integration.md
index 3e0ee3345..428978bed 100644
--- a/site/content/en/v1.0/tasks/observability/grafana-integration.md
+++ b/site/content/en/v1.0/tasks/observability/grafana-integration.md
@@ -40,7 +40,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana from the command
 from prerequisites sections, the prometheus datasource should be already configured.
 
-You can also add the data source manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the data source manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
diff --git a/site/content/en/v1.1/tasks/observability/grafana-integration.md b/site/content/en/v1.1/tasks/observability/grafana-integration.md
index 259f6958b..1975ff953 100644
--- a/site/content/en/v1.1/tasks/observability/grafana-integration.md
+++ b/site/content/en/v1.1/tasks/observability/grafana-integration.md
@@ -23,7 +23,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
 from prerequisites sections, the Prometheus datasource should be already configured.
 
-You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
@@ -72,7 +72,7 @@ feel free to make [contributions](../../../contributions/CONTRIBUTING).
 
 ### Grafonnet
 
-Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html). 
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
 This is the preferred method for any new dashboards.
 
 You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.
diff --git a/site/content/en/v1.2/tasks/observability/grafana-integration.md b/site/content/en/v1.2/tasks/observability/grafana-integration.md
index 259f6958b..1975ff953 100644
--- a/site/content/en/v1.2/tasks/observability/grafana-integration.md
+++ b/site/content/en/v1.2/tasks/observability/grafana-integration.md
@@ -23,7 +23,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
 from prerequisites sections, the Prometheus datasource should be already configured.
 
-You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
@@ -72,7 +72,7 @@ feel free to make [contributions](../../../contributions/CONTRIBUTING).
 
 ### Grafonnet
 
-Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html). 
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
 This is the preferred method for any new dashboards.
 
 You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.
diff --git a/site/content/en/v1.3/tasks/observability/grafana-integration.md b/site/content/en/v1.3/tasks/observability/grafana-integration.md
index 259f6958b..1975ff953 100644
--- a/site/content/en/v1.3/tasks/observability/grafana-integration.md
+++ b/site/content/en/v1.3/tasks/observability/grafana-integration.md
@@ -23,7 +23,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
 from prerequisites sections, the Prometheus datasource should be already configured.
 
-You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
@@ -72,7 +72,7 @@ feel free to make [contributions](../../../contributions/CONTRIBUTING).
 
 ### Grafonnet
 
-Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html). 
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
 This is the preferred method for any new dashboards.
 
 You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.
diff --git a/site/content/en/v1.4/concepts/_index.md b/site/content/en/v1.4/concepts/_index.md
index 4d568bd44..d12baa94f 100644
--- a/site/content/en/v1.4/concepts/_index.md
+++ b/site/content/en/v1.4/concepts/_index.md
@@ -3,3 +3,88 @@ title: "Concepts"
 weight: 1
 description: Learn about key concepts when working with Envoy Gateway
 ---
+
+## Overview
+
+**Envoy Gateway** is a Kubernetes-native [API Gateway](api-gateways.md) and reverse proxy control plane. It simplifies deploying and operating [Envoy Proxy](proxy.md) as a data plane by using the standard [Gateway API](gateway-api.md) and its own extensible APIs.
+
+By combining Envoy's performance and flexibility with Kubernetes-native configuration, Envoy Gateway helps platform teams expose and manage secure, observable, and scalable APIs with minimal operational overhead.
+
+## Why Use Envoy Gateway?
+
+Traditionally, configuring Envoy Proxy required deep networking expertise and writing complex configuration files. Envoy Gateway removes that barrier by:
+
+- Integrating tightly with Kubernetes through the Gateway API
+- Providing custom CRDs for advanced traffic policies
+- Automatically translating Kubernetes resources into Envoy config
+- Managing the lifecycle of Envoy Proxy instances
+
+Envoy Gateway is designed to be **simple for app developers**, **powerful for platform engineers**, and **production-ready for large-scale deployments**.
+
+## Structure
+
+The different layers of Envoy Gateway are the following:
+
+| Layer       | Description |
+|----------------|-------------|
+| **User Configuration** | Users define routing, security, and traffic policies using standard Kubernetes Gateway API resources, optionally extended with Envoy Gateway CRDs.|
+| **Envoy Gateway Controller** | A control plane component that watches Gateway API and Envoy Gateway-specific resources, translates them, and produces configuration for Envoy Proxy.|
+| **Envoy Proxy(Data Plane)** | A high-performance proxy that receives and handles live traffic according to the configuration generated by Envoy Gateway.|
+
+Together, these layers create a system that's:
+- Easy to configure
+- Powerful enough for complex needs
+- Standardized and familiar
+- Ready for the future
+
+## Resources
+
+![](/img/envoy-gateway-resources-overview.png)
+
+There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
+
+### Kubernetes Gateway API Resources
+- **GatewayClass:** Defines a class of Gateways with common configuration.
+- **Gateway:** Specifies how traffic can enter the cluster.
+- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
+
+### Envoy Gateway (EG) API Resources
+- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
+- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
+- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
+
+| Resource                                                                | API         | Required | Purpose            | References             | Description                                                                                                                                                                                                 |
+| ----------------------------------------------------------------------- | ----------- | -------- | ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [GatewayClass][1]                                                       | Gateway API | Yes      | Gateway Config     | Core                   | Defines a class of Gateways with common configuration.                                                                                                                                                      |
+| [Gateway][2]                                                            | Gateway API | Yes      | Gateway Config     | GatewayClass           | Specifies how traffic can enter the cluster.                                                                                                                                                                |
+| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes      | Routing            | Gateway                | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_                                                |
+| [Backend][8]                                                            | EG API      | No       | Routing            | N/A                    | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets.                                    |
+| [ClientTrafficPolicy][9]                                                | EG API      | No       | Traffic Handling   | Gateway                | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations.                                                                                 |
+| [BackendTrafficPolicy][10]                                              | EG API      | No       | Traffic Handling   | Gateway, Route         | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_                             |
+| [SecurityPolicy][11]                                                    | EG API      | No       | Security           | Gateway, Route         | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_                          |
+| [BackendTLSPolicy][12]                                                  | Gateway API | No       | Security           | Service                | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services.                     |
+| [EnvoyProxy][13]                                                        | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
+| [EnvoyPatchPolicy][14]                                                  | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_                |
+| [EnvoyExtensionPolicy][15]                                              | EG API      | No       | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_                                                             |
+| [HTTPRouteFilter][16]                                                   | EG API      | No       | Customize & Extend | HTTPRoute              | Allows for the additional request/response processing. |
+
+
+## Next Steps
+For a deeper understanding of Envoy Gateway’s building blocks, you may also wish to explore these conceptual guides:
+
+[1]:	https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
+[2]:	https://gateway-api.sigs.k8s.io/api-types/gateway/
+[3]:	https://gateway-api.sigs.k8s.io/api-types/httproute/
+[4]:	https://gateway-api.sigs.k8s.io/api-types/grpcroute/
+[5]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TLSRoute
+[6]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TCPRoute
+[7]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.UDPRoute
+[8]:	../tasks/traffic/backend
+[9]:	../api/extension_types#clienttrafficpolicy
+[10]:	../api/extension_types#backendtrafficpolicy
+[11]:	../api/extension_types#securitypolicy
+[12]:	https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[13]:	../api/extension_types#envoyproxy
+[14]:	../api/extension_types#envoypatchpolicy
+[15]:	../api/extension_types#envoyextensionpolicy
+[16]:   ../api/extension_types#httproutefilter
diff --git a/site/content/en/v1.4/concepts/api-gateways.md b/site/content/en/v1.4/concepts/api-gateways.md
new file mode 100644
index 000000000..35e240e20
--- /dev/null
+++ b/site/content/en/v1.4/concepts/api-gateways.md
@@ -0,0 +1,27 @@
+---
+title: "API Gateways"
+weight: 3
+---
+
+## Overview
+An API gateway is a centralized entry point for managing, securing, and routing requests to backend services. It handles cross-cutting concerns, like authentication, rate limiting, and protocol translation, so individual services don’t have to. Decoupling clients from internal systems simplifies scaling, enforces consistency, and reduces redundancy.
+
+## Use Cases
+
+Use an API Gateway to:
+- Avoid duplicating logic across microservices.
+- Create a central point of control for access, monitoring, and traffic rules.
+- Expose internal services to the public internet.
+- Provide protocol support for HTTP, gRPC, or TLS.
+- Enforce policies and see traffic metrics at the edge.
+
+## API Gateways in relation to Envoy Gateway
+
+Under the hood, Envoy Proxy is a powerful, production-grade proxy that supports many of the capabilities you'd expect from an API Gateway, like traffic routing, retries, TLS termination, observability, and more. However, configuring Envoy directly can be complex and verbose.
+
+Envoy Gateway makes configuring Envoy Proxy simple by implementing and extending the Kubernetes-native Gateway API. You define high-level traffic rules using resources like Gateway, HTTPRoute, or TLSRoute, and Envoy Gateway automatically translates them into detailed Envoy Proxy configurations.
+
+## Related Resources
+
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
+- [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/)
diff --git a/site/content/en/v1.4/concepts/gateway-api.md b/site/content/en/v1.4/concepts/gateway-api.md
new file mode 100644
index 000000000..1ee514ff5
--- /dev/null
+++ b/site/content/en/v1.4/concepts/gateway-api.md
@@ -0,0 +1,35 @@
+---
+title: "The Gateway API"
+weight: 1
+---
+
+## Before You Begin
+You may want to be familiar with:
+- [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/)
+- [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
+
+## Overview
+The Gateway API is a Kubernetes API designed to provide a consistent, expressive, and extensible method for managing network traffic into and within a Kubernetes cluster, compared to the legacy Ingress API. It introduces core resources such as `GatewayClass` and `Gateway` and various route types like `HTTPRoute` and `TLSRoute`, which allow you to define how traffic is routed, secured, and exposed.
+
+The Gateway API succeeds the Ingress API, which many Kubernetes users may already be familiar with. The Ingress API provided a mechanism for exposing HTTP(S) services to external traffic. The lack of advanced features like regex path matching led to custom annotations to compensate for these deficiencies. This non-standard approach led to fragmentation across Ingress Controllers, challenging portability.
+
+## Use Cases
+Use The Gateway API to:
+- Define how external traffic enters and is routed within your cluster
+- Configure HTTP(S), TLS, and TCP traffic routing in a standardized, Kubernetes-native way
+- Apply host-based, path-based, and header-based routing rules using HTTPRoute
+- Terminate TLS at the edge using Gateway TLS configuration
+- Separate responsibilities between infrastructure and application teams through role-oriented resource design
+- Improve portability and consistency across different gateway implementations
+
+## The Gateway API in Envoy Gateway
+In essence, the Gateway API provides a standard interface. Envoy Gateway adds production-grade capabilities to that interface, bridging the gap between simplicity and power while keeping everything Kubernetes-native.
+
+One of the Gateway API's key strengths is that implementers can extend it. While providing a foundation for standard routing and traffic control needs, it enables implementations to introduce custom resources that address specific use cases.
+
+Envoy Gateway leverages this model by introducing a suite of Gateway API extensions—implemented as Kubernetes Custom Resource Definitions (CRDs)—to expose powerful features from Envoy Proxy. These features include enhanced support for rate limiting, authentication, traffic shaping, and more. By utilizing these extensions, users can access production-grade functionality in a Kubernetes-native and declarative manner, without needing to write a low-level Envoy configuration.
+
+## Related Resources
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
+- [Envoy Gateway API Reference](../api/extension_types)
+- [Extensibility Tasks](../tasks/extensibility/_index.md)
diff --git a/site/content/en/v1.4/concepts/gateway_api_extensions/_index.md b/site/content/en/v1.4/concepts/gateway_api_extensions/_index.md
new file mode 100644
index 000000000..c74bccb95
--- /dev/null
+++ b/site/content/en/v1.4/concepts/gateway_api_extensions/_index.md
@@ -0,0 +1,46 @@
+---
+title: "Gateway API Extensions"
+weight: 2
+---
+## Before You Begin
+- [The Gateway API](https://gateway-api.sigs.k8s.io/)
+
+## Overview
+Gateway API Extensions let you configure extra features that aren’t part of the standard Kubernetes Gateway API. These extensions are built by the teams that create and maintain Gateway API implementations.
+The Gateway API was designed to be extensible safe, and reliable. In the old Ingress API, people had to use custom annotations to add new features, but those weren’t type-safe, making it hard to check if their configuration was correct.
+With Gateway API Extensions, implementers provide type-safe Custom Resource Definitions (CRDs). This means every configuration you write has a clear structure and strict rules, making it easier to catch mistakes early and be confident your setup is valid.
+## Use Cases
+
+Here are some examples of what kind of features extensions include:
+
+1. **Advanced Traffic Management:** 
+    Implementing sophisticated load balancing algorithms, circuit breaking, or retries not defined in the core API
+2. **Enhanced Security Controls:** 
+    Adding implementation-specific TLS configurations, authentication mechanisms, or access control rules
+3. **Observability Integration:** 
+    Connecting Gateway resources to monitoring systems, logging pipelines, or tracing frameworks
+4. **Custom Protocol Support:** 
+    Extending beyond HTTP/TCP/UDP with specialized protocol handling
+5. **Rate Limiting and Compression:** 
+    Implementing traffic policing specific to the implementation's capabilities
+
+## Gateway API Extensions in Envoy Gateway
+
+The Envoy Gateway API introduces a set of Gateway API extensions that enable users to leverage the power of the Envoy proxy. Envoy Gateway uses a policy attachment model, where custom policies are applied to standard Gateway API resources (like HTTPRoute or Gateway) without modifying the core API. This approach provides separation of concerns and makes it easier to manage configurations across teams.
+
+{{% alert title="Current Extensions" color="info" %}}
+Currently supported extensions include
+[`Backend`](../../api/extension_types#backend),
+[`BackendTrafficPolicy`](../../api/extension_types#backendtrafficpolicy),
+[`ClientTrafficPolicy`](../../api/extension_types#clienttrafficpolicy),
+[`EnvoyExtensionPolicy`](../../api/extension_types#envoyextensionpolicy),
+[`EnvoyGateway`](../../api/extension_types#envoygateway),
+[`EnvoyPatchPolicy`](../../api/extension_types#envoypatchpolicy),
+[`EnvoyProxy`](../../api/extension_types#envoyproxy),
+[`HTTPRouteFilter`](../../api/extension_types#httproutefilter), and
+[`SecurityPolicy`](../../api/extension_types#securitypolicy),
+{{% /alert %}}
+
+These extensions are processed through Envoy Gateway's control plane, translating them into xDS configurations applied to Envoy Proxy instances. This layered architecture allows for consistent, scalable, and production-grade traffic control without needing to manage raw Envoy configuration directly.
+
+## Related Resources
diff --git a/site/content/en/v1.4/concepts/gateway_api_extensions/backend-traffic-policy.md b/site/content/en/v1.4/concepts/gateway_api_extensions/backend-traffic-policy.md
new file mode 100644
index 000000000..1cc981a1b
--- /dev/null
+++ b/site/content/en/v1.4/concepts/gateway_api_extensions/backend-traffic-policy.md
@@ -0,0 +1,153 @@
+---
+title: "BackendTrafficPolicy"
+---
+## Before you Begin
+- [Gateway API Extensions](_index.md)
+
+## Overview
+`BackendTrafficPolicy` is an extension to the Kubernetes Gateway API that controls how Envoy Gateway communicates with your backend services. It can configure connection behavior, resilience mechanisms, and performance optimizations without requiring changes to your applications.
+
+Think of it as a traffic controller between your gateway and backend services. It can detect problems, prevent failures from spreading, and optimize request handling to improve system stability.
+
+## Use Cases
+
+`BackendTrafficPolicy` is particularly useful in scenarios where you need to:
+
+1. **Protect your services:**
+   Limit connections and reject excess traffic when necessary
+
+2. **Build resilient systems:**
+   Detect failing services and redirect traffic
+
+3. **Improve performance:**
+   Optimize how requests are distributed and responses are handled
+
+4. **Test system behavior:**
+   Inject faults and validate your recovery mechanisms
+
+## BackendTrafficPolicy in Envoy Gateway
+
+`BackendTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages traffic to your backend services.
+
+You can attach it to Gateway API resources in two ways:
+
+1. Using `targetRefs` to directly reference specific Gateway resources
+2. Using `targetSelectors` to match Gateway resources based on labels
+
+The policy applies to all resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+
+For example, consider these two policies:
+
+```yaml
+# Policy 1: Applies to all routes in the gateway
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: gateway-policy
+spec:
+  targetRefs:
+    - kind: Gateway
+      name: my-gateway
+  circuitBreaker:
+    maxConnections: 100
+
+---
+# Policy 2: Applies to a specific route
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: route-policy
+spec:
+  targetRefs:
+    - kind: HTTPRoute
+      name: my-route
+  circuitBreaker:
+    maxConnections: 50
+```
+
+In this example `my-route` and `my-gateway` would both affect the route. However, since Policy 2 targets the route directly while Policy 1 targets the gateway, Policy 2's configuration (`maxConnections: 50`) will take precedence for that specific route.
+
+Lastly, it's important to note that even when you apply a policy to a Gateway, the policy's effects are tracked separately for each backend service referenced in your routes. For example, if you set up circuit breaking on a Gateway with multiple backend services, each backend service will have its own independent circuit breaker counter. This ensures that issues with one backend service don't affect the others.
+
+## Policy Merging
+
+BackendTrafficPolicy supports merging configurations using the `mergeType` field, which allows route-level policies to combine with gateway-level policies rather than completely overriding them. This enables layered policy strategies where platform teams can set baseline configurations at the Gateway level, while application teams can add specific policies for their routes.
+
+### Merge Types
+
+- **StrategicMerge**: Uses Kubernetes strategic merge patch semantics, providing intelligent merging for complex data structures including arrays
+- **JSONMerge**: Uses RFC 7396 JSON Merge Patch semantics, with simple replacement strategy where arrays are completely replaced
+
+### Example Usage
+
+Here's an example demonstrating policy merging for rate limiting:
+
+```yaml
+# Platform team: Gateway-level policy with global abuse prevention
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: global-backendtrafficpolicy
+spec:
+  rateLimit:
+    type: Global
+    global:
+      rules:
+      - clientSelectors:
+        - sourceCIDR:
+            type: Distinct
+            value: 0.0.0.0/0
+        limit:
+          requests: 100
+          unit: Second
+        shared: true
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: eg
+
+---
+# Application team: Route-level policy with specific limits
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: route-backendtrafficpolicy
+spec:
+  mergeType: StrategicMerge  # Enables merging with gateway policy
+  rateLimit:
+    type: Global
+    global:
+      rules:
+      - clientSelectors:
+        - sourceCIDR:
+            type: Distinct
+            value: 0.0.0.0/0
+        limit:
+          requests: 5
+          unit: Minute
+        shared: false
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: signup-service-httproute
+```
+
+In this example, the route-level policy merges with the gateway-level policy, resulting in both rate limits being enforced: the global 100 requests/second abuse limit and the route-specific 5 requests/minute limit.
+
+### Key Constraints
+
+- The `mergeType` field can only be set on policies targeting child resources (like HTTPRoute), not parent resources (like Gateway)
+- When `mergeType` is unset, no merging occurs - only the most specific policy takes effect
+- The merged configuration combines both policies, enabling layered protection strategies
+
+## Related Resources
+
+- [Circuit Breakers](../../tasks/traffic/circuit-breaker.md)
+- [Failover](../../tasks/traffic/failover)
+- [Fault Injection](../../tasks/traffic/fault-injection)
+- [Global Rate Limit](../../tasks/traffic/global-rate-limit)
+- [Local Rate Limit](../../tasks/traffic/local-rate-limit)
+- [Load Balancing](../../tasks/traffic/load-balancing)
+- [Response Compression](../../tasks/traffic/response-compression)
+- [Response Override](../../tasks/traffic/response-override)
+- [BackendTrafficPolicy API Reference](../../api/extension_types#backendtrafficpolicy)
diff --git a/site/content/en/v1.4/concepts/gateway_api_extensions/client-traffic-policy.md b/site/content/en/v1.4/concepts/gateway_api_extensions/client-traffic-policy.md
new file mode 100644
index 000000000..8dc47a306
--- /dev/null
+++ b/site/content/en/v1.4/concepts/gateway_api_extensions/client-traffic-policy.md
@@ -0,0 +1,88 @@
+---
+title: "ClientTrafficPolicy"
+---
+## Before you Begin
+- [Gateway API Extensions](_index.md)
+
+## Overview
+
+`ClientTrafficPolicy` is an extension to the Kubernetes Gateway API that allows system administrators to configure how the Envoy Proxy server behaves with downstream clients. It is a policy attachment resource that can be applied to Gateway resources and holds settings for configuring the behavior of the connection between the downstream client and Envoy Proxy listener.
+
+Think of `ClientTrafficPolicy` as a set of rules for your Gateway's entry points, it lets you configure specific behaviors for each listener in your Gateway, with more specific rules taking precedence over general ones.
+
+## Use Cases
+
+`ClientTrafficPolicy` is particularly useful in scenarios where you need to:
+
+1. **Enforce TLS Security**
+   Configure TLS termination, mutual TLS (mTLS), and certificate validation at the edge.
+
+2. **Manage Client Connections**
+   Control TCP keepalive behavior and connection timeouts for optimal resource usage.
+
+3. **Handle Client Identity**
+   Configure trusted proxy chains to correctly resolve client IPs for logging and access control.
+
+4. **Normalize Request Paths**
+   Sanitize incoming request paths to ensure compatibility with backend routing rules.
+
+5. **Tune HTTP Protocols**
+   Configure HTTP/1, HTTP/2, and HTTP/3 settings for compatibility and performance.
+
+6. **Monitor Listener Health**
+   Set up health checks for integration with load balancers and failover mechanisms.
+
+## ClientTrafficPolicy in Envoy Gateway
+
+`ClientTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages incoming client traffic.
+
+You can attach it to Gateway API resources in two ways:
+
+1. Using `targetRefs` to directly reference specific Gateway resources
+2. Using `targetSelectors` to match Gateway resources based on labels
+
+The policy applies to all Gateway resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+
+For example, consider these policies targeting the same Gateway Listener:
+
+```yaml
+# Policy A: Targets a specific listener in the gateway
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+  name: listener-specific-policy
+spec:
+  targetRefs:
+    - kind: Gateway
+      name: my-gateway
+      sectionName: https-listener  # Targets specific listener
+  timeout:
+    http:
+      idleTimeout: 30s
+
+---
+# Policy B: Targets the entire gateway
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: ClientTrafficPolicy
+metadata:
+  name: gateway-wide-policy
+spec:
+  targetRefs:
+    - kind: Gateway
+      name: my-gateway  # Targets all listeners
+  timeout:
+    http:
+      idleTimeout: 60s
+```
+
+In this case:
+- Policy A will be applied/attached to the specific Listener defined in the `targetRef.SectionName`
+- Policy B will be applied to the remaining Listeners within the Gateway. Policy B will have an additional status condition Overridden=True.
+
+## Related Resources
+
+- [Connection Limit](../../tasks/traffic/connection-limit.md)
+- [HTTP Request Headers](../../tasks/traffic/http-request-headers)
+- [HTTP/3](../../tasks/traffic/http3)
+- [Mutual TLS: External Clients to the Gateway](../../tasks/security/mutual-tls/)
+- [ClientTrafficPolicy API Reference](../../api/extension_types#clienttrafficpolicy)
diff --git a/site/content/en/v1.4/concepts/gateway_api_extensions/security-policy.md b/site/content/en/v1.4/concepts/gateway_api_extensions/security-policy.md
new file mode 100644
index 000000000..12f0eccfd
--- /dev/null
+++ b/site/content/en/v1.4/concepts/gateway_api_extensions/security-policy.md
@@ -0,0 +1,81 @@
+---
+title: "SecurityPolicy"
+---
+
+## Before you Begin
+- [Gateway API Extensions](_index.md)
+
+## Overview
+
+`SecurityPolicy` is an Envoy Gateway extension to the Kubernetes Gateway API that allows you to define authentication and authorization requirements for traffic entering your gateway. It acts as a security layer that only properly authenticated and authorized requests are allowed through your backend services.
+
+`SecurityPolicy` is designed for you to enforce access controls through configuration at the edge of your infrastructure in a declarative, Kubernetes-native way, without needing to configure complex proxy rules manually.
+
+## Use Cases
+
+1. **Authentication Methods:**
+    - Authenticate client apps using mTLS, JWTs, API keys, or Basic Auth
+    - Authenticate users with OIDC Provider integration
+
+2. **Authorization Controls:**
+    - Define and enforce authorization rules based on user roles and permissions
+    - Integrate with external authorization services for real-time policy decisions
+    - JWT Token Authorization Checks
+
+3. **Cross-Origin Security:**
+    - Configure CORS to allow or restrict cross-origin requests for APIs
+
+## SecurityPolicy in Envoy Gateway
+
+`SecurityPolicy` is implemented as a Kubernetes Custom Resource Definition (CRD) and follows the policy attachment model. You can attach it to Gateway API resources in two ways:
+
+1. Using `targetRefs` to directly reference specific Gateway resources
+2. Using `targetSelectors` to match Gateway resources based on labels
+
+The policy applies to all resources that match either targeting method. When multiple policies target the same resource, the most specific configuration wins.
+
+For example, consider these policies targeting the same Gateway Listener:
+
+```yaml
+# Policy A: Applies to a specific listener
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: listener-policy
+  namespace: default
+spec:
+  targetRefs:
+    - kind: Gateway
+      name: my-gateway
+      sectionName: https  # Applies only to "https" listener
+  cors:
+    allowOrigins:
+      - exact: https://example.com
+---
+# Policy B: Applies to the entire gateway
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: SecurityPolicy
+metadata:
+  name: gateway-policy
+  namespace: default
+spec:
+  targetRefs:
+    - kind: Gateway
+      name: my-gateway  # Applies to all listeners
+  cors:
+    allowOrigins:
+      - exact: https://default.com
+```
+
+In the example, policy A affects only the HTTPS listener, while policy B applies to the rest of the listeners in the gateway. Since Policy A is more specific, the system will show Overridden=True for Policy B on the https listener.
+
+## Related Resources
+- [API Key Authentication](../../tasks/security/apikey-auth.md)
+- [Basic Authentication](../../tasks/security/basic-auth.md)
+- [CORS](../../tasks/security/cors.md)
+- [External Authorization](../../tasks/security/ext-auth.md)
+- [IP Allowlist/Denylist](../../tasks/security/restrict-ip-access.md)
+- [JWT Authentication](../../tasks/security/jwt-authentication.md)
+- [JWT Claim Based Authorization](../../tasks/security/jwt-claim-authorization.md)
+- [OIDC Authorization](../../tasks/security/oidc.md)
+- [SecurityPolicy API Reference](../../api/extension_types#securitypolicy)
diff --git a/site/content/en/v1.4/concepts/load-balancing.md b/site/content/en/v1.4/concepts/load-balancing.md
new file mode 100644
index 000000000..a644ecefd
--- /dev/null
+++ b/site/content/en/v1.4/concepts/load-balancing.md
@@ -0,0 +1,70 @@
+---
+title: "Load Balancing"
+---
+
+## Overview
+
+Load balancing distributes incoming requests across multiple backend services to improve availability, responsiveness, and scalability. Instead of directing all traffic to a single backend, which can cause slowdowns or outages, load balancing spreads the load across multiple instances, helping your applications stay fast and reliable under pressure.
+
+## Use Cases
+
+Use load balancing to:
+
+- Handle high traffic by distributing it across multiple service instances  
+- Keep services available even if one or more backends go down  
+- Improve response time by routing to less busy or closer backends  
+
+## Load Balancing in Envoy Gateway
+
+Envoy Gateway supports several load balancing strategies that determine how traffic is distributed across backend services. These strategies are configured using the `BackendTrafficPolicy` resource and can be applied to `Gateway`, `HTTPRoute`, or `GRPCRoute` resources either by directly referencing them using the targetRefs field or by dynamically selecting them using the targetSelectors field, which matches resources based on Kubernetes labels.
+
+**Supported load balancing types:**
+- **Round Robin** – Sends requests sequentially to all available backends
+- **Random** – Chooses a backend at random to balance load
+- **Least Request** – Sends the request to the backend with the fewest active requests (this is the default)
+- **Consistent Hash** – Routes requests based on a hash (e.g., client IP or header), which helps keep repeat requests going to the same backend (useful for session affinity)
+
+If no load balancing strategy is specified, Envoy Gateway uses **Least Request** by default.
+
+## Example: Round Robin Load Balancing
+
+This example shows how to apply the Round Robin strategy using a `BackendTrafficPolicy` that targets a specific `HTTPRoute`:
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: round-robin-policy
+  namespace: default
+spec:
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: round-robin-route
+  loadBalancer:
+    type: RoundRobin
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: round-robin-route
+  namespace: default
+spec:
+  parentRefs:
+  - name: eg
+  hostnames:
+  - "www.example.com"
+  rules:
+  - matches:
+    - path:
+        type: PathPrefix
+        value: /round
+    backendRefs:
+    - name: backend
+      port: 3000
+```
+In this setup, traffic matching /round is distributed evenly across all available backend service instances. For example, if there are four replicas of the backend service, each one should receive roughly 25% of the requests.
+
+## Related Resources
+- [BackendTrafficPolicy](gateway_api_extensions/backend-traffic-policy.md)
+- [Task: Load Balancing](../tasks/traffic/load-balancing.md)
diff --git a/site/content/en/v1.4/concepts/proxy.md b/site/content/en/v1.4/concepts/proxy.md
new file mode 100644
index 000000000..5e4dcb5b9
--- /dev/null
+++ b/site/content/en/v1.4/concepts/proxy.md
@@ -0,0 +1,33 @@
+---
+title: "Proxy"
+weight: 4
+---
+
+## Overview
+**A proxy server is an intermediary between a client (like a web browser) and another server (like an API server).** When the client makes a request, the proxy forwards it to the destination server, receives the response, and then sends it back to the client.
+
+Proxies are used to enhance security, manage traffic, anonymize user activity, or optimize performance through caching and load balancing features. In cloud environments, they often handle critical tasks such as request routing, TLS termination, authentication, and traffic shaping.
+
+## Use Cases
+
+**Use Envoy Proxy to:**
+- Manage internal or external traffic with a powerful L3/L4/L7 proxy
+- Control HTTP, gRPC, or TLS routing with fine-grained match and rewrite rules
+- Gain full observability via built-in metrics, tracing, and logging
+- Implement intelligent load balancing and resilient failover strategies
+- Integrate seamlessly with service meshes, API gateways, and other control planes
+
+## Proxy in Envoy Gateway
+Envoy Gateway is a system made up of two main parts:
+- A _data plane_, which handles the actual network traffic
+- A _control plane_, which manages and configures the _data plane_
+
+Envoy Gateway uses the Envoy Proxy, which was originally developed at Lyft. This proxy is the foundation of the Envoy project, of which Envoy Gateway is a part, and is now a graduated project within the Cloud Native Computing Foundation (CNCF).
+
+Envoy Proxy is a high-performance, open-source proxy designed for cloud-native applications. Envoy supports use cases for edge and service proxies, routing traffic at the system’s boundary or between internal services.
+
+The control plane uses the Kubernetes Gateway API to understand your settings and then translates them into the format Envoy Proxy needs (called _xDS configuration_). It also runs and updates the Envoy Proxy instances inside your Kubernetes cluster.
+
+## Related Resources
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
+- [Envoy Proxy](https://www.envoyproxy.io/)
diff --git a/site/content/en/v1.4/concepts/rate-limiting.md b/site/content/en/v1.4/concepts/rate-limiting.md
new file mode 100644
index 000000000..6573197b7
--- /dev/null
+++ b/site/content/en/v1.4/concepts/rate-limiting.md
@@ -0,0 +1,107 @@
+---
+title: "Rate Limiting"
+---
+
+## Overview
+
+Rate limiting is a technique for controlling the number of incoming requests over a defined period. It can be used to control usage for business purposes, like agreed usage quotas, or to ensure the stability of a system, preventing overload and protecting the system from, e.g., Denial of Service attacks.
+
+## Use Cases
+
+Rate limiting is commonly used to:
+
+- **Prevent Overload:** Protect internal systems like databases from excessive traffic.
+- **Enhance Security:** Block or limit abusive behavior such as brute-force attempts or DDoS attacks.
+- **Ensure Fair Usage:** Enforce quotas and prevent resource hogging by individual clients.
+- **Implement Entitlements:** Define API usage limits based on user identity or role.
+
+## Rate Limiting in Envoy Gateway
+
+Envoy Gateway supports two types of rate limiting:
+
+- **Global Rate Limiting:** Shared limits across all Envoy instances.
+- **Local Rate Limiting:** Independent limits per Envoy instance.
+
+Envoy Gateway supports rate limiting through the `BackendTrafficPolicy` custom resource. You can define rate-limiting rules and apply them to `HTTPRoute`, `GRPCRoute`, or `Gateway` resources either by directly referencing them with the targetRefs field or by dynamically selecting them using the targetSelectors field, which matches resources based on Kubernetes labels.
+
+{{% alert title="Note" color="primary" %}}
+Rate limits are applied per route, even if the `BackendTrafficPolicy` targets a `Gateway`. For example, if the limit is 100r/s and a Gateway has 3 routes, each route has its own 100r/s bucket.
+{{% /alert %}}
+
+---
+
+## Global Rate Limiting
+
+Global rate limiting ensures a consistent request limit across the entire Envoy fleet. This is ideal for shared resources or distributed environments where coordinated enforcement is critical.
+
+Global limits are enforced via Envoy’s external Rate Limit Service, which is automatically deployed and managed by the Envoy Gateway system. The Rate Limit Service requires a datastore component (commonly Redis). When a request is received, Envoy sends a descriptor to this external service to determine if the request should be allowed.
+
+**Benefits of global limits:**
+
+- Centralized control across instances
+- Fair sharing of backend capacity
+- Burst resistance during autoscaling
+
+### Example
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: global-ratelimit
+spec:
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: my-api
+  rateLimit:
+    type: Global
+    global:
+      rules:
+      - limit:
+          requests: 100
+          unit: Minute
+
+```
+This configuration limits all requests across all Envoy instances for the my-api route to 100 requests per minute total. If there are multiple replicas of Envoy, the limit is shared across all of them.
+
+---
+
+## Local Rate Limiting
+
+
+Local rate limiting applies limits independently within each Envoy Proxy instance. It does not rely on external services, making it lightweight and efficient—especially for blocking abusive traffic early.
+
+**Benefits of local limits:**
+
+- Lightweight and does not require an external rate limit service
+- Fast enforcement with rate limiting at the edge
+- Effective as a first line of defense against traffic bursts
+
+### Example
+
+```yaml
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: BackendTrafficPolicy
+metadata:
+  name: local-ratelimit
+spec:
+  targetRefs:
+  - group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: my-api
+  rateLimit:
+    type: Local
+    local:
+      rules:
+      - limit:
+          requests: 50
+          unit: Minute
+
+```
+This configuration limits traffic to 50 requests per minute per Envoy instance for the my-api route. If there are two Envoy replicas, up to 100 total requests per minute may be allowed (50 per replica).
+
+## Related Resources
+- [BackendTrafficPolicy](gateway_api_extensions/backend-traffic-policy.md)
+- [Task: Global Rate Limit](../tasks/traffic/global-rate-limit.md)
+- [Task: Local Rate Limit](../tasks/traffic/local-rate-limit.md)
diff --git a/site/content/en/v1.4/install/install-helm.md b/site/content/en/v1.4/install/install-helm.md
index 5a18076de..009394e0e 100644
--- a/site/content/en/v1.4/install/install-helm.md
+++ b/site/content/en/v1.4/install/install-helm.md
@@ -58,9 +58,9 @@ consideration when debugging.
 ## Installing CRDs separately
 
 The [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-helm/tags) includes two types of CRDs under its crds/ directory:
-* [Gateway API CRDs](../concepts/introduction/#gateway-api/) (from the *experimental* channel): This channel includes additional `alpha` resources
+* [Gateway API CRDs](../concepts/#gateway-api) (from the *experimental* channel): This channel includes additional `alpha` resources
 such as `TCPRoute` and `BackendTLSPolicy`, which are commonly used by Envoy Gateway users.
-* [Envoy Gateway CRDs](../concepts/introduction/#gateway_api_extensions): These are custom CRDs that extend the Gateway API to support additional
+* [Envoy Gateway CRDs](../concepts/gateway_api_extensions/): These are custom CRDs that extend the Gateway API to support additional
 Envoy Gateway-specific features.
 
 If you prefer to manage CRDs separately, the [Envoy Gateway CRDs Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-crds-helm/tags) allows you
diff --git a/site/content/en/v1.4/tasks/observability/grafana-integration.md b/site/content/en/v1.4/tasks/observability/grafana-integration.md
index 259f6958b..1975ff953 100644
--- a/site/content/en/v1.4/tasks/observability/grafana-integration.md
+++ b/site/content/en/v1.4/tasks/observability/grafana-integration.md
@@ -23,7 +23,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
 from prerequisites sections, the Prometheus datasource should be already configured.
 
-You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
@@ -72,7 +72,7 @@ feel free to make [contributions](../../../contributions/CONTRIBUTING).
 
 ### Grafonnet
 
-Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html). 
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
 This is the preferred method for any new dashboards.
 
 You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.



Test patch:
diff --git a/internal/gatewayapi/listener_test.go b/internal/gatewayapi/listener_test.go
index 293ded7f1..520cb2305 100644
--- a/internal/gatewayapi/listener_test.go
+++ b/internal/gatewayapi/listener_test.go
@@ -9,11 +9,16 @@ import (
 	"strings"
 	"testing"
 
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/util/intstr"
 	"k8s.io/utils/ptr"
 	gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+	"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
 	"github.com/envoyproxy/gateway/internal/gatewayapi/status"
 )
 
@@ -650,3 +655,231 @@ func TestCheckOverlappingCertificates(t *testing.T) {
 		})
 	}
 }
+
+func TestProcessTracingServiceName(t *testing.T) {
+	cases := []struct {
+		name                string
+		gateway             *gwapiv1.Gateway
+		envoyProxy          *egv1a1.EnvoyProxy
+		mergeGateways       bool
+		expectedServiceName string
+		expectError         bool
+	}{
+		{
+			name: "no tracing configuration",
+			gateway: &gwapiv1.Gateway{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-gateway",
+					Namespace: "test-namespace",
+				},
+			},
+			envoyProxy: &egv1a1.EnvoyProxy{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-proxy",
+					Namespace: "test-namespace",
+				},
+			},
+			expectedServiceName: "",
+		},
+		{
+			name: "tracing with default service name",
+			gateway: &gwapiv1.Gateway{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-gateway",
+					Namespace: "test-namespace",
+				},
+			},
+			envoyProxy: &egv1a1.EnvoyProxy{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-proxy",
+					Namespace: "test-namespace",
+				},
+				Spec: egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name:      "otel-collector",
+												Port:      ptr.To(gwapiv1.PortNumber(4317)),
+												Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+											},
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+			expectedServiceName: "test-gateway.test-namespace",
+		},
+		{
+			name: "tracing with custom service name",
+			gateway: &gwapiv1.Gateway{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-gateway",
+					Namespace: "test-namespace",
+				},
+			},
+			envoyProxy: &egv1a1.EnvoyProxy{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-proxy",
+					Namespace: "test-namespace",
+				},
+				Spec: egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name:      "otel-collector",
+												Port:      ptr.To(gwapiv1.PortNumber(4317)),
+												Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+											},
+										},
+									},
+								},
+								ServiceName: ptr.To("my-custom-service"),
+							},
+						},
+					},
+				},
+			},
+			expectedServiceName: "my-custom-service",
+		},
+		{
+			name: "tracing with merge gateways and custom service name",
+			gateway: &gwapiv1.Gateway{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-gateway",
+					Namespace: "test-namespace",
+				},
+				Spec: gwapiv1.GatewaySpec{
+					GatewayClassName: "test-gateway-class",
+				},
+			},
+			envoyProxy: &egv1a1.EnvoyProxy{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-proxy",
+					Namespace: "test-namespace",
+				},
+				Spec: egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name:      "otel-collector",
+												Port:      ptr.To(gwapiv1.PortNumber(4317)),
+												Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+											},
+										},
+									},
+								},
+								ServiceName: ptr.To("custom-service"),
+							},
+						},
+					},
+				},
+			},
+			mergeGateways:       true,
+			expectedServiceName: "custom-service", // Custom service name should override merge logic
+		},
+		{
+			name: "tracing with merge gateways without custom service name",
+			gateway: &gwapiv1.Gateway{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-gateway",
+					Namespace: "test-namespace",
+				},
+				Spec: gwapiv1.GatewaySpec{
+					GatewayClassName: "test-gateway-class",
+				},
+			},
+			envoyProxy: &egv1a1.EnvoyProxy{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-proxy",
+					Namespace: "test-namespace",
+				},
+				Spec: egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name:      "otel-collector",
+												Port:      ptr.To(gwapiv1.PortNumber(4317)),
+												Namespace: ptr.To(gwapiv1.Namespace("monitoring")),
+											},
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+			mergeGateways:       true,
+			expectedServiceName: "test-gateway-class", // Should use gateway class name when merging
+		},
+	}
+
+	for _, tc := range cases {
+		t.Run(tc.name, func(t *testing.T) {
+			translator := &Translator{}
+			resources := &resource.Resources{}
+
+			// Mock service to resolve BackendRefs
+			resources.Services = append(resources.Services,
+				&corev1.Service{
+					ObjectMeta: metav1.ObjectMeta{
+						Namespace: "monitoring",
+						Name:      "otel-collector",
+					},
+					Spec: corev1.ServiceSpec{
+						ClusterIP: "3.3.3.3",
+						Ports: []corev1.ServicePort{
+							{
+								Name:        "grpc",
+								Port:        4317,
+								TargetPort:  intstr.IntOrString{IntVal: 4317},
+								Protocol:    corev1.ProtocolTCP,
+								AppProtocol: ptr.To("grpc"),
+							},
+						},
+					},
+				},
+			)
+
+			result, err := translator.processTracing(tc.gateway, tc.envoyProxy, tc.mergeGateways, resources)
+
+			if tc.expectError {
+				assert.Error(t, err)
+				return
+			}
+
+			require.NoError(t, err)
+
+			if tc.expectedServiceName == "" {
+				assert.Nil(t, result)
+				return
+			}
+
+			assert.NotNil(t, result)
+			assert.Equal(t, tc.expectedServiceName, result.ServiceName)
+		})
+	}
+}
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.in.yaml
index f3ef317db..86a3967de 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.in.yaml
@@ -14,7 +14,6 @@ clientTrafficPolicies:
       connectionLimit:
         value: 3
         closeDelay: 10s
-    enableProxyProtocol: true
     timeout:
       tcp:
         idleTimeout: 1200s
@@ -31,6 +30,8 @@ clientTrafficPolicies:
       signatureAlgorithms:
       - sig1
       - sig2
+    proxyProtocol:
+      optional: false
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
index 4345a3087..61ae1b4c7 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-for-tcp-listeners.out.yaml
@@ -11,7 +11,8 @@ clientTrafficPolicies:
       connectionLimit:
         closeDelay: 10s
         value: 3
-    enableProxyProtocol: true
+    proxyProtocol:
+      optional: false
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
@@ -199,9 +200,9 @@ xdsIR:
         limit:
           closeDelay: 10s
           value: 3
-      enableProxyProtocol: true
       name: envoy-gateway/gateway-1/tls-1
       port: 10443
+      proxyProtocol: {}
       routes:
       - destination:
           metadata:
@@ -270,9 +271,9 @@ xdsIR:
         limit:
           closeDelay: 10s
           value: 3
-      enableProxyProtocol: true
       name: envoy-gateway/gateway-1/tcp-1
       port: 8080
+      proxyProtocol: {}
       routes:
       - destination:
           metadata:
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.in.yaml
new file mode 100644
index 000000000..9e161c0d8
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.in.yaml
@@ -0,0 +1,97 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: target-gateway-precedence-test
+  spec:
+    # Legacy API - should be overridden by new API
+    enableProxyProtocol: false
+    # New API - should take precedence
+    proxyProtocol:
+      optional: true
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-precedence-test
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: target-gateway-legacy-only
+  spec:
+    # Legacy API only - should work as before
+    enableProxyProtocol: true
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-legacy-only
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    namespace: envoy-gateway
+    name: target-gateway-new-api-only
+  spec:
+    # New API only - no legacy field
+    proxyProtocol:
+      optional: false
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-new-api-only
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-precedence-test
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http-1
+      protocol: HTTP
+      port: 80
+      allowedRoutes:
+        namespaces:
+          from: Same
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-legacy-only
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: tcp-1
+      protocol: TCP
+      port: 9090
+      allowedRoutes:
+        namespaces:
+          from: Same
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    namespace: envoy-gateway
+    name: gateway-new-api-only
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - name: http-2
+      protocol: HTTP
+      port: 8080
+      allowedRoutes:
+        namespaces:
+          from: Same
+tcpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: TCPRoute
+  metadata:
+    namespace: envoy-gateway
+    name: tcproute-1
+  spec:
+    parentRefs:
+    - name: gateway-legacy-only
+    rules:
+    - backendRefs:
+      - name: tcp-backend
+        port: 3000
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml
new file mode 100644
index 000000000..71badcafb
--- /dev/null
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol-legacy-mixed.out.yaml
@@ -0,0 +1,363 @@
+clientTrafficPolicies:
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: target-gateway-precedence-test
+    namespace: envoy-gateway
+  spec:
+    enableProxyProtocol: false
+    proxyProtocol:
+      optional: true
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-precedence-test
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-precedence-test
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: target-gateway-legacy-only
+    namespace: envoy-gateway
+  spec:
+    enableProxyProtocol: true
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-legacy-only
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-legacy-only
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+- apiVersion: gateway.envoyproxy.io/v1alpha1
+  kind: ClientTrafficPolicy
+  metadata:
+    creationTimestamp: null
+    name: target-gateway-new-api-only
+    namespace: envoy-gateway
+  spec:
+    proxyProtocol:
+      optional: false
+    targetRef:
+      group: gateway.networking.k8s.io
+      kind: Gateway
+      name: gateway-new-api-only
+  status:
+    ancestors:
+    - ancestorRef:
+        group: gateway.networking.k8s.io
+        kind: Gateway
+        name: gateway-new-api-only
+        namespace: envoy-gateway
+      conditions:
+      - lastTransitionTime: null
+        message: Policy has been accepted.
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+gateways:
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-precedence-test
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: Same
+      name: http-1
+      port: 80
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 0
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http-1
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-legacy-only
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: Same
+      name: tcp-1
+      port: 9090
+      protocol: TCP
+  status:
+    listeners:
+    - attachedRoutes: 1
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: tcp-1
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: TCPRoute
+- apiVersion: gateway.networking.k8s.io/v1
+  kind: Gateway
+  metadata:
+    creationTimestamp: null
+    name: gateway-new-api-only
+    namespace: envoy-gateway
+  spec:
+    gatewayClassName: envoy-gateway-class
+    listeners:
+    - allowedRoutes:
+        namespaces:
+          from: Same
+      name: http-2
+      port: 8080
+      protocol: HTTP
+  status:
+    listeners:
+    - attachedRoutes: 0
+      conditions:
+      - lastTransitionTime: null
+        message: Sending translated listener configuration to the data plane
+        reason: Programmed
+        status: "True"
+        type: Programmed
+      - lastTransitionTime: null
+        message: Listener has been successfully translated
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: Listener references have been resolved
+        reason: ResolvedRefs
+        status: "True"
+        type: ResolvedRefs
+      name: http-2
+      supportedKinds:
+      - group: gateway.networking.k8s.io
+        kind: HTTPRoute
+      - group: gateway.networking.k8s.io
+        kind: GRPCRoute
+infraIR:
+  envoy-gateway/gateway-legacy-only:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-legacy-only/tcp-1
+        ports:
+        - containerPort: 9090
+          name: tcp-9090
+          protocol: TCP
+          servicePort: 9090
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-legacy-only
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+        ownerReference:
+          kind: GatewayClass
+          name: envoy-gateway-class
+      name: envoy-gateway/gateway-legacy-only
+      namespace: envoy-gateway-system
+  envoy-gateway/gateway-new-api-only:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-new-api-only/http-2
+        ports:
+        - containerPort: 8080
+          name: http-8080
+          protocol: HTTP
+          servicePort: 8080
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-new-api-only
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+        ownerReference:
+          kind: GatewayClass
+          name: envoy-gateway-class
+      name: envoy-gateway/gateway-new-api-only
+      namespace: envoy-gateway-system
+  envoy-gateway/gateway-precedence-test:
+    proxy:
+      listeners:
+      - address: null
+        name: envoy-gateway/gateway-precedence-test/http-1
+        ports:
+        - containerPort: 10080
+          name: http-80
+          protocol: HTTP
+          servicePort: 80
+      metadata:
+        labels:
+          gateway.envoyproxy.io/owning-gateway-name: gateway-precedence-test
+          gateway.envoyproxy.io/owning-gateway-namespace: envoy-gateway
+        ownerReference:
+          kind: GatewayClass
+          name: envoy-gateway-class
+      name: envoy-gateway/gateway-precedence-test
+      namespace: envoy-gateway-system
+tcpRoutes:
+- apiVersion: gateway.networking.k8s.io/v1alpha2
+  kind: TCPRoute
+  metadata:
+    creationTimestamp: null
+    name: tcproute-1
+    namespace: envoy-gateway
+  spec:
+    parentRefs:
+    - name: gateway-legacy-only
+    rules:
+    - backendRefs:
+      - name: tcp-backend
+        port: 3000
+  status:
+    parents:
+    - conditions:
+      - lastTransitionTime: null
+        message: Route is accepted
+        reason: Accepted
+        status: "True"
+        type: Accepted
+      - lastTransitionTime: null
+        message: service envoy-gateway/tcp-backend not found
+        reason: BackendNotFound
+        status: "False"
+        type: ResolvedRefs
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+      parentRef:
+        name: gateway-legacy-only
+xdsIR:
+  envoy-gateway/gateway-legacy-only:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
+    tcp:
+    - address: 0.0.0.0
+      name: envoy-gateway/gateway-legacy-only/tcp-1
+      port: 9090
+      proxyProtocol: {}
+      routes:
+      - destination:
+          metadata:
+            kind: TCPRoute
+            name: tcproute-1
+            namespace: envoy-gateway
+          name: tcproute/envoy-gateway/tcproute-1/rule/-1
+        name: tcproute/envoy-gateway/tcproute-1
+  envoy-gateway/gateway-new-api-only:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-new-api-only
+        namespace: envoy-gateway
+        sectionName: http-2
+      name: envoy-gateway/gateway-new-api-only/http-2
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 8080
+      proxyProtocol: {}
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
+  envoy-gateway/gateway-precedence-test:
+    accessLog:
+      json:
+      - path: /dev/stdout
+    http:
+    - address: 0.0.0.0
+      hostnames:
+      - '*'
+      isHTTP2: false
+      metadata:
+        kind: Gateway
+        name: gateway-precedence-test
+        namespace: envoy-gateway
+        sectionName: http-1
+      name: envoy-gateway/gateway-precedence-test/http-1
+      path:
+        escapedSlashesAction: UnescapeAndRedirect
+        mergeSlashes: true
+      port: 10080
+      proxyProtocol:
+        optional: true
+    readyListener:
+      address: 0.0.0.0
+      ipFamily: IPv4
+      path: /ready
+      port: 19003
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml
index 60ac2d95a..e5c9a899b 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.in.yaml
@@ -5,7 +5,8 @@ clientTrafficPolicies:
     namespace: envoy-gateway
     name: target-gateway-1-section-http-1
   spec:
-    enableProxyProtocol: true
+    proxyProtocol:
+      optional: true
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
diff --git a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml
index 5a33f4837..54b6f9f01 100644
--- a/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml
+++ b/internal/gatewayapi/testdata/clienttrafficpolicy-proxyprotocol.out.yaml
@@ -6,7 +6,8 @@ clientTrafficPolicies:
     name: target-gateway-1-section-http-1
     namespace: envoy-gateway
   spec:
-    enableProxyProtocol: true
+    proxyProtocol:
+      optional: true
     targetRef:
       group: gateway.networking.k8s.io
       kind: Gateway
@@ -131,7 +132,6 @@ xdsIR:
       - path: /dev/stdout
     http:
     - address: 0.0.0.0
-      enableProxyProtocol: true
       hostnames:
       - '*'
       isHTTP2: false
@@ -145,6 +145,8 @@ xdsIR:
         escapedSlashesAction: UnescapeAndRedirect
         mergeSlashes: true
       port: 10080
+      proxyProtocol:
+        optional: true
     - address: 0.0.0.0
       hostnames:
       - '*'
diff --git a/internal/gatewayapi/testdata/httproute-with-enable-zone-discovery.out.yaml b/internal/gatewayapi/testdata/httproute-with-enable-zone-discovery.out.yaml
index 726f58635..d3cbb6688 100644
--- a/internal/gatewayapi/testdata/httproute-with-enable-zone-discovery.out.yaml
+++ b/internal/gatewayapi/testdata/httproute-with-enable-zone-discovery.out.yaml
@@ -157,10 +157,12 @@ xdsIR:
               namespace: default
               sectionName: "8080"
             name: httproute/default/httproute-1/rule/1/backend/0
+            preferLocal:
+              force:
+                minEndpointsInZoneThreshold: 1
+              minEndpointsThreshold: 1
             protocol: HTTP
             weight: 1
-            zoneAwareRouting:
-              minSize: 1
         headerMatches:
         - distinct: false
           exact: bar
@@ -195,10 +197,12 @@ xdsIR:
               namespace: default
               sectionName: "8080"
             name: httproute/default/httproute-1/rule/0/backend/0
+            preferLocal:
+              force:
+                minEndpointsInZoneThreshold: 1
+              minEndpointsThreshold: 1
             protocol: HTTP
             weight: 1
-            zoneAwareRouting:
-              minSize: 1
         hostname: '*'
         isHTTP2: false
         metadata:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
index 5a5681090..5032c858a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/custom.yaml
@@ -55,7 +55,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -132,7 +132,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -144,7 +144,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -156,7 +156,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
index eb3cb2d11..42c9abbef 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default-env.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
index 85493cc19..75b37037c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/default.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
index 5798d2886..4c2ae4741 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/disable-prometheus.yaml
@@ -50,7 +50,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -80,7 +80,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -92,7 +92,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -104,7 +104,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
index 8da12ec97..e1448f65f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/extension-env.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
index 188674644..9876d80fd 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/gateway-namespace-mode.yaml
@@ -57,7 +57,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: ns1/gateway-1
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -134,7 +134,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: ns1/gateway-1
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -146,7 +146,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: ns1/gateway-1
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -158,7 +158,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
index 692f9b5b5..d51f06a91 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-labels-and-annotations.yaml
@@ -63,7 +63,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -140,7 +140,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -152,7 +152,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -164,7 +164,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
index 099d5a225..6daf40628 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/override-prometheus-annotations.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
index 405926768..af349ae31 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/patch-daemonset.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
index 78cc0b6b2..93fca25a4 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/shutdown-manager.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
index 78da341b7..0fe48735c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/volumes.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
index f13e24005..e23b7e5f3 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-annotations.yaml
@@ -59,7 +59,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
index 639532931..85551faca 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-extra-args.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
index d3bfde68a..7c702c7e7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-image-pull-secrets.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
index 72939b575..ae57b4f37 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-name.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
index 277bee2f3..1f946a609 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-node-selector.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
index 0a174dcbc..a600458f2 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/daemonsets/with-topology-spread-constraints.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -131,7 +131,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -143,7 +143,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -155,7 +155,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
index ecae105bc..3a9dc52e2 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom-sa.yaml
@@ -61,7 +61,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: ns1/gateway-1
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -138,7 +138,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: ns1/gateway-1
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -150,7 +150,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: ns1/gateway-1
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -162,7 +162,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
index e96b837aa..a166ae60a 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom.yaml
@@ -60,7 +60,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -137,7 +137,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -149,7 +149,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -161,7 +161,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
index 0088db13c..8acc3756e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/custom_with_initcontainers.yaml
@@ -60,7 +60,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -137,7 +137,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -149,7 +149,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -161,7 +161,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
index 251f7fecf..0d349bc17 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default-env.yaml
@@ -59,7 +59,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
index 2d104ca9d..ede9ec8af 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/default.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
index 0d988425b..0f09569fe 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/disable-prometheus.yaml
@@ -54,7 +54,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -84,7 +84,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -96,7 +96,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -108,7 +108,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
index fa3d0304a..9ee4006cd 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/dual-stack.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
index 2ba927e8f..acf680897 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/extension-env.yaml
@@ -59,7 +59,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
index abaa6eaa3..d6597ba7e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/gateway-namespace-mode.yaml
@@ -61,7 +61,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: ns1/gateway-1
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -138,7 +138,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: ns1/gateway-1
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -150,7 +150,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: ns1/gateway-1
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -162,7 +162,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
index 0b5f26b8a..2c7089526 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/ipv6.yaml
@@ -58,7 +58,7 @@ spec:
                 address: ::1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
index fd8320a49..f36c72213 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-labels-and-annotations.yaml
@@ -67,7 +67,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -144,7 +144,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -156,7 +156,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -168,7 +168,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
index 7a7fe26c7..277d3d6b6 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/override-prometheus-annotations.yaml
@@ -60,7 +60,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -137,7 +137,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -149,7 +149,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -161,7 +161,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
index 75b5c0466..c146c0762 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/patch-deployment.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
index 61098fcd5..fbdeedc0f 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/shutdown-manager.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
index 57a77172e..f108892f7 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/volumes.yaml
@@ -59,7 +59,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -136,7 +136,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -148,7 +148,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -160,7 +160,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
index 1e46ab65a..d26f2927b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-annotations.yaml
@@ -63,7 +63,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -140,7 +140,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -152,7 +152,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -164,7 +164,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
index 8fddca291..8b2d1062e 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-empty-memory-limits.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
index b9f6849ae..f33611c8c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-extra-args.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
index d40f50a44..780384082 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-image-pull-secrets.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
index 5dcc3df82..f28e21e5b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-name.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
index ef27a5ff9..391c2789b 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-node-selector.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
index 6d81fc846..fbfa53939 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/deployments/with-topology-spread-constraints.yaml
@@ -58,7 +58,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: default
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -135,7 +135,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: default
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -147,7 +147,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: default
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -159,7 +159,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
index 8d1198c7e..0e3c18c3c 100644
--- a/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
+++ b/internal/infrastructure/kubernetes/proxy/testdata/gateway-namespace-mode/deployment.yaml
@@ -61,7 +61,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: namespace-1/gateway-1
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -138,7 +138,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: namespace-1/gateway-1
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -150,7 +150,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: namespace-1/gateway-1
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -162,7 +162,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
@@ -475,7 +475,7 @@ spec:
                 address: 127.0.0.1
                 port_value: 19000
           cluster_manager:
-            local_cluster_name: local_cluster
+            local_cluster_name: namespace-2/gateway-2
           node:
             locality:
               zone: $(ENVOY_SERVICE_ZONE)
@@ -552,7 +552,7 @@ spec:
             - connect_timeout: 10s
               lb_policy: ROUND_ROBIN
               load_assignment:
-                cluster_name: local_cluster
+                cluster_name: namespace-2/gateway-2
                 endpoints:
                 - lb_endpoints:
                   - endpoint:
@@ -564,7 +564,7 @@ spec:
                   load_balancing_weight: 1
                   locality:
                     zone: $(ENVOY_SERVICE_ZONE)
-              name: local_cluster
+              name: namespace-2/gateway-2
               type: STATIC
             - connect_timeout: 10s
               load_assignment:
@@ -576,7 +576,7 @@ spec:
                     endpoint:
                       address:
                         socket_address:
-                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local
+                          address: envoy-gateway.envoy-gateway-system.svc.cluster.local.
                           port_value: 18000
               typed_extension_protocol_options:
                 envoy.extensions.upstreams.http.v3.HttpProtocolOptions:
diff --git a/internal/ir/xds_test.go b/internal/ir/xds_test.go
index 9ad48cbcf..6cebc99dc 100644
--- a/internal/ir/xds_test.go
+++ b/internal/ir/xds_test.go
@@ -1125,8 +1125,10 @@ func TestRouteDestination_NeedsClusterPerSetting(t *testing.T) {
 								Port: 8080,
 							},
 						},
-						AddressType:      ptr.To(FQDN),
-						ZoneAwareRouting: &ZoneAwareRouting{MinSize: 1},
+						AddressType: ptr.To(FQDN),
+						PreferLocal: &PreferLocalZone{
+							Force: &ForceLocalZone{MinEndpointsInZoneThreshold: ptr.To[uint32](1)},
+						},
 					},
 					{
 						Endpoints: []*DestinationEndpoint{
@@ -1153,8 +1155,10 @@ func TestRouteDestination_NeedsClusterPerSetting(t *testing.T) {
 								Port: 8080,
 							},
 						},
-						AddressType:      ptr.To(FQDN),
-						ZoneAwareRouting: &ZoneAwareRouting{MinSize: 1},
+						AddressType: ptr.To(FQDN),
+						PreferLocal: &PreferLocalZone{
+							Force: &ForceLocalZone{MinEndpointsInZoneThreshold: ptr.To[uint32](1)},
+						},
 					},
 				},
 			},
diff --git a/internal/xds/translator/proxy_protocol_test.go b/internal/xds/translator/proxy_protocol_test.go
index b86c2d765..d3b6f9bdf 100644
--- a/internal/xds/translator/proxy_protocol_test.go
+++ b/internal/xds/translator/proxy_protocol_test.go
@@ -9,46 +9,57 @@ import (
 	"testing"
 
 	listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
-	"github.com/envoyproxy/go-control-plane/pkg/wellknown"
-	"github.com/stretchr/testify/require"
+	"github.com/stretchr/testify/assert"
+
+	"github.com/envoyproxy/gateway/internal/ir"
 )
 
 func TestPatchProxyProtocolFilter(t *testing.T) {
 	type testCase struct {
-		name     string
-		listener *listenerv3.Listener
+		name                  string
+		listener              *listenerv3.Listener
+		proxyProtocolSettings *ir.ProxyProtocolSettings
+		expectedFilterName    string
+		expectedFilterCount   int
 	}
 
-	enableProxyProtocol := true
-
 	testCases := []testCase{
 		{
-			name: "listener with proxy proto available already",
-			listener: &listenerv3.Listener{
-				ListenerFilters: []*listenerv3.ListenerFilter{
-					{
-						Name: wellknown.ProxyProtocol,
-					},
-				},
+			name:                  "proxyProtocolSettings=nil (disabled)",
+			listener:              &listenerv3.Listener{},
+			proxyProtocolSettings: nil,
+			expectedFilterName:    "",
+			expectedFilterCount:   0,
+		},
+		{
+			name:     "proxyProtocolSettings configured with Optional=false",
+			listener: &listenerv3.Listener{},
+			proxyProtocolSettings: &ir.ProxyProtocolSettings{
+				Optional: false,
 			},
+			expectedFilterName:  "envoy.filters.listener.proxy_protocol",
+			expectedFilterCount: 1,
 		},
 		{
-			name: "listener with tls, append proxy proto",
-			listener: &listenerv3.Listener{
-				ListenerFilters: []*listenerv3.ListenerFilter{
-					{
-						Name: wellknown.TLSInspector,
-					},
-				},
+			name:     "proxyProtocolSettings configured with Optional=true",
+			listener: &listenerv3.Listener{},
+			proxyProtocolSettings: &ir.ProxyProtocolSettings{
+				Optional: true,
 			},
+			expectedFilterName:  "envoy.filters.listener.proxy_protocol",
+			expectedFilterCount: 1,
 		},
 	}
 
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {
-			patchProxyProtocolFilter(tc.listener, enableProxyProtocol)
-			// proxy proto filter should be added always as first
-			require.Equal(t, wellknown.ProxyProtocol, tc.listener.ListenerFilters[0].Name)
+			patchProxyProtocolFilter(tc.listener, tc.proxyProtocolSettings)
+
+			assert.Len(t, tc.listener.ListenerFilters, tc.expectedFilterCount)
+
+			if tc.expectedFilterCount > 0 {
+				assert.Equal(t, tc.expectedFilterName, tc.listener.ListenerFilters[0].Name)
+			}
 		})
 	}
 }
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-lb-routing.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-lb-routing.yaml
new file mode 100644
index 000000000..f26259fc8
--- /dev/null
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-lb-routing.yaml
@@ -0,0 +1,67 @@
+http:
+- name: "first-listener"
+  address: "::"
+  port: 10080
+  hostnames:
+  - "*"
+  routes:
+  - name: "route-with-settings-preferlocal"
+    hostname: "*"
+    destination:
+      name: "route-with-settings-preferlocal-dest"
+      settings:
+      - endpoints:
+        - host: "1.2.3.4"
+          port: 8080
+          zone: us-east-1a
+        - host: "2.3.4.5"
+          port: 8080
+          zone: us-east-1b
+        name: "route-with-settings-preferlocal/backend/0"
+        weight: 30
+        preferLocal:
+          minEndpointsThreshold: 1
+          force:
+            minEndpointsInZoneThreshold: 1
+  - name: "route-with-lb-preferlocal"
+    hostname: "*"
+    destination:
+      name: "route-with-lb-preferlocal-dest"
+      settings:
+      - endpoints:
+        - host: "1.2.3.4"
+          port: 8080
+          zone: us-east-1a
+        - host: "2.3.4.5"
+          port: 8080
+          zone: us-east-1b
+        name: "route-with-lb-preferlocal-dest/backend/0"
+        weight: 30
+    traffic:
+      loadBalancer:
+        leastRequest: {}
+        preferLocal:
+          minEndpointsThreshold: 3
+  - name: "route-with-lb-and-settings-preferlocal"
+    hostname: "*"
+    destination:
+      name: "route-with-lb-and-settings-preferlocal-dest"
+      settings:
+      - endpoints:
+        - host: "1.2.3.4"
+          port: 8080
+          zone: us-east-1a
+        - host: "2.3.4.5"
+          port: 8080
+          zone: us-east-1b
+        name: "route-with-lb-and-settings-preferlocal-dest/backend/0"
+        weight: 30
+        preferLocal:
+          minEndpointsThreshold: 1
+          force:
+            minEndpointsInZoneThreshold: 1
+    traffic:
+      loadBalancer:
+        leastRequest: {}
+        preferLocal:
+          minEndpointsThreshold: 3
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing-weighted-clusters.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing-weighted-clusters.yaml
index fb9c0c6fc..666d55f8f 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing-weighted-clusters.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing-weighted-clusters.yaml
@@ -19,8 +19,10 @@ http:
           zone: us-east-1b
         name: "first-route-dest/backend/0"
         weight: 30
-        zoneAwareRouting:
-          minSize: 1
+        preferLocal:
+          force:
+            minEndpointsInZoneThreshold: 1
+          minEndpointsThreshold: 1
       - endpoints:
         - host: "3.4.5.6"
           port: 9090
diff --git a/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing.yaml b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing.yaml
index 37d103aed..ffd776b06 100644
--- a/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/http-route-zonal-routing.yaml
@@ -19,5 +19,7 @@ http:
           zone: us-east-1b
         name: "first-route-dest/backend/0"
         weight: 30
-        zoneAwareRouting:
-          minSize: 1
+        preferLocal:
+          force:
+            minEndpointsInZoneThreshold: 1
+          minEndpointsThreshold: 1
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
index 41bbd6ead..5818d8499 100644
--- a/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-proxy-protocol.yaml
@@ -20,7 +20,8 @@ http:
     - name: secret-2
       certificate: [99, 101, 114, 116, 45, 100, 97, 116, 97]
       privateKey: [107, 101, 121, 45, 100, 97, 116, 97]
-  enableProxyProtocol: true
+  proxyProtocol:
+    optional: false
   routes:
   - name: "first-route"
     hostname: "*"
@@ -35,7 +36,8 @@ tcp:
 - name: "second-listener"
   address: "::"
   port: 10081
-  enableProxyProtocol: true
+  proxyProtocol:
+    optional: false
   routes:
   - name: "tcp-route-dest"
     destination:
diff --git a/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml
index cc24bfbdf..48b7ae0e8 100644
--- a/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml
+++ b/internal/xds/translator/testdata/in/xds-ir/listener-tcp-without-route.yaml
@@ -5,7 +5,8 @@ tcp:
     limit:
       closeDelay: 10s
       value: 3
-  enableProxyProtocol: true
+  proxyProtocol:
+    optional: false
   name: envoy-gateway/gateway-1/tls-1
   port: 10443
   tcpKeepalive:
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
index 26dedfa4e..2b97daa22 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.listeners.yaml
@@ -15,7 +15,7 @@
           maxConcurrentStreams: 100
         httpFilters:
         - disabled: true
-          name: envoy.filters.http.stateful_session/header-based-session-persistence-route
+          name: envoy.filters.http.stateful_session
           typedConfig:
             '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
             sessionState:
@@ -23,41 +23,6 @@
               typedConfig:
                 '@type': type.googleapis.com/envoy.extensions.http.stateful_session.header.v3.HeaderBasedSessionState
                 name: session-header
-        - disabled: true
-          name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex
-          typedConfig:
-            '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
-            sessionState:
-              name: envoy.http.stateful_session.cookie
-              typedConfig:
-                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
-                cookie:
-                  name: session-header
-                  path: /v1
-                  ttl: 3600s
-        - disabled: true
-          name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix
-          typedConfig:
-            '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
-            sessionState:
-              name: envoy.http.stateful_session.cookie
-              typedConfig:
-                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
-                cookie:
-                  name: session-header
-                  path: /v2/
-        - disabled: true
-          name: envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact
-          typedConfig:
-            '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSession
-            sessionState:
-              name: envoy.http.stateful_session.cookie
-              typedConfig:
-                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
-                cookie:
-                  name: session-cookie
-                  path: /v3/user
-                  ttl: 3600s
         - name: envoy.filters.http.router
           typedConfig:
             '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
index c5450601b..52f05f15b 100644
--- a/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-session-persistence.routes.yaml
@@ -14,9 +14,14 @@
         upgradeConfigs:
         - upgradeType: websocket
       typedPerFilterConfig:
-        envoy.filters.http.stateful_session/header-based-session-persistence-route:
-          '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
-          config: {}
+        envoy.filters.http.stateful_session:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSessionPerRoute
+          statefulSession:
+            sessionState:
+              name: envoy.http.stateful_session.header
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.header.v3.HeaderBasedSessionState
+                name: session-header
     - match:
         safeRegex:
           regex: /v1/.*/hoge
@@ -26,9 +31,17 @@
         upgradeConfigs:
         - upgradeType: websocket
       typedPerFilterConfig:
-        envoy.filters.http.stateful_session/cookie-based-session-persistence-route-regex:
-          '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
-          config: {}
+        envoy.filters.http.stateful_session:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSessionPerRoute
+          statefulSession:
+            sessionState:
+              name: envoy.http.stateful_session.cookie
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+                cookie:
+                  name: session-header
+                  path: /v1
+                  ttl: 3600s
     - match:
         pathSeparatedPrefix: /v2
       name: cookie-based-session-persistence-route-prefix
@@ -37,9 +50,16 @@
         upgradeConfigs:
         - upgradeType: websocket
       typedPerFilterConfig:
-        envoy.filters.http.stateful_session/cookie-based-session-persistence-route-prefix:
-          '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
-          config: {}
+        envoy.filters.http.stateful_session:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSessionPerRoute
+          statefulSession:
+            sessionState:
+              name: envoy.http.stateful_session.cookie
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+                cookie:
+                  name: session-header
+                  path: /v2/
     - match:
         path: /v3/user
       name: cookie-based-session-persistence-route-exact
@@ -48,6 +68,14 @@
         upgradeConfigs:
         - upgradeType: websocket
       typedPerFilterConfig:
-        envoy.filters.http.stateful_session/cookie-based-session-persistence-route-exact:
-          '@type': type.googleapis.com/envoy.config.route.v3.FilterConfig
-          config: {}
+        envoy.filters.http.stateful_session:
+          '@type': type.googleapis.com/envoy.extensions.filters.http.stateful_session.v3.StatefulSessionPerRoute
+          statefulSession:
+            sessionState:
+              name: envoy.http.stateful_session.cookie
+              typedConfig:
+                '@type': type.googleapis.com/envoy.extensions.http.stateful_session.cookie.v3.CookieBasedSessionState
+                cookie:
+                  name: session-cookie
+                  path: /v3/user
+                  ttl: 3600s
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.clusters.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.clusters.yaml
new file mode 100644
index 000000000..50cd448cd
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.clusters.yaml
@@ -0,0 +1,77 @@
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_PREFERRED
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: route-with-settings-preferlocal-dest
+  ignoreHealthOnHostRemoval: true
+  lbPolicy: LEAST_REQUEST
+  loadBalancingPolicy:
+    policies:
+    - typedExtensionConfig:
+        name: envoy.load_balancing_policies.least_request
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+          localityLbConfig:
+            zoneAwareLbConfig:
+              forceLocalZone:
+                minSize: 1
+              minClusterSize: "1"
+  name: route-with-settings-preferlocal-dest
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_PREFERRED
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: route-with-lb-preferlocal-dest/backend/0
+  ignoreHealthOnHostRemoval: true
+  lbPolicy: LEAST_REQUEST
+  loadBalancingPolicy:
+    policies:
+    - typedExtensionConfig:
+        name: envoy.load_balancing_policies.least_request
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+          localityLbConfig:
+            zoneAwareLbConfig:
+              minClusterSize: "3"
+  name: route-with-lb-preferlocal-dest/backend/0
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
+- circuitBreakers:
+    thresholds:
+    - maxRetries: 1024
+  commonLbConfig: {}
+  connectTimeout: 10s
+  dnsLookupFamily: V4_PREFERRED
+  edsClusterConfig:
+    edsConfig:
+      ads: {}
+      resourceApiVersion: V3
+    serviceName: route-with-lb-and-settings-preferlocal-dest/backend/0
+  ignoreHealthOnHostRemoval: true
+  lbPolicy: LEAST_REQUEST
+  loadBalancingPolicy:
+    policies:
+    - typedExtensionConfig:
+        name: envoy.load_balancing_policies.least_request
+        typedConfig:
+          '@type': type.googleapis.com/envoy.extensions.load_balancing_policies.least_request.v3.LeastRequest
+          localityLbConfig:
+            zoneAwareLbConfig:
+              minClusterSize: "3"
+  name: route-with-lb-and-settings-preferlocal-dest/backend/0
+  perConnectionBufferLimitBytes: 32768
+  type: EDS
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.endpoints.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.endpoints.yaml
new file mode 100644
index 000000000..9ad2673fe
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.endpoints.yaml
@@ -0,0 +1,58 @@
+- clusterName: route-with-settings-preferlocal-dest
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 8080
+      loadBalancingWeight: 1
+    locality:
+      zone: us-east-1a
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 2.3.4.5
+            portValue: 8080
+      loadBalancingWeight: 1
+    locality:
+      zone: us-east-1b
+- clusterName: route-with-lb-preferlocal-dest/backend/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 8080
+      loadBalancingWeight: 1
+    - endpoint:
+        address:
+          socketAddress:
+            address: 2.3.4.5
+            portValue: 8080
+      loadBalancingWeight: 1
+    loadBalancingWeight: 30
+    locality:
+      region: route-with-lb-preferlocal-dest/backend/0
+- clusterName: route-with-lb-and-settings-preferlocal-dest/backend/0
+  endpoints:
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 1.2.3.4
+            portValue: 8080
+      loadBalancingWeight: 1
+    locality:
+      zone: us-east-1a
+  - lbEndpoints:
+    - endpoint:
+        address:
+          socketAddress:
+            address: 2.3.4.5
+            portValue: 8080
+      loadBalancingWeight: 1
+    locality:
+      zone: us-east-1b
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.listeners.yaml
new file mode 100644
index 000000000..5c7db4154
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.listeners.yaml
@@ -0,0 +1,33 @@
+- address:
+    socketAddress:
+      address: '::'
+      portValue: 10080
+  defaultFilterChain:
+    filters:
+    - name: envoy.filters.network.http_connection_manager
+      typedConfig:
+        '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+        commonHttpProtocolOptions:
+          headersWithUnderscoresAction: REJECT_REQUEST
+        http2ProtocolOptions:
+          initialConnectionWindowSize: 1048576
+          initialStreamWindowSize: 65536
+          maxConcurrentStreams: 100
+        httpFilters:
+        - name: envoy.filters.http.router
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
+            suppressEnvoyHeaders: true
+        normalizePath: true
+        rds:
+          configSource:
+            ads: {}
+            resourceApiVersion: V3
+          routeConfigName: first-listener
+        serverHeaderTransformation: PASS_THROUGH
+        statPrefix: http-10080
+        useRemoteAddress: true
+    name: first-listener
+  maxConnectionsToAcceptPerSocketEvent: 1
+  name: first-listener
+  perConnectionBufferLimitBytes: 32768
diff --git a/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.routes.yaml
new file mode 100644
index 000000000..c6b19600c
--- /dev/null
+++ b/internal/xds/translator/testdata/out/xds-ir/http-route-zonal-lb-routing.routes.yaml
@@ -0,0 +1,36 @@
+- ignorePortInHostMatching: true
+  name: first-listener
+  virtualHosts:
+  - domains:
+    - '*'
+    name: first-listener/*
+    routes:
+    - match:
+        prefix: /
+      name: route-with-settings-preferlocal
+      route:
+        cluster: route-with-settings-preferlocal-dest
+        upgradeConfigs:
+        - upgradeType: websocket
+    - match:
+        prefix: /
+      name: route-with-lb-preferlocal
+      route:
+        clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
+        upgradeConfigs:
+        - upgradeType: websocket
+        weightedClusters:
+          clusters:
+          - name: route-with-lb-preferlocal-dest/backend/0
+            weight: 30
+    - match:
+        prefix: /
+      name: route-with-lb-and-settings-preferlocal
+      route:
+        clusterNotFoundResponseCode: INTERNAL_SERVER_ERROR
+        upgradeConfigs:
+        - upgradeType: websocket
+        weightedClusters:
+          clusters:
+          - name: route-with-lb-and-settings-preferlocal-dest/backend/0
+            weight: 30
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
index 8b0b416a0..f50d6e0f6 100755
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.listeners.yaml
@@ -42,6 +42,49 @@
             '@type': type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth
             users:
               inlineBytes: dXNlcjE6e1NIQX10RVNzQm1FL3lOWTNsYjZhMEw2dlZRRVpOcXc9CnVzZXIyOntTSEF9RUo5TFBGRFhzTjl5blNtYnh2anA3NUJtbHg4PQo=
+        - disabled: true
+          name: envoy.filters.http.oauth2/securitypolicy/default/policy-for-gateway-2
+          typedConfig:
+            '@type': type.googleapis.com/envoy.extensions.filters.http.oauth2.v3.OAuth2
+            config:
+              authScopes:
+              - openid
+              - email
+              - profile
+              authType: BASIC_AUTH
+              authorizationEndpoint: https://oauth.foo.com/oauth2/v2/auth
+              credentials:
+                clientId: client.oauth.foo.com
+                cookieNames:
+                  bearerToken: AccessToken-5F93C2E4
+                  idToken: IdToken-5F93C2E4
+                  oauthExpires: OauthExpires-5F93C2E4
+                  oauthHmac: OauthHMAC-5F93C2E4
+                  oauthNonce: OauthNonce-5F93C2E4
+                  refreshToken: RefreshToken-5F93C2E4
+                hmacSecret:
+                  name: oauth2/hmac_secret/securitypolicy/default/policy-for-gateway-2
+                  sdsConfig:
+                    ads: {}
+                    resourceApiVersion: V3
+                tokenSecret:
+                  name: oauth2/client_secret/securitypolicy/default/policy-for-gateway-2
+                  sdsConfig:
+                    ads: {}
+                    resourceApiVersion: V3
+              preserveAuthorizationHeader: true
+              redirectPathMatcher:
+                path:
+                  exact: /foo/oauth2/callback
+              redirectUri: https://www.example.com/foo/oauth2/callback
+              signoutPath:
+                path:
+                  exact: /foo/logout
+              tokenEndpoint:
+                cluster: oauth_foo_com_443
+                timeout: 10s
+                uri: https://oauth.foo.com/token
+              useRefreshToken: false
         - name: envoy.filters.http.router
           typedConfig:
             '@type': type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
diff --git a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml
index 5ce26e0d7..445fa0324 100755
--- a/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml
+++ b/internal/xds/translator/testdata/out/xds-ir/multiple-listeners-same-port-with-different-filters.routes.yaml
@@ -45,6 +45,11 @@
     - match:
         pathSeparatedPrefix: /bar
       name: httproute/default/httproute-3/rule/0/match/0/www_bar_com
+      responseHeadersToAdd:
+      - append: true
+        header:
+          key: alt-svc
+          value: h3=":443"; ma=86400
       route:
         cluster: httproute/default/httproute-3/rule/0
         upgradeConfigs:
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index b5ad578b9..fb1150e05 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -769,7 +769,8 @@ _Appears in:_
 | `targetRefs` | _[LocalPolicyTargetReferenceWithSectionName](https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReferenceWithSectionName) array_ |  true  |  | TargetRefs are the names of the Gateway resources this policy<br />is being attached to. |
 | `targetSelectors` | _[TargetSelector](#targetselector) array_ |  true  |  | TargetSelectors allow targeting resources for this policy based on labels |
 | `tcpKeepalive` | _[TCPKeepalive](#tcpkeepalive)_ |  false  |  | TcpKeepalive settings associated with the downstream client connection.<br />If defined, sets SO_KEEPALIVE on the listener socket to enable TCP Keepalives.<br />Disabled by default. |
-| `enableProxyProtocol` | _boolean_ |  false  |  | EnableProxyProtocol interprets the ProxyProtocol header and adds the<br />Client Address into the X-Forwarded-For header.<br />Note Proxy Protocol must be present when this field is set, else the connection<br />is closed. |
+| `enableProxyProtocol` | _boolean_ |  false  |  | EnableProxyProtocol interprets the ProxyProtocol header and adds the<br />Client Address into the X-Forwarded-For header.<br />Note Proxy Protocol must be present when this field is set, else the connection<br />is closed.<br />Deprecated: Use ProxyProtocol instead. |
+| `proxyProtocol` | _[ProxyProtocolSettings](#proxyprotocolsettings)_ |  false  |  | ProxyProtocol configures the Proxy Protocol settings. When configured,<br />the Proxy Protocol header will be interpreted and the Client Address<br />will be added into the X-Forwarded-For header.<br />If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence. |
 | `clientIPDetection` | _[ClientIPDetectionSettings](#clientipdetectionsettings)_ |  false  |  | ClientIPDetectionSettings provides configuration for determining the original client IP address for requests. |
 | `tls` | _[ClientTLSSettings](#clienttlssettings)_ |  false  |  | TLS settings configure TLS termination settings with the downstream client. |
 | `path` | _[PathSettings](#pathsettings)_ |  false  |  | Path enables managing how the incoming path set by clients can be normalized. |
@@ -3562,7 +3563,7 @@ _Appears in:_
 
 | Field | Type | Required | Default | Description |
 | ---   | ---  | ---      | ---     | ---         |
-| `clientCIDRs` | _[CIDR](#cidr) array_ |  false  |  | ClientCIDRs are the IP CIDR ranges of the client.<br />Valid examples are "192.168.1.0/24" or "2001:db8::/64"<br />If multiple CIDR ranges are specified, one of the CIDR ranges must match<br />the client IP for the rule to match.<br />The client IP is inferred from the X-Forwarded-For header, a custom header,<br />or the proxy protocol.<br />You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in<br />the `ClientTrafficPolicy` to configure how the client IP is detected. |
+| `clientCIDRs` | _[CIDR](#cidr) array_ |  false  |  | ClientCIDRs are the IP CIDR ranges of the client.<br />Valid examples are "192.168.1.0/24" or "2001:db8::/64"<br />If multiple CIDR ranges are specified, one of the CIDR ranges must match<br />the client IP for the rule to match.<br />The client IP is inferred from the X-Forwarded-For header, a custom header,<br />or the proxy protocol.<br />You can use the `ClientIPDetection` or the `ProxyProtocol` field in<br />the `ClientTrafficPolicy` to configure how the client IP is detected. |
 | `jwt` | _[JWTPrincipal](#jwtprincipal)_ |  false  |  | JWT authorize the request based on the JWT claims and scopes.<br />Note: in order to use JWT claims for authorization, you must configure the<br />JWT authentication in the same `SecurityPolicy`. |
 | `headers` | _[AuthorizationHeaderMatch](#authorizationheadermatch) array_ |  false  |  | Headers authorize the request based on user identity extracted from custom headers.<br />If multiple headers are specified, all headers must match for the rule to match. |
 
@@ -3864,6 +3865,23 @@ _Appears in:_
 | `version` | _[ProxyProtocolVersion](#proxyprotocolversion)_ |  true  |  | Version of ProxyProtol<br />Valid ProxyProtocolVersion values are<br />"V1"<br />"V2" |
 
 
+#### ProxyProtocolSettings
+
+
+
+ProxyProtocolSettings configures the Proxy Protocol settings. When configured,
+the Proxy Protocol header will be interpreted and the Client Address
+will be added into the X-Forwarded-For header.
+If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+
+_Appears in:_
+- [ClientTrafficPolicySpec](#clienttrafficpolicyspec)
+
+| Field | Type | Required | Default | Description |
+| ---   | ---  | ---      | ---     | ---         |
+| `optional` | _boolean_ |  false  |  | Optional allows requests without a Proxy Protocol header to be proxied.<br />If set to true, the listener will accept requests without a Proxy Protocol header.<br />If set to false, the listener will reject requests without a Proxy Protocol header.<br />If not set, the default behavior is to reject requests without a Proxy Protocol header.<br />Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.<br />For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt |
+
+
 #### ProxyProtocolVersion
 
 _Underlying type:_ _string_
@@ -4963,6 +4981,7 @@ _Appears in:_
 | `type` | _[TracingProviderType](#tracingprovidertype)_ |  true  | OpenTelemetry | Type defines the tracing provider type. |
 | `host` | _string_ |  false  |  | Host define the provider service hostname.<br />Deprecated: Use BackendRefs instead. |
 | `port` | _integer_ |  false  | 4317 | Port defines the port the provider service is exposed on.<br />Deprecated: Use BackendRefs instead. |
+| `serviceName` | _string_ |  false  |  | ServiceName defines the service name to use in tracing configuration.<br />If not set, Envoy Gateway will use a default service name set as<br />"name.namespace" (e.g., "my-gateway.default").<br />Note: This field is only supported for OpenTelemetry and Datadog tracing providers.<br />For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag<br />(typically "namespace/name" format). Setting this field has no effect for Zipkin. |
 | `zipkin` | _[ZipkinTracingProvider](#zipkintracingprovider)_ |  false  |  | Zipkin defines the Zipkin tracing provider configuration |
 
 
diff --git a/site/content/en/latest/concepts/_index.md b/site/content/en/latest/concepts/_index.md
index 4d568bd44..d12baa94f 100644
--- a/site/content/en/latest/concepts/_index.md
+++ b/site/content/en/latest/concepts/_index.md
@@ -3,3 +3,88 @@ title: "Concepts"
 weight: 1
 description: Learn about key concepts when working with Envoy Gateway
 ---
+
+## Overview
+
+**Envoy Gateway** is a Kubernetes-native [API Gateway](api-gateways.md) and reverse proxy control plane. It simplifies deploying and operating [Envoy Proxy](proxy.md) as a data plane by using the standard [Gateway API](gateway-api.md) and its own extensible APIs.
+
+By combining Envoy's performance and flexibility with Kubernetes-native configuration, Envoy Gateway helps platform teams expose and manage secure, observable, and scalable APIs with minimal operational overhead.
+
+## Why Use Envoy Gateway?
+
+Traditionally, configuring Envoy Proxy required deep networking expertise and writing complex configuration files. Envoy Gateway removes that barrier by:
+
+- Integrating tightly with Kubernetes through the Gateway API
+- Providing custom CRDs for advanced traffic policies
+- Automatically translating Kubernetes resources into Envoy config
+- Managing the lifecycle of Envoy Proxy instances
+
+Envoy Gateway is designed to be **simple for app developers**, **powerful for platform engineers**, and **production-ready for large-scale deployments**.
+
+## Structure
+
+The different layers of Envoy Gateway are the following:
+
+| Layer       | Description |
+|----------------|-------------|
+| **User Configuration** | Users define routing, security, and traffic policies using standard Kubernetes Gateway API resources, optionally extended with Envoy Gateway CRDs.|
+| **Envoy Gateway Controller** | A control plane component that watches Gateway API and Envoy Gateway-specific resources, translates them, and produces configuration for Envoy Proxy.|
+| **Envoy Proxy(Data Plane)** | A high-performance proxy that receives and handles live traffic according to the configuration generated by Envoy Gateway.|
+
+Together, these layers create a system that's:
+- Easy to configure
+- Powerful enough for complex needs
+- Standardized and familiar
+- Ready for the future
+
+## Resources
+
+![](/img/envoy-gateway-resources-overview.png)
+
+There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
+
+### Kubernetes Gateway API Resources
+- **GatewayClass:** Defines a class of Gateways with common configuration.
+- **Gateway:** Specifies how traffic can enter the cluster.
+- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
+
+### Envoy Gateway (EG) API Resources
+- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
+- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
+- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
+
+| Resource                                                                | API         | Required | Purpose            | References             | Description                                                                                                                                                                                                 |
+| ----------------------------------------------------------------------- | ----------- | -------- | ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| [GatewayClass][1]                                                       | Gateway API | Yes      | Gateway Config     | Core                   | Defines a class of Gateways with common configuration.                                                                                                                                                      |
+| [Gateway][2]                                                            | Gateway API | Yes      | Gateway Config     | GatewayClass           | Specifies how traffic can enter the cluster.                                                                                                                                                                |
+| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes      | Routing            | Gateway                | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_                                                |
+| [Backend][8]                                                            | EG API      | No       | Routing            | N/A                    | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets.                                    |
+| [ClientTrafficPolicy][9]                                                | EG API      | No       | Traffic Handling   | Gateway                | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations.                                                                                 |
+| [BackendTrafficPolicy][10]                                              | EG API      | No       | Traffic Handling   | Gateway, Route         | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_                             |
+| [SecurityPolicy][11]                                                    | EG API      | No       | Security           | Gateway, Route         | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_                          |
+| [BackendTLSPolicy][12]                                                  | Gateway API | No       | Security           | Service                | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services.                     |
+| [EnvoyProxy][13]                                                        | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
+| [EnvoyPatchPolicy][14]                                                  | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_                |
+| [EnvoyExtensionPolicy][15]                                              | EG API      | No       | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_                                                             |
+| [HTTPRouteFilter][16]                                                   | EG API      | No       | Customize & Extend | HTTPRoute              | Allows for the additional request/response processing. |
+
+
+## Next Steps
+For a deeper understanding of Envoy Gateway’s building blocks, you may also wish to explore these conceptual guides:
+
+[1]:	https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
+[2]:	https://gateway-api.sigs.k8s.io/api-types/gateway/
+[3]:	https://gateway-api.sigs.k8s.io/api-types/httproute/
+[4]:	https://gateway-api.sigs.k8s.io/api-types/grpcroute/
+[5]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TLSRoute
+[6]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TCPRoute
+[7]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.UDPRoute
+[8]:	../tasks/traffic/backend
+[9]:	../api/extension_types#clienttrafficpolicy
+[10]:	../api/extension_types#backendtrafficpolicy
+[11]:	../api/extension_types#securitypolicy
+[12]:	https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
+[13]:	../api/extension_types#envoyproxy
+[14]:	../api/extension_types#envoypatchpolicy
+[15]:	../api/extension_types#envoyextensionpolicy
+[16]:   ../api/extension_types#httproutefilter
diff --git a/site/content/en/latest/concepts/introduction/api-gateways.md b/site/content/en/latest/concepts/api-gateways.md
similarity index 91%
rename from site/content/en/latest/concepts/introduction/api-gateways.md
rename to site/content/en/latest/concepts/api-gateways.md
index 3583e11d2..35e240e20 100644
--- a/site/content/en/latest/concepts/introduction/api-gateways.md
+++ b/site/content/en/latest/concepts/api-gateways.md
@@ -23,5 +23,5 @@ Envoy Gateway makes configuring Envoy Proxy simple by implementing and extending
 
 ## Related Resources
 
-- [Getting Started with Envoy Gateway](../../tasks/quickstart.md)
-- [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/)
\ No newline at end of file
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
+- [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/)
diff --git a/site/content/en/latest/concepts/concepts_overview.md b/site/content/en/latest/concepts/concepts_overview.md
deleted file mode 100644
index 55872ef47..000000000
--- a/site/content/en/latest/concepts/concepts_overview.md
+++ /dev/null
@@ -1,56 +0,0 @@
-+++
-title = "Envoy Gateway Resources"
-+++
-
-There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-
-## Overview
-
-![](/img/envoy-gateway-resources-overview.png)
-
-There are several resources that play a part in enabling you to meet your Kubernetes ingress traffic handling needs. This page provides a brief overview of the resources you’ll be working with.
-
-### Kubernetes Gateway API Resources
-- **GatewayClass:** Defines a class of Gateways with common configuration.
-- **Gateway:** Specifies how traffic can enter the cluster.
-- **Routes:** **HTTPRoute, GRPCRoute, TLSRoute, TCPRoute, UDPRoute:** Define routing rules for different types of traffic.
-
-### Envoy Gateway (EG) API Resources
-- **EnvoyProxy:** Represents the deployment and configuration of the Envoy proxy within a Kubernetes cluster, managing its lifecycle and settings.
-- **EnvoyPatchPolicy, ClientTrafficPolicy, SecurityPolicy, BackendTrafficPolicy, EnvoyExtensionPolicy, BackendTLSPolicy:** Additional policies and configurations specific to Envoy Gateway.
-- **Backend:** A resource that makes routing to cluster-external backends easier and makes access to external processes via Unix Domain Sockets possible.
-
-| Resource                                                                | API         | Required | Purpose            | References             | Description                                                                                                                                                                                                 |
-| ----------------------------------------------------------------------- | ----------- | -------- | ------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| [GatewayClass][1]                                                       | Gateway API | Yes      | Gateway Config     | Core                   | Defines a class of Gateways with common configuration.                                                                                                                                                      |
-| [Gateway][2]                                                            | Gateway API | Yes      | Gateway Config     | GatewayClass           | Specifies how traffic can enter the cluster.                                                                                                                                                                |
-| [HTTPRoute][3] [GRPCRoute][4] [TLSRoute][5] [TCPRoute][6] [UDPRoute][7] | Gateway API | Yes      | Routing            | Gateway                | Define routing rules for different types of traffic. **Note:**_For simplicity these resources are referenced collectively as Route in the References column_                                                |
-| [Backend][8]                                                            | EG API      | No       | Routing            | N/A                    | Used for routing to cluster-external backends using FQDN or IP. Can also be used when you want to extend Envoy with external processes accessed via Unix Domain Sockets.                                    |
-| [ClientTrafficPolicy][9]                                                | EG API      | No       | Traffic Handling   | Gateway                | Specifies policies for handling client traffic, including rate limiting, retries, and other client-specific configurations.                                                                                 |
-| [BackendTrafficPolicy][10]                                              | EG API      | No       | Traffic Handling   | Gateway, Route         | Specifies policies for traffic directed towards backend services, including load balancing, health checks, and failover strategies. **Note:**_Most specific configuration wins_                             |
-| [SecurityPolicy][11]                                                    | EG API      | No       | Security           | Gateway, Route         | Defines security-related policies such as authentication, authorization, and encryption settings for traffic handled by Envoy Gateway. **Note:**_Most specific configuration wins_                          |
-| [BackendTLSPolicy][12]                                                  | Gateway API | No       | Security           | Service                | Defines TLS settings for backend connections, including certificate management, TLS version settings, and other security configurations. This policy is applied to Kubernetes Services.                     |
-| [EnvoyProxy][13]                                                        | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | The EnvoyProxy resource represents the deployment and configuration of the Envoy proxy itself within a Kubernetes cluster, managing its lifecycle and settings. **Note:**_Most specific configuration wins_ |
-| [EnvoyPatchPolicy][14]                                                  | EG API      | No       | Customize & Extend | GatewayClass, Gateway  | This policy defines custom patches to be applied to Envoy Gateway resources, allowing users to tailor the configuration to their specific needs. **Note:**_Most specific configuration wins_                |
-| [EnvoyExtensionPolicy][15]                                              | EG API      | No       | Customize & Extend | Gateway, Route, Backend| Allows for the configuration of Envoy proxy extensions, enabling custom behavior and functionality. **Note:**_Most specific configuration wins_                                                             |
-| [HTTPRouteFilter][16]                                                   | EG API      | No       | Customize & Extend | HTTPRoute              | Allows for the additional request/response processing. |
-
-
-
-
-[1]:	https://gateway-api.sigs.k8s.io/api-types/gatewayclass/
-[2]:	https://gateway-api.sigs.k8s.io/api-types/gateway/
-[3]:	https://gateway-api.sigs.k8s.io/api-types/httproute/
-[4]:	https://gateway-api.sigs.k8s.io/api-types/grpcroute/
-[5]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TLSRoute
-[6]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.TCPRoute
-[7]:	https://gateway-api.sigs.k8s.io/reference/spec#gateway.networking.k8s.io/v1alpha2.UDPRoute
-[8]:	../tasks/traffic/backend
-[9]:	../api/extension_types#clienttrafficpolicy
-[10]:	../api/extension_types#backendtrafficpolicy
-[11]:	../api/extension_types#securitypolicy
-[12]:	https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy/
-[13]:	../api/extension_types#envoyproxy
-[14]:	../api/extension_types#envoypatchpolicy
-[15]:	../api/extension_types#envoyextensionpolicy
-[16]:   ../api/extension_types#httproutefilter
diff --git a/site/content/en/latest/concepts/introduction/gateway-api.md b/site/content/en/latest/concepts/gateway-api.md
similarity index 93%
rename from site/content/en/latest/concepts/introduction/gateway-api.md
rename to site/content/en/latest/concepts/gateway-api.md
index 608893fff..1ee514ff5 100644
--- a/site/content/en/latest/concepts/introduction/gateway-api.md
+++ b/site/content/en/latest/concepts/gateway-api.md
@@ -30,6 +30,6 @@ One of the Gateway API's key strengths is that implementers can extend it. While
 Envoy Gateway leverages this model by introducing a suite of Gateway API extensions—implemented as Kubernetes Custom Resource Definitions (CRDs)—to expose powerful features from Envoy Proxy. These features include enhanced support for rate limiting, authentication, traffic shaping, and more. By utilizing these extensions, users can access production-grade functionality in a Kubernetes-native and declarative manner, without needing to write a low-level Envoy configuration.
 
 ## Related Resources
-- [Getting Started with Envoy Gateway](../../tasks/quickstart.md)
-- [Envoy Gateway API Reference](../../api/extension_types)
-- [Extensibility Tasks](../../tasks/extensibility/_index.md)
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
+- [Envoy Gateway API Reference](../api/extension_types)
+- [Extensibility Tasks](../tasks/extensibility/_index.md)
diff --git a/site/content/en/latest/concepts/introduction/gateway_api_extensions/_index.md b/site/content/en/latest/concepts/gateway_api_extensions/_index.md
similarity index 78%
rename from site/content/en/latest/concepts/introduction/gateway_api_extensions/_index.md
rename to site/content/en/latest/concepts/gateway_api_extensions/_index.md
index 26d3789db..c74bccb95 100644
--- a/site/content/en/latest/concepts/introduction/gateway_api_extensions/_index.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/_index.md
@@ -29,16 +29,16 @@ Here are some examples of what kind of features extensions include:
 The Envoy Gateway API introduces a set of Gateway API extensions that enable users to leverage the power of the Envoy proxy. Envoy Gateway uses a policy attachment model, where custom policies are applied to standard Gateway API resources (like HTTPRoute or Gateway) without modifying the core API. This approach provides separation of concerns and makes it easier to manage configurations across teams.
 
 {{% alert title="Current Extensions" color="info" %}}
-Currently supported extensions include 
-[`Backend`](../../../api/extension_types#backend), 
-[`BackendTrafficPolicy`](../../../api/extension_types#backendtrafficpolicy), 
-[`ClientTrafficPolicy`](../../../api/extension_types#clienttrafficpolicy), 
-[`EnvoyExtensionPolicy`](../../../api/extension_types#envoyextensionpolicy), 
-[`EnvoyGateway`](../../../api/extension_types#envoygateway), 
-[`EnvoyPatchPolicy`](../../../api/extension_types#envoypatchpolicy), 
-[`EnvoyProxy`](../../../api/extension_types#envoyproxy), 
-[`HTTPRouteFilter`](../../../api/extension_types#httproutefilter), and 
-[`SecurityPolicy`](../../../api/extension_types#securitypolicy), 
+Currently supported extensions include
+[`Backend`](../../api/extension_types#backend),
+[`BackendTrafficPolicy`](../../api/extension_types#backendtrafficpolicy),
+[`ClientTrafficPolicy`](../../api/extension_types#clienttrafficpolicy),
+[`EnvoyExtensionPolicy`](../../api/extension_types#envoyextensionpolicy),
+[`EnvoyGateway`](../../api/extension_types#envoygateway),
+[`EnvoyPatchPolicy`](../../api/extension_types#envoypatchpolicy),
+[`EnvoyProxy`](../../api/extension_types#envoyproxy),
+[`HTTPRouteFilter`](../../api/extension_types#httproutefilter), and
+[`SecurityPolicy`](../../api/extension_types#securitypolicy),
 {{% /alert %}}
 
 These extensions are processed through Envoy Gateway's control plane, translating them into xDS configurations applied to Envoy Proxy instances. This layered architecture allows for consistent, scalable, and production-grade traffic control without needing to manage raw Envoy configuration directly.
diff --git a/site/content/en/latest/concepts/introduction/gateway_api_extensions/backend-traffic-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
similarity index 87%
rename from site/content/en/latest/concepts/introduction/gateway_api_extensions/backend-traffic-policy.md
rename to site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
index 995d66e7d..1cc981a1b 100644
--- a/site/content/en/latest/concepts/introduction/gateway_api_extensions/backend-traffic-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/backend-traffic-policy.md
@@ -13,21 +13,21 @@ Think of it as a traffic controller between your gateway and backend services. I
 
 `BackendTrafficPolicy` is particularly useful in scenarios where you need to:
 
-1. **Protect your services:** 
+1. **Protect your services:**
    Limit connections and reject excess traffic when necessary
 
-2. **Build resilient systems:** 
+2. **Build resilient systems:**
    Detect failing services and redirect traffic
 
-3. **Improve performance:** 
+3. **Improve performance:**
    Optimize how requests are distributed and responses are handled
 
-4. **Test system behavior:** 
+4. **Test system behavior:**
    Inject faults and validate your recovery mechanisms
 
 ## BackendTrafficPolicy in Envoy Gateway
 
-`BackendTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages traffic to your backend services. 
+`BackendTrafficPolicy` is part of the Envoy Gateway API suite, which extends the Kubernetes Gateway API with additional capabilities. It's implemented as a Custom Resource Definition (CRD) that you can use to configure how Envoy Gateway manages traffic to your backend services.
 
 You can attach it to Gateway API resources in two ways:
 
@@ -142,12 +142,12 @@ In this example, the route-level policy merges with the gateway-level policy, re
 
 ## Related Resources
 
-- [Circuit Breakers](../../../tasks/traffic/circuit-breaker.md)
-- [Failover](../../../tasks/traffic/failover)
-- [Fault Injection](../../../tasks/traffic/fault-injection)
-- [Global Rate Limit](../../../tasks/traffic/global-rate-limit)
-- [Local Rate Limit](../../../tasks/traffic/local-rate-limit)
-- [Load Balancing](../../../tasks/traffic/load-balancing)
-- [Response Compression](../../../tasks/traffic/response-compression)
-- [Response Override](../../../tasks/traffic/response-override)
-- [BackendTrafficPolicy API Reference](../../../api/extension_types#backendtrafficpolicy)
+- [Circuit Breakers](../../tasks/traffic/circuit-breaker.md)
+- [Failover](../../tasks/traffic/failover)
+- [Fault Injection](../../tasks/traffic/fault-injection)
+- [Global Rate Limit](../../tasks/traffic/global-rate-limit)
+- [Local Rate Limit](../../tasks/traffic/local-rate-limit)
+- [Load Balancing](../../tasks/traffic/load-balancing)
+- [Response Compression](../../tasks/traffic/response-compression)
+- [Response Override](../../tasks/traffic/response-override)
+- [BackendTrafficPolicy API Reference](../../api/extension_types#backendtrafficpolicy)
diff --git a/site/content/en/latest/concepts/introduction/gateway_api_extensions/client-traffic-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
similarity index 90%
rename from site/content/en/latest/concepts/introduction/gateway_api_extensions/client-traffic-policy.md
rename to site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
index 6d43eaec0..8dc47a306 100644
--- a/site/content/en/latest/concepts/introduction/gateway_api_extensions/client-traffic-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/client-traffic-policy.md
@@ -81,8 +81,8 @@ In this case:
 
 ## Related Resources
 
-- [Connection Limit](../../../tasks/traffic/connection-limit.md)
-- [HTTP Request Headers](../../../tasks/traffic/http-request-headers)
-- [HTTP/3](../../../tasks/traffic/http3)
-- [Mutual TLS: External Clients to the Gateway](../../../tasks/security/mutual-tls/)
-- [ClientTrafficPolicy API Reference](../../../api/extension_types#clienttrafficpolicy)
+- [Connection Limit](../../tasks/traffic/connection-limit.md)
+- [HTTP Request Headers](../../tasks/traffic/http-request-headers)
+- [HTTP/3](../../tasks/traffic/http3)
+- [Mutual TLS: External Clients to the Gateway](../../tasks/security/mutual-tls/)
+- [ClientTrafficPolicy API Reference](../../api/extension_types#clienttrafficpolicy)
diff --git a/site/content/en/latest/concepts/introduction/gateway_api_extensions/security-policy.md b/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
similarity index 81%
rename from site/content/en/latest/concepts/introduction/gateway_api_extensions/security-policy.md
rename to site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
index cc0a27391..12f0eccfd 100644
--- a/site/content/en/latest/concepts/introduction/gateway_api_extensions/security-policy.md
+++ b/site/content/en/latest/concepts/gateway_api_extensions/security-policy.md
@@ -70,12 +70,12 @@ spec:
 In the example, policy A affects only the HTTPS listener, while policy B applies to the rest of the listeners in the gateway. Since Policy A is more specific, the system will show Overridden=True for Policy B on the https listener.
 
 ## Related Resources
-- [API Key Authentication](../../../tasks/security/apikey-auth.md)
-- [Basic Authentication](../../../tasks/security/basic-auth.md)
-- [CORS](../../../tasks/security/cors.md)
-- [External Authorization](../../../tasks/security/ext-auth.md)
-- [IP Allowlist/Denylist](../../../tasks/security/restrict-ip-access.md)
-- [JWT Authentication](../../../tasks/security/jwt-authentication.md)
-- [JWT Claim Based Authorization](../../../tasks/security/jwt-claim-authorization.md)
-- [OIDC Authorization](../../../tasks/security/oidc.md)
-- [SecurityPolicy API Reference](../../../api/extension_types#securitypolicy)
+- [API Key Authentication](../../tasks/security/apikey-auth.md)
+- [Basic Authentication](../../tasks/security/basic-auth.md)
+- [CORS](../../tasks/security/cors.md)
+- [External Authorization](../../tasks/security/ext-auth.md)
+- [IP Allowlist/Denylist](../../tasks/security/restrict-ip-access.md)
+- [JWT Authentication](../../tasks/security/jwt-authentication.md)
+- [JWT Claim Based Authorization](../../tasks/security/jwt-claim-authorization.md)
+- [OIDC Authorization](../../tasks/security/oidc.md)
+- [SecurityPolicy API Reference](../../api/extension_types#securitypolicy)
diff --git a/site/content/en/latest/concepts/introduction/_index.md b/site/content/en/latest/concepts/introduction/_index.md
deleted file mode 100644
index 52e0098ed..000000000
--- a/site/content/en/latest/concepts/introduction/_index.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: "Introduction"
-weight: 1
----
-
-## Overview
-
-**Envoy Gateway** is a Kubernetes-native [API Gateway](api-gateways.md) and reverse proxy control plane. It simplifies deploying and operating [Envoy Proxy](proxy.md) as a data plane by using the standard [Gateway API](gateway-api.md) and its own extensible APIs.
-
-By combining Envoy's performance and flexibility with Kubernetes-native configuration, Envoy Gateway helps platform teams expose and manage secure, observable, and scalable APIs with minimal operational overhead.
-
-## Why Use Envoy Gateway?
-
-Traditionally, configuring Envoy Proxy required deep networking expertise and writing complex configuration files. Envoy Gateway removes that barrier by:
-
-- Integrating tightly with Kubernetes through the Gateway API
-- Providing custom CRDs for advanced traffic policies
-- Automatically translating Kubernetes resources into Envoy config
-- Managing the lifecycle of Envoy Proxy instances
-
-Envoy Gateway is designed to be **simple for app developers**, **powerful for platform engineers**, and **production-ready for large-scale deployments**.
-
-## Structure
-
-The different layers of Envoy Gateway are the following:
-
-| Layer       | Description |
-|----------------|-------------|
-| **User Configuration** | Users define routing, security, and traffic policies using standard Kubernetes Gateway API resources, optionally extended with Envoy Gateway CRDs.|
-| **Envoy Gateway Controller** | A control plane component that watches Gateway API and Envoy Gateway-specific resources, translates them, and produces configuration for Envoy Proxy.|
-| **Envoy Proxy(Data Plane)** | A high-performance proxy that receives and handles live traffic according to the configuration generated by Envoy Gateway.|
-
-Together, these layers create a system that's:
-- Easy to configure
-- Powerful enough for complex needs
-- Standardized and familiar
-- Ready for the future
-
-## Next Steps
-For a deeper understanding of Envoy Gateway’s building blocks, you may also wish to explore these conceptual guides:
\ No newline at end of file
diff --git a/site/content/en/latest/concepts/introduction/load-balancing.md b/site/content/en/latest/concepts/load-balancing.md
similarity index 94%
rename from site/content/en/latest/concepts/introduction/load-balancing.md
rename to site/content/en/latest/concepts/load-balancing.md
index e99bbc138..a644ecefd 100644
--- a/site/content/en/latest/concepts/introduction/load-balancing.md
+++ b/site/content/en/latest/concepts/load-balancing.md
@@ -66,5 +66,5 @@ spec:
 In this setup, traffic matching /round is distributed evenly across all available backend service instances. For example, if there are four replicas of the backend service, each one should receive roughly 25% of the requests.
 
 ## Related Resources
-- [BackendTrafficPolicy](../introduction/gateway_api_extensions/backend-traffic-policy.md)
-- [Task: Load Balancing](../../tasks/traffic/load-balancing.md)
+- [BackendTrafficPolicy](gateway_api_extensions/backend-traffic-policy.md)
+- [Task: Load Balancing](../tasks/traffic/load-balancing.md)
diff --git a/site/content/en/latest/concepts/introduction/proxy.md b/site/content/en/latest/concepts/proxy.md
similarity index 96%
rename from site/content/en/latest/concepts/introduction/proxy.md
rename to site/content/en/latest/concepts/proxy.md
index fab550ae8..5e4dcb5b9 100644
--- a/site/content/en/latest/concepts/introduction/proxy.md
+++ b/site/content/en/latest/concepts/proxy.md
@@ -29,5 +29,5 @@ Envoy Proxy is a high-performance, open-source proxy designed for cloud-native a
 The control plane uses the Kubernetes Gateway API to understand your settings and then translates them into the format Envoy Proxy needs (called _xDS configuration_). It also runs and updates the Envoy Proxy instances inside your Kubernetes cluster.
 
 ## Related Resources
-- [Getting Started with Envoy Gateway](../../tasks/quickstart.md)
+- [Getting Started with Envoy Gateway](../tasks/quickstart.md)
 - [Envoy Proxy](https://www.envoyproxy.io/)
diff --git a/site/content/en/latest/concepts/introduction/rate-limiting.md b/site/content/en/latest/concepts/rate-limiting.md
similarity index 94%
rename from site/content/en/latest/concepts/introduction/rate-limiting.md
rename to site/content/en/latest/concepts/rate-limiting.md
index 02df8c39b..6573197b7 100644
--- a/site/content/en/latest/concepts/introduction/rate-limiting.md
+++ b/site/content/en/latest/concepts/rate-limiting.md
@@ -102,6 +102,6 @@ spec:
 This configuration limits traffic to 50 requests per minute per Envoy instance for the my-api route. If there are two Envoy replicas, up to 100 total requests per minute may be allowed (50 per replica).
 
 ## Related Resources
-- [BackendTrafficPolicy](../introduction/gateway_api_extensions/backend-traffic-policy.md)
-- [Task: Global Rate Limit](../../tasks/traffic/global-rate-limit.md)
-- [Task: Local Rate Limit](../../tasks/traffic/local-rate-limit.md)
+- [BackendTrafficPolicy](gateway_api_extensions/backend-traffic-policy.md)
+- [Task: Global Rate Limit](../tasks/traffic/global-rate-limit.md)
+- [Task: Local Rate Limit](../tasks/traffic/local-rate-limit.md)
diff --git a/site/content/en/latest/install/gateway-helm-api.md b/site/content/en/latest/install/gateway-helm-api.md
index abd96395b..bd2abbec9 100644
--- a/site/content/en/latest/install/gateway-helm-api.md
+++ b/site/content/en/latest/install/gateway-helm-api.md
@@ -23,7 +23,7 @@ The Helm chart for Envoy Gateway
 
 | Key | Type | Default | Description |
 |-----|------|---------|-------------|
-| certgen | object | `{"job":{"affinity":{},"annotations":{},"args":[],"nodeSelector":{},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65532,"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
+| certgen | object | `{"job":{"affinity":{},"annotations":{},"args":[],"nodeSelector":{},"pod":{"annotations":{},"labels":{}},"resources":{},"securityContext":{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"privileged":false,"readOnlyRootFilesystem":true,"runAsGroup":65532,"runAsNonRoot":true,"runAsUser":65532,"seccompProfile":{"type":"RuntimeDefault"}},"tolerations":[],"ttlSecondsAfterFinished":30},"rbac":{"annotations":{},"labels":{}}}` | Certgen is used to generate the certificates required by EnvoyGateway. If you want to construct a custom certificate, you can generate a custom certificate through Cert-Manager before installing EnvoyGateway. Certgen will not overwrite the custom certificate. Please do not manually modify `values.yaml` to disable certgen, it may cause EnvoyGateway OIDC,OAuth2,etc. to not work as expected. |
 | config.envoyGateway | object | `{"extensionApis":{},"gateway":{"controllerName":"gateway.envoyproxy.io/gatewayclass-controller"},"logging":{"level":{"default":"info"}},"provider":{"type":"Kubernetes"}}` | EnvoyGateway configuration. Visit https://gateway.envoyproxy.io/docs/api/extension_types/#envoygateway to view all options. |
 | createNamespace | bool | `false` |  |
 | deployment.annotations | object | `{}` |  |
diff --git a/site/content/en/latest/install/install-helm.md b/site/content/en/latest/install/install-helm.md
index 5a18076de..009394e0e 100644
--- a/site/content/en/latest/install/install-helm.md
+++ b/site/content/en/latest/install/install-helm.md
@@ -58,9 +58,9 @@ consideration when debugging.
 ## Installing CRDs separately
 
 The [Envoy Gateway Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-helm/tags) includes two types of CRDs under its crds/ directory:
-* [Gateway API CRDs](../concepts/introduction/#gateway-api/) (from the *experimental* channel): This channel includes additional `alpha` resources
+* [Gateway API CRDs](../concepts/#gateway-api) (from the *experimental* channel): This channel includes additional `alpha` resources
 such as `TCPRoute` and `BackendTLSPolicy`, which are commonly used by Envoy Gateway users.
-* [Envoy Gateway CRDs](../concepts/introduction/#gateway_api_extensions): These are custom CRDs that extend the Gateway API to support additional
+* [Envoy Gateway CRDs](../concepts/gateway_api_extensions/): These are custom CRDs that extend the Gateway API to support additional
 Envoy Gateway-specific features.
 
 If you prefer to manage CRDs separately, the [Envoy Gateway CRDs Helm Chart](https://hub.docker.com/r/envoyproxy/gateway-crds-helm/tags) allows you
diff --git a/site/content/en/latest/tasks/observability/grafana-integration.md b/site/content/en/latest/tasks/observability/grafana-integration.md
index 259f6958b..1975ff953 100644
--- a/site/content/en/latest/tasks/observability/grafana-integration.md
+++ b/site/content/en/latest/tasks/observability/grafana-integration.md
@@ -23,7 +23,7 @@ GRAFANA_IP=$(kubectl get svc grafana -n monitoring -o jsonpath='{.status.loadBal
 To visualise metrics from Prometheus, we have to connect Grafana with Prometheus. If you installed Grafana follow the command
 from prerequisites sections, the Prometheus datasource should be already configured.
 
-You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/).
+You can also add the datasource manually by following the instructions from [Grafana Docs](https://grafana.com/docs/grafana/latest/datasources/prometheus/configure/).
 
 ## Accessing Grafana
 
@@ -72,7 +72,7 @@ feel free to make [contributions](../../../contributions/CONTRIBUTING).
 
 ### Grafonnet
 
-Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html). 
+Newer dashboards are generated with [Jsonnet](https://jsonnet.org/) with the [Grafonnet](https://grafana.github.io/grafonnet/index.html).
 This is the preferred method for any new dashboards.
 
 You can run `make helm-generate.gateway-addons-helm` to generate new version of dashboards.
diff --git a/test/cel-validation/envoyproxy_test.go b/test/cel-validation/envoyproxy_test.go
index 3c85511fd..cd0e37995 100644
--- a/test/cel-validation/envoyproxy_test.go
+++ b/test/cel-validation/envoyproxy_test.go
@@ -1161,6 +1161,59 @@ func TestEnvoyProxyProvider(t *testing.T) {
 			},
 			wantErrors: []string{"host or backendRefs needs to be set"},
 		},
+		{
+			desc: "valid-tracing-service-name",
+			mutate: func(envoy *egv1a1.EnvoyProxy) {
+				envoy.Spec = egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name: "fake-service",
+												Kind: ptr.To(gwapiv1.Kind("Service")),
+												Port: ptr.To(gwapiv1.PortNumber(880)),
+											},
+										},
+									},
+								},
+								ServiceName: ptr.To("my-custom-service"),
+							},
+						},
+					},
+				}
+			},
+		},
+		{
+			desc: "invalid-tracing-empty-service-name",
+			mutate: func(envoy *egv1a1.EnvoyProxy) {
+				envoy.Spec = egv1a1.EnvoyProxySpec{
+					Telemetry: &egv1a1.ProxyTelemetry{
+						Tracing: &egv1a1.ProxyTracing{
+							Provider: egv1a1.TracingProvider{
+								Type: egv1a1.TracingProviderTypeOpenTelemetry,
+								BackendCluster: egv1a1.BackendCluster{
+									BackendRefs: []egv1a1.BackendRef{
+										{
+											BackendObjectReference: gwapiv1.BackendObjectReference{
+												Name: "fake-service",
+												Kind: ptr.To(gwapiv1.Kind("Service")),
+												Port: ptr.To(gwapiv1.PortNumber(880)),
+											},
+										},
+									},
+								},
+								ServiceName: ptr.To(""),
+							},
+						},
+					},
+				}
+			},
+			wantErrors: []string{"serviceName cannot be empty if provided"},
+		},
 		{
 			desc: "ProxyHpa-maxReplicas-is-required",
 			mutate: func(envoy *egv1a1.EnvoyProxy) {
diff --git a/test/e2e/testdata/tracing-datadog-custom-service-name.yaml b/test/e2e/testdata/tracing-datadog-custom-service-name.yaml
new file mode 100644
index 000000000..6b5ec0379
--- /dev/null
+++ b/test/e2e/testdata/tracing-datadog-custom-service-name.yaml
@@ -0,0 +1,78 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: tracing-datadog-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+    - name: http
+      port: 80
+      protocol: HTTP
+      allowedRoutes:
+        namespaces:
+          from: All
+  infrastructure:
+    parametersRef:
+      group: gateway.envoyproxy.io
+      kind: EnvoyProxy
+      name: tracing-datadog-custom-service-name
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  name: tracing-datadog-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  ipFamily: IPv4
+  logging:
+    level:
+      default: debug
+  telemetry:
+    tracing:
+      provider:
+        type: Datadog
+        backendRefs:
+          - name: otel-collector
+            namespace: monitoring
+            port: 8126
+        serviceName: my-custom-service
+      customTags:
+        "provider":
+          type: Literal
+          literal:
+            value: "datadog"
+        "k8s.cluster.name":
+          type: Literal
+          literal:
+            value: "envoy-gateway"
+        "k8s.pod.name":
+          type: Environment
+          environment:
+            name: ENVOY_POD_NAME
+            defaultValue: "-"
+        "k8s.namespace.name":
+          type: Environment
+          environment:
+            name: ENVOY_POD_NAMESPACE
+            defaultValue: "envoy-gateway-system"
+  shutdown:
+    drainTimeout: 5s
+    minDrainDuration: 1s
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: tracing-datadog-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: tracing-datadog-custom-service-name
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /datadog-custom-service
+      backendRefs:
+        - name: infra-backend-v2
+          port: 8080
diff --git a/test/e2e/testdata/tracing-otel-custom-service-name.yaml b/test/e2e/testdata/tracing-otel-custom-service-name.yaml
new file mode 100644
index 000000000..aa56c385e
--- /dev/null
+++ b/test/e2e/testdata/tracing-otel-custom-service-name.yaml
@@ -0,0 +1,74 @@
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: tracing-otel-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+    - name: http
+      port: 80
+      protocol: HTTP
+      allowedRoutes:
+        namespaces:
+          from: All
+  infrastructure:
+    parametersRef:
+      group: gateway.envoyproxy.io
+      kind: EnvoyProxy
+      name: tracing-otel-custom-service-name
+---
+apiVersion: gateway.envoyproxy.io/v1alpha1
+kind: EnvoyProxy
+metadata:
+  name: tracing-otel-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  ipFamily: IPv4
+  telemetry:
+    tracing:
+      provider:
+        backendRefs:
+          - name: otel-collector
+            namespace: monitoring
+            port: 4317
+        serviceName: my-custom-service
+      customTags:
+        "provider":
+          type: Literal
+          literal:
+            value: "otel"
+        "k8s.cluster.name":
+          type: Literal
+          literal:
+            value: "envoy-gateway"
+        "k8s.pod.name":
+          type: Environment
+          environment:
+            name: ENVOY_POD_NAME
+            defaultValue: "-"
+        "k8s.namespace.name":
+          type: Environment
+          environment:
+            name: ENVOY_POD_NAMESPACE
+            defaultValue: "envoy-gateway-system"
+  shutdown:
+    drainTimeout: 5s
+    minDrainDuration: 1s
+---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: tracing-otel-custom-service-name
+  namespace: gateway-conformance-infra
+spec:
+  parentRefs:
+    - name: tracing-otel-custom-service-name
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /custom-service
+      backendRefs:
+        - name: infra-backend-v1
+          port: 8080
diff --git a/test/e2e/tests/tracing.go b/test/e2e/tests/tracing.go
index f7350d82a..25a615a20 100644
--- a/test/e2e/tests/tracing.go
+++ b/test/e2e/tests/tracing.go
@@ -26,34 +26,55 @@ func init() {
 
 var OpenTelemetryTracingTest = suite.ConformanceTest{
 	ShortName:   "OpenTelemetryTracing",
-	Description: "Make sure OpenTelemetry tracing is working",
-	Manifests:   []string{"testdata/tracing-otel.yaml"},
+	Description: "Make sure OpenTelemetry tracing is working (default and custom service name)",
+	Manifests:   []string{"testdata/tracing-otel.yaml", "testdata/tracing-otel-custom-service-name.yaml"},
 	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
-		t.Run("tempo", func(t *testing.T) {
-			ns := "gateway-conformance-infra"
-			routeNN := types.NamespacedName{Name: "tracing-otel", Namespace: ns}
-			gwNN := types.NamespacedName{Name: "tracing-otel", Namespace: ns}
-			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
-
-			expectedResponse := httputils.ExpectedResponse{
-				Request: httputils.Request{
-					Path: "/otel",
-				},
-				Response: httputils.Response{
-					StatusCode: 200,
-				},
-				Namespace: ns,
-			}
-			// make sure listener is ready
-			httputils.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
-
-			tags := map[string]string{
-				"component":    "proxy",
-				"provider":     "otel",
-				"service.name": naming.ServiceName(gwNN),
-			}
-			tracing.ExpectedTraceCount(t, suite, gwAddr, expectedResponse, tags)
-		})
+		cases := []struct {
+			name        string
+			routeName   string
+			gwName      string
+			path        string
+			expectedSvc string
+		}{
+			{
+				name:        "default-service-name",
+				routeName:   "tracing-otel",
+				gwName:      "tracing-otel",
+				path:        "/otel",
+				expectedSvc: naming.ServiceName(types.NamespacedName{Name: "tracing-otel", Namespace: "gateway-conformance-infra"}),
+			},
+			{
+				name:        "custom-service-name",
+				routeName:   "tracing-otel-custom-service-name",
+				gwName:      "tracing-otel-custom-service-name",
+				path:        "/custom-service",
+				expectedSvc: "my-custom-service",
+			},
+		}
+		for _, tc := range cases {
+			t.Run(tc.name, func(t *testing.T) {
+				ns := "gateway-conformance-infra"
+				routeNN := types.NamespacedName{Name: tc.routeName, Namespace: ns}
+				gwNN := types.NamespacedName{Name: tc.gwName, Namespace: ns}
+				gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+				expectedResponse := httputils.ExpectedResponse{
+					Request: httputils.Request{
+						Path: tc.path,
+					},
+					Response: httputils.Response{
+						StatusCode: 200,
+					},
+					Namespace: ns,
+				}
+				httputils.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+				tags := map[string]string{
+					"component":    "proxy",
+					"provider":     "otel",
+					"service.name": tc.expectedSvc,
+				}
+				tracing.ExpectedTraceCount(t, suite, gwAddr, expectedResponse, tags)
+			})
+		}
 	},
 }
 
@@ -94,33 +115,54 @@ var ZipkinTracingTest = suite.ConformanceTest{
 
 var DatadogTracingTest = suite.ConformanceTest{
 	ShortName:   "DatadogTracing",
-	Description: "Make sure Datadog tracing is working",
-	Manifests:   []string{"testdata/tracing-datadog.yaml"},
+	Description: "Make sure Datadog tracing is working (default and custom service name)",
+	Manifests:   []string{"testdata/tracing-datadog.yaml", "testdata/tracing-datadog-custom-service-name.yaml"},
 	Test: func(t *testing.T, suite *suite.ConformanceTestSuite) {
-		t.Run("tempo", func(t *testing.T) {
-			ns := "gateway-conformance-infra"
-			routeNN := types.NamespacedName{Name: "tracing-datadog", Namespace: ns}
-			gwNN := types.NamespacedName{Name: "eg-special-case-datadog", Namespace: ns}
-			gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
-
-			expectedResponse := httputils.ExpectedResponse{
-				Request: httputils.Request{
-					Path: "/datadog",
-				},
-				Response: httputils.Response{
-					StatusCode: 200,
-				},
-				Namespace: ns,
-			}
-			// make sure listener is ready
-			httputils.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
-
-			tags := map[string]string{
-				"component":    "proxy",
-				"provider":     "datadog",
-				"service.name": fmt.Sprintf("%s.%s", gwNN.Name, gwNN.Namespace),
-			}
-			tracing.ExpectedTraceCount(t, suite, gwAddr, expectedResponse, tags)
-		})
+		cases := []struct {
+			name        string
+			routeName   string
+			gwName      string
+			path        string
+			expectedSvc string
+		}{
+			{
+				name:        "default-service-name",
+				routeName:   "tracing-datadog",
+				gwName:      "eg-special-case-datadog",
+				path:        "/datadog",
+				expectedSvc: fmt.Sprintf("%s.%s", "eg-special-case-datadog", "gateway-conformance-infra"),
+			},
+			{
+				name:        "custom-service-name",
+				routeName:   "tracing-datadog-custom-service-name",
+				gwName:      "tracing-datadog-custom-service-name",
+				path:        "/datadog-custom-service",
+				expectedSvc: "my-custom-service",
+			},
+		}
+		for _, tc := range cases {
+			t.Run(tc.name, func(t *testing.T) {
+				ns := "gateway-conformance-infra"
+				routeNN := types.NamespacedName{Name: tc.routeName, Namespace: ns}
+				gwNN := types.NamespacedName{Name: tc.gwName, Namespace: ns}
+				gwAddr := kubernetes.GatewayAndHTTPRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), routeNN)
+				expectedResponse := httputils.ExpectedResponse{
+					Request: httputils.Request{
+						Path: tc.path,
+					},
+					Response: httputils.Response{
+						StatusCode: 200,
+					},
+					Namespace: ns,
+				}
+				httputils.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, expectedResponse)
+				tags := map[string]string{
+					"component":    "proxy",
+					"provider":     "datadog",
+					"service.name": tc.expectedSvc,
+				}
+				tracing.ExpectedTraceCount(t, suite, gwAddr, expectedResponse, tags)
+			})
+		}
 	},
 }
diff --git a/test/helm/gateway-crds-helm/all.out.yaml b/test/helm/gateway-crds-helm/all.out.yaml
index c16d276ed..30d7e8e8c 100644
--- a/test/helm/gateway-crds-helm/all.out.yaml
+++ b/test/helm/gateway-crds-helm/all.out.yaml
@@ -20154,6 +20154,8 @@ spec:
                   Client Address into the X-Forwarded-For header.
                   Note Proxy Protocol must be present when this field is set, else the connection
                   is closed.
+
+                  Deprecated: Use ProxyProtocol instead.
                 type: boolean
               headers:
                 description: HeaderSettings provides configuration for header management.
@@ -20486,6 +20488,24 @@ spec:
                     - UnescapeAndRedirect
                     type: string
                 type: object
+              proxyProtocol:
+                description: |-
+                  ProxyProtocol configures the Proxy Protocol settings. When configured,
+                  the Proxy Protocol header will be interpreted and the Client Address
+                  will be added into the X-Forwarded-For header.
+                  If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+                minProperties: 0
+                properties:
+                  optional:
+                    description: |-
+                      Optional allows requests without a Proxy Protocol header to be proxied.
+                      If set to true, the listener will accept requests without a Proxy Protocol header.
+                      If set to false, the listener will reject requests without a Proxy Protocol header.
+                      If not set, the default behavior is to reject requests without a Proxy Protocol header.
+                      Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.
+                      For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt
+                    type: boolean
+                type: object
               targetRef:
                 description: |-
                   TargetRef is the name of the resource this policy is being attached to.
@@ -38778,6 +38798,18 @@ spec:
                             format: int32
                             minimum: 0
                             type: integer
+                          serviceName:
+                            description: |-
+                              ServiceName defines the service name to use in tracing configuration.
+                              If not set, Envoy Gateway will use a default service name set as
+                              "name.namespace" (e.g., "my-gateway.default").
+                              Note: This field is only supported for OpenTelemetry and Datadog tracing providers.
+                              For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag
+                              (typically "namespace/name" format). Setting this field has no effect for Zipkin.
+                            type: string
+                            x-kubernetes-validations:
+                            - message: serviceName cannot be empty if provided
+                              rule: self != ""
                           type:
                             default: OpenTelemetry
                             description: Type defines the tracing provider type.
@@ -39420,7 +39452,7 @@ spec:
 
                                 The client IP is inferred from the X-Forwarded-For header, a custom header,
                                 or the proxy protocol.
-                                You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
+                                You can use the `ClientIPDetection` or the `ProxyProtocol` field in
                                 the `ClientTrafficPolicy` to configure how the client IP is detected.
                               items:
                                 description: |-
diff --git a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
index fce013c4e..3e1b5980d 100644
--- a/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
+++ b/test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
@@ -2842,6 +2842,8 @@ spec:
                   Client Address into the X-Forwarded-For header.
                   Note Proxy Protocol must be present when this field is set, else the connection
                   is closed.
+
+                  Deprecated: Use ProxyProtocol instead.
                 type: boolean
               headers:
                 description: HeaderSettings provides configuration for header management.
@@ -3174,6 +3176,24 @@ spec:
                     - UnescapeAndRedirect
                     type: string
                 type: object
+              proxyProtocol:
+                description: |-
+                  ProxyProtocol configures the Proxy Protocol settings. When configured,
+                  the Proxy Protocol header will be interpreted and the Client Address
+                  will be added into the X-Forwarded-For header.
+                  If both EnableProxyProtocol and ProxyProtocol are set, ProxyProtocol takes precedence.
+                minProperties: 0
+                properties:
+                  optional:
+                    description: |-
+                      Optional allows requests without a Proxy Protocol header to be proxied.
+                      If set to true, the listener will accept requests without a Proxy Protocol header.
+                      If set to false, the listener will reject requests without a Proxy Protocol header.
+                      If not set, the default behavior is to reject requests without a Proxy Protocol header.
+                      Warning: Optional breaks conformance with the specification. Only enable if ALL traffic to the listener comes from a trusted source.
+                      For more information on security implications, see haproxy.org/download/2.1/doc/proxy-protocol.txt
+                    type: boolean
+                type: object
               targetRef:
                 description: |-
                   TargetRef is the name of the resource this policy is being attached to.
@@ -21466,6 +21486,18 @@ spec:
                             format: int32
                             minimum: 0
                             type: integer
+                          serviceName:
+                            description: |-
+                              ServiceName defines the service name to use in tracing configuration.
+                              If not set, Envoy Gateway will use a default service name set as
+                              "name.namespace" (e.g., "my-gateway.default").
+                              Note: This field is only supported for OpenTelemetry and Datadog tracing providers.
+                              For Zipkin, the service name in traces is always derived from the Envoy --service-cluster flag
+                              (typically "namespace/name" format). Setting this field has no effect for Zipkin.
+                            type: string
+                            x-kubernetes-validations:
+                            - message: serviceName cannot be empty if provided
+                              rule: self != ""
                           type:
                             default: OpenTelemetry
                             description: Type defines the tracing provider type.
@@ -22108,7 +22140,7 @@ spec:
 
                                 The client IP is inferred from the X-Forwarded-For header, a custom header,
                                 or the proxy protocol.
-                                You can use the `ClientIPDetection` or the `EnableProxyProtocol` field in
+                                You can use the `ClientIPDetection` or the `ProxyProtocol` field in
                                 the `ClientTrafficPolicy` to configure how the client IP is detected.
                               items:
                                 description: |-
diff --git a/test/helm/gateway-helm/certgen-annotations.in.yaml b/test/helm/gateway-helm/certgen-annotations.in.yaml
new file mode 100644
index 000000000..bc07a9c3a
--- /dev/null
+++ b/test/helm/gateway-helm/certgen-annotations.in.yaml
@@ -0,0 +1,11 @@
+global:
+  images:
+    envoyGateway:
+      image: "docker.io/envoyproxy/gateway-dev:latest"
+      pullPolicy: Always
+
+certgen:
+  job:
+    pod:
+      annotations:
+        foo: bar
\ No newline at end of file
diff --git a/test/helm/gateway-helm/certgen-annotations.out.yaml b/test/helm/gateway-helm/certgen-annotations.out.yaml
new file mode 100644
index 000000000..ee7cd1a07
--- /dev/null
+++ b/test/helm/gateway-helm/certgen-annotations.out.yaml
@@ -0,0 +1,700 @@
+---
+# Source: gateway-helm/templates/envoy-gateway-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+---
+# Source: gateway-helm/templates/envoy-gateway-config.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    extensionApis: {}
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    logging:
+      level:
+        default: info
+    provider:
+      kubernetes:
+        rateLimitDeployment:
+          container:
+            image: docker.io/envoyproxy/ratelimit:master
+          patch:
+            type: StrategicMerge
+            value:
+              spec:
+                template:
+                  spec:
+                    containers:
+                    - imagePullPolicy: IfNotPresent
+                      name: envoy-ratelimit
+        shutdownManager:
+          image: docker.io/envoyproxy/gateway-dev:latest
+      type: Kubernetes
+---
+# Source: gateway-helm/templates/envoy-gateway-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  creationTimestamp: null
+  name: gateway-helm-envoy-gateway-role
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - nodes
+  - namespaces
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gatewayclasses
+  verbs:
+  - get
+  - list
+  - patch
+  - update
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gatewayclasses/status
+  verbs:
+  - update
+- apiGroups:
+  - multicluster.x-k8s.io
+  resources:
+  - serviceimports
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - ""
+  resources:
+  - configmaps
+  - secrets
+  - services
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - apps
+  resources:
+  - deployments
+  - daemonsets
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - discovery.k8s.io
+  resources:
+  - endpointslices
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.envoyproxy.io
+  resources:
+  - envoyproxies
+  - envoypatchpolicies
+  - clienttrafficpolicies
+  - backendtrafficpolicies
+  - securitypolicies
+  - envoyextensionpolicies
+  - backends
+  - httproutefilters
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.envoyproxy.io
+  resources:
+  - envoypatchpolicies/status
+  - clienttrafficpolicies/status
+  - backendtrafficpolicies/status
+  - securitypolicies/status
+  - envoyextensionpolicies/status
+  - backends/status
+  verbs:
+  - update
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gateways
+  - grpcroutes
+  - httproutes
+  - referencegrants
+  - tcproutes
+  - tlsroutes
+  - udproutes
+  - backendtlspolicies
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gateways/status
+  - grpcroutes/status
+  - httproutes/status
+  - tcproutes/status
+  - tlsroutes/status
+  - udproutes/status
+  - backendtlspolicies/status
+  verbs:
+  - update
+- apiGroups:
+  - ""
+  resources:
+  - pods
+  - pods/binding
+  verbs:
+  - get
+  - list
+  - patch
+  - update
+  - watch
+---
+# Source: gateway-helm/templates/envoy-gateway-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: gateway-helm-envoy-gateway-rolebinding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: gateway-helm-envoy-gateway-role
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/infra-manager-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-infra-manager
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - serviceaccounts
+  - services
+  - configmaps
+  verbs:
+  - create
+  - get
+  - list
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - apps
+  resources:
+  - deployments
+  - daemonsets
+  verbs:
+  - create
+  - get
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - autoscaling
+  - policy
+  resources:
+  - horizontalpodautoscalers
+  - poddisruptionbudgets
+  verbs:
+  - create
+  - get
+  - list
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - certificates.k8s.io
+  resources:
+  - clustertrustbundles
+  verbs:
+  - list
+  - get
+  - watch
+---
+# Source: gateway-helm/templates/leader-election-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-leader-election-role
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - configmaps
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+- apiGroups:
+  - coordination.k8s.io
+  resources:
+  - leases
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+- apiGroups:
+  - ""
+  resources:
+  - events
+  verbs:
+  - create
+  - patch
+---
+# Source: gateway-helm/templates/infra-manager-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-infra-manager
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-infra-manager'
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/leader-election-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-leader-election-rolebinding
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-leader-election-role'
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/envoy-gateway-service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    control-plane: envoy-gateway
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  selector:
+    control-plane: envoy-gateway
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+  ports:
+  - name: grpc
+    port: 18000
+    targetPort: 18000
+  - name: ratelimit
+    port: 18001
+    targetPort: 18001
+  - name: wasm
+    port: 18002
+    targetPort: 18002
+  - name: metrics
+    port: 19001
+    targetPort: 19001
+  - name: webhook
+    port: 9443
+    targetPort: 9443
+---
+# Source: gateway-helm/templates/envoy-gateway-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    control-plane: envoy-gateway
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      control-plane: envoy-gateway
+      app.kubernetes.io/name: gateway-helm
+      app.kubernetes.io/instance: gateway-helm
+  template:
+    metadata:
+      annotations:
+        prometheus.io/port: "19001"
+        prometheus.io/scrape: "true"
+      labels:
+        control-plane: envoy-gateway
+        app.kubernetes.io/name: gateway-helm
+        app.kubernetes.io/instance: gateway-helm
+    spec:
+      containers:
+      - args:
+        - server
+        - --config-path=/config/envoy-gateway.yaml
+        env:
+        - name: ENVOY_GATEWAY_NAMESPACE
+          valueFrom:
+            fieldRef:
+              apiVersion: v1
+              fieldPath: metadata.namespace
+        - name: KUBERNETES_CLUSTER_DOMAIN
+          value: cluster.local
+        image: docker.io/envoyproxy/gateway-dev:latest
+        imagePullPolicy: Always
+        livenessProbe:
+          httpGet:
+            path: /healthz
+            port: 8081
+          initialDelaySeconds: 15
+          periodSeconds: 20
+        name: envoy-gateway
+        ports:
+        - containerPort: 18000
+          name: grpc
+        - containerPort: 18001
+          name: ratelimit
+        - containerPort: 18002
+          name: wasm
+        - containerPort: 19001
+          name: metrics
+        - name: webhook
+          containerPort: 9443
+        readinessProbe:
+          httpGet:
+            path: /readyz
+            port: 8081
+          initialDelaySeconds: 5
+          periodSeconds: 10
+        resources:
+          limits:
+            memory: 1024Mi
+          requests:
+            cpu: 100m
+            memory: 256Mi
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          privileged: false
+          runAsGroup: 65532
+          runAsNonRoot: true
+          runAsUser: 65532
+          seccompProfile:
+            type: RuntimeDefault
+        volumeMounts:
+        - mountPath: /config
+          name: envoy-gateway-config
+          readOnly: true
+        - mountPath: /certs
+          name: certs
+          readOnly: true
+      imagePullSecrets: []
+      serviceAccountName: envoy-gateway
+      terminationGracePeriodSeconds: 10
+      volumes:
+      - configMap:
+          defaultMode: 420
+          name: envoy-gateway-config
+        name: envoy-gateway-config
+      - name: certs
+        secret:
+          secretName: envoy-gateway
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+rules:
+  - apiGroups:
+    - admissionregistration.k8s.io
+    resources:
+    - mutatingwebhookconfigurations
+    verbs:
+    - get
+    - list
+    - watch
+  - apiGroups:
+      - admissionregistration.k8s.io
+    resources:
+      - mutatingwebhookconfigurations
+    resourceNames:
+      - 'envoy-gateway-topology-injector.envoy-gateway-system'
+    verbs:
+      - update
+      - patch
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+subjects:
+  - kind: ServiceAccount
+    name: 'gateway-helm-certgen'
+    namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - secrets
+  verbs:
+  - get
+  - create
+  - update
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-certgen'
+subjects:
+- kind: ServiceAccount
+  name: 'gateway-helm-certgen'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/certgen.yaml
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+spec:
+  backoffLimit: 1
+  completions: 1
+  parallelism: 1
+  template:
+    metadata:
+      labels:
+        app: certgen
+      annotations:
+        foo: bar
+    spec:
+      containers:
+      - command:
+        - envoy-gateway
+        - certgen
+        env:
+        - name: ENVOY_GATEWAY_NAMESPACE
+          valueFrom:
+            fieldRef:
+              apiVersion: v1
+              fieldPath: metadata.namespace
+        - name: KUBERNETES_CLUSTER_DOMAIN
+          value: cluster.local
+        image: docker.io/envoyproxy/gateway-dev:latest
+        imagePullPolicy: Always
+        name: envoy-gateway-certgen
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          privileged: false
+          readOnlyRootFilesystem: true
+          runAsGroup: 65532
+          runAsNonRoot: true
+          runAsUser: 65532
+          seccompProfile:
+            type: RuntimeDefault
+      imagePullSecrets: []
+      restartPolicy: Never
+      serviceAccountName: gateway-helm-certgen
+  ttlSecondsAfterFinished: 30
+---
+# Source: gateway-helm/templates/envoy-proxy-topology-injector-webhook.yaml
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+  name: 'envoy-gateway-topology-injector.envoy-gateway-system'
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"
+  labels:
+    app.kubernetes.io/component: topology-injector
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+webhooks:
+  - name: topology.webhook.gateway.envoyproxy.io
+    admissionReviewVersions: ["v1"]
+    sideEffects: None
+    clientConfig:
+      service:
+        name: envoy-gateway
+        namespace: 'envoy-gateway-system'
+        path: "/inject-pod-topology"
+        port: 9443
+    failurePolicy: Ignore
+    rules:
+      - operations: ["CREATE"]
+        apiGroups: [""]
+        apiVersions: ["v1"]
+        resources: ["pods/binding"]
+    namespaceSelector:
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: In
+          values:
+            - envoy-gateway-system
diff --git a/test/helm/gateway-helm/certgen-labels.in.yaml b/test/helm/gateway-helm/certgen-labels.in.yaml
new file mode 100644
index 000000000..5e634ece0
--- /dev/null
+++ b/test/helm/gateway-helm/certgen-labels.in.yaml
@@ -0,0 +1,11 @@
+global:
+  images:
+    envoyGateway:
+      image: "docker.io/envoyproxy/gateway-dev:latest"
+      pullPolicy: Always
+
+certgen:
+  job:
+    pod:
+      labels:
+        foo: bar
\ No newline at end of file
diff --git a/test/helm/gateway-helm/certgen-labels.out.yaml b/test/helm/gateway-helm/certgen-labels.out.yaml
new file mode 100644
index 000000000..69c0168c2
--- /dev/null
+++ b/test/helm/gateway-helm/certgen-labels.out.yaml
@@ -0,0 +1,699 @@
+---
+# Source: gateway-helm/templates/envoy-gateway-serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+---
+# Source: gateway-helm/templates/envoy-gateway-config.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: envoy-gateway-config
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+data:
+  envoy-gateway.yaml: |
+    apiVersion: gateway.envoyproxy.io/v1alpha1
+    kind: EnvoyGateway
+    extensionApis: {}
+    gateway:
+      controllerName: gateway.envoyproxy.io/gatewayclass-controller
+    logging:
+      level:
+        default: info
+    provider:
+      kubernetes:
+        rateLimitDeployment:
+          container:
+            image: docker.io/envoyproxy/ratelimit:master
+          patch:
+            type: StrategicMerge
+            value:
+              spec:
+                template:
+                  spec:
+                    containers:
+                    - imagePullPolicy: IfNotPresent
+                      name: envoy-ratelimit
+        shutdownManager:
+          image: docker.io/envoyproxy/gateway-dev:latest
+      type: Kubernetes
+---
+# Source: gateway-helm/templates/envoy-gateway-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  creationTimestamp: null
+  name: gateway-helm-envoy-gateway-role
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - nodes
+  - namespaces
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gatewayclasses
+  verbs:
+  - get
+  - list
+  - patch
+  - update
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gatewayclasses/status
+  verbs:
+  - update
+- apiGroups:
+  - multicluster.x-k8s.io
+  resources:
+  - serviceimports
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - ""
+  resources:
+  - configmaps
+  - secrets
+  - services
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - apps
+  resources:
+  - deployments
+  - daemonsets
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - discovery.k8s.io
+  resources:
+  - endpointslices
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.envoyproxy.io
+  resources:
+  - envoyproxies
+  - envoypatchpolicies
+  - clienttrafficpolicies
+  - backendtrafficpolicies
+  - securitypolicies
+  - envoyextensionpolicies
+  - backends
+  - httproutefilters
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.envoyproxy.io
+  resources:
+  - envoypatchpolicies/status
+  - clienttrafficpolicies/status
+  - backendtrafficpolicies/status
+  - securitypolicies/status
+  - envoyextensionpolicies/status
+  - backends/status
+  verbs:
+  - update
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gateways
+  - grpcroutes
+  - httproutes
+  - referencegrants
+  - tcproutes
+  - tlsroutes
+  - udproutes
+  - backendtlspolicies
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - gateway.networking.k8s.io
+  resources:
+  - gateways/status
+  - grpcroutes/status
+  - httproutes/status
+  - tcproutes/status
+  - tlsroutes/status
+  - udproutes/status
+  - backendtlspolicies/status
+  verbs:
+  - update
+- apiGroups:
+  - ""
+  resources:
+  - pods
+  - pods/binding
+  verbs:
+  - get
+  - list
+  - patch
+  - update
+  - watch
+---
+# Source: gateway-helm/templates/envoy-gateway-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: gateway-helm-envoy-gateway-rolebinding
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: gateway-helm-envoy-gateway-role
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/infra-manager-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-infra-manager
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - serviceaccounts
+  - services
+  - configmaps
+  verbs:
+  - create
+  - get
+  - list
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - apps
+  resources:
+  - deployments
+  - daemonsets
+  verbs:
+  - create
+  - get
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - autoscaling
+  - policy
+  resources:
+  - horizontalpodautoscalers
+  - poddisruptionbudgets
+  verbs:
+  - create
+  - get
+  - list
+  - delete
+  - deletecollection
+  - patch
+- apiGroups:
+  - certificates.k8s.io
+  resources:
+  - clustertrustbundles
+  verbs:
+  - list
+  - get
+  - watch
+---
+# Source: gateway-helm/templates/leader-election-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-leader-election-role
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - configmaps
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+- apiGroups:
+  - coordination.k8s.io
+  resources:
+  - leases
+  verbs:
+  - get
+  - list
+  - watch
+  - create
+  - update
+  - patch
+  - delete
+- apiGroups:
+  - ""
+  resources:
+  - events
+  verbs:
+  - create
+  - patch
+---
+# Source: gateway-helm/templates/infra-manager-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-infra-manager
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-infra-manager'
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/leader-election-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-leader-election-rolebinding
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-leader-election-role'
+subjects:
+- kind: ServiceAccount
+  name: 'envoy-gateway'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/envoy-gateway-service.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    control-plane: envoy-gateway
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  selector:
+    control-plane: envoy-gateway
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+  ports:
+  - name: grpc
+    port: 18000
+    targetPort: 18000
+  - name: ratelimit
+    port: 18001
+    targetPort: 18001
+  - name: wasm
+    port: 18002
+    targetPort: 18002
+  - name: metrics
+    port: 19001
+    targetPort: 19001
+  - name: webhook
+    port: 9443
+    targetPort: 9443
+---
+# Source: gateway-helm/templates/envoy-gateway-deployment.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: envoy-gateway
+  namespace: 'envoy-gateway-system'
+  labels:
+    control-plane: envoy-gateway
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      control-plane: envoy-gateway
+      app.kubernetes.io/name: gateway-helm
+      app.kubernetes.io/instance: gateway-helm
+  template:
+    metadata:
+      annotations:
+        prometheus.io/port: "19001"
+        prometheus.io/scrape: "true"
+      labels:
+        control-plane: envoy-gateway
+        app.kubernetes.io/name: gateway-helm
+        app.kubernetes.io/instance: gateway-helm
+    spec:
+      containers:
+      - args:
+        - server
+        - --config-path=/config/envoy-gateway.yaml
+        env:
+        - name: ENVOY_GATEWAY_NAMESPACE
+          valueFrom:
+            fieldRef:
+              apiVersion: v1
+              fieldPath: metadata.namespace
+        - name: KUBERNETES_CLUSTER_DOMAIN
+          value: cluster.local
+        image: docker.io/envoyproxy/gateway-dev:latest
+        imagePullPolicy: Always
+        livenessProbe:
+          httpGet:
+            path: /healthz
+            port: 8081
+          initialDelaySeconds: 15
+          periodSeconds: 20
+        name: envoy-gateway
+        ports:
+        - containerPort: 18000
+          name: grpc
+        - containerPort: 18001
+          name: ratelimit
+        - containerPort: 18002
+          name: wasm
+        - containerPort: 19001
+          name: metrics
+        - name: webhook
+          containerPort: 9443
+        readinessProbe:
+          httpGet:
+            path: /readyz
+            port: 8081
+          initialDelaySeconds: 5
+          periodSeconds: 10
+        resources:
+          limits:
+            memory: 1024Mi
+          requests:
+            cpu: 100m
+            memory: 256Mi
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          privileged: false
+          runAsGroup: 65532
+          runAsNonRoot: true
+          runAsUser: 65532
+          seccompProfile:
+            type: RuntimeDefault
+        volumeMounts:
+        - mountPath: /config
+          name: envoy-gateway-config
+          readOnly: true
+        - mountPath: /certs
+          name: certs
+          readOnly: true
+      imagePullSecrets: []
+      serviceAccountName: envoy-gateway
+      terminationGracePeriodSeconds: 10
+      volumes:
+      - configMap:
+          defaultMode: 420
+          name: envoy-gateway-config
+        name: envoy-gateway-config
+      - name: certs
+        secret:
+          secretName: envoy-gateway
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+rules:
+  - apiGroups:
+    - admissionregistration.k8s.io
+    resources:
+    - mutatingwebhookconfigurations
+    verbs:
+    - get
+    - list
+    - watch
+  - apiGroups:
+      - admissionregistration.k8s.io
+    resources:
+      - mutatingwebhookconfigurations
+    resourceNames:
+      - 'envoy-gateway-topology-injector.envoy-gateway-system'
+    verbs:
+      - update
+      - patch
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: 'gateway-helm-certgen:envoy-gateway-system'
+subjects:
+  - kind: ServiceAccount
+    name: 'gateway-helm-certgen'
+    namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+rules:
+- apiGroups:
+  - ""
+  resources:
+  - secrets
+  verbs:
+  - get
+  - create
+  - update
+---
+# Source: gateway-helm/templates/certgen-rbac.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"   # Ensure rbac is created before the certgen job when using ArgoCD.
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: 'gateway-helm-certgen'
+subjects:
+- kind: ServiceAccount
+  name: 'gateway-helm-certgen'
+  namespace: 'envoy-gateway-system'
+---
+# Source: gateway-helm/templates/certgen.yaml
+apiVersion: batch/v1
+kind: Job
+metadata:
+  name: gateway-helm-certgen
+  namespace: 'envoy-gateway-system'
+  labels:
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+spec:
+  backoffLimit: 1
+  completions: 1
+  parallelism: 1
+  template:
+    metadata:
+      labels:
+        app: certgen
+        foo: bar
+    spec:
+      containers:
+      - command:
+        - envoy-gateway
+        - certgen
+        env:
+        - name: ENVOY_GATEWAY_NAMESPACE
+          valueFrom:
+            fieldRef:
+              apiVersion: v1
+              fieldPath: metadata.namespace
+        - name: KUBERNETES_CLUSTER_DOMAIN
+          value: cluster.local
+        image: docker.io/envoyproxy/gateway-dev:latest
+        imagePullPolicy: Always
+        name: envoy-gateway-certgen
+        securityContext:
+          allowPrivilegeEscalation: false
+          capabilities:
+            drop:
+            - ALL
+          privileged: false
+          readOnlyRootFilesystem: true
+          runAsGroup: 65532
+          runAsNonRoot: true
+          runAsUser: 65532
+          seccompProfile:
+            type: RuntimeDefault
+      imagePullSecrets: []
+      restartPolicy: Never
+      serviceAccountName: gateway-helm-certgen
+  ttlSecondsAfterFinished: 30
+---
+# Source: gateway-helm/templates/envoy-proxy-topology-injector-webhook.yaml
+apiVersion: admissionregistration.k8s.io/v1
+kind: MutatingWebhookConfiguration
+metadata:
+  name: 'envoy-gateway-topology-injector.envoy-gateway-system'
+  annotations:
+    "helm.sh/hook": pre-install, pre-upgrade
+    "helm.sh/hook-weight": "-1"
+  labels:
+    app.kubernetes.io/component: topology-injector
+    helm.sh/chart: gateway-helm-v0.0.0-latest
+    app.kubernetes.io/name: gateway-helm
+    app.kubernetes.io/instance: gateway-helm
+    app.kubernetes.io/version: "latest"
+    app.kubernetes.io/managed-by: Helm
+webhooks:
+  - name: topology.webhook.gateway.envoyproxy.io
+    admissionReviewVersions: ["v1"]
+    sideEffects: None
+    clientConfig:
+      service:
+        name: envoy-gateway
+        namespace: 'envoy-gateway-system'
+        path: "/inject-pod-topology"
+        port: 9443
+    failurePolicy: Ignore
+    rules:
+      - operations: ["CREATE"]
+        apiGroups: [""]
+        apiVersions: ["v1"]
+        resources: ["pods/binding"]
+    namespaceSelector:
+      matchExpressions:
+        - key: kubernetes.io/metadata.name
+          operator: In
+          values:
+            - envoy-gateway-system