udp: write performance improvement via udp_gso (#12219)

Introduces UdpPacketWriter Interface that can be used to perform writes in Batched/PassThrough modes by using QuicGsoBatchWriter implementation from QUICHE extension.

**Additional Description:**
UDP GSO (Generic Segmentation Offload) was introduced in Linux at version 4.18. It allows batch-writing of multiple messages into a single payload and sending these messages along as a batch in a single sendmsg syscall.
Currently, Envoy performs the sending of messages using simple sendmsg implementation in pass-through mode, i.e. no support for batch writing. With this change, UdpListener can use UdpPacketWriter interface as a DefaultWriter or a GsoBatchWriter to perform pass-through or batched writes respectively.
Detailed description of the changes can be found in the design document, [here](https://docs.google.com/document/d/16ePbgkfrzQ6v-cOVMSnKDja3dUdZvX-mxT9jw29rx4g/edit?usp=sharing).

**Risk Level:** Low, not in use
**Testing:**
- Added udp_listener_impl_batched_writes_test, to verify that multiple packets of varying sizes are batched/flushed as per gso specifications while using UdpGsoBatchWriter.
- Modified existing tests, to verify that UdpDefaultWriter performs writes in pass-through mode.
- Ran all tests. All 677 tests passed successfully.
```

**Docs Changes:** None
**Release Notes:** None
**Fixes:** #11925

Signed-off-by: Yugant <yugant@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 933e267db60961e76549ae6e65ac4872cb78db4d
master-ci-test
data-plane-api(CircleCI) 4 years ago
parent c6d5ae2875
commit 66443ebd3b
  1. 13
      envoy/config/listener/v3/listener.proto
  2. 21
      envoy/config/listener/v3/udp_default_writer_config.proto
  3. 21
      envoy/config/listener/v3/udp_gso_batch_writer_config.proto
  4. 13
      envoy/config/listener/v4alpha/listener.proto
  5. 23
      envoy/config/listener/v4alpha/udp_default_writer_config.proto
  6. 23
      envoy/config/listener/v4alpha/udp_gso_batch_writer_config.proto

@ -5,6 +5,7 @@ package envoy.config.listener.v3;
import "envoy/config/accesslog/v3/accesslog.proto";
import "envoy/config/core/v3/address.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/listener/v3/api_listener.proto";
import "envoy/config/listener/v3/listener_components.proto";
@ -35,7 +36,7 @@ message ListenerCollection {
udpa.core.v1.CollectionEntry entries = 1;
}
// [#next-free-field: 23]
// [#next-free-field: 24]
message Listener {
option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Listener";
@ -248,4 +249,14 @@ message Listener {
// Configuration for :ref:`access logs <arch_overview_access_logs>`
// emitted by this listener.
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;
}

@ -0,0 +1,21 @@
syntax = "proto3";
package envoy.config.listener.v3;
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v3";
option java_outer_classname = "UdpDefaultWriterConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Udp Default Writer Config]
// [#not-implemented-hide:]
// Configuration specific to the Udp Default Writer.
message UdpDefaultWriterOptions {
}

@ -0,0 +1,21 @@
syntax = "proto3";
package envoy.config.listener.v3;
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v3";
option java_outer_classname = "UdpGsoBatchWriterConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = ACTIVE;
// [#protodoc-title: Udp Gso Batch Writer Config]
// [#not-implemented-hide:]
// Configuration specific to the Udp Gso Batch Writer.
message UdpGsoBatchWriterOptions {
}

@ -5,6 +5,7 @@ package envoy.config.listener.v4alpha;
import "envoy/config/accesslog/v4alpha/accesslog.proto";
import "envoy/config/core/v4alpha/address.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/listener/v4alpha/api_listener.proto";
import "envoy/config/listener/v4alpha/listener_components.proto";
@ -38,7 +39,7 @@ message ListenerCollection {
udpa.core.v1.CollectionEntry entries = 1;
}
// [#next-free-field: 23]
// [#next-free-field: 24]
message Listener {
option (udpa.annotations.versioning).previous_message_type = "envoy.config.listener.v3.Listener";
@ -251,4 +252,14 @@ message Listener {
// Configuration for :ref:`access logs <arch_overview_access_logs>`
// emitted by this listener.
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;
}

@ -0,0 +1,23 @@
syntax = "proto3";
package envoy.config.listener.v4alpha;
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v4alpha";
option java_outer_classname = "UdpDefaultWriterConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: Udp Default Writer Config]
// [#not-implemented-hide:]
// Configuration specific to the Udp Default Writer.
message UdpDefaultWriterOptions {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.listener.v3.UdpDefaultWriterOptions";
}

@ -0,0 +1,23 @@
syntax = "proto3";
package envoy.config.listener.v4alpha;
import "google/protobuf/duration.proto";
import "google/protobuf/wrappers.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
option java_package = "io.envoyproxy.envoy.config.listener.v4alpha";
option java_outer_classname = "UdpGsoBatchWriterConfigProto";
option java_multiple_files = true;
option (udpa.annotations.file_status).package_version_status = NEXT_MAJOR_VERSION_CANDIDATE;
// [#protodoc-title: Udp Gso Batch Writer Config]
// [#not-implemented-hide:]
// Configuration specific to the Udp Gso Batch Writer.
message UdpGsoBatchWriterOptions {
option (udpa.annotations.versioning).previous_message_type =
"envoy.config.listener.v3.UdpGsoBatchWriterOptions";
}
Loading…
Cancel
Save