Skip to content

fix: honor TCPRoute/UDPRoute sectionName and listener port for StreamRoute matching#445

Open
AlinsRan wants to merge 1 commit into
masterfrom
ee-2802-l4-server-port
Open

fix: honor TCPRoute/UDPRoute sectionName and listener port for StreamRoute matching#445
AlinsRan wants to merge 1 commit into
masterfrom
ee-2802-l4-server-port

Conversation

@AlinsRan

Copy link
Copy Markdown
Contributor

Type of change:

  • Bugfix

What this PR does / why we need it:

Sync from apache/apisix-ingress-controller#2818 (fixes apache/apisix-ingress-controller#2802).

TranslateTCPRoute / TranslateUDPRoute emitted a single StreamRoute with no match criteria (the old // TODO: ... server_port). In APISIX stream mode a StreamRoute without server_port matches every connection on any stream listener, so all L4 routes across all Gateways collided onto one backend — parentRefs.sectionName / per-listener port routing were ignored.

Fix:

  • Controllers (tcproute_controller.go, udproute_controller.go): populate tctx.Listeners from the listeners ParseRouteParentRefs matched for each parentRef (honoring sectionName, port, protocol, allowedRoutes).
  • internal/controller/context.go + utils.go: RouteParentRefContext gains an additive Listeners slice; ParseRouteParentRefs records the matched listener(s); adds an appendListeners helper. The existing single-Listener field and match/break behavior are left intact (no HTTPRoute behavior change).
  • Translator (tcproute.go, udproute.go): set StreamRoute.server_port from the matched listener port(s), one StreamRoute per port with a port-qualified name/ID.

Gating (self-contained): EE has no listener_port_match_mode, so injection is decided locally — inject server_port on explicit sectionName/port targeting, or when more than one listener port is matched; otherwise keep the previous single portless StreamRoute (backward compatible).

Tests:

  • Unit (l4route_serverport_test.go): explicit sectionName injects the matching port; multi-listener fans out to distinct ServerPorts; dedup; single-listener-without-explicit stays portless; no-listener fallback. TCP + UDP.
  • L4 e2e listeners updated to APISIX's real stream ports (TCP 9100, UDP 9200) so server_port isolation is exercised.

Scope: TLSRoute not included (has SNI as its L4 discriminator). Multi-listener fan-out from a single parentRef is not populated by ParseRouteParentRefs here (EE keeps its match-and-break loop; the OSS hostname-helper refactor that removes the break was intentionally not ported to avoid changing HTTPRoute hostname behavior); fan-out across multiple parentRefs/gateways still works, and the sectionName isolation from the bug report is fully fixed.

Pre-submission checklist:

  • Test cases added
  • Backward compatible (server_port injection is opt-in via explicit targeting / multi-port)

…Route matching

TranslateTCPRoute/TranslateUDPRoute emitted a single StreamRoute with no match
criteria, so every TCP/UDP connection on any stream listener matched it. All L4
routes collided onto one backend, ignoring parentRefs.sectionName and per-listener
port routing.

The controllers now populate tctx.Listeners from the listeners ParseRouteParentRefs
matched for each parentRef (honoring sectionName, port, protocol and allowedRoutes).
The translator derives StreamRoute.server_port from the matched listener port(s),
emitting one StreamRoute per port with a port-qualified name/ID so listeners no
longer collide. Injection is gated locally (explicit sectionName/port targeting, or
more than one distinct listener port); otherwise the previous single portless
StreamRoute is kept for backward compatibility. L4 e2e listeners are updated to
APISIX's real stream ports (TCP 9100, UDP 9200) so server_port isolation is exercised.

Sync from apache/apisix-ingress-controller#2818 (fixes #2802)
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5ac7f27d-2e62-4443-afa6-073d16c07093

📥 Commits

Reviewing files that changed from the base of the PR and between 5f84a00 and d80419f.

📒 Files selected for processing (9)
  • internal/adc/translator/l4route_serverport_test.go
  • internal/adc/translator/tcproute.go
  • internal/adc/translator/udproute.go
  • internal/controller/context.go
  • internal/controller/tcproute_controller.go
  • internal/controller/udproute_controller.go
  • internal/controller/utils.go
  • test/e2e/gatewayapi/tcproute.go
  • test/e2e/gatewayapi/udproute.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ee-2802-l4-server-port

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-22T01:02:33Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    result: partial
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 0
      Passed: 32
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests partially succeeded with 1 test skips. Extended tests partially
    succeeded with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@AlinsRan AlinsRan self-assigned this Jul 22, 2026
@github-actions

Copy link
Copy Markdown
Contributor

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-22T01:03:09Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    result: success
    statistics:
      Failed: 0
      Passed: 12
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests succeeded.
- core:
    failedTests:
    - HTTPRouteInvalidBackendRefUnknownKind
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    result: partial
    skippedTests:
    - TLSRouteSimpleSameNamespace
    statistics:
      Failed: 0
      Passed: 10
      Skipped: 1
  name: GATEWAY-TLS
  summary: Core tests partially succeeded with 1 test skips.

@github-actions

Copy link
Copy Markdown
Contributor

conformance test report

apiVersion: gateway.networking.k8s.io/v1
date: "2026-07-22T01:20:01Z"
gatewayAPIChannel: experimental
gatewayAPIVersion: v1.3.0
implementation:
  contact: null
  organization: APISIX
  project: apisix-ingress-controller
  url: https://github.com/apache/apisix-ingress-controller.git
  version: v2.0.0
kind: ConformanceReport
mode: default
profiles:
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    statistics:
      Failed: 1
      Passed: 11
      Skipped: 0
  name: GATEWAY-GRPC
  summary: Core tests failed with 1 test failures.
- core:
    failedTests:
    - GatewayModifyListeners
    result: failure
    skippedTests:
    - HTTPRouteHTTPSListener
    statistics:
      Failed: 1
      Passed: 31
      Skipped: 1
  extended:
    result: partial
    skippedTests:
    - HTTPRouteRedirectPortAndScheme
    statistics:
      Failed: 0
      Passed: 11
      Skipped: 1
    supportedFeatures:
    - GatewayAddressEmpty
    - GatewayPort8080
    - HTTPRouteBackendProtocolWebSocket
    - HTTPRouteDestinationPortMatching
    - HTTPRouteHostRewrite
    - HTTPRouteMethodMatching
    - HTTPRoutePathRewrite
    - HTTPRoutePortRedirect
    - HTTPRouteQueryParamMatching
    - HTTPRouteRequestMirror
    - HTTPRouteResponseHeaderModification
    - HTTPRouteSchemeRedirect
    unsupportedFeatures:
    - GatewayHTTPListenerIsolation
    - GatewayInfrastructurePropagation
    - GatewayStaticAddresses
    - HTTPRouteBackendProtocolH2C
    - HTTPRouteBackendRequestHeaderModification
    - HTTPRouteBackendTimeout
    - HTTPRouteParentRefPort
    - HTTPRoutePathRedirect
    - HTTPRouteRequestMultipleMirrors
    - HTTPRouteRequestPercentageMirror
    - HTTPRouteRequestTimeout
  name: GATEWAY-HTTP
  summary: Core tests failed with 1 test failures. Extended tests partially succeeded
    with 1 test skips.
- core:
    failedTests:
    - GatewayModifyListeners
    - TLSRouteSimpleSameNamespace
    result: failure
    statistics:
      Failed: 2
      Passed: 9
      Skipped: 0
  name: GATEWAY-TLS
  summary: Core tests failed with 2 test failures.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Gateway API TCPRoute ignores parentRefs.sectionName / listener port, causing all TCP listeners to match the same backend

1 participant