udp: allow configurable max packet size (#15388)

1) Add configuration for max packet size to UDP listeners
2) Add configuration for max packet size to UDP proxy filter
3) Fix crashing issue when a GRO receive is truncated. This
   was fixed in the open because GRO recieve does not support
   IP fragmentation, thus the previous size of 24000 bytes was
   large enough to receive a jumbo frame size datagram. The issue
   is now exposed by allowing packet size to be configured larger.
4) Reorganize code and some config around UDP listeners to streamline
   the logic when the listener is a UDP listener. Also moved the UDP
   batch writer configuration to a better place since it's still
   effectively alpha and was marked not implemented.

Fixes https://github.com/envoyproxy/envoy/issues/15327

Signed-off-by: Matt Klein <mklein@lyft.com>

Mirrored from https://github.com/envoyproxy/envoy @ 73eec645a39343eec33b5d61bf492ba49c397cfe
pull/624/head
data-plane-api(Azure Pipelines) 4 years ago
parent 68a7f300e4
commit cd28fa4ec7
  1. 19
      envoy/config/listener/v3/listener.proto
  2. 2
      envoy/config/listener/v3/listener_components.proto
  3. 8
      envoy/config/listener/v3/quic_config.proto
  4. 6
      envoy/config/listener/v3/udp_gso_batch_writer_config.proto
  5. 41
      envoy/config/listener/v3/udp_listener_config.proto
  6. 19
      envoy/config/listener/v4alpha/listener.proto
  7. 2
      envoy/config/listener/v4alpha/listener_components.proto
  8. 8
      envoy/config/listener/v4alpha/quic_config.proto
  9. 6
      envoy/config/listener/v4alpha/udp_gso_batch_writer_config.proto
  10. 41
      envoy/config/listener/v4alpha/udp_listener_config.proto
  11. 9
      envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.proto
  12. 3
      envoy/extensions/transport_sockets/quic/v3/quic_transport.proto
  13. 3
      envoy/extensions/transport_sockets/quic/v4alpha/quic_transport.proto

@ -5,7 +5,6 @@ package envoy.config.listener.v3;
import "envoy/config/accesslog/v3/accesslog.proto"; import "envoy/config/accesslog/v3/accesslog.proto";
import "envoy/config/core/v3/address.proto"; import "envoy/config/core/v3/address.proto";
import "envoy/config/core/v3/base.proto"; import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto";
import "envoy/config/core/v3/socket_option.proto"; import "envoy/config/core/v3/socket_option.proto";
import "envoy/config/listener/v3/api_listener.proto"; import "envoy/config/listener/v3/api_listener.proto";
import "envoy/config/listener/v3/listener_components.proto"; import "envoy/config/listener/v3/listener_components.proto";
@ -93,7 +92,7 @@ message Listener {
message InternalListenerConfig { message InternalListenerConfig {
} }
reserved 14; reserved 14, 23;
// The unique name by which this listener is known. If no name is provided, // The unique name by which this listener is known. If no name is provided,
// Envoy will allocate an internal UUID for the listener. If the listener is to be dynamically // Envoy will allocate an internal UUID for the listener. If the listener is to be dynamically
@ -216,10 +215,8 @@ message Listener {
// If the protocol in the listener socket address in :ref:`protocol // If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v3.SocketAddress.protocol>` is :ref:`UDP // <envoy_api_field_config.core.v3.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v3.SocketAddress.Protocol.UDP>`, this field specifies the actual udp // <envoy_api_enum_value_config.core.v3.SocketAddress.Protocol.UDP>`, this field specifies UDP
// listener to create, i.e. :ref:`udp_listener_name // listener specific configuration.
// <envoy_api_field_config.listener.v3.UdpListenerConfig.udp_listener_name>` = "raw_udp_listener" for
// creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener".
UdpListenerConfig udp_listener_config = 18; UdpListenerConfig udp_listener_config = 18;
// Used to represent an API listener, which is used in non-proxy clients. The type of API // Used to represent an API listener, which is used in non-proxy clients. The type of API
@ -261,16 +258,6 @@ message Listener {
// emitted by this listener. // emitted by this listener.
repeated accesslog.v3.AccessLog access_log = 22; repeated accesslog.v3.AccessLog access_log = 22;
// If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v3.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v3.SocketAddress.Protocol.UDP>`, this field specifies the actual udp
// writer to create, i.e. :ref:`name <envoy_api_field_config.core.v3.TypedExtensionConfig.name>`
// = "udp_default_writer" for creating a udp writer with writing in passthrough mode,
// = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode.
// If not present, treat it as "udp_default_writer".
// [#not-implemented-hide:]
core.v3.TypedExtensionConfig udp_writer_config = 23;
// The maximum length a tcp listener's pending connections queue can grow to. If no value is // The maximum length a tcp listener's pending connections queue can grow to. If no value is
// provided net.core.somaxconn will be used on Linux and 128 otherwise. // provided net.core.somaxconn will be used on Linux and 128 otherwise.
google.protobuf.UInt32Value tcp_backlog_size = 24; google.protobuf.UInt32Value tcp_backlog_size = 24;

@ -338,7 +338,7 @@ message ListenerFilter {
oneof config_type { oneof config_type {
// Filter specific configuration which depends on the filter being // Filter specific configuration which depends on the filter being
// instantiated. See the supported filters for further documentation. // instantiated. See the supported filters for further documentation.
// [#extension-category: envoy.filters.listener] // [#extension-category: envoy.filters.listener,envoy.filters.udp_listener]
google.protobuf.Any typed_config = 3; google.protobuf.Any typed_config = 3;
} }

@ -15,11 +15,11 @@ option java_outer_classname = "QuicConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE; option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: QUIC listener Config] // [#protodoc-title: QUIC listener config]
// [#extension: envoy.listener.quic] // [#comment:#extension: envoy.udp_listeners.quiche_quic_listener]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Configuration specific to the QUIC protocol. // Configuration specific to the UDP QUIC listener.
// Next id: 5
message QuicProtocolOptions { message QuicProtocolOptions {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.listener.QuicProtocolOptions"; "envoy.api.v2.listener.QuicProtocolOptions";

@ -9,9 +9,11 @@ option java_outer_classname = "UdpGsoBatchWriterConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE; option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Udp Gso Batch Writer Config] // [#protodoc-title: UDP GSO Batch Writer]
// [#comment:#extension: envoy.udp_packet_writers.udp_gso_batch_writer]
// Configuration specific to the UDP GSO Batch Writer.
// [#not-implemented-hide:] // [#not-implemented-hide:]
// Configuration specific to the Udp Gso Batch Writer. // [#comment:TODO(#12829): Remove this as an extension point.]
message UdpGsoBatchWriterOptions { message UdpGsoBatchWriterOptions {
} }

@ -2,38 +2,53 @@ syntax = "proto3";
package envoy.config.listener.v3; package envoy.config.listener.v3;
import "envoy/config/core/v3/extension.proto";
import "google/protobuf/any.proto"; import "google/protobuf/any.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto"; import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v3"; option java_package = "io.envoyproxy.envoy.config.listener.v3";
option java_outer_classname = "UdpListenerConfigProto"; option java_outer_classname = "UdpListenerConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE; option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: UDP Listener Config] // [#protodoc-title: UDP listener config]
// Listener :ref:`configuration overview <config_listeners>` // Listener :ref:`configuration overview <config_listeners>`
// [#next-free-field: 7]
message UdpListenerConfig { message UdpListenerConfig {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.api.v2.listener.UdpListenerConfig"; "envoy.api.v2.listener.UdpListenerConfig";
reserved 2; reserved 1, 2, 3;
reserved "config"; reserved "config";
// Used to look up UDP listener factory, matches "raw_udp_listener" or // Used to create a specific UDP listener factory. If not specified the default UDP listener is
// "quic_listener" to create a specific udp listener. // used.
// If not specified, treat as "raw_udp_listener". // [#comment:#extension-category: envoy.udp_listeners]
string udp_listener_name = 1; // [#not-implemented-hide:]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Used to create a specific listener factory. To some factory, e.g. core.v3.TypedExtensionConfig listener_config = 4;
// "raw_udp_listener", config is not needed.
// [#extension-category: envoy.filters.udp_listener] // The maximum size of received downstream UDP datagrams. Using a larger size will cause Envoy to allocate
oneof config_type { // more memory per listener. Received datagrams above this size will be dropped. If not set
google.protobuf.Any typed_config = 3; // defaults to 1500 bytes.
} google.protobuf.UInt64Value max_downstream_rx_datagram_size = 5
[(validate.rules).uint64 = {lt: 65536 gt: 0}];
// If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v3.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v3.SocketAddress.Protocol.UDP>`, this field specifies the
// actual UDP writer to create. If not specified the default UDP writer is used.
// [#comment:#extension-category: envoy.udp_packet_writers]
// [#not-implemented-hide:]
// [#comment:TODO(#12829): Remove this as an extension point.]
core.v3.TypedExtensionConfig writer_config = 6;
} }
message ActiveRawUdpListenerConfig { message ActiveRawUdpListenerConfig {

@ -5,7 +5,6 @@ package envoy.config.listener.v4alpha;
import "envoy/config/accesslog/v4alpha/accesslog.proto"; import "envoy/config/accesslog/v4alpha/accesslog.proto";
import "envoy/config/core/v4alpha/address.proto"; import "envoy/config/core/v4alpha/address.proto";
import "envoy/config/core/v4alpha/base.proto"; import "envoy/config/core/v4alpha/base.proto";
import "envoy/config/core/v4alpha/extension.proto";
import "envoy/config/core/v4alpha/socket_option.proto"; import "envoy/config/core/v4alpha/socket_option.proto";
import "envoy/config/listener/v4alpha/api_listener.proto"; import "envoy/config/listener/v4alpha/api_listener.proto";
import "envoy/config/listener/v4alpha/listener_components.proto"; import "envoy/config/listener/v4alpha/listener_components.proto";
@ -98,7 +97,7 @@ message Listener {
"envoy.config.listener.v3.Listener.InternalListenerConfig"; "envoy.config.listener.v3.Listener.InternalListenerConfig";
} }
reserved 14, 7; reserved 14, 23, 7;
reserved "deprecated_v1"; reserved "deprecated_v1";
@ -220,10 +219,8 @@ message Listener {
// If the protocol in the listener socket address in :ref:`protocol // If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v4alpha.SocketAddress.protocol>` is :ref:`UDP // <envoy_api_field_config.core.v4alpha.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v4alpha.SocketAddress.Protocol.UDP>`, this field specifies the actual udp // <envoy_api_enum_value_config.core.v4alpha.SocketAddress.Protocol.UDP>`, this field specifies UDP
// listener to create, i.e. :ref:`udp_listener_name // listener specific configuration.
// <envoy_api_field_config.listener.v4alpha.UdpListenerConfig.udp_listener_name>` = "raw_udp_listener" for
// creating a packet-oriented UDP listener. If not present, treat it as "raw_udp_listener".
UdpListenerConfig udp_listener_config = 18; UdpListenerConfig udp_listener_config = 18;
// Used to represent an API listener, which is used in non-proxy clients. The type of API // Used to represent an API listener, which is used in non-proxy clients. The type of API
@ -265,16 +262,6 @@ message Listener {
// emitted by this listener. // emitted by this listener.
repeated accesslog.v4alpha.AccessLog access_log = 22; repeated accesslog.v4alpha.AccessLog access_log = 22;
// If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v4alpha.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v4alpha.SocketAddress.Protocol.UDP>`, this field specifies the actual udp
// writer to create, i.e. :ref:`name <envoy_api_field_config.core.v4alpha.TypedExtensionConfig.name>`
// = "udp_default_writer" for creating a udp writer with writing in passthrough mode,
// = "udp_gso_batch_writer" for creating a udp writer with writing in batch mode.
// If not present, treat it as "udp_default_writer".
// [#not-implemented-hide:]
core.v4alpha.TypedExtensionConfig udp_writer_config = 23;
// The maximum length a tcp listener's pending connections queue can grow to. If no value is // The maximum length a tcp listener's pending connections queue can grow to. If no value is
// provided net.core.somaxconn will be used on Linux and 128 otherwise. // provided net.core.somaxconn will be used on Linux and 128 otherwise.
google.protobuf.UInt32Value tcp_backlog_size = 24; google.protobuf.UInt32Value tcp_backlog_size = 24;

@ -330,7 +330,7 @@ message ListenerFilter {
oneof config_type { oneof config_type {
// Filter specific configuration which depends on the filter being // Filter specific configuration which depends on the filter being
// instantiated. See the supported filters for further documentation. // instantiated. See the supported filters for further documentation.
// [#extension-category: envoy.filters.listener] // [#extension-category: envoy.filters.listener,envoy.filters.udp_listener]
google.protobuf.Any typed_config = 3; google.protobuf.Any typed_config = 3;
} }

@ -15,11 +15,11 @@ option java_outer_classname = "QuicConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: QUIC listener Config] // [#protodoc-title: QUIC listener config]
// [#extension: envoy.listener.quic] // [#comment:#extension: envoy.udp_listeners.quiche_quic_listener]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Configuration specific to the QUIC protocol. // Configuration specific to the UDP QUIC listener.
// Next id: 5
message QuicProtocolOptions { message QuicProtocolOptions {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.listener.v3.QuicProtocolOptions"; "envoy.config.listener.v3.QuicProtocolOptions";

@ -10,10 +10,12 @@ option java_outer_classname = "UdpGsoBatchWriterConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: Udp Gso Batch Writer Config] // [#protodoc-title: UDP GSO Batch Writer]
// [#comment:#extension: envoy.udp_packet_writers.udp_gso_batch_writer]
// Configuration specific to the UDP GSO Batch Writer.
// [#not-implemented-hide:] // [#not-implemented-hide:]
// Configuration specific to the Udp Gso Batch Writer. // [#comment:TODO(#12829): Remove this as an extension point.]
message UdpGsoBatchWriterOptions { message UdpGsoBatchWriterOptions {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.listener.v3.UdpGsoBatchWriterOptions"; "envoy.config.listener.v3.UdpGsoBatchWriterOptions";

@ -2,38 +2,53 @@ syntax = "proto3";
package envoy.config.listener.v4alpha; package envoy.config.listener.v4alpha;
import "envoy/config/core/v4alpha/extension.proto";
import "google/protobuf/any.proto"; import "google/protobuf/any.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto"; import "udpa/annotations/versioning.proto";
import "validate/validate.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v4alpha"; option java_package = "io.envoyproxy.envoy.config.listener.v4alpha";
option java_outer_classname = "UdpListenerConfigProto"; option java_outer_classname = "UdpListenerConfigProto";
option java_multiple_files = true; option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: UDP Listener Config] // [#protodoc-title: UDP listener config]
// Listener :ref:`configuration overview <config_listeners>` // Listener :ref:`configuration overview <config_listeners>`
// [#next-free-field: 7]
message UdpListenerConfig { message UdpListenerConfig {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.listener.v3.UdpListenerConfig"; "envoy.config.listener.v3.UdpListenerConfig";
reserved 2; reserved 1, 2, 3;
reserved "config"; reserved "config";
// Used to look up UDP listener factory, matches "raw_udp_listener" or // Used to create a specific UDP listener factory. If not specified the default UDP listener is
// "quic_listener" to create a specific udp listener. // used.
// If not specified, treat as "raw_udp_listener". // [#comment:#extension-category: envoy.udp_listeners]
string udp_listener_name = 1; // [#not-implemented-hide:]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Used to create a specific listener factory. To some factory, e.g. core.v4alpha.TypedExtensionConfig listener_config = 4;
// "raw_udp_listener", config is not needed.
// [#extension-category: envoy.filters.udp_listener] // The maximum size of received downstream UDP datagrams. Using a larger size will cause Envoy to allocate
oneof config_type { // more memory per listener. Received datagrams above this size will be dropped. If not set
google.protobuf.Any typed_config = 3; // defaults to 1500 bytes.
} google.protobuf.UInt64Value max_downstream_rx_datagram_size = 5
[(validate.rules).uint64 = {lt: 65536 gt: 0}];
// If the protocol in the listener socket address in :ref:`protocol
// <envoy_api_field_config.core.v4alpha.SocketAddress.protocol>` is :ref:`UDP
// <envoy_api_enum_value_config.core.v4alpha.SocketAddress.Protocol.UDP>`, this field specifies the
// actual UDP writer to create. If not specified the default UDP writer is used.
// [#comment:#extension-category: envoy.udp_packet_writers]
// [#not-implemented-hide:]
// [#comment:TODO(#12829): Remove this as an extension point.]
core.v4alpha.TypedExtensionConfig writer_config = 6;
} }
message ActiveRawUdpListenerConfig { message ActiveRawUdpListenerConfig {

@ -3,6 +3,7 @@ syntax = "proto3";
package envoy.extensions.filters.udp.udp_proxy.v3; package envoy.extensions.filters.udp.udp_proxy.v3;
import "google/protobuf/duration.proto"; import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto"; import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto"; import "udpa/annotations/versioning.proto";
@ -18,7 +19,7 @@ option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#extension: envoy.filters.udp_listener.udp_proxy] // [#extension: envoy.filters.udp_listener.udp_proxy]
// Configuration for the UDP proxy filter. // Configuration for the UDP proxy filter.
// [#next-free-field: 6] // [#next-free-field: 7]
message UdpProxyConfig { message UdpProxyConfig {
option (udpa.annotations.versioning).previous_message_type = option (udpa.annotations.versioning).previous_message_type =
"envoy.config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig"; "envoy.config.filter.udp.udp_proxy.v2alpha.UdpProxyConfig";
@ -68,4 +69,10 @@ message UdpProxyConfig {
// load balancing algorithms will select a host randomly. Currently the number of hash policies is // load balancing algorithms will select a host randomly. Currently the number of hash policies is
// limited to 1. // limited to 1.
repeated HashPolicy hash_policies = 5 [(validate.rules).repeated = {max_items: 1}]; repeated HashPolicy hash_policies = 5 [(validate.rules).repeated = {max_items: 1}];
// The maximum size of received upstream UDP datagrams. Using a larger size will cause Envoy to allocate
// more memory per listener. Received datagrams above this size will be dropped. If not set
// defaults to 1500 bytes.
google.protobuf.UInt64Value max_upstream_rx_datagram_size = 6
[(validate.rules).uint64 = {lt: 65536 gt: 0}];
} }

@ -13,7 +13,8 @@ option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE; option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: quic transport] // [#protodoc-title: quic transport]
// [#extension: envoy.transport_sockets.quic] // [#comment:#extension: envoy.transport_sockets.quic]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Configuration for Downstream QUIC transport socket. This provides Google's implementation of Google QUIC and IETF QUIC to Envoy. // Configuration for Downstream QUIC transport socket. This provides Google's implementation of Google QUIC and IETF QUIC to Envoy.
message QuicDownstreamTransport { message QuicDownstreamTransport {

@ -14,7 +14,8 @@ option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE; option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: quic transport] // [#protodoc-title: quic transport]
// [#extension: envoy.transport_sockets.quic] // [#comment:#extension: envoy.transport_sockets.quic]
// [#comment:TODO(#12829): Remove this as an extension point.]
// Configuration for Downstream QUIC transport socket. This provides Google's implementation of Google QUIC and IETF QUIC to Envoy. // Configuration for Downstream QUIC transport socket. This provides Google's implementation of Google QUIC and IETF QUIC to Envoy.
message QuicDownstreamTransport { message QuicDownstreamTransport {

Loading…
Cancel
Save