Skip to content

fix: honor BackendTrafficPolicy targetRefs.sectionName for Service ports#428

Open
AlinsRan wants to merge 3 commits into
masterfrom
fix/backend-traffic-policy-section-name
Open

fix: honor BackendTrafficPolicy targetRefs.sectionName for Service ports#428
AlinsRan wants to merge 3 commits into
masterfrom
fix/backend-traffic-policy-section-name

Conversation

@AlinsRan

@AlinsRan AlinsRan commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

What this does

Fixes #421.

AttachBackendTrafficPolicyToUpstream selected the policy to apply by matching only targetRef.Name and ignored targetRef.sectionName. As a result a BackendTrafficPolicy intended for a single named Service port was treated as if it applied to the entire Service.

For a Service target, the Gateway API interprets sectionName as the port name (see the generated API reference). This PR makes attachment honor it:

  • A targetRef without sectionName still applies to the whole Service (unchanged behavior).
  • A targetRef with sectionName attaches only to the backend whose resolved Service port name matches it.
  • A port-specific targetRef takes precedence over a whole-Service targetRef that matches the same backend.
  • Per Gateway API semantics, a sectionName that cannot be resolved does not attach.

To resolve a backend's port name, the function now also receives tctx.Services and maps the backend ref port number to the Service port name. All call sites (httproute / grpcroute / ingress / tcproute / tlsroute / udproute) are updated.

Tests

Added TestAttachBackendTrafficPolicyToUpstreamSectionName covering: sectionName match, mismatch (no attach), no-sectionName whole-Service attach, and port-specific precedence over whole-Service.

go build, go vet, and go test ./internal/adc/translator/ all pass.

Summary by CodeRabbit

  • New Features
    • Backend traffic policies now support port-specific targeting via sectionName, so scheme changes can apply to a specific named backend port (not just the whole service).
  • Bug Fixes
    • Improved backend traffic policy attachment to consistently use service/port context across HTTPRoute, TCPRoute, TLSRoute, UDPRoute, gRPCRoute, and ingress.
    • Added correct behavior when sectionName can’t be resolved for the referenced backend port.
  • Tests
    • Added unit tests for sectionName matching and overrides, plus a new end-to-end coverage for Gateway HTTPRoute behavior.

AttachBackendTrafficPolicyToUpstream only matched targetRef.Name and
ignored sectionName, so a policy scoped to one named Service port was
applied to the whole Service.

Now when a targetRef sets sectionName, the policy attaches only to the
backend whose Service port name matches it; a port-specific targetRef
takes precedence over a whole-Service one. Per Gateway API semantics, a
sectionName that cannot be resolved does not attach.

Closes #421
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 052e9016-0d1a-4de5-b150-1e56860aba52

📥 Commits

Reviewing files that changed from the base of the PR and between 63352d6 and 8c8aec6.

📒 Files selected for processing (1)
  • test/e2e/crds/v1alpha1/backendtrafficpolicy.go

📝 Walkthrough

Walkthrough

AttachBackendTrafficPolicyToUpstream in policies.go gains a services map parameter and new selection logic that prefers policies whose targetRef.sectionName matches the backend's Service port name, falling back to a generic (no sectionName) policy. A new backendRefMatchesSectionName helper performs the port lookup. All six route translators are updated to pass tctx.Services, unit tests cover the matching scenarios, and an E2E test validates the end-to-end behavior.

Changes

BackendTrafficPolicy sectionName-aware attachment

Layer / File(s) Summary
Core policy attachment logic and sectionName helper
internal/adc/translator/policies.go
AttachBackendTrafficPolicyToUpstream accepts a new services map[types.NamespacedName]*corev1.Service parameter. Iterates all candidate policies to find a "specific" match (targetRef sectionName resolves to the backend's Service port name via backendRefMatchesSectionName) or falls back to a "generic" policy with no sectionName; attaches only the winning policy. New backendRefMatchesSectionName helper returns false for nil port, missing Service, or unmatched port number.
Unit test coverage for sectionName matching
internal/adc/translator/httproute_test.go
TestAttachBackendTrafficPolicyToUpstreamSectionName provides table-driven test cases covering matching sectionName applies policy scheme, non-matching sectionName prevents attachment, absent sectionName applies to whole service, and port-specific policy overrides whole-service policy.
Call-site propagation across route translators
internal/adc/translator/httproute.go, internal/adc/translator/grpcroute.go, internal/adc/translator/ingress.go, internal/adc/translator/tcproute.go, internal/adc/translator/tlsroute.go, internal/adc/translator/udproute.go
All six route translators pass tctx.Services as the fourth argument to AttachBackendTrafficPolicyToUpstream during upstream policy binding.
End-to-end test validation
test/e2e/crds/v1alpha1/backendtrafficpolicy.go
New "Section Name" test context verifies that BackendTrafficPolicy with sectionName targeting a specific Service port applies only to that port and does not affect traffic to other ports of the same backend service.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 6
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: honor BackendTrafficPolicy targetRefs.sectionName for Service ports' directly describes the main change: enabling sectionName support for BackendTrafficPolicy when targeting Service backends.
Linked Issues check ✅ Passed The PR fully addresses issue #421 by implementing sectionName support in AttachBackendTrafficPolicyToUpstream, updating all call sites, and adding comprehensive tests for port-specific policy attachment behavior.
Out of Scope Changes check ✅ Passed All changes are within scope: updates to call sites across route types pass the Services context, the core logic implements sectionName matching with port resolution, and the e2e test validates the new behavior.
E2e Test Quality Review ✅ Passed E2E test is comprehensive with full business flow (API→Service→Gateway→APISIX). Unit tests cover all scenarios (sectionName match/mismatch, precedence, kind mismatch). Clear assertions, proper erro...
Security Check ✅ Passed Security analysis of PR changes finds no vulnerabilities across 7 categories: no sensitive data exposure in logs, no unencrypted secret storage, proper namespace-based authorization enforcement, co...

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/backend-traffic-policy-section-name

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/adc/translator/policies.go`:
- Around line 54-60: The policy matching logic in the loop iterating through
po.Spec.TargetRefs only validates the Name field of the targetRef against
ref.Name, which allows policies for different resource kinds (e.g.,
ServiceImport) to incorrectly attach to resources with the same name but
different kinds (e.g., Service). Add validation to also check that the
targetRef's group and kind match the corresponding fields of ref before
proceeding with the name comparison and the subsequent
backendRefMatchesSectionName check. This ensures policies are scoped to the
correct resource type and prevents cross-kind attachment when names collide.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1a7756f5-9f28-46b9-b2fa-ae57f0937e7d

📥 Commits

Reviewing files that changed from the base of the PR and between a3d4540 and 3c78cad.

📒 Files selected for processing (8)
  • internal/adc/translator/grpcroute.go
  • internal/adc/translator/httproute.go
  • internal/adc/translator/httproute_test.go
  • internal/adc/translator/ingress.go
  • internal/adc/translator/policies.go
  • internal/adc/translator/tcproute.go
  • internal/adc/translator/tlsroute.go
  • internal/adc/translator/udproute.go

Comment thread internal/adc/translator/policies.go
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

conformance test report - apisix mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-06-22T01:54:43Z"
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

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

conformance test report - apisix-standalone mode

apiVersion: gateway.networking.k8s.io/v1
date: "2026-06-22T01:53:44Z"
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.

@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

conformance test report

apiVersion: gateway.networking.k8s.io/v1
date: "2026-06-22T02:11:24Z"
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.

AlinsRan added 2 commits June 22, 2026 09:03
Matching only by name allowed a policy to attach across resource kinds
when names collide (e.g. a ServiceImport-targeted policy attaching to a
Service backend). Validate the targetRef group/kind against the backend
ref (applying Gateway API defaults: empty group, Service kind) before
matching.
Route two hostnames to the same Service via its two named ports (http/80
and http-v2/8080), then assert a policy with sectionName: http-v2 rewrites
the upstream host only for the http-v2 backend and not for the http one.
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: honor BackendTrafficPolicy targetRefs.sectionName when attaching to Service backends

1 participant