Skip to content

Need a way to set socket options for replies to individual down-streams of listeners #38208

@VivekSubr

Description

@VivekSubr

Need a way to set socket options for replies to individual down-streams of listeners

Description:
We have a requirement to set dscp socket option for traffic outbound from istio gateway, we are able to set for outbound traffic using cluster names, as follows ->

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
spec:
  configPatches:
  - applyTo: CLUSTER
    match:
      cluster:
        name: outbound|80||testcluster
    patch:
      operation: MERGE
      value:
        upstream_bind_config:
          socket_options:
          - int_value: 64
            level: 0
            name: 1
            state: STATE_PREBIND
          source_address:
            address: 0.0.0.0
            port_value: 0

However, how to do this for replies to downstream? (HTTP replies in our case) There's no cluster names for that, it's only possible to set one socket_options once for listener.

We've been working around that by patching envoy to read dscp value from http header for replies,

diff -urNp envoy/source/common/router/router.cc envoy-patched/source/common/router/router.cc
--- envoy/source/common/router/router.cc	2024-11-26 13:27:07.779636678 +0000
+++ envoy-patched/source/common/router/router.cc	2025-01-10 09:19:59.583055171 +0000

@@ -1685,6 +1687,41 @@ void Filter::onUpstreamHeaders(uint64_t
   // provide finalizeResponseHeaders functions on the Router::Config and VirtualHost interfaces.
   route_entry_->finalizeResponseHeaders(*headers, callbacks_->streamInfo());
 
+  static constexpr const char* dscpHeaderStr = "x-differentiated-services-code-point";
+  static const Http::LowerCaseString s_dscpHdrStr(dscpHeaderStr);
+  auto getResult = headers->get(s_dscpHdrStr);
+  if (!getResult.empty())
+  {
+    uint64_t dscp = 0;
+    if (absl::SimpleAtoi(getResult[0]->value().getStringView(), &dscp)) {
+      auto connection = const_cast<Network::Connection*>(callbacks_->connection().ptr());
+
+      dscp = (dscp << 2);
+      std::unique_ptr<Network::Socket::Options> options = std::make_unique<Network::Socket::Options>();
+      options->push_back(std::make_shared<Network::AddrFamilyAwareSocketOptionImpl>(
+        envoy::config::core::v3::SocketOption::STATE_PREBIND,
+        ENVOY_SOCKET_IP_TOS,
+        ENVOY_SOCKET_IPV6_TCLASS,
+        dscp));
+
+      dynamic_cast<Network::ConnectionImpl*>(connection)->setSocketOptions(std::move(options),
+                                   envoy::config::core::v3::SocketOption::STATE_PREBIND);
+    }
+    headers->remove(s_dscpHdrStr);
+  }

We wanted to know ->

  • Is there any way to configure socket_options for connections made by listener to different downstreams?
  • If not, would it okay to implement this in a filter? Perhaps a http filter that does something like the above code snippet?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementFeature requests. Not bugs or questions.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions