Matching Filter Chains in Listeners
Envoy listeners implement the matching API for selecting a filter chain based on a collection of network inputs. Matching is done once per connection. Connections are drained when the associated named filter chain configuration changes, but not when the filter chain matcher is the only updated field in a listener.
The action in the matcher API must be a string value corresponding to the name of the filter chain. If there is no filter chain with the given name, the match fails, and the default filter chain is used if specified, or the connection is rejected. Filter chain matcher requires that all filter chains in a listener are uniquely named.
The matcher API replaces the existing filter filter_chain_match field. When using the matcher API, the filter chain match field is ignored and should not be set.
Examples
Detect TLS traffic
The following examples uses tls_inspector listener filter to detect
whether the transport appears to be TLS, in which case the matcher in the listener selects the filter chain tls.
Otherwise, the filter chain plaintext is used.
    filter_chain_matcher:
      matcher_tree:
        input:
          name: transport
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.TransportProtocolInput
        exact_match_map:
          map:
            "tls":
              action:
                name: tls
                typed_config:
                  "@type": type.googleapis.com/google.protobuf.StringValue
                  value: tls
      on_no_match:
        action:
          name: plaintext
          typed_config:
            "@type": type.googleapis.com/google.protobuf.StringValue
            value: plaintext
Match Against the Destination IP
The following example assumes PROXY protocol is used for incoming
traffic. If the recovered destination IP is in CIDR 10.0.0.0/24, then the filter chain vip is used. Otherwise,
the filter chain default is used.
    filter_chain_matcher:
      matcher_tree:
        input:
          name: destination_ip
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DestinationIPInput
        prefix_match_map:
          map:
            "10.0.0.":
              action:
                name: vip
                typed_config:
                  "@type": type.googleapis.com/google.protobuf.StringValue
                  value: vip
      on_no_match:
        action:
          name: default
          typed_config:
            "@type": type.googleapis.com/google.protobuf.StringValue
            value: default
Match Against the Destination Port and the Source IP
The following example uses original_dst listener filter to recover the
original destination port. The matcher in the listener selects one of the three filter chains http, internal,
and tls as follows:
- If the destination port is - 80, then the filter chain- httpaccepts the connection.
- If the destination port is - 443and the source IP is in the range- 192.0.0.0/2or- 10.0.0.0/24, then the filter chain- internalaccepts the connection. If the source IP is not in the ranges then the filter chain- tlsaccepts the connection.
- Otherwise, the connection is rejected, because there is no default filter chain. 
    filter_chain_matcher:
      matcher_tree:
        input:
          name: port
          typed_config:
            "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.DestinationPortInput
        exact_match_map:
          map:
            "80":
              action:
                name: http
                typed_config:
                  "@type": type.googleapis.com/google.protobuf.StringValue
                  value: http
            "443":
              matcher:
                matcher_tree:
                  input:
                    name: ip
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.matching.common_inputs.network.v3.SourceIPInput
                  custom_match:
                    name: ip-matcher
                    typed_config:
                      "@type": type.googleapis.com/xds.type.matcher.v3.IPMatcher
                      range_matchers:
                      - ranges:
                        - address_prefix: 192.0.0.0
                          prefix_len: 2
                        - address_prefix: 10.0.0.0
                          prefix_len: 24
                        on_match:
                          action:
                            name: internal
                            typed_config:
                              "@type": type.googleapis.com/google.protobuf.StringValue
                              value: internal
                      - ranges:
                        - address_prefix: 0.0.0.0
                        on_match:
                          action:
                            name: tls
                            typed_config:
                              "@type": type.googleapis.com/google.protobuf.StringValue
                              value: tls