Skip to content

Commit 27b4aa8

Browse files
authored
Clarify Gateway Listener Distinct definitions (#3477)
* Clarify Gateway Listener Distinct definitions Signed-off-by: Nick Young <[email protected]> * Update with PR comments Signed-off-by: Nick Young <[email protected]> --------- Signed-off-by: Nick Young <[email protected]>
1 parent 1dc9d2e commit 27b4aa8

File tree

4 files changed

+396
-186
lines changed

4 files changed

+396
-186
lines changed

apis/v1/gateway_types.go

Lines changed: 79 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ type GatewaySpec struct {
6969
// logical endpoints that are bound on this Gateway's addresses.
7070
// At least one Listener MUST be specified.
7171
//
72+
// ## Distinct Listeners
73+
//
7274
// Each Listener in a set of Listeners (for example, in a single Gateway)
7375
// MUST be _distinct_, in that a traffic flow MUST be able to be assigned to
7476
// exactly one listener. (This section uses "set of Listeners" rather than
@@ -80,74 +82,103 @@ type GatewaySpec struct {
8082
// combination of Port, Protocol, and, if supported by the protocol, Hostname.
8183
//
8284
// Some combinations of port, protocol, and TLS settings are considered
83-
// Core support and MUST be supported by implementations based on their
84-
// targeted conformance profile:
85+
// Core support and MUST be supported by implementations based on the objects
86+
// they support:
8587
//
86-
// HTTP Profile
88+
// HTTPRoute
8789
//
8890
// 1. HTTPRoute, Port: 80, Protocol: HTTP
8991
// 2. HTTPRoute, Port: 443, Protocol: HTTPS, TLS Mode: Terminate, TLS keypair provided
9092
//
91-
// TLS Profile
93+
// TLSRoute
9294
//
9395
// 1. TLSRoute, Port: 443, Protocol: TLS, TLS Mode: Passthrough
9496
//
9597
// "Distinct" Listeners have the following property:
9698
//
97-
// The implementation can match inbound requests to a single distinct
98-
// Listener. When multiple Listeners share values for fields (for
99+
// **The implementation can match inbound requests to a single distinct
100+
// Listener**.
101+
//
102+
// When multiple Listeners share values for fields (for
99103
// example, two Listeners with the same Port value), the implementation
100104
// can match requests to only one of the Listeners using other
101105
// Listener fields.
102106
//
103-
// For example, the following Listener scenarios are distinct:
107+
// When multiple listeners have the same value for the Protocol field, then
108+
// each of the Listeners with matching Protocol values MUST have different
109+
// values for other fields.
110+
//
111+
// The set of fields that MUST be different for a Listener differs per protocol.
112+
// The following rules define the rules for what fields MUST be considered for
113+
// Listeners to be distinct with each protocol currently defined in the
114+
// Gateway API spec.
115+
//
116+
// The set of listeners that all share a protocol value MUST have _different_
117+
// values for _at least one_ of these fields to be distinct:
118+
//
119+
// * **HTTP, HTTPS, TLS**: Port, Hostname
120+
// * **TCP, UDP**: Port
121+
//
122+
// One **very** important rule to call out involves what happens when an
123+
// implementation:
104124
//
105-
// 1. Multiple Listeners with the same Port that all use the "HTTP"
106-
// Protocol that all have unique Hostname values.
107-
// 2. Multiple Listeners with the same Port that use either the "HTTPS" or
108-
// "TLS" Protocol that all have unique Hostname values.
109-
// 3. A mixture of "TCP" and "UDP" Protocol Listeners, where no Listener
110-
// with the same Protocol has the same Port value.
125+
// * Supports TCP protocol Listeners, as well as HTTP, HTTPS, or TLS protocol
126+
// Listeners, and
127+
// * sees HTTP, HTTPS, or TLS protocols with the same `port` as one with TCP
128+
// Protocol.
111129
//
112-
// Some fields in the Listener struct have possible values that affect
113-
// whether the Listener is distinct. Hostname is particularly relevant
114-
// for HTTP or HTTPS protocols.
130+
// In this case all the Listeners that share a port with the
131+
// TCP Listener are not distinct and so MUST NOT be accepted.
115132
//
116-
// When using the Hostname value to select between same-Port, same-Protocol
117-
// Listeners, the Hostname value must be different on each Listener for the
118-
// Listener to be distinct.
133+
// If an implementation does not support TCP Protocol Listeners, then the
134+
// previous rule does not apply, and the TCP Listeners SHOULD NOT be
135+
// accepted.
119136
//
120-
// When the Listeners are distinct based on Hostname, inbound request
137+
// Note that the `tls` field is not used for determining if a listener is distinct, because
138+
// Listeners that _only_ differ on TLS config will still conflict in all cases.
139+
//
140+
// ### Listeners that are distinct only by Hostname
141+
//
142+
// When the Listeners are distinct based only on Hostname, inbound request
121143
// hostnames MUST match from the most specific to least specific Hostname
122144
// values to choose the correct Listener and its associated set of Routes.
123145
//
124-
// Exact matches must be processed before wildcard matches, and wildcard
125-
// matches must be processed before fallback (empty Hostname value)
146+
// Exact matches MUST be processed before wildcard matches, and wildcard
147+
// matches MUST be processed before fallback (empty Hostname value)
126148
// matches. For example, `"foo.example.com"` takes precedence over
127149
// `"*.example.com"`, and `"*.example.com"` takes precedence over `""`.
128150
//
129151
// Additionally, if there are multiple wildcard entries, more specific
130152
// wildcard entries must be processed before less specific wildcard entries.
131153
// For example, `"*.foo.example.com"` takes precedence over `"*.example.com"`.
154+
//
132155
// The precise definition here is that the higher the number of dots in the
133156
// hostname to the right of the wildcard character, the higher the precedence.
134157
//
135158
// The wildcard character will match any number of characters _and dots_ to
136159
// the left, however, so `"*.example.com"` will match both
137160
// `"foo.bar.example.com"` _and_ `"bar.example.com"`.
138161
//
162+
// ## Handling indistinct Listeners
163+
//
139164
// If a set of Listeners contains Listeners that are not distinct, then those
140-
// Listeners are Conflicted, and the implementation MUST set the "Conflicted"
165+
// Listeners are _Conflicted_, and the implementation MUST set the "Conflicted"
141166
// condition in the Listener Status to "True".
142167
//
168+
// The words "indistict" and "conflicted" are considered equivalent for the
169+
// purpose of this documentation.
170+
//
143171
// Implementations MAY choose to accept a Gateway with some Conflicted
144172
// Listeners only if they only accept the partial Listener set that contains
145-
// no Conflicted Listeners. To put this another way, implementations may
146-
// accept a partial Listener set only if they throw out *all* the conflicting
147-
// Listeners. No picking one of the conflicting listeners as the winner.
148-
// This also means that the Gateway must have at least one non-conflicting
149-
// Listener in this case, otherwise it violates the requirement that at
150-
// least one Listener must be present.
173+
// no Conflicted Listeners.
174+
//
175+
// Specifically, an implementation MAY accept a partial Listener set subject to
176+
// the following rules:
177+
//
178+
// * The implementation MUST NOT pick one conflicting Listener as the winner.
179+
// ALL indistinct Listeners must not be accepted for processing.
180+
// * At least one distinct Listener MUST be present, or else the Gateway effectively
181+
// contains _no_ Listeners, and must be rejected from processing as a whole.
151182
//
152183
// The implementation MUST set a "ListenersNotValid" condition on the
153184
// Gateway Status when the Gateway contains Conflicted Listeners whether or
@@ -156,7 +187,25 @@ type GatewaySpec struct {
156187
// Accepted. Additionally, the Listener status for those listeners SHOULD
157188
// indicate which Listeners are conflicted and not Accepted.
158189
//
159-
// A Gateway's Listeners are considered "compatible" if:
190+
// ## General Listener behavior
191+
//
192+
// Note that, for all distinct Listeners, requests SHOULD match at most one Listener.
193+
// For example, if Listeners are defined for "foo.example.com" and "*.example.com", a
194+
// request to "foo.example.com" SHOULD only be routed using routes attached
195+
// to the "foo.example.com" Listener (and not the "*.example.com" Listener).
196+
//
197+
// This concept is known as "Listener Isolation", and it is an Extended feature
198+
// of Gateway API. Implementations that do not support Listener Isolation MUST
199+
// clearly document this, and MUST NOT claim support for the
200+
// `GatewayHTTPListenerIsolation` feature.
201+
//
202+
// Implementations that _do_ support Listener Isolation SHOULD claim support
203+
// for the Extended `GatewayHTTPListenerIsolation` feature and pass the associated
204+
// conformance tests.
205+
//
206+
// ## Compatible Listeners
207+
//
208+
// A Gateway's Listeners are considered _compatible_ if:
160209
//
161210
// 1. They are distinct.
162211
// 2. The implementation can serve them in compliance with the Addresses
@@ -171,13 +220,6 @@ type GatewaySpec struct {
171220
// on the same address, or cannot mix HTTPS and generic TLS listens on the same port
172221
// would not consider those cases compatible, even though they are distinct.
173222
//
174-
// Note that requests SHOULD match at most one Listener. For example, if
175-
// Listeners are defined for "foo.example.com" and "*.example.com", a
176-
// request to "foo.example.com" SHOULD only be routed using routes attached
177-
// to the "foo.example.com" Listener (and not the "*.example.com" Listener).
178-
// This concept is known as "Listener Isolation". Implementations that do
179-
// not support Listener Isolation MUST clearly document this.
180-
//
181223
// Implementations MAY merge separate Gateways onto a single set of
182224
// Addresses if all Listeners across all Gateways are compatible.
183225
//

0 commit comments

Comments
 (0)