Gateway-wide CTP incorrectly accepted when Gateway name is a prefix of another Gateway name (mergeGateways)
#9226 aperta il 15 giu 2026
Metriche repository
- Star
- (2871 star)
- Metriche merge PR
- (Metriche PR in attesa)
Descrizione
Description:
When mergeGateways is enabled and two Gateways exist where one name is a string prefix of the other (e.g. gw and gw-b), a Gateway-wide ClientTrafficPolicy targeting the shorter-named Gateway is incorrectly accepted even though a same-port HTTP listener exists on the other Gateway. The port overlap validation in validatePortOverlapForClientTrafficPolicy uses strings.Index(currName, prefix) == 0 to check whether a same-port listener belongs to the targeted Gateway, but because extractGatewayNameFromListener returns the prefix without a trailing slash, "envoy-gateway/gw" falsely matches "envoy-gateway/gw-b/http", causing the conflict to go undetected.
The same bug was identified and fixed for extractListenerSetPrefixFromListener in #9026 (trailing slash added to the returned prefix). The Gateway path has the same vulnerability.
Repro steps:
Apply the following resources:
envoyProxyForGatewayClass:
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyProxy
metadata:
namespace: envoy-gateway
name: test
spec:
mergeGateways: true
clientTrafficPolicies:
- apiVersion: gateway.envoyproxy.io/v1alpha1
kind: ClientTrafficPolicy
metadata:
namespace: envoy-gateway
name: ctp-gw-wide
spec:
targetRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: gw
tcpKeepalive:
probes: 5
gateways:
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gw
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
hostname: gw.example.com
protocol: HTTP
port: 8081
allowedRoutes:
namespaces:
from: Same
- apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
namespace: envoy-gateway
name: gw-b
spec:
gatewayClassName: envoy-gateway-class
listeners:
- name: http
hostname: gw-b.example.com
protocol: HTTP
port: 8081
allowedRoutes:
namespaces:
from: Same
Observe that the ClientTrafficPolicy status shows Accepted: True — it should show a port conflict error referencing the gw-b listener.
Environment:
Reproducible via the translation unit tests, no cluster required. The test fixture is at internal/gatewayapi/testdata/clienttrafficpolicy-gateway-wide-same-port-prefix-name-conflict.{in,out}.yaml.
Logs:
N/A