...
1# GEP-957: Destination Port Matching
2
3* Issue: [#957](https://github.com/kubernetes-sigs/gateway-api/issues/957)
4* Status: Experimental
5
6> **Note**: This GEP is exempt from the [Probationary Period][expprob] rules of
7> our GEP overview as it existed before those rules did, and so it has been
8> explicitly grandfathered in.
9
10[expprob]:https://gateway-api.sigs.k8s.io/geps/overview/#probationary-period
11
12## TLDR
13
14Add a new `port` field to ParentRef to support port matching in Routes.
15
16## Goals
17
18* Support port matching in routes based on the destination port number of the
19 request.
20
21## Non-Goals
22
23* Support port matching based on port name.
24
25## Introduction
26
27Port matching is a common service mesh use case where traffic policies/rules
28need to be applied to traffic to certain destination ports. For ingress, while
29the API today already supports attaching a route to a specific listener, it may
30be useful to support attaching routes to listener(s) on a specified port. This
31allows route authors to apply networking behaviors on a fixed port.
32
33## API
34
35The proposal is to add a new field `Port` to `ParentRef`:
36
37```go
38type ParentRef struct {
39 ...
40 // Port is the network port this Route targets. It can be interpreted
41 // differently based on the type of parent resource:
42 //
43 // Gateway: All listeners listening on the specified port that also support
44 // this kind of Route(and select this Route). It's not recommended to set
45 // `Port` unless the networking behaviors specified in a Route must
46 // apply to a specific port as opposed to a listener(s) whose port(s) may
47 // be changed.
48 // When both Port and SectionName are specified, the name and port of the
49 // selected listener must match both specified values.
50 //
51 // Implementations MAY choose to support other parent resources.
52 // Implementations supporting other types of parent resources MUST clearly
53 // document how/if Port is interpreted.
54 //
55 // For the purpose of status, an attachment is considered successful as
56 // long as the parent resource accepts it partially. For example, Gateway
57 // listeners can restrict which Routes can attach to them by Route kind,
58 // namespace, or hostname. If 1 of 2 Gateway listeners accept attachment from
59 // the referencing Route, the Route MUST be considered successfully
60 // attached. If no Gateway listeners accept attachment from this Route, the
61 // Route MUST be considered detached from the Gateway.
62 //
63 // Support: Core
64 //
65 // +optional
66 Port *PortNumber `json:"port,omitempty"`
67 ...
68}
69```
70
71The following example shows how an HTTPRoute could be applied to port 8000. In
72this example, the HTTPRoute will be attached to listeners foo and bar on port
738000 but not listener baz on port 8080.
74```yaml
75kind: HTTPRoute
76metadata:
77 name: example
78 namespace: example
79spec:
80 parentRef:
81 - name: my-gateway
82 port: 8000
83 ...
84---
85kind: Gateway
86metadata:
87 name: my-gateway
88 namespace: example
89spec:
90 listeners:
91 - name: foo
92 port: 8000
93 protocol: HTTP
94 ...
95 - name: bar
96 port: 8000
97 protocol: HTTP
98 ...
99 - name: baz
100 port: 8080
101 ...
102```
103
104The following example shows how a TCPRoute could be attached to an Mesh CRD to
105route all traffic in a service mesh whose original destination port is 8000 to
106port 8080 of service foo.
107```yaml
108kind: TCPRoute
109metadata:
110 name: example
111 namespace: example
112spec:
113 parentRef:
114 - name: my-mesh
115 group: example.io
116 kind: Mesh
117 port: 8000
118 rules:
119 - backendRefs
120 - name: foo
121 port: 8080
122```
123
124## Alternatives
125### 1. Use SectionName in ParentRef for port matching
126Port matching can be supported if SectionName accepts port numbers in addition
127to listener names. This approach results in a less explicit API when a ParentRef
128points to a resource that is not `Gateway`. For example, an implementation may
129attach a route to an `Mesh` CRD. In this case, it's less inituitive to set
130`ParentRef.SectionName` to `443` to express `route all traffic whose destination
131port is 443 to ...`. It also complicates the validation on SectionName in order
132to differentiate between a listener name and a port number.
133
134### 2. Update TrafficMatches to support port matching
135TrafficMatches was proposed in
136[gep-735](https://gateway-api.sigs.k8s.io/geps/gep-735/) to support TCP and UDP
137address matching. TrafficMatches can be extended to support port matching.
138TrafficMatches will need to be added to HTTPRoute/TLSRoute if the feature is
139desired there.
140
141While this proposal works for mesh, it may be confusing for ingress because a
142user can specify port matching behavior in a route that is incompatible with
143the listeners the route attaches to. For example, a user can specify a match
144on port 443 in a route while the route only attaches to a listener on port 80.
View as plain text