nic-6443 commented on code in PR #2818:
URL: 
https://github.com/apache/apisix-ingress-controller/pull/2818#discussion_r3679543741


##########
internal/adc/translator/tcproute.go:
##########
@@ -42,6 +43,68 @@ func newDefaultUpstreamWithoutScheme() *adctypes.Upstream {
        }
 }
 
+// listenerPortSet returns the de-duplicated set of ports of the listeners the
+// route attaches to. tctx.Listeners is populated by the controller from the
+// listeners that ParseRouteParentRefs already matched against the route's
+// parentRefs (honoring sectionName, port, protocol and allowedRoutes).
+func listenerPortSet(tctx *provider.TranslateContext) map[int32]struct{} {
+       portSet := make(map[int32]struct{}, len(tctx.Listeners))
+       for _, listener := range tctx.Listeners {
+               portSet[listener.Port] = struct{}{}
+       }
+       return portSet
+}
+
+// buildL4StreamRoutes builds the StreamRoutes for one L4 route rule.
+//
+// A StreamRoute without a server_port match matches every connection on any
+// stream listener, so multiple L4 routes collide onto one backend (#2802). To
+// isolate them we set server_port from the matched listener port(s), emitting 
one
+// StreamRoute per port.
+//
+// Whether to inject server_port is gated by shouldInjectServerPortVars (the 
same
+// listener_port_match_mode used by HTTPRoute/GRPCRoute): the listener port is 
a
+// logical Gateway value that must equal APISIX's physical stream listen port 
for
+// the match to work, so injection is opt-in (explicit sectionName/port 
targeting,
+// or more than one listener port). When it is not injected we keep the 
previous
+// single portless StreamRoute, preserving backward compatibility.
+func (t *Translator) buildL4StreamRoutes(tctx *provider.TranslateContext, 
namespace, name string, ruleIndex int, typ, routeKind string, labels 
map[string]string) []*adctypes.StreamRoute {
+       var ports []int32
+       if portSet := listenerPortSet(tctx); 
t.shouldInjectServerPortVars(tctx.RouteParentRefs, portSet) {

Review Comment:
   [P2] Derive explicit targeting from matched parentRefs
   
   `tctx.RouteParentRefs` is the unfiltered route spec, while `listenerPortSet` 
contains only listeners returned by `ParseRouteParentRefs`. If a route has an 
explicit parentRef that does not resolve or match plus a valid implicit 
parentRef with one listener, `hasExplicitListenerTarget` still returns true 
because of the invalid ref. In `auto` mode this injects the valid listener’s 
logical port instead of keeping the route portless, which can make the route 
unreachable when that port differs from APISIX’s physical stream port. Please 
derive the explicit-target signal from matched parent/listener contexts and 
cover the mixed invalid-explicit + valid-implicit case.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to