Repository: envoyproxy/envoy
File: api/envoy/extensions/filters/network/tcp_proxy/v3/tcp_proxy.proto (Protocol Buffers)

Code before:
  // contains ``PROXY`` protocol state (including any TLVs) parsed by a downstream proxy protocol listener
  // filter, the TLVs specified here are ignored unless ``merge_proxy_protocol_tlvs`` is set to true.
  //
  // .. note::
  //   To ensure the specified TLVs are allowed in the upstream ``PROXY`` protocol header, you must also
  //   configure passthrough TLVs on the upstream proxy protocol transport. See
  //   :ref:`core.v3.ProxyProtocolConfig.pass_through_tlvs <envoy_v3_api_field_config.core.v3.ProxyProtocolConfig.pass_through_tlvs>`
  //   for details.
  repeated config.core.v3.TlvEntry proxy_protocol_tlvs = 19;

  // When set to true and the connection already contains ``PROXY`` protocol state
  // (including TLVs) from a downstream proxy protocol listener filter, the TLVs
  // specified in ``proxy_protocol_tlvs`` are merged with the downstream TLVs.
  //
  // **Precedence behavior**:
  //
  // - TLVs specified in ``proxy_protocol_tlvs`` take precedence over downstream TLVs
  //   with the same type.
  // - This allows adding or overriding specific TLV values while preserving
  //   other downstream TLVs.
  // - The source/destination addresses from the downstream ``PROXY`` protocol state
  //   are preserved (not modified).
  //
  // When set to false (default), the ``proxy_protocol_tlvs`` are ignored if
  // downstream ``PROXY`` protocol state already exists.
  bool merge_proxy_protocol_tlvs = 23;

  // Specifies when to establish the upstream connection.
  //
  // When not specified, defaults to ``IMMEDIATE`` for backward compatibility.
  //
  // .. attention::
  //   Server-first protocols (e.g., SMTP, MySQL, POP3) require ``IMMEDIATE`` mode.
  UpstreamConnectMode upstream_connect_mode = 21 [(validate.rules).enum = {defined_only: true}];

  // Maximum bytes of early data to buffer from the downstream connection before
  // the upstream connection is established.
  //
  // If not set, the TCP proxy will read-disable the downstream connection until the
  // upstream connection is established (legacy behavior).
  //
  // If set, enables ``receive_before_connect`` mode where the filter allows the filter
  // chain to read downstream data before the upstream connection exists. The data is
  // buffered and forwarded once the upstream connection is ready. When the buffer exceeds
  // this limit, the downstream connection is read-disabled to prevent excessive memory usage.
  //
  // This field is required when ``upstream_connect_mode`` is ``ON_DOWNSTREAM_DATA``.
  //
  // .. note::
  //   Use this carefully with server-first protocols. The upstream may send data before
  //   receiving anything from downstream, which could fill the early data buffer.

Review comment (suggestion):
I would suggest calling it `merge_with_downstream_tlvs` to be more clear and also add more info to the docs.

```suggestion
  // Controls whether TLVs specified in ``proxy_protocol_tlvs`` are merged with downstream
  // ``PROXY`` protocol TLVs when downstream ``PROXY`` protocol state already exists.
  //
  // When set to ``true`` and the connection already contains ``PROXY`` protocol state
  // (including TLVs) from a downstream proxy protocol listener filter, the TLVs
  // specified in ``proxy_protocol_tlvs`` are merged with the downstream TLVs.
  //
  // When set to ``false`` (default), the TLVs specified in ``proxy_protocol_tlvs`` are
  // ignored if downstream ``PROXY`` protocol state already exists. In this case, only
  // the downstream TLVs are forwarded to the upstream.
  //
  // **Precedence behavior**:
  //
  // - TLVs specified in ``proxy_protocol_tlvs`` take precedence over downstream TLVs
  //   with the same type. This allows adding or overriding specific TLV values while
  //   preserving other downstream TLVs.
  // - The source/destination addresses from the downstream ``PROXY`` protocol state
  //   are preserved (not modified).
  // - TLVs with types that do not conflict are combined, resulting in a merged set
  //   of TLVs from both sources.
  //
  // .. note::
  //   This field only takes effect when downstream ``PROXY`` protocol state exists.
  //   If the TCP proxy filter is creating new ``PROXY`` protocol state, this field
  //   has no effect and the TLVs specified in ``proxy_protocol_tlvs`` are always
  //   included.
  //
  // .. note::
  //   To ensure the merged TLVs are allowed in the upstream ``PROXY`` protocol header,
  //   you must also configure passthrough TLVs on the upstream proxy protocol transport.
  //   See :ref:`core.v3.ProxyProtocolConfig.pass_through_tlvs <envoy_v3_api_field_config.core.v3.ProxyProtocolConfig.pass_through_tlvs>`
  //   for details.
  bool merge_with_downstream_tlvs = 23;
```

Code after:
  //   <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.TcpAccessLogOptions.access_log_flush_interval>`.
  google.protobuf.Duration access_log_flush_interval = 15 [
    deprecated = true,
    (validate.rules).duration = {gte {nanos: 1000000}},
    (envoy.annotations.deprecated_at_minor_version) = "3.0"
  ];

  // If both this field and :ref:`flush_access_log_on_connected
  // <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.TcpAccessLogOptions.flush_access_log_on_connected>`
  // are specified, the former (deprecated field) is ignored.
  //
  // .. attention::
  //   This field is deprecated in favor of
  //   :ref:`flush_access_log_on_connected
  //   <envoy_v3_api_field_extensions.filters.network.tcp_proxy.v3.TcpProxy.TcpAccessLogOptions.flush_access_log_on_connected>`.
  bool flush_access_log_on_connected = 16
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // Additional access log options for the TCP proxy.
  TcpAccessLogOptions access_log_options = 17;

  // TLVs to add to the PROXY protocol header sent upstream. Behavior when PROXY protocol
  // state already exists (e.g., downstream TLVs from proxy_protocol listener filter) is
  // controlled by ``proxy_protocol_tlv_merge_policy``.
  //
  // .. note::
  //   To ensure the TLVs are allowed upstream, configure passthrough TLVs on the upstream
  //   proxy protocol transport. See :ref:`core.v3.ProxyProtocolConfig.pass_through_tlvs
  //   <envoy_v3_api_field_config.core.v3.ProxyProtocolConfig.pass_through_tlvs>` for details.
  repeated config.core.v3.TlvEntry proxy_protocol_tlvs = 19;

  // Specifies how TLVs in ``proxy_protocol_tlvs`` are merged with existing PROXY protocol state
  // (e.g., downstream TLVs from the proxy_protocol listener filter). See
  // :ref:`ProxyProtocolTlvMergePolicy
  // <envoy_v3_api_enum_extensions.filters.network.tcp_proxy.v3.ProxyProtocolTlvMergePolicy>`.
  ProxyProtocolTlvMergePolicy proxy_protocol_tlv_merge_policy = 23
      [(validate.rules).enum = {defined_only: true}];

  // Specifies when to establish the upstream connection.
  //
  // When not specified, defaults to ``IMMEDIATE`` for backward compatibility.
  //
  // .. attention::
  //   Server-first protocols (e.g., SMTP, MySQL, POP3) require ``IMMEDIATE`` mode.
  UpstreamConnectMode upstream_connect_mode = 21 [(validate.rules).enum = {defined_only: true}];

  // Maximum bytes of early data to buffer from the downstream connection before
  // the upstream connection is established.
  //
  // If not set, the TCP proxy will read-disable the downstream connection until the
  // upstream connection is established (legacy behavior).