sigs.k8s.io/gateway-api@v1.0.0/geps/gep-735.md (about)

     1  # GEP-735: TCP and UDP addresses matching
     2  
     3  * Issue: [#735](https://github.com/kubernetes-sigs/gateway-api/issues/735)
     4  * Status: Declined
     5  
     6  ## Notes about declined status
     7  
     8  At one point before the release of `v0.5.0` we did have an implementation
     9  of this GEP in `main`, but we decided to pull back on it for multiple
    10  reasons:
    11  
    12  - operated too much like WAF/firewall functionality, which is not in scope
    13  - no implementations championing the use case
    14  
    15  It should also be noted that the maintainers have at least considered the
    16  idea of an `IPRoute` API which would help differentiate this from firewall
    17  functionality, however there haven't been any strong champions for such a
    18  use case for this either.
    19  
    20  As such this GEP is marked as `Declined` to make it clear to readers that
    21  presently we don't have plans to include this in any future release. Keep
    22  in mind that this doesn't mean that we wouldn't consider it again as a
    23  future feature however: if you're interested in this functionality please
    24  feel free to start a new [github discussion][disc] and/or feel free to
    25  create a new PR updating this GEP with your use case(s) and context.
    26  
    27  [disc]:https://github.com/kubernetes-sigs/gateway-api/discussions
    28  
    29  ## TLDR
    30  
    31  Spec for matching source and destination addresses on L4 APIs.
    32  
    33  ## Goals
    34  
    35  - add matching rules for address to `TCPRoute`
    36  - add matching rules for address to `UDPRoute`
    37  - intentionally avoid type definitions that would make it hard to expand later
    38  
    39  ## Non-Goals
    40  
    41  - define rules for port matching
    42  
    43  ## Introduction
    44  
    45  While `TCPRoute` and `UDPRoute` currently support custom matching extensions,
    46  there is desire among the community to include some "fundamental" matching
    47  options in the spec that cover the most common requirements. In this GEP we
    48  request address matching for these APIs in order to support a standard
    49  for some of the commonplace setups of gateway implementations. Matching is
    50  intended to be covered for both _source_ and _destination_ to enable a finer
    51  level of tuning options for L4 traffic routing at a level below the `Gateway`.
    52  
    53  ## API
    54  
    55  The API changes include the following new types:
    56  
    57  - `AddressMatch` to indicate the IP for address matching
    58  - `AddressRouteMatches` to configure matching according to network address
    59  
    60  These types enable the address matching required, with some active
    61  considerations about how to leave these open ended for later expansion.
    62  
    63  ### AddressMatch Type
    64  
    65  A new `AddressMatch` type provides the targeting mechanism for match inclusion
    66  of a given network address:
    67  
    68  ```go
    69  type AddressMatch struct {
    70  	// Type of the address, either IPAddress or NamedAddress.
    71  	//
    72  	// If NamedAddress is used this is a custom and specific value for each
    73  	// implementation to handle (and add validation for) according to their
    74  	// own needs.
    75  	//
    76  	// For IPAddress the implementor may expect either IPv4 or IPv6.
    77  	//
    78  	// Support: Core (IPAddress)
    79  	// Support: Implementation-specific (NamedAddress)
    80  	//
    81  	// +optional
    82  	// +kubebuilder:validation:Enum=IPAddress;NamedAddress
    83  	// +kubebuilder:default=IPAddress
    84  	Type *AddressType `json:"type,omitempty"`
    85  
    86  	// Value of the address. The validity of the values will depend
    87  	// on the type and support by the controller.
    88  	//
    89  	// If implementations support proxy-protocol (see:
    90  	// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) they
    91  	// must respect the connection metadata from proxy-protocol
    92  	// in the match logic implemented for these address values.
    93  	//
    94  	// Examples: `1.2.3.4`, `128::1`, `my-named-address`.
    95  	//
    96  	// Support: Core
    97  	//
    98  	// +kubebuilder:validation:MinLength=1
    99  	// +kubebuilder:validation:MaxLength=253
   100  	Value string `json:"value"`
   101  }
   102  ```
   103  
   104  ### AddressRouteMatches Type
   105  
   106  Using the new `AddressMatch` type matches can be expressed in topical lists on
   107  `TCPRoute` and `UDPRoute` using the new `AddressRouteMatches` type:
   108  
   109  ```go
   110  type AddressRouteMatches struct {
   111  	// SourceAddresses indicates the originating (source) network
   112  	// addresses which are valid for routing traffic.
   113  	//
   114  	// Support: Core
   115  	SourceAddresses []AddressMatch `json:"sourceAddresses"`
   116  
   117  	// DestinationAddresses indicates the destination network addresses
   118  	// which are valid for routing traffic.
   119  	//
   120  	// Support: Core
   121  	DestinationAddresses []AddressMatch `json:"destinationAddresses"`
   122  }
   123  ```
   124  
   125  This type becomes an optional field and shared by both `TCPRouteRule` and
   126  `UDPRouteRule` as a list:
   127  
   128  ```go
   129  type TCPRouteRule struct {
   130  	// Matches add rules for filtering traffic to backends based on addresses.
   131  	//
   132  	// +optional
   133  	Matches []AddressRouteMatches `json:"matches,omitempty"`
   134  }
   135  ```
   136  
   137  Each element in `[]AddressRouteMatches` should be implemented as an `OR` style
   138  match (e.g. the inbound traffic matches as long as at least one of the separate
   139  `AddressRouteMatches` rules is matched).
   140  
   141  The above would make the following YAML examples possible:
   142  
   143  ```yaml
   144  apiVersion: gateway.networking.k8s.io/v1alpha2
   145  kind: TCPRoute
   146  metadata:
   147    name: matching
   148  spec:
   149    rules:
   150    - matches:
   151      - sourceAddresses:
   152        - value: "192.168.1.1"
   153        - value: "FE80::0202:B3FF:FE1E:8329"
   154        - type: NamedAddress
   155          value: "my-custom-name"
   156        destinationAddresses:
   157        - value: "10.96.0.1"
   158      backendRefs:
   159      - name: my-service
   160        port: 8080
   161  ```
   162  
   163  ## Alternatives
   164  
   165  ### Pure Gateway Mode
   166  
   167  Technically the existing specification supported this kind of matching through
   168  `Gateway` object `Listeners` and it was considered to simply document that
   169  further and expand upon it, but in a desire to better support more complex
   170  setups that are becoming commonplace in the ecosystem (e.g. service mesh) there
   171  was sufficient cause to add this functionality at the route level.
   172  
   173  ### Copying NetworkPolicy
   174  
   175  After the first draft of this document we consulted the `NetworkPolicy` API to
   176  determine if there were enough similarities to copy some of the semantics there
   177  to here. Both the [existing API][k8s-net] and (at the time of writing) the
   178  [upcoming API][pol-new] were reviewed. Ultimately some influence was taken from
   179  `NetworkPolicyPort` to define the `PolicyMatch` structure here, but some ideas
   180  such as binding ports and network addresses together in a single struct did not
   181  seem necessary as the `RuleAction` present in policy did not seem applicable
   182  for this work at the time. We may want to revisit this as the new policy work
   183  merges and matures.
   184  
   185  [k8s-net]:https://github.com/kubernetes/kubernetes/blob/1e6f3b5cd68049a3501782af8ff3ddd647d0b408/pkg/apis/networking/types.go#L95
   186  [pol-new]:https://github.com/kubernetes/enhancements/pull/2522
   187  
   188  ### Port Matching
   189  
   190  While we were able to think of some cases for port matching, the constraints of
   191  listeners for the Gateway make it much harder to understand the value at this
   192  stage. We're deferring port matching to focus on address matching for this
   193  iteration so that we can come back around to it separately once we've gathered
   194  more use case information.
   195  
   196  ### CIDR AddressType
   197  
   198  When using `AddressType` as a component to `AddressMatch` it was considered to
   199  add a new type `CIDRAddress` which would allow matching against an entire
   200  subnet. This sounds good, but given a lack of concrete feedback on an
   201  immediate need for this in the original issue [#727][issue-727] it was decided
   202  that this could wait for now and just as easily be added later in a backwards
   203  compatible manner.
   204  
   205  [issue-727]:https://github.com/kubernetes-sigs/gateway-api/issues/727
   206  
   207  ## References
   208  
   209  A related conversation in [#727][issue-727] ultimately instigated these
   210  new requirements and may be helpful to review.
   211  
   212  [issue-727]:https://github.com/kubernetes-sigs/gateway-api/issues/727