diff --git a/api/BUILD b/api/BUILD
index d8cffd4a48..59fc00be5e 100644
--- a/api/BUILD
+++ b/api/BUILD
@@ -57,6 +57,7 @@ proto_library(
     name = "v3_protos",
     visibility = ["//visibility:public"],
     deps = [
+        "//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg",
         "//contrib/envoy/extensions/filters/http/squash/v3:pkg",
         "//contrib/envoy/extensions/filters/http/sxg/v3alpha:pkg",
         "//contrib/envoy/extensions/filters/network/kafka_broker/v3:pkg",
diff --git a/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/BUILD b/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/BUILD
new file mode 100644
index 0000000000..1c1a6f6b44
--- /dev/null
+++ b/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/BUILD
@@ -0,0 +1,12 @@
+# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
+
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_package(
+    deps = [
+        "//envoy/config/core/v3:pkg",
+        "@com_github_cncf_udpa//udpa/annotations:pkg",
+    ],
+)
diff --git a/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.proto b/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.proto
new file mode 100644
index 0000000000..b02031704c
--- /dev/null
+++ b/api/contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.proto
@@ -0,0 +1,31 @@
+syntax = "proto3";
+
+package envoy.extensions.custom_cluster_plugins.cluster_fallback.v3;
+
+import "udpa/annotations/sensitive.proto";
+import "udpa/annotations/status.proto";
+import "validate/validate.proto";
+
+option java_package = "io.envoyproxy.envoy.extensions.custom_cluster_plugins.cluster_fallback.v3";
+option java_outer_classname = "ClusterfallbackProto";
+option java_multiple_files = true;
+option (udpa.annotations.file_status).package_version_status = ACTIVE;
+
+message ClusterFallbackConfig {
+
+  message ClusterConfig {
+    string routing_cluster = 1;
+
+    repeated string fallback_clusters = 2;
+  }
+
+  message WeightedClusterConfig {
+    repeated ClusterConfig config = 1;
+  }
+
+  oneof config_specifier {
+    ClusterConfig cluster_config = 1;
+
+    WeightedClusterConfig weighted_cluster_config = 2;
+  }
+}
diff --git a/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/BUILD b/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/BUILD
new file mode 100644
index 0000000000..ee92fb6525
--- /dev/null
+++ b/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/BUILD
@@ -0,0 +1,9 @@
+# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
+
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_package(
+    deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"],
+)
diff --git a/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.proto b/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.proto
new file mode 100644
index 0000000000..400fa0f4c2
--- /dev/null
+++ b/api/contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.proto
@@ -0,0 +1,119 @@
+syntax = "proto3";
+
+package envoy.extensions.filters.http.http_dubbo_transcoder.v3;
+
+import "google/protobuf/wrappers.proto";
+
+import "udpa/annotations/status.proto";
+import "udpa/annotations/versioning.proto";
+import "validate/validate.proto";
+
+option java_package = "io.envoyproxy.envoy.extensions.filters.http.http_dubbo_transcoder.v3";
+option java_outer_classname = "HttpDubboTranscoderProto";
+option java_multiple_files = true;
+option (udpa.annotations.file_status).package_version_status = ACTIVE;
+
+// [#protodoc-title: Buffer]
+// Buffer :ref:`configuration overview <config_http_filters_buffer>`.
+// [#extension: envoy.filters.http.buffer]
+message HttpDubboTranscoder {
+  enum UrlUnescapeSpec {
+    // URL path parameters will not decode RFC 6570 reserved characters.
+    // For example, segment `%2f%23/%20%2523` is unescaped to `%2f%23/ %23`.
+    ALL_CHARACTERS_EXCEPT_RESERVED = 0;
+
+    // URL path parameters will be fully URI-decoded except in
+    // cases of single segment matches in reserved expansion, where "%2F" will be
+    // left encoded.
+    // For example, segment `%2f%23/%20%2523` is unescaped to `%2f#/ %23`.
+    ALL_CHARACTERS_EXCEPT_SLASH = 1;
+
+    // URL path parameters will be fully URI-decoded.
+    // For example, segment `%2f%23/%20%2523` is unescaped to `/#/ %23`.
+    ALL_CHARACTERS = 2;
+  }
+
+  message RequestValidateOptions {
+    // default this trascoder will pass the request which contains unknown query paramters,
+    // if this option set to true, the request will be reject with 400 Bad Request.
+    bool reject_unknown_query_parameters = 1;
+
+    bool reject_unknown_method = 2;
+  }
+
+  message DubboMethodMapping {
+    enum MatchHttpMethodSpec {
+      ALL_GET = 0;
+      ALL_POST = 1;
+      ALL_PUT = 2;
+      ALL_DELETE = 3;
+      ALL_PATCH = 4;
+    }
+
+    message ParameterMapping {
+      enum ExtractKeySpec {
+        ALL_QUERY_PARAMETER = 0;
+        ALL_HEADER = 1;
+        ALL_PATH = 2;
+        ALL_BODY = 3;
+      }
+
+      ExtractKeySpec extract_key_spec = 1;
+
+      string extract_key = 2;
+
+      string mapping_type = 3;
+    }
+
+    message PathMatcher {
+      string match_pattern = 1;
+
+      MatchHttpMethodSpec match_http_method_spec = 2;
+    }
+
+    message PassthroughSetting {
+      message PassthroughHeaders {
+        repeated string keys = 1;
+      }
+
+      oneof headers_setting {
+        bool passthrough_all_headers = 1;
+
+        PassthroughHeaders passthrough_headers = 2;
+      }
+    }
+
+    string name = 1 [(validate.rules).string = {min_len: 1}];
+
+    PathMatcher path_matcher = 2;
+
+    repeated ParameterMapping parameter_mapping = 3;
+
+    PassthroughSetting passthrough_setting = 4;
+  }
+
+  message DubboServiceMapping {
+    string name = 1 [(validate.rules).string = {min_len: 1}];
+
+    string version = 2;
+
+    repeated DubboMethodMapping method_mapping = 3;
+
+    string group = 4;
+  }
+
+  // Configure the behavior when handling requests that cannot be transcoded.
+  //
+  // By default, the transcoder will silently pass through HTTP requests that are malformed.
+  // This includes requests with unknown query parameters, unregister paths, etc.
+  RequestValidateOptions request_validation_options = 2;
+
+  // URL unescaping policy.
+  // This spec is only applied when extracting variable with multiple segments in the URL path.
+  // For example, in case of `/foo/{x=*}/bar/{y=prefix/*}/{z=**}` `x` variable is single segment and `y` and `z` are multiple segments.
+  // For a path with `/foo/first/bar/prefix/second/third/fourth`, `x=first`, `y=prefix/second`, `z=third/fourth`.
+  // If this setting is not specified, the value defaults to :ref:`ALL_CHARACTERS_EXCEPT_RESERVED<envoy_v3_api_enum_value_extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder.UrlUnescapeSpec.ALL_CHARACTERS_EXCEPT_RESERVED>`.
+  UrlUnescapeSpec url_unescape_spec = 3 [(validate.rules).enum = {defined_only: true}];
+
+  repeated DubboServiceMapping services_mapping = 4;
+}
diff --git a/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/BUILD b/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/BUILD
new file mode 100644
index 0000000000..ee92fb6525
--- /dev/null
+++ b/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/BUILD
@@ -0,0 +1,9 @@
+# DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py.
+
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_package(
+    deps = ["@com_github_cncf_udpa//udpa/annotations:pkg"],
+)
diff --git a/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/tcp_connection_pool.proto b/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/tcp_connection_pool.proto
new file mode 100644
index 0000000000..6adc905f6e
--- /dev/null
+++ b/api/contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/tcp_connection_pool.proto
@@ -0,0 +1,17 @@
+syntax = "proto3";
+
+package envoy.extensions.upstreams.http.dubbo_tcp.v3;
+
+import "udpa/annotations/status.proto";
+
+option java_package = "io.envoyproxy.envoy.extensions.upstreams.http.dubbo_tcp.v3";
+option java_outer_classname = "TcpConnectionPoolProto";
+option java_multiple_files = true;
+option (udpa.annotations.file_status).package_version_status = ACTIVE;
+
+// [#protodoc-title: Tcp Connection Pool]
+
+// A connection pool which forwards downstream HTTP as TCP to upstream,
+// [#extension: envoy.upstreams.http.tcp]
+message DubboTcpConnectionPoolProto {
+}
diff --git a/api/envoy/config/route/v3/route.proto b/api/envoy/config/route/v3/route.proto
index e2bf52165b..3e806eeb57 100644
--- a/api/envoy/config/route/v3/route.proto
+++ b/api/envoy/config/route/v3/route.proto
@@ -4,7 +4,6 @@ package envoy.config.route.v3;
 
 import "envoy/config/core/v3/base.proto";
 import "envoy/config/core/v3/config_source.proto";
-import "envoy/config/core/v3/extension.proto";
 import "envoy/config/route/v3/route_components.proto";
 
 import "google/protobuf/wrappers.proto";
@@ -121,19 +120,12 @@ message RouteConfiguration {
   //
   google.protobuf.UInt32Value max_direct_response_body_size_bytes = 11;
 
-  // [#not-implemented-hide:]
   // A list of plugins and their configurations which may be used by a
-  // :ref:`envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin`
+  // :ref:`cluster specifier plugin name <envoy_v3_api_field_config.route.v3.RouteAction.cluster_specifier_plugin>`
   // within the route. All *extension.name* fields in this list must be unique.
   repeated ClusterSpecifierPlugin cluster_specifier_plugins = 12;
 }
 
-// Configuration for a cluster specifier plugin.
-message ClusterSpecifierPlugin {
-  // The name of the plugin and its opaque configuration.
-  core.v3.TypedExtensionConfig extension = 1;
-}
-
 message Vhds {
   option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.Vhds";
 
diff --git a/api/envoy/config/route/v3/route_components.proto b/api/envoy/config/route/v3/route_components.proto
index d25edd756d..80da2bdcef 100644
--- a/api/envoy/config/route/v3/route_components.proto
+++ b/api/envoy/config/route/v3/route_components.proto
@@ -203,7 +203,7 @@ message FilterAction {
 //
 //   Envoy supports routing on HTTP method via :ref:`header matching
 //   <envoy_v3_api_msg_config.route.v3.HeaderMatcher>`.
-// [#next-free-field: 19]
+// [#next-free-field: 20]
 message Route {
   option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.Route";
 
@@ -301,6 +301,21 @@ message Route {
   // If set, the bytes actually buffered will be the minimum value of this and the
   // listener per_connection_buffer_limit_bytes.
   google.protobuf.UInt32Value per_request_buffer_limit_bytes = 16;
+
+  // The human readable prefix to use when emitting statistics for this endpoint.
+  // The statistics are rooted at vhost.<virtual host name>.route.<stat_prefix>.
+  // This should be set for highly critical
+  // endpoints that one wishes to get “per-route” statistics on.
+  // If not set, endpoint statistics are not generated.
+  //
+  // The emitted statistics are the same as those documented for :ref:`virtual clusters <config_http_filters_router_vcluster_stats>`.
+  //
+  // .. warning::
+  //
+  //    We do not recommend setting up a stat prefix for
+  //    every application endpoint. This is both not easily maintainable and
+  //    statistics use a non-trivial amount of memory(approximately 1KiB per route).
+  string stat_prefix = 19;
 }
 
 // Compared to the :ref:`cluster <envoy_v3_api_field_config.route.v3.RouteAction.cluster>` field that specifies a
@@ -426,9 +441,32 @@ message WeightedCluster {
   // configuration file will be used as the default weight. See the :ref:`runtime documentation
   // <operations_runtime>` for how key names map to the underlying implementation.
   string runtime_key_prefix = 2;
+
+  // Name of the cluster specifier plugin to use to determine the cluster for requests on this route.
+  // The cluster specifier plugin name must be defined in the associated
+  // :ref:`cluster specifier plugins <envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins>`
+  // in the :ref:`name <envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name>` field.
+  string cluster_specifier_plugin = 100;
+
+  // Custom cluster specifier plugin configuration to use to determine the cluster for requests
+  // on this route.
+  ClusterSpecifierPlugin inline_cluster_specifier_plugin = 101;
 }
 
-// [#next-free-field: 14]
+// Configuration for a cluster specifier plugin.
+message ClusterSpecifierPlugin {
+  // The name of the plugin and its opaque configuration.
+  core.v3.TypedExtensionConfig extension = 1 [(validate.rules).message = {required: true}];
+
+  // If is_optional is not set or is set to false and the plugin defined by this message is not a
+  // supported type, the containing resource is NACKed. If is_optional is set to true, the resource
+  // would not be NACKed for this reason. In this case, routes referencing this plugin's name would
+  // not be treated as an illegal configuration, but would result in a failure if the route is
+  // selected.
+  bool is_optional = 2;
+}
+
+// [#next-free-field: 15]
 message RouteMatch {
   option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteMatch";
 
@@ -607,7 +645,7 @@ message CorsPolicy {
   core.v3.RuntimeFractionalPercent shadow_enabled = 10;
 }
 
-// [#next-free-field: 38]
+// [#next-free-field: 40]
 message RouteAction {
   option (udpa.annotations.versioning).previous_message_type = "envoy.api.v2.route.RouteAction";
 
@@ -884,13 +922,15 @@ message RouteAction {
     // for additional documentation.
     WeightedCluster weighted_clusters = 3;
 
-    // [#not-implemented-hide:]
-    // Name of the cluster specifier plugin to use to determine the cluster for
-    // requests on this route. The plugin name must be defined in the associated
-    // :ref:`envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins`
-    // in the
-    // :ref:`envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name` field.
+    // Name of the cluster specifier plugin to use to determine the cluster for requests on this route.
+    // The cluster specifier plugin name must be defined in the associated
+    // :ref:`cluster specifier plugins <envoy_v3_api_field_config.route.v3.RouteConfiguration.cluster_specifier_plugins>`
+    // in the :ref:`name <envoy_v3_api_field_config.core.v3.TypedExtensionConfig.name>` field.
     string cluster_specifier_plugin = 37;
+
+    // Custom cluster specifier plugin configuration to use to determine the cluster for requests
+    // on this route.
+    ClusterSpecifierPlugin inline_cluster_specifier_plugin = 39;
   }
 
   // The HTTP status code to use when configured cluster is not found.
@@ -971,20 +1011,29 @@ message RouteAction {
 
   oneof host_rewrite_specifier {
     // Indicates that during forwarding, the host header will be swapped with
-    // this value.
+    // this value. Using this option will append the
+    // :ref:`config_http_conn_man_headers_x-forwarded-host` header if
+    // :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
+    // is set.
     string host_rewrite_literal = 6
         [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];
 
     // Indicates that during forwarding, the host header will be swapped with
     // the hostname of the upstream host chosen by the cluster manager. This
     // option is applicable only when the destination cluster for a route is of
-    // type *strict_dns* or *logical_dns*. Setting this to true with other cluster
-    // types has no effect.
+    // type *strict_dns* or *logical_dns*. Setting this to true with other cluster types
+    // has no effect. Using this option will append the
+    // :ref:`config_http_conn_man_headers_x-forwarded-host` header if
+    // :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
+    // is set.
     google.protobuf.BoolValue auto_host_rewrite = 7;
 
     // Indicates that during forwarding, the host header will be swapped with the content of given
     // downstream or :ref:`custom <config_http_conn_man_headers_custom_request_headers>` header.
-    // If header value is empty, host header is left intact.
+    // If header value is empty, host header is left intact. Using this option will append the
+    // :ref:`config_http_conn_man_headers_x-forwarded-host` header if
+    // :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
+    // is set.
     //
     // .. attention::
     //
@@ -1000,6 +1049,10 @@ message RouteAction {
     // Indicates that during forwarding, the host header will be swapped with
     // the result of the regex substitution executed on path value with query and fragment removed.
     // This is useful for transitioning variable content between path segment and subdomain.
+    // Using this option will append the
+    // :ref:`config_http_conn_man_headers_x-forwarded-host` header if
+    // :ref:`append_x_forwarded_host <envoy_v3_api_field_config.route.v3.RouteAction.append_x_forwarded_host>`
+    // is set.
     //
     // For example with the following config:
     //
@@ -1015,6 +1068,15 @@ message RouteAction {
     type.matcher.v3.RegexMatchAndSubstitute host_rewrite_path_regex = 35;
   }
 
+  // If set, then a host rewrite action (one of
+  // :ref:`host_rewrite_literal <envoy_v3_api_field_config.route.v3.RouteAction.host_rewrite_literal>`,
+  // :ref:`auto_host_rewrite <envoy_v3_api_field_config.route.v3.RouteAction.auto_host_rewrite>`,
+  // :ref:`host_rewrite_header <envoy_v3_api_field_config.route.v3.RouteAction.host_rewrite_header>`, or
+  // :ref:`host_rewrite_path_regex <envoy_v3_api_field_config.route.v3.RouteAction.host_rewrite_path_regex>`)
+  // causes the original value of the host header, if any, to be appended to the
+  // :ref:`config_http_conn_man_headers_x-forwarded-host` HTTP header.
+  bool append_x_forwarded_host = 38;
+
   // Specifies the upstream timeout for the route. If not specified, the default is 15s. This
   // spans between the point at which the entire downstream request (i.e. end-of-stream) has been
   // processed and when the upstream response has been completely processed. A value of 0 will
@@ -1169,6 +1231,8 @@ message RouteAction {
 
   // Specifies the maximum stream duration for this route.
   MaxStreamDuration max_stream_duration = 36;
+
+  InternalActiveRedirectPolicy internal_active_redirect_policy = 1000;
 }
 
 // HTTP retry :ref:`architecture overview <arch_overview_http_routing_retry>`.
@@ -2076,6 +2140,109 @@ message InternalRedirectPolicy {
   bool allow_cross_scheme_redirect = 4;
 }
 
+// Redirects to the specified URI based on the response code.
+// [#next-free-field: 19]
+message InternalActiveRedirectPolicy {
+  // [#next-free-field: 18]
+  message RedirectPolicy {
+    // An internal redirect is not handled, unless the number of previous internal redirects that a
+    // downstream request has encountered is lower than this value.
+    // In the case where a downstream request is bounced among multiple routes by internal redirect,
+    // the first route that hits this threshold, or does not set :ref:`internal_redirect_policy
+    // <envoy_api_field_config.route.v4alpha.RouteAction.internal_redirect_policy>`
+    // will pass the redirect back to downstream.
+    //
+    // If not specified, at most one redirect will be followed.
+    google.protobuf.UInt32Value max_internal_redirects = 10;
+
+    // Defines what upstream response codes are allowed to trigger internal redirect.
+    // All response codes support redirection except 200.
+    repeated uint32 redirect_response_codes = 11 [(validate.rules).repeated = {max_items: 50}];
+
+    // The URI of the redirect.
+    oneof redirect_url_rewrite_specifier {
+      option (validate.required) = true;
+
+      string redirect_url = 12 [(validate.rules).string = {min_len: 1}];
+
+      type.matcher.v3.RegexMatchAndSubstitute redirect_url_rewrite_regex = 13;
+    }
+
+    // Specifies a list of predicates that are queried when an upstream response is deemed
+    // to trigger an internal redirect by all other criteria. Any predicate in the list can reject
+    // the redirect, causing the response to be proxied to downstream.
+    repeated core.v3.TypedExtensionConfig predicates = 14;
+
+    // Allow internal redirect to follow a target URI with a different scheme than the value of
+    // x-forwarded-proto. The default is false.
+    bool allow_cross_scheme_redirect = 15;
+
+    // HTTP headers to add to a local reply. This allows the response mapper to append, to add
+    // or to override headers of any local reply before it is sent to a downstream client.
+    repeated core.v3.HeaderValueOption request_headers_to_add = 16
+        [(validate.rules).repeated = {max_items: 1000}];
+
+    // Indicates that during forwarding, the host header will be swapped with
+    // this value.
+    string host_rewrite_literal = 17
+        [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];
+
+    // If true, the host name in the downstream request is used for redirection.
+    bool forced_use_original_host = 20;
+
+    bool forced_add_header_before_route_matcher = 22;
+  }
+
+  // An internal redirect is not handled, unless the number of previous internal redirects that a
+  // downstream request has encountered is lower than this value.
+  // In the case where a downstream request is bounced among multiple routes by internal redirect,
+  // the first route that hits this threshold, or does not set :ref:`internal_redirect_policy
+  // <envoy_api_field_config.route.v4alpha.RouteAction.internal_redirect_policy>`
+  // will pass the redirect back to downstream.
+  //
+  // If not specified, at most one redirect will be followed.
+  google.protobuf.UInt32Value max_internal_redirects = 1;
+
+  // Defines what upstream response codes are allowed to trigger internal redirect.
+  // All response codes support redirection except 200.
+  repeated uint32 redirect_response_codes = 2 [(validate.rules).repeated = {max_items: 50}];
+
+  // The URI of the redirect.
+  oneof redirect_url_rewrite_specifier {
+    //option (validate.required) = true;
+
+    string redirect_url = 7 [(validate.rules).string = {min_len: 1}];
+
+    type.matcher.v3.RegexMatchAndSubstitute redirect_url_rewrite_regex = 8;
+  }
+
+  // Specifies a list of predicates that are queried when an upstream response is deemed
+  // to trigger an internal redirect by all other criteria. Any predicate in the list can reject
+  // the redirect, causing the response to be proxied to downstream.
+  repeated core.v3.TypedExtensionConfig predicates = 4;
+
+  // Allow internal redirect to follow a target URI with a different scheme than the value of
+  // x-forwarded-proto. The default is false.
+  bool allow_cross_scheme_redirect = 5;
+
+  // HTTP headers to add to a local reply. This allows the response mapper to append, to add
+  // or to override headers of any local reply before it is sent to a downstream client.
+  repeated core.v3.HeaderValueOption request_headers_to_add = 6
+      [(validate.rules).repeated = {max_items: 1000}];
+
+  // Indicates that during forwarding, the host header will be swapped with
+  // this value.
+  string host_rewrite_literal = 9
+      [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];
+
+  // If true, the host name in the downstream request is used for redirection.
+  bool forced_use_original_host = 19;
+
+  bool forced_add_header_before_route_matcher = 21;
+
+  repeated RedirectPolicy policies = 18;
+}
+
 // A simple wrapper for an HTTP filter config. This is intended to be used as a wrapper for the
 // map value in
 // :ref:`VirtualHost.typed_per_filter_config<envoy_v3_api_field_config.route.v3.VirtualHost.typed_per_filter_config>`,
diff --git a/api/versioning/BUILD b/api/versioning/BUILD
index 8febd11d20..13a58e1d11 100644
--- a/api/versioning/BUILD
+++ b/api/versioning/BUILD
@@ -9,6 +9,7 @@ proto_library(
     name = "active_protos",
     visibility = ["//visibility:public"],
     deps = [
+        "//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg",
         "//contrib/envoy/extensions/filters/http/squash/v3:pkg",
         "//contrib/envoy/extensions/filters/http/sxg/v3alpha:pkg",
         "//contrib/envoy/extensions/filters/network/kafka_broker/v3:pkg",
diff --git a/bazel/BUILD b/bazel/BUILD
index 3b22ffc8ff..1553e76a9d 100644
--- a/bazel/BUILD
+++ b/bazel/BUILD
@@ -539,6 +539,13 @@ config_setting(
     define_values = {"FUZZING_ENGINE": "oss-fuzz"},
 )
 
+# By default we enable AliMesh build. If want to build community
+# version then build Envoy with flag of '--define alimesh=false'.
+config_setting(
+    name = "alimesh",
+    values = {"define": "alimesh=false"},
+)
+
 alias(
     name = "fuzzing_engine",
     actual = select({
diff --git a/bazel/envoy_binary.bzl b/bazel/envoy_binary.bzl
index 6ea24b9888..ad9375d9b1 100644
--- a/bazel/envoy_binary.bzl
+++ b/bazel/envoy_binary.bzl
@@ -8,6 +8,7 @@ load(
     "envoy_external_dep_path",
     "envoy_stdlib_deps",
     "tcmalloc_external_dep",
+    "envoy_select_alimesh",
 )
 
 # Envoy C++ binary targets should be specified with this function.
diff --git a/bazel/envoy_internal.bzl b/bazel/envoy_internal.bzl
index 9c5130f15e..20d80977f2 100644
--- a/bazel/envoy_internal.bzl
+++ b/bazel/envoy_internal.bzl
@@ -122,6 +122,7 @@ def envoy_copts(repository, test = False):
            envoy_select_enable_http3(["-DENVOY_ENABLE_QUIC"], repository) + \
            _envoy_select_perf_annotation(["-DENVOY_PERF_ANNOTATION"]) + \
            envoy_select_google_grpc(["-DENVOY_GOOGLE_GRPC"], repository) + \
+           envoy_select_alimesh(["-DALIMESH"]) + \
            _envoy_select_path_normalization_by_default(["-DENVOY_NORMALIZE_PATH_BY_DEFAULT"], repository)
 
 # References to Envoy external dependencies should be wrapped with this function.
@@ -179,3 +180,9 @@ def _envoy_select_perf_annotation(xs):
         "@envoy//bazel:enable_perf_annotation": xs,
         "//conditions:default": [],
     })
+
+def envoy_select_alimesh(xs):
+    return select({
+        "@envoy//bazel:alimesh": [],
+        "//conditions:default": xs,
+    })
diff --git a/bazel/envoy_library.bzl b/bazel/envoy_library.bzl
index 5b1d674483..3a2204083c 100644
--- a/bazel/envoy_library.bzl
+++ b/bazel/envoy_library.bzl
@@ -93,12 +93,18 @@ def envoy_cc_library(
         tags = [],
         deps = [],
         strip_include_prefix = None,
+        alimesh_deps = [],
         include_prefix = None,
         textual_hdrs = None,
         defines = []):
     if tcmalloc_dep:
         deps += tcmalloc_external_deps(repository)
 
+    deps = deps + select({
+        "@envoy//bazel:alimesh": [],
+        "//conditions:default": alimesh_deps,
+    })
+
     cc_library(
         name = name,
         srcs = srcs,
diff --git a/bazel/external/wee8.genrule_cmd b/bazel/external/wee8.genrule_cmd
index 7b175a1f20..a16e6112f8 100644
--- a/bazel/external/wee8.genrule_cmd
+++ b/bazel/external/wee8.genrule_cmd
@@ -99,6 +99,8 @@ WEE8_BUILD_ARGS+=" v8_use_external_startup_data=false"
 # Disable read-only heap, since it's leaky and HEAPCHECK complains about it.
 # TODO(PiotrSikora): remove when fixed upstream.
 WEE8_BUILD_ARGS+=" v8_enable_shared_ro_heap=false"
+# Disable pointer compression (limits the maximum number of WasmVMs).
+WEE8_BUILD_ARGS+=" v8_enable_pointer_compression=false"
 
 # Set target architecture.
 if [[ $${ARCH} == "x86_64" ]]; then
diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl
index c642f6e375..6aba260762 100644
--- a/bazel/repositories.bzl
+++ b/bazel/repositories.bzl
@@ -1,5 +1,7 @@
 load(":dev_binding.bzl", "envoy_dev_binding")
 load(":genrule_repository.bzl", "genrule_repository")
+load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
+load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository", "new_git_repository")
 load("@envoy_api//bazel:envoy_http_archive.bzl", "envoy_http_archive")
 load("@envoy_api//bazel:external_deps.bzl", "load_repository_locations")
 load(":repository_locations.bzl", "REPOSITORY_LOCATIONS_SPEC")
@@ -7,6 +9,8 @@ load("@com_google_googleapis//:repository_rules.bzl", "switched_rules_by_languag
 
 PPC_SKIP_TARGETS = ["envoy.filters.http.lua"]
 
+DARWIN_SKIP_TARGETS = []
+
 WINDOWS_SKIP_TARGETS = [
     "envoy.filters.http.sxg",
     "envoy.tracers.dynamic_ot",
@@ -573,6 +577,10 @@ def _com_github_alibaba_hessian2_codec():
         name = "hessian2_codec_codec_impl",
         actual = "@com_github_alibaba_hessian2_codec//hessian2:codec_impl_lib",
     )
+    native.bind(
+        name = "hessian2_codec_object_impl",
+        actual = "@com_github_alibaba_hessian2_codec//hessian2:object_lib",
+    )
 
 def _com_github_ncopa_suexec():
     external_http_archive(
diff --git a/ci/run_clang_tidy.sh b/ci/run_clang_tidy.sh
index 0aca2629f3..a485c4a564 100755
--- a/ci/run_clang_tidy.sh
+++ b/ci/run_clang_tidy.sh
@@ -98,9 +98,12 @@ function run_clang_tidy_diff() {
   git diff "$1" | filter_excludes | \
     python3 "${LLVM_PREFIX}/share/clang/clang-tidy-diff.py" \
       -clang-tidy-binary="${CLANG_TIDY}" \
-      -export-fixes="${FIX_YAML}" -j "${NUM_CPUS:-0}" -p 1 -quiet
+      -export-fixes="${FIX_YAML}" -j "${NUM_CPUS:-0}" -p 1 -quiet \
+      -iregex="^(?!.*(${CLANG_TIDY_SKIL_KEYWORD})).*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)"
 }
 
+export CLANG_TIDY_SKIL_KEYWORD="egds|data_restorer|alimesh.*mocks|unit_route|test/.*eagleeye"
+
 if [[ $# -gt 0 ]]; then
   echo "Running clang-tidy on: $*"
   run_clang_tidy "$@"
diff --git a/contrib/common/active_redirect/source/BUILD b/contrib/common/active_redirect/source/BUILD
new file mode 100644
index 0000000000..8a770f9b26
--- /dev/null
+++ b/contrib/common/active_redirect/source/BUILD
@@ -0,0 +1,34 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "active_redirect_policy_lib",
+    srcs = ["active_redirect_policy_impl.cc"],
+    hdrs = ["active_redirect_policy_impl.h"],
+    external_deps = ["abseil_optional"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//contrib/envoy/http:active_redirect_policy_interface",
+        "//envoy/http:header_map_interface",
+        "//envoy/router:router_interface",
+        "//source/common/common:empty_string",
+        "//source/common/common:utility_lib",
+        "//source/common/config:utility_lib",
+        "//source/common/http:header_utility_lib",
+        "//source/common/http:headers_lib",
+        "//source/common/http:path_utility_lib",
+        "//source/common/http:utility_lib",
+        "//source/common/protobuf:utility_lib",
+        "//source/common/router:header_parser_lib",
+        "@envoy_api//envoy/config/core/v3:pkg_cc_proto",
+        "@envoy_api//envoy/config/route/v3:pkg_cc_proto",
+        "@envoy_api//envoy/type/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/common/active_redirect/source/active_redirect_policy_impl.cc b/contrib/common/active_redirect/source/active_redirect_policy_impl.cc
new file mode 100644
index 0000000000..03d9bdeab2
--- /dev/null
+++ b/contrib/common/active_redirect/source/active_redirect_policy_impl.cc
@@ -0,0 +1,225 @@
+#include "contrib/common/active_redirect/source/active_redirect_policy_impl.h"
+
+#include <memory>
+#include <string>
+
+#include "source/common/common/empty_string.h"
+#include "source/common/common/regex.h"
+#include "source/common/common/utility.h"
+#include "source/common/config/utility.h"
+#include "source/common/http/path_utility.h"
+
+namespace Envoy {
+namespace Router {
+
+InternalActiveRedirectPolicyImpl::InternalActiveRedirectPolicyImpl(
+    const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config,
+    ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name)
+    : current_route_name_(current_route_name),
+      redirect_response_codes_(buildRedirectResponseCodes(policy_config)),
+      max_internal_redirects_(
+          PROTOBUF_GET_WRAPPED_OR_DEFAULT(policy_config, max_internal_redirects, 1)),
+      enabled_(true), allow_cross_scheme_redirect_(policy_config.allow_cross_scheme_redirect()),
+      redirect_url_(policy_config.redirect_url()),
+      request_headers_parser_(HeaderParser::configure(policy_config.request_headers_to_add())),
+      redirect_url_rewrite_regex_(
+          policy_config.has_redirect_url_rewrite_regex()
+              ? Regex::Utility::parseRegex(policy_config.redirect_url_rewrite_regex().pattern())
+              : nullptr),
+      redirect_url_rewrite_regex_substitution_(
+          policy_config.has_redirect_url_rewrite_regex()
+              ? policy_config.redirect_url_rewrite_regex().substitution()
+              : ""),
+      host_rewrite_(policy_config.host_rewrite_literal()),
+      forced_use_original_host_(policy_config.forced_use_original_host()),
+      forced_add_header_before_route_matcher_(policy_config.forced_add_header_before_route_matcher()) {
+  for (const auto& predicate : policy_config.predicates()) {
+    auto& factory =
+        Envoy::Config::Utility::getAndCheckFactory<InternalRedirectPredicateFactory>(predicate);
+    auto config = factory.createEmptyConfigProto();
+    Envoy::Config::Utility::translateOpaqueConfig(predicate.typed_config(), validator, *config);
+    predicate_factories_.emplace_back(&factory, std::move(config));
+  }
+}
+
+InternalActiveRedirectPolicyImpl::InternalActiveRedirectPolicyImpl(
+    const envoy::config::route::v3::InternalActiveRedirectPolicy::RedirectPolicy& policy_config,
+    ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name)
+    : current_route_name_(current_route_name),
+      redirect_response_codes_(buildRedirectResponseCodes(policy_config)),
+      max_internal_redirects_(
+          PROTOBUF_GET_WRAPPED_OR_DEFAULT(policy_config, max_internal_redirects, 1)),
+      enabled_(true), allow_cross_scheme_redirect_(policy_config.allow_cross_scheme_redirect()),
+      redirect_url_(policy_config.redirect_url()),
+      request_headers_parser_(HeaderParser::configure(policy_config.request_headers_to_add())),
+      redirect_url_rewrite_regex_(
+          policy_config.has_redirect_url_rewrite_regex()
+              ? Regex::Utility::parseRegex(policy_config.redirect_url_rewrite_regex().pattern())
+              : nullptr),
+      redirect_url_rewrite_regex_substitution_(
+          policy_config.has_redirect_url_rewrite_regex()
+              ? policy_config.redirect_url_rewrite_regex().substitution()
+              : ""),
+      host_rewrite_(policy_config.host_rewrite_literal()) {
+  for (const auto& predicate : policy_config.predicates()) {
+    auto& factory =
+        Envoy::Config::Utility::getAndCheckFactory<InternalRedirectPredicateFactory>(predicate);
+    auto config = factory.createEmptyConfigProto();
+    Envoy::Config::Utility::translateOpaqueConfig(predicate.typed_config(), validator, *config);
+    predicate_factories_.emplace_back(&factory, std::move(config));
+  }
+}
+
+std::vector<InternalRedirectPredicateSharedPtr>
+InternalActiveRedirectPolicyImpl::predicates() const {
+  std::vector<InternalRedirectPredicateSharedPtr> predicates;
+  for (const auto& predicate_factory : predicate_factories_) {
+    predicates.emplace_back(predicate_factory.first->createInternalRedirectPredicate(
+        *predicate_factory.second, current_route_name_));
+  }
+  return predicates;
+}
+
+absl::flat_hash_set<Http::Code> InternalActiveRedirectPolicyImpl::buildRedirectResponseCodes(
+    const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config) const {
+  if (policy_config.redirect_response_codes_size() == 0) {
+    return absl::flat_hash_set<Http::Code>{};
+  }
+
+  absl::flat_hash_set<Http::Code> ret;
+  std::for_each(policy_config.redirect_response_codes().begin(),
+                policy_config.redirect_response_codes().end(), [&ret](uint32_t response_code) {
+                  const absl::flat_hash_set<uint32_t> valid_redirect_response_code = {
+                      301, 302, 303, 307, 308, 200};
+                  if (!valid_redirect_response_code.contains(response_code)) {
+                    ret.insert(static_cast<Http::Code>(response_code));
+                  }
+                });
+  return ret;
+}
+
+absl::flat_hash_set<Http::Code> InternalActiveRedirectPolicyImpl::buildRedirectResponseCodes(
+    const envoy::config::route::v3::InternalActiveRedirectPolicy::RedirectPolicy& policy_config)
+    const {
+  if (policy_config.redirect_response_codes_size() == 0) {
+    return absl::flat_hash_set<Http::Code>{};
+  }
+
+  absl::flat_hash_set<Http::Code> ret;
+  std::for_each(policy_config.redirect_response_codes().begin(),
+                policy_config.redirect_response_codes().end(), [&ret](uint32_t response_code) {
+                  const absl::flat_hash_set<uint32_t> valid_redirect_response_code = {
+                      301, 302, 303, 307, 308, 200};
+                  if (!valid_redirect_response_code.contains(response_code)) {
+                    ret.insert(static_cast<Http::Code>(response_code));
+                  }
+                });
+  return ret;
+}
+
+void InternalActiveRedirectPolicyImpl::evaluateHeaders(
+    Http::HeaderMap& headers, const StreamInfo::StreamInfo* stream_info) const {
+  request_headers_parser_->evaluateHeaders(headers, stream_info);
+  if (!host_rewrite_.empty()) {
+    Http::RequestHeaderMap& request_headers = dynamic_cast<Http::RequestHeaderMap&>(headers);
+    request_headers.setHost(host_rewrite_);
+  }
+}
+
+std::string
+InternalActiveRedirectPolicyImpl::redirectUrl(absl::optional<std::string> current_path) const {
+  if (!redirect_url_.empty()) {
+    ENVOY_LOG(debug, "The redirect url: {}", redirect_url_);
+    return redirect_url_;
+  }
+
+  RELEASE_ASSERT(current_path.has_value(),
+                 "The internal redirect address uses a regular expression, but does not pass in "
+                 "the current path value");
+  auto just_path(Http::PathUtil::removeQueryAndFragment(current_path.value()));
+  return redirect_url_rewrite_regex_->replaceAll(just_path,
+                                                 redirect_url_rewrite_regex_substitution_);
+}
+
+bool InternalActiveRedirectPolicyImpl::forcedUseOriginalHost() const {
+  return forced_use_original_host_;
+}
+
+InternalActiveRedirectPoliciesImpl::InternalActiveRedirectPoliciesImpl(
+    const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config,
+    ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) {
+  if (policy_config.policies().empty() && !policy_config.redirect_response_codes().empty()) {
+    ENVOY_LOG(warn, "Please configure the redirection policy using the Policies field, the old "
+                    "configuration will be deprecated");
+    auto policy = std::make_unique<InternalActiveRedirectPolicyImpl>(policy_config, validator,
+                                                                     current_route_name);
+    policies_.emplace_back(std::move(policy));
+  }
+
+  for (const auto& policy : policy_config.policies()) {
+    auto policy_impl =
+        std::make_unique<InternalActiveRedirectPolicyImpl>(policy, validator, current_route_name);
+    policies_.emplace_back(std::move(policy_impl));
+  }
+
+  if (policies_.empty()) {
+    ENVOY_LOG(warn, "No redirection policy is currently configured. A default value is generated");
+    auto policy_impl = std::make_unique<InternalActiveRedirectPolicyImpl>();
+    policies_.emplace_back(std::move(policy_impl));
+  }
+}
+
+InternalActiveRedirectPoliciesImpl::InternalActiveRedirectPoliciesImpl() {
+  auto policy_impl = std::make_unique<InternalActiveRedirectPolicyImpl>();
+  policies_.emplace_back(std::move(policy_impl));
+}
+
+std::vector<InternalRedirectPredicateSharedPtr>
+InternalActiveRedirectPoliciesImpl::predicates() const {
+  return policies_.at(current_policy_index_)->predicates();
+}
+
+void InternalActiveRedirectPoliciesImpl::evaluateHeaders(
+    Http::HeaderMap& headers, const StreamInfo::StreamInfo* stream_info) const {
+  return policies_.at(current_policy_index_)->evaluateHeaders(headers, stream_info);
+}
+
+std::string
+InternalActiveRedirectPoliciesImpl::redirectUrl(absl::optional<std::string> current_path) const {
+  return policies_.at(current_policy_index_)->redirectUrl(current_path);
+}
+
+bool InternalActiveRedirectPoliciesImpl::enabled() const {
+  return policies_.at(current_policy_index_)->enabled();
+}
+
+bool InternalActiveRedirectPoliciesImpl::shouldRedirectForResponseCode(
+    const Http::Code& response_code) const {
+  for (ActiveRedirectPolicies::size_type i = 0; i < policies_.size(); i++) {
+    if (policies_.at(i)->shouldRedirectForResponseCode(response_code)) {
+      current_policy_index_ = i;
+      return true;
+    }
+  }
+
+  return false;
+}
+
+uint32_t InternalActiveRedirectPoliciesImpl::maxInternalRedirects() const {
+  return policies_.at(current_policy_index_)->maxInternalRedirects();
+}
+
+bool InternalActiveRedirectPoliciesImpl::isCrossSchemeRedirectAllowed() const {
+  return policies_.at(current_policy_index_)->isCrossSchemeRedirectAllowed();
+}
+
+bool InternalActiveRedirectPoliciesImpl::forcedUseOriginalHost() const {
+  return policies_.at(current_policy_index_)->forcedUseOriginalHost();
+}
+
+bool InternalActiveRedirectPoliciesImpl::forcedAddHeaderBeforeRouteMatcher() const {
+  return policies_.at(current_policy_index_)->forcedAddHeaderBeforeRouteMatcher();
+}
+
+} // namespace Router
+} // namespace Envoy
diff --git a/contrib/common/active_redirect/source/active_redirect_policy_impl.h b/contrib/common/active_redirect/source/active_redirect_policy_impl.h
new file mode 100644
index 0000000000..5eae0dbde5
--- /dev/null
+++ b/contrib/common/active_redirect/source/active_redirect_policy_impl.h
@@ -0,0 +1,118 @@
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "envoy/config/core/v3/base.pb.h"
+#include "envoy/config/route/v3/route.pb.h"
+#include "envoy/config/route/v3/route_components.pb.h"
+#include "envoy/type/v3/percent.pb.h"
+
+#include "source/common/http/header_utility.h"
+#include "source/common/protobuf/protobuf.h"
+#include "source/common/protobuf/utility.h"
+#include "source/common/router/header_parser.h"
+
+#include "absl/container/node_hash_map.h"
+#include "absl/types/optional.h"
+#include "contrib/envoy/http/active_redirect_policy.h"
+
+namespace Envoy {
+namespace Router {
+
+/**
+ * Implementation of InternalActiveRedirectPolicyImpl that reads from the proto
+ * InternalActiveRedirectPolicyImpl of the RouteAction.
+ */
+class InternalActiveRedirectPolicyImpl : public InternalActiveRedirectPolicy,
+                                         Logger::Loggable<Logger::Id::config> {
+public:
+  // Constructor that enables internal redirect with policy_config controlling the configurable
+  // behaviors.
+  explicit InternalActiveRedirectPolicyImpl(
+      const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config,
+      ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name);
+  explicit InternalActiveRedirectPolicyImpl(
+      const envoy::config::route::v3::InternalActiveRedirectPolicy::RedirectPolicy& policy_config,
+      ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name);
+  // Default constructor that disables internal redirect.
+  InternalActiveRedirectPolicyImpl() = default;
+
+  bool enabled() const override { return enabled_; }
+
+  bool shouldRedirectForResponseCode(const Http::Code& response_code) const override {
+    return redirect_response_codes_.contains(response_code);
+  }
+
+  std::vector<InternalRedirectPredicateSharedPtr> predicates() const override;
+
+  uint32_t maxInternalRedirects() const override { return max_internal_redirects_; }
+
+  bool isCrossSchemeRedirectAllowed() const override { return allow_cross_scheme_redirect_; }
+
+  void evaluateHeaders(Http::HeaderMap& headers,
+                       const StreamInfo::StreamInfo* stream_info) const override;
+
+  std::string redirectUrl(absl::optional<std::string> current_path = absl::nullopt) const override;
+
+  bool forcedUseOriginalHost() const override;
+  bool forcedAddHeaderBeforeRouteMatcher() const override {
+    return forced_add_header_before_route_matcher_;
+  }
+
+private:
+  absl::flat_hash_set<Http::Code> buildRedirectResponseCodes(
+      const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config) const;
+  absl::flat_hash_set<Http::Code> buildRedirectResponseCodes(
+      const envoy::config::route::v3::InternalActiveRedirectPolicy::RedirectPolicy& policy_config)
+      const;
+
+  const std::string current_route_name_;
+  const absl::flat_hash_set<Http::Code> redirect_response_codes_;
+  const uint32_t max_internal_redirects_{1};
+  const bool enabled_{false};
+  const bool allow_cross_scheme_redirect_{false};
+  const std::string redirect_url_;
+  const HeaderParserPtr request_headers_parser_;
+  const Regex::CompiledMatcherPtr redirect_url_rewrite_regex_;
+  const std::string redirect_url_rewrite_regex_substitution_;
+  const std::string host_rewrite_;
+  const bool forced_use_original_host_{false};
+  const bool forced_add_header_before_route_matcher_{false};
+
+  std::vector<std::pair<InternalRedirectPredicateFactory*, ProtobufTypes::MessagePtr>>
+      predicate_factories_;
+};
+
+using InternalActiveRedirectPolicySharedPtr = std::shared_ptr<InternalActiveRedirectPolicyImpl>;
+using ActiveRedirectPolicies = std::vector<InternalActiveRedirectPolicySharedPtr>;
+
+class InternalActiveRedirectPoliciesImpl : public InternalActiveRedirectPolicy,
+                                           Logger::Loggable<Logger::Id::config> {
+public:
+  // Constructor that enables internal redirect with policy_config controlling the configurable
+  // behaviors.
+  explicit InternalActiveRedirectPoliciesImpl(
+      const envoy::config::route::v3::InternalActiveRedirectPolicy& policy_config,
+      ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name);
+  // Default constructor that disables internal redirect.
+  InternalActiveRedirectPoliciesImpl();
+
+  bool enabled() const override;
+  bool shouldRedirectForResponseCode(const Http::Code& response_code) const override;
+  std::vector<InternalRedirectPredicateSharedPtr> predicates() const override;
+  uint32_t maxInternalRedirects() const override;
+  bool isCrossSchemeRedirectAllowed() const override;
+  void evaluateHeaders(Http::HeaderMap& headers,
+                       const StreamInfo::StreamInfo* stream_info) const override;
+  std::string redirectUrl(absl::optional<std::string> current_path = absl::nullopt) const override;
+  bool forcedUseOriginalHost() const override;
+  bool forcedAddHeaderBeforeRouteMatcher() const override;
+
+private:
+  ActiveRedirectPolicies policies_;
+  mutable ActiveRedirectPolicies::size_type current_policy_index_{0};
+};
+
+} // namespace Router
+} // namespace Envoy
diff --git a/contrib/common/localtime_formatter/source/BUILD b/contrib/common/localtime_formatter/source/BUILD
new file mode 100644
index 0000000000..e421762231
--- /dev/null
+++ b/contrib/common/localtime_formatter/source/BUILD
@@ -0,0 +1,29 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "substitution_formatter_lib",
+    srcs = ["substitution_formatter.cc"],
+    hdrs = ["substitution_formatter.h"],
+    external_deps = ["abseil_str_format"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/formatter:substitution_formatter_interface",
+        "//envoy/stream_info:stream_info_interface",
+        "//source/common/common:assert_lib",
+        "//source/common/common:utility_lib",
+        "//source/common/config:metadata_lib",
+        "//source/common/grpc:common_lib",
+        "//source/common/http:utility_lib",
+        "//source/common/protobuf:message_validator_lib",
+        "//source/common/stream_info:utility_lib",
+        "@envoy_api//envoy/config/core/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/common/localtime_formatter/source/substitution_formatter.cc b/contrib/common/localtime_formatter/source/substitution_formatter.cc
new file mode 100644
index 0000000000..c643526f84
--- /dev/null
+++ b/contrib/common/localtime_formatter/source/substitution_formatter.cc
@@ -0,0 +1,84 @@
+#include "contrib/common/localtime_formatter/source/substitution_formatter.h"
+
+#include <climits>
+#include <cstdint>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include "envoy/config/core/v3/base.pb.h"
+
+#include "source/common/api/os_sys_calls_impl.h"
+#include "source/common/common/assert.h"
+#include "source/common/common/empty_string.h"
+#include "source/common/common/fmt.h"
+#include "source/common/common/utility.h"
+#include "source/common/config/metadata.h"
+#include "source/common/grpc/common.h"
+#include "source/common/grpc/status.h"
+#include "source/common/http/utility.h"
+#include "source/common/protobuf/message_validator_impl.h"
+#include "source/common/protobuf/utility.h"
+#include "source/common/stream_info/utility.h"
+
+#include "absl/strings/str_split.h"
+#include "fmt/format.h"
+
+namespace Envoy {
+namespace Formatter {
+
+LocalStartTimeFormatter::LocalStartTimeFormatter(const std::string& token)
+    : date_formatter_(parseFormat(token, sizeof("LOCAL_START_TIME(") - 1)) {}
+
+absl::optional<std::string> LocalStartTimeFormatter::format(
+    const Http::RequestHeaderMap&, const Http::ResponseHeaderMap&, const Http::ResponseTrailerMap&,
+    const StreamInfo::StreamInfo& stream_info, absl::string_view) const {
+  return DateTimeFormatter::fromTime(stream_info.startTime(), absl::LocalTimeZone());
+}
+
+ProtobufWkt::Value LocalStartTimeFormatter::formatValue(
+    const Http::RequestHeaderMap& request_headers, const Http::ResponseHeaderMap& response_headers,
+    const Http::ResponseTrailerMap& response_trailers, const StreamInfo::StreamInfo& stream_info,
+    absl::string_view local_reply_body) const {
+  return ValueUtil::optionalStringValue(
+      format(request_headers, response_headers, response_trailers, stream_info, local_reply_body));
+}
+
+std::string LocalStartTimeFormatter::DateTimeFormatter::fromTime(const SystemTime& system_time,
+                                                                 absl::TimeZone time_zone) {
+  static const std::string DefaultDateFormat = "%Y-%m-%dT%H:%M:%E3SZ";
+
+  struct CachedTime {
+    std::chrono::seconds epoch_time_seconds;
+    std::string formatted_time;
+  };
+  static thread_local CachedTime cached_time;
+
+  const std::chrono::milliseconds epoch_time_ms =
+      std::chrono::duration_cast<std::chrono::milliseconds>(system_time.time_since_epoch());
+
+  const std::chrono::seconds epoch_time_seconds =
+      std::chrono::duration_cast<std::chrono::seconds>(epoch_time_ms);
+
+  if (cached_time.formatted_time.empty() || cached_time.epoch_time_seconds != epoch_time_seconds) {
+    cached_time.formatted_time =
+        absl::FormatTime(DefaultDateFormat, absl::FromChrono(system_time), time_zone);
+    cached_time.epoch_time_seconds = epoch_time_seconds;
+  } else {
+    // Overwrite the digits in the ".000Z" at the end of the string with the
+    // millisecond count from the input time.
+    ASSERT(cached_time.formatted_time.length() == 24);
+    size_t offset = cached_time.formatted_time.length() - 4;
+    uint32_t msec = epoch_time_ms.count() % 1000;
+    cached_time.formatted_time[offset++] = ('0' + (msec / 100));
+    msec %= 100;
+    cached_time.formatted_time[offset++] = ('0' + (msec / 10));
+    msec %= 10;
+    cached_time.formatted_time[offset++] = ('0' + msec);
+  }
+
+  return cached_time.formatted_time;
+}
+
+} // namespace Formatter
+} // namespace Envoy
diff --git a/contrib/common/localtime_formatter/source/substitution_formatter.h b/contrib/common/localtime_formatter/source/substitution_formatter.h
new file mode 100644
index 0000000000..7ba8535c19
--- /dev/null
+++ b/contrib/common/localtime_formatter/source/substitution_formatter.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <functional>
+#include <string>
+#include <vector>
+
+#include "envoy/common/time.h"
+#include "envoy/config/core/v3/base.pb.h"
+#include "envoy/formatter/substitution_formatter.h"
+#include "envoy/stream_info/stream_info.h"
+
+#include "source/common/common/utility.h"
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/types/optional.h"
+
+namespace Envoy {
+namespace Formatter {
+
+/**
+ * Access log format parser.
+ */
+class LocalStartTimeFormatter : public FormatterProvider {
+public:
+  LocalStartTimeFormatter(const std::string& format);
+
+  // FormatterProvider
+  absl::optional<std::string> format(const Http::RequestHeaderMap&, const Http::ResponseHeaderMap&,
+                                     const Http::ResponseTrailerMap&, const StreamInfo::StreamInfo&,
+                                     absl::string_view) const override;
+  ProtobufWkt::Value formatValue(const Http::RequestHeaderMap&, const Http::ResponseHeaderMap&,
+                                 const Http::ResponseTrailerMap&, const StreamInfo::StreamInfo&,
+                                 absl::string_view) const override;
+
+  /**
+   * Utility class for access log date/time format with milliseconds support.
+   */
+  class DateTimeFormatter {
+  public:
+    static std::string fromTime(const SystemTime& time, absl::TimeZone time_zone);
+  };
+
+  std::string parseFormat(const std::string& token, size_t parameters_start) {
+    const size_t parameters_length = token.length() - (parameters_start + 1);
+    return token[parameters_start - 1] == '(' ? token.substr(parameters_start, parameters_length)
+                                              : "";
+  }
+
+private:
+  const DateFormatter date_formatter_;
+};
+
+} // namespace Formatter
+} // namespace Envoy
diff --git a/contrib/common/localtime_formatter/test/BUILD b/contrib/common/localtime_formatter/test/BUILD
new file mode 100644
index 0000000000..22f9658bdb
--- /dev/null
+++ b/contrib/common/localtime_formatter/test/BUILD
@@ -0,0 +1,29 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_test",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_test(
+    name = "substitution_formatter_test",
+    srcs = ["substitution_formatter_test.cc"],
+    deps = [
+        "//contrib/common/localtime_formatter/source:substitution_formatter_lib",
+        "//source/common/common:utility_lib",
+        "//source/common/http:header_map_lib",
+        "//source/common/json:json_loader_lib",
+        "//source/common/network:address_lib",
+        "//source/common/router:string_accessor_lib",
+        "//test/mocks/api:api_mocks",
+        "//test/mocks/http:http_mocks",
+        "//test/mocks/ssl:ssl_mocks",
+        "//test/mocks/stream_info:stream_info_mocks",
+        "//test/test_common:threadsafe_singleton_injector_lib",
+        "//test/test_common:utility_lib",
+        "@envoy_api//envoy/config/core/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/common/localtime_formatter/test/substitution_formatter_test.cc b/contrib/common/localtime_formatter/test/substitution_formatter_test.cc
new file mode 100644
index 0000000000..8d92aaf5f4
--- /dev/null
+++ b/contrib/common/localtime_formatter/test/substitution_formatter_test.cc
@@ -0,0 +1,68 @@
+#include <chrono>
+#include <cstdint>
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include "envoy/config/core/v3/base.pb.h"
+#include "envoy/event/timer.h"
+
+#include "source/common/common/logger.h"
+#include "source/common/common/utility.h"
+#include "source/common/formatter/substitution_formatter.h"
+#include "source/common/http/header_map_impl.h"
+#include "source/common/json/json_loader.h"
+#include "source/common/network/address_impl.h"
+#include "source/common/protobuf/utility.h"
+#include "source/common/router/string_accessor_impl.h"
+
+#include "test/mocks/api/mocks.h"
+#include "test/mocks/http/mocks.h"
+#include "test/mocks/ssl/mocks.h"
+#include "test/mocks/stream_info/mocks.h"
+#include "test/test_common/printers.h"
+#include "test/test_common/threadsafe_singleton_injector.h"
+#include "test/test_common/utility.h"
+
+#include "contrib/common/localtime_formatter/source/substitution_formatter.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::NiceMock;
+using testing::Return;
+
+namespace Envoy {
+namespace Formatter {
+namespace {
+
+TEST(AlimeshSubstitutionFormatterTest, localStartTimeFormatter) {
+  NiceMock<StreamInfo::MockStreamInfo> stream_info;
+  Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"}, {":path", "/"}};
+  Http::TestResponseHeaderMapImpl response_headers;
+  Http::TestResponseTrailerMapImpl response_trailers;
+  std::string body;
+
+  {
+    LocalStartTimeFormatter local_start_time_format("");
+    int rand = std::rand();
+    std::shared_ptr<SystemTime> time =
+        std::make_shared<SystemTime>(Envoy::Event::TimeSystem::Microseconds(rand));
+    EXPECT_CALL(stream_info, startTime()).WillRepeatedly(Return(*time));
+    EXPECT_EQ(LocalStartTimeFormatter::DateTimeFormatter::fromTime(*time, absl::LocalTimeZone()),
+              local_start_time_format.format(request_headers, response_headers, response_trailers,
+                                             stream_info, body));
+  }
+
+  {
+    absl::Time abslStartTime =
+        TestUtility::parseTime("Dec 18 01:50:34 2018 GMT", "%b %e %H:%M:%S %Y GMT");
+    SystemTime startTime = absl::ToChronoTime(abslStartTime);
+
+    EXPECT_EQ("2018-12-18T01:50:34.000Z", LocalStartTimeFormatter::DateTimeFormatter::fromTime(
+                                              startTime, absl::LocalTimeZone()));
+  }
+}
+
+} // namespace
+} // namespace Formatter
+} // namespace Envoy
diff --git a/contrib/contrib_build_config.bzl b/contrib/contrib_build_config.bzl
index 3a9987a910..ff403d915e 100644
--- a/contrib/contrib_build_config.bzl
+++ b/contrib/contrib_build_config.bzl
@@ -4,9 +4,16 @@ CONTRIB_EXTENSIONS = {
     # HTTP filters
     #
 
+    "envoy.filters.http.http_dubbo_transcoder":                 "//contrib/http_dubbo_transcoder/filters/http/source:config",
     "envoy.filters.http.squash":                                "//contrib/squash/filters/http/source:config",
     "envoy.filters.http.sxg":                                   "//contrib/sxg/filters/http/source:config",
 
+    #
+    # Upstreams
+    #
+
+    "envoy.upstreams.http.dubbo_tcp":                           "//contrib/upstreams/http/dubbo_tcp/source:config",
+
     #
     # Network filters
     #
@@ -29,4 +36,10 @@ CONTRIB_EXTENSIONS = {
     #
 
     "envoy.tls.key_providers.cryptomb":                         "//contrib/cryptomb/private_key_providers/source:config",
+
+    #
+    # Custom cluster plugins
+    #
+
+    "envoy.router.cluster_specifier_plugin.cluster_fallback":   "//contrib/custom_cluster_plugins/cluster_fallback/source:config",
 }
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/source/BUILD b/contrib/custom_cluster_plugins/cluster_fallback/source/BUILD
new file mode 100644
index 0000000000..a9ddb6edf3
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/source/BUILD
@@ -0,0 +1,39 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_contrib_extension",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "filter_lib",
+    srcs = [
+        "filter.cc",
+    ],
+    hdrs = [
+        "filter.h",
+    ],
+    repository = "@envoy",
+    deps = [
+        "//envoy/router:cluster_specifier_plugin_interface",
+        "//source/common/router:config_lib",
+        "@envoy_api//contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_contrib_extension(
+    name = "config",
+    srcs = ["config.cc"],
+    hdrs = ["config.h"],
+    repository = "@envoy",
+    deps = [
+        ":filter_lib",
+        "//source/extensions/filters/network:well_known_names",
+        "//source/extensions/filters/network/common:factory_base_lib",
+        "@envoy_api//contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/source/config.cc b/contrib/custom_cluster_plugins/cluster_fallback/source/config.cc
new file mode 100644
index 0000000000..fe5158eeb6
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/source/config.cc
@@ -0,0 +1,26 @@
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/config.h"
+
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/filter.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+Envoy::Router::ClusterSpecifierPluginSharedPtr
+ClusterFallbackPluginFactoryConfig::createClusterSpecifierPlugin(
+    const Protobuf::Message& config, Server::Configuration::CommonFactoryContext& context) {
+  const auto& proto_config =
+      MessageUtil::downcastAndValidate<const envoy::extensions::custom_cluster_plugins::
+                                           cluster_fallback::v3::ClusterFallbackConfig&>(
+          config, context.messageValidationVisitor());
+  return std::make_shared<ClusterFallbackPlugin>(proto_config, context);
+}
+
+REGISTER_FACTORY(ClusterFallbackPluginFactoryConfig,
+                 Envoy::Router::ClusterSpecifierPluginFactoryConfig);
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/source/config.h b/contrib/custom_cluster_plugins/cluster_fallback/source/config.h
new file mode 100644
index 0000000000..d05294c585
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/source/config.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.h"
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.validate.h"
+
+#include "envoy/router/cluster_specifier_plugin.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+class ClusterFallbackPluginFactoryConfig
+    : public Envoy::Router::ClusterSpecifierPluginFactoryConfig {
+public:
+  ClusterFallbackPluginFactoryConfig() = default;
+
+  std::string name() const override {
+    return "envoy.router.cluster_specifier_plugin.cluster_fallback";
+  }
+
+  Envoy::Router::ClusterSpecifierPluginSharedPtr
+  createClusterSpecifierPlugin(const Protobuf::Message& config,
+                               Server::Configuration::CommonFactoryContext& context) override;
+
+  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
+    return std::make_unique<
+        envoy::extensions::custom_cluster_plugins::cluster_fallback::v3::ClusterFallbackConfig>();
+  }
+};
+
+DECLARE_FACTORY(ClusterFallbackPluginFactoryConfig);
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/source/filter.cc b/contrib/custom_cluster_plugins/cluster_fallback/source/filter.cc
new file mode 100644
index 0000000000..f009b6318e
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/source/filter.cc
@@ -0,0 +1,118 @@
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/filter.h"
+
+#include "source/common/common/assert.h"
+
+#include "source/common/router/config_impl.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+ClusterFallbackPlugin::ClusterFallbackPlugin(
+    const envoy::extensions::custom_cluster_plugins::cluster_fallback::v3::ClusterFallbackConfig&
+        config,
+    Server::Configuration::CommonFactoryContext& context)
+    : cluster_manager_(context.clusterManager()) {
+  if (config.config_specifier_case() ==
+      envoy::extensions::custom_cluster_plugins::cluster_fallback::v3::ClusterFallbackConfig::
+          kWeightedClusterConfig) {
+    for (auto& item : config.weighted_cluster_config().config()) {
+      clusters_config_.emplace(item.routing_cluster(),
+                               std::vector<std::string>(item.fallback_clusters().begin(),
+                                                        item.fallback_clusters().end()));
+    }
+  } else {
+    clusters_config_.emplace(
+        config.cluster_config().routing_cluster(),
+        std::vector<std::string>(config.cluster_config().fallback_clusters().begin(),
+                                 config.cluster_config().fallback_clusters().end()));
+  }
+
+  if (clusters_config_.empty()) {
+    ENVOY_LOG(info, "there is no fallback cluster");
+  }
+}
+
+Envoy::Router::RouteConstSharedPtr
+ClusterFallbackPlugin::route(const Envoy::Router::RouteEntry& route_entry,
+                             const Http::RequestHeaderMap&) const {
+  if (typeid(route_entry) == typeid(Envoy::Router::RouteEntryImplBase::WeightedClusterEntry&) ||
+      typeid(route_entry) == typeid(Envoy::Router::RouteEntryImplBase::DynamicRouteEntry&)) {
+    return calculateWeightedClusterFallback(route_entry);
+  }
+
+  ASSERT(dynamic_cast<const Envoy::Router::RouteEntryImplBase*>(&route_entry) != nullptr);
+  return calculateNormalClusterFallback(route_entry);
+}
+
+Envoy::Router::RouteConstSharedPtr ClusterFallbackPlugin::calculateNormalClusterFallback(
+    const Envoy::Router::RouteEntry& route_entry) const {
+  ASSERT(clusters_config_.size() == 1);
+
+  const auto& base = dynamic_cast<const Envoy::Router::RouteEntryImplBase&>(route_entry);
+  auto first_item = clusters_config_.begin();
+  if (hasHealthHost(first_item->first)) {
+    ENVOY_LOG(info, "The target cluster {} has healthy nodes and does not require fallback",
+              first_item->first);
+    return base.clone(first_item->first);
+  }
+
+  for (const auto& cluster_name : first_item->second) {
+    if (hasHealthHost(cluster_name)) {
+      return base.clone(cluster_name);
+    }
+  }
+
+  ENVOY_LOG(info, "All clusters have no healthy nodes, the original routing cluster is returned");
+  return base.clone(first_item->first);
+}
+
+Envoy::Router::RouteConstSharedPtr ClusterFallbackPlugin::calculateWeightedClusterFallback(
+    const Envoy::Router::RouteEntry& route_entry) const {
+  const auto& cluster_entry =
+      dynamic_cast<const Envoy::Router::RouteEntryImplBase::DynamicRouteEntry&>(route_entry);
+
+  auto search = clusters_config_.find(route_entry.clusterName());
+  if (search == clusters_config_.end()) {
+    ENVOY_LOG(warn, "there is no fallback cluster config, the original routing cluster is returned");
+    return cluster_entry.getRouteConstSharedPtr();
+  }
+
+  if (hasHealthHost(search->first)) {
+    ENVOY_LOG(info, "The target cluster {} has healthy nodes and does not require fallback",
+              search->first);
+    return cluster_entry.getRouteConstSharedPtr();
+  }
+
+  for (const auto& cluster_name : search->second) {
+    if (hasHealthHost(cluster_name)) {
+      return cluster_entry.clone(cluster_name);
+    }
+  }
+
+  ENVOY_LOG(info, "All clusters have no healthy nodes, the original routing cluster is returned");
+  return cluster_entry.getRouteConstSharedPtr();
+}
+
+bool ClusterFallbackPlugin::hasHealthHost(absl::string_view cluster_name) const {
+  bool has_health_host{false};
+  Upstream::ThreadLocalCluster* cluster = cluster_manager_.getThreadLocalCluster(cluster_name);
+  if (!cluster) {
+    return has_health_host;
+  }
+
+  for (auto& i : cluster->prioritySet().hostSetsPerPriority()) {
+    if (i->healthyHosts().size() > 0) {
+      has_health_host = true;
+      break;
+    }
+  }
+
+  return has_health_host;
+}
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/source/filter.h b/contrib/custom_cluster_plugins/cluster_fallback/source/filter.h
new file mode 100644
index 0000000000..d11ce9ca33
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/source/filter.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.h"
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.validate.h"
+
+#include "envoy/router/cluster_specifier_plugin.h"
+#include "envoy/upstream/cluster_manager.h"
+
+#include "source/common/common/logger_impl.h"
+#include "source/common/common/logger.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+class ClusterFallbackPlugin : public Envoy::Router::ClusterSpecifierPlugin,
+                              public Logger::Loggable<Logger::Id::router> {
+public:
+  ClusterFallbackPlugin(
+      const envoy::extensions::custom_cluster_plugins::cluster_fallback::v3::ClusterFallbackConfig&
+          config,
+      Server::Configuration::CommonFactoryContext& context);
+
+  Envoy::Router::RouteConstSharedPtr route(const Envoy::Router::RouteEntry& parent,
+                                           const Http::RequestHeaderMap&) const;
+
+private:
+  bool hasHealthHost(absl::string_view cluster_name) const;
+  Envoy::Router::RouteConstSharedPtr
+  calculateWeightedClusterFallback(const Envoy::Router::RouteEntry& route_entry) const;
+  Envoy::Router::RouteConstSharedPtr
+  calculateNormalClusterFallback(const Envoy::Router::RouteEntry& route_entry) const;
+
+  Upstream::ClusterManager& cluster_manager_;
+  std::unordered_map<std::string/*routing cluster*/, std::vector<std::string>/*fallback clusters*/> clusters_config_;
+};
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/test/BUILD b/contrib/custom_cluster_plugins/cluster_fallback/test/BUILD
new file mode 100644
index 0000000000..81c939afd6
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/test/BUILD
@@ -0,0 +1,37 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_test",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_test(
+    name = "config_test",
+    srcs = ["config_test.cc"],
+    deps = [
+        "//contrib/custom_cluster_plugins/cluster_fallback/source:config",
+        "//test/mocks/server:factory_context_mocks",
+        "//test/test_common:utility_lib",
+        "@envoy_api//contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_test(
+    name = "filter_test",
+    srcs = ["filter_test.cc"],
+    deps = [
+        "//contrib/custom_cluster_plugins/cluster_fallback/source:config",
+        "//contrib/custom_cluster_plugins/cluster_fallback/source:filter_lib",
+        "//test/mocks/server:factory_context_mocks",
+        "//test/mocks/upstream:cluster_manager_mocks",
+        "//test/mocks/upstream:cluster_mocks",
+        "//test/mocks/upstream:host_mocks",
+        "//test/mocks/upstream:host_set_mocks",
+        "//test/mocks/upstream:thread_local_cluster_mocks",
+        "//test/test_common:utility_lib",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
\ No newline at end of file
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/test/config_test.cc b/contrib/custom_cluster_plugins/cluster_fallback/test/config_test.cc
new file mode 100644
index 0000000000..c68e13229d
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/test/config_test.cc
@@ -0,0 +1,48 @@
+#include "test/mocks/server/factory_context.h"
+#include "test/test_common/utility.h"
+
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/config.h"
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.h"
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.validate.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::_;
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+TEST(ClusterFallbackPluginFactoryConfigTest, ClusterFallbackPluginCorrectYaml) {
+  const std::string yaml_string = R"EOF(
+extension:
+  name: envoy.router.cluster_specifier_plugin.cluster_fallback
+  typed_config:
+    "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+    routing_cluster: test
+    fallback_clusters:
+    - fallback1
+    - fallback2
+)EOF";
+
+  envoy::config::route::v3::ClusterSpecifierPlugin plugin_config;
+  TestUtility::loadFromYaml(yaml_string, plugin_config);
+
+  auto* factory =
+      Envoy::Config::Utility::getFactory<Envoy::Router::ClusterSpecifierPluginFactoryConfig>(
+          plugin_config.extension());
+  EXPECT_NE(nullptr, factory);
+
+  auto config = Envoy::Config::Utility::translateToFactoryConfig(
+      plugin_config.extension(), ProtobufMessage::getStrictValidationVisitor(), *factory);
+  NiceMock<Server::Configuration::MockServerFactoryContext> context;
+  auto plugin = factory->createClusterSpecifierPlugin(*config, context);
+  EXPECT_NE(nullptr, plugin);
+}
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/custom_cluster_plugins/cluster_fallback/test/filter_test.cc b/contrib/custom_cluster_plugins/cluster_fallback/test/filter_test.cc
new file mode 100644
index 0000000000..84bbc015d5
--- /dev/null
+++ b/contrib/custom_cluster_plugins/cluster_fallback/test/filter_test.cc
@@ -0,0 +1,686 @@
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/filter.h"
+
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.h"
+#include "contrib/envoy/extensions/custom_cluster_plugins/cluster_fallback/v3/cluster_fallback.pb.validate.h"
+#include "contrib/custom_cluster_plugins/cluster_fallback/source/config.h"
+#include "source/common/router/config_impl.h"
+
+#include "test/mocks/server/instance.h"
+#include "test/mocks/router/mocks.h"
+#include "test/mocks/upstream/cluster_manager.h"
+#include "test/mocks/upstream/host.h"
+#include "test/mocks/upstream/priority_set.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::_;
+using testing::ReturnRef;
+
+namespace Envoy {
+namespace Extensions {
+namespace CustomClusterPlugins {
+namespace ClusterFallback {
+
+Http::TestRequestHeaderMapImpl genHeaders(const std::string& host, const std::string& path,
+                                          const std::string& method, const std::string& scheme) {
+  auto hdrs =
+      Http::TestRequestHeaderMapImpl{{":authority", host},         {":path", path},
+                                     {":method", method},          {"x-safe", "safe"},
+                                     {"x-global-nope", "global"},  {"x-vhost-nope", "vhost"},
+                                     {"x-route-nope", "route"},    {":scheme", scheme},
+                                     {"x-forwarded-proto", scheme}};
+
+  if (scheme.empty()) {
+    hdrs.remove(":scheme");
+  }
+
+  return hdrs;
+}
+
+Http::TestRequestHeaderMapImpl genHeaders(const std::string& host, const std::string& path,
+                                          const std::string& method) {
+  return genHeaders(host, path, method, "http");
+}
+
+TEST(ClusterFallbackPluginTest, NormalWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: envoy.router.cluster_specifier_plugin.cluster_fallback
+          typed_config:
+            "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+            cluster_config:
+              routing_cluster: test
+              fallback_clusters:
+              - fallback1
+              - fallback2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> test_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto mock_host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{mock_host};
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      test_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*mock_host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(test_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("test", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, OnceFallbackWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: envoy.router.cluster_specifier_plugin.cluster_fallback
+          typed_config:
+            "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+            cluster_config:
+              routing_cluster: test
+              fallback_clusters:
+              - fallback1
+              - fallback2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{host};
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*mock_host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback1", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, TwiceFallbackWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: envoy.router.cluster_specifier_plugin.cluster_fallback
+          typed_config:
+            "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+            cluster_config:
+              routing_cluster: test
+              fallback_clusters:
+              - fallback1
+              - fallback2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+
+  // cluster test does not exist.
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  // cluster fallback1 is empty.
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  Envoy::Upstream::HostVector empty_hosts{};
+  EXPECT_CALL(*mock_host_set, healthyHosts()).WillOnce(ReturnRef(empty_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback2_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{host};
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback2_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback2")))
+      .WillOnce(Return(fallback2_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback2", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, NoHealthClusterWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/bar"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: envoy.router.cluster_specifier_plugin.cluster_fallback
+          typed_config:
+            "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+            cluster_config:
+              routing_cluster: test
+              fallback_clusters:
+              - fallback1
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+
+  // cluster test is empty.
+  std::shared_ptr<Upstream::MockThreadLocalCluster> test_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::MockHostSet* mock_host_set_test =
+      test_cluster->cluster_.prioritySet().getMockHostSet(0);
+  Envoy::Upstream::HostVector empty_hosts_test{};
+  EXPECT_CALL(*mock_host_set_test, healthyHosts()).WillOnce(ReturnRef(empty_hosts_test));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(test_cluster.get()));
+
+  // cluster fallback1 is empty.
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  Envoy::Upstream::HostVector empty_hosts{};
+  EXPECT_CALL(*mock_host_set, healthyHosts()).WillOnce(ReturnRef(empty_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  auto route = config.route(genHeaders("some_cluster", "/bar", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("test", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, ClusterSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: envoy.router.cluster_specifier_plugin.cluster_fallback
+    typed_config:
+      "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+      cluster_config:
+        routing_cluster: test
+        fallback_clusters:
+        - fallback1
+        - fallback2
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+
+  // cluster test is empty.
+  std::shared_ptr<Upstream::MockThreadLocalCluster> test_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::MockHostSet* mock_host_set_test =
+      test_cluster->cluster_.prioritySet().getMockHostSet(0);
+  Envoy::Upstream::HostVector empty_hosts_test{};
+  EXPECT_CALL(*mock_host_set_test, healthyHosts()).Times(2).WillRepeatedly(ReturnRef(empty_hosts_test));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .Times(2).WillRepeatedly(Return(test_cluster.get()));
+
+  // cluster fallback1 is empty.
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  Envoy::Upstream::HostVector empty_hosts{};
+  EXPECT_CALL(*mock_host_set, healthyHosts()).Times(2).WillRepeatedly(ReturnRef(empty_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .Times(2).WillRepeatedly(Return(fallback1_cluster.get()));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback2_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{host};
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback2_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).Times(2).WillRepeatedly(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback2")))
+      .Times(2).WillRepeatedly(Return(fallback2_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  auto route = config.route(genHeaders("some_cluster", "/bar", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback2", route->routeEntry()->clusterName());
+
+  route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback2", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, WeightedClusterNormalWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: test
+          weight: 100
+        - name: cluster2
+          weight: 0
+        inline_cluster_specifier_plugin:
+          extension:
+            name: envoy.router.cluster_specifier_plugin.cluster_fallback
+            typed_config:
+              "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+              weighted_cluster_config:
+                config:
+                - routing_cluster: test
+                  fallback_clusters:
+                  - fallback1
+                - routing_cluster: cluster2
+                  fallback_clusters:
+                  - fallback2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> test_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto mock_host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{mock_host};
+  Envoy::Upstream::MockHostSet* mock_host_set =
+      test_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*mock_host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(test_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("test", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, WeightedClusterFallbackWithInlinePlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: test
+          weight: 100
+        - name: cluster2
+          weight: 0
+        inline_cluster_specifier_plugin:
+          extension:
+            name: envoy.router.cluster_specifier_plugin.cluster_fallback
+            typed_config:
+              "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+              weighted_cluster_config:
+                config:
+                - routing_cluster: test
+                  fallback_clusters:
+                  - fallback1
+                - routing_cluster: cluster2
+                  fallback_clusters:
+                  - fallback2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  // cluster test does not exist.
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto mock_host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{mock_host};
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback1", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, WeightedClusterFallback) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: envoy.router.cluster_specifier_plugin.cluster_fallback
+    typed_config:
+      "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+      weighted_cluster_config:
+        config:
+        - routing_cluster: test
+          fallback_clusters:
+          - fallback1
+        - routing_cluster: cluster2
+          fallback_clusters:
+          - fallback2
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: test
+          weight: 100
+        - name: cluster2
+          weight: 0
+        cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  // cluster test does not exist.
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto mock_host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{mock_host};
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback1", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, WeightedClusterNoHealthHost) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: envoy.router.cluster_specifier_plugin.cluster_fallback
+    typed_config:
+      "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+      weighted_cluster_config:
+        config:
+        - routing_cluster: test
+          fallback_clusters:
+          - fallback1
+        - routing_cluster: cluster2
+          fallback_clusters:
+          - fallback2
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: test
+          weight: 100
+        - name: cluster2
+          weight: 0
+        cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  // cluster test does not exist.
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  Envoy::Upstream::HostVector mock_hosts;
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  auto route = config.route(genHeaders("some_cluster", "/foo", "GET"), stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("test", route->routeEntry()->clusterName());
+}
+
+TEST(ClusterFallbackPluginTest, WeightedClusterFallbackViaClusterHeader) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: envoy.router.cluster_specifier_plugin.cluster_fallback
+    typed_config:
+      "@type": type.googleapis.com/envoy.extensions.custom_cluster_plugins.cluster_fallback.v3.ClusterFallbackConfig
+      weighted_cluster_config:
+        config:
+        - routing_cluster: test
+          fallback_clusters:
+          - fallback1
+        - routing_cluster: cluster2
+          fallback_clusters:
+          - fallback2
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - cluster_header: cluster
+          weight: 100
+        - name: cluster2
+          weight: 0
+        cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_specifier_plugin: envoy.router.cluster_specifier_plugin.cluster_fallback
+  )EOF";
+
+  NiceMock<Server::Configuration::MockServerFactoryContext> factory_context;
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+
+  // cluster test does not exist.
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("test")))
+      .WillOnce(Return(nullptr));
+
+  std::shared_ptr<Upstream::MockThreadLocalCluster> fallback1_cluster =
+      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
+  auto mock_host = std::make_shared<NiceMock<Envoy::Upstream::MockHost>>();
+  Envoy::Upstream::HostVector mock_hosts{mock_host};
+  Envoy::Upstream::MockHostSet* host_set =
+      fallback1_cluster->cluster_.prioritySet().getMockHostSet(0);
+  EXPECT_CALL(*host_set, healthyHosts()).WillOnce(ReturnRef(mock_hosts));
+  EXPECT_CALL(factory_context.cluster_manager_, getThreadLocalCluster(testing::Eq("fallback1")))
+      .WillOnce(Return(fallback1_cluster.get()));
+
+  envoy::config::route::v3::RouteConfiguration route_config;
+  TestUtility::loadFromYaml(yaml, route_config);
+
+  const Envoy::Router::OptionalHttpFilters& optional_http_filters =
+      Envoy::Router::OptionalHttpFilters();
+  Envoy::Router::ConfigImpl config(route_config, optional_http_filters, factory_context,
+                                   ProtobufMessage::getNullValidationVisitor(), false);
+
+  Http::TestRequestHeaderMapImpl header = genHeaders("some_cluster", "/foo", "GET");
+  header.setByKey("cluster", "test");
+  auto route = config.route(header, stream_info, 0);
+  EXPECT_NE(nullptr, route);
+  EXPECT_EQ("fallback1", route->routeEntry()->clusterName());
+}
+
+} // namespace ClusterFallback
+} // namespace CustomClusterPlugins
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/envoy/http/BUILD b/contrib/envoy/http/BUILD
new file mode 100644
index 0000000000..b20612de58
--- /dev/null
+++ b/contrib/envoy/http/BUILD
@@ -0,0 +1,23 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "active_redirect_policy_interface",
+    hdrs = ["active_redirect_policy.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/http:codes_interface",
+        "//envoy/http:header_map_interface",
+        "//envoy/router:internal_redirect_interface",
+        "//envoy/stream_info:stream_info_interface",
+        "@envoy_api//envoy/config/core/v3:pkg_cc_proto",
+        "@envoy_api//envoy/config/route/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/envoy/http/active_redirect_policy.h b/contrib/envoy/http/active_redirect_policy.h
new file mode 100644
index 0000000000..7ed5ded7fe
--- /dev/null
+++ b/contrib/envoy/http/active_redirect_policy.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include <memory>
+#include <string>
+
+#include "envoy/config/core/v3/base.pb.h"
+#include "envoy/config/route/v3/route_components.pb.h"
+#include "envoy/http/codes.h"
+#include "envoy/http/header_map.h"
+#include "envoy/router/internal_redirect.h"
+#include "envoy/stream_info/stream_info.h"
+
+namespace Envoy {
+
+namespace Router {
+
+/**
+ * InternalActiveRedirectPolicy from the route configuration.
+ */
+class InternalActiveRedirectPolicy {
+public:
+  virtual ~InternalActiveRedirectPolicy() = default;
+
+  /**
+   * @return whether internal redirect is enabled on this route.
+   */
+  virtual bool enabled() const PURE;
+
+  /**
+   * @param response_code the response code from the upstream.
+   * @return whether the given response_code should trigger an internal redirect on this route.
+   */
+  virtual bool shouldRedirectForResponseCode(const Http::Code& response_code) const PURE;
+
+  /**
+   * Creates the target route predicates. This should really be called only once for each upstream
+   * redirect response. Creating the predicates lazily to avoid wasting CPU cycles on non-redirect
+   * responses, which should be the most common case.
+   * @return a vector of newly constructed InternalRedirectPredicate instances.
+   */
+  virtual std::vector<InternalRedirectPredicateSharedPtr> predicates() const PURE;
+
+  /**
+   * @return the maximum number of allowed internal redirects on this route.
+   */
+  virtual uint32_t maxInternalRedirects() const PURE;
+
+  /**
+   * @return if it is allowed to follow the redirect with a different scheme in
+   *         the target URI than the downstream request.
+   */
+  virtual bool isCrossSchemeRedirectAllowed() const PURE;
+
+  virtual void evaluateHeaders(Http::HeaderMap& headers,
+                               const StreamInfo::StreamInfo* stream_info) const PURE;
+
+  virtual std::string
+  redirectUrl(absl::optional<std::string> current_path = absl::nullopt) const PURE;
+
+  virtual bool forcedUseOriginalHost() const PURE;
+
+  virtual bool forcedAddHeaderBeforeRouteMatcher() const PURE;
+};
+
+} // namespace Router
+} // namespace Envoy
diff --git a/contrib/extensions_metadata.yaml b/contrib/extensions_metadata.yaml
index 215a7936f0..6d42f83f38 100644
--- a/contrib/extensions_metadata.yaml
+++ b/contrib/extensions_metadata.yaml
@@ -1,3 +1,13 @@
+envoy.filters.http.http_dubbo_transcoder:
+  categories:
+  - envoy.filters.http
+  security_posture: requires_trusted_downstream_and_upstream
+  status: stable
+envoy.upstreams.http.dubbo_tcp:
+  categories:
+  - envoy.upstreams
+  security_posture: robust_to_untrusted_downstream
+  status: stable
 envoy.filters.http.squash:
   categories:
   - envoy.filters.http
@@ -48,3 +58,8 @@ envoy.tls.key_providers.cryptomb:
   - envoy.tls.key_providers
   security_posture: robust_to_untrusted_downstream
   status: alpha
+envoy.router.cluster_specifier_plugin.cluster_fallback:
+  categories:
+  - envoy.router
+  security_posture: robust_to_untrusted_downstream
+  status: alpha
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/BUILD b/contrib/http_dubbo_transcoder/filters/http/source/BUILD
new file mode 100644
index 0000000000..90cbab579f
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/BUILD
@@ -0,0 +1,90 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_contrib_extension",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "dubbo_transcoder_filter_lib",
+    srcs = ["dubbo_transcoder_filter.cc"],
+    hdrs = ["dubbo_transcoder_filter.h"],
+    external_deps = [
+        "path_matcher",
+        "hessian2_codec_codec_impl",
+        "hessian2_codec_object_codec_lib",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":transcoder_interface",
+        ":utility_lib",
+        "//envoy/event:dispatcher_interface",
+        "//envoy/http:codes_interface",
+        "//envoy/http:filter_interface",
+        "//envoy/http:query_params_interface",
+        "//source/common/buffer:buffer_lib",
+        "//source/common/common:assert_lib",
+        "//source/common/common:enum_to_int",
+        "//source/common/common:minimal_logger_lib",
+        "//source/common/common:regex_lib",
+        "//source/common/http:codes_lib",
+        "//source/common/http:header_map_lib",
+        "//source/common/http:headers_lib",
+        "//source/common/http:utility_lib",
+        "//source/common/runtime:runtime_lib",
+        "//source/common/common:hex_lib",
+        "//source/extensions/filters/http:well_known_names",
+        "@com_google_googleapis//google/api:http_cc_proto",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+        "@envoy_api//envoy/type/matcher/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_contrib_extension(
+    name = "config",
+    srcs = ["config.cc"],
+    hdrs = ["config.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":dubbo_transcoder_filter_lib",
+        "//envoy/registry",
+        "//source/extensions/filters/http:well_known_names",
+        "//source/extensions/filters/http/common:factory_base_lib",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_library(
+    name = "transcoder_interface",
+    hdrs = ["transcoder.h"],
+    deps = [
+        "//envoy/http:filter_interface",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_library(
+    name = "utility_lib",
+    srcs = ["utility.cc"],
+    hdrs = ["utility.h"],
+    external_deps = [
+        "hessian2_codec_object_impl",
+        "hessian2_codec_codec_impl",
+        "hessian2_codec_object_codec_lib",
+        "json",
+    ],
+    deps = [
+        ":transcoder_interface",
+        "//envoy/http:filter_interface",
+        "//envoy/http:query_params_interface",
+        "//source/common/buffer:buffer_lib",
+        "//source/common/common:enum_to_int",
+        "//source/common/http:codes_lib",
+        "//source/common/http:utility_lib",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/config.cc b/contrib/http_dubbo_transcoder/filters/http/source/config.cc
new file mode 100644
index 0000000000..81f9827cdc
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/config.cc
@@ -0,0 +1,32 @@
+#include "contrib/http_dubbo_transcoder/filters/http/source/config.h"
+
+#include "contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+Http::FilterFactoryCb HttpDubboTranscodeFilterFactory::createFilterFactoryFromProtoTyped(
+    const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder& proto_config,
+    const std::string&, Server::Configuration::FactoryContext&) {
+  DubboTranscoderConfigSharedPtr config = std::make_shared<DubboTranscoderConfig>(proto_config);
+  return [config](Http::FilterChainFactoryCallbacks& callbacks) -> void {
+    callbacks.addStreamFilter(std::make_shared<TranscodeFilter>(*config));
+  };
+}
+
+Router::RouteSpecificFilterConfigConstSharedPtr
+HttpDubboTranscodeFilterFactory::createRouteSpecificFilterConfigTyped(
+    const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder& proto_config,
+    Server::Configuration::ServerFactoryContext&, ProtobufMessage::ValidationVisitor&) {
+  return std::make_shared<DubboTranscoderConfig>(proto_config);
+};
+
+REGISTER_FACTORY(HttpDubboTranscodeFilterFactory,
+                 Server::Configuration::NamedHttpFilterConfigFactory);
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/config.h b/contrib/http_dubbo_transcoder/filters/http/source/config.h
new file mode 100644
index 0000000000..80161be035
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/config.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+
+#include "source/extensions/filters/http/common/factory_base.h"
+#include "source/extensions/filters/http/well_known_names.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+/**
+ * Config registration for the buffer filter.
+ */
+class HttpDubboTranscodeFilterFactory
+    : public Common::FactoryBase<
+          envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder> {
+public:
+  HttpDubboTranscodeFilterFactory() : FactoryBase("envoy.filters.http.http_dubbo_transcoder") {}
+
+private:
+  Http::FilterFactoryCb createFilterFactoryFromProtoTyped(
+      const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder&
+          proto_config,
+      const std::string& stats_prefix, Server::Configuration::FactoryContext& context) override;
+
+  Router::RouteSpecificFilterConfigConstSharedPtr createRouteSpecificFilterConfigTyped(
+      const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder&
+          proto_config,
+      Server::Configuration::ServerFactoryContext& context,
+      ProtobufMessage::ValidationVisitor& validator) override;
+};
+
+DECLARE_FACTORY(HttpDubboTranscodeFilterFactory);
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.cc b/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.cc
new file mode 100644
index 0000000000..0d8f0b6000
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.cc
@@ -0,0 +1,577 @@
+#include "contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h"
+
+#include "source/common/common/assert.h"
+#include "source/common/common/hex.h"
+#include "source/common/common/regex.h"
+#include "source/common/http/status.h"
+#include "source/common/http/utility.h"
+#include "source/extensions/filters/http/well_known_names.h"
+
+#include "absl/status/status.h"
+#include "absl/strings/str_split.h"
+
+#include "contrib/http_dubbo_transcoder/filters/http/source/utility.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+static const std::string HTTPResponseKey = "result";
+static const std::string HTTPResponseErrorKey = "error";
+static const std::string HTTPResponseAttachmentKey = "attachment";
+
+static const std::string DubboGenericMethodName = "$invoke";
+static const std::string DubboGenericParamTypes =
+    "Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/Object;";
+
+static const std::string DubboDefaultProtocolVsersion = "2.7.1";
+static const std::string DubboDefaultMethodVersion = "0.0.0";
+
+static const std::string AttachmentPathKey = "path";
+static const std::string AttachmentGenericKey = "generic";
+static const std::string AttachmentInterfaceKey = "interface";
+static const std::string AttachmentVersionKey = "version";
+static const std::string AttachmentTrueValue = "true";
+static const std::string AttachmentGroupKey = "group";
+constexpr uint8_t EVENT_BIT_ON = 0x20;
+static std::atomic_ulong RequestId{0};
+
+DubboTranscoderConfig::DubboTranscoderConfig(
+    const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder&
+        proto_config) {
+
+  disabled_ = proto_config.services_mapping().empty();
+  if (disabled_) {
+    return;
+  }
+
+  request_validate_options_ = proto_config.request_validation_options();
+
+  // build path matcher
+  ::google::grpc::transcoding::PathMatcherBuilder<MethodInfoSharedPtr> pmb;
+  for (const auto& service : proto_config.services_mapping()) {
+    for (const auto& method : service.method_mapping()) {
+      MethodInfoSharedPtr method_info =
+          createMethodInfo(service.name(), service.version(), service.group(), method);
+      pmb.Register(method_info->match_http_method_, method_info->match_pattern_, "", method_info);
+    }
+  }
+  switch (proto_config.url_unescape_spec()) {
+  case envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+      ALL_CHARACTERS_EXCEPT_RESERVED:
+    pmb.SetUrlUnescapeSpec(
+        google::grpc::transcoding::UrlUnescapeSpec::kAllCharactersExceptReserved);
+    break;
+  case envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+      ALL_CHARACTERS_EXCEPT_SLASH:
+    pmb.SetUrlUnescapeSpec(google::grpc::transcoding::UrlUnescapeSpec::kAllCharactersExceptSlash);
+    break;
+  case envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+      ALL_CHARACTERS:
+    pmb.SetUrlUnescapeSpec(google::grpc::transcoding::UrlUnescapeSpec::kAllCharacters);
+    break;
+  default:
+    NOT_REACHED_GCOVR_EXCL_LINE;
+  }
+  path_matcher_ = pmb.Build();
+}
+
+MethodInfoSharedPtr DubboTranscoderConfig::createMethodInfo(
+    const std::string& service_name, const std::string& service_version,
+    const std::string& service_group,
+    const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+        DubboMethodMapping& method_mapping) {
+  MethodInfoSharedPtr method_info = std::make_shared<MethodInfo>();
+  method_info->service_name_ = service_name;
+  method_info->service_version_ = service_version;
+  method_info->service_group_ = service_group;
+  method_info->name_ = method_mapping.name();
+
+  if (method_mapping.has_path_matcher()) {
+    std::string http_method_spec = envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+        HttpDubboTranscoder_DubboMethodMapping_MatchHttpMethodSpec_Name(
+            method_mapping.path_matcher().match_http_method_spec());
+    method_info->match_http_method_ = std::string(absl::StripPrefix(http_method_spec, "ALL_"));
+    method_info->match_pattern_ = method_mapping.path_matcher().match_pattern();
+  } else {
+    // Default matching path: service/method, http method: get.
+    std::string http_method_spec = envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+        HttpDubboTranscoder_DubboMethodMapping_MatchHttpMethodSpec_Name(
+            envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+                HttpDubboTranscoder_DubboMethodMapping_MatchHttpMethodSpec_ALL_GET);
+    method_info->match_http_method_ = std::string(absl::StripPrefix(http_method_spec, "ALL_"));
+    method_info->match_pattern_ = fmt::format("/{}/{}", service_name, method_info->name_);
+  }
+
+  ENVOY_LOG(debug, "http method: {}, match pattern {}", method_info->match_http_method_,
+            method_info->match_pattern_);
+
+  if (!method_mapping.parameter_mapping().empty()) {
+    method_info->parameter_mapping_ = method_mapping.parameter_mapping();
+  }
+
+  if (method_mapping.has_passthrough_setting()) {
+    const auto& passthrough_setting = method_mapping.passthrough_setting();
+
+    using PassthroughSetting = envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+        HttpDubboTranscoder::DubboMethodMapping::PassthroughSetting;
+    switch (method_mapping.passthrough_setting().headers_setting_case()) {
+    case PassthroughSetting::kPassthroughAllHeaders:
+      method_info->passthrough_all_headers_ = passthrough_setting.passthrough_all_headers();
+      break;
+    case PassthroughSetting::kPassthroughHeaders:
+      method_info->passthrough_header_keys_ = passthrough_setting.passthrough_headers().keys();
+      break;
+    default:
+      NOT_REACHED_GCOVR_EXCL_LINE;
+    }
+  }
+
+  return method_info;
+}
+
+std::tuple<absl::Status, Http2DubboTranscoder*>
+DubboTranscoderConfig::createTranscoder(Http::RequestHeaderMap& headers) const {
+  ASSERT(!disabled_);
+
+  const std::string method(headers.getMethodValue());
+  std::string path(headers.getPathValue());
+  std::string args;
+
+  const size_t pos = path.find('?');
+  if (pos != std::string::npos) {
+    args = path.substr(pos + 1);
+    path = path.substr(0, pos);
+  }
+
+  ENVOY_LOG(debug, "path is {} args is {} method is {}", path, args, method);
+
+  std::vector<VariableBinding> variable_bindings;
+  auto method_info = path_matcher_->Lookup(method, path, args, &variable_bindings, nullptr);
+  if (!method_info) {
+    return {absl::NotFoundError(fmt::format("Could not resolve {} to a method", path)), nullptr};
+  }
+
+  return {absl::OkStatus(), new Http2DubboTranscoder(*method_info, std::move(variable_bindings))};
+}
+
+Http2DubboTranscoder::Http2DubboTranscoder(const MethodInfo& method_info,
+                                           std::vector<VariableBinding>&& bindings)
+    : method_info_(method_info), bindings_(std::move(bindings)) {
+  ENVOY_LOG(debug, "method name is {} method args count is {}", method_info_.name_,
+            method_info_.parameter_mapping_.size());
+};
+
+absl::Status Http2DubboTranscoder::translateDubboToHttp(Buffer::Instance& data) {
+  if (response_buffer_.length() == 0) {
+    response_buffer_.move(data);
+
+    if (response_buffer_.length() < DUBBO_HEADER_SIZE) {
+      return absl::DataLossError("Dubbo message data is incomplete");
+    }
+
+    if (!validateMagicNumber(response_buffer_)) {
+      return absl::InternalError("Illegal Dubbo message");
+    }
+  } else {
+    response_buffer_.move(data);
+  }
+
+  decodeDubboHeader(response_buffer_, response_header_);
+
+  if ((response_header_.type_ & EVENT_BIT_ON) == EVENT_BIT_ON) {
+    response_buffer_.drain(DUBBO_HEADER_SIZE + static_cast<uint64_t>(response_header_.length_));
+    return absl::AbortedError("Heartbeat response should be aborted");
+  }
+
+  if ((static_cast<uint64_t>(response_header_.length_) + DUBBO_HEADER_SIZE) >
+      response_buffer_.length()) {
+    return absl::OutOfRangeError("Invalid dubbo response size");
+  }
+
+  response_buffer_.drain(DUBBO_HEADER_SIZE);
+  std::string response;
+  response.reserve(response_header_.length_);
+  response.resize(response_header_.length_);
+  response_buffer_.copyOut(0, response_header_.length_, &response[0]);
+  response_buffer_.drain(response_header_.length_);
+  Hessian2::Decoder decoder(response);
+  auto type_value = decoder.decode<int32_t>();
+  if (type_value == nullptr) {
+    return absl::InternalError("Cannot parse RpcResult type from buffer");
+  }
+
+  auto type = static_cast<RpcResponseType>(*type_value);
+  auto [has_value, has_exception, has_attachment] = DubboUtility::resolveResponseFlag(type);
+  json http_json;
+  if (has_exception || has_value) {
+    auto response_value = decoder.decode<Object>();
+    http_json[has_value ? HTTPResponseKey : HTTPResponseErrorKey] =
+        DubboUtility::hessian2Json(response_value.get());
+  }
+
+  if (has_attachment) {
+    auto attachment_value = decoder.decode<Object>();
+    http_json[HTTPResponseAttachmentKey] = DubboUtility::hessian2Json(attachment_value.get());
+  }
+
+  data.add(http_json.dump());
+  return absl::OkStatus();
+}
+
+absl::Status Http2DubboTranscoder::extractTranscoderParameters(Http::RequestHeaderMap& headers,
+                                                               Buffer::Instance& body) {
+  ASSERT(!current_params_.has_value());
+
+  ENVOY_LOG(debug, "method name is {} method args count is {}", method_info_.name_,
+            method_info_.parameter_mapping_.size());
+
+  TypedParamsWithAttachment params_and_attachment;
+  params_and_attachment.parameter_types_.resize(method_info_.parameter_mapping_.size());
+  params_and_attachment.arguments_.resize(method_info_.parameter_mapping_.size());
+
+  uint8_t current_path_binding_index = 1;
+  uint8_t current_params_index = 0;
+  using ParameterMapping = envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+      HttpDubboTranscoder::DubboMethodMapping::ParameterMapping;
+  json body_json;
+  if (!body.toString().empty()) {
+    // If the exception is not caught, a core dump error may occur
+    try {
+      body_json = json::parse(body.toString());
+    } catch (json::parse_error& e) {
+      ENVOY_LOG(warn, "json::parse throw exception : {}", e.what());
+    }
+  }
+
+  for (const auto& parameter : method_info_.parameter_mapping_) {
+    const auto& extract_key = parameter.extract_key();
+    ENVOY_LOG(debug, "parameter extract key {}", extract_key);
+
+    std::string parameter_value;
+    switch (parameter.extract_key_spec()) {
+    case ParameterMapping::ALL_QUERY_PARAMETER: {
+      Http::Utility::QueryParams params = Http::Utility::parseQueryString(headers.getPathValue());
+      if (params.empty()) {
+        return absl::InternalError("Error parsing query parameters");
+      }
+
+      if (!params.count(extract_key)) {
+        return absl::NotFoundError(fmt::format("The parameter {} could not be found", extract_key));
+      }
+      parameter_value = params[extract_key];
+      break;
+    }
+    case ParameterMapping::ALL_HEADER: {
+      auto result = headers.get(Http::LowerCaseString(extract_key));
+      if (result.empty()) {
+        return absl::NotFoundError(fmt::format("The header {} could not be found", extract_key));
+      }
+      parameter_value = std::string(result[0]->value().getStringView());
+      break;
+    }
+    case ParameterMapping::ALL_PATH: {
+      if (current_path_binding_index > bindings_.size()) {
+        return absl::OutOfRangeError("Error parsing query parameters");
+      }
+      parameter_value = bindings_.at(current_path_binding_index - 1).value;
+      current_path_binding_index++;
+      break;
+    }
+    case ParameterMapping::ALL_BODY: {
+      if (body_json.is_discarded() || body_json.is_null()) {
+        return absl::InvalidArgumentError("the body can not be parsed as json or body is empty.");
+      } else {
+        if (!extract_key.empty()) {
+          auto key = body_json.find(extract_key);
+          if (key == body_json.end()) {
+            return absl::NotFoundError(
+                fmt::format("The parameter {} could not be found", extract_key));
+          }
+          params_and_attachment.arguments_[current_params_index] = *key;
+        } else {
+          params_and_attachment.arguments_[current_params_index] = body_json;
+        }
+        params_and_attachment.parameter_types_[current_params_index] = parameter.mapping_type();
+      }
+      current_params_index++;
+      continue;
+    }
+    default:
+      return absl::UnimplementedError("Unsupported types");
+    }
+
+    ENVOY_LOG(debug, "parameter extract value {}, type {}", parameter_value,
+              parameter.mapping_type());
+
+    absl::optional<json> result =
+        DubboUtility::convertStringToTypeValue(parameter_value, parameter.mapping_type());
+    if (!result) {
+      return absl::InvalidArgumentError(
+          "can not transcode the request because the given param not match the type");
+    }
+
+    params_and_attachment.arguments_[current_params_index] = result.value();
+    params_and_attachment.parameter_types_[current_params_index] = parameter.mapping_type();
+    current_params_index++;
+  }
+
+  ENVOY_LOG(debug, "method name is {} method args count is {}", method_info_.name_,
+            method_info_.parameter_mapping_.size());
+
+  if (method_info_.passthrough_all_headers_.has_value()) {
+    if (method_info_.passthrough_all_headers_.value()) {
+      headers.iterate(
+          [&params_and_attachment](const Http::HeaderEntry& header) -> Http::HeaderMap::Iterate {
+            const std::string& header_key = {header.key().getStringView().begin(),
+                                             header.key().getStringView().end()};
+            params_and_attachment.attachment_[header_key] = header.value().getStringView();
+            return Http::HeaderMap::Iterate::Continue;
+          });
+    }
+  } else {
+    if (method_info_.passthrough_header_keys_.has_value()) {
+      for (const auto& key : method_info_.passthrough_header_keys_.value()) {
+
+        auto result = headers.get(Http::LowerCaseString(key));
+        if (result.empty()) {
+          return absl::NotFoundError(fmt::format("The header {} could not be found", key));
+        }
+        params_and_attachment.attachment_[key] = result[0]->value().getStringView();
+      }
+    } else {
+      ENVOY_LOG(debug, "passthrough_header_keys has no value");
+    }
+  }
+
+  if (!method_info_.service_group_.empty()) {
+    params_and_attachment.attachment_[AttachmentGroupKey] = method_info_.service_group_;
+  }
+
+  current_params_.emplace(params_and_attachment);
+  return absl::OkStatus();
+}
+
+void Http2DubboTranscoder::encodeDubboFrameWithGenericCall(Buffer::Instance& data) {
+  // Encode dubbo data.
+  std::string encoded_data;
+  Hessian2::Encoder encoder(encoded_data);
+
+  // Write dubbo header.
+  {
+    // Write the dubbo protocol: magic-number\type\serialization id\status.
+    data.writeBEInt(static_cast<uint16_t>(DUBBO_MAGIC));
+    data.writeBEInt(static_cast<uint8_t>(TYPE_INFO));
+    data.writeBEInt(static_cast<uint8_t>(DEFAULT_REQUEST_STAT));
+
+    // Write the request id.
+    // TODO(zhaobingkun.zbk)
+    if (RequestId == ULONG_MAX) {
+      RequestId = 0;
+    }
+    data.writeBEInt(static_cast<int64_t>(++RequestId));
+  }
+
+  // Encode dubbo body.
+  {
+    // Encode: dubbo version\service name\service version.
+    encoder.encode(DubboDefaultProtocolVsersion);
+    encoder.encode(method_info_.service_name_);
+    encoder.encode(method_info_.service_version_.empty() ? DubboDefaultMethodVersion
+                                                         : method_info_.service_version_);
+    // Encode: method name\parameter type, use generic call.
+    encoder.encode(DubboGenericMethodName);
+    encoder.encode(DubboGenericParamTypes);
+
+    // Encode: arguments.
+    encoder.encode(method_info_.name_);
+    if (current_params_.has_value()) {
+      auto type_j = json(current_params_.value().parameter_types_);
+      DubboUtility::encodeParameterList(type_j, encoder);
+
+      auto params_j = json(current_params_.value().arguments_);
+      DubboUtility::encodeParameterList(params_j, encoder);
+    } else {
+      ENVOY_LOG(debug, "The parameter is empty");
+    }
+  }
+
+  // Encode attachment.
+  {
+    if (!current_params_.value().attachment_.is_null()) {
+      DubboUtility::json2Hessian(current_params_.value().attachment_, encoder);
+    } else {
+      encoder.encodeMapBegin("");
+      encoder.encodeMapEnd();
+    }
+  }
+
+  // Write the message data length.
+  data.writeBEInt(static_cast<uint32_t>(encoded_data.size()));
+
+  // Write body and attachment data.
+  data.add(encoded_data.c_str(), encoded_data.size());
+
+  ENVOY_LOG(debug, "encoded data is {} size is {} ", data.toString(), data.length());
+}
+
+inline bool Http2DubboTranscoder::validateMagicNumber(Buffer::Instance& data) {
+  return data.peekBEInt<uint16_t>() == DUBBO_MAGIC;
+}
+
+void Http2DubboTranscoder::decodeDubboHeader(Buffer::Instance& data, Header& dubbo_header) {
+  ASSERT(data.length() >= DUBBO_HEADER_SIZE);
+
+  uint64_t start_position = 0;
+  dubbo_header.magic_ = data.peekBEInt<uint16_t>(start_position);
+
+  start_position += sizeof(dubbo_header.magic_);
+  dubbo_header.type_ = data.peekBEInt<uint8_t>(start_position);
+
+  start_position += sizeof(dubbo_header.type_);
+  dubbo_header.state_ = data.peekBEInt<uint8_t>(start_position);
+
+  start_position += sizeof(dubbo_header.state_);
+  dubbo_header.reqId_ = data.peekBEInt<int64_t>(start_position);
+
+  start_position += sizeof(dubbo_header.reqId_);
+  dubbo_header.length_ = data.peekBEInt<int32_t>(start_position);
+}
+
+void TranscodeFilter::initPerRouteConfig() {
+  const auto* route_local =
+      Http::Utility::resolveMostSpecificPerFilterConfig<DubboTranscoderConfig>(
+          "envoy.filters.http.http_dubbo_transcoder", decoder_callbacks_->route());
+
+  per_route_config_ = route_local ? route_local : &config_;
+}
+
+// transcoder filter impl
+Http::FilterHeadersStatus TranscodeFilter::decodeHeaders(Http::RequestHeaderMap& header,
+                                                         bool end_stream) {
+  initPerRouteConfig();
+  if (per_route_config_->disabled()) {
+    return Http::FilterHeadersStatus::Continue;
+  }
+
+  ENVOY_STREAM_LOG(debug, "decodeHeaders:", *decoder_callbacks_);
+
+  auto [status, transcoder] = per_route_config_->createTranscoder(header);
+  if (!status.ok()) {
+    ENVOY_STREAM_LOG(debug, "Failed to transcode request headers: {}", *decoder_callbacks_,
+                     status.ToString());
+
+    if (status.code() == absl::StatusCode::kNotFound &&
+        !per_route_config_->requestValidateOptions().reject_unknown_method()) {
+      ENVOY_LOG(debug, "Request is passed through without transcoding because it cannot be mapped "
+                       "to a Dubbo method.");
+      return Http::FilterHeadersStatus::Continue;
+    }
+    error_ = true;
+    decoder_callbacks_->sendLocalReply(static_cast<Http::Code>(Http::Code::InternalServerError),
+                                       status.ToString(), nullptr, absl::nullopt, "");
+    return Http::FilterHeadersStatus::StopIteration;
+  }
+
+  transcoder_.reset(transcoder);
+
+  if (end_stream) {
+    Buffer::OwnedImpl empty_data;
+    status = transcoder_->extractTranscoderParameters(header, empty_data);
+    if (!status.ok()) {
+      ENVOY_LOG(warn, "Failed to resolve headers, error is {}", status.ToString());
+
+      // TODO(zhaobingkun.zbk)
+      Http::Code http_code = DubboUtility::convertStatusToHttpCode(status.code());
+      error_ = true;
+      decoder_callbacks_->sendLocalReply(static_cast<Http::Code>(http_code), status.ToString(),
+                                         nullptr, absl::nullopt, "");
+      return Http::FilterHeadersStatus::StopIteration;
+    }
+
+    Buffer::OwnedImpl data;
+    transcoder_->encodeDubboFrameWithGenericCall(data);
+    decoder_callbacks_->addDecodedData(data, true);
+    ENVOY_STREAM_LOG(debug, "sent dubbo frame", *decoder_callbacks_);
+  }
+
+  // Modify the request method to use http.tcp connection pools.
+  header.setMethod(Http::Headers::get().MethodValues.Connect);
+  request_header_ = &header;
+  return Http::FilterHeadersStatus::Continue;
+}
+
+Http::FilterDataStatus TranscodeFilter::decodeData(Buffer::Instance& data, bool end_stream) {
+  if (data.length() == 0) {
+    return Http::FilterDataStatus::Continue;
+  }
+
+  if (!transcoder_ || error_) {
+    ENVOY_STREAM_LOG(debug, "Transcoder does not exist or an error occurred, end_stream: {}",
+                     *decoder_callbacks_, end_stream);
+
+    return Http::FilterDataStatus::Continue;
+  }
+
+  const auto status = transcoder_->extractTranscoderParameters(*request_header_, data);
+  if (!status.ok()) {
+    ENVOY_LOG(warn, "Failed to auto mapping body, error is {}", status.ToString());
+
+    // TODO(zhaobingkun.zbk)
+    Http::Code http_code = DubboUtility::convertStatusToHttpCode(status.code());
+    error_ = true;
+    decoder_callbacks_->sendLocalReply(static_cast<Http::Code>(http_code), status.ToString(),
+                                       nullptr, absl::nullopt, "");
+    return Http::FilterDataStatus::StopIterationNoBuffer;
+  }
+
+  data.drain(data.length());
+  transcoder_->encodeDubboFrameWithGenericCall(data);
+
+  ENVOY_STREAM_LOG(debug, "encoded dubbo frame, length: {}, data: {}", *decoder_callbacks_,
+                   data.length(), data.toString());
+
+  return Http::FilterDataStatus::Continue;
+}
+
+Http::FilterTrailersStatus TranscodeFilter::decodeTrailers(Http::RequestTrailerMap&) {
+  return Http::FilterTrailersStatus::Continue;
+}
+
+Http::FilterHeadersStatus TranscodeFilter::encodeHeaders(Http::ResponseHeaderMap&, bool) {
+  return Http::FilterHeadersStatus::Continue;
+}
+
+Http::FilterDataStatus TranscodeFilter::encodeData(Buffer::Instance& data, bool end_stream) {
+  ENVOY_STREAM_LOG(debug, "Recieve data from remote {} length is {} end_stream is {}",
+                   *decoder_callbacks_, data.toString(), data.length(), end_stream);
+
+  if (transcoder_) {
+    absl::Status status = transcoder_->translateDubboToHttp(data);
+    if (!status.ok()) {
+      if (status.code() != absl::StatusCode::kAborted) {
+        Http::Code http_code = DubboUtility::convertStatusToHttpCode(status.code());
+        error_ = true;
+        decoder_callbacks_->sendLocalReply(static_cast<Http::Code>(http_code), status.ToString(),
+                                           nullptr, absl::nullopt, "");
+      }
+      return Http::FilterDataStatus::StopIterationNoBuffer;
+    }
+  }
+
+  return Http::FilterDataStatus::Continue;
+}
+
+Http::FilterTrailersStatus TranscodeFilter::encodeTrailers(Http::ResponseTrailerMap&) {
+  if (transcoder_) {
+    transcoder_.reset();
+  }
+
+  return Http::FilterTrailersStatus::Continue;
+}
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h b/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h
new file mode 100644
index 0000000000..39ba90821e
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h
@@ -0,0 +1,238 @@
+#pragma once
+
+#include <sstream>
+#include <unordered_map>
+#include <vector>
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/transcoder.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/utility.h"
+
+#include "envoy/api/api.h"
+#include "envoy/http/filter.h"
+#include "envoy/type/matcher/v3/regex.pb.h"
+
+#include "source/common/common/logger_impl.h"
+#include "source/common/common/logger.h"
+#include "source/common/common/regex.h"
+#include "source/common/http/codes.h"
+#include "source/common/http/header_map_impl.h"
+
+#include "grpc_transcoding/path_matcher.h"
+
+#include "hessian2/basic_codec/object_codec.hpp"
+#include "hessian2/codec.hpp"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+class Http2DubboTranscoder;
+
+/***
+ * transcoder config
+ */
+class DubboTranscoderConfig : public Router::RouteSpecificFilterConfig,
+                              public Logger::Loggable<Logger::Id::config> {
+public:
+  /***
+   * resolve the global enable falg in the config
+   */
+  DubboTranscoderConfig(
+      const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder&
+          config);
+
+  /***
+   * this function will create the corresponding transcoder acccording to the
+   * headers, mainly according to the content-type field
+   *
+   * @return nullptr if the any thing wrong when create transcoder
+   */
+  std::tuple<absl::Status, Http2DubboTranscoder*>
+  createTranscoder(Http::RequestHeaderMap& headers) const;
+
+  MethodInfoSharedPtr
+  createMethodInfo(const std::string& service_name, const std::string& service_version,
+                   const std::string& service_group,
+                   const envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+                       HttpDubboTranscoder::DubboMethodMapping& method_mapping);
+
+  /***
+   * wether enable the transcoder
+   */
+  bool disabled() const { return disabled_; }
+
+  const envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+      RequestValidateOptions&
+      requestValidateOptions() const {
+    return request_validate_options_;
+  }
+
+private:
+  bool disabled_{false};
+  envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder::
+      RequestValidateOptions request_validate_options_;
+  google::grpc::transcoding::PathMatcherPtr<MethodInfoSharedPtr> path_matcher_;
+};
+
+using DubboTranscoderConfigSharedPtr = std::shared_ptr<DubboTranscoderConfig>;
+
+/***
+ * the error maybe occured while peoccsing the header or body
+ * 0 means no error
+ */
+enum class ParamsErrorCode : int8_t {
+  OK = 0,
+  CountError = 1,
+  TypeError = 2,
+  ParseError = 4,
+  MethodNotFound = 5,
+  OthersError = 7,
+};
+
+// DUBBO HEADER FRAME
+struct Header {
+  uint16_t magic_;
+  uint8_t type_;
+  uint8_t state_;
+  int64_t reqId_;
+  int32_t length_;
+};
+
+constexpr uint64_t DUBBO_HEADER_SIZE = 16;
+constexpr uint64_t DUBBO_MAGIC_SIZE = 2;
+constexpr uint64_t DUBBO_TYPE_SIZE = 1;
+constexpr uint64_t DUBBO_STATE_SIZE = 1;
+constexpr uint64_t DUBBO_REQID_SIZE = 8;
+constexpr uint64_t DUBBO_PACKETLEN_SIZE = 4;
+constexpr uint16_t DUBBO_MAGIC = 0xdabb;
+constexpr uint8_t DEFAULT_REQUEST_STAT = 0;
+constexpr int64_t DEFAULT_REQUEST_ID = 1;
+/**
+ *
+ * | req or response | 2 way | event | Serializtion |
+ * |       1         |    1  |    0  |      2       |
+ * |       1         |    1  |    0  |    00010     |
+ * more details:
+ * https://dubbo.apache.org/en/blog/2018/10/05/introduction-to-the-dubbo-protocol/
+ */
+constexpr uint8_t TYPE_INFO = 0xc2;
+
+// this type point to the state_ field in the Header struct
+enum class ResponseStatus : uint8_t {
+  Ok = 20,
+  ClientTimeout = 30,
+  ServerTimeout = 31,
+  BadRequest = 40,
+  BadResponse = 50,
+  ServiceNotFound = 60,
+  ServiceError = 70,
+  ServerError = 80,
+  ClientError = 90,
+  ServerThreadpoolExhaustedError = 100,
+};
+
+/***
+ * Rpc response represent used by DubboDecoder
+ */
+struct RpcResponse {
+  std::string body_;
+  Envoy::Http::Code code_;
+};
+
+using RpcResponsePtr = std::unique_ptr<RpcResponse>;
+
+/***
+ * this class transcode the http request to dubbo request
+ * the transcode support http2Dubbo specification
+ * the transcode split into 2 condition:
+ * 1. service map (one path corresponding to a set methods of a service)
+ * 2. method map (one path corresponding to one method)
+ */
+class Http2DubboTranscoder : public Logger::Loggable<Logger::Id::filter> {
+public:
+  /***
+   * @param method_info_vec the correspond methodinfo of the request,come from sharedPtr of
+   * pathmatcher
+   * @param config the transcoder config
+   */
+  Http2DubboTranscoder(const MethodInfo& method_info, std::vector<VariableBinding>&& bindings);
+
+  std::string getName() const { return "http_dubbo_transcoder"; }
+
+  absl::Status translateDubboToHttp(Buffer::Instance& data);
+  absl::Status extractTranscoderParameters(Http::RequestHeaderMap& headers, Buffer::Instance& body);
+
+  void encodeDubboFrameWithGenericCall(Buffer::Instance& data);
+
+private:
+  bool validateMagicNumber(Buffer::Instance& data);
+  void decodeDubboHeader(Buffer::Instance& data, Header& dubbo_header);
+
+  struct TypedParamsWithAttachment {
+    std::vector<std::string> parameter_types_;
+    std::vector<json> arguments_;
+    nlohmann::json attachment_;
+  };
+
+  const MethodInfo& method_info_;
+  const std::vector<VariableBinding> bindings_;
+  Buffer::OwnedImpl request_buffer_{};
+  Buffer::OwnedImpl response_buffer_{};
+  Header response_header_;
+  absl::optional<TypedParamsWithAttachment> current_params_;
+};
+
+using Http2DubboTranscoderPtr = std::unique_ptr<Http2DubboTranscoder>;
+
+/***
+ * Transcoder Filter
+ */
+class TranscodeFilter : public Http::StreamFilter, public Logger::Loggable<Logger::Id::filter> {
+public:
+  TranscodeFilter(DubboTranscoderConfig& config) : config_(config){};
+  // Http::StreamFilterBase
+  void onDestroy() override{};
+
+  // Http::StreamDecoderFilter
+  Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers,
+                                          bool end_stream) override;
+  Http::FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override;
+  Http::FilterTrailersStatus decodeTrailers(Http::RequestTrailerMap&) override;
+  void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override {
+    decoder_callbacks_ = &callbacks;
+  }
+
+  // Http::StreamEncoderFilter
+  Http::FilterHeadersStatus encode100ContinueHeaders(Http::ResponseHeaderMap&) override {
+    return Http::FilterHeadersStatus::Continue;
+  }
+  Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap&, bool) override;
+  Http::FilterDataStatus encodeData(Buffer::Instance&, bool) override;
+  Http::FilterTrailersStatus encodeTrailers(Http::ResponseTrailerMap&) override;
+  Http::FilterMetadataStatus encodeMetadata(Http::MetadataMap&) override {
+    return Http::FilterMetadataStatus::Continue;
+  }
+  void setEncoderFilterCallbacks(Http::StreamEncoderFilterCallbacks& callbacks) override {
+    encoder_callbacks_ = &callbacks;
+  }
+
+private:
+  void initPerRouteConfig();
+
+  Http2DubboTranscoderPtr transcoder_;
+  DubboTranscoderConfig& config_;
+  const DubboTranscoderConfig* per_route_config_{};
+  Http::StreamEncoderFilterCallbacks* encoder_callbacks_{};
+  Http::StreamDecoderFilterCallbacks* decoder_callbacks_{};
+  Http::RequestHeaderMap* request_header_{};
+
+  bool error_{false};
+};
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/transcoder.h b/contrib/http_dubbo_transcoder/filters/http/source/transcoder.h
new file mode 100644
index 0000000000..693de1fb4d
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/transcoder.h
@@ -0,0 +1,60 @@
+#pragma once
+
+#include <vector>
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+#include "envoy/http/filter.h"
+
+#include "source/common/buffer/buffer_impl.h"
+#include "source/common/common/logger.h"
+#include "source/common/http/codes.h"
+#include "source/common/http/header_map_impl.h"
+
+#include "absl/container/flat_hash_map.h"
+#include "absl/status/status.h"
+#include "include/nlohmann/json.hpp"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+using Status = absl::Status;
+
+/***
+ * the Rpc invocation meta represent
+ */
+
+struct VariableBinding {
+  // the location the params in the dubbo request arg
+  std::vector<std::string> field_path;
+  // The value to be inserted.
+  std::string value;
+};
+using VariableBindingVecPtr = std::unique_ptr<std::vector<VariableBinding>>;
+
+using TypeAndFiledPath = std::pair<std::string, std::vector<std::string>>;
+
+struct MethodInfo {
+  std::string service_name_;
+  std::string service_version_;
+  std::string service_group_;
+  std::string name_;
+  std::string match_http_method_;
+  std::string match_pattern_;
+  Protobuf::RepeatedPtrField<envoy::extensions::filters::http::http_dubbo_transcoder::v3::
+                                 HttpDubboTranscoder_DubboMethodMapping_ParameterMapping>
+      parameter_mapping_;
+  Protobuf::RepeatedPtrField<std::string> attachment_from_header_keys_;
+  absl::optional<bool> passthrough_all_headers_;
+  absl::optional<Protobuf::RepeatedPtrField<std::string>> passthrough_header_keys_;
+  bool passthrough_body_{false};
+};
+
+using MethodInfoSharedPtr = std::shared_ptr<MethodInfo>;
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/utility.cc b/contrib/http_dubbo_transcoder/filters/http/source/utility.cc
new file mode 100644
index 0000000000..8af0557a05
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/utility.cc
@@ -0,0 +1,284 @@
+#include "utility.h"
+
+#include <iostream>
+#include <vector>
+
+#include "envoy/http/codes.h"
+#include "envoy/http/query_params.h"
+
+#include "source/common/buffer/buffer_impl.h"
+#include "source/common/common/enum_to_int.h"
+#include "source/common/common/regex.h"
+
+#include "absl/strings/str_split.h"
+#include "hessian2/object.hpp"
+#include "include/nlohmann/json.hpp"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+absl::optional<json> DubboUtility::convertStringToTypeValue(absl::string_view value,
+                                                            std::string type) {
+
+  // the return value converted value maybe int boolean string, so use json to store the value
+  if (type == JsonType2JavaType.at(json::value_t::boolean)) {
+    if (value == "true" || value == "false") {
+      return {json(value == "true" ? true : false)};
+    }
+    return absl::nullopt;
+  } else if (type == JsonType2JavaType.at(json::value_t::number_float)) {
+    envoy::type::matcher::v3::RegexMatcher matcher;
+    *matcher.mutable_google_re2() = envoy::type::matcher::v3::RegexMatcher::GoogleRE2();
+    matcher.set_regex("^-?([1-9]\\d*\\.\\d*|0\\.\\d*[1-9]\\d*|0?\\.0+|0)$");
+    const auto compiled_matcher = Regex::Utility::parseRegex(matcher);
+    if (!compiled_matcher->match(value)) {
+      return absl::nullopt;
+    }
+    return {json(strtod(value.data(), nullptr))};
+  } else if (type == JsonType2JavaType.at(json::value_t::number_integer)) {
+    envoy::type::matcher::v3::RegexMatcher matcher;
+    *matcher.mutable_google_re2() = envoy::type::matcher::v3::RegexMatcher::GoogleRE2();
+    matcher.set_regex("^(0|[1-9][0-9]*|-[1-9][0-9]*)$");
+    const auto compiled_matcher = Regex::Utility::parseRegex(matcher);
+    if (!compiled_matcher->match(value)) {
+      return absl::nullopt;
+    }
+    return {json(strtoll(value.data(), nullptr, 10))};
+  } else if (type == JsonType2JavaType.at(json::value_t::string)) {
+    return {json(value)};
+  } else if (type == JsonType2JavaType.at(json::value_t::array)) {
+    json array_json;
+    array_json.emplace_back(std::string(value));
+    return array_json;
+  } else {
+    return absl::nullopt;
+  }
+}
+
+Http::Code DubboUtility::convertStatusToHttpCode(absl::StatusCode status) {
+  Http::Code ret_http_code;
+
+  switch (status) {
+  case absl::StatusCode::kInternal:
+    ret_http_code = Http::Code::InternalServerError;
+    break;
+  case absl::StatusCode::kNotFound:
+    ret_http_code = Http::Code::NotFound;
+    break;
+  case absl::StatusCode::kOutOfRange:
+    ret_http_code = Http::Code::RangeNotSatisfiable;
+    break;
+  case absl::StatusCode::kUnimplemented:
+    ret_http_code = Http::Code::NotImplemented;
+    break;
+  case absl::StatusCode::kInvalidArgument:
+    ret_http_code = Http::Code::BadRequest;
+    break;
+  case absl::StatusCode::kDataLoss:
+    ret_http_code = Http::Code::BadRequest;
+    break;
+  default:
+    ret_http_code = Http::Code::NotFound;
+  }
+
+  return ret_http_code;
+}
+
+std::tuple<bool, bool, bool> DubboUtility::resolveResponseFlag(RpcResponseType flag) {
+  bool has_value = false, has_excption = false, has_attachment = false;
+
+  switch (flag) {
+  case RpcResponseType::ResponseWithException:
+    has_excption = true;
+    break;
+  case RpcResponseType::ResponseWithExceptionWithAttachments:
+    has_excption = true;
+    has_attachment = true;
+    break;
+  case RpcResponseType::ResponseWithNullValue:
+    has_value = false;
+    break;
+  case RpcResponseType::ResponseNullValueWithAttachments:
+    has_value = false;
+    has_attachment = true;
+    break;
+  case RpcResponseType::ResponseWithValue:
+    has_value = true;
+    break;
+  case RpcResponseType::ResponseValueWithAttachments:
+    has_value = true;
+    has_attachment = true;
+    break;
+  }
+
+  return {has_value, has_excption, has_attachment};
+}
+
+json DubboUtility::hessian2Json(Object* input) {
+  json out;
+
+  if (input == nullptr) {
+    out = NullValue;
+    return out;
+  }
+
+  switch (input->type()) {
+  case Object::Type::TypedMap:
+  case Object::Type::UntypedMap: {
+    for (auto& item : input->asType<Hessian2::UntypedMapObject>()) {
+      Hessian2::StringObject& key = item.first->asType<Hessian2::StringObject>();
+      if (key.toMutableString() != nullptr && *(key.toMutableString()) != ClassKey) {
+        out[*(key.toMutableString())] = hessian2Json(item.second.get());
+      }
+    }
+  } break;
+
+  case Object::Type::UntypedList:
+  case Object::Type::TypedList: {
+    for (auto& item : input->asType<Hessian2::TypedListObject>()) {
+      json j = hessian2Json(item.get());
+      out.push_back(j);
+    }
+  } break;
+
+  case Object::Type::String: {
+    out = *(input->asType<Hessian2::StringObject>().toMutableString());
+  } break;
+
+  case Object::Type::Double: {
+    out = *(input->asType<Hessian2::DoubleObject>().toMutableDouble());
+  } break;
+
+  case Object::Type::Integer: {
+    out = *(input->asType<Hessian2::IntegerObject>().toMutableInteger());
+  } break;
+
+  case Object::Type::Long: {
+    out = *(input->asType<Hessian2::LongObject>().toMutableLong());
+  } break;
+
+  case Object::Type::Boolean: {
+    out = *(input->asType<Hessian2::BooleanObject>().toMutableBoolean());
+  } break;
+
+  case Object::Type::Ref: {
+    out = hessian2Json((input->asType<Hessian2::RefObject>().toRefDest().value()));
+  } break;
+
+  case Object::Type::Class:
+    out = input->toClassInstance().value()->def_->type_;
+    break;
+
+  case Object::Type::Date:
+    out = input->toMutableDate()->count();
+    break;
+
+  case Object::Type::Null:
+    out = NullValue;
+    break;
+
+  case Object::Type::Binary:
+    out = *(input->toMutableBinary());
+    break;
+
+  default:
+    break;
+  }
+
+  return out;
+}
+
+void DubboUtility::json2Hessian(json&& object, Hessian2::Encoder& encoder) {
+  auto type = object.type();
+  switch (type) {
+  case json::value_t::object: {
+    encoder.encodeMapBegin("");
+    for (auto& el : object.items()) {
+      encoder.encode<std::string>(el.key());
+      json2Hessian(el.value(), encoder);
+    }
+    encoder.encodeMapEnd();
+  } break;
+
+  case json::value_t::boolean:
+    encoder.encode<bool>(object.get<bool>());
+    break;
+
+  case json::value_t::number_integer:
+  case json::value_t::number_unsigned:
+    encoder.encode<int64_t>(object.get<int64_t>());
+    break;
+
+  case json::value_t::number_float:
+    encoder.encode<double>(object.get<double>());
+    break;
+
+  case json::value_t::array: {
+    Hessian2::Object::UntypedList untyped_list;
+    for (auto& item : object.items()) {
+      createUntypedListObjcet(item.value(), untyped_list);
+    }
+    Hessian2::UntypedListObject untyped_list_object(std::move(untyped_list));
+    encoder.encode<Hessian2::UntypedListObject>(untyped_list_object);
+  } break;
+
+  case json::value_t::string:
+    encoder.encode<std::string>(object.get<std::string>());
+    break;
+
+  case json::value_t::binary:
+    encoder.encode<std::vector<uint8_t>>(object.get_binary());
+    break;
+
+  case json::value_t::null:
+  default:
+    encoder.encode<Object>(Hessian2::NullObject());
+    break;
+  }
+}
+
+void DubboUtility::json2Hessian(json& j, Hessian2::Encoder& encoder) {
+  DubboUtility::json2Hessian(std::move(j), encoder);
+}
+
+void DubboUtility::encodeParameterList(json& j, Hessian2::Encoder& encoder) {
+  encoder.encodeVarListBegin("");
+  for (auto& item : j.items()) {
+    json2Hessian(item.value(), encoder);
+  }
+  encoder.encodeVarListEnd();
+}
+
+void DubboUtility::createUntypedListObjcet(const json& object,
+                                           Hessian2::Object::UntypedList& untyped_list) {
+  auto type = object.type();
+  switch (type) {
+  case json::value_t::string:
+    untyped_list.emplace_back(std::make_unique<Hessian2::StringObject>(object.get<std::string>()));
+    break;
+  case json::value_t::number_unsigned:
+  case json::value_t::number_integer:
+    untyped_list.emplace_back(std::make_unique<Hessian2::IntegerObject>(object.get<int64_t>()));
+    break;
+  case json::value_t::number_float:
+    untyped_list.emplace_back(std::make_unique<Hessian2::DoubleObject>(object.get<double>()));
+    break;
+  case json::value_t::boolean:
+    untyped_list.emplace_back(std::make_unique<Hessian2::BooleanObject>(object.get<bool>()));
+    break;
+  case json::value_t::binary:
+    untyped_list.emplace_back(std::make_unique<Hessian2::BinaryObject>(object.get_binary()));
+    break;
+  case json::value_t::null:
+  default:
+    untyped_list.emplace_back(std::make_unique<Hessian2::NullObject>());
+    break;
+  }
+}
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/source/utility.h b/contrib/http_dubbo_transcoder/filters/http/source/utility.h
new file mode 100644
index 0000000000..bd7c197468
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/source/utility.h
@@ -0,0 +1,88 @@
+#pragma once
+#include <iostream>
+#include <vector>
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+#include "envoy/http/codes.h"
+#include "envoy/http/query_params.h"
+
+#include "source/common/buffer/buffer_impl.h"
+#include "source/common/common/enum_to_int.h"
+#include "source/common/common/regex.h"
+#include "source/common/http/utility.h"
+
+#include "hessian2/basic_codec/object_codec.hpp"
+#include "hessian2/object.hpp"
+#include "include/nlohmann/json.hpp"
+#include "transcoder.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+using json = nlohmann::json;
+using Object = Hessian2::Object;
+using ObjectPtr = std::unique_ptr<Object>;
+using ListObject = Hessian2::UntypedListObject;
+using ListObjectPtr = std::unique_ptr<ListObject>;
+using StringObject = Hessian2::StringObject;
+using StringObjectPtr = std::unique_ptr<StringObject>;
+using MapObject = Hessian2::UntypedMapObject;
+using MapObjectPtr = std::unique_ptr<MapObject>;
+
+static const std::string NullValue = "null";
+static const std::string ClassKey = "class";
+
+static const absl::flat_hash_map<json::value_t, std::string> JsonType2JavaType{
+    {json::value_t::number_integer, "java.lang.Long"},
+    {json::value_t::number_unsigned, "java.lang.Long"},
+    {json::value_t::string, "java.lang.String"},
+    {json::value_t::boolean, "java.lang.Boolean"},
+    {json::value_t::array, "java.util.List"},
+    {json::value_t::object, "java.util.Map"},
+    {json::value_t::number_float, "java.lang.Double"},
+    {json::value_t::null, ""},
+};
+
+// the first byte in the response body express the response type
+enum class RpcResponseType : uint8_t {
+  ResponseWithException = 0,
+  ResponseWithValue = 1,
+  ResponseWithNullValue = 2,
+  ResponseWithExceptionWithAttachments = 3,
+  ResponseValueWithAttachments = 4,
+  ResponseNullValueWithAttachments = 5,
+};
+
+class DubboUtility {
+public:
+  /***
+   * this is a tool funtion convert a string view value to the given type value
+   * now just support base type:
+   * 1. Integer
+   * 2. Boolean
+   * 3. Double
+   * 4. String
+   *
+   * other types will return absl::nullopt
+   * @return the true value represent by json
+   *
+   */
+  static absl::optional<json> convertStringToTypeValue(absl::string_view, std::string);
+  static Http::Code convertStatusToHttpCode(absl::StatusCode status);
+
+  // hessian2 json translate
+  static json hessian2Json(Object* obj);
+  static void json2Hessian(json&& j, Hessian2::Encoder& encoder);
+  static void json2Hessian(json& j, Hessian2::Encoder& encoder);
+  static void encodeParameterList(json& j, Hessian2::Encoder& encoder);
+  static void createUntypedListObjcet(const json& object, Hessian2::Object::UntypedList& untyped_list);
+  static std::tuple<bool, bool, bool> resolveResponseFlag(RpcResponseType flag);
+};
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/BUILD b/contrib/http_dubbo_transcoder/filters/http/test/BUILD
new file mode 100644
index 0000000000..ee22ba5512
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/BUILD
@@ -0,0 +1,31 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_test",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_test(
+    name = "config_test",
+    srcs = ["config_test.cc"],
+    deps = [
+        "//contrib/http_dubbo_transcoder/filters/http/source:config",
+        "//test/mocks/server:factory_context_mocks",
+        "//test/test_common:utility_lib",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_test(
+    name = "dubbo_transcoder_filter_test",
+    srcs = ["dubbo_transcoder_filter_test.cc"],
+    deps = [
+        "//contrib/http_dubbo_transcoder/filters/http/source:config",
+        "//test/mocks/server:factory_context_mocks",
+        "//test/test_common:utility_lib",
+        "@envoy_api//contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/config_test.cc b/contrib/http_dubbo_transcoder/filters/http/test/config_test.cc
new file mode 100644
index 0000000000..a8a224284d
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/config_test.cc
@@ -0,0 +1,80 @@
+#include "test/mocks/server/factory_context.h"
+#include "test/test_common/utility.h"
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/config.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::_;
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+TEST(HttpDubboTranscodeFilterFactoryTest, HttpDubboTranscodeFilterCorrectYaml) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: true
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+  envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder proto_config;
+  TestUtility::loadFromYaml(yaml_string, proto_config);
+  NiceMock<Server::Configuration::MockFactoryContext> context;
+  HttpDubboTranscodeFilterFactory factory;
+  Http::FilterFactoryCb cb = factory.createFilterFactoryFromProto(proto_config, "stats", context);
+  Http::MockFilterChainFactoryCallbacks filter_callback;
+  EXPECT_CALL(filter_callback, addStreamFilter(_));
+  cb(filter_callback);
+}
+
+TEST(HttpDubboTranscodeFilterFactoryTest, HttpDubboTranscodePerFilterCorrectYaml) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: true
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping: 
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+  envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder proto_config;
+  TestUtility::loadFromYaml(yaml_string, proto_config);
+  NiceMock<Server::Configuration::MockServerFactoryContext> context;
+  HttpDubboTranscodeFilterFactory factory;
+  auto route_config = factory.createRouteSpecificFilterConfig(
+      proto_config, context, ProtobufMessage::getStrictValidationVisitor());
+  const auto* config = dynamic_cast<const DubboTranscoderConfig*>(route_config.get());
+  EXPECT_FALSE(config->disabled());
+}
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/dubbo_transcoder_filter_test.cc b/contrib/http_dubbo_transcoder/filters/http/test/dubbo_transcoder_filter_test.cc
new file mode 100644
index 0000000000..32fb08ffe8
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/dubbo_transcoder_filter_test.cc
@@ -0,0 +1,754 @@
+#include "test/mocks/server/factory_context.h"
+#include "test/test_common/utility.h"
+
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.h"
+#include "contrib/envoy/extensions/filters/http/http_dubbo_transcoder/v3/http_dubbo_transcoder.pb.validate.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/config.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/dubbo_transcoder_filter.h"
+#include "contrib/http_dubbo_transcoder/filters/http/source/utility.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using testing::_;
+
+namespace Envoy {
+namespace Extensions {
+namespace HttpFilters {
+namespace HttpDubboTranscoder {
+
+class TranscodeFilterTest : public testing::Test {
+public:
+  TranscodeFilterTest() = default;
+
+  void setConfiguration() {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+    setConfiguration(yaml_string);
+  }
+
+  void setConfiguration(const std::string& yaml_string) {
+    envoy::extensions::filters::http::http_dubbo_transcoder::v3::HttpDubboTranscoder proto_config;
+    TestUtility::loadFromYaml(yaml_string, proto_config);
+
+    time_system_.setSystemTime(std::chrono::seconds(1610503040));
+    config_ = std::make_shared<DubboTranscoderConfig>(proto_config);
+  }
+
+  void setFilter() { setFilter(std::make_shared<TranscodeFilter>(*config_)); }
+
+  void setFilter(std::shared_ptr<TranscodeFilter> filter) {
+    filter_ = filter;
+    filter_->setDecoderFilterCallbacks(decoder_callbacks_);
+    filter_->setEncoderFilterCallbacks(encoder_callbacks_);
+  }
+
+  Stats::TestUtil::TestStore scope_;
+  Event::SimulatedTimeSystem time_system_;
+  NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks_;
+  NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks_;
+  std::shared_ptr<DubboTranscoderConfig> config_;
+  std::shared_ptr<TranscodeFilter> filter_;
+};
+
+TEST_F(TranscodeFilterTest, NormalHttpGetMethod) {
+  setConfiguration();
+  setFilter();
+
+  EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+
+  Http::TestRequestHeaderMapImpl request_headers{
+      {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param=test"}};
+  EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+  EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+}
+
+TEST_F(TranscodeFilterTest, AllowUnknownMethodAndParameter) {
+  setConfiguration();
+  setFilter();
+
+  {
+    // the path mismatch.
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"},
+                                                   {":path", "/mytest.service/test?my_param=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Post, request_headers.getMethodValue());
+  }
+
+  {
+    // the parameter mismatch.
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/mytest.service/test?my_test=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+}
+
+TEST_F(TranscodeFilterTest, RejectUnknownMethodAndParameter) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: true
+  reject_unknown_method: true
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+  setConfiguration(yaml_string);
+  setFilter();
+
+  {
+    // the path mismatch.
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(1);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"},
+                                                   {":path", "/mytest.service/test?my_param=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Post, request_headers.getMethodValue());
+  }
+
+  {
+    // the parameter mismatch.
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(1);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_test=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+}
+
+TEST_F(TranscodeFilterTest, ExtractParameterKeyFromQuery) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param1
+      mapping_type: "java.lang.String"
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param2
+      mapping_type: "java.lang.Long"
+)EOF";
+  setConfiguration(yaml_string);
+  setFilter();
+
+  {
+    // normal request
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param1=test&my_param2=12345"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+  {
+    // the request path don't include a query
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::InternalServerError, _, _, _, _))
+        .Times(1);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/mytest.service/sayHello"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+
+  {
+    // query key don't match the extract_key
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::NotFound, _, _, _, _)).Times(1);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param1=test&my_param4=45645"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+}
+
+TEST_F(TranscodeFilterTest, ExtractParameterKeyFromHeader) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_HEADER
+      extract_key: my_param1
+      mapping_type: "java.lang.String"
+    - extract_key_spec: ALL_HEADER
+      extract_key: my_param2
+      mapping_type: "java.lang.Double"
+)EOF";
+  setConfiguration(yaml_string);
+  setFilter();
+  {
+    // normal request
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/mytest.service/sayHello"},
+                                                   {"my_param1", "test"},
+                                                   {"my_param2", "0.234"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+  {
+    // extract_key my_param1 cannot be found in headers
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::NotFound, _, _, _, _)).Times(1);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/mytest.service/sayHello"},
+                                                   {"param", "test"},
+                                                   {"my_param2", "0.234"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+  {
+    // my_param2's mapping type is Double, but given String
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::BadRequest, _, _, _, _)).Times(1);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/mytest.service/sayHello"},
+                                                   {"my_param1", "test"},
+                                                   {"my_param2", "abc"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+}
+
+TEST_F(TranscodeFilterTest, DefaultMatchingPathAndHttpMethod) {
+  const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    parameter_mapping:
+    - extract_key_spec: ALL_HEADER
+      extract_key: my_param1
+      mapping_type: "java.lang.String"
+)EOF";
+  setConfiguration(yaml_string);
+  setFilter();
+
+  {
+    // normal request
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/common.sayHello/sayHello"}, {"my_param1", "test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+
+  {
+    // extract_key my_param1 cannot be found in headers
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::NotFound, _, _, _, _)).Times(1);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/common.sayHello/sayHello"}, {"param", "test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+              filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Get, request_headers.getMethodValue());
+  }
+}
+
+TEST_F(TranscodeFilterTest, ExtractParameterKeyFromBody) {
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    parameter_mapping:
+    - extract_key_spec: ALL_BODY
+      extract_key: name
+      mapping_type: "java.lang.String"
+    - extract_key_spec: ALL_HEADER
+      extract_key: my_param1
+      mapping_type: "java.lang.String"
+)EOF";
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, _)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/common.sayHello/sayHello"}, {"my_param1", "test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+
+    std::string json_string = R"EOF(
+      {
+        "age": 10,
+        "name" : "test"
+      }
+    )EOF";
+    Buffer::OwnedImpl data(json_string);
+    EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false));
+
+    std::string encoded_data(data.toString());
+    EXPECT_TRUE(encoded_data.find("test") != std::string::npos);
+  }
+
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    parameter_mapping:
+    - extract_key_spec: ALL_BODY
+      mapping_type: "java.util.Map"
+)EOF";
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, _)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/common.sayHello/sayHello"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+
+    std::string json_string = R"EOF(
+      {
+        "age": 10,
+        "name" : "test"
+      }
+    )EOF";
+    Buffer::OwnedImpl data(json_string);
+    EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false));
+
+    std::string encoded_data(data.toString());
+    EXPECT_TRUE(encoded_data.find("age") != std::string::npos);
+  }
+}
+
+TEST_F(TranscodeFilterTest, PassthroughSetting) {
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    parameter_mapping:
+    - extract_key_spec: ALL_BODY
+      extract_key: name
+      mapping_type: "java.lang.String"
+    passthrough_setting:
+      passthrough_all_headers: true
+)EOF";
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/common.sayHello/sayHello"}, {"my_param1", "test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+
+    std::string json_string = R"EOF(
+      {
+        "age": 10,
+        "name" : "test"
+      }
+    )EOF";
+    Buffer::OwnedImpl data(json_string);
+    EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false));
+
+    std::string encoded_data(data.toString());
+    EXPECT_TRUE(encoded_data.find("my_param1") != std::string::npos);
+    EXPECT_TRUE(encoded_data.find("sayHello") != std::string::npos);
+  }
+
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    parameter_mapping:
+    - extract_key_spec: ALL_BODY
+      extract_key: name
+      mapping_type: "java.lang.String"
+    passthrough_setting:
+      passthrough_all_headers: false
+)EOF";
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/common.sayHello/sayHello"}, {"my_param1", "test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, false));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+
+    std::string json_string = R"EOF(
+      {
+        "age": 10,
+        "name" : "test"
+      }
+    )EOF";
+    Buffer::OwnedImpl data(json_string);
+    EXPECT_EQ(Http::FilterDataStatus::Continue, filter_->decodeData(data, false));
+
+    std::string encoded_data(data.toString());
+    EXPECT_TRUE(encoded_data.find("my_param1") == std::string::npos);
+    EXPECT_TRUE(encoded_data.find("GET") == std::string::npos);
+  }
+}
+
+TEST(DobboUtilityTest, convertStringToTypeValueTest) {
+  {
+    absl::string_view value{"0.234234"};
+    std::string type{"java.lang.Double"};
+    nlohmann::json result = 0.234234;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"-0.234234"};
+    std::string type{"java.lang.Double"};
+    nlohmann::json result = -0.234234;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"0.0"};
+    std::string type{"java.lang.Double"};
+    nlohmann::json result = 0;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+
+  {
+    absl::string_view value{"837465"};
+    std::string type{"java.lang.Long"};
+    nlohmann::json result = 837465;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"-34534"};
+    std::string type{"java.lang.Long"};
+    nlohmann::json result = -34534;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"0"};
+    std::string type{"java.lang.Long"};
+    nlohmann::json result = 0;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"true"};
+    std::string type{"java.lang.Boolean"};
+    nlohmann::json result = true;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+  {
+    absl::string_view value{"false"};
+    std::string type{"java.lang.Boolean"};
+    nlohmann::json result = false;
+    EXPECT_EQ(result, DubboUtility::convertStringToTypeValue(value, type).value());
+  }
+}
+
+TEST_F(TranscodeFilterTest, EncodeDataFromDubboServer) {
+  setConfiguration();
+  setFilter();
+
+  // initialize filter_->transcoder by calling filter->decodeHeaders
+  Http::TestRequestHeaderMapImpl request_headers{
+      {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param=test"}};
+  EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+
+  {
+    // 1. Normal dubbo request message
+    Buffer::OwnedImpl buffer;
+    buffer.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    buffer.writeBEInt(static_cast<uint64_t>(1));
+    std::string content({'I', 0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    buffer.writeBEInt(static_cast<uint32_t>(content.size()));
+    buffer.add(content);
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(buffer, true), Http::FilterDataStatus::Continue);
+  }
+
+  {
+    // 2. Response is divided into header and body
+    Buffer::OwnedImpl response_header;
+    response_header.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    response_header.writeBEInt(static_cast<uint64_t>(1));
+    std::string content({'I', 0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    response_header.writeBEInt(static_cast<uint32_t>(content.size()));
+    // recieve dubbo header
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::RangeNotSatisfiable, _, _, _, _))
+        .Times(1);
+    EXPECT_EQ(filter_->encodeData(response_header, true),
+              Http::FilterDataStatus::StopIterationNoBuffer);
+    Buffer::OwnedImpl response_body;
+    response_body.add(content);
+    // recieve dubbo body
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(response_body, true), Http::FilterDataStatus::Continue);
+  }
+
+  {
+    // 3. The header is split into two parts, and the second part is sent along with the body
+    Buffer::OwnedImpl response_header;
+    response_header.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    response_header.writeBEInt(static_cast<uint64_t>(1));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::BadRequest, _, _, _, _)).Times(1);
+    EXPECT_EQ(filter_->encodeData(response_header, true),
+              Http::FilterDataStatus::StopIterationNoBuffer);
+
+    std::string content({'I', 0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    Buffer::OwnedImpl response_body;
+    response_body.writeBEInt(static_cast<uint32_t>(content.size()));
+    response_body.add(content);
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(response_body, true), Http::FilterDataStatus::Continue);
+  }
+  {
+    // 4. The body is split into two parts, with the first part sent along with the header
+    Buffer::OwnedImpl response_header;
+    response_header.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    response_header.writeBEInt(static_cast<uint64_t>(1));
+    std::string content({'I', 0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    response_header.writeBEInt(static_cast<uint32_t>(content.size()));
+    response_header.add(std::string({'I', 0x00, 0x00, 0x00, 0x01, 0x05}));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::RangeNotSatisfiable, _, _, _, _))
+        .Times(1);
+    EXPECT_EQ(filter_->encodeData(response_header, true),
+              Http::FilterDataStatus::StopIterationNoBuffer);
+
+    Buffer::OwnedImpl response_body;
+    response_body.add(std::string({'h', 'e', 'l', 'l', 'o'}));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(response_body, true), Http::FilterDataStatus::Continue);
+  }
+  {
+    // 5. The whole response is divided into three parts
+    Buffer::OwnedImpl response_header;
+    response_header.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    response_header.writeBEInt(static_cast<uint64_t>(1));
+    std::string content({'I', 0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    response_header.writeBEInt(static_cast<uint32_t>(content.size()));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::RangeNotSatisfiable, _, _, _, _))
+        .Times(1);
+    EXPECT_EQ(filter_->encodeData(response_header, true),
+              Http::FilterDataStatus::StopIterationNoBuffer);
+
+    Buffer::OwnedImpl body_part1;
+    body_part1.add(std::string({'I', 0x00, 0x00, 0x00, 0x01}));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::RangeNotSatisfiable, _, _, _, _))
+        .Times(1);
+    EXPECT_EQ(filter_->encodeData(body_part1, true), Http::FilterDataStatus::StopIterationNoBuffer);
+
+    Buffer::OwnedImpl body_part2;
+    body_part2.add(std::string({0x05, 'h', 'e', 'l', 'l', 'o'}));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(body_part2, true), Http::FilterDataStatus::Continue);
+  }
+  {
+    // 6. Cannot parse RpcResult type from buffer
+    Buffer::OwnedImpl buffer;
+    buffer.add(std::string({'\xda', '\xbb', 0x42, 20}));
+    buffer.writeBEInt(static_cast<uint64_t>(1));
+    std::string content({0x00, 0x00, 0x00, 0x01, 0x05, 'h', 'e', 'l', 'l', 'o'});
+    buffer.writeBEInt(static_cast<uint32_t>(content.size()));
+    buffer.add(content);
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(Http::Code::InternalServerError, _, _, _, _))
+        .Times(1);
+    EXPECT_EQ(filter_->encodeData(buffer, true), Http::FilterDataStatus::StopIterationNoBuffer);
+  }
+  {
+    // 7. Heartbeat event
+    Buffer::OwnedImpl buffer;
+    buffer.add(std::string({'\xda', '\xbb', 0x62, 20})); // event bit is set to 1
+    buffer.writeBEInt(static_cast<uint64_t>(1));
+    buffer.writeBEInt(static_cast<uint32_t>(0));
+    EXPECT_CALL(decoder_callbacks_, sendLocalReply(_, _, _, _, _)).Times(0);
+    EXPECT_EQ(filter_->encodeData(buffer, true), Http::FilterDataStatus::StopIterationNoBuffer);
+  }
+}
+
+TEST_F(TranscodeFilterTest, ServiceVersionAndGroup) {
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  version: "0.0.0"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+  {
+    const std::string yaml_string = R"EOF(
+url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+request_validation_options:
+  reject_unknown_query_parameters: false
+  reject_unknown_method: false
+services_mapping:
+- name: "common.sayHello"
+  group: "dev"
+  method_mapping:
+    name: "sayHello"
+    path_matcher:
+      match_pattern: "/mytest.service/sayHello"
+      match_http_method_spec: ALL_GET
+    parameter_mapping:
+    - extract_key_spec: ALL_QUERY_PARAMETER
+      extract_key: my_param
+      mapping_type: "java.lang.String"
+)EOF";
+
+    setConfiguration(yaml_string);
+    setFilter();
+
+    EXPECT_CALL(decoder_callbacks_, addDecodedData(_, true)).Times(1);
+
+    Http::TestRequestHeaderMapImpl request_headers{
+        {":method", "GET"}, {":path", "/mytest.service/sayHello?my_param=test"}};
+    EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
+    EXPECT_EQ(Http::Headers::get().MethodValues.Connect, request_headers.getMethodValue());
+  }
+}
+
+} // namespace HttpDubboTranscoder
+} // namespace HttpFilters
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo.yaml b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo.yaml
new file mode 100644
index 0000000000..ba754d86e1
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo.yaml
@@ -0,0 +1,100 @@
+static_resources:
+  listeners:
+  - address:
+      socket_address:
+        address: 0.0.0.0
+        port_value: 80
+    filter_chains:
+    - filters:
+      - name: envoy.filters.network.http_connection_manager
+        typed_config:
+          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          codec_type: auto
+          stat_prefix: ingress_http
+          http_protocol_options:
+            accept_http_10: true
+          route_config:
+            name: local_route
+            virtual_hosts:
+            - name: service
+              domains:
+              - "*"
+              routes:
+              - match:
+                  prefix: "/abc"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+              - match:
+                  prefix: "/mytest_1"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+          http_filters:
+          - name: envoy.filters.http.http_dubbo_transcoder
+            typed_config: 
+              "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.Transcoder
+              disable: false
+              auto_map: true
+              url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+              request_validation_options:
+                reject_unknown_query_parameters: true
+              services:
+              - name: "common.sayHello"
+                version: "0.0.0"
+                methods:
+                  get: "/abc/{path.name}"
+                  name: "sayHello"
+                  maps:
+                  - name: "path.name"
+                    mapTo: "params.0"
+                    type: "java.lang.String"
+              - name: "common.sayHello"
+                version: "0.0.0"
+                map_service_url: /mytest_*
+                methods:
+                  get: "{header.name}"
+                  name: "sayHello"
+                  body_template: ""
+                  maps:
+                  - name: "header.name"
+                    mapTo: "params.0"
+                    type: "java.lang.String"
+          - name: envoy.filters.http.router
+            typed_config: {}
+  clusters:
+  - name: local_service          
+    connect_timeout: 5s
+    type: strict_dns
+    lb_policy: round_robin
+    upstream_config:
+      name: envoy.upstreams.http.tcp
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.upstreams.http.tcp.v3.TcpConnectionPoolProto
+    load_assignment:
+      cluster_name: local_service
+      endpoints:
+      - lb_endpoints:
+        - endpoint:
+            address:
+              socket_address:
+                address: 11.164.30.21
+                port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 139.162.123.134
+      #           port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 114.55.31.224
+      #           port_value: 20880
\ No newline at end of file
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_new.yaml b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_new.yaml
new file mode 100644
index 0000000000..81c0578135
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_new.yaml
@@ -0,0 +1,228 @@
+static_resources:
+  listeners:
+  - address:
+      socket_address:
+        address: 0.0.0.0
+        port_value: 3344
+    filter_chains:
+    - filters:
+      - name: envoy.filters.network.http_connection_manager
+        typed_config:
+          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          codec_type: auto
+          stat_prefix: ingress_http
+          http_protocol_options:
+            accept_http_10: true
+          route_config:
+            name: local_route
+            virtual_hosts:
+            - name: service
+              domains:
+              - "*"
+              routes:
+              - match:
+                  prefix: "/demoservice.DemoService"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+              - match:
+                  prefix: "/mytest.service"
+                route:
+                  cluster: local_test_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+          http_filters:
+          - name: envoy.filters.http.http_dubbo_transcoder
+            typed_config: 
+              "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+              url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+              request_validation_options:
+                reject_unknown_query_parameters: true
+              services_mapping:
+              - name: "common.sayHello"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "org.apache.dubbo.samples.basic.api.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello11"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+                  passthrough_setting:
+                    passthrough_all_headers: true
+                    passthrough_body: true
+              - name: "org.apache.dubbo.samples.basic.api.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "getEchoxx"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello22"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.util.List"
+                  passthrough_setting:
+                    passthrough_all_headers: true
+                    passthrough_body: true
+              - name: "org.apache.dubbo.samples.basic.api.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "getEcho"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello33"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param1
+                    mapping_type: "java.util.List"
+                  passthrough_setting:
+                    passthrough_all_headers: true
+                    passthrough_body: true
+              - name: "org.apache.dubbo.samples.basic.api.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "getEcho"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello44"
+                    match_http_method_spec: ALL_POST
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+                  passthrough_setting:
+                    passthrough_all_headers: true
+                    passthrough_body: true
+              - name: "org.apache.dubbo.samples.basic.api.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "mapEcho"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello55"
+                    match_http_method_spec: ALL_POST
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+                  passthrough_setting:
+                    passthrough_headers:
+                      keys:
+                      - "token"
+                    passthrough_body: true
+              - name: "org.apache.dubbo.demo.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "getEcho"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHelloxxxxx"
+                    match_http_method_spec: ALL_POST
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "org.apache.dubbo.demo.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_POST
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  parameter_mapping:
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_1
+                    mapping_type: "java.lang.String"
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_2
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_PATH
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+          - name: envoy.filters.http.router
+            typed_config: {}
+  clusters:
+  - name: local_test_service          
+    connect_timeout: 5s
+    type: strict_dns
+    lb_policy: round_robin
+    upstream_config:
+      name: envoy.upstreams.http.dubbo_tcp
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.upstreams.http.dubbo_tcp.v3.DubboTcpConnectionPoolProto
+    load_assignment:
+      cluster_name: local_service
+      endpoints:
+      - lb_endpoints:
+        - endpoint:
+            address:
+              socket_address:
+                address: 30.225.8.108
+                port_value: 20880
+  - name: local_service          
+    connect_timeout: 5s
+    type: strict_dns
+    lb_policy: round_robin
+    upstream_config:
+      name: envoy.upstreams.http.dubbo_tcp
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.upstreams.http.dubbo_tcp.v3.DubboTcpConnectionPoolProto
+    load_assignment:
+      cluster_name: local_service
+      endpoints:
+      - lb_endpoints:
+        - endpoint:
+            address:
+              socket_address:
+                address: 30.225.8.108
+                port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 139.162.123.134
+      #           port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 114.55.31.224
+      #           port_value: 20880
\ No newline at end of file
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route copy.yaml b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route copy.yaml
new file mode 100644
index 0000000000..1e928ae8a0
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route copy.yaml	
@@ -0,0 +1,151 @@
+static_resources:
+  listeners:
+  - address:
+      socket_address:
+        address: 0.0.0.0
+        port_value: 80
+    filter_chains:
+    - filters:
+      - name: envoy.filters.network.http_connection_manager
+        typed_config:
+          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          codec_type: auto
+          stat_prefix: ingress_http
+          http_protocol_options:
+            accept_http_10: true
+          route_config:
+            name: local_route
+            virtual_hosts:
+            - name: service
+              domains:
+              - "*"
+              routes:
+              - match:
+                  prefix: "/demoservice.DemoService"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+              - match:
+                  prefix: "/mytest.service"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+                typed_per_filter_config:
+                  envoy.filters.http.http_dubbo_transcoder:
+                    "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+                    auto_mapping: true
+                    url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+                    request_validation_options:
+                      reject_unknown_query_parameters: true
+                    services_mapping:
+                    - name: "common.sayHello"
+                      version: "0.0.0"
+                      method_mapping:
+                        name: "sayHello"
+                        path_matcher:
+                          match_pattern: "/mytest.service/sayHello"
+                          match_http_method_spec: ALL_GET
+                        parameter_mapping:
+                        - extract_key_spec: ALL_HEADER
+                          extract_key: key1
+                          mapping_type: "java.lang.String"
+          http_filters:
+          - name: envoy.filters.http.http_dubbo_transcoder
+            typed_config: 
+              "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+              auto_mapping: true
+              url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+              request_validation_options:
+                reject_unknown_query_parameters: true
+              services_mapping:
+              - name: "common.sayHello"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "common.sayHello"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_POST
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  parameter_mapping:
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_1
+                    mapping_type: "java.lang.String"
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_2
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_PATH
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+                  attachment_from_header_keys:
+                  - header_key_1
+          - name: envoy.filters.http.router
+            typed_config: {}
+  clusters:
+  - name: local_service          
+    connect_timeout: 5s
+    type: strict_dns
+    lb_policy: round_robin
+    upstream_config:
+      name: envoy.upstreams.http.tcp
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.upstreams.http.tcp.v3.TcpConnectionPoolProto
+    load_assignment:
+      cluster_name: local_service
+      endpoints:
+      - lb_endpoints:
+        - endpoint:
+            address:
+              socket_address:
+                address: 11.164.30.21
+                port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 139.162.123.134
+      #           port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 114.55.31.224
+      #           port_value: 20880
\ No newline at end of file
diff --git a/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route.yaml b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route.yaml
new file mode 100644
index 0000000000..b574b70de1
--- /dev/null
+++ b/contrib/http_dubbo_transcoder/filters/http/test/test_data/dubbo_pre_route.yaml
@@ -0,0 +1,166 @@
+static_resources:
+  listeners:
+  - address:
+      socket_address:
+        address: 0.0.0.0
+        port_value: 80
+    filter_chains:
+    - filters:
+      - name: envoy.filters.network.http_connection_manager
+        typed_config:
+          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
+          codec_type: auto
+          stat_prefix: ingress_http
+          http_protocol_options:
+            accept_http_10: true
+          route_config:
+            name: local_route
+            virtual_hosts:
+            - name: service
+              domains:
+              - "*"
+              typed_per_filter_config:
+                envoy.filters.http.http_dubbo_transcoder:
+                  "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+                  auto_mapping: true
+                  url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+                  request_validation_options:
+                    reject_unknown_query_parameters: true
+                  services_mapping:
+                  - name: "common.sayHello"
+                    version: "0.0.0"
+                    method_mapping:
+                      name: "sayHello"
+                      path_matcher:
+                        match_pattern: "/mytest.service/sayHello"
+                        match_http_method_spec: ALL_GET
+                      parameter_mapping:
+                      - extract_key_spec: ALL_HEADER
+                        extract_key: key1
+                        mapping_type: "java.lang.String"
+              routes:
+              - match:
+                  prefix: "/demoservice.DemoService"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+              - match:
+                  prefix: "/mytest.service"
+                route:
+                  cluster: local_service
+                  upgrade_configs: 
+                  - upgrade_type: "CONNECT"
+                    connect_config: 
+                      allow_post: true
+                typed_per_filter_config:
+                  envoy.filters.http.http_dubbo_transcoder:
+                    "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+                    services_mapping:
+                    - name: "common.sayHello"
+                      version: "0.0.0"
+                      method_mapping:
+                        name: "sayHello"
+                        path_matcher:
+                          match_pattern: "/mytest.service/sayHello222"
+                          match_http_method_spec: ALL_GET
+                        parameter_mapping:
+                        - extract_key_spec: ALL_HEADER
+                          extract_key: key1
+                          mapping_type: "java.lang.String"
+          http_filters:
+          - name: envoy.filters.http.http_dubbo_transcoder
+            typed_config: 
+              "@type": type.googleapis.com/envoy.extensions.filters.http.http_dubbo_transcoder.v3.HttpDubboTranscoder
+              auto_mapping: true
+              url_unescape_spec: ALL_CHARACTERS_EXCEPT_RESERVED
+              request_validation_options:
+                reject_unknown_query_parameters: true
+              services_mapping:
+              - name: "common.sayHello"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "common.sayHello"
+                version: "0.0.0"
+                method_mapping:
+                  name: "getEcho"
+                  path_matcher:
+                    match_pattern: "/mytest.service/sayHello"
+                    match_http_method_spec: ALL_POST
+                  parameter_mapping:
+                  - extract_key_spec: ALL_QUERY_PARAMETER
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  parameter_mapping:
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_1
+                    mapping_type: "java.lang.String"
+                  - extract_key_spec: ALL_HEADER
+                    extract_key: my_param_2
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+                  parameter_mapping:
+                  - extract_key_spec: ALL_PATH
+                    extract_key: my_param
+                    mapping_type: "java.lang.String"
+              - name: "demoservice.DemoService"
+                version: "0.0.0"
+                method_mapping:
+                  name: "sayHello"
+                  path_matcher:
+                    match_pattern: "/demoservice.DemoService/sayHello/{my_param}"
+                    match_http_method_spec: ALL_GET
+                  attachment_from_header_keys:
+                  - header_key_1
+          - name: envoy.filters.http.router
+            typed_config: {}
+  clusters:
+  - name: local_service          
+    connect_timeout: 5s
+    type: strict_dns
+    lb_policy: round_robin
+    upstream_config:
+      name: envoy.upstreams.http.tcp
+      typed_config:
+        "@type": type.googleapis.com/envoy.extensions.upstreams.http.tcp.v3.TcpConnectionPoolProto
+    load_assignment:
+      cluster_name: local_service
+      endpoints:
+      - lb_endpoints:
+        - endpoint:
+            address:
+              socket_address:
+                address: 11.164.30.21
+                port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 139.162.123.134
+      #           port_value: 20880
+      # - lb_endpoints:
+      #   - endpoint:
+      #       address:
+      #         socket_address:
+      #           address: 114.55.31.224
+      #           port_value: 20880
\ No newline at end of file
diff --git a/contrib/server/admin/source/BUILD b/contrib/server/admin/source/BUILD
new file mode 100644
index 0000000000..04e9191fb6
--- /dev/null
+++ b/contrib/server/admin/source/BUILD
@@ -0,0 +1,28 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_library(
+    name = "cluster_endpoints_handler_lib",
+    srcs = ["cluster_endpoints_handler.cc"],
+    hdrs = ["cluster_endpoints_handler.h"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/http:codes_interface",
+        "//envoy/server:admin_interface",
+        "//envoy/server:instance_interface",
+        "//source/common/buffer:buffer_lib",
+        "//source/common/http:codes_lib",
+        "//source/common/http:header_map_lib",
+        "//source/common/upstream:host_utility_lib",
+        "//source/server/admin:handler_ctx_lib",
+        "//source/server/admin:utils_lib",
+        "@envoy_api//envoy/admin/v3:pkg_cc_proto",
+    ],
+)
diff --git a/contrib/server/admin/source/cluster_endpoints_handler.cc b/contrib/server/admin/source/cluster_endpoints_handler.cc
new file mode 100644
index 0000000000..5b73fbbd81
--- /dev/null
+++ b/contrib/server/admin/source/cluster_endpoints_handler.cc
@@ -0,0 +1,76 @@
+#include "contrib/server/admin/source/cluster_endpoints_handler.h"
+
+#include "envoy/admin/v3/clusters.pb.h"
+
+#include "source/common/http/headers.h"
+#include "source/common/http/utility.h"
+#include "source/common/network/utility.h"
+#include "source/common/upstream/host_utility.h"
+#include "source/server/admin/utils.h"
+
+namespace Envoy {
+namespace Server {
+
+namespace {} // namespace
+
+ClusterEndpointsHandler::ClusterEndpointsHandler(Server::Instance& server)
+    : HandlerContextBase(server) {}
+
+Http::Code ClusterEndpointsHandler::handlerClusterEndpoints(absl::string_view path,
+                                                            Http::HeaderMap&,
+                                                            Buffer::Instance& response,
+                                                            AdminStream& admin_stream) {
+  Http::Utility::QueryParams params = Http::Utility::parseQueryString(path);
+  if (params.empty()) {
+    // Check if the params are in the request's body.}{}
+    if (admin_stream.getRequestBody() != nullptr &&
+        isFormUrlEncoded(admin_stream.getRequestHeaders().ContentType())) {
+      params = Http::Utility::parseFromBody(admin_stream.getRequestBody()->toString());
+    }
+  }
+
+  absl::optional<absl::string_view> service_name =
+      params.find("service") != params.end()
+          ? absl::optional<absl::string_view>{params.at("service")}
+          : absl::nullopt;
+
+  if (params.empty() || !service_name.has_value()) {
+    response.add("usage: /endpoints?service=value1&protocol=value2\n");
+    response.add("       or send the parameters as form values\n");
+    response.add("use an empty value to remove a previously added override");
+    return Http::Code::BadRequest;
+  }
+
+  auto all_clusters = server_.clusterManager().clusters();
+  for (const auto& [name, cluster_ref] : all_clusters.active_clusters_) {
+    // const Upstream::Cluster& cluster = cluster_pair.second.get();
+    const Upstream::Cluster& cluster = cluster_ref.get();
+    Upstream::ClusterInfoConstSharedPtr cluster_info = cluster.info();
+    if (absl::StrContains(cluster_info->name(), service_name.value())) {
+      response.add(fmt::format("ClusterName: {}\n", cluster_info->name()));
+      for (auto& host_set : cluster.prioritySet().hostSetsPerPriority()) {
+        for (auto& host : host_set->hosts()) {
+          response.add(fmt::format("\tendpoint: {}", host->address()->asString()));
+          response.add(
+              fmt::format("\tmetadata: {}\n",
+                          host->metadata() == nullptr
+                              ? std::string()
+                              : MessageUtil::getJsonStringFromMessageOrDie(*host->metadata())));
+        }
+      }
+    }
+  }
+  return Http::Code::OK;
+}
+
+bool ClusterEndpointsHandler::isFormUrlEncoded(const Http::HeaderEntry* content_type) const {
+  if (content_type == nullptr) {
+    return false;
+  }
+
+  return content_type->value().getStringView() ==
+         Http::Headers::get().ContentTypeValues.FormUrlEncoded;
+}
+
+} // namespace Server
+} // namespace Envoy
diff --git a/contrib/server/admin/source/cluster_endpoints_handler.h b/contrib/server/admin/source/cluster_endpoints_handler.h
new file mode 100644
index 0000000000..13ba0108bf
--- /dev/null
+++ b/contrib/server/admin/source/cluster_endpoints_handler.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "envoy/buffer/buffer.h"
+#include "envoy/http/codes.h"
+#include "envoy/http/header_map.h"
+#include "envoy/server/admin.h"
+#include "envoy/server/instance.h"
+
+#include "source/server/admin/handler_ctx.h"
+
+#include "absl/strings/string_view.h"
+
+namespace Envoy {
+namespace Server {
+
+class ClusterEndpointsHandler : public HandlerContextBase {
+
+public:
+  ClusterEndpointsHandler(Server::Instance& server);
+
+  Http::Code handlerClusterEndpoints(absl::string_view path_and_query,
+                                     Http::HeaderMap& response_headers, Buffer::Instance& response,
+                                     AdminStream&);
+
+private:
+  bool isFormUrlEncoded(const Http::HeaderEntry* content_type) const;
+};
+
+} // namespace Server
+} // namespace Envoy
diff --git a/contrib/sip_proxy/filters/network/source/router/router_impl.h b/contrib/sip_proxy/filters/network/source/router/router_impl.h
index 231d94c7a6..c51ccb1f0e 100644
--- a/contrib/sip_proxy/filters/network/source/router/router_impl.h
+++ b/contrib/sip_proxy/filters/network/source/router/router_impl.h
@@ -241,7 +241,7 @@ public:
   std::shared_ptr<UpstreamRequest> getUpstreamRequest(const std::string& host) {
     try {
       return tls_->getTyped<ThreadLocalTransactionInfo>().upstream_request_map_.at(host);
-    } catch (std::out_of_range) {
+    } catch (std::out_of_range const&) {
       return nullptr;
     }
   }
diff --git a/contrib/upstreams/http/dubbo_tcp/source/BUILD b/contrib/upstreams/http/dubbo_tcp/source/BUILD
new file mode 100644
index 0000000000..6c07446efa
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/source/BUILD
@@ -0,0 +1,54 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_contrib_extension",
+    "envoy_cc_library",
+    "envoy_contrib_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_contrib_package()
+
+envoy_cc_contrib_extension(
+    name = "config",
+    srcs = [
+        "config.cc",
+    ],
+    hdrs = [
+        "config.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":upstream_request_lib",
+        "@envoy_api//contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3:pkg_cc_proto",
+    ],
+)
+
+envoy_cc_library(
+    name = "upstream_request_lib",
+    srcs = [
+        "upstream_request.cc",
+    ],
+    hdrs = [
+        "upstream_request.h",
+    ],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/http:codes_interface",
+        "//envoy/http:filter_interface",
+        "//envoy/upstream:upstream_interface",
+        "//source/common/common:assert_lib",
+        "//source/common/common:minimal_logger_lib",
+        "//source/common/common:utility_lib",
+        "//source/common/http:codes_lib",
+        "//source/common/http:header_map_lib",
+        "//source/common/http:headers_lib",
+        "//source/common/http:message_lib",
+        "//source/common/network:application_protocol_lib",
+        "//source/common/network:transport_socket_options_lib",
+        "//source/common/router:router_lib",
+        "//source/common/upstream:load_balancer_lib",
+        "//source/extensions/common/proxy_protocol:proxy_protocol_header_lib",
+        "//source/extensions/upstreams/http/tcp:upstream_request_lib",
+    ],
+)
diff --git a/contrib/upstreams/http/dubbo_tcp/source/config.cc b/contrib/upstreams/http/dubbo_tcp/source/config.cc
new file mode 100644
index 0000000000..163c85b892
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/source/config.cc
@@ -0,0 +1,27 @@
+#include "config.h"
+
+#include "upstream_request.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace Upstreams {
+namespace Http {
+namespace DubboTcp {
+
+Router::GenericConnPoolPtr DubboTcpGenericConnPoolFactory::createGenericConnPool(
+    Upstream::ThreadLocalCluster& thread_local_cluster, bool is_connect,
+    const Router::RouteEntry& route_entry,
+    absl::optional<Envoy::Http::Protocol> downstream_protocol,
+    Upstream::LoadBalancerContext* ctx) const {
+  auto ret = std::make_unique<TcpConnPool>(thread_local_cluster, is_connect, route_entry,
+                                           downstream_protocol, ctx);
+  return (ret->valid() ? std::move(ret) : nullptr);
+}
+
+REGISTER_FACTORY(DubboTcpGenericConnPoolFactory, Router::GenericConnPoolFactory);
+
+} // namespace DubboTcp
+} // namespace Http
+} // namespace Upstreams
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/upstreams/http/dubbo_tcp/source/config.h b/contrib/upstreams/http/dubbo_tcp/source/config.h
new file mode 100644
index 0000000000..c889847566
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/source/config.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "contrib/envoy/extensions/upstreams/http/dubbo_tcp/v3/tcp_connection_pool.pb.h"
+#include "envoy/registry/registry.h"
+#include "envoy/router/router.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace Upstreams {
+namespace Http {
+namespace DubboTcp {
+
+/**
+ * Config registration for the TcpConnPool. @see Router::GenericConnPoolFactory
+ */
+class DubboTcpGenericConnPoolFactory : public Router::GenericConnPoolFactory {
+public:
+  std::string name() const override { return "envoy.filters.connection_pools.http.dubbo_tcp"; }
+  std::string category() const override { return "envoy.upstreams"; }
+  Router::GenericConnPoolPtr
+  createGenericConnPool(Upstream::ThreadLocalCluster& thread_local_cluster, bool is_connect,
+                        const Router::RouteEntry& route_entry,
+                        absl::optional<Envoy::Http::Protocol> downstream_protocol,
+                        Upstream::LoadBalancerContext* ctx) const override;
+  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
+    return std::make_unique<
+        envoy::extensions::upstreams::http::dubbo_tcp::v3::DubboTcpConnectionPoolProto>();
+  }
+};
+
+DECLARE_FACTORY(DubboTcpGenericConnPoolFactory);
+
+} // namespace DubboTcp
+} // namespace Http
+} // namespace Upstreams
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/upstreams/http/dubbo_tcp/source/upstream_request.cc b/contrib/upstreams/http/dubbo_tcp/source/upstream_request.cc
new file mode 100644
index 0000000000..ec484af45a
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/source/upstream_request.cc
@@ -0,0 +1,119 @@
+#include "upstream_request.h"
+
+#include <cstdint>
+#include <memory>
+
+#include "envoy/upstream/upstream.h"
+
+#include "source/common/common/assert.h"
+#include "source/common/common/utility.h"
+#include "source/common/http/codes.h"
+#include "source/common/http/header_map_impl.h"
+#include "source/common/http/headers.h"
+#include "source/common/http/message_impl.h"
+#include "source/common/network/transport_socket_options_impl.h"
+#include "source/common/router/router.h"
+#include "source/extensions/common/proxy_protocol/proxy_protocol_header.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace Upstreams {
+namespace Http {
+namespace DubboTcp {
+
+void TcpConnPool::onPoolReady(Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& conn_data,
+                              Upstream::HostDescriptionConstSharedPtr host) {
+  upstream_handle_ = nullptr;
+  Network::Connection& latched_conn = conn_data->connection();
+  auto upstream =
+      std::make_unique<TcpUpstream>(&callbacks_->upstreamToDownstream(), std::move(conn_data));
+  callbacks_->onPoolReady(std::move(upstream), host,
+                          latched_conn.connectionInfoProvider().localAddress(),
+                          latched_conn.streamInfo(), {});
+}
+
+TcpUpstream::TcpUpstream(Router::UpstreamToDownstream* upstream_request,
+                         Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& upstream)
+    : upstream_request_(upstream_request), upstream_conn_data_(std::move(upstream)) {
+  upstream_conn_data_->connection().enableHalfClose(false);
+  upstream_conn_data_->addUpstreamCallbacks(*this);
+}
+
+void TcpUpstream::encodeData(Buffer::Instance& data, bool end_stream) {
+  end_stream = false;
+  upstream_conn_data_->connection().write(data, end_stream);
+}
+
+Envoy::Http::Status TcpUpstream::encodeHeaders(const Envoy::Http::RequestHeaderMap&,
+                                               bool end_stream) {
+  // Headers should only happen once, so use this opportunity to add the proxy
+  // proto header, if configured.
+  const Router::RouteEntry* route_entry = upstream_request_->route().routeEntry();
+  ASSERT(route_entry != nullptr);
+  if (route_entry->connectConfig().has_value()) {
+    Buffer::OwnedImpl data;
+    auto& connect_config = route_entry->connectConfig().value();
+    if (connect_config.has_proxy_protocol_config()) {
+      Extensions::Common::ProxyProtocol::generateProxyProtoHeader(
+          connect_config.proxy_protocol_config(), upstream_request_->connection(), data);
+    }
+
+    if (data.length() != 0 || end_stream) {
+      upstream_conn_data_->connection().write(data, end_stream);
+    }
+  }
+
+  // TcpUpstream::encodeHeaders is called after the UpstreamRequest is fully initialized. Alsoc use
+  // this time to synthesize the 200 response headers downstream to complete the CONNECT handshake.
+  Envoy::Http::ResponseHeaderMapPtr headers{
+      Envoy::Http::createHeaderMap<Envoy::Http::ResponseHeaderMapImpl>(
+          {{Envoy::Http::Headers::get().Status, "200"}})};
+  upstream_request_->decodeHeaders(std::move(headers), false);
+  return Envoy::Http::okStatus();
+}
+
+void TcpUpstream::encodeTrailers(const Envoy::Http::RequestTrailerMap&) {
+  Buffer::OwnedImpl data;
+  upstream_conn_data_->connection().write(data, true);
+}
+
+void TcpUpstream::readDisable(bool disable) {
+  if (upstream_conn_data_->connection().state() != Network::Connection::State::Open) {
+    return;
+  }
+  upstream_conn_data_->connection().readDisable(disable);
+}
+
+void TcpUpstream::resetStream() {
+  upstream_request_ = nullptr;
+  upstream_conn_data_->connection().close(Network::ConnectionCloseType::NoFlush);
+}
+
+void TcpUpstream::onUpstreamData(Buffer::Instance& data, bool end_stream) {
+  end_stream = true;
+  upstream_request_->decodeData(data, end_stream);
+}
+
+void TcpUpstream::onEvent(Network::ConnectionEvent event) {
+  if (event != Network::ConnectionEvent::Connected && upstream_request_) {
+    upstream_request_->onResetStream(Envoy::Http::StreamResetReason::ConnectionTermination, "");
+  }
+}
+
+void TcpUpstream::onAboveWriteBufferHighWatermark() {
+  if (upstream_request_) {
+    upstream_request_->onAboveWriteBufferHighWatermark();
+  }
+}
+
+void TcpUpstream::onBelowWriteBufferLowWatermark() {
+  if (upstream_request_) {
+    upstream_request_->onBelowWriteBufferLowWatermark();
+  }
+}
+
+} // namespace DubboTcp
+} // namespace Http
+} // namespace Upstreams
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/upstreams/http/dubbo_tcp/source/upstream_request.h b/contrib/upstreams/http/dubbo_tcp/source/upstream_request.h
new file mode 100644
index 0000000000..527b26190b
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/source/upstream_request.h
@@ -0,0 +1,98 @@
+#pragma once
+
+#include <cstdint>
+#include <memory>
+
+#include "envoy/http/codec.h"
+#include "envoy/tcp/conn_pool.h"
+#include "envoy/upstream/thread_local_cluster.h"
+
+#include "source/common/buffer/watermark_buffer.h"
+#include "source/common/common/cleanup.h"
+#include "source/common/common/logger.h"
+#include "source/common/config/well_known_names.h"
+#include "source/common/router/upstream_request.h"
+#include "source/common/stream_info/stream_info_impl.h"
+#include "source/extensions/upstreams/http/tcp/upstream_request.h"
+
+namespace Envoy {
+namespace Extensions {
+namespace Upstreams {
+namespace Http {
+namespace DubboTcp {
+
+class TcpConnPool : public Router::GenericConnPool, public Envoy::Tcp::ConnectionPool::Callbacks {
+public:
+  TcpConnPool(Upstream::ThreadLocalCluster& thread_local_cluster, bool is_connect,
+              const Router::RouteEntry& route_entry, absl::optional<Envoy::Http::Protocol>,
+              Upstream::LoadBalancerContext* ctx) {
+    ASSERT(is_connect);
+    conn_pool_data_ = thread_local_cluster.tcpConnPool(route_entry.priority(), ctx);
+  }
+  void newStream(Router::GenericConnectionPoolCallbacks* callbacks) override {
+    callbacks_ = callbacks;
+    upstream_handle_ = conn_pool_data_.value().newConnection(*this);
+  }
+
+  bool cancelAnyPendingStream() override {
+    if (upstream_handle_) {
+      upstream_handle_->cancel(Envoy::Tcp::ConnectionPool::CancelPolicy::Default);
+      upstream_handle_ = nullptr;
+      return true;
+    }
+    return false;
+  }
+  Upstream::HostDescriptionConstSharedPtr host() const override {
+    return conn_pool_data_.value().host();
+  }
+
+  bool valid() { return conn_pool_data_.has_value(); }
+
+  // Tcp::ConnectionPool::Callbacks
+  void onPoolFailure(ConnectionPool::PoolFailureReason reason,
+                     absl::string_view transport_failure_reason,
+                     Upstream::HostDescriptionConstSharedPtr host) override {
+    upstream_handle_ = nullptr;
+    callbacks_->onPoolFailure(reason, transport_failure_reason, host);
+  }
+
+  void onPoolReady(Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& conn_data,
+                   Upstream::HostDescriptionConstSharedPtr host) override;
+
+private:
+  absl::optional<Envoy::Upstream::TcpPoolData> conn_pool_data_;
+  Envoy::Tcp::ConnectionPool::Cancellable* upstream_handle_{};
+  Router::GenericConnectionPoolCallbacks* callbacks_{};
+};
+
+class TcpUpstream : public Router::GenericUpstream,
+                    public Envoy::Tcp::ConnectionPool::UpstreamCallbacks {
+public:
+  TcpUpstream(Router::UpstreamToDownstream* upstream_request,
+              Envoy::Tcp::ConnectionPool::ConnectionDataPtr&& upstream);
+
+  // GenericUpstream
+  void encodeData(Buffer::Instance& data, bool end_stream) override;
+  void encodeMetadata(const Envoy::Http::MetadataMapVector&) override {}
+  Envoy::Http::Status encodeHeaders(const Envoy::Http::RequestHeaderMap&, bool end_stream) override;
+  void encodeTrailers(const Envoy::Http::RequestTrailerMap&) override;
+  void readDisable(bool disable) override;
+  void resetStream() override;
+  void setAccount(Buffer::BufferMemoryAccountSharedPtr) override {}
+
+  // Tcp::ConnectionPool::UpstreamCallbacks
+  void onUpstreamData(Buffer::Instance& data, bool end_stream) override;
+  void onEvent(Network::ConnectionEvent event) override;
+  void onAboveWriteBufferHighWatermark() override;
+  void onBelowWriteBufferLowWatermark() override;
+
+private:
+  Router::UpstreamToDownstream* upstream_request_;
+  Envoy::Tcp::ConnectionPool::ConnectionDataPtr upstream_conn_data_;
+};
+
+} // namespace DubboTcp
+} // namespace Http
+} // namespace Upstreams
+} // namespace Extensions
+} // namespace Envoy
diff --git a/contrib/upstreams/http/dubbo_tcp/test/BUILD b/contrib/upstreams/http/dubbo_tcp/test/BUILD
new file mode 100644
index 0000000000..3629142ff6
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/test/BUILD
@@ -0,0 +1,33 @@
+load(
+    "//bazel:envoy_build_system.bzl",
+    "envoy_cc_test",
+    "envoy_package",
+)
+
+licenses(["notice"])  # Apache 2
+
+envoy_package()
+
+envoy_cc_test(
+    name = "upstream_request_test",
+    srcs = ["upstream_request_test.cc"],
+    deps = [
+        "//contrib/upstreams/http/dubbo_tcp/source:upstream_request_lib",
+        "//source/common/buffer:buffer_lib",
+        "//source/common/network:address_lib",
+        "//source/common/router:router_lib",
+        "//source/common/upstream:upstream_includes",
+        "//source/common/upstream:upstream_lib",
+        "//test/common/http:common_lib",
+        "//test/mocks:common_lib",
+        "//test/mocks/network:network_mocks",
+        "//test/mocks/router:router_filter_interface",
+        "//test/mocks/router:router_mocks",
+        "//test/mocks/server:factory_context_mocks",
+        "//test/mocks/server:instance_mocks",
+        "//test/mocks/upstream:upstream_mocks",
+        "//test/test_common:environment_lib",
+        "//test/test_common:simulated_time_system_lib",
+        "//test/test_common:utility_lib",
+    ],
+)
diff --git a/contrib/upstreams/http/dubbo_tcp/test/upstream_request_test.cc b/contrib/upstreams/http/dubbo_tcp/test/upstream_request_test.cc
new file mode 100644
index 0000000000..b42a54afa8
--- /dev/null
+++ b/contrib/upstreams/http/dubbo_tcp/test/upstream_request_test.cc
@@ -0,0 +1,280 @@
+#include "source/common/buffer/buffer_impl.h"
+#include "source/common/network/address_impl.h"
+#include "source/common/router/config_impl.h"
+#include "source/common/router/router.h"
+#include "source/common/router/upstream_request.h"
+#include "source/extensions/common/proxy_protocol/proxy_protocol_header.h"
+
+#include "contrib/upstreams/http/dubbo_tcp/source/upstream_request.h"
+
+#include "test/common/http/common.h"
+#include "test/mocks/common.h"
+#include "test/mocks/router/mocks.h"
+#include "test/mocks/router/router_filter_interface.h"
+#include "test/mocks/server/factory_context.h"
+#include "test/mocks/server/instance.h"
+#include "test/mocks/tcp/mocks.h"
+#include "test/test_common/utility.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using Envoy::Http::TestRequestHeaderMapImpl;
+using Envoy::Router::UpstreamRequest;
+using testing::_;
+using testing::AnyNumber;
+using testing::NiceMock;
+using testing::Return;
+using testing::ReturnRef;
+
+namespace Envoy {
+namespace Extensions {
+namespace Upstreams {
+namespace Http {
+namespace DubboTcp {
+
+class TcpConnPoolTest : public ::testing::Test {
+public:
+  TcpConnPoolTest() : host_(std::make_shared<NiceMock<Upstream::MockHost>>()) {
+    NiceMock<Router::MockRouteEntry> route_entry;
+    NiceMock<Upstream::MockClusterManager> cm;
+    cm.initializeThreadLocalClusters({"fake_cluster"});
+    EXPECT_CALL(cm.thread_local_cluster_, tcpConnPool(_, _))
+        .WillOnce(Return(Upstream::TcpPoolData([]() {}, &mock_pool_)));
+    conn_pool_ = std::make_unique<TcpConnPool>(cm.thread_local_cluster_, true, route_entry,
+                                               Envoy::Http::Protocol::Http11, nullptr);
+  }
+
+  std::unique_ptr<TcpConnPool> conn_pool_;
+  Envoy::Tcp::ConnectionPool::MockInstance mock_pool_;
+  Router::MockGenericConnectionPoolCallbacks mock_generic_callbacks_;
+  std::shared_ptr<NiceMock<Upstream::MockHost>> host_;
+  NiceMock<Envoy::ConnectionPool::MockCancellable> cancellable_;
+};
+
+TEST_F(TcpConnPoolTest, Basic) {
+  NiceMock<Network::MockClientConnection> connection;
+
+  EXPECT_CALL(mock_pool_, newConnection(_)).WillOnce(Return(&cancellable_));
+  conn_pool_->newStream(&mock_generic_callbacks_);
+
+  EXPECT_CALL(mock_generic_callbacks_, upstreamToDownstream());
+  EXPECT_CALL(mock_generic_callbacks_, onPoolReady(_, _, _, _, _));
+  auto data = std::make_unique<NiceMock<Envoy::Tcp::ConnectionPool::MockConnectionData>>();
+  EXPECT_CALL(*data, connection()).Times(AnyNumber()).WillRepeatedly(ReturnRef(connection));
+  conn_pool_->onPoolReady(std::move(data), host_);
+}
+
+TEST_F(TcpConnPoolTest, OnPoolFailure) {
+  EXPECT_CALL(mock_pool_, newConnection(_)).WillOnce(Return(&cancellable_));
+  conn_pool_->newStream(&mock_generic_callbacks_);
+
+  EXPECT_CALL(mock_generic_callbacks_, onPoolFailure(_, "foo", _));
+  conn_pool_->onPoolFailure(Envoy::Tcp::ConnectionPool::PoolFailureReason::LocalConnectionFailure,
+                            "foo", host_);
+
+  // Make sure that the pool failure nulled out the pending request.
+  EXPECT_FALSE(conn_pool_->cancelAnyPendingStream());
+}
+
+TEST_F(TcpConnPoolTest, Cancel) {
+  // Initially cancel should fail as there is no pending request.
+  EXPECT_FALSE(conn_pool_->cancelAnyPendingStream());
+
+  EXPECT_CALL(mock_pool_, newConnection(_)).WillOnce(Return(&cancellable_));
+  conn_pool_->newStream(&mock_generic_callbacks_);
+
+  // Canceling should now return true as there was an active request.
+  EXPECT_TRUE(conn_pool_->cancelAnyPendingStream());
+
+  // A second cancel should return false as there is not a pending request.
+  EXPECT_FALSE(conn_pool_->cancelAnyPendingStream());
+}
+
+class TcpUpstreamTest : public ::testing::Test {
+public:
+  TcpUpstreamTest() {
+    EXPECT_CALL(mock_router_filter_, downstreamHeaders())
+        .Times(AnyNumber())
+        .WillRepeatedly(Return(&request_));
+    EXPECT_CALL(mock_router_filter_, cluster()).Times(AnyNumber());
+    mock_router_filter_.requests_.push_back(std::make_unique<UpstreamRequest>(
+        mock_router_filter_, std::make_unique<NiceMock<Router::MockGenericConnPool>>()));
+    auto data = std::make_unique<NiceMock<Envoy::Tcp::ConnectionPool::MockConnectionData>>();
+    EXPECT_CALL(*data, connection()).Times(AnyNumber()).WillRepeatedly(ReturnRef(connection_));
+    tcp_upstream_ =
+        std::make_unique<TcpUpstream>(mock_router_filter_.requests_.front().get(), std::move(data));
+  }
+  ~TcpUpstreamTest() override { EXPECT_CALL(mock_router_filter_, config()).Times(AnyNumber()); }
+
+protected:
+  TestRequestHeaderMapImpl request_{{":method", "CONNECT"},
+                                    {":path", "/"},
+                                    {":protocol", "bytestream"},
+                                    {":scheme", "https"},
+                                    {":authority", "host"}};
+  NiceMock<Network::MockClientConnection> connection_;
+  NiceMock<Router::MockRouterFilterInterface> mock_router_filter_;
+  Envoy::Tcp::ConnectionPool::MockConnectionData* mock_connection_data_;
+  std::unique_ptr<TcpUpstream> tcp_upstream_;
+};
+
+TEST_F(TcpUpstreamTest, Basic) {
+  // Swallow the request headers and generate response headers.
+  EXPECT_CALL(connection_, write(_, false)).Times(0);
+  EXPECT_CALL(mock_router_filter_, onUpstreamHeaders(200, _, _, false));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  // Proxy the data.
+  EXPECT_CALL(connection_, write(BufferStringEqual("foo"), false));
+  Buffer::OwnedImpl buffer("foo");
+  tcp_upstream_->encodeData(buffer, false);
+
+  // Metadata is swallowed.
+  Envoy::Http::MetadataMapVector metadata_map_vector;
+  tcp_upstream_->encodeMetadata(metadata_map_vector);
+
+  // Forward data.
+  Buffer::OwnedImpl response1("bar");
+  // The dubbo forces end_stream to be true in the onupStreamData function.
+  EXPECT_CALL(mock_router_filter_, onUpstreamData(BufferStringEqual("bar"), _, true));
+  tcp_upstream_->onUpstreamData(response1, false);
+}
+
+TEST_F(TcpUpstreamTest, V1Header) {
+  envoy::config::core::v3::ProxyProtocolConfig* proxy_config =
+      mock_router_filter_.route_entry_.connect_config_->mutable_proxy_protocol_config();
+  proxy_config->set_version(envoy::config::core::v3::ProxyProtocolConfig::V1);
+  mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
+      ->setRemoteAddress(std::make_shared<Network::Address::Ipv4Instance>("1.2.3.4", 5));
+  mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
+      ->setLocalAddress(std::make_shared<Network::Address::Ipv4Instance>("4.5.6.7", 8));
+
+  Buffer::OwnedImpl expected_data;
+  Extensions::Common::ProxyProtocol::generateProxyProtoHeader(
+      *proxy_config, mock_router_filter_.client_connection_, expected_data);
+
+  // encodeHeaders now results in the proxy proto header being sent.
+  EXPECT_CALL(connection_, write(BufferEqual(&expected_data), false));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  // Data is proxied as usual.
+  EXPECT_CALL(connection_, write(BufferStringEqual("foo"), false));
+  Buffer::OwnedImpl buffer("foo");
+  tcp_upstream_->encodeData(buffer, false);
+}
+
+TEST_F(TcpUpstreamTest, V2Header) {
+  envoy::config::core::v3::ProxyProtocolConfig* proxy_config =
+      mock_router_filter_.route_entry_.connect_config_->mutable_proxy_protocol_config();
+  proxy_config->set_version(envoy::config::core::v3::ProxyProtocolConfig::V2);
+  mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
+      ->setRemoteAddress(std::make_shared<Network::Address::Ipv4Instance>("1.2.3.4", 5));
+  mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
+      ->setLocalAddress(std::make_shared<Network::Address::Ipv4Instance>("4.5.6.7", 8));
+
+  Buffer::OwnedImpl expected_data;
+  Extensions::Common::ProxyProtocol::generateProxyProtoHeader(
+      *proxy_config, mock_router_filter_.client_connection_, expected_data);
+
+  // encodeHeaders now results in the proxy proto header being sent.
+  EXPECT_CALL(connection_, write(BufferEqual(&expected_data), false));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  // Data is proxied as usual.
+  EXPECT_CALL(connection_, write(BufferStringEqual("foo"), false));
+  Buffer::OwnedImpl buffer("foo");
+  tcp_upstream_->encodeData(buffer, false);
+}
+
+TEST_F(TcpUpstreamTest, TrailersEndStream) {
+  // Swallow the headers.
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  EXPECT_CALL(connection_, write(BufferStringEqual(""), true));
+  Envoy::Http::TestRequestTrailerMapImpl trailers{{"foo", "bar"}};
+  tcp_upstream_->encodeTrailers(trailers);
+}
+
+TEST_F(TcpUpstreamTest, HeaderEndStreamHalfClose) {
+  EXPECT_CALL(connection_, write(BufferStringEqual(""), true));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, true).ok());
+}
+
+TEST_F(TcpUpstreamTest, ReadDisable) {
+  EXPECT_CALL(connection_, readDisable(true));
+  tcp_upstream_->readDisable(true);
+
+  EXPECT_CALL(connection_, readDisable(false));
+  tcp_upstream_->readDisable(false);
+
+  // Once the connection is closed, don't touch it.
+  connection_.state_ = Network::Connection::State::Closed;
+  EXPECT_CALL(connection_, readDisable(_)).Times(0);
+  tcp_upstream_->readDisable(true);
+}
+
+TEST_F(TcpUpstreamTest, UpstreamEvent) {
+  // Make sure upstream disconnects result in stream reset.
+  EXPECT_CALL(mock_router_filter_,
+              onUpstreamReset(Envoy::Http::StreamResetReason::ConnectionTermination, "", _));
+  tcp_upstream_->onEvent(Network::ConnectionEvent::RemoteClose);
+}
+
+TEST_F(TcpUpstreamTest, Watermarks) {
+  EXPECT_CALL(mock_router_filter_, callbacks()).Times(AnyNumber());
+  EXPECT_CALL(mock_router_filter_.callbacks_, onDecoderFilterAboveWriteBufferHighWatermark());
+  tcp_upstream_->onAboveWriteBufferHighWatermark();
+
+  EXPECT_CALL(mock_router_filter_.callbacks_, onDecoderFilterBelowWriteBufferLowWatermark());
+  tcp_upstream_->onBelowWriteBufferLowWatermark();
+}
+
+TEST_F(TcpUpstreamTest, EmptyConnectConfig) {
+  NiceMock<Envoy::Router::MockRouteEntry> route_entry;
+  EXPECT_FALSE(route_entry.connect_config_.has_value());
+  EXPECT_CALL(mock_router_filter_, routeEntry()).WillOnce(Return(&route_entry));
+
+  // Swallow the request headers and generate response headers.
+  EXPECT_CALL(connection_, write(_, false)).Times(0);
+  EXPECT_CALL(mock_router_filter_, onUpstreamHeaders(200, _, _, false));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  // Proxy the data.
+  EXPECT_CALL(connection_, write(BufferStringEqual("foo"), false));
+  Buffer::OwnedImpl buffer("foo");
+  tcp_upstream_->encodeData(buffer, false);
+
+  // Metadata is swallowed.
+  Envoy::Http::MetadataMapVector metadata_map_vector;
+  tcp_upstream_->encodeMetadata(metadata_map_vector);
+
+  // Forward data.
+  Buffer::OwnedImpl response1("bar");
+  // The dubbo forces end_stream to be true in the onupStreamData function.
+  EXPECT_CALL(mock_router_filter_, onUpstreamData(BufferStringEqual("bar"), _, true));
+  tcp_upstream_->onUpstreamData(response1, false);
+}
+
+TEST_F(TcpUpstreamTest, ConnectConfig) {
+  NiceMock<Envoy::Router::MockRouteEntry> route_entry;
+  route_entry.connect_config_ = absl::make_optional<Envoy::Router::RouteEntry::ConnectConfig>();
+  EXPECT_TRUE(route_entry.connect_config_.has_value());
+  EXPECT_CALL(mock_router_filter_, routeEntry()).WillOnce(Return(&route_entry));
+
+  // Swallow the request headers and generate response headers.
+  EXPECT_CALL(connection_, write(_, false)).Times(0);
+  EXPECT_CALL(mock_router_filter_, onUpstreamHeaders(200, _, _, false));
+  EXPECT_TRUE(tcp_upstream_->encodeHeaders(request_, false).ok());
+
+  // Proxy the data.
+  EXPECT_CALL(connection_, write(BufferStringEqual("foo"), false));
+  Buffer::OwnedImpl buffer("foo");
+  tcp_upstream_->encodeData(buffer, false);
+}
+
+} // namespace DubboTcp
+} // namespace Http
+} // namespace Upstreams
+} // namespace Extensions
+} // namespace Envoy
diff --git a/envoy/config/extension_config_provider.h b/envoy/config/extension_config_provider.h
index ce84225eb6..ba8761f045 100644
--- a/envoy/config/extension_config_provider.h
+++ b/envoy/config/extension_config_provider.h
@@ -16,7 +16,7 @@ using ConfigAppliedCb = std::function<void()>;
  * the extension configuration discovery service. Dynamically updated extension
  * configurations may share subscriptions across extension config providers.
  */
-template <class Factory, class FactoryCallback> class ExtensionConfigProvider {
+template <class FactoryCallback> class ExtensionConfigProvider {
 public:
   virtual ~ExtensionConfigProvider() = default;
 
@@ -35,17 +35,20 @@ public:
   virtual absl::optional<FactoryCallback> config() PURE;
 };
 
-template <class FactoryCallback> class DynamicExtensionConfigProviderBase {
+class DynamicExtensionConfigProviderBase {
 public:
   virtual ~DynamicExtensionConfigProviderBase() = default;
 
   /**
-   * Update the provider with a new configuration.
-   * @param config is an extension factory callback to replace the existing configuration.
+   * Update the provider with a new configuration. This interface accepts proto rather than a
+   * factory callback so that it can be generic over factory types. If instantiating the factory
+   * throws, it should only do so on the main thread, before any changes are applied to workers.
+   * @param config is the new configuration. It is expected that the configuration has already been
+   * validated.
    * @param version_info is the version of the new extension configuration.
    * @param cb the continuation callback for a completed configuration application on all threads.
    */
-  virtual void onConfigUpdate(FactoryCallback config, const std::string& version_info,
+  virtual void onConfigUpdate(const Protobuf::Message& config, const std::string& version_info,
                               ConfigAppliedCb applied_on_all_threads) PURE;
 
   /**
@@ -60,9 +63,9 @@ public:
   virtual void applyDefaultConfiguration() PURE;
 };
 
-template <class Factory, class FactoryCallback>
-class DynamicExtensionConfigProvider : public DynamicExtensionConfigProviderBase<FactoryCallback>,
-                                       public ExtensionConfigProvider<Factory, FactoryCallback> {};
+template <class FactoryCallback>
+class DynamicExtensionConfigProvider : public DynamicExtensionConfigProviderBase,
+                                       public ExtensionConfigProvider<FactoryCallback> {};
 
 } // namespace Config
 } // namespace Envoy
diff --git a/envoy/filter/config_provider_manager.h b/envoy/filter/config_provider_manager.h
index 824c36e73d..cd1affc579 100644
--- a/envoy/filter/config_provider_manager.h
+++ b/envoy/filter/config_provider_manager.h
@@ -2,7 +2,6 @@
 
 #include "envoy/config/core/v3/config_source.pb.h"
 #include "envoy/config/extension_config_provider.h"
-#include "envoy/http/filter.h"
 #include "envoy/init/manager.h"
 #include "envoy/server/filter_config.h"
 
@@ -11,19 +10,20 @@
 namespace Envoy {
 namespace Filter {
 
-using FilterConfigProvider =
-    Envoy::Config::ExtensionConfigProvider<Server::Configuration::NamedHttpFilterConfigFactory,
-                                           Envoy::Http::FilterFactoryCb>;
-using FilterConfigProviderPtr = std::unique_ptr<FilterConfigProvider>;
-using DynamicFilterConfigProvider = Envoy::Config::DynamicExtensionConfigProvider<
-    Server::Configuration::NamedHttpFilterConfigFactory, Envoy::Http::FilterFactoryCb>;
-using DynamicFilterConfigProviderPtr = std::unique_ptr<DynamicFilterConfigProvider>;
+template <class FactoryCb>
+using FilterConfigProvider = Envoy::Config::ExtensionConfigProvider<FactoryCb>;
+template <class FactoryCb>
+using FilterConfigProviderPtr = std::unique_ptr<FilterConfigProvider<FactoryCb>>;
+template <class FactoryCb>
+using DynamicFilterConfigProvider = Envoy::Config::DynamicExtensionConfigProvider<FactoryCb>;
+template <class FactoryCb>
+using DynamicFilterConfigProviderPtr = std::unique_ptr<DynamicFilterConfigProvider<FactoryCb>>;
 
 /**
  * The FilterConfigProviderManager exposes the ability to get an FilterConfigProvider
  * for both static and dynamic filter config providers.
  */
-class FilterConfigProviderManager {
+template <class FactoryCb> class FilterConfigProviderManager {
 public:
   virtual ~FilterConfigProviderManager() = default;
 
@@ -38,7 +38,7 @@ public:
    * configured chain
    * @param filter_chain_type is the filter chain type
    */
-  virtual DynamicFilterConfigProviderPtr createDynamicFilterConfigProvider(
+  virtual DynamicFilterConfigProviderPtr<FactoryCb> createDynamicFilterConfigProvider(
       const envoy::config::core::v3::ExtensionConfigSource& config_source,
       const std::string& filter_config_name, Server::Configuration::FactoryContext& factory_context,
       const std::string& stat_prefix, bool last_filter_in_filter_chain,
@@ -49,8 +49,8 @@ public:
    * @param config is a fully resolved filter instantiation factory.
    * @param filter_config_name is the name of the filter configuration resource.
    */
-  virtual FilterConfigProviderPtr
-  createStaticFilterConfigProvider(const Envoy::Http::FilterFactoryCb& config,
+  virtual FilterConfigProviderPtr<FactoryCb>
+  createStaticFilterConfigProvider(const FactoryCb& config,
                                    const std::string& filter_config_name) PURE;
 };
 
diff --git a/envoy/http/header_map.h b/envoy/http/header_map.h
index 3fb5506c84..d84d7dc516 100644
--- a/envoy/http/header_map.h
+++ b/envoy/http/header_map.h
@@ -74,7 +74,6 @@ public:
   bool operator==(const LowerCaseString& rhs) const { return string_ == rhs.string_; }
   bool operator!=(const LowerCaseString& rhs) const { return string_ != rhs.string_; }
   bool operator<(const LowerCaseString& rhs) const { return string_.compare(rhs.string_) < 0; }
-
   friend std::ostream& operator<<(std::ostream& os, const LowerCaseString& lower_case_string) {
     return os << lower_case_string.string_;
   }
@@ -82,7 +81,14 @@ public:
   // Implicit conversion to absl::string_view.
   operator absl::string_view() const { return string_; }
 
+#if defined(ALIMESH)
+  virtual ~LowerCaseString() = default;
+
+protected:
+#else
 private:
+#endif
+
   void lower() {
     std::transform(string_.begin(), string_.end(), string_.begin(), absl::ascii_tolower);
   }
@@ -304,6 +310,7 @@ private:
   HEADER_FUNC(Expect)                                                                              \
   HEADER_FUNC(ForwardedClientCert)                                                                 \
   HEADER_FUNC(ForwardedFor)                                                                        \
+  HEADER_FUNC(ForwardedHost)                                                                       \
   HEADER_FUNC(ForwardedProto)                                                                      \
   HEADER_FUNC(GrpcTimeout)                                                                         \
   HEADER_FUNC(Host)                                                                                \
@@ -346,9 +353,6 @@ private:
   INLINE_RESP_STRING_HEADERS(HEADER_FUNC)                                                          \
   INLINE_RESP_NUMERIC_HEADERS(HEADER_FUNC)
 
-/**
- * Default O(1) request and response headers.
- */
 #define INLINE_REQ_RESP_STRING_HEADERS(HEADER_FUNC)                                                \
   HEADER_FUNC(Connection)                                                                          \
   HEADER_FUNC(ContentType)                                                                         \
diff --git a/envoy/router/BUILD b/envoy/router/BUILD
index 86bc52bc99..97fb35e916 100644
--- a/envoy/router/BUILD
+++ b/envoy/router/BUILD
@@ -11,6 +11,9 @@ envoy_package()
 envoy_cc_library(
     name = "context_interface",
     hdrs = ["context.h"],
+    deps = [
+        ":router_interface",
+    ],
 )
 
 envoy_cc_library(
@@ -57,6 +60,9 @@ envoy_cc_library(
 envoy_cc_library(
     name = "router_interface",
     hdrs = ["router.h"],
+    alimesh_deps = [
+        "//contrib/envoy/http:active_redirect_policy_interface",
+    ],
     external_deps = ["abseil_optional"],
     deps = [
         ":internal_redirect_interface",
@@ -129,3 +135,13 @@ envoy_cc_library(
         "//source/common/common:minimal_logger_lib",
     ],
 )
+
+envoy_cc_library(
+    name = "cluster_specifier_plugin_interface",
+    hdrs = ["cluster_specifier_plugin.h"],
+    deps = [
+        ":router_interface",
+        "//envoy/config:typed_config_interface",
+        "//envoy/server:factory_context_interface",
+    ],
+)
diff --git a/envoy/router/cluster_specifier_plugin.h b/envoy/router/cluster_specifier_plugin.h
new file mode 100644
index 0000000000..7e0257aabf
--- /dev/null
+++ b/envoy/router/cluster_specifier_plugin.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <functional>
+#include <memory>
+#include <string>
+
+#include "envoy/common/pure.h"
+#include "envoy/config/typed_config.h"
+#include "envoy/router/router.h"
+#include "envoy/server/factory_context.h"
+
+namespace Envoy {
+namespace Router {
+
+/**
+ * Interface class for creating cluster specifier plugin from related route entry.
+ */
+class ClusterSpecifierPlugin {
+public:
+  virtual ~ClusterSpecifierPlugin() = default;
+
+  /**
+   * Create route from related route entry and request headers.
+   *
+   * @param parent related route entry.
+   * @param header request headers.
+   * @return RouteConstSharedPtr final route with specific cluster.
+   */
+  virtual RouteConstSharedPtr route(const RouteEntry& parent,
+                                    const Http::RequestHeaderMap& header) const PURE;
+};
+
+using ClusterSpecifierPluginSharedPtr = std::shared_ptr<ClusterSpecifierPlugin>;
+
+/*
+ * Extension configuration for cluster specifier plugin factory.
+ */
+class ClusterSpecifierPluginFactoryConfig : public Envoy::Config::TypedFactory {
+public:
+  /**
+   * Creates a particular cluster specifier plugin factory implementation.
+   *
+   * @param config supplies the configuration for the cluster specifier plugin factory extension.
+   * @return ClusterSpecifierPluginSharedPtr cluster specifier plugin use to create final route from
+   * request headers.
+   */
+  virtual ClusterSpecifierPluginSharedPtr
+  createClusterSpecifierPlugin(const Protobuf::Message& config,
+                               Server::Configuration::CommonFactoryContext& context) PURE;
+
+  std::string category() const override { return "envoy.router.cluster_specifier_plugin"; }
+};
+
+using ClusterSpecifierPluginFactoryConfigPtr = std::unique_ptr<ClusterSpecifierPluginFactoryConfig>;
+
+} // namespace Router
+} // namespace Envoy
diff --git a/envoy/router/context.h b/envoy/router/context.h
index 2d3dc4ad92..54fdbdfb74 100644
--- a/envoy/router/context.h
+++ b/envoy/router/context.h
@@ -1,12 +1,14 @@
 #pragma once
 
 #include "envoy/common/pure.h"
+#include "envoy/router/router.h"
 
 namespace Envoy {
 namespace Router {
 
 struct StatNames;
 struct VirtualClusterStatNames;
+struct RouteStatNames;
 
 class Context {
 public:
@@ -21,6 +23,16 @@ public:
    * @return a struct containing StatNames for virtual cluster stats.
    */
   virtual const VirtualClusterStatNames& virtualClusterStatNames() const PURE;
+
+  /**
+   * @return a struct containing StatNames for route level stats.
+   */
+  virtual const RouteStatNames& routeStatNames() const PURE;
+
+  /**
+   * @return a reference to the default generic connection pool factory.
+   */
+  virtual GenericConnPoolFactory& genericConnPoolFactory() PURE;
 };
 
 } // namespace Router
diff --git a/envoy/router/router.h b/envoy/router/router.h
index b7d8f8db2f..ad2e5bfd74 100644
--- a/envoy/router/router.h
+++ b/envoy/router/router.h
@@ -30,6 +30,10 @@
 
 #include "absl/types/optional.h"
 
+#if defined(ALIMESH)
+#include "contrib/envoy/http/active_redirect_policy.h"
+#endif
+
 namespace Envoy {
 
 namespace Upstream {
@@ -487,12 +491,58 @@ using ShadowPolicyPtr = std::unique_ptr<ShadowPolicy>;
   STATNAME(vcluster)                                                                               \
   STATNAME(vhost)
 
+/**
+ * All route level stats. @see stats_macro.h
+ */
+#define ALL_ROUTE_STATS(COUNTER, GAUGE, HISTOGRAM, TEXT_READOUT, STATNAME)                         \
+  COUNTER(upstream_rq_retry)                                                                       \
+  COUNTER(upstream_rq_retry_limit_exceeded)                                                        \
+  COUNTER(upstream_rq_retry_overflow)                                                              \
+  COUNTER(upstream_rq_retry_success)                                                               \
+  COUNTER(upstream_rq_timeout)                                                                     \
+  COUNTER(upstream_rq_total)                                                                       \
+  STATNAME(route)                                                                                  \
+  STATNAME(vhost)
+
 /**
  * Struct definition for all virtual cluster stats. @see stats_macro.h
  */
 MAKE_STAT_NAMES_STRUCT(VirtualClusterStatNames, ALL_VIRTUAL_CLUSTER_STATS);
 MAKE_STATS_STRUCT(VirtualClusterStats, VirtualClusterStatNames, ALL_VIRTUAL_CLUSTER_STATS);
 
+/**
+ * Struct definition for all route level stats. @see stats_macro.h
+ */
+MAKE_STAT_NAMES_STRUCT(RouteStatNames, ALL_ROUTE_STATS);
+MAKE_STATS_STRUCT(RouteStats, RouteStatNames, ALL_ROUTE_STATS);
+
+/**
+ * RouteStatsContext defines config needed to generate all route level stats.
+ */
+class RouteStatsContext {
+public:
+  RouteStatsContext(Stats::Scope& scope, const RouteStatNames& route_stat_names,
+                    const Stats::StatName& vhost_stat_name, const std::string& stat_prefix)
+      : route_stat_name_storage_(stat_prefix, scope.symbolTable()),
+        route_stats_scope_(Stats::Utility::scopeFromStatNames(
+            scope, {route_stat_names.vhost_, vhost_stat_name, route_stat_names.route_,
+                    route_stat_name_storage_.statName()})),
+        route_stat_name_(route_stat_name_storage_.statName()),
+        route_stats_(route_stat_names, *route_stats_scope_) {}
+
+  const Stats::StatName statName() const { return route_stat_name_; }
+  const RouteStats& stats() const { return route_stats_; }
+
+private:
+  const Stats::StatNameManagedStorage route_stat_name_storage_;
+  Stats::ScopeSharedPtr route_stats_scope_;
+  Stats::StatName route_stat_name_;
+  RouteStats route_stats_;
+};
+
+using RouteStatsContextPtr = std::unique_ptr<RouteStatsContext>;
+using RouteStatsContextOptRef = OptRef<RouteStatsContext>;
+
 /**
  * Virtual cluster definition (allows splitting a virtual host into virtual clusters orthogonal to
  * routes for stat tracking and priority purposes).
@@ -501,6 +551,11 @@ class VirtualCluster {
 public:
   virtual ~VirtualCluster() = default;
 
+  /**
+   * @return the string name of the virtual cluster.
+   */
+  virtual const absl::optional<std::string>& name() const PURE;
+
   /**
    * @return the stat-name of the virtual cluster.
    */
@@ -870,6 +925,11 @@ public:
    */
   virtual bool autoHostRewrite() const PURE;
 
+  /**
+   * @return bool true if the x-forwarded-host header should be updated.
+   */
+  virtual bool appendXfh() const PURE;
+
   /**
    * @return MetadataMatchCriteria* the metadata that a subset load balancer should match when
    * selecting an upstream host
@@ -928,6 +988,15 @@ public:
    * @return std::string& the name of the route.
    */
   virtual const std::string& routeName() const PURE;
+
+#if defined(ALIMESH)
+  virtual const InternalActiveRedirectPolicy& internalActiveRedirectPolicy() const PURE;
+#endif
+  /**
+   * @return RouteStatsContextOptRef the config needed to generate route level stats.
+   */
+  virtual const RouteStatsContextOptRef routeStatsContext() const PURE;
+
 };
 
 /**
@@ -1206,9 +1275,9 @@ public:
 class UpstreamToDownstream : public Http::ResponseDecoder, public Http::StreamCallbacks {
 public:
   /**
-   * @return return the routeEntry for the downstream stream.
+   * @return return the route for the downstream stream.
    */
-  virtual const RouteEntry& routeEntry() const PURE;
+  virtual const Route& route() const PURE;
   /**
    * @return return the connection for the downstream stream.
    */
diff --git a/envoy/stream_info/stream_info.h b/envoy/stream_info/stream_info.h
index 1a48d18e2c..c6d82db4f4 100644
--- a/envoy/stream_info/stream_info.h
+++ b/envoy/stream_info/stream_info.h
@@ -290,6 +290,16 @@ public:
    * @return std::string& the name of the route.
    */
   virtual const std::string& getRouteName() const PURE;
+  /**
+   * @param std::string name denotes the name of the virtual cluster.
+   */
+  virtual void setVirtualClusterName(const absl::optional<std::string>& name) PURE;
+
+  /**
+   * @return std::string& the name of the virtual cluster which got matched.
+   */
+  virtual const absl::optional<std::string>& virtualClusterName() const PURE;
+
   /**
    * @param bytes_received denotes number of bytes to add to total received bytes.
    */
diff --git a/envoy/thread_local/thread_local.h b/envoy/thread_local/thread_local.h
index b314fa817a..07f1e03e82 100644
--- a/envoy/thread_local/thread_local.h
+++ b/envoy/thread_local/thread_local.h
@@ -77,6 +77,13 @@ protected:
   // Callers must use the TypedSlot API, below.
   virtual void runOnAllThreads(const UpdateCb& update_cb) PURE;
   virtual void runOnAllThreads(const UpdateCb& update_cb, const Event::PostCb& complete_cb) PURE;
+
+  /**
+   * Returns whether or not global threading has been shutdown.
+   *
+   * @return true if global threading has been shutdown or false if not.
+   */
+  virtual bool isShutdown() const PURE;
 };
 
 using SlotPtr = std::unique_ptr<Slot>;
@@ -177,6 +184,13 @@ public:
     slot_->runOnAllThreads(makeSlotUpdateCb(cb), complete_cb);
   }
 
+  /**
+   * Returns whether or not global threading has been shutdown.
+   *
+   * @return true if global threading has been shutdown or false if not.
+   */
+  bool isShutdown() const { return slot_->isShutdown(); };
+
 private:
   static OptRef<T> getOpt(ThreadLocalObjectSharedPtr obj) {
     if (obj) {
diff --git a/envoy/upstream/outlier_detection.h b/envoy/upstream/outlier_detection.h
index 038e81b88e..aefd450cac 100644
--- a/envoy/upstream/outlier_detection.h
+++ b/envoy/upstream/outlier_detection.h
@@ -110,6 +110,10 @@ public:
    * and LocalOrigin type returns success rate for local origin errors.
    */
   virtual double successRate(SuccessRateMonitorType type) const PURE;
+
+#if defined(ALIMESH)
+  virtual void forceEjectHost() PURE;
+#endif
 };
 
 using DetectorHostMonitorPtr = std::unique_ptr<DetectorHostMonitor>;
diff --git a/source/common/config/well_known_names.cc b/source/common/config/well_known_names.cc
index 71a03839b1..2f186e5b47 100644
--- a/source/common/config/well_known_names.cc
+++ b/source/common/config/well_known_names.cc
@@ -136,6 +136,9 @@ TagNameValues::TagNameValues() {
 
   // listener_manager.(worker_<id>.)*
   addRe2(WORKER_ID, R"(^listener_manager\.((worker_\d+)\.))", "listener_manager.worker_");
+
+  // vhost.[<virtual host name>.]route.(<route_stat_prefix>.)*
+  addTokenized(ROUTE, "vhost.*.route.$.**");
 }
 
 void TagNameValues::addRe2(const std::string& name, const std::string& regex,
diff --git a/source/common/config/well_known_names.h b/source/common/config/well_known_names.h
index 0b694392a4..5c556f682d 100644
--- a/source/common/config/well_known_names.h
+++ b/source/common/config/well_known_names.h
@@ -126,6 +126,8 @@ public:
   const std::string RESPONSE_CODE_CLASS = "envoy.response_code_class";
   // Route config name for RDS updates
   const std::string RDS_ROUTE_CONFIG = "envoy.rds_route_config";
+  // Request route given by the Router http filter
+  const std::string ROUTE = "envoy.route";
   // Listener manager worker id
   const std::string WORKER_ID = "envoy.worker_id";
 
diff --git a/source/common/conn_pool/BUILD b/source/common/conn_pool/BUILD
index d526dfbf95..048aa131fb 100644
--- a/source/common/conn_pool/BUILD
+++ b/source/common/conn_pool/BUILD
@@ -14,6 +14,7 @@ envoy_cc_library(
     hdrs = ["conn_pool_base.h"],
     deps = [
         "//envoy/stats:timespan_interface",
+        "//source/common/common:debug_recursion_checker_lib",
         "//source/common/common:linked_object",
         "//source/common/stats:timespan_lib",
         "//source/common/upstream:upstream_lib",
diff --git a/source/common/conn_pool/conn_pool_base.cc b/source/common/conn_pool/conn_pool_base.cc
index 113836ab13..a0f6d30ba5 100644
--- a/source/common/conn_pool/conn_pool_base.cc
+++ b/source/common/conn_pool/conn_pool_base.cc
@@ -1,6 +1,7 @@
 #include "source/common/conn_pool/conn_pool_base.h"
 
 #include "source/common/common/assert.h"
+#include "source/common/common/debug_recursion_checker.h"
 #include "source/common/network/transport_socket_options_impl.h"
 #include "source/common/runtime/runtime_features.h"
 #include "source/common/stats/timespan_impl.h"
@@ -333,6 +334,8 @@ void ConnPoolImplBase::transitionActiveClientState(ActiveClient& client,
 void ConnPoolImplBase::addIdleCallbackImpl(Instance::IdleCb cb) { idle_callbacks_.push_back(cb); }
 
 void ConnPoolImplBase::closeIdleConnectionsForDrainingPool() {
+  Common::AutoDebugRecursionChecker assert_not_in(recursion_checker_);
+
   // Create a separate list of elements to close to avoid mutate-while-iterating problems.
   std::list<ActiveClient*> to_close;
 
@@ -387,11 +390,7 @@ bool ConnPoolImplBase::isIdleImpl() const {
          connecting_clients_.empty();
 }
 
-void ConnPoolImplBase::checkForIdleAndCloseIdleConnsIfDraining() {
-  if (is_draining_for_deletion_) {
-    closeIdleConnectionsForDrainingPool();
-  }
-
+void ConnPoolImplBase::checkForIdleAndNotify() {
   if (isIdleImpl()) {
     ENVOY_LOG(debug, "invoking idle callbacks - is_draining_for_deletion_={}",
               is_draining_for_deletion_);
@@ -401,6 +400,14 @@ void ConnPoolImplBase::checkForIdleAndCloseIdleConnsIfDraining() {
   }
 }
 
+void ConnPoolImplBase::checkForIdleAndCloseIdleConnsIfDraining() {
+  if (is_draining_for_deletion_) {
+    closeIdleConnectionsForDrainingPool();
+  }
+
+  checkForIdleAndNotify();
+}
+
 void ConnPoolImplBase::onConnectionEvent(ActiveClient& client, absl::string_view failure_reason,
                                          Network::ConnectionEvent event) {
   if (client.state() == ActiveClient::State::CONNECTING) {
@@ -459,7 +466,15 @@ void ConnPoolImplBase::onConnectionEvent(ActiveClient& client, absl::string_view
 
     dispatcher_.deferredDelete(client.removeFromList(owningList(client.state())));
 
-    checkForIdleAndCloseIdleConnsIfDraining();
+    // Check if the pool transitioned to idle state after removing closed client
+    // from one of the client tracking lists.
+    // There is no need to check if other connections are idle in a draining pool
+    // because the pool will close all idle connection when it is starting to
+    // drain.
+    // Trying to close other connections here can lead to deep recursion when
+    // a large number idle connections are closed at the start of pool drain.
+    // See CdsIntegrationTest.CdsClusterDownWithLotsOfIdleConnections for an example.
+    checkForIdleAndNotify();
 
     client.setState(ActiveClient::State::CLOSED);
 
diff --git a/source/common/conn_pool/conn_pool_base.h b/source/common/conn_pool/conn_pool_base.h
index dafc845f88..b8884ddee7 100644
--- a/source/common/conn_pool/conn_pool_base.h
+++ b/source/common/conn_pool/conn_pool_base.h
@@ -6,6 +6,7 @@
 #include "envoy/stats/timespan.h"
 #include "envoy/upstream/cluster_manager.h"
 
+#include "source/common/common/debug_recursion_checker.h"
 #include "source/common/common/dump_state_utils.h"
 #include "source/common/common/linked_object.h"
 
@@ -201,6 +202,9 @@ public:
   void onConnectionEvent(ActiveClient& client, absl::string_view failure_reason,
                          Network::ConnectionEvent event);
 
+  // Check if the pool has gone idle and invoke idle notification callbacks.
+  void checkForIdleAndNotify();
+
   // See if the pool has gone idle. If we're draining, this will also close idle connections.
   void checkForIdleAndCloseIdleConnsIfDraining();
 
@@ -341,6 +345,7 @@ private:
 
   void onUpstreamReady();
   Event::SchedulableCallbackPtr upstream_ready_cb_;
+  Common::DebugRecursionChecker recursion_checker_;
 };
 
 } // namespace ConnectionPool
diff --git a/source/common/filter/config_discovery_impl.cc b/source/common/filter/config_discovery_impl.cc
index 74acc6b838..840035f4a7 100644
--- a/source/common/filter/config_discovery_impl.cc
+++ b/source/common/filter/config_discovery_impl.cc
@@ -8,7 +8,6 @@
 
 #include "source/common/common/containers.h"
 #include "source/common/common/thread.h"
-#include "source/common/config/utility.h"
 #include "source/common/grpc/common.h"
 #include "source/common/protobuf/utility.h"
 
@@ -57,23 +56,15 @@ void DynamicFilterConfigProviderImplBase::validateTypeUrl(const std::string& typ
 
 const std::string& DynamicFilterConfigProviderImplBase::name() { return subscription_->name(); }
 
-void DynamicFilterConfigProviderImplBase::validateTerminalFilter(const std::string& name,
-                                                                 const std::string& filter_type,
-                                                                 bool is_terminal_filter) {
-  Config::Utility::validateTerminalFilters(name, filter_type, filter_chain_type_,
-                                           is_terminal_filter, last_filter_in_filter_chain_);
-}
-
 FilterConfigSubscription::FilterConfigSubscription(
     const envoy::config::core::v3::ConfigSource& config_source,
-    const std::string& filter_config_name, Server::Configuration::FactoryContext& factory_context,
-    const std::string& stat_prefix,
+    const std::string& filter_config_name,
+    Server::Configuration::ServerFactoryContext& factory_context, const std::string& stat_prefix,
     FilterConfigProviderManagerImplBase& filter_config_provider_manager,
     const std::string& subscription_id)
     : Config::SubscriptionBase<envoy::config::core::v3::TypedExtensionConfig>(
           factory_context.messageValidationContext().dynamicValidationVisitor(), "name"),
       filter_config_name_(filter_config_name), factory_context_(factory_context),
-      validator_(factory_context.messageValidationContext().dynamicValidationVisitor()),
       init_target_(fmt::format("FilterConfigSubscription init {}", filter_config_name_),
                    [this]() { start(); }),
       scope_(factory_context.scope().createScope(stat_prefix + "extension_config_discovery." +
@@ -116,9 +107,6 @@ void FilterConfigSubscription::onConfigUpdate(
   if (new_hash == last_config_hash_) {
     return;
   }
-  auto& factory =
-      Config::Utility::getAndCheckFactory<Server::Configuration::NamedHttpFilterConfigFactory>(
-          filter_config);
   // Ensure that the filter config is valid in the filter chain context once the proto is processed.
   // Validation happens before updating to prevent a partial update application. It might be
   // possible that the providers have distinct type URL constraints.
@@ -126,29 +114,25 @@ void FilterConfigSubscription::onConfigUpdate(
   for (auto* provider : filter_config_providers_) {
     provider->validateTypeUrl(type_url);
   }
-  ProtobufTypes::MessagePtr message = Config::Utility::translateAnyToFactoryConfig(
-      filter_config.typed_config(), validator_, factory);
-  bool is_terminal_filter = factory.isTerminalFilterByProto(*message, factory_context_);
+  auto [message, factory_name] =
+      filter_config_provider_manager_.getMessage(filter_config, factory_context_);
   for (auto* provider : filter_config_providers_) {
-    provider->validateTerminalFilter(filter_config_name_, factory.name(), is_terminal_filter);
+    provider->validateMessage(filter_config_name_, *message, factory_name);
   }
-  Envoy::Http::FilterFactoryCb factory_callback =
-      factory.createFilterFactoryFromProto(*message, stat_prefix_, factory_context_);
   ENVOY_LOG(debug, "Updating filter config {}", filter_config_name_);
 
   Common::applyToAllWithCleanup<DynamicFilterConfigProviderImplBase*>(
       filter_config_providers_,
-      [&factory_callback, &version_info](DynamicFilterConfigProviderImplBase* provider,
-                                         std::shared_ptr<Cleanup> cleanup) {
-        provider->onConfigUpdate(factory_callback, version_info, [cleanup] {});
+      [&message = message, &version_info](DynamicFilterConfigProviderImplBase* provider,
+                                          std::shared_ptr<Cleanup> cleanup) {
+        provider->onConfigUpdate(*message, version_info, [cleanup] {});
       },
       [this]() { stats_.config_reload_.inc(); });
   last_config_hash_ = new_hash;
-  last_config_ = factory_callback;
+  last_config_ = std::move(message);
   last_type_url_ = type_url;
   last_version_info_ = version_info;
-  last_filter_name_ = factory.name();
-  last_filter_is_terminal_ = is_terminal_filter;
+  last_factory_name_ = factory_name;
 }
 
 void FilterConfigSubscription::onConfigUpdate(
@@ -165,10 +149,10 @@ void FilterConfigSubscription::onConfigUpdate(
         [this]() { stats_.config_reload_.inc(); });
 
     last_config_hash_ = 0;
-    last_config_ = absl::nullopt;
+    last_config_ = nullptr;
     last_type_url_ = "";
-    last_filter_is_terminal_ = false;
-    last_filter_name_ = "";
+    last_version_info_ = "";
+    last_factory_name_ = "";
   } else if (!added_resources.empty()) {
     onConfigUpdate(added_resources, added_resources[0].get().version());
   }
@@ -202,7 +186,8 @@ std::shared_ptr<FilterConfigSubscription> FilterConfigProviderManagerImplBase::g
   auto it = subscriptions_.find(subscription_id);
   if (it == subscriptions_.end()) {
     auto subscription = std::make_shared<FilterConfigSubscription>(
-        config_source, name, factory_context, stat_prefix, *this, subscription_id);
+        config_source, name, factory_context.getServerFactoryContext(), stat_prefix, *this,
+        subscription_id);
     subscriptions_.insert({subscription_id, std::weak_ptr<FilterConfigSubscription>(subscription)});
     return subscription;
   } else {
@@ -222,11 +207,11 @@ void FilterConfigProviderManagerImplBase::applyLastOrDefaultConfig(
   // update arrives first. In this case, use the default config, increment a metric,
   // and the applied config eventually converges once ECDS update arrives.
   bool last_config_valid = false;
-  if (subscription->lastConfig().has_value()) {
+  if (subscription->lastConfig()) {
     TRY_ASSERT_MAIN_THREAD {
       provider.validateTypeUrl(subscription->lastTypeUrl());
-      provider.validateTerminalFilter(filter_config_name, subscription->lastFilterName(),
-                                      subscription->isLastFilterTerminal());
+      provider.validateMessage(filter_config_name, *subscription->lastConfig(),
+                               subscription->lastFactoryName());
       last_config_valid = true;
     }
     END_TRY catch (const EnvoyException& e) {
@@ -235,7 +220,7 @@ void FilterConfigProviderManagerImplBase::applyLastOrDefaultConfig(
       subscription->incrementConflictCounter();
     }
     if (last_config_valid) {
-      provider.onConfigUpdate(subscription->lastConfig().value(), subscription->lastVersionInfo(),
+      provider.onConfigUpdate(*subscription->lastConfig(), subscription->lastVersionInfo(),
                               nullptr);
     }
   }
@@ -246,49 +231,23 @@ void FilterConfigProviderManagerImplBase::applyLastOrDefaultConfig(
   }
 }
 
-DynamicFilterConfigProviderPtr FilterConfigProviderManagerImpl::createDynamicFilterConfigProvider(
-    const envoy::config::core::v3::ExtensionConfigSource& config_source,
-    const std::string& filter_config_name, Server::Configuration::FactoryContext& factory_context,
-    const std::string& stat_prefix, bool last_filter_in_filter_chain,
-    const std::string& filter_chain_type) {
-  auto subscription = getSubscription(config_source.config_source(), filter_config_name,
-                                      factory_context, stat_prefix);
-  // For warming, wait until the subscription receives the first response to indicate readiness.
-  // Otherwise, mark ready immediately and start the subscription on initialization. A default
-  // config is expected in the latter case.
-  if (!config_source.apply_default_config_without_warming()) {
-    factory_context.initManager().add(subscription->initTarget());
-  }
-  absl::flat_hash_set<std::string> require_type_urls;
-  for (const auto& type_url : config_source.type_urls()) {
-    auto factory_type_url = TypeUtil::typeUrlToDescriptorFullName(type_url);
-    require_type_urls.emplace(factory_type_url);
-  }
-
-  Envoy::Http::FilterFactoryCb default_config = nullptr;
-  if (config_source.has_default_config()) {
-    default_config = getDefaultConfig(config_source.default_config(), filter_config_name,
-                                      factory_context, stat_prefix, last_filter_in_filter_chain,
-                                      filter_chain_type, require_type_urls);
-  }
-
-  auto provider = std::make_unique<DynamicFilterConfigProviderImpl>(
-      subscription, require_type_urls, factory_context, default_config, last_filter_in_filter_chain,
-      filter_chain_type);
-
-  // Ensure the subscription starts if it has not already.
-  if (config_source.apply_default_config_without_warming()) {
-    factory_context.initManager().add(provider->initTarget());
-  }
-  applyLastOrDefaultConfig(subscription, *provider, filter_config_name);
-  return provider;
+std::tuple<ProtobufTypes::MessagePtr, std::string> HttpFilterConfigProviderManagerImpl::getMessage(
+    const envoy::config::core::v3::TypedExtensionConfig& filter_config,
+    Server::Configuration::ServerFactoryContext& factory_context) const {
+  auto& factory =
+      Config::Utility::getAndCheckFactory<Server::Configuration::NamedHttpFilterConfigFactory>(
+          filter_config);
+  ProtobufTypes::MessagePtr message = Config::Utility::translateAnyToFactoryConfig(
+      filter_config.typed_config(),
+      factory_context.messageValidationContext().dynamicValidationVisitor(), factory);
+  return {std::move(message), factory.name()};
 }
 
-Http::FilterFactoryCb HttpFilterConfigProviderManagerImpl::getDefaultConfig(
+ProtobufTypes::MessagePtr HttpFilterConfigProviderManagerImpl::getDefaultConfig(
     const ProtobufWkt::Any& proto_config, const std::string& filter_config_name,
-    Server::Configuration::FactoryContext& factory_context, const std::string& stat_prefix,
-    bool last_filter_in_filter_chain, const std::string& filter_chain_type,
-    const absl::flat_hash_set<std::string> require_type_urls) const {
+    Server::Configuration::FactoryContext& factory_context, bool last_filter_in_filter_chain,
+    const std::string& filter_chain_type,
+    const absl::flat_hash_set<std::string>& require_type_urls) const {
   auto* default_factory =
       Config::Utility::getFactoryByType<Server::Configuration::NamedHttpFilterConfigFactory>(
           proto_config);
@@ -304,7 +263,7 @@ Http::FilterFactoryCb HttpFilterConfigProviderManagerImpl::getDefaultConfig(
       filter_config_name, default_factory->name(), filter_chain_type,
       default_factory->isTerminalFilterByProto(*message, factory_context),
       last_filter_in_filter_chain);
-  return default_factory->createFilterFactoryFromProto(*message, stat_prefix, factory_context);
+  return message;
 }
 
 } // namespace Filter
diff --git a/source/common/filter/config_discovery_impl.h b/source/common/filter/config_discovery_impl.h
index 7646f42176..c07ab14a94 100644
--- a/source/common/filter/config_discovery_impl.h
+++ b/source/common/filter/config_discovery_impl.h
@@ -14,6 +14,7 @@
 
 #include "source/common/common/assert.h"
 #include "source/common/config/subscription_base.h"
+#include "source/common/config/utility.h"
 #include "source/common/init/manager_impl.h"
 #include "source/common/init/target_impl.h"
 
@@ -31,8 +32,7 @@ using FilterConfigSubscriptionSharedPtr = std::shared_ptr<FilterConfigSubscripti
 /**
  * Base class for a filter config provider using discovery subscriptions.
  **/
-class DynamicFilterConfigProviderImplBase
-    : public Config::DynamicExtensionConfigProviderBase<Envoy::Http::FilterFactoryCb> {
+class DynamicFilterConfigProviderImplBase : public Config::DynamicExtensionConfigProviderBase {
 public:
   DynamicFilterConfigProviderImplBase(FilterConfigSubscriptionSharedPtr& subscription,
                                       const absl::flat_hash_set<std::string>& require_type_urls,
@@ -43,8 +43,8 @@ public:
   const Init::Target& initTarget() const { return init_target_; }
 
   void validateTypeUrl(const std::string& type_url) const;
-  void validateTerminalFilter(const std::string& name, const std::string& filter_type,
-                              bool is_terminal_filter);
+  virtual void validateMessage(const std::string& config_name, const Protobuf::Message& message,
+                               const std::string& factory_name) const PURE;
 
   const std::string& name();
 
@@ -56,6 +56,7 @@ private:
   // case no warming is requested by any other filter config provider.
   Init::TargetImpl init_target_;
 
+protected:
   const bool last_filter_in_filter_chain_;
   const std::string filter_chain_type_;
 };
@@ -63,55 +64,60 @@ private:
 /**
  * Implementation of a filter config provider using discovery subscriptions.
  **/
+template <class Factory, class FactoryCb>
 class DynamicFilterConfigProviderImpl : public DynamicFilterConfigProviderImplBase,
-                                        public DynamicFilterConfigProvider {
+                                        public DynamicFilterConfigProvider<FactoryCb> {
 public:
   DynamicFilterConfigProviderImpl(FilterConfigSubscriptionSharedPtr& subscription,
                                   const absl::flat_hash_set<std::string>& require_type_urls,
                                   Server::Configuration::FactoryContext& factory_context,
-                                  Envoy::Http::FilterFactoryCb default_config,
+                                  ProtobufTypes::MessagePtr&& default_config,
                                   bool last_filter_in_filter_chain,
-                                  const std::string& filter_chain_type)
+                                  const std::string& filter_chain_type,
+                                  const std::string& stat_prefix)
       : DynamicFilterConfigProviderImplBase(subscription, require_type_urls,
                                             last_filter_in_filter_chain, filter_chain_type),
-        default_configuration_(default_config ? absl::make_optional(default_config)
-                                              : absl::nullopt),
-        tls_(factory_context.threadLocal()) {
+        stat_prefix_(stat_prefix), factory_context_(factory_context),
+        main_config_(std::make_shared<MainConfig>()),
+        default_configuration_(std::move(default_config)), tls_(factory_context.threadLocal()) {
     tls_.set([](Event::Dispatcher&) { return std::make_shared<ThreadLocalConfig>(); });
   };
 
+  ~DynamicFilterConfigProviderImpl() override {
+    // Issuing an empty update to guarantee that the shared current config is
+    // deleted on the main thread last. This is required if the current config
+    // holds its own TLS.
+    if (!tls_.isShutdown()) {
+      update(absl::nullopt, nullptr);
+    }
+  }
+
+  // DynamicFilterConfigProviderImplBase
+  void validateMessage(const std::string& config_name, const Protobuf::Message& message,
+                       const std::string& factory_name) const override {
+    auto* factory = Registry::FactoryRegistry<Factory>::getFactory(factory_name);
+    bool is_terminal_filter = factory->isTerminalFilterByProto(message, factory_context_);
+    Config::Utility::validateTerminalFilters(config_name, factory_name, filter_chain_type_,
+                                             is_terminal_filter, last_filter_in_filter_chain_);
+  }
+
   // Config::ExtensionConfigProvider
   const std::string& name() override { return DynamicFilterConfigProviderImplBase::name(); }
-  absl::optional<Envoy::Http::FilterFactoryCb> config() override { return tls_->config_; }
-
-  // Config::DynamicExtensionConfigProvider
-  void onConfigUpdate(Envoy::Http::FilterFactoryCb config, const std::string&,
-                      Config::ConfigAppliedCb cb) override {
-    tls_.runOnAllThreads(
-        [config, cb](OptRef<ThreadLocalConfig> tls) {
-          tls->config_ = config;
-          if (cb) {
-            cb();
-          }
-        },
-        [this, config]() {
-          // This happens after all workers have discarded the previous config so it can be safely
-          // deleted on the main thread by an update with the new config.
-          this->current_config_ = config;
-        });
+  absl::optional<FactoryCb> config() override { return tls_->config_; }
+
+  // Config::DynamicExtensionConfigProviderBase
+  void onConfigUpdate(const Protobuf::Message& message, const std::string&,
+                      Config::ConfigAppliedCb applied_on_all_threads) override {
+    const FactoryCb config = instantiateFilterFactory(message);
+    update(config, applied_on_all_threads);
   }
 
   void onConfigRemoved(Config::ConfigAppliedCb applied_on_all_threads) override {
-    tls_.runOnAllThreads(
-        [config = default_configuration_](OptRef<ThreadLocalConfig> tls) { tls->config_ = config; },
-        [this, applied_on_all_threads]() {
-          // This happens after all workers have discarded the previous config so it can be safely
-          // deleted on the main thread by an update with the new config.
-          this->current_config_ = default_configuration_;
-          if (applied_on_all_threads) {
-            applied_on_all_threads();
-          }
-        });
+    const absl::optional<FactoryCb> default_config =
+        default_configuration_
+            ? absl::make_optional(instantiateFilterFactory(*default_configuration_))
+            : absl::nullopt;
+    update(default_config, applied_on_all_threads);
   }
 
   void applyDefaultConfiguration() override {
@@ -121,15 +127,41 @@ public:
   }
 
 private:
+  FactoryCb instantiateFilterFactory(const Protobuf::Message& message) const {
+    auto* factory = Registry::FactoryRegistry<Factory>::getFactoryByType(message.GetTypeName());
+    return factory->createFilterFactoryFromProto(message, stat_prefix_, factory_context_);
+  }
+
+  void update(absl::optional<FactoryCb> config, Config::ConfigAppliedCb applied_on_all_threads) {
+    // This call must not capture 'this' as it is invoked on all workers asynchronously.
+    tls_.runOnAllThreads([config](OptRef<ThreadLocalConfig> tls) { tls->config_ = config; },
+                         [main_config = main_config_, config, applied_on_all_threads]() {
+                           // This happens after all workers have discarded the previous config so
+                           // it can be safely deleted on the main thread by an update with the new
+                           // config.
+                           main_config->current_config_ = config;
+                           if (applied_on_all_threads) {
+                             applied_on_all_threads();
+                           }
+                         });
+  }
+
   struct ThreadLocalConfig : public ThreadLocal::ThreadLocalObject {
     ThreadLocalConfig() : config_{absl::nullopt} {}
-    absl::optional<Envoy::Http::FilterFactoryCb> config_{};
+    absl::optional<FactoryCb> config_{};
   };
 
   // Currently applied configuration to ensure that the main thread deletes the last reference to
-  // it.
-  absl::optional<Envoy::Http::FilterFactoryCb> current_config_{absl::nullopt};
-  const absl::optional<Envoy::Http::FilterFactoryCb> default_configuration_;
+  // it. Filter factories may hold their own thread local storage which is required to be deleted
+  // on the main thread.
+  struct MainConfig {
+    absl::optional<FactoryCb> current_config_{absl::nullopt};
+  };
+
+  const std::string stat_prefix_;
+  Server::Configuration::FactoryContext& factory_context_;
+  std::shared_ptr<MainConfig> main_config_;
+  const ProtobufTypes::MessagePtr default_configuration_;
   ThreadLocal::TypedSlot<ThreadLocalConfig> tls_;
 };
 
@@ -159,7 +191,7 @@ class FilterConfigSubscription
 public:
   FilterConfigSubscription(const envoy::config::core::v3::ConfigSource& config_source,
                            const std::string& filter_config_name,
-                           Server::Configuration::FactoryContext& factory_context,
+                           Server::Configuration::ServerFactoryContext& factory_context,
                            const std::string& stat_prefix,
                            FilterConfigProviderManagerImplBase& filter_config_provider_manager,
                            const std::string& subscription_id);
@@ -168,11 +200,10 @@ public:
 
   const Init::SharedTargetImpl& initTarget() { return init_target_; }
   const std::string& name() { return filter_config_name_; }
-  const absl::optional<Envoy::Http::FilterFactoryCb>& lastConfig() { return last_config_; }
+  const Protobuf::Message* lastConfig() { return last_config_.get(); }
   const std::string& lastTypeUrl() { return last_type_url_; }
   const std::string& lastVersionInfo() { return last_version_info_; }
-  const std::string& lastFilterName() { return last_filter_name_; }
-  bool isLastFilterTerminal() { return last_filter_is_terminal_; }
+  const std::string& lastFactoryName() { return last_factory_name_; }
   void incrementConflictCounter();
 
 private:
@@ -189,13 +220,11 @@ private:
 
   const std::string filter_config_name_;
   uint64_t last_config_hash_{0ul};
-  absl::optional<Envoy::Http::FilterFactoryCb> last_config_{absl::nullopt};
+  ProtobufTypes::MessagePtr last_config_;
   std::string last_type_url_;
   std::string last_version_info_;
-  std::string last_filter_name_;
-  bool last_filter_is_terminal_;
-  Server::Configuration::FactoryContext& factory_context_;
-  ProtobufMessage::ValidationVisitor& validator_;
+  std::string last_factory_name_;
+  Server::Configuration::ServerFactoryContext& factory_context_;
 
   Init::SharedTargetImpl init_target_;
   bool started_{false};
@@ -218,18 +247,18 @@ private:
 /**
  * Provider implementation of a static filter config.
  **/
-class StaticFilterConfigProviderImpl : public FilterConfigProvider {
+template <class FactoryCb>
+class StaticFilterConfigProviderImpl : public FilterConfigProvider<FactoryCb> {
 public:
-  StaticFilterConfigProviderImpl(const Envoy::Http::FilterFactoryCb& config,
-                                 const std::string filter_config_name)
+  StaticFilterConfigProviderImpl(const FactoryCb& config, const std::string filter_config_name)
       : config_(config), filter_config_name_(filter_config_name) {}
 
   // Config::ExtensionConfigProvider
   const std::string& name() override { return filter_config_name_; }
-  absl::optional<Envoy::Http::FilterFactoryCb> config() override { return config_; }
+  absl::optional<FactoryCb> config() override { return config_; }
 
 private:
-  Envoy::Http::FilterFactoryCb config_;
+  FactoryCb config_;
   const std::string filter_config_name_;
 };
 
@@ -237,6 +266,13 @@ private:
  * Base class for a FilterConfigProviderManager.
  */
 class FilterConfigProviderManagerImplBase : Logger::Loggable<Logger::Id::filter> {
+public:
+  virtual ~FilterConfigProviderManagerImplBase() = default;
+
+  virtual std::tuple<ProtobufTypes::MessagePtr, std::string>
+  getMessage(const envoy::config::core::v3::TypedExtensionConfig& filter_config,
+             Server::Configuration::ServerFactoryContext& factory_context) const PURE;
+
 protected:
   std::shared_ptr<FilterConfigSubscription>
   getSubscription(const envoy::config::core::v3::ConfigSource& config_source,
@@ -254,39 +290,77 @@ private:
 /**
  * An implementation of FilterConfigProviderManager.
  */
+template <class Factory, class FactoryCb>
 class FilterConfigProviderManagerImpl : public FilterConfigProviderManagerImplBase,
-                                        public FilterConfigProviderManager,
+                                        public FilterConfigProviderManager<FactoryCb>,
                                         public Singleton::Instance {
 public:
-  DynamicFilterConfigProviderPtr createDynamicFilterConfigProvider(
+  DynamicFilterConfigProviderPtr<FactoryCb> createDynamicFilterConfigProvider(
       const envoy::config::core::v3::ExtensionConfigSource& config_source,
       const std::string& filter_config_name, Server::Configuration::FactoryContext& factory_context,
       const std::string& stat_prefix, bool last_filter_in_filter_chain,
-      const std::string& filter_chain_type) override;
+      const std::string& filter_chain_type) override {
+    auto subscription = getSubscription(config_source.config_source(), filter_config_name,
+                                        factory_context, stat_prefix);
+    // For warming, wait until the subscription receives the first response to indicate readiness.
+    // Otherwise, mark ready immediately and start the subscription on initialization. A default
+    // config is expected in the latter case.
+    if (!config_source.apply_default_config_without_warming()) {
+      factory_context.initManager().add(subscription->initTarget());
+    }
+    absl::flat_hash_set<std::string> require_type_urls;
+    for (const auto& type_url : config_source.type_urls()) {
+      auto factory_type_url = TypeUtil::typeUrlToDescriptorFullName(type_url);
+      require_type_urls.emplace(factory_type_url);
+    }
+
+    ProtobufTypes::MessagePtr default_config;
+    if (config_source.has_default_config()) {
+      default_config =
+          getDefaultConfig(config_source.default_config(), filter_config_name, factory_context,
+                           last_filter_in_filter_chain, filter_chain_type, require_type_urls);
+    }
+
+    auto provider = std::make_unique<DynamicFilterConfigProviderImpl<Factory, FactoryCb>>(
+        subscription, require_type_urls, factory_context, std::move(default_config),
+        last_filter_in_filter_chain, filter_chain_type, stat_prefix);
 
-  FilterConfigProviderPtr
-  createStaticFilterConfigProvider(const Envoy::Http::FilterFactoryCb& config,
+    // Ensure the subscription starts if it has not already.
+    if (config_source.apply_default_config_without_warming()) {
+      factory_context.initManager().add(provider->initTarget());
+    }
+    applyLastOrDefaultConfig(subscription, *provider, filter_config_name);
+    return provider;
+  }
+
+  FilterConfigProviderPtr<FactoryCb>
+  createStaticFilterConfigProvider(const FactoryCb& config,
                                    const std::string& filter_config_name) override {
-    return std::make_unique<StaticFilterConfigProviderImpl>(config, filter_config_name);
+    return std::make_unique<StaticFilterConfigProviderImpl<FactoryCb>>(config, filter_config_name);
   }
 
 protected:
-  virtual Http::FilterFactoryCb
+  virtual ProtobufTypes::MessagePtr
   getDefaultConfig(const ProtobufWkt::Any& proto_config, const std::string& filter_config_name,
                    Server::Configuration::FactoryContext& factory_context,
-                   const std::string& stat_prefix, bool last_filter_in_filter_chain,
-                   const std::string& filter_chain_type,
-                   const absl::flat_hash_set<std::string> require_type_urls) const PURE;
+                   bool last_filter_in_filter_chain, const std::string& filter_chain_type,
+                   const absl::flat_hash_set<std::string>& require_type_urls) const PURE;
 };
 
-class HttpFilterConfigProviderManagerImpl : public FilterConfigProviderManagerImpl {
+class HttpFilterConfigProviderManagerImpl
+    : public FilterConfigProviderManagerImpl<Server::Configuration::NamedHttpFilterConfigFactory,
+                                             Http::FilterFactoryCb> {
+public:
+  std::tuple<ProtobufTypes::MessagePtr, std::string>
+  getMessage(const envoy::config::core::v3::TypedExtensionConfig& filter_config,
+             Server::Configuration::ServerFactoryContext& factory_context) const override;
+
 protected:
-  Http::FilterFactoryCb
+  ProtobufTypes::MessagePtr
   getDefaultConfig(const ProtobufWkt::Any& proto_config, const std::string& filter_config_name,
                    Server::Configuration::FactoryContext& factory_context,
-                   const std::string& stat_prefix, bool last_filter_in_filter_chain,
-                   const std::string& filter_chain_type,
-                   const absl::flat_hash_set<std::string> require_type_urls) const override;
+                   bool last_filter_in_filter_chain, const std::string& filter_chain_type,
+                   const absl::flat_hash_set<std::string>& require_type_urls) const override;
 };
 
 } // namespace Filter
diff --git a/source/common/formatter/BUILD b/source/common/formatter/BUILD
index 202ad9d030..ade7608fa2 100644
--- a/source/common/formatter/BUILD
+++ b/source/common/formatter/BUILD
@@ -12,6 +12,9 @@ envoy_cc_library(
     name = "substitution_formatter_lib",
     srcs = ["substitution_formatter.cc"],
     hdrs = ["substitution_formatter.h"],
+    alimesh_deps = [
+        "//contrib/common/localtime_formatter/source:substitution_formatter_lib",
+    ],
     external_deps = ["abseil_str_format"],
     deps = [
         "//envoy/api:api_interface",
diff --git a/source/common/formatter/substitution_formatter.cc b/source/common/formatter/substitution_formatter.cc
index cc11f6cf0d..47457caa6a 100644
--- a/source/common/formatter/substitution_formatter.cc
+++ b/source/common/formatter/substitution_formatter.cc
@@ -27,6 +27,10 @@
 #include "absl/strings/str_split.h"
 #include "fmt/format.h"
 
+#if defined(ALIMESH)
+#include "contrib/common/localtime_formatter/source/substitution_formatter.h"
+#endif
+
 using Envoy::Config::Metadata;
 
 namespace Envoy {
@@ -441,6 +445,11 @@ FormatterProviderPtr SubstitutionFormatParser::parseBuiltinCommand(const std::st
     return std::make_unique<HeadersByteSizeFormatter>(
         HeadersByteSizeFormatter::HeaderType::ResponseTrailers);
   }
+#if defined(ALIMESH)
+  else if (absl::StartsWith(token, "LOCAL_START_TIME")) {
+    return std::make_unique<LocalStartTimeFormatter>(token);
+  }
+#endif
 
   return nullptr;
 }
@@ -685,6 +694,7 @@ private:
 };
 
 StreamInfoFormatter::StreamInfoFormatter(const std::string& field_name) {
+  // TODO: Change this huge if-else ladder to use a switch case instead.
   if (field_name == "REQUEST_DURATION") {
     field_extractor_ = std::make_unique<StreamInfoDurationFieldExtractor>(
         [](const StreamInfo::StreamInfo& stream_info) {
@@ -912,6 +922,11 @@ StreamInfoFormatter::StreamInfoFormatter(const std::string& field_name) {
           }
           return absl::nullopt;
         });
+  } else if (field_name == "VIRTUAL_CLUSTER_NAME") {
+    field_extractor_ = std::make_unique<StreamInfoStringFieldExtractor>(
+        [](const StreamInfo::StreamInfo& stream_info) -> absl::optional<std::string> {
+          return stream_info.virtualClusterName();
+        });
   } else {
     throw EnvoyException(fmt::format("Not supported field in StreamInfo: {}", field_name));
   }
diff --git a/source/common/formatter/substitution_formatter.h b/source/common/formatter/substitution_formatter.h
index 239700da17..509f382634 100644
--- a/source/common/formatter/substitution_formatter.h
+++ b/source/common/formatter/substitution_formatter.h
@@ -113,6 +113,11 @@ private:
   static const size_t ReqParamStart{sizeof("REQ(") - 1};
   static const size_t RespParamStart{sizeof("RESP(") - 1};
   static const size_t TrailParamStart{sizeof("TRAILER(") - 1};
+  static const size_t StartTimeParamStart{sizeof("START_TIME(") - 1};
+
+#if defined(ALIMESH)
+  static const size_t LocalStartTimeParamStart{sizeof("LOCAL_START_TIME(") - 1};
+#endif
 };
 
 /**
diff --git a/source/common/grpc/async_client_impl.cc b/source/common/grpc/async_client_impl.cc
index dd63a6bac8..c58fbd7539 100644
--- a/source/common/grpc/async_client_impl.cc
+++ b/source/common/grpc/async_client_impl.cc
@@ -54,7 +54,7 @@ RawAsyncStream* AsyncClientImpl::startRaw(absl::string_view service_full_name,
   auto grpc_stream =
       std::make_unique<AsyncStreamImpl>(*this, service_full_name, method_name, callbacks, options);
 
-  grpc_stream->initialize(false);
+  grpc_stream->initialize(options.buffer_body_for_retry);
   if (grpc_stream->hasResetStream()) {
     return nullptr;
   }
diff --git a/source/common/http/async_client_impl.cc b/source/common/http/async_client_impl.cc
index 2c1da999f2..d0e225d66f 100644
--- a/source/common/http/async_client_impl.cc
+++ b/source/common/http/async_client_impl.cc
@@ -31,6 +31,11 @@ const absl::optional<envoy::config::route::v3::RouteAction::UpgradeConfig::Conne
     AsyncStreamImpl::RouteEntryImpl::connect_config_nullopt_;
 const std::list<LowerCaseString> AsyncStreamImpl::NullConfig::internal_only_headers_;
 
+#if defined(ALIMESH)
+const Router::InternalActiveRedirectPoliciesImpl
+    AsyncStreamImpl::RouteEntryImpl::internal_active_redirect_policy_;
+#endif
+
 AsyncClientImpl::AsyncClientImpl(Upstream::ClusterInfoConstSharedPtr cluster,
                                  Stats::Store& stats_store, Event::Dispatcher& dispatcher,
                                  const LocalInfo::LocalInfo& local_info,
diff --git a/source/common/http/async_client_impl.h b/source/common/http/async_client_impl.h
index 608813cc01..a7c5255f12 100644
--- a/source/common/http/async_client_impl.h
+++ b/source/common/http/async_client_impl.h
@@ -191,6 +191,9 @@ private:
 
     // Router::RouteEntry
     const std::string& clusterName() const override { return cluster_name_; }
+    const Router::RouteStatsContextOptRef routeStatsContext() const override {
+      return Router::RouteStatsContextOptRef();
+    }
     Http::Code clusterNotFoundResponseCode() const override {
       return Http::Code::InternalServerError;
     }
@@ -259,6 +262,7 @@ private:
     }
     const Router::VirtualHost& virtualHost() const override { return virtual_host_; }
     bool autoHostRewrite() const override { return false; }
+    bool appendXfh() const override { return false; }
     bool includeVirtualHostRateLimits() const override { return true; }
     const Router::PathMatchCriterion& pathMatchCriterion() const override {
       return path_match_criterion_;
@@ -268,6 +272,12 @@ private:
       return connect_config_nullopt_;
     }
 
+#if defined(ALIMESH)
+    const Router::InternalActiveRedirectPolicy& internalActiveRedirectPolicy() const override {
+      return internal_active_redirect_policy_;
+    }
+#endif
+
     bool includeAttemptCountInRequest() const override { return false; }
     bool includeAttemptCountInResponse() const override { return false; }
     const Router::RouteEntry::UpgradeMap& upgradeMap() const override { return upgrade_map_; }
@@ -283,6 +293,10 @@ private:
     static const std::multimap<std::string, std::string> opaque_config_;
     static const NullPathMatchCriterion path_match_criterion_;
 
+#if defined(ALIMESH)
+    static const Router::InternalActiveRedirectPoliciesImpl internal_active_redirect_policy_;
+#endif
+
     Router::RouteEntry::UpgradeMap upgrade_map_;
     const std::string& cluster_name_;
     absl::optional<std::chrono::milliseconds> timeout_;
diff --git a/source/common/http/codes.cc b/source/common/http/codes.cc
index 0f6b81f64f..48601c53ee 100644
--- a/source/common/http/codes.cc
+++ b/source/common/http/codes.cc
@@ -32,7 +32,7 @@ CodeStatsImpl::CodeStatsImpl(Stats::SymbolTable& symbol_table)
       upstream_rq_completed_(stat_name_pool_.add("upstream_rq_completed")),
       upstream_rq_time_(stat_name_pool_.add("upstream_rq_time")),
       vcluster_(stat_name_pool_.add("vcluster")), vhost_(stat_name_pool_.add("vhost")),
-      zone_(stat_name_pool_.add("zone")) {
+      route_(stat_name_pool_.add("route")), zone_(stat_name_pool_.add("zone")) {
 
   // Pre-allocate response codes 200, 404, and 503, as those seem quite likely.
   // We don't pre-allocate all the HTTP codes because the first 127 allocations
@@ -108,6 +108,16 @@ void CodeStatsImpl::chargeResponseStat(const ResponseStatInfo& info,
                {vhost_, info.request_vhost_name_, vcluster_, info.request_vcluster_name_, rq_code});
   }
 
+  // Handle route level stats.
+  if (!info.request_route_name_.empty()) {
+    incCounter(info.global_scope_, {vhost_, info.request_vhost_name_, route_,
+                                    info.request_route_name_, upstream_rq_completed_});
+    incCounter(info.global_scope_,
+               {vhost_, info.request_vhost_name_, route_, info.request_route_name_, rq_group});
+    incCounter(info.global_scope_,
+               {vhost_, info.request_vhost_name_, route_, info.request_route_name_, rq_code});
+  }
+
   // Handle per zone stats.
   if (!info.from_zone_.empty() && !info.to_zone_.empty()) {
     incCounter(info.cluster_scope_,
@@ -151,6 +161,13 @@ void CodeStatsImpl::chargeResponseTiming(const ResponseTimingInfo& info) const {
                     Stats::Histogram::Unit::Milliseconds, count);
   }
 
+  if (!info.request_route_name_.empty()) {
+    recordHistogram(
+        info.global_scope_,
+        {vhost_, info.request_vhost_name_, route_, info.request_route_name_, upstream_rq_time_},
+        Stats::Histogram::Unit::Milliseconds, count);
+  }
+
   // Handle per zone stats.
   if (!info.from_zone_.empty() && !info.to_zone_.empty()) {
     recordHistogram(info.cluster_scope_,
diff --git a/source/common/http/codes.h b/source/common/http/codes.h
index d3f78ee16c..bb731aa702 100644
--- a/source/common/http/codes.h
+++ b/source/common/http/codes.h
@@ -22,6 +22,7 @@ struct CodeStats::ResponseStatInfo {
   bool internal_request_;
   Stats::StatName request_vhost_name_;
   Stats::StatName request_vcluster_name_;
+  Stats::StatName request_route_name_;
   Stats::StatName from_zone_;
   Stats::StatName to_zone_;
   bool upstream_canary_;
@@ -36,6 +37,7 @@ struct CodeStats::ResponseTimingInfo {
   bool internal_request_;
   Stats::StatName request_vhost_name_;
   Stats::StatName request_vcluster_name_;
+  Stats::StatName request_route_name_;
   Stats::StatName from_zone_;
   Stats::StatName to_zone_;
 };
@@ -82,6 +84,7 @@ private:
   const Stats::StatName upstream_rq_time_;
   const Stats::StatName vcluster_;
   const Stats::StatName vhost_;
+  const Stats::StatName route_;
   const Stats::StatName zone_;
 
   // Use an array of atomic pointers to hold StatNameStorage objects for
diff --git a/source/common/http/conn_manager_impl.cc b/source/common/http/conn_manager_impl.cc
index 90f6be301b..4715a90908 100644
--- a/source/common/http/conn_manager_impl.cc
+++ b/source/common/http/conn_manager_impl.cc
@@ -178,9 +178,14 @@ ConnectionManagerImpl::~ConnectionManagerImpl() {
   user_agent_.completeConnectionLength(*conn_length_);
 }
 
-void ConnectionManagerImpl::checkForDeferredClose() {
+void ConnectionManagerImpl::checkForDeferredClose(bool skip_delay_close) {
+  Network::ConnectionCloseType close = Network::ConnectionCloseType::FlushWriteAndDelay;
+  if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.skip_delay_close") &&
+      skip_delay_close) {
+    close = Network::ConnectionCloseType::FlushWrite;
+  }
   if (drain_state_ == DrainState::Closing && streams_.empty() && !codec_->wantsToWrite()) {
-    doConnectionClose(Network::ConnectionCloseType::FlushWriteAndDelay, absl::nullopt,
+    doConnectionClose(close, absl::nullopt,
                       StreamInfo::ResponseCodeDetails::get().DownstreamLocalDisconnect);
   }
 }
@@ -197,8 +202,8 @@ void ConnectionManagerImpl::doEndStream(ActiveStream& stream) {
   // here is when Envoy "ends" the stream by calling recreateStream at which point recreateStream
   // explicitly nulls out response_encoder to avoid the downstream being notified of the
   // Envoy-internal stream instance being ended.
-  if (stream.response_encoder_ != nullptr &&
-      (!stream.filter_manager_.remoteComplete() || !stream.state_.codec_saw_local_complete_)) {
+  if (stream.response_encoder_ != nullptr && (!stream.filter_manager_.remoteDecodeComplete() ||
+                                              !stream.state_.codec_saw_local_complete_)) {
     // Indicate local is complete at this point so that if we reset during a continuation, we don't
     // raise further data or trailers.
     ENVOY_STREAM_LOG(debug, "doEndStream() resetting stream", stream);
@@ -234,7 +239,16 @@ void ConnectionManagerImpl::doEndStream(ActiveStream& stream) {
     drain_state_ = DrainState::Closing;
   }
 
-  checkForDeferredClose();
+  // If HTTP/1.0 has no content length, it is framed by close and won't consider
+  // the request complete until the FIN is read. Don't delay close in this case.
+  bool http_10_sans_cl = (codec_->protocol() == Protocol::Http10) &&
+                         (!stream.response_headers_ || !stream.response_headers_->ContentLength());
+  // We also don't delay-close in the case of HTTP/1.1 where the request is
+  // fully read, as there's no race condition to avoid.
+  bool connection_close = stream.state_.saw_connection_close_;
+  bool request_complete = stream.filter_manager_.remoteDecodeComplete();
+
+  checkForDeferredClose(connection_close && (request_complete || http_10_sans_cl));
 }
 
 void ConnectionManagerImpl::doDeferredStreamDestroy(ActiveStream& stream) {
@@ -364,7 +378,7 @@ Network::FilterStatus ConnectionManagerImpl::onData(Buffer::Instance& data, bool
     ASSERT(status.ok());
 
     // Processing incoming data may release outbound data so check for closure here as well.
-    checkForDeferredClose();
+    checkForDeferredClose(false);
 
     // The HTTP/1 codec will pause dispatch after a single message is complete. We want to
     // either redispatch if there are no streams and we have more data. If we have a single
@@ -530,7 +544,7 @@ void ConnectionManagerImpl::onDrainTimeout() {
   ASSERT(drain_state_ != DrainState::NotDraining);
   codec_->goAway();
   drain_state_ = DrainState::Closing;
-  checkForDeferredClose();
+  checkForDeferredClose(false);
 }
 
 void ConnectionManagerImpl::chargeTracingStats(const Tracing::Reason& tracing_reason,
@@ -778,6 +792,16 @@ void ConnectionManagerImpl::ActiveStream::onStreamMaxDurationReached() {
 
 void ConnectionManagerImpl::ActiveStream::chargeStats(const ResponseHeaderMap& headers) {
   uint64_t response_code = Utility::getResponseStatus(headers);
+
+#if defined(ALIMESH)
+  if (Grpc::Common::hasGrpcContentType(headers)) {
+    absl::optional<Grpc::Status::GrpcStatus> grpc_status = Grpc::Common::getGrpcStatus(headers);
+    if (grpc_status.has_value()) {
+      response_code = Grpc::Utility::grpcToHttpStatus(grpc_status.value());
+    }
+  }
+#endif
+
   filter_manager_.streamInfo().response_code_ = response_code;
 
   if (filter_manager_.streamInfo().health_check_request_) {
@@ -1416,7 +1440,7 @@ void ConnectionManagerImpl::ActiveStream::encodeHeaders(ResponseHeaderMap& heade
   // If we are destroying a stream before remote is complete and the connection does not support
   // multiplexing, we should disconnect since we don't want to wait around for the request to
   // finish.
-  if (!filter_manager_.remoteComplete()) {
+  if (!filter_manager_.remoteDecodeComplete()) {
     if (connection_manager_.codec_->protocol() < Protocol::Http2) {
       connection_manager_.drain_state_ = DrainState::Closing;
     }
diff --git a/source/common/http/conn_manager_impl.h b/source/common/http/conn_manager_impl.h
index b83e0aa264..b336352fff 100644
--- a/source/common/http/conn_manager_impl.h
+++ b/source/common/http/conn_manager_impl.h
@@ -398,7 +398,7 @@ private:
    * Check to see if the connection can be closed after gracefully waiting to send pending codec
    * data.
    */
-  void checkForDeferredClose();
+  void checkForDeferredClose(bool skip_deferred_close);
 
   /**
    * Do a delayed destruction of a stream to allow for stack unwind. Also calls onDestroy() for
diff --git a/source/common/http/filter_manager.cc b/source/common/http/filter_manager.cc
index fc15f8041f..46e9fda6f6 100644
--- a/source/common/http/filter_manager.cc
+++ b/source/common/http/filter_manager.cc
@@ -303,6 +303,12 @@ bool ActiveStreamDecoderFilter::canContinue() {
   return !parent_.state_.local_complete_;
 }
 
+bool ActiveStreamEncoderFilter::canContinue() {
+  // As with ActiveStreamDecoderFilter::canContinue() make sure we do not
+  // continue if a local reply has been sent.
+  return !parent_.state_.remote_encode_complete_;
+}
+
 Buffer::InstancePtr ActiveStreamDecoderFilter::createBuffer() {
   auto buffer = dispatcher().getWatermarkFactory().createBuffer(
       [this]() -> void { this->requestDataDrained(); },
@@ -316,7 +322,7 @@ Buffer::InstancePtr& ActiveStreamDecoderFilter::bufferedData() {
   return parent_.buffered_request_data_;
 }
 
-bool ActiveStreamDecoderFilter::complete() { return parent_.state_.remote_complete_; }
+bool ActiveStreamDecoderFilter::complete() { return parent_.state_.remote_decode_complete_; }
 
 void ActiveStreamDecoderFilter::doHeaders(bool end_stream) {
   parent_.decodeHeaders(this, *parent_.filter_manager_callbacks_.requestHeaders(), end_stream);
@@ -828,8 +834,8 @@ void FilterManager::decodeMetadata(ActiveStreamDecoderFilter* filter, MetadataMa
 }
 
 void FilterManager::maybeEndDecode(bool end_stream) {
-  ASSERT(!state_.remote_complete_);
-  state_.remote_complete_ = end_stream;
+  ASSERT(!state_.remote_decode_complete_);
+  state_.remote_decode_complete_ = end_stream;
   if (end_stream) {
     stream_info_.onLastDownstreamRxByteReceived();
     ENVOY_STREAM_LOG(debug, "request end stream", *this);
@@ -1338,6 +1344,8 @@ void FilterManager::encodeTrailers(ActiveStreamEncoderFilter* filter,
 
 void FilterManager::maybeEndEncode(bool end_stream) {
   if (end_stream) {
+    ASSERT(!state_.remote_encode_complete_);
+    state_.remote_encode_complete_ = true;
     filter_manager_callbacks_.endStream();
   }
 }
@@ -1627,6 +1635,7 @@ Http1StreamEncoderOptionsOptRef ActiveStreamEncoderFilter::http1StreamEncoderOpt
 }
 
 void ActiveStreamEncoderFilter::responseDataTooLarge() {
+  ENVOY_STREAM_LOG(debug, "response data too large watermark exceeded", parent_);
   if (parent_.state_.encoder_filters_streaming_) {
     onEncoderFilterAboveWriteBufferHighWatermark();
   } else {
diff --git a/source/common/http/filter_manager.h b/source/common/http/filter_manager.h
index 633fa6862d..9d8718a48c 100644
--- a/source/common/http/filter_manager.h
+++ b/source/common/http/filter_manager.h
@@ -315,7 +315,7 @@ struct ActiveStreamEncoderFilter : public ActiveStreamFilterBase,
       : ActiveStreamFilterBase(parent, dual_filter, std::move(match_state)), handle_(filter) {}
 
   // ActiveStreamFilterBase
-  bool canContinue() override { return true; }
+  bool canContinue() override;
   Buffer::InstancePtr createBuffer() override;
   Buffer::InstancePtr& bufferedData() override;
   bool complete() override;
@@ -907,7 +907,7 @@ public:
   /**
    * Whether remote processing has been marked as complete.
    */
-  bool remoteComplete() const { return state_.remote_complete_; }
+  bool remoteDecodeComplete() const { return state_.remote_decode_complete_; }
 
   /**
    * Instructs the FilterManager to not create a filter chain. This makes it possible to issue
@@ -1059,14 +1059,16 @@ private:
 
   struct State {
     State()
-        : remote_complete_(false), local_complete_(false), has_continue_headers_(false),
-          created_filter_chain_(false), is_head_request_(false), is_grpc_request_(false),
-          non_100_response_headers_encoded_(false), under_on_local_reply_(false),
-          decoder_filter_chain_aborted_(false), encoder_filter_chain_aborted_(false) {}
+        : remote_encode_complete_(false), remote_decode_complete_(false), local_complete_(false),
+          has_continue_headers_(false), created_filter_chain_(false), is_head_request_(false),
+          is_grpc_request_(false), non_100_response_headers_encoded_(false),
+          under_on_local_reply_(false), decoder_filter_chain_aborted_(false),
+          encoder_filter_chain_aborted_(false) {}
 
     uint32_t filter_call_state_{0};
 
-    bool remote_complete_ : 1;
+    bool remote_encode_complete_ : 1;
+    bool remote_decode_complete_ : 1;
     bool local_complete_ : 1; // This indicates that local is complete prior to filter processing.
                               // A filter can still stop the stream from being complete as seen
                               // by the codec.
diff --git a/source/common/http/headers.h b/source/common/http/headers.h
index ccae31bf70..5420eb4475 100644
--- a/source/common/http/headers.h
+++ b/source/common/http/headers.h
@@ -52,6 +52,7 @@ class CustomHeaderValues {
 public:
   const LowerCaseString Accept{"accept"};
   const LowerCaseString AcceptEncoding{"accept-encoding"};
+  const LowerCaseString AccessControlRequestHeaders{"access-control-request-headers"};
   const LowerCaseString AccessControlRequestMethod{"access-control-request-method"};
   const LowerCaseString AccessControlAllowOrigin{"access-control-allow-origin"};
   const LowerCaseString AccessControlAllowHeaders{"access-control-allow-headers"};
@@ -115,6 +116,16 @@ public:
     const std::string AcceptEncoding{"Accept-Encoding"};
     const std::string Wildcard{"*"};
   } VaryValues;
+
+#if defined(ALIMESH)
+  struct {
+    const LowerCaseString TriArriveTime{"req-arrive-time"};
+    const LowerCaseString TriCostTime{"req-cost-time"};
+    const LowerCaseString TriStartTime{"req-start-time"};
+    const LowerCaseString TriRespStartTime{"resp-start-time"};
+    const LowerCaseString EnvoyOriginalHost{"original-host"};
+  } AliExtendedValues;
+#endif
 };
 
 using CustomHeaders = ConstSingleton<CustomHeaderValues>;
diff --git a/source/common/http/utility.cc b/source/common/http/utility.cc
index ac822a9515..b60199da72 100644
--- a/source/common/http/utility.cc
+++ b/source/common/http/utility.cc
@@ -387,6 +387,14 @@ void Utility::appendVia(RequestOrResponseHeaderMap& headers, const std::string&
   headers.appendVia(via, ", ");
 }
 
+void Utility::updateAuthority(RequestHeaderMap& headers, absl::string_view hostname,
+                              const bool append_xfh) {
+  if (append_xfh && !headers.getHostValue().empty()) {
+    headers.appendForwardedHost(headers.getHostValue(), ",");
+  }
+  headers.setHost(hostname);
+}
+
 std::string Utility::createSslRedirectPath(const RequestHeaderMap& headers) {
   ASSERT(headers.Host());
   ASSERT(headers.Path());
diff --git a/source/common/http/utility.h b/source/common/http/utility.h
index 5038ebce1e..dff9a474d8 100644
--- a/source/common/http/utility.h
+++ b/source/common/http/utility.h
@@ -194,6 +194,14 @@ void appendXff(RequestHeaderMap& headers, const Network::Address::Instance& remo
  */
 void appendVia(RequestOrResponseHeaderMap& headers, const std::string& via);
 
+/**
+ * Update authority with the specified hostname.
+ * @param headers headers where authority should be updated.
+ * @param hostname hostname that authority should be updated with.
+ * @param append_xfh append the original authority to the x-forwarded-host header.
+ */
+void updateAuthority(RequestHeaderMap& headers, absl::string_view hostname, bool append_xfh);
+
 /**
  * Creates an SSL (https) redirect path based on the input host and path headers.
  * @param headers supplies the request headers.
diff --git a/source/common/network/socket_impl.cc b/source/common/network/socket_impl.cc
index c19ac2542f..72509632bf 100644
--- a/source/common/network/socket_impl.cc
+++ b/source/common/network/socket_impl.cc
@@ -71,7 +71,16 @@ Api::SysCallIntResult SocketImpl::bind(Network::Address::InstanceConstSharedPtr
 
   bind_result = io_handle_->bind(address);
   if (bind_result.return_value_ == 0 && address->ip()->port() == 0) {
+#if defined(ALIMESH)
+    try {
+      connection_info_provider_->setLocalAddress(io_handle_->localAddress());
+    } catch (const EnvoyException& ex) {
+      bind_result.return_value_ = -1;
+      ENVOY_LOG_MISC(critical, "envoy exception raised in SocketImpl::bind(): {}", ex.what());
+    }
+#else
     connection_info_provider_->setLocalAddress(io_handle_->localAddress());
+#endif
   }
   return bind_result;
 }
diff --git a/source/common/router/BUILD b/source/common/router/BUILD
index 4e0bbe9145..3690d8689a 100644
--- a/source/common/router/BUILD
+++ b/source/common/router/BUILD
@@ -31,6 +31,9 @@ envoy_cc_library(
     name = "config_lib",
     srcs = ["config_impl.cc"],
     hdrs = ["config_impl.h"],
+    alimesh_deps = [
+        "//contrib/common/active_redirect/source:active_redirect_policy_lib",
+    ],
     external_deps = ["abseil_optional"],
     deps = [
         ":config_utility_lib",
@@ -43,6 +46,7 @@ envoy_cc_library(
         ":tls_context_match_criteria_lib",
         "//envoy/config:typed_metadata_interface",
         "//envoy/http:header_map_interface",
+        "//envoy/router:cluster_specifier_plugin_interface",
         "//envoy/router:router_interface",
         "//envoy/runtime:runtime_interface",
         "//envoy/server:filter_config_interface",  # TODO(rodaine): break dependency on server
@@ -99,6 +103,7 @@ envoy_cc_library(
         "//envoy/router:context_interface",
         "//envoy/router:router_interface",
         "//envoy/stats:stats_macros",
+        "//source/common/config:utility_lib",
     ],
 )
 
@@ -275,6 +280,9 @@ envoy_cc_library(
         "router.h",
         "upstream_request.h",
     ],
+    alimesh_deps = [
+        "//envoy/stats:timespan_interface",
+    ],
     deps = [
         ":config_lib",
         ":context_lib",
diff --git a/source/common/router/config_impl.cc b/source/common/router/config_impl.cc
index d756c60796..5bdc137011 100644
--- a/source/common/router/config_impl.cc
+++ b/source/common/router/config_impl.cc
@@ -70,6 +70,36 @@ const envoy::config::route::v3::WeightedCluster::ClusterWeight& validateWeighted
   return cluster;
 }
 
+// If the implementation of a cluster specifier plugin is not provided in current Envoy and the
+// plugin is set to optional, then this null plugin will be used as a placeholder.
+class NullClusterSpecifierPlugin : public ClusterSpecifierPlugin {
+public:
+  RouteConstSharedPtr route(const RouteEntry&, const Http::RequestHeaderMap&) const override {
+    return nullptr;
+  }
+};
+
+ClusterSpecifierPluginSharedPtr
+getClusterSpecifierPluginByTheProto(const envoy::config::route::v3::ClusterSpecifierPlugin& plugin,
+                                    ProtobufMessage::ValidationVisitor& validator,
+                                    Server::Configuration::ServerFactoryContext& factory_context) {
+  auto* factory =
+      Envoy::Config::Utility::getFactory<ClusterSpecifierPluginFactoryConfig>(plugin.extension());
+  if (factory == nullptr) {
+    if (plugin.is_optional()) {
+      return std::make_shared<NullClusterSpecifierPlugin>();
+    }
+    throw EnvoyException(
+        fmt::format("Didn't find a registered implementation for '{}' with type URL: '{}'",
+                    plugin.extension().name(),
+                    Envoy::Config::Utility::getFactoryType(plugin.extension().typed_config())));
+  }
+  ASSERT(factory != nullptr);
+  auto config =
+      Envoy::Config::Utility::translateToFactoryConfig(plugin.extension(), validator, *factory);
+  return factory->createClusterSpecifierPlugin(*config, factory_context);
+}
+
 } // namespace
 
 const std::string& OriginalConnectPort::key() {
@@ -336,7 +366,8 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost,
           route.route().has_host_rewrite_path_regex()
               ? route.route().host_rewrite_path_regex().substitution()
               : ""),
-      cluster_name_(route.route().cluster()), cluster_header_name_(route.route().cluster_header()),
+      append_xfh_(route.route().append_x_forwarded_host()), cluster_name_(route.route().cluster()),
+      cluster_header_name_(route.route().cluster_header()),
       cluster_not_found_response_code_(ConfigUtility::parseClusterNotFoundResponseCode(
           route.route().cluster_not_found_response_code())),
       timeout_(PROTOBUF_GET_MS_OR_DEFAULT(route.route(), timeout, DEFAULT_ROUTE_TIMEOUT_MS)),
@@ -389,7 +420,13 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost,
           vhost_.globalRouteConfig().maxDirectResponseBodySizeBytes())),
       per_filter_configs_(route.typed_per_filter_config(), optional_http_filters, factory_context,
                           validator),
+#if !defined(ALIMESH)
       route_name_(route.name()), time_source_(factory_context.mainThreadDispatcher().timeSource()) {
+#else
+      route_name_(route.name()), time_source_(factory_context.mainThreadDispatcher().timeSource()),
+      internal_active_redirect_policy_(
+          buildActiveInternalRedirectPolicy(route.route(), validator, route.name())) {
+#endif
   if (route.route().has_metadata_match()) {
     const auto filter_it = route.route().metadata_match().filter_metadata().find(
         Envoy::Config::MetadataFilters::get().ENVOY_LB);
@@ -427,6 +464,26 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost,
       throw EnvoyException(fmt::format("Sum of weights in the weighted_cluster should add up to {}",
                                        total_cluster_weight_));
     }
+
+#if defined(ALIMESH)
+    if (route.route().weighted_clusters().has_inline_cluster_specifier_plugin()) {
+      cluster_specifier_plugin_ = getClusterSpecifierPluginByTheProto(
+          route.route().weighted_clusters().inline_cluster_specifier_plugin(), validator,
+          factory_context);
+    } else if (!route.route().weighted_clusters().cluster_specifier_plugin().empty()) {
+      cluster_specifier_plugin_ = vhost_.globalRouteConfig().clusterSpecifierPlugin(
+          route.route().weighted_clusters().cluster_specifier_plugin());
+    }
+#endif
+
+  } else if (route.route().cluster_specifier_case() ==
+             envoy::config::route::v3::RouteAction::ClusterSpecifierCase::
+                 kInlineClusterSpecifierPlugin) {
+    cluster_specifier_plugin_ = getClusterSpecifierPluginByTheProto(
+        route.route().inline_cluster_specifier_plugin(), validator, factory_context);
+  } else if (route.route().has_cluster_specifier_plugin()) {
+    cluster_specifier_plugin_ =
+        vhost_.globalRouteConfig().clusterSpecifierPlugin(route.route().cluster_specifier_plugin());
   }
 
   for (const auto& query_parameter : route.match().query_parameters()) {
@@ -493,6 +550,20 @@ RouteEntryImplBase::RouteEntryImplBase(const VirtualHostImpl& vhost,
               "not be stripped: {}",
               path_redirect_);
   }
+  ENVOY_LOG(info, "route stats is {}, name is {}", route.stat_prefix(), route.name());
+  if (!route.stat_prefix().empty()) {
+    route_stats_context_ = std::make_unique<RouteStatsContext>(
+        factory_context.scope(), factory_context.routerContext().routeStatNames(), vhost.statName(),
+        route.stat_prefix());
+  } else if (!route.name().empty()) {
+    // Added by Ingress
+    // use route_name as default stat_prefix
+    route_stats_context_ = std::make_unique<RouteStatsContext>(
+        factory_context.scope(), factory_context.routerContext().routeStatNames(), vhost.statName(),
+        route.name());
+  }
+  // End Added
+
 }
 
 bool RouteEntryImplBase::evaluateRuntimeMatch(const uint64_t random_value) const {
@@ -590,6 +661,11 @@ void RouteEntryImplBase::finalizeRequestHeaders(Http::RequestHeaderMap& headers,
     request_headers_parser_->evaluateHeaders(headers, stream_info);
   }
 
+#if defined(ALIMESH)
+  headers.setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost,
+                          headers.getHostValue());
+#endif
+
   // Restore the port if this was a CONNECT request.
   // Note this will restore the port for HTTP/2 CONNECT-upgrades as well as as HTTP/1.1 style
   // CONNECT requests.
@@ -601,7 +677,7 @@ void RouteEntryImplBase::finalizeRequestHeaders(Http::RequestHeaderMap& headers,
   }
 
   if (!host_rewrite_.empty()) {
-    headers.setHost(host_rewrite_);
+    Http::Utility::updateAuthority(headers, host_rewrite_, append_xfh_);
   } else if (auto_host_rewrite_header_) {
     const auto header = headers.get(*auto_host_rewrite_header_);
     if (!header.empty()) {
@@ -609,14 +685,16 @@ void RouteEntryImplBase::finalizeRequestHeaders(Http::RequestHeaderMap& headers,
       // value is used.
       const absl::string_view header_value = header[0]->value().getStringView();
       if (!header_value.empty()) {
-        headers.setHost(header_value);
+        Http::Utility::updateAuthority(headers, header_value, append_xfh_);
       }
     }
   } else if (host_rewrite_path_regex_ != nullptr) {
     const std::string path(headers.getPathValue());
     absl::string_view just_path(Http::PathUtil::removeQueryAndFragment(path));
-    headers.setHost(
-        host_rewrite_path_regex_->replaceAll(just_path, host_rewrite_path_regex_substitution_));
+    Http::Utility::updateAuthority(
+        headers,
+        host_rewrite_path_regex_->replaceAll(just_path, host_rewrite_path_regex_substitution_),
+        append_xfh_);
   }
 
   // Handle path rewrite
@@ -946,6 +1024,30 @@ InternalRedirectPolicyImpl RouteEntryImplBase::buildInternalRedirectPolicy(
   return InternalRedirectPolicyImpl(policy_config, validator, current_route_name);
 }
 
+#if defined(ALIMESH)
+InternalActiveRedirectPoliciesImpl RouteEntryImplBase::buildActiveInternalRedirectPolicy(
+    const envoy::config::route::v3::RouteAction& route_config,
+    ProtobufMessage::ValidationVisitor& validator, absl::string_view current_route_name) const {
+  if (route_config.has_internal_active_redirect_policy()) {
+    return InternalActiveRedirectPoliciesImpl(route_config.internal_active_redirect_policy(),
+                                              validator, current_route_name);
+  }
+  envoy::config::route::v3::InternalActiveRedirectPolicy policy_config;
+  switch (route_config.internal_redirect_action()) {
+  case envoy::config::route::v3::RouteAction::HANDLE_INTERNAL_REDIRECT:
+    break;
+  case envoy::config::route::v3::RouteAction::PASS_THROUGH_INTERNAL_REDIRECT:
+    FALLTHRU;
+  default:
+    return InternalActiveRedirectPoliciesImpl();
+  }
+  if (route_config.has_max_internal_redirects()) {
+    *policy_config.mutable_max_internal_redirects() = route_config.max_internal_redirects();
+  }
+  return InternalActiveRedirectPoliciesImpl(policy_config, validator, current_route_name);
+}
+#endif
+
 DecoratorConstPtr RouteEntryImplBase::parseDecorator(const envoy::config::route::v3::Route& route) {
   DecoratorConstPtr ret;
   if (route.has_decorator()) {
@@ -1000,16 +1102,20 @@ RouteEntryImplBase::pickClusterViaClusterHeader(const Http::LowerCaseString& clu
   return std::make_shared<DynamicRouteEntry>(this, final_cluster_name);
 }
 
-RouteConstSharedPtr RouteEntryImplBase::clusterEntry(const Http::HeaderMap& headers,
+RouteConstSharedPtr RouteEntryImplBase::clusterEntry(const Http::RequestHeaderMap& headers,
                                                      uint64_t random_value) const {
   // Gets the route object chosen from the list of weighted clusters
   // (if there is one) or returns self.
   if (weighted_clusters_.empty()) {
     if (!cluster_name_.empty() || isDirectResponse()) {
       return shared_from_this();
-    } else {
-      ASSERT(!cluster_header_name_.get().empty());
+    } else if (!cluster_header_name_.get().empty()) {
       return pickClusterViaClusterHeader(cluster_header_name_, headers);
+    } else {
+      // TODO(wbpcode): make the cluster header or weighted clusters an implementation of the
+      // cluster specifier plugin.
+      ASSERT(cluster_specifier_plugin_ != nullptr);
+      return cluster_specifier_plugin_->route(*this, headers);
     }
   }
   return pickWeightedCluster(headers, random_value, true);
@@ -1035,6 +1141,18 @@ RouteConstSharedPtr RouteEntryImplBase::pickWeightedCluster(const Http::HeaderMa
     }
 
     if (selected_value >= begin && selected_value < end) {
+#if defined(ALIMESH)
+      if (cluster_specifier_plugin_ != nullptr) {
+        auto request_header = dynamic_cast<const Http::RequestHeaderMap*>(&headers);
+        if (!cluster->clusterHeaderName().get().empty() &&
+            !headers.get(cluster->clusterHeaderName()).empty()) {
+          auto route = pickClusterViaClusterHeader(cluster->clusterHeaderName(), headers);
+          auto route_entry = dynamic_cast<const DynamicRouteEntry*>(route.get());
+          return cluster_specifier_plugin_->route(*route_entry, *request_header);
+        }
+        return cluster_specifier_plugin_->route(*cluster, *request_header);
+      }
+#endif
       if (!cluster->clusterHeaderName().get().empty() &&
           !headers.get(cluster->clusterHeaderName()).empty()) {
         return pickClusterViaClusterHeader(cluster->clusterHeaderName(), headers);
@@ -1372,7 +1490,7 @@ VirtualHostImpl::VirtualClusterEntry::VirtualClusterEntry(
     const envoy::config::route::v3::VirtualCluster& virtual_cluster, Stats::Scope& scope,
     const VirtualClusterStatNames& stat_names)
     : StatNameProvider(virtual_cluster.name(), scope.symbolTable()),
-      VirtualClusterBase(stat_name_storage_.statName(),
+      VirtualClusterBase(virtual_cluster.name(), stat_name_storage_.statName(),
                          scope.scopeFromStatName(stat_name_storage_.statName()), stat_names) {
   if (virtual_cluster.headers().empty()) {
     throw EnvoyException("virtual clusters must define 'headers'");
@@ -1469,6 +1587,21 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb
     return nullptr;
   }
 
+#if defined(ALIMESH)
+  RouteConstSharedPtr redirect_route = SSL_PERMANENT_REDIRECT_ROUTE;
+  // only return 301 when http method is GET or HEAD
+  if (headers.Method() && (headers.Method()->value() == Http::Headers::get().MethodValues.Get ||
+                           headers.Method()->value() == Http::Headers::get().MethodValues.Head)) {
+    redirect_route = SSL_REDIRECT_ROUTE;
+  }
+  // First check for ssl redirect.
+  if (ssl_requirements_ == SslRequirements::All && scheme != "https") {
+    return redirect_route;
+  } else if (ssl_requirements_ == SslRequirements::ExternalOnly && scheme != "https" &&
+             !Http::HeaderUtility::isEnvoyInternalRequest(headers)) {
+    return redirect_route;
+  }
+#else
   // First check for ssl redirect.
   if (ssl_requirements_ == SslRequirements::All && scheme != "https") {
     return SSL_REDIRECT_ROUTE;
@@ -1476,6 +1609,7 @@ RouteConstSharedPtr VirtualHostImpl::getRouteFromEntries(const RouteCallback& cb
              !Http::HeaderUtility::isEnvoyInternalRequest(headers)) {
     return SSL_REDIRECT_ROUTE;
   }
+#endif
 
   // Check for a route that matches the request.
   for (auto route = routes_.begin(); route != routes_.end(); ++route) {
@@ -1568,6 +1702,12 @@ const Envoy::Config::TypedMetadataImpl<Envoy::Config::TypedMetadataFactory>
 const std::shared_ptr<const SslRedirectRoute> VirtualHostImpl::SSL_REDIRECT_ROUTE{
     new SslRedirectRoute()};
 
+#if defined(ALIMESH)
+const SslPermanentRedirector SslPermanentRedirectRoute::SSL_PERMANENT_REDIRECTOR;
+const std::shared_ptr<const SslPermanentRedirectRoute>
+    VirtualHostImpl::SSL_PERMANENT_REDIRECT_ROUTE{new SslPermanentRedirectRoute};
+#endif
+
 const VirtualCluster*
 VirtualHostImpl::virtualClusterFromEntries(const Http::HeaderMap& headers) const {
   for (const VirtualClusterEntry& entry : virtual_clusters_) {
@@ -1594,6 +1734,13 @@ ConfigImpl::ConfigImpl(const envoy::config::route::v3::RouteConfiguration& confi
       max_direct_response_body_size_bytes_(
           PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, max_direct_response_body_size_bytes,
                                           DEFAULT_MAX_DIRECT_RESPONSE_BODY_SIZE_BYTES)) {
+  // Initialize all cluster specifier plugins before creating route matcher. Because the route may
+  // reference it by name.
+  for (const auto& plugin_proto : config.cluster_specifier_plugins()) {
+    auto plugin = getClusterSpecifierPluginByTheProto(plugin_proto, validator, factory_context);
+    cluster_specifier_plugins_.emplace(plugin_proto.extension().name(), std::move(plugin));
+  }
+
   route_matcher_ = std::make_unique<RouteMatcher>(
       config, optional_http_filters, *this, factory_context, validator,
       PROTOBUF_GET_WRAPPED_OR_DEFAULT(config, validate_clusters, validate_clusters_default));
@@ -1608,6 +1755,16 @@ ConfigImpl::ConfigImpl(const envoy::config::route::v3::RouteConfiguration& confi
                                                      config.response_headers_to_remove());
 }
 
+ClusterSpecifierPluginSharedPtr
+ConfigImpl::clusterSpecifierPlugin(absl::string_view provider) const {
+  auto iter = cluster_specifier_plugins_.find(provider);
+  if (iter == cluster_specifier_plugins_.end() || iter->second == nullptr) {
+    throw EnvoyException(
+        fmt::format("Unknown cluster specifier plugin name: {} is used in the route", provider));
+  }
+  return iter->second;
+}
+
 RouteConstSharedPtr ConfigImpl::route(const RouteCallback& cb,
                                       const Http::RequestHeaderMap& headers,
                                       const StreamInfo::StreamInfo& stream_info,
diff --git a/source/common/router/config_impl.h b/source/common/router/config_impl.h
index 659861f3b1..308d0ad83c 100644
--- a/source/common/router/config_impl.h
+++ b/source/common/router/config_impl.h
@@ -13,6 +13,8 @@
 #include "envoy/config/core/v3/base.pb.h"
 #include "envoy/config/route/v3/route.pb.h"
 #include "envoy/config/route/v3/route_components.pb.h"
+#include "envoy/config/route/v3/route_components.pb.validate.h"
+#include "envoy/router/cluster_specifier_plugin.h"
 #include "envoy/router/router.h"
 #include "envoy/runtime/runtime.h"
 #include "envoy/server/filter_config.h"
@@ -34,6 +36,10 @@
 #include "absl/container/node_hash_map.h"
 #include "absl/types/optional.h"
 
+#if defined(ALIMESH)
+#include "contrib/common/active_redirect/source/active_redirect_policy_impl.h"
+#endif
+
 namespace Envoy {
 namespace Router {
 
@@ -141,6 +147,22 @@ private:
       typed_metadata_;
 };
 
+#if defined(ALIMESH)
+class SslPermanentRedirector : public SslRedirector {
+public:
+  Http::Code responseCode() const override { return Http::Code::PermanentRedirect; }
+};
+class SslPermanentRedirectRoute : public SslRedirectRoute {
+public:
+  const DirectResponseEntry* directResponseEntry() const override {
+    return &SSL_PERMANENT_REDIRECTOR;
+  }
+
+private:
+  static const SslPermanentRedirector SSL_PERMANENT_REDIRECTOR;
+};
+#endif
+
 /**
  * Implementation of CorsPolicy that reads from the proto route and virtual host config.
  */
@@ -234,16 +256,20 @@ private:
 
   struct VirtualClusterBase : public VirtualCluster {
   public:
-    VirtualClusterBase(Stats::StatName stat_name, Stats::ScopePtr&& scope,
-                       const VirtualClusterStatNames& stat_names)
-        : stat_name_(stat_name), scope_(std::move(scope)),
+    VirtualClusterBase(const absl::optional<std::string>& name, Stats::StatName stat_name,
+                       Stats::ScopePtr&& scope, const VirtualClusterStatNames& stat_names)
+        : name_(name), stat_name_(stat_name), scope_(std::move(scope)),
           stats_(generateStats(*scope_, stat_names)) {}
 
     // Router::VirtualCluster
+    // name_ and stat_name_ are two different representations for the same string, retained in
+    // memory to avoid symbol-table locks that would be needed when converting on-the-fly.
+    const absl::optional<std::string>& name() const override { return name_; }
     Stats::StatName statName() const override { return stat_name_; }
     VirtualClusterStats& stats() const override { return stats_; }
 
   private:
+    const absl::optional<std::string> name_;
     const Stats::StatName stat_name_;
     Stats::ScopePtr scope_;
     mutable VirtualClusterStats stats_;
@@ -257,11 +283,14 @@ private:
 
   struct CatchAllVirtualCluster : public VirtualClusterBase {
     CatchAllVirtualCluster(Stats::Scope& scope, const VirtualClusterStatNames& stat_names)
-        : VirtualClusterBase(stat_names.other_, scope.scopeFromStatName(stat_names.other_),
-                             stat_names) {}
+        : VirtualClusterBase(absl::nullopt, stat_names.other_,
+                             scope.scopeFromStatName(stat_names.other_), stat_names) {}
   };
 
   static const std::shared_ptr<const SslRedirectRoute> SSL_REDIRECT_ROUTE;
+#if defined(ALIMESH)
+  static const std::shared_ptr<const SslPermanentRedirectRoute> SSL_PERMANENT_REDIRECT_ROUTE;
+#endif
 
   const Stats::StatNameManagedStorage stat_name_storage_;
   Stats::ScopePtr vcluster_scope_;
@@ -516,6 +545,12 @@ public:
 
   // Router::RouteEntry
   const std::string& clusterName() const override;
+  const RouteStatsContextOptRef routeStatsContext() const override {
+    if (route_stats_context_ != nullptr) {
+      return *route_stats_context_;
+    }
+    return RouteStatsContextOptRef();
+  }
   Http::Code clusterNotFoundResponseCode() const override {
     return cluster_not_found_response_code_;
   }
@@ -544,6 +579,15 @@ public:
   const InternalRedirectPolicy& internalRedirectPolicy() const override {
     return internal_redirect_policy_;
   }
+#if defined(ALIMESH)
+  const InternalActiveRedirectPolicy& internalActiveRedirectPolicy() const override {
+    return internal_active_redirect_policy_;
+  }
+
+  RouteConstSharedPtr clone(const std::string& name) const {
+    return std::make_shared<DynamicRouteEntry>(this, name);
+  }
+#endif
   uint32_t retryShadowBufferLimit() const override { return retry_shadow_buffer_limit_; }
   const std::vector<ShadowPolicyPtr>& shadowPolicies() const override { return shadow_policies_; }
   const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override {
@@ -569,6 +613,7 @@ public:
   }
   const VirtualHost& virtualHost() const override { return vhost_; }
   bool autoHostRewrite() const override { return auto_host_rewrite_; }
+  bool appendXfh() const override { return append_xfh_; }
   const std::multimap<std::string, std::string>& opaqueConfig() const override {
     return opaque_config_;
   }
@@ -608,42 +653,13 @@ public:
       const std::string& filter_name,
       std::function<void(const Router::RouteSpecificFilterConfig&)> cb) const override;
 
-protected:
-  const bool case_sensitive_;
-  const std::string prefix_rewrite_;
-  Regex::CompiledMatcherPtr regex_rewrite_;
-  Regex::CompiledMatcherPtr regex_rewrite_redirect_;
-  std::string regex_rewrite_substitution_;
-  std::string regex_rewrite_redirect_substitution_;
-  const std::string host_rewrite_;
-  bool include_vh_rate_limits_;
-  absl::optional<ConnectConfig> connect_config_;
-
-  RouteConstSharedPtr clusterEntry(const Http::HeaderMap& headers, uint64_t random_value) const;
-
-  /**
-   * Returns the correct path rewrite string for this route.
-   *
-   * The provided container may be used to store memory backing the return value
-   * therefore it must outlive any use of the return value.
-   */
-  const std::string& getPathRewrite(const Http::RequestHeaderMap& headers,
-                                    absl::optional<std::string>& container) const;
-
-  void finalizePathHeader(Http::RequestHeaderMap& headers, absl::string_view matched_path,
-                          bool insert_envoy_original_path) const;
-
-  absl::optional<std::string>
-  currentUrlPathAfterRewriteWithMatchedPath(const Http::RequestHeaderMap& headers,
-                                            absl::string_view matched_path) const;
-
-private:
-  struct RuntimeData {
-    std::string fractional_runtime_key_{};
-    envoy::type::v3::FractionalPercent fractional_runtime_default_{};
-  };
-
+#if defined(ALIMESH)
+  class DynamicRouteEntry : public RouteEntry,
+                            public Route,
+                            public std::enable_shared_from_this<DynamicRouteEntry> {
+#else
   class DynamicRouteEntry : public RouteEntry, public Route {
+#endif
   public:
     DynamicRouteEntry(const RouteEntryImplBase* parent, const std::string& name)
         : parent_(parent), cluster_name_(name) {}
@@ -723,6 +739,7 @@ private:
 
     const VirtualHost& virtualHost() const override { return parent_->virtualHost(); }
     bool autoHostRewrite() const override { return parent_->autoHostRewrite(); }
+    bool appendXfh() const override { return parent_->appendXfh(); }
     bool includeVirtualHostRateLimits() const override {
       return parent_->includeVirtualHostRateLimits();
     }
@@ -745,6 +762,9 @@ private:
     const absl::optional<ConnectConfig>& connectConfig() const override {
       return parent_->connectConfig();
     }
+    const RouteStatsContextOptRef routeStatsContext() const override {
+      return parent_->routeStatsContext();
+    }
     const UpgradeMap& upgradeMap() const override { return parent_->upgradeMap(); }
 
     // Router::Route
@@ -762,6 +782,18 @@ private:
       parent_->traversePerFilterConfig(filter_name, cb);
     };
 
+#if defined(ALIMESH)
+    const InternalActiveRedirectPolicy& internalActiveRedirectPolicy() const override {
+      return parent_->internalActiveRedirectPolicy();
+    }
+
+    RouteConstSharedPtr clone(const std::string& name) const {
+      return std::make_shared<Envoy::Router::RouteEntryImplBase::DynamicRouteEntry>(parent_, name);
+    }
+
+    virtual RouteConstSharedPtr getRouteConstSharedPtr() const { return shared_from_this(); }
+#endif
+
   private:
     const RouteEntryImplBase* parent_;
     const std::string cluster_name_;
@@ -821,6 +853,10 @@ private:
 
     const Http::LowerCaseString& clusterHeaderName() const { return cluster_header_name_; }
 
+#if defined(ALIMESH)
+    RouteConstSharedPtr getRouteConstSharedPtr() const override { return shared_from_this(); }
+#endif
+
   private:
     const std::string runtime_key_;
     Runtime::Loader& loader_;
@@ -835,6 +871,64 @@ private:
 
   using WeightedClusterEntrySharedPtr = std::shared_ptr<WeightedClusterEntry>;
 
+protected:
+  const bool case_sensitive_;
+  const std::string prefix_rewrite_;
+  Regex::CompiledMatcherPtr regex_rewrite_;
+  Regex::CompiledMatcherPtr regex_rewrite_redirect_;
+  std::string regex_rewrite_substitution_;
+  std::string regex_rewrite_redirect_substitution_;
+  const std::string host_rewrite_;
+  bool include_vh_rate_limits_;
+  absl::optional<ConnectConfig> connect_config_;
+
+  RouteConstSharedPtr clusterEntry(const Http::RequestHeaderMap& headers,
+                                   uint64_t random_value) const;
+
+  /**
+   * Returns the correct path rewrite string for this route.
+   *
+   * The provided container may be used to store memory backing the return value
+   * therefore it must outlive any use of the return value.
+   */
+  const std::string& getPathRewrite(const Http::RequestHeaderMap& headers,
+                                    absl::optional<std::string>& container) const;
+
+  void finalizePathHeader(Http::RequestHeaderMap& headers, absl::string_view matched_path,
+                          bool insert_envoy_original_path) const;
+
+  absl::optional<std::string>
+  currentUrlPathAfterRewriteWithMatchedPath(const Http::RequestHeaderMap& headers,
+                                            absl::string_view matched_path) const;
+
+private:
+  struct RuntimeData {
+    std::string fractional_runtime_key_{};
+    envoy::type::v3::FractionalPercent fractional_runtime_default_{};
+  };
+
+  /**
+   * Returns a vector of request header parsers which applied or will apply header transformations
+   * to the request in this route.
+   * @param specificity_ascend specifies whether the returned parsers will be sorted from least
+   *        specific to most specific (global connection manager level header parser, virtual host
+   *        level header parser and finally route-level parser.) or the reverse.
+   * @return a vector of request header parsers.
+   */
+  absl::InlinedVector<const HeaderParser*, 3>
+  getRequestHeaderParsers(bool specificity_ascend) const;
+
+  /**
+   * Returns a vector of response header parsers which applied or will apply header transformations
+   * to the response in this route.
+   * @param specificity_ascend specifies whether the returned parsers will be sorted from least
+   *        specific to most specific (global connection manager level header parser, virtual host
+   *        level header parser and finally route-level parser.) or the reverse.
+   * @return a vector of request header parsers.
+   */
+  absl::InlinedVector<const HeaderParser*, 3>
+  getResponseHeaderParsers(bool specificity_ascend) const;
+
   absl::optional<RuntimeData> loadRuntimeData(const envoy::config::route::v3::RouteMatch& route);
 
   static std::multimap<std::string, std::string>
@@ -863,6 +957,12 @@ private:
                               ProtobufMessage::ValidationVisitor& validator,
                               absl::string_view current_route_name) const;
 
+#if defined(ALIMESH)
+  InternalActiveRedirectPoliciesImpl
+  buildActiveInternalRedirectPolicy(const envoy::config::route::v3::RouteAction& route_config,
+                                    ProtobufMessage::ValidationVisitor& validator,
+                                    absl::string_view current_route_name) const;
+#endif
   RouteConstSharedPtr pickClusterViaClusterHeader(const Http::LowerCaseString& cluster_header_name,
                                                   const Http::HeaderMap& headers) const;
 
@@ -879,8 +979,11 @@ private:
   const absl::optional<Http::LowerCaseString> auto_host_rewrite_header_;
   const Regex::CompiledMatcherPtr host_rewrite_path_regex_;
   const std::string host_rewrite_path_regex_substitution_;
+  const bool append_xfh_;
   const std::string cluster_name_;
+  RouteStatsContextPtr route_stats_context_;
   const Http::LowerCaseString cluster_header_name_;
+  ClusterSpecifierPluginSharedPtr cluster_specifier_plugin_;
   const Http::Code cluster_not_found_response_code_;
   const std::chrono::milliseconds timeout_;
   const absl::optional<std::chrono::milliseconds> idle_timeout_;
@@ -933,6 +1036,10 @@ private:
   PerFilterConfigs per_filter_configs_;
   const std::string route_name_;
   TimeSource& time_source_;
+
+#if defined(ALIMESH)
+  const InternalActiveRedirectPoliciesImpl internal_active_redirect_policy_;
+#endif
 };
 
 /**
@@ -1145,6 +1252,8 @@ public:
     return max_direct_response_body_size_bytes_;
   }
 
+  ClusterSpecifierPluginSharedPtr clusterSpecifierPlugin(absl::string_view provider) const;
+
 private:
   std::unique_ptr<RouteMatcher> route_matcher_;
   std::list<Http::LowerCaseString> internal_only_headers_;
@@ -1155,6 +1264,9 @@ private:
   const bool uses_vhds_;
   const bool most_specific_header_mutations_wins_;
   const uint32_t max_direct_response_body_size_bytes_;
+
+  // Cluster specifier plugins/providers.
+  absl::flat_hash_map<std::string, ClusterSpecifierPluginSharedPtr> cluster_specifier_plugins_;
 };
 
 /**
diff --git a/source/common/router/context_impl.cc b/source/common/router/context_impl.cc
index 2a2df3b234..921455ce68 100644
--- a/source/common/router/context_impl.cc
+++ b/source/common/router/context_impl.cc
@@ -1,10 +1,15 @@
 #include "source/common/router/context_impl.h"
 
+#include "source/common/config/utility.h"
+
 namespace Envoy {
 namespace Router {
 
 ContextImpl::ContextImpl(Stats::SymbolTable& symbol_table)
-    : stat_names_(symbol_table), virtual_cluster_stat_names_(symbol_table) {}
+    : stat_names_(symbol_table), route_stat_names_(symbol_table),
+      virtual_cluster_stat_names_(symbol_table),
+      generic_conn_pool_factory_(Envoy::Config::Utility::getFactoryByName<GenericConnPoolFactory>(
+          "envoy.filters.connection_pools.http.generic")) {}
 
 } // namespace Router
 } // namespace Envoy
diff --git a/source/common/router/context_impl.h b/source/common/router/context_impl.h
index fd36cbdd3a..da794fde5c 100644
--- a/source/common/router/context_impl.h
+++ b/source/common/router/context_impl.h
@@ -4,6 +4,8 @@
 #include "envoy/router/router.h"
 #include "envoy/stats/stats_macros.h"
 
+#include "source/common/common/assert.h"
+
 namespace Envoy {
 namespace Router {
 
@@ -38,10 +40,17 @@ public:
   const VirtualClusterStatNames& virtualClusterStatNames() const override {
     return virtual_cluster_stat_names_;
   }
+  const RouteStatNames& routeStatNames() const override { return route_stat_names_; }
+  GenericConnPoolFactory& genericConnPoolFactory() override {
+    ASSERT(generic_conn_pool_factory_ != nullptr);
+    return *generic_conn_pool_factory_;
+  }
 
 private:
   const StatNames stat_names_;
+  const RouteStatNames route_stat_names_;
   const VirtualClusterStatNames virtual_cluster_stat_names_;
+  GenericConnPoolFactory* generic_conn_pool_factory_;
 };
 
 } // namespace Router
diff --git a/source/common/router/delegating_route_impl.cc b/source/common/router/delegating_route_impl.cc
index 422b43248d..ddf1899837 100644
--- a/source/common/router/delegating_route_impl.cc
+++ b/source/common/router/delegating_route_impl.cc
@@ -126,6 +126,8 @@ bool DelegatingRouteEntry::autoHostRewrite() const {
   return base_route_->routeEntry()->autoHostRewrite();
 }
 
+bool DelegatingRouteEntry::appendXfh() const { return base_route_->routeEntry()->appendXfh(); }
+
 const MetadataMatchCriteria* DelegatingRouteEntry::metadataMatchCriteria() const {
   return base_route_->routeEntry()->metadataMatchCriteria();
 }
diff --git a/source/common/router/delegating_route_impl.h b/source/common/router/delegating_route_impl.h
index f9696e8fc7..939d3094be 100644
--- a/source/common/router/delegating_route_impl.h
+++ b/source/common/router/delegating_route_impl.h
@@ -95,6 +95,7 @@ public:
   const VirtualCluster* virtualCluster(const Http::HeaderMap& headers) const override;
   const VirtualHost& virtualHost() const override;
   bool autoHostRewrite() const override;
+  bool appendXfh() const override;
   const MetadataMatchCriteria* metadataMatchCriteria() const override;
   const std::multimap<std::string, std::string>& opaqueConfig() const override;
   bool includeVirtualHostRateLimits() const override;
@@ -106,6 +107,12 @@ public:
   const absl::optional<ConnectConfig>& connectConfig() const override;
   const std::string& routeName() const override;
 
+#if defined(ALIMESH)
+  const InternalActiveRedirectPolicy& internalActiveRedirectPolicy() const override {
+    return base_route_->routeEntry()->internalActiveRedirectPolicy();
+  }
+#endif
+
 private:
   const Router::RouteConstSharedPtr base_route_;
 };
diff --git a/source/common/router/retry_state_impl.cc b/source/common/router/retry_state_impl.cc
index 0b7d86b2c2..ec03e34e9f 100644
--- a/source/common/router/retry_state_impl.cc
+++ b/source/common/router/retry_state_impl.cc
@@ -17,19 +17,27 @@
 namespace Envoy {
 namespace Router {
 
-RetryStatePtr RetryStateImpl::create(const RetryPolicy& route_policy,
-                                     Http::RequestHeaderMap& request_headers,
-                                     const Upstream::ClusterInfo& cluster,
-                                     const VirtualCluster* vcluster, Runtime::Loader& runtime,
-                                     Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
-                                     TimeSource& time_source, Upstream::ResourcePriority priority) {
-  RetryStatePtr ret;
+bool clusterSupportsHttp3AndTcpFallback(const Upstream::ClusterInfo& cluster) {
+  return (cluster.features() & Upstream::ClusterInfo::Features::HTTP3) &&
+         // USE_ALPN is only set when a TCP pool is also configured. Such cluster supports TCP
+         // fallback.
+         (cluster.features() & Upstream::ClusterInfo::Features::USE_ALPN);
+}
+
+std::unique_ptr<RetryStateImpl>
+RetryStateImpl::create(const RetryPolicy& route_policy, Http::RequestHeaderMap& request_headers,
+                       const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
+                       RouteStatsContextOptRef route_stats_context, Runtime::Loader& runtime,
+                       Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
+                       TimeSource& time_source, Upstream::ResourcePriority priority) {
+  std::unique_ptr<RetryStateImpl> ret;
 
   // We short circuit here and do not bother with an allocation if there is no chance we will retry.
   if (request_headers.EnvoyRetryOn() || request_headers.EnvoyRetryGrpcOn() ||
       route_policy.retryOn()) {
-    ret.reset(new RetryStateImpl(route_policy, request_headers, cluster, vcluster, runtime, random,
-                                 dispatcher, time_source, priority));
+    ret.reset(new RetryStateImpl(route_policy, request_headers, cluster, vcluster,
+                                 route_stats_context, runtime, random, dispatcher, time_source,
+                                 priority));
   }
 
   // Consume all retry related headers to avoid them being propagated to the upstream
@@ -47,13 +55,14 @@ RetryStatePtr RetryStateImpl::create(const RetryPolicy& route_policy,
 RetryStateImpl::RetryStateImpl(const RetryPolicy& route_policy,
                                Http::RequestHeaderMap& request_headers,
                                const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
+                               RouteStatsContextOptRef route_stats_context,
                                Runtime::Loader& runtime, Random::RandomGenerator& random,
                                Event::Dispatcher& dispatcher, TimeSource& time_source,
                                Upstream::ResourcePriority priority)
-    : cluster_(cluster), vcluster_(vcluster), runtime_(runtime), random_(random),
-      dispatcher_(dispatcher), time_source_(time_source), retry_on_(route_policy.retryOn()),
-      retries_remaining_(route_policy.numRetries()), priority_(priority),
-      retry_host_predicates_(route_policy.retryHostPredicates()),
+    : cluster_(cluster), vcluster_(vcluster), route_stats_context_(route_stats_context),
+      runtime_(runtime), random_(random), dispatcher_(dispatcher), time_source_(time_source),
+      retry_on_(route_policy.retryOn()), retries_remaining_(route_policy.numRetries()),
+      priority_(priority), retry_host_predicates_(route_policy.retryHostPredicates()),
       retry_priority_(route_policy.retryPriority()),
       retriable_status_codes_(route_policy.retriableStatusCodes()),
       retriable_headers_(route_policy.retriableHeaders()),
@@ -240,6 +249,9 @@ RetryStatus RetryStateImpl::shouldRetry(bool would_retry, DoRetryCallback callba
     if (vcluster_) {
       vcluster_->stats().upstream_rq_retry_success_.inc();
     }
+    if (route_stats_context_.has_value()) {
+      route_stats_context_->stats().upstream_rq_retry_success_.inc();
+    }
   }
 
   resetRetry();
@@ -255,6 +267,9 @@ RetryStatus RetryStateImpl::shouldRetry(bool would_retry, DoRetryCallback callba
     if (vcluster_) {
       vcluster_->stats().upstream_rq_retry_limit_exceeded_.inc();
     }
+    if (route_stats_context_.has_value()) {
+      route_stats_context_->stats().upstream_rq_retry_limit_exceeded_.inc();
+    }
     return RetryStatus::NoRetryLimitExceeded;
   }
 
@@ -265,6 +280,9 @@ RetryStatus RetryStateImpl::shouldRetry(bool would_retry, DoRetryCallback callba
     if (vcluster_) {
       vcluster_->stats().upstream_rq_retry_overflow_.inc();
     }
+    if (route_stats_context_.has_value()) {
+      route_stats_context_->stats().upstream_rq_retry_overflow_.inc();
+    }
     return RetryStatus::NoOverflow;
   }
 
@@ -279,6 +297,10 @@ RetryStatus RetryStateImpl::shouldRetry(bool would_retry, DoRetryCallback callba
   if (vcluster_) {
     vcluster_->stats().upstream_rq_retry_.inc();
   }
+  if (route_stats_context_.has_value()) {
+    route_stats_context_->stats().upstream_rq_retry_.inc();
+  }
+
   enableBackoffTimer();
   return RetryStatus::Yes;
 }
diff --git a/source/common/router/retry_state_impl.h b/source/common/router/retry_state_impl.h
index affa6f9fa0..f344ad0789 100644
--- a/source/common/router/retry_state_impl.h
+++ b/source/common/router/retry_state_impl.h
@@ -25,12 +25,12 @@ namespace Router {
  */
 class RetryStateImpl : public RetryState {
 public:
-  static RetryStatePtr create(const RetryPolicy& route_policy,
-                              Http::RequestHeaderMap& request_headers,
-                              const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
-                              Runtime::Loader& runtime, Random::RandomGenerator& random,
-                              Event::Dispatcher& dispatcher, TimeSource& time_source,
-                              Upstream::ResourcePriority priority);
+  static std::unique_ptr<RetryStateImpl>
+  create(const RetryPolicy& route_policy, Http::RequestHeaderMap& request_headers,
+         const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
+         RouteStatsContextOptRef route_stats_context, Runtime::Loader& runtime,
+         Random::RandomGenerator& random, Event::Dispatcher& dispatcher, TimeSource& time_source,
+         Upstream::ResourcePriority priority);
   ~RetryStateImpl() override;
 
   /**
@@ -94,9 +94,9 @@ public:
 private:
   RetryStateImpl(const RetryPolicy& route_policy, Http::RequestHeaderMap& request_headers,
                  const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
-                 Runtime::Loader& runtime, Random::RandomGenerator& random,
-                 Event::Dispatcher& dispatcher, TimeSource& time_source,
-                 Upstream::ResourcePriority priority);
+                 RouteStatsContextOptRef route_stats_context, Runtime::Loader& runtime,
+                 Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
+                 TimeSource& time_source, Upstream::ResourcePriority priority);
 
   void enableBackoffTimer();
   void resetRetry();
@@ -105,6 +105,7 @@ private:
 
   const Upstream::ClusterInfo& cluster_;
   const VirtualCluster* vcluster_;
+  RouteStatsContextOptRef route_stats_context_;
   Runtime::Loader& runtime_;
   Random::RandomGenerator& random_;
   Event::Dispatcher& dispatcher_;
diff --git a/source/common/router/router.cc b/source/common/router/router.cc
index 054b6a6858..aaea17c8d3 100644
--- a/source/common/router/router.cc
+++ b/source/common/router/router.cc
@@ -42,6 +42,10 @@
 #include "source/common/stream_info/uint32_accessor_impl.h"
 #include "source/common/tracing/http_tracer_impl.h"
 
+#if defined(ALIMESH)
+#include "source/common/http/path_utility.h"
+#endif
+
 namespace Envoy {
 namespace Router {
 namespace {
@@ -298,13 +302,12 @@ Stats::StatName Filter::upstreamZone(Upstream::HostDescriptionConstSharedPtr ups
   return upstream_host ? upstream_host->localityZoneStatName() : config_.empty_stat_name_;
 }
 
-void Filter::chargeUpstreamCode(uint64_t response_status_code,
-                                const Http::ResponseHeaderMap& response_headers,
-                                Upstream::HostDescriptionConstSharedPtr upstream_host,
-                                bool dropped) {
-  // Passing the response_status_code explicitly is an optimization to avoid
-  // multiple calls to slow Http::Utility::getResponseStatus.
-  ASSERT(response_status_code == Http::Utility::getResponseStatus(response_headers));
+#if defined(ALIMESH)
+void Filter::chargeUpstreamGrpcCode(uint64_t http_status_code, uint64_t grpc_response_code,
+                                    const Http::ResponseHeaderMap& response_headers,
+                                    Upstream::HostDescriptionConstSharedPtr upstream_host,
+                                    bool dropped) {
+  ASSERT(Grpc::Common::getGrpcStatus(response_headers).has_value());
   if (config_.emit_dynamic_stats_ && !callbacks_->streamInfo().healthCheck()) {
     const Http::HeaderEntry* upstream_canary_header = response_headers.EnvoyUpstreamCanary();
     const bool is_canary = (upstream_canary_header && upstream_canary_header->value() == "true") ||
@@ -315,11 +318,13 @@ void Filter::chargeUpstreamCode(uint64_t response_status_code,
     Http::CodeStats::ResponseStatInfo info{config_.scope_,
                                            cluster_->statsScope(),
                                            config_.empty_stat_name_,
-                                           response_status_code,
+                                           grpc_response_code,
                                            internal_request,
                                            route_entry_->virtualHost().statName(),
                                            request_vcluster_ ? request_vcluster_->statName()
                                                              : config_.empty_stat_name_,
+                                           route_stats_context_.has_value() ? route_stats_context_->statName()
+                                                                            : config_.empty_stat_name_,
                                            config_.zone_name_,
                                            upstream_zone,
                                            is_canary};
@@ -327,6 +332,62 @@ void Filter::chargeUpstreamCode(uint64_t response_status_code,
     Http::CodeStats& code_stats = httpContext().codeStats();
     code_stats.chargeResponseStat(info, exclude_http_code_stats_);
 
+    if (alt_stat_prefix_ != nullptr) {
+      Http::CodeStats::ResponseStatInfo alt_info{config_.scope_,
+                                                 cluster_->statsScope(),
+                                                 alt_stat_prefix_->statName(),
+                                                 grpc_response_code,
+                                                 internal_request,
+                                                 config_.empty_stat_name_,
+                                                 config_.empty_stat_name_,
+                                                 config_.empty_stat_name_,
+                                                 config_.zone_name_,
+                                                 upstream_zone,
+                                                 is_canary};
+      code_stats.chargeResponseStat(alt_info, exclude_http_code_stats_);
+    }
+
+    if (dropped) {
+      cluster_->loadReportStats().upstream_rq_dropped_.inc();
+    }
+    if (upstream_host && Http::CodeUtility::is5xx(http_status_code)) {
+      upstream_host->stats().rq_error_.inc();
+    }
+  }
+}
+#endif
+
+void Filter::chargeUpstreamCode(uint64_t response_status_code,
+                                const Http::ResponseHeaderMap& response_headers,
+                                Upstream::HostDescriptionConstSharedPtr upstream_host,
+                                bool dropped) {
+  // Passing the response_status_code explicitly is an optimization to avoid
+  // multiple calls to slow Http::Utility::getResponseStatus.
+  ASSERT(response_status_code == Http::Utility::getResponseStatus(response_headers));
+  if (config_.emit_dynamic_stats_ && !callbacks_->streamInfo().healthCheck()) {
+    const Http::HeaderEntry* upstream_canary_header = response_headers.EnvoyUpstreamCanary();
+    const bool is_canary = (upstream_canary_header && upstream_canary_header->value() == "true") ||
+                           (upstream_host ? upstream_host->canary() : false);
+    const bool internal_request = Http::HeaderUtility::isEnvoyInternalRequest(*downstream_headers_);
+
+    Stats::StatName upstream_zone = upstreamZone(upstream_host);
+    Http::CodeStats::ResponseStatInfo info{
+        config_.scope_,
+        cluster_->statsScope(),
+        config_.empty_stat_name_,
+        response_status_code,
+        internal_request,
+        route_entry_->virtualHost().statName(),
+        request_vcluster_ ? request_vcluster_->statName() : config_.empty_stat_name_,
+        route_stats_context_.has_value() ? route_stats_context_->statName()
+                                         : config_.empty_stat_name_,
+        config_.zone_name_,
+        upstream_zone,
+        is_canary};
+
+    Http::CodeStats& code_stats = httpContext().codeStats();
+    code_stats.chargeResponseStat(info, exclude_http_code_stats_);
+
     if (alt_stat_prefix_ != nullptr) {
       Http::CodeStats::ResponseStatInfo alt_info{config_.scope_,
                                                  cluster_->statsScope(),
@@ -335,6 +396,7 @@ void Filter::chargeUpstreamCode(uint64_t response_status_code,
                                                  internal_request,
                                                  config_.empty_stat_name_,
                                                  config_.empty_stat_name_,
+                                                 config_.empty_stat_name_,
                                                  config_.zone_name_,
                                                  upstream_zone,
                                                  is_canary};
@@ -453,6 +515,10 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers,
 
   // Set up stat prefixes, etc.
   request_vcluster_ = route_entry_->virtualCluster(headers);
+  if (request_vcluster_ != nullptr) {
+    callbacks_->streamInfo().setVirtualClusterName(request_vcluster_->name());
+  }
+  route_stats_context_ = route_entry_->routeStatsContext();
   ENVOY_STREAM_LOG(debug, "cluster '{}' match for URL '{}'", *callbacks_,
                    route_entry_->clusterName(), headers.getPathValue());
 
@@ -645,6 +711,15 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers,
   // Inject the active span's tracing context into the request headers.
   callbacks_->activeSpan().injectContext(headers);
 
+#if defined(ALIMESH)
+  Http::HeaderString start_time;
+  start_time.setInteger(std::chrono::duration_cast<std::chrono::milliseconds>(
+                            callbacks_->streamInfo().startTime().time_since_epoch())
+                            .count());
+  downstream_headers_->setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.TriStartTime,
+                                       start_time.getStringView());
+#endif
+
   route_entry_->finalizeRequestHeaders(headers, callbacks_->streamInfo(),
                                        !config_.suppress_envoy_headers_);
   FilterUtility::setUpstreamScheme(
@@ -654,9 +729,10 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::RequestHeaderMap& headers,
   // Ensure an http transport scheme is selected before continuing with decoding.
   ASSERT(headers.Scheme());
 
-  retry_state_ = createRetryState(
-      route_entry_->retryPolicy(), headers, *cluster_, request_vcluster_, config_.runtime_,
-      config_.random_, callbacks_->dispatcher(), config_.timeSource(), route_entry_->priority());
+  retry_state_ =
+      createRetryState(route_entry_->retryPolicy(), headers, *cluster_, request_vcluster_,
+                       route_stats_context_, config_.runtime_, config_.random_,
+                       callbacks_->dispatcher(), config_.timeSource(), route_entry_->priority());
 
   // Determine which shadow policies to use. It's possible that we don't do any shadowing due to
   // runtime keys.
@@ -697,8 +773,7 @@ Filter::createConnPool(Upstream::ThreadLocalCluster& thread_local_cluster) {
                           cluster_->upstreamConfig().value().DebugString()));
   }
   if (!factory) {
-    factory = &Envoy::Config::Utility::getAndCheckFactoryByName<GenericConnPoolFactory>(
-        "envoy.filters.connection_pools.http.generic");
+    factory = &config_.router_context_.genericConnPoolFactory();
   }
 
   bool should_tcp_proxy = false;
@@ -912,6 +987,9 @@ void Filter::onResponseTimeout() {
       if (request_vcluster_) {
         request_vcluster_->stats().upstream_rq_timeout_.inc();
       }
+      if (route_stats_context_.has_value()) {
+        route_stats_context_->stats().upstream_rq_timeout_.inc();
+      }
 
       if (cluster_->timeoutBudgetStats().has_value()) {
         // Cancel firing per-try timeout information, because the per-try timeout did not come into
@@ -1303,6 +1381,15 @@ void Filter::onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPt
     upstream_request.upstreamHost()->outlierDetector().putHttpResponseCode(response_code);
   }
 
+#if defined(ALIMESH)
+  static Envoy::Http::LowerCaseString shutdown_key("micro.service.shutdown.endpoint");
+  if (!headers->get(shutdown_key).empty()) {
+    upstream_request.upstreamHost()->outlierDetector().forceEjectHost();
+    ENVOY_STREAM_LOG(debug, "found shutdown header, host will be shutdown ,so forceEject this Host",
+                     *callbacks_);
+  }
+#endif
+
   if (headers->EnvoyImmediateHealthCheckFail() != nullptr) {
     upstream_request.upstreamHost()->healthChecker().setUnhealthy(
         Upstream::HealthCheckHostMonitor::UnhealthyType::ImmediateHealthCheckFail);
@@ -1356,6 +1443,18 @@ void Filter::onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPt
     // next downstream.
   }
 
+#if defined(ALIMESH)
+  if (route_entry_->internalActiveRedirectPolicy().enabled() &&
+      route_entry_->internalActiveRedirectPolicy().shouldRedirectForResponseCode(
+          static_cast<Http::Code>(response_code)) &&
+      setupActiveRedirect(*headers, upstream_request)) {
+    ENVOY_STREAM_LOG(debug, "setup active redirect", *callbacks_);
+    return;
+    // If the redirect could not be handled, fail open and let it pass to the
+    // next downstream.
+  }
+#endif
+
   // Check if we got a "bad" response, but there are still upstream requests in
   // flight awaiting headers or scheduled retries. If so, exit to give them a
   // chance to return before returning a response downstream.
@@ -1381,6 +1480,29 @@ void Filter::onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPt
     MonotonicTime response_received_time = dispatcher.timeSource().monotonicTime();
     std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(
         response_received_time - downstream_request_complete_time_);
+#if defined(ALIMESH)
+    std::chrono::milliseconds duration_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
+        response_received_time - callbacks_->streamInfo().startTimeMonotonic());
+    Http::HeaderString cost_time;
+    cost_time.setInteger(duration_ms.count());
+    headers->setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.TriCostTime,
+                             cost_time.getStringView());
+
+    Http::HeaderString arrive_time;
+    arrive_time.setInteger(std::chrono::duration_cast<std::chrono::milliseconds>(
+                               callbacks_->streamInfo().startTime().time_since_epoch())
+                               .count());
+    headers->setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.TriArriveTime,
+                             arrive_time.getStringView());
+
+    SystemTime system_response_receive_time = dispatcher.timeSource().systemTime();
+    Http::HeaderString start_time;
+    start_time.setInteger(std::chrono::duration_cast<std::chrono::milliseconds>(
+                              system_response_receive_time.time_since_epoch())
+                              .count());
+    headers->setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.TriRespStartTime,
+                             start_time.getStringView());
+#endif
     if (!config_.suppress_envoy_headers_) {
       headers->setEnvoyUpstreamServiceTime(ms.count());
     }
@@ -1389,7 +1511,16 @@ void Filter::onUpstreamHeaders(uint64_t response_code, Http::ResponseHeaderMapPt
   upstream_request.upstreamCanary(
       (headers->EnvoyUpstreamCanary() && headers->EnvoyUpstreamCanary()->value() == "true") ||
       upstream_request.upstreamHost()->canary());
+#if defined(ALIMESH)
+  if (grpc_status.has_value()) {
+    chargeUpstreamGrpcCode(response_code, grpc_to_http_status, *headers,
+                           upstream_request.upstreamHost(), false);
+  } else {
+    chargeUpstreamCode(response_code, *headers, upstream_request.upstreamHost(), false);
+  }
+#else
   chargeUpstreamCode(response_code, *headers, upstream_request.upstreamHost(), false);
+#endif
   if (!Http::CodeUtility::is5xx(response_code)) {
     handleNon5xxResponseHeaders(grpc_status, upstream_request, end_stream, grpc_to_http_status);
   }
@@ -1488,17 +1619,19 @@ void Filter::onUpstreamComplete(UpstreamRequest& upstream_request) {
     const bool internal_request = Http::HeaderUtility::isEnvoyInternalRequest(*downstream_headers_);
 
     Http::CodeStats& code_stats = httpContext().codeStats();
-    Http::CodeStats::ResponseTimingInfo info{config_.scope_,
-                                             cluster_->statsScope(),
-                                             config_.empty_stat_name_,
-                                             response_time,
-                                             upstream_request.upstreamCanary(),
-                                             internal_request,
-                                             route_entry_->virtualHost().statName(),
-                                             request_vcluster_ ? request_vcluster_->statName()
-                                                               : config_.empty_stat_name_,
-                                             config_.zone_name_,
-                                             upstreamZone(upstream_request.upstreamHost())};
+    Http::CodeStats::ResponseTimingInfo info{
+        config_.scope_,
+        cluster_->statsScope(),
+        config_.empty_stat_name_,
+        response_time,
+        upstream_request.upstreamCanary(),
+        internal_request,
+        route_entry_->virtualHost().statName(),
+        request_vcluster_ ? request_vcluster_->statName() : config_.empty_stat_name_,
+        route_stats_context_.has_value() ? route_stats_context_->statName()
+                                         : config_.empty_stat_name_,
+        config_.zone_name_,
+        upstreamZone(upstream_request.upstreamHost())};
 
     code_stats.chargeResponseTiming(info);
 
@@ -1511,6 +1644,7 @@ void Filter::onUpstreamComplete(UpstreamRequest& upstream_request) {
                                                internal_request,
                                                config_.empty_stat_name_,
                                                config_.empty_stat_name_,
+                                               config_.empty_stat_name_,
                                                config_.zone_name_,
                                                upstreamZone(upstream_request.upstreamHost())};
 
@@ -1624,7 +1758,8 @@ bool Filter::convertRequestHeadersForInternalRedirect(Http::RequestHeaderMap& do
     return false;
   }
 
-  const auto& route_name = route->routeEntry()->routeName();
+  const auto& route_name = route->directResponseEntry() ? route->directResponseEntry()->routeName()
+                                                        : route->routeEntry()->routeName();
   for (const auto& predicate : policy.predicates()) {
     if (!predicate->acceptTargetRoute(*filter_state, route_name, !scheme_is_http,
                                       !target_is_http)) {
@@ -1654,6 +1789,143 @@ bool Filter::convertRequestHeadersForInternalRedirect(Http::RequestHeaderMap& do
   return true;
 }
 
+#if defined(ALIMESH)
+bool Filter::setupActiveRedirect(const Http::ResponseHeaderMap&, UpstreamRequest&) {
+  ENVOY_STREAM_LOG(debug, "attempting internal active redirect", *callbacks_);
+
+  std::string end_stream = downstream_end_stream_ ? "true" : "false";
+  ENVOY_STREAM_LOG(debug, "downstream_end_stream: {}", *callbacks_, end_stream);
+  ENVOY_STREAM_LOG(debug, "!decodingBuffer: {}", *callbacks_,
+                   !callbacks_->decodingBuffer() ? "true" : "false");
+
+  // Redirects are not supported for streaming requests yet.
+  if (downstream_end_stream_ &&
+      !callbacks_->decodingBuffer() && // Redirects with body not yet supported.
+      convertRequestHeadersForInternalActiveRedirect(*downstream_headers_) &&
+      callbacks_->recreateStream(nullptr)) {
+    ENVOY_STREAM_LOG(debug, "Internal active redirect success", *callbacks_);
+    cluster_->stats().upstream_internal_redirect_succeeded_total_.inc();
+    return true;
+  }
+
+  ENVOY_STREAM_LOG(warn, "Internal active redirect failed", *callbacks_);
+  cluster_->stats().upstream_internal_redirect_failed_total_.inc();
+  return false;
+}
+
+bool Filter::convertRequestHeadersForInternalActiveRedirect(
+    Http::RequestHeaderMap& downstream_headers) {
+  if (!downstream_headers.Path()) {
+    ENVOY_STREAM_LOG(warn, "There is no path in the downstream header", *callbacks_);
+    return false;
+  }
+
+  // Make sure the redirect response contains a URL to redirect to.
+  const auto& policy = route_entry_->internalActiveRedirectPolicy();
+  const std::string path(downstream_headers.getPathValue());
+  absl::string_view just_path(Http::PathUtil::removeQueryAndFragment(path));
+  std::string redirect_url = policy.redirectUrl(just_path.data());
+  if (redirect_url.empty()) {
+    ENVOY_STREAM_LOG(warn, "The redirect is empty", *callbacks_);
+    config_.stats_.passthrough_internal_redirect_bad_location_.inc();
+    return false;
+  }
+
+  Http::Utility::Url absolute_url;
+  if (!absolute_url.initialize(redirect_url, false)) {
+    ENVOY_STREAM_LOG(warn, "Invalid redirect address: {}", *callbacks_, redirect_url);
+    config_.stats_.passthrough_internal_redirect_bad_location_.inc();
+    return false;
+  }
+
+  // Don't allow serving TLS responses over plaintext unless allowed by policy.
+  const bool scheme_is_http = schemeIsHttp(downstream_headers, *callbacks_->connection());
+  const bool target_is_http = absolute_url.scheme() == Http::Headers::get().SchemeValues.Http;
+  if (!policy.isCrossSchemeRedirectAllowed() && scheme_is_http != target_is_http) {
+    ENVOY_STREAM_LOG(warn, "Illegal Scheme", *callbacks_);
+    config_.stats_.passthrough_internal_redirect_unsafe_scheme_.inc();
+    return false;
+  }
+
+  const StreamInfo::FilterStateSharedPtr& filter_state = callbacks_->streamInfo().filterState();
+  // Make sure that performing the redirect won't result in exceeding the configured number of
+  // redirects allowed for this route.
+  if (!filter_state->hasData<StreamInfo::UInt32Accessor>(NumInternalRedirectsFilterStateName)) {
+    filter_state->setData(
+        NumInternalRedirectsFilterStateName, std::make_shared<StreamInfo::UInt32AccessorImpl>(0),
+        StreamInfo::FilterState::StateType::Mutable, StreamInfo::FilterState::LifeSpan::Request);
+  }
+  StreamInfo::UInt32Accessor& num_internal_redirect =
+      filter_state->getDataMutable<StreamInfo::UInt32Accessor>(NumInternalRedirectsFilterStateName);
+  if (num_internal_redirect.value() >= policy.maxInternalRedirects()) {
+    ENVOY_STREAM_LOG(warn, "Redirection times exceeded maximum {}", *callbacks_,
+                     policy.maxInternalRedirects());
+    config_.stats_.passthrough_internal_redirect_too_many_redirects_.inc();
+    return false;
+  }
+  // Copy the old values, so they can be restored if the redirect fails.
+  const std::string original_host(downstream_headers.getHostValue());
+  const std::string original_path(downstream_headers.getPathValue());
+  const bool scheme_is_set = (downstream_headers.Scheme() != nullptr);
+  Cleanup restore_original_headers(
+      [&downstream_headers, original_host, original_path, scheme_is_set, scheme_is_http]() {
+        downstream_headers.setHost(original_host);
+        downstream_headers.setPath(original_path);
+        if (scheme_is_set) {
+          downstream_headers.setScheme(scheme_is_http ? Http::Headers::get().SchemeValues.Http
+                                                      : Http::Headers::get().SchemeValues.Https);
+        }
+      });
+
+  // Replace the original scheme and path.
+  downstream_headers.setScheme(absolute_url.scheme());
+  downstream_headers.setPath(absolute_url.pathAndQueryParams());
+
+  if (!policy.forcedUseOriginalHost()) {
+    // Replace the original host.
+    ENVOY_STREAM_LOG(info, "Replace the original host", *callbacks_);
+    downstream_headers.setHost(absolute_url.hostAndPort());
+  }
+
+  if (policy.forcedAddHeaderBeforeRouteMatcher()) {
+    policy.evaluateHeaders(downstream_headers, nullptr);
+  }
+
+  callbacks_->clearRouteCache();
+  const auto route = callbacks_->route();
+  // Don't allow a redirect to a non existing route.
+  if (!route) {
+    config_.stats_.passthrough_internal_redirect_no_route_.inc();
+    ENVOY_STREAM_LOG(warn, "The internal redirect no route", *callbacks_);
+    return false;
+  }
+
+  const auto& route_name = route->directResponseEntry() ? route->directResponseEntry()->routeName()
+                                                        : route->routeEntry()->routeName();
+  for (const auto& predicate : policy.predicates()) {
+    if (!predicate->acceptTargetRoute(*filter_state, route_name, !scheme_is_http,
+                                      !target_is_http)) {
+      config_.stats_.passthrough_internal_redirect_predicate_.inc();
+      ENVOY_STREAM_LOG(warn, "rejecting redirect targeting {}, by {} predicate", *callbacks_,
+                       route_name, predicate->name());
+      return false;
+    }
+  }
+
+  if (!policy.forcedAddHeaderBeforeRouteMatcher()) {
+    policy.evaluateHeaders(downstream_headers, nullptr);
+  }
+
+  num_internal_redirect.increment();
+  restore_original_headers.cancel();
+  // Preserve the original request URL for the second pass.
+  downstream_headers.setEnvoyOriginalUrl(absl::StrCat(scheme_is_http
+                                                          ? Http::Headers::get().SchemeValues.Http
+                                                          : Http::Headers::get().SchemeValues.Https,
+                                                      "://", original_host, original_path));
+  return true;
+}
+#endif
 void Filter::runRetryOptionsPredicates(UpstreamRequest& retriable_request) {
   for (const auto& options_predicate : route_entry_->retryPolicy().retryOptionsPredicates()) {
     const Upstream::RetryOptionsPredicate::UpdateOptionsParameters parameters{
@@ -1719,15 +1991,14 @@ uint32_t Filter::numRequestsAwaitingHeaders() {
                        [](const auto& req) -> bool { return req->awaitingHeaders(); });
 }
 
-RetryStatePtr ProdFilter::createRetryState(const RetryPolicy& policy,
-                                           Http::RequestHeaderMap& request_headers,
-                                           const Upstream::ClusterInfo& cluster,
-                                           const VirtualCluster* vcluster, Runtime::Loader& runtime,
-                                           Random::RandomGenerator& random,
-                                           Event::Dispatcher& dispatcher, TimeSource& time_source,
-                                           Upstream::ResourcePriority priority) {
-  return RetryStateImpl::create(policy, request_headers, cluster, vcluster, runtime, random,
-                                dispatcher, time_source, priority);
+RetryStatePtr
+ProdFilter::createRetryState(const RetryPolicy& policy, Http::RequestHeaderMap& request_headers,
+                             const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
+                             RouteStatsContextOptRef route_stats_context, Runtime::Loader& runtime,
+                             Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
+                             TimeSource& time_source, Upstream::ResourcePriority priority) {
+  return RetryStateImpl::create(policy, request_headers, cluster, vcluster, route_stats_context, 
+                             runtime, random, dispatcher, time_source, priority);
 }
 
 } // namespace Router
diff --git a/source/common/router/router.h b/source/common/router/router.h
index e9d0234aed..92425f23e1 100644
--- a/source/common/router/router.h
+++ b/source/common/router/router.h
@@ -35,6 +35,10 @@
 #include "source/common/stream_info/stream_info_impl.h"
 #include "source/common/upstream/load_balancer_impl.h"
 
+#if defined(ALIMESH)
+#include "envoy/stats/timespan.h"
+#endif
+
 namespace Envoy {
 namespace Router {
 
@@ -188,8 +192,8 @@ public:
                const Protobuf::RepeatedPtrField<std::string>& strict_check_headers,
                TimeSource& time_source, Http::Context& http_context,
                Router::Context& router_context)
-      : scope_(scope), local_info_(local_info), cm_(cm), runtime_(runtime), random_(random),
-        stats_(router_context.statNames(), scope, stat_prefix),
+      : router_context_(router_context), scope_(scope), local_info_(local_info), cm_(cm),
+        runtime_(runtime), random_(random), stats_(router_context_.statNames(), scope, stat_prefix),
         emit_dynamic_stats_(emit_dynamic_stats), start_child_span_(start_child_span),
         suppress_envoy_headers_(suppress_envoy_headers),
         respect_expected_rq_timeout_(respect_expected_rq_timeout),
@@ -224,6 +228,7 @@ public:
   ShadowWriter& shadowWriter() { return *shadow_writer_; }
   TimeSource& timeSource() { return time_source_; }
 
+  Router::Context& router_context_;
   Stats::Scope& scope_;
   const LocalInfo::LocalInfo& local_info_;
   Upstream::ClusterManager& cm_;
@@ -286,7 +291,8 @@ public:
   virtual bool downstreamEndStream() const PURE;
   virtual uint32_t attemptCount() const PURE;
   virtual const VirtualCluster* requestVcluster() const PURE;
-  virtual const RouteEntry* routeEntry() const PURE;
+  virtual const RouteStatsContextOptRef routeStatsContext() const PURE;
+  virtual const Route* route() const PURE;
   virtual const std::list<UpstreamRequestPtr>& upstreamRequests() const PURE;
   virtual const UpstreamRequest* finalUpstreamRequest() const PURE;
   virtual TimeSource& timeSource() PURE;
@@ -462,7 +468,8 @@ public:
   bool downstreamEndStream() const override { return downstream_end_stream_; }
   uint32_t attemptCount() const override { return attempt_count_; }
   const VirtualCluster* requestVcluster() const override { return request_vcluster_; }
-  const RouteEntry* routeEntry() const override { return route_entry_; }
+  const RouteStatsContextOptRef routeStatsContext() const override { return route_stats_context_; }
+  const Route* route() const override { return route_.get(); }
   const std::list<UpstreamRequestPtr>& upstreamRequests() const override {
     return upstream_requests_;
   }
@@ -475,6 +482,11 @@ private:
   void onPerTryTimeoutCommon(UpstreamRequest& upstream_request, Stats::Counter& error_counter,
                              const std::string& response_code_details);
   Stats::StatName upstreamZone(Upstream::HostDescriptionConstSharedPtr upstream_host);
+#if defined(ALIMESH)
+  void chargeUpstreamGrpcCode(uint64_t http_status_code, uint64_t grpc_response_code,
+                              const Http::ResponseHeaderMap& response_headers,
+                              Upstream::HostDescriptionConstSharedPtr upstream_host, bool dropped);
+#endif
   void chargeUpstreamCode(uint64_t response_status_code,
                           const Http::ResponseHeaderMap& response_headers,
                           Upstream::HostDescriptionConstSharedPtr upstream_host, bool dropped);
@@ -482,13 +494,12 @@ private:
                           bool dropped);
   void chargeUpstreamAbort(Http::Code code, bool dropped, UpstreamRequest& upstream_request);
   void cleanup();
-  virtual RetryStatePtr createRetryState(const RetryPolicy& policy,
-                                         Http::RequestHeaderMap& request_headers,
-                                         const Upstream::ClusterInfo& cluster,
-                                         const VirtualCluster* vcluster, Runtime::Loader& runtime,
-                                         Random::RandomGenerator& random,
-                                         Event::Dispatcher& dispatcher, TimeSource& time_source,
-                                         Upstream::ResourcePriority priority) PURE;
+  virtual RetryStatePtr
+  createRetryState(const RetryPolicy& policy, Http::RequestHeaderMap& request_headers,
+                   const Upstream::ClusterInfo& cluster, const VirtualCluster* vcluster,
+                   RouteStatsContextOptRef route_stats_context, Runtime::Loader& runtime,
+                   Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
+                   TimeSource& time_source, Upstream::ResourcePriority priority) PURE;
 
   std::unique_ptr<GenericConnPool>
   createConnPool(Upstream::ThreadLocalCluster& thread_local_cluster);
@@ -532,6 +543,12 @@ private:
                                    uint64_t grpc_to_http_status);
   Http::Context& httpContext() { return config_.http_context_; }
 
+#if defined(ALIMESH)
+  bool setupActiveRedirect(const Http::ResponseHeaderMap& headers,
+                           UpstreamRequest& upstream_request);
+  bool convertRequestHeadersForInternalActiveRedirect(Http::RequestHeaderMap& downstream_headers);
+#endif
+
   RetryStatePtr retry_state_;
   FilterConfig& config_;
   Http::StreamDecoderFilterCallbacks* callbacks_{};
@@ -540,6 +557,7 @@ private:
   Upstream::ClusterInfoConstSharedPtr cluster_;
   std::unique_ptr<Stats::StatNameDynamicStorage> alt_stat_prefix_;
   const VirtualCluster* request_vcluster_;
+  RouteStatsContextOptRef route_stats_context_;
   Event::TimerPtr response_timeout_;
   FilterUtility::TimeoutData timeout_;
   FilterUtility::HedgingParams hedging_params_;
@@ -584,9 +602,10 @@ private:
   // Filter
   RetryStatePtr createRetryState(const RetryPolicy& policy, Http::RequestHeaderMap& request_headers,
                                  const Upstream::ClusterInfo& cluster,
-                                 const VirtualCluster* vcluster, Runtime::Loader& runtime,
-                                 Random::RandomGenerator& random, Event::Dispatcher& dispatcher,
-                                 TimeSource& time_source,
+                                 const VirtualCluster* vcluster,
+                                 RouteStatsContextOptRef route_stats_context,
+                                 Runtime::Loader& runtime, Random::RandomGenerator& random,
+                                 Event::Dispatcher& dispatcher, TimeSource& time_source,
                                  Upstream::ResourcePriority priority) override;
 };
 
diff --git a/source/common/router/upstream_request.cc b/source/common/router/upstream_request.cc
index 147f7af49f..80792d9a81 100644
--- a/source/common/router/upstream_request.cc
+++ b/source/common/router/upstream_request.cc
@@ -207,7 +207,7 @@ void UpstreamRequest::dumpState(std::ostream& os, int indent_level) const {
   DUMP_DETAILS(request_headers);
 }
 
-const RouteEntry& UpstreamRequest::routeEntry() const { return *parent_.routeEntry(); }
+const Route& UpstreamRequest::route() const { return *parent_.route(); }
 
 const Network::Connection& UpstreamRequest::connection() const {
   return *parent_.callbacks()->connection();
@@ -425,6 +425,12 @@ void UpstreamRequest::onPoolReady(
     // here.
     parent_.requestVcluster()->stats().upstream_rq_total_.inc();
   }
+  if (parent_.routeStatsContext().has_value()) {
+    // The cluster increases its upstream_rq_total_ counter right before firing this onPoolReady
+    // callback. Hence, the upstream request increases the route level upstream_rq_total_ stat
+    // here.
+    parent_.routeStatsContext()->stats().upstream_rq_total_.inc();
+  }
 
   host->outlierDetector().putResult(Upstream::Outlier::Result::LocalOriginConnectSuccess);
 
@@ -465,12 +471,23 @@ void UpstreamRequest::onPoolReady(
 
   calling_encode_headers_ = true;
   auto* headers = parent_.downstreamHeaders();
-  if (parent_.routeEntry()->autoHostRewrite() && !host->hostname().empty()) {
-    parent_.downstreamHeaders()->setHost(host->hostname());
+  const auto* route_entry = parent_.route()->routeEntry();
+  if (route_entry->autoHostRewrite() && !host->hostname().empty()) {
+    Http::Utility::updateAuthority(*parent_.downstreamHeaders(), host->hostname(),
+                                   route_entry->appendXfh());
   }
 
   if (span_ != nullptr) {
     span_->injectContext(*parent_.downstreamHeaders());
+
+#if defined(ALIMESH)
+    const std::string& address = host->address()->ip()->addressAsString();
+    if (host->address()->ip()->version() == Network::Address::IpVersion::v6) {
+      span_->setTag(Tracing::Tags::get().PeerIpv6, address);
+    } else {
+      span_->setTag(Tracing::Tags::get().PeerIpv4, address);
+    }
+#endif
   }
 
   upstream_timing_.onFirstUpstreamTxByteSent(parent_.callbacks()->dispatcher().timeSource());
diff --git a/source/common/router/upstream_request.h b/source/common/router/upstream_request.h
index 98f214c0d2..bd033f8084 100644
--- a/source/common/router/upstream_request.h
+++ b/source/common/router/upstream_request.h
@@ -65,7 +65,7 @@ public:
   void onAboveWriteBufferHighWatermark() override { disableDataFromDownstreamForFlowControl(); }
   void onBelowWriteBufferLowWatermark() override { enableDataFromDownstreamForFlowControl(); }
   // UpstreamToDownstream
-  const RouteEntry& routeEntry() const override;
+  const Route& route() const override;
   const Network::Connection& connection() const override;
 
   void disableDataFromDownstreamForFlowControl();
diff --git a/source/common/runtime/runtime_features.cc b/source/common/runtime/runtime_features.cc
index 945a5ff122..81ee0d4d95 100644
--- a/source/common/runtime/runtime_features.cc
+++ b/source/common/runtime/runtime_features.cc
@@ -90,6 +90,7 @@ constexpr const char* runtime_features[] = {
     "envoy.reloadable_features.strip_port_from_connect",
     "envoy.reloadable_features.treat_host_like_authority",
     "envoy.reloadable_features.treat_upstream_connect_timeout_as_connect_failure",
+    "envoy.reloadable_features.skip_delay_close",
     "envoy.reloadable_features.udp_listener_updates_filter_chain_in_place",
     "envoy.reloadable_features.udp_per_event_loop_read_limit",
     "envoy.reloadable_features.unquote_log_string_values",
diff --git a/source/common/stream_info/stream_info_impl.h b/source/common/stream_info/stream_info_impl.h
index 5abd0c7261..6ce2afe773 100644
--- a/source/common/stream_info/stream_info_impl.h
+++ b/source/common/stream_info/stream_info_impl.h
@@ -187,6 +187,14 @@ struct StreamInfoImpl : public StreamInfo {
 
   const std::string& getRouteName() const override { return route_name_; }
 
+  void setVirtualClusterName(const absl::optional<std::string>& virtual_cluster_name) override {
+    virtual_cluster_name_ = virtual_cluster_name;
+  }
+
+  const absl::optional<std::string>& virtualClusterName() const override {
+    return virtual_cluster_name_;
+  }
+
   void setUpstreamLocalAddress(
       const Network::Address::InstanceConstSharedPtr& upstream_local_address) override {
     upstream_local_address_ = upstream_local_address;
@@ -306,6 +314,9 @@ struct StreamInfoImpl : public StreamInfo {
   std::string route_name_;
   absl::optional<uint64_t> upstream_connection_id_;
   absl::optional<uint32_t> attempt_count_;
+  // TODO(agrawroh): Check if the owner of this storage outlives the StreamInfo. We should only copy
+  // the string if it could outlive the StreamInfo.
+  absl::optional<std::string> virtual_cluster_name_;
 
 private:
   static Network::ConnectionInfoProviderSharedPtr emptyDownstreamAddressProvider() {
diff --git a/source/common/thread_local/thread_local_impl.h b/source/common/thread_local/thread_local_impl.h
index 26c08dfce3..69b159bea3 100644
--- a/source/common/thread_local/thread_local_impl.h
+++ b/source/common/thread_local/thread_local_impl.h
@@ -47,6 +47,7 @@ private:
     void runOnAllThreads(const UpdateCb& cb, const Event::PostCb& complete_cb) override;
     bool currentThreadRegistered() override;
     void set(InitializeCb cb) override;
+    bool isShutdown() const override { return parent_.shutdown_; }
 
     InstanceImpl& parent_;
     const uint32_t index_;
diff --git a/source/common/tracing/http_tracer_impl.cc b/source/common/tracing/http_tracer_impl.cc
index 84e7168a68..e55cf00e0a 100644
--- a/source/common/tracing/http_tracer_impl.cc
+++ b/source/common/tracing/http_tracer_impl.cc
@@ -277,6 +277,17 @@ SpanPtr HttpTracerImpl::startSpan(const Config& config, Http::RequestHeaderMap&
   if (active_span) {
     active_span->setTag(Tracing::Tags::get().NodeId, local_info_.nodeName());
     active_span->setTag(Tracing::Tags::get().Zone, local_info_.zoneName());
+
+#if defined(ALIMESH)
+    const std::string& remote_address =
+        stream_info.downstreamAddressProvider().localAddress()->ip()->addressAsString();
+    if (stream_info.downstreamAddressProvider().localAddress()->ip()->version() ==
+        Network::Address::IpVersion::v6) {
+      active_span->setTag(Tracing::Tags::get().PeerIpv6, remote_address);
+    } else {
+      active_span->setTag(Tracing::Tags::get().PeerIpv4, remote_address);
+    }
+#endif
   }
 
   return active_span;
diff --git a/source/common/upstream/health_checker_impl.cc b/source/common/upstream/health_checker_impl.cc
index 09d8ebeca4..998e4c2ef5 100644
--- a/source/common/upstream/health_checker_impl.cc
+++ b/source/common/upstream/health_checker_impl.cc
@@ -546,7 +546,18 @@ void TcpHealthCheckerImpl::TcpActiveHealthCheckSession::onInterval() {
     client_->addReadFilter(session_callbacks_);
 
     expect_close_ = false;
+#if defined(ALIMESH)
+    try {
+      client_->connect();
+    } catch (const EnvoyException& ex) {
+      ENVOY_CONN_LOG(critical,
+                     "envoy exception raised in TcpActiveHealthCheckSession::onInterval(): {}",
+                     *client_, ex.what());
+      return;
+    }
+#else
     client_->connect();
+#endif
     client_->noDelay(true);
   }
 
diff --git a/source/common/upstream/outlier_detection_impl.cc b/source/common/upstream/outlier_detection_impl.cc
index bbf52ae4bc..183e6ab223 100644
--- a/source/common/upstream/outlier_detection_impl.cc
+++ b/source/common/upstream/outlier_detection_impl.cc
@@ -64,6 +64,17 @@ void DetectorHostMonitorImpl::updateCurrentSuccessRateBucket() {
   local_origin_sr_monitor_.updateCurrentSuccessRateBucket();
 }
 
+#if defined(ALIMESH)
+void DetectorHostMonitorImpl::forceEjectHost() {
+  std::shared_ptr<DetectorImpl> detector = detector_.lock();
+  if (!detector) {
+    // It's possible for the cluster/detector to go away while we still have a host in use.
+    return;
+  }
+  detector->onConsecutive5xx(host_.lock());
+}
+#endif
+
 void DetectorHostMonitorImpl::putHttpResponseCode(uint64_t response_code) {
   external_origin_sr_monitor_.incTotalReqCounter();
   if (Http::CodeUtility::is5xx(response_code)) {
diff --git a/source/common/upstream/outlier_detection_impl.h b/source/common/upstream/outlier_detection_impl.h
index 76fd2efe1a..caee2050be 100644
--- a/source/common/upstream/outlier_detection_impl.h
+++ b/source/common/upstream/outlier_detection_impl.h
@@ -42,6 +42,10 @@ public:
   const absl::optional<MonotonicTime>& lastUnejectionTime() override { return time_; }
   double successRate(SuccessRateMonitorType) const override { return -1; }
 
+#if defined(ALIMESH)
+  void forceEjectHost() override {}
+#endif
+
 private:
   const absl::optional<MonotonicTime> time_{};
 };
@@ -183,6 +187,10 @@ public:
   void localOriginFailure();
   void localOriginNoFailure();
 
+#if defined(ALIMESH)
+  void forceEjectHost() override;
+#endif
+
 private:
   std::weak_ptr<DetectorImpl> detector_;
   std::weak_ptr<Host> host_;
diff --git a/source/common/upstream/upstream_impl.cc b/source/common/upstream/upstream_impl.cc
index ab0e0c76a4..438001bb7d 100644
--- a/source/common/upstream/upstream_impl.cc
+++ b/source/common/upstream/upstream_impl.cc
@@ -805,6 +805,7 @@ ClusterInfoImpl::ClusterInfoImpl(
                          factory_context.clusterManager().clusterCircuitBreakersStatNames()),
       maintenance_mode_runtime_key_(absl::StrCat("upstream.maintenance_mode.", name_)),
       source_address_(getSourceAddress(config, bind_config)),
+      lb_round_robin_config_(config.round_robin_lb_config()),
       lb_least_request_config_(config.least_request_lb_config()),
       lb_ring_hash_config_(config.ring_hash_lb_config()),
       lb_maglev_config_(config.maglev_lb_config()),
diff --git a/source/exe/BUILD b/source/exe/BUILD
index f3fb551eb8..e4cef50276 100644
--- a/source/exe/BUILD
+++ b/source/exe/BUILD
@@ -9,7 +9,7 @@ load(
     "envoy_package",
 )
 load("//source/extensions:all_extensions.bzl", "envoy_all_core_extensions", "envoy_all_extensions")
-load("//bazel:repositories.bzl", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
+load("//bazel:repositories.bzl", "DARWIN_SKIP_TARGETS", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
 
 licenses(["notice"])  # Apache 2
 
@@ -40,6 +40,7 @@ envoy_cc_library(
     ] + select({
         "//bazel:windows_x86_64": envoy_all_extensions(WINDOWS_SKIP_TARGETS),
         "//bazel:linux_ppc": envoy_all_extensions(PPC_SKIP_TARGETS),
+        "//bazel:darwin": envoy_all_extensions(DARWIN_SKIP_TARGETS),
         "//conditions:default": envoy_all_extensions(),
     }),
 )
diff --git a/source/extensions/common/wasm/context.cc b/source/extensions/common/wasm/context.cc
index 07447110f2..9279360508 100644
--- a/source/extensions/common/wasm/context.cc
+++ b/source/extensions/common/wasm/context.cc
@@ -433,6 +433,12 @@ Context::findValue(absl::string_view name, Protobuf::Arena* arena, bool last) co
   using google::api::expr::runtime::CelProtoWrapper;
   using google::api::expr::runtime::CelValue;
 
+#if defined(ALIMESH)
+  Envoy::Http::StreamFilterCallbacks* filter_callbacks = decoder_callbacks_;
+  if (filter_callbacks == nullptr) {
+    filter_callbacks = encoder_callbacks_;
+  }
+#endif
   const StreamInfo::StreamInfo* info = getConstRequestStreamInfo();
 
   // Convert into a dense token to enable a jump table implementation.
@@ -546,6 +552,21 @@ Context::findValue(absl::string_view name, Protobuf::Arena* arena, bool last) co
     }
     break;
   case PropertyToken::ROUTE_NAME:
+#if defined(ALIMESH)
+    if (filter_callbacks) {
+      auto route = filter_callbacks->route();
+      if (route) {
+        auto route_entry = route->routeEntry();
+        if (route_entry) {
+          return CelValue::CreateString(&route_entry->routeName());
+        }
+        auto dr_entry = route->directResponseEntry();
+        if (dr_entry) {
+          return CelValue::CreateString(&dr_entry->routeName());
+        }
+      }
+    }
+#endif
     if (info) {
       return CelValue::CreateString(&info->getRouteName());
     }
diff --git a/source/extensions/extensions_build_config.bzl b/source/extensions/extensions_build_config.bzl
index 7e220b0a4a..b52ab543bb 100644
--- a/source/extensions/extensions_build_config.bzl
+++ b/source/extensions/extensions_build_config.bzl
@@ -184,6 +184,8 @@ EXTENSIONS = {
     "envoy.tracers.datadog":                            "//source/extensions/tracers/datadog:config",
     "envoy.tracers.zipkin":                             "//source/extensions/tracers/zipkin:config",
     "envoy.tracers.opencensus":                         "//source/extensions/tracers/opencensus:config",
+
+    # WiP
     "envoy.tracers.xray":                               "//source/extensions/tracers/xray:config",
     "envoy.tracers.skywalking":                         "//source/extensions/tracers/skywalking:config",
 
diff --git a/source/extensions/extensions_metadata.yaml b/source/extensions/extensions_metadata.yaml
index d8cec006bd..d57e869c1c 100644
--- a/source/extensions/extensions_metadata.yaml
+++ b/source/extensions/extensions_metadata.yaml
@@ -594,6 +594,11 @@ envoy.tracers.opencensus:
   - envoy.tracers
   security_posture: robust_to_untrusted_downstream
   status: stable
+envoy.tracers.opentelemetry:
+  categories:
+  - envoy.tracers
+  security_posture: unknown
+  status: wip
 envoy.tracers.skywalking:
   categories:
   - envoy.tracers
diff --git a/source/extensions/filters/common/ext_authz/ext_authz.h b/source/extensions/filters/common/ext_authz/ext_authz.h
index 96545dd83a..5792ed1596 100644
--- a/source/extensions/filters/common/ext_authz/ext_authz.h
+++ b/source/extensions/filters/common/ext_authz/ext_authz.h
@@ -43,6 +43,10 @@ public:
   const Http::LowerCaseString EnvoyAuthPartialBody{absl::StrCat(prefix(), "-auth-partial-body")};
   const Http::LowerCaseString EnvoyAuthHeadersToRemove{
       absl::StrCat(prefix(), "-auth-headers-to-remove")};
+
+#if defined(ALIMESH)
+  const Http::LowerCaseString XMseExternalAuthzCheckResult{"x-mse-external-authz-check-result"};
+#endif
 };
 
 using Headers = ConstSingleton<HeaderValues>;
diff --git a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc
index 3cf233d661..e515d6f103 100644
--- a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc
+++ b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.cc
@@ -8,6 +8,7 @@
 #include "source/common/common/enum_to_int.h"
 #include "source/common/common/fmt.h"
 #include "source/common/common/matchers.h"
+#include "source/common/common/utility.h"
 #include "source/common/http/async_client_impl.h"
 #include "source/common/http/codes.h"
 #include "source/common/runtime/runtime_features.h"
@@ -308,6 +309,26 @@ void RawHttpClientImpl::onBeforeFinalizeUpstreamSpan(
   }
 }
 
+#if defined(ALIMESH)
+bool isAuthorizationPass(const Http::ResponseHeaderMap& headers) {
+  const uint64_t status_code = Http::Utility::getResponseStatus(headers);
+
+  // The HTTP status code is first condition.
+  if (status_code != enumToInt(Http::Code::OK)) {
+    return false;
+  }
+
+  const auto& get_result = headers.get(Headers::get().XMseExternalAuthzCheckResult);
+  // If x-mse-external-authz-check-result doesn't exist or has more than one value,
+  // we think this case is allowed.
+  if (get_result.size() != 1) {
+    return true;
+  }
+
+  return absl::EqualsIgnoreCase(StringUtil::trim(get_result[0]->value().getStringView()), "true");
+}
+#endif
+
 ResponsePtr RawHttpClientImpl::toResponse(Http::ResponseMessagePtr message) {
   const uint64_t status_code = Http::Utility::getResponseStatus(message->headers());
 
@@ -344,7 +365,11 @@ ResponsePtr RawHttpClientImpl::toResponse(Http::ResponseMessagePtr message) {
   message->headers().remove(storage_header_name);
 
   // Create an Ok authorization response.
+#if !defined(ALIMESH)
   if (status_code == enumToInt(Http::Code::OK)) {
+#else
+  if (isAuthorizationPass(message->headers())) {
+#endif
     SuccessResponse ok{message->headers(),
                        config_->upstreamHeaderMatchers(),
                        config_->upstreamHeaderToAppendMatchers(),
diff --git a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h
index a517bef948..c485e68d1c 100644
--- a/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h
+++ b/source/extensions/filters/common/ext_authz/ext_authz_http_impl.h
@@ -155,6 +155,10 @@ private:
 
 using ClientConfigSharedPtr = std::shared_ptr<ClientConfig>;
 
+#if defined(ALIMESH)
+bool isAuthorizationPass(const Http::ResponseHeaderMap& headers);
+#endif
+
 /**
  * This client implementation is used when the Ext_Authz filter needs to communicate with an
  * HTTP authorization server. Unlike the gRPC client that allows the server to define the
diff --git a/source/extensions/filters/http/cors/cors_filter.cc b/source/extensions/filters/http/cors/cors_filter.cc
index c7314a437a..1f260c3392 100644
--- a/source/extensions/filters/http/cors/cors_filter.cc
+++ b/source/extensions/filters/http/cors/cors_filter.cc
@@ -19,6 +19,8 @@ struct HttpResponseCodeDetailValues {
 };
 using HttpResponseCodeDetails = ConstSingleton<HttpResponseCodeDetailValues>;
 
+Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
+    access_control_request_headers_handle(Http::CustomHeaders::get().AccessControlRequestHeaders);
 Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
     access_control_request_method_handle(Http::CustomHeaders::get().AccessControlRequestMethod);
 Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::RequestHeaders>
@@ -97,12 +99,26 @@ Http::FilterHeadersStatus CorsFilter::decodeHeaders(Http::RequestHeaderMap& head
                                          Http::CustomHeaders::get().CORSValues.True);
   }
 
-  if (!allowMethods().empty()) {
-    response_headers->setInline(access_control_allow_methods_handle.handle(), allowMethods());
+  const absl::string_view allow_methods = allowMethods();
+  if (!allow_methods.empty()) {
+    if (allow_methods == "*") {
+      response_headers->setInline(
+          access_control_allow_methods_handle.handle(),
+          headers.getInlineValue(access_control_request_method_handle.handle()));
+    } else {
+      response_headers->setInline(access_control_allow_methods_handle.handle(), allow_methods);
+    }
   }
 
-  if (!allowHeaders().empty()) {
-    response_headers->setInline(access_control_allow_headers_handle.handle(), allowHeaders());
+  const absl::string_view allow_headers = allowHeaders();
+  if (!allow_headers.empty()) {
+    if (allow_headers == "*") {
+      response_headers->setInline(
+          access_control_allow_headers_handle.handle(),
+          headers.getInlineValue(access_control_request_headers_handle.handle()));
+    } else {
+      response_headers->setInline(access_control_allow_headers_handle.handle(), allow_headers);
+    }
   }
 
   if (!maxAge().empty()) {
diff --git a/source/extensions/filters/http/ext_authz/ext_authz.cc b/source/extensions/filters/http/ext_authz/ext_authz.cc
index 90df75ee27..cd4ee8923f 100644
--- a/source/extensions/filters/http/ext_authz/ext_authz.cc
+++ b/source/extensions/filters/http/ext_authz/ext_authz.cc
@@ -311,6 +311,7 @@ void Filter::onComplete(Filters::Common::ExtAuthz::ResponsePtr&& response) {
                                              empty_stat_name,
                                              empty_stat_name,
                                              empty_stat_name,
+                                             empty_stat_name,
                                              false};
       config_->httpContext().codeStats().chargeResponseStat(info, false);
     }
diff --git a/source/extensions/filters/http/ratelimit/ratelimit.cc b/source/extensions/filters/http/ratelimit/ratelimit.cc
index c007471d77..5d3e19fdf4 100644
--- a/source/extensions/filters/http/ratelimit/ratelimit.cc
+++ b/source/extensions/filters/http/ratelimit/ratelimit.cc
@@ -174,6 +174,7 @@ void Filter::complete(Filters::Common::RateLimit::LimitStatus status,
                                            empty_stat_name,
                                            empty_stat_name,
                                            empty_stat_name,
+                                           empty_stat_name,
                                            false};
     httpContext().codeStats().chargeResponseStat(info, false);
     if (config_->enableXEnvoyRateLimitedHeader()) {
diff --git a/source/extensions/filters/http/wasm/wasm_filter.h b/source/extensions/filters/http/wasm/wasm_filter.h
index 8032153dd1..a01b86a9db 100644
--- a/source/extensions/filters/http/wasm/wasm_filter.h
+++ b/source/extensions/filters/http/wasm/wasm_filter.h
@@ -28,7 +28,13 @@ public:
 
   std::shared_ptr<Context> createFilter() {
     Wasm* wasm = nullptr;
+    if (!tls_slot_->currentThreadRegistered()) {
+      return nullptr;
+    }
     PluginHandleSharedPtr handle = tls_slot_->get()->handle();
+    if (!handle) {
+      return nullptr;
+    }
     if (handle->wasmHandle()) {
       wasm = handle->wasmHandle()->wasm().get();
     }
diff --git a/source/extensions/filters/network/http_connection_manager/config.h b/source/extensions/filters/network/http_connection_manager/config.h
index e480599fef..3464659a14 100644
--- a/source/extensions/filters/network/http_connection_manager/config.h
+++ b/source/extensions/filters/network/http_connection_manager/config.h
@@ -39,7 +39,7 @@ namespace Extensions {
 namespace NetworkFilters {
 namespace HttpConnectionManager {
 
-using FilterConfigProviderManager = Filter::FilterConfigProviderManager;
+using FilterConfigProviderManager = Filter::FilterConfigProviderManager<Http::FilterFactoryCb>;
 
 /**
  * Config registration for the HTTP connection manager filter. @see NamedNetworkFilterConfigFactory.
@@ -125,7 +125,7 @@ public:
 
   // Http::FilterChainFactory
   void createFilterChain(Http::FilterChainFactoryCallbacks& callbacks) override;
-  using FilterFactoriesList = std::list<Filter::FilterConfigProviderPtr>;
+  using FilterFactoriesList = std::list<Filter::FilterConfigProviderPtr<Http::FilterFactoryCb>>;
   struct FilterConfig {
     std::unique_ptr<FilterFactoriesList> filter_factories;
     bool allow_upgrade;
diff --git a/source/extensions/tracers/common/BUILD b/source/extensions/tracers/common/BUILD
index 89e447c456..d7610929c7 100644
--- a/source/extensions/tracers/common/BUILD
+++ b/source/extensions/tracers/common/BUILD
@@ -11,6 +11,7 @@ envoy_extension_package()
 envoy_cc_library(
     name = "factory_base_lib",
     hdrs = ["factory_base.h"],
+    visibility = ["//visibility:public"],
     deps = [
         "//envoy/server:tracer_config_interface",
         "//source/common/config:utility_lib",
diff --git a/source/extensions/tracers/skywalking/skywalking_stats.h b/source/extensions/tracers/skywalking/skywalking_stats.h
index 9646299eb6..1517cc1622 100644
--- a/source/extensions/tracers/skywalking/skywalking_stats.h
+++ b/source/extensions/tracers/skywalking/skywalking_stats.h
@@ -17,6 +17,8 @@ struct SkyWalkingTracerStats {
   SKYWALKING_TRACER_STATS(GENERATE_COUNTER_STRUCT)
 };
 
+using SkyWalkingTracerStatsSharedPtr = std::shared_ptr<SkyWalkingTracerStats>;
+
 } // namespace SkyWalking
 } // namespace Tracers
 } // namespace Extensions
diff --git a/source/extensions/tracers/skywalking/skywalking_tracer_impl.cc b/source/extensions/tracers/skywalking/skywalking_tracer_impl.cc
index 81489fc2ff..2f3c8432b9 100644
--- a/source/extensions/tracers/skywalking/skywalking_tracer_impl.cc
+++ b/source/extensions/tracers/skywalking/skywalking_tracer_impl.cc
@@ -28,8 +28,9 @@ using cpp2sky::TracerException;
 
 Driver::Driver(const envoy::config::trace::v3::SkyWalkingConfig& proto_config,
                Server::Configuration::TracerFactoryContext& context)
-    : tracing_stats_{SKYWALKING_TRACER_STATS(
-          POOL_COUNTER_PREFIX(context.serverFactoryContext().scope(), "tracing.skywalking."))},
+    : tracing_stats_(std::make_shared<SkyWalkingTracerStats>(
+          SkyWalkingTracerStats{SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(
+              context.serverFactoryContext().scope(), "tracing.skywalking."))})),
       tls_slot_ptr_(context.serverFactoryContext().threadLocal().allocateSlot()) {
   loadConfig(proto_config.client_config(), context.serverFactoryContext());
   tracing_context_factory_ = std::make_unique<TracingContextFactory>(config_);
diff --git a/source/extensions/tracers/skywalking/skywalking_tracer_impl.h b/source/extensions/tracers/skywalking/skywalking_tracer_impl.h
index 433c92706e..58849667b1 100644
--- a/source/extensions/tracers/skywalking/skywalking_tracer_impl.h
+++ b/source/extensions/tracers/skywalking/skywalking_tracer_impl.h
@@ -43,7 +43,7 @@ private:
   };
 
   TracerConfig config_;
-  SkyWalkingTracerStats tracing_stats_;
+  SkyWalkingTracerStatsSharedPtr tracing_stats_;
   ThreadLocal::SlotPtr tls_slot_ptr_;
   std::unique_ptr<TracingContextFactory> tracing_context_factory_;
 };
diff --git a/source/extensions/tracers/skywalking/trace_segment_reporter.cc b/source/extensions/tracers/skywalking/trace_segment_reporter.cc
index c3ecda817d..fe3a5cb45b 100644
--- a/source/extensions/tracers/skywalking/trace_segment_reporter.cc
+++ b/source/extensions/tracers/skywalking/trace_segment_reporter.cc
@@ -17,7 +17,7 @@ Http::RegisterCustomInlineHeader<Http::CustomInlineHeaderRegistry::Type::Request
 TraceSegmentReporter::TraceSegmentReporter(Grpc::AsyncClientFactoryPtr&& factory,
                                            Event::Dispatcher& dispatcher,
                                            Random::RandomGenerator& random_generator,
-                                           SkyWalkingTracerStats& stats,
+                                           SkyWalkingTracerStatsSharedPtr stats,
                                            uint32_t delayed_buffer_size, const std::string& token)
     : tracing_stats_(stats), client_(factory->createUncachedRawAsyncClient()),
       service_method_(*Protobuf::DescriptorPool::generated_pool()->FindMethodByName(
@@ -48,14 +48,14 @@ void TraceSegmentReporter::report(TracingContextPtr tracing_context) {
   ENVOY_LOG(trace, "Try to report segment to SkyWalking Server:\n{}", request.DebugString());
 
   if (stream_ != nullptr) {
-    tracing_stats_.segments_sent_.inc();
+    tracing_stats_->segments_sent_.inc();
     stream_->sendMessage(request, false);
     return;
   }
   // Null stream_ and cache segment data temporarily.
   delayed_segments_cache_.emplace(request);
   if (delayed_segments_cache_.size() > delayed_buffer_size_) {
-    tracing_stats_.segments_dropped_.inc();
+    tracing_stats_->segments_dropped_.inc();
     delayed_segments_cache_.pop();
   }
 }
@@ -63,12 +63,12 @@ void TraceSegmentReporter::report(TracingContextPtr tracing_context) {
 void TraceSegmentReporter::flushTraceSegments() {
   ENVOY_LOG(debug, "Flush segments in cache to SkyWalking backend service");
   while (!delayed_segments_cache_.empty() && stream_ != nullptr) {
-    tracing_stats_.segments_sent_.inc();
-    tracing_stats_.segments_flushed_.inc();
+    tracing_stats_->segments_sent_.inc();
+    tracing_stats_->segments_flushed_.inc();
     stream_->sendMessage(delayed_segments_cache_.front(), false);
     delayed_segments_cache_.pop();
   }
-  tracing_stats_.cache_flushed_.inc();
+  tracing_stats_->cache_flushed_.inc();
 }
 
 void TraceSegmentReporter::closeStream() {
diff --git a/source/extensions/tracers/skywalking/trace_segment_reporter.h b/source/extensions/tracers/skywalking/trace_segment_reporter.h
index db198d2e0c..2fb5a07188 100644
--- a/source/extensions/tracers/skywalking/trace_segment_reporter.h
+++ b/source/extensions/tracers/skywalking/trace_segment_reporter.h
@@ -23,7 +23,7 @@ class TraceSegmentReporter : public Logger::Loggable<Logger::Id::tracing>,
 public:
   explicit TraceSegmentReporter(Grpc::AsyncClientFactoryPtr&& factory,
                                 Event::Dispatcher& dispatcher, Random::RandomGenerator& random,
-                                SkyWalkingTracerStats& stats, uint32_t delayed_buffer_size,
+                                SkyWalkingTracerStatsSharedPtr stats, uint32_t delayed_buffer_size,
                                 const std::string& token);
   ~TraceSegmentReporter() override;
 
@@ -46,7 +46,7 @@ private:
   void handleFailure();
   void setRetryTimer();
 
-  SkyWalkingTracerStats& tracing_stats_;
+  SkyWalkingTracerStatsSharedPtr tracing_stats_;
   Grpc::AsyncClient<skywalking::v3::SegmentObject, skywalking::v3::Commands> client_;
   Grpc::AsyncStream<skywalking::v3::SegmentObject> stream_{};
   const Protobuf::MethodDescriptor& service_method_;
diff --git a/source/extensions/upstreams/http/tcp/upstream_request.cc b/source/extensions/upstreams/http/tcp/upstream_request.cc
index 914e346d19..8af638ba16 100644
--- a/source/extensions/upstreams/http/tcp/upstream_request.cc
+++ b/source/extensions/upstreams/http/tcp/upstream_request.cc
@@ -47,16 +47,19 @@ Envoy::Http::Status TcpUpstream::encodeHeaders(const Envoy::Http::RequestHeaderM
                                                bool end_stream) {
   // Headers should only happen once, so use this opportunity to add the proxy
   // proto header, if configured.
-  ASSERT(upstream_request_->routeEntry().connectConfig().has_value());
-  Buffer::OwnedImpl data;
-  auto& connect_config = upstream_request_->routeEntry().connectConfig().value();
-  if (connect_config.has_proxy_protocol_config()) {
-    Extensions::Common::ProxyProtocol::generateProxyProtoHeader(
-        connect_config.proxy_protocol_config(), upstream_request_->connection(), data);
-  }
-
-  if (data.length() != 0 || end_stream) {
-    upstream_conn_data_->connection().write(data, end_stream);
+  const Router::RouteEntry* route_entry = upstream_request_->route().routeEntry();
+  ASSERT(route_entry != nullptr);
+  if (route_entry->connectConfig().has_value()) {
+    Buffer::OwnedImpl data;
+    auto& connect_config = route_entry->connectConfig().value();
+    if (connect_config.has_proxy_protocol_config()) {
+      Extensions::Common::ProxyProtocol::generateProxyProtoHeader(
+          connect_config.proxy_protocol_config(), upstream_request_->connection(), data);
+    }
+
+    if (data.length() != 0 || end_stream) {
+      upstream_conn_data_->connection().write(data, end_stream);
+    }
   }
 
   // TcpUpstream::encodeHeaders is called after the UpstreamRequest is fully initialized. Also use
diff --git a/source/server/BUILD b/source/server/BUILD
index 3f4ed5f359..12de035da3 100644
--- a/source/server/BUILD
+++ b/source/server/BUILD
@@ -150,6 +150,7 @@ envoy_cc_library(
         "//envoy/network:listener_interface",
         "//envoy/server:listener_manager_interface",
         "//source/server:connection_handler_impl",
+
     ],
 )
 
diff --git a/source/server/admin/BUILD b/source/server/admin/BUILD
index 365a5b8109..c0c22d55e3 100644
--- a/source/server/admin/BUILD
+++ b/source/server/admin/BUILD
@@ -12,6 +12,9 @@ envoy_cc_library(
     name = "admin_lib",
     srcs = ["admin.cc"],
     hdrs = ["admin.h"],
+    alimesh_deps = [
+        "//contrib/server/admin/source:cluster_endpoints_handler_lib",
+    ],
     deps = [
         ":admin_filter_lib",
         ":clusters_handler_lib",
diff --git a/source/server/admin/admin.cc b/source/server/admin/admin.cc
index 74c17040b2..e9979ad537 100644
--- a/source/server/admin/admin.cc
+++ b/source/server/admin/admin.cc
@@ -158,70 +158,73 @@ AdminImpl::AdminImpl(const std::string& profile_path, Server::Instance& server)
       config_dump_handler_(config_tracker_, server), init_dump_handler_(server),
       stats_handler_(server), logs_handler_(server), profiling_handler_(profile_path),
       runtime_handler_(server), listeners_handler_(server), server_cmd_handler_(server),
-      server_info_handler_(server),
+      server_info_handler_(server), cluster_endpoints_handler_(server),
       // TODO(jsedgwick) add /runtime_reset endpoint that removes all admin-set values
-      handlers_{
-          {"/", "Admin home page", MAKE_ADMIN_HANDLER(handlerAdminHome), false, false},
-          {"/certs", "print certs on machine",
-           MAKE_ADMIN_HANDLER(server_info_handler_.handlerCerts), false, false},
-          {"/clusters", "upstream cluster status",
-           MAKE_ADMIN_HANDLER(clusters_handler_.handlerClusters), false, false},
-          {"/config_dump", "dump current Envoy configs (experimental)",
-           MAKE_ADMIN_HANDLER(config_dump_handler_.handlerConfigDump), false, false},
-          {"/init_dump", "dump current Envoy init manager information (experimental)",
-           MAKE_ADMIN_HANDLER(init_dump_handler_.handlerInitDump), false, false},
-          {"/contention", "dump current Envoy mutex contention stats (if enabled)",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerContention), false, false},
-          {"/cpuprofiler", "enable/disable the CPU profiler",
-           MAKE_ADMIN_HANDLER(profiling_handler_.handlerCpuProfiler), false, true},
-          {"/heapprofiler", "enable/disable the heap profiler",
-           MAKE_ADMIN_HANDLER(profiling_handler_.handlerHeapProfiler), false, true},
-          {"/healthcheck/fail", "cause the server to fail health checks",
-           MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerHealthcheckFail), false, true},
-          {"/healthcheck/ok", "cause the server to pass health checks",
-           MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerHealthcheckOk), false, true},
-          {"/help", "print out list of admin commands", MAKE_ADMIN_HANDLER(handlerHelp), false,
-           false},
-          {"/hot_restart_version", "print the hot restart compatibility version",
-           MAKE_ADMIN_HANDLER(server_info_handler_.handlerHotRestartVersion), false, false},
-          {"/logging", "query/change logging levels",
-           MAKE_ADMIN_HANDLER(logs_handler_.handlerLogging), false, true},
-          {"/memory", "print current allocation/heap usage",
-           MAKE_ADMIN_HANDLER(server_info_handler_.handlerMemory), false, false},
-          {"/quitquitquit", "exit the server",
-           MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerQuitQuitQuit), false, true},
-          {"/reset_counters", "reset all counters to zero",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerResetCounters), false, true},
-          {"/drain_listeners", "drain listeners",
-           MAKE_ADMIN_HANDLER(listeners_handler_.handlerDrainListeners), false, true},
-          {"/server_info", "print server version/status information",
-           MAKE_ADMIN_HANDLER(server_info_handler_.handlerServerInfo), false, false},
-          {"/ready", "print server state, return 200 if LIVE, otherwise return 503",
-           MAKE_ADMIN_HANDLER(server_info_handler_.handlerReady), false, false},
-          {"/stats", "print server stats", MAKE_ADMIN_HANDLER(stats_handler_.handlerStats), false,
-           false},
-          {"/stats/prometheus", "print server stats in prometheus format",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerPrometheusStats), false, false},
-          {"/stats/recentlookups", "Show recent stat-name lookups",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookups), false, false},
-          {"/stats/recentlookups/clear", "clear list of stat-name lookups and counter",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsClear), false, true},
-          {"/stats/recentlookups/disable", "disable recording of reset stat-name lookup names",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsDisable), false, true},
-          {"/stats/recentlookups/enable", "enable recording of reset stat-name lookup names",
-           MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsEnable), false, true},
-          {"/listeners", "print listener info",
-           MAKE_ADMIN_HANDLER(listeners_handler_.handlerListenerInfo), false, false},
-          {"/runtime", "print runtime values", MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntime),
-           false, false},
-          {"/runtime_modify", "modify runtime values",
-           MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntimeModify), false, true},
-          {"/reopen_logs", "reopen access logs",
-           MAKE_ADMIN_HANDLER(logs_handler_.handlerReopenLogs), false, true},
-      },
-      date_provider_(server.dispatcher().timeSource()),
-      admin_filter_chain_(std::make_shared<AdminFilterChain>()),
-      local_reply_(LocalReply::Factory::createDefault()) {}
+      handlers_ {
+  {"/", "Admin home page", MAKE_ADMIN_HANDLER(handlerAdminHome), false, false},
+      {"/certs", "print certs on machine", MAKE_ADMIN_HANDLER(server_info_handler_.handlerCerts),
+       false, false},
+      {"/clusters", "upstream cluster status",
+       MAKE_ADMIN_HANDLER(clusters_handler_.handlerClusters), false, false},
+      {"/config_dump", "dump current Envoy configs (experimental)",
+       MAKE_ADMIN_HANDLER(config_dump_handler_.handlerConfigDump), false, false},
+      {"/init_dump", "dump current Envoy init manager information (experimental)",
+       MAKE_ADMIN_HANDLER(init_dump_handler_.handlerInitDump), false, false},
+      {"/contention", "dump current Envoy mutex contention stats (if enabled)",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerContention), false, false},
+      {"/cpuprofiler", "enable/disable the CPU profiler",
+       MAKE_ADMIN_HANDLER(profiling_handler_.handlerCpuProfiler), false, true},
+      {"/heapprofiler", "enable/disable the heap profiler",
+       MAKE_ADMIN_HANDLER(profiling_handler_.handlerHeapProfiler), false, true},
+      {"/healthcheck/fail", "cause the server to fail health checks",
+       MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerHealthcheckFail), false, true},
+      {"/healthcheck/ok", "cause the server to pass health checks",
+       MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerHealthcheckOk), false, true},
+      {"/help", "print out list of admin commands", MAKE_ADMIN_HANDLER(handlerHelp), false, false},
+      {"/hot_restart_version", "print the hot restart compatibility version",
+       MAKE_ADMIN_HANDLER(server_info_handler_.handlerHotRestartVersion), false, false},
+      {"/logging", "query/change logging levels", MAKE_ADMIN_HANDLER(logs_handler_.handlerLogging),
+       false, true},
+      {"/memory", "print current allocation/heap usage",
+       MAKE_ADMIN_HANDLER(server_info_handler_.handlerMemory), false, false},
+      {"/quitquitquit", "exit the server",
+       MAKE_ADMIN_HANDLER(server_cmd_handler_.handlerQuitQuitQuit), false, true},
+      {"/reset_counters", "reset all counters to zero",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerResetCounters), false, true},
+      {"/drain_listeners", "drain listeners",
+       MAKE_ADMIN_HANDLER(listeners_handler_.handlerDrainListeners), false, true},
+      {"/server_info", "print server version/status information",
+       MAKE_ADMIN_HANDLER(server_info_handler_.handlerServerInfo), false, false},
+      {"/ready", "print server state, return 200 if LIVE, otherwise return 503",
+       MAKE_ADMIN_HANDLER(server_info_handler_.handlerReady), false, false},
+      {"/stats", "print server stats", MAKE_ADMIN_HANDLER(stats_handler_.handlerStats), false,
+       false},
+      {"/stats/prometheus", "print server stats in prometheus format",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerPrometheusStats), false, false},
+      {"/stats/recentlookups", "Show recent stat-name lookups",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookups), false, false},
+      {"/stats/recentlookups/clear", "clear list of stat-name lookups and counter",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsClear), false, true},
+      {"/stats/recentlookups/disable", "disable recording of reset stat-name lookup names",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsDisable), false, true},
+      {"/stats/recentlookups/enable", "enable recording of reset stat-name lookup names",
+       MAKE_ADMIN_HANDLER(stats_handler_.handlerStatsRecentLookupsEnable), false, true},
+      {"/listeners", "print listener info",
+       MAKE_ADMIN_HANDLER(listeners_handler_.handlerListenerInfo), false, false},
+      {"/runtime", "print runtime values", MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntime),
+       false, false},
+      {"/runtime_modify", "modify runtime values",
+       MAKE_ADMIN_HANDLER(runtime_handler_.handlerRuntimeModify), false, true},
+      {"/reopen_logs", "reopen access logs", MAKE_ADMIN_HANDLER(logs_handler_.handlerReopenLogs),
+       false, true},
+#if defined(ALIMESH)
+      {"/endpoints", "print endpoints info related the service",
+       MAKE_ADMIN_HANDLER(cluster_endpoints_handler_.handlerClusterEndpoints), false, false},
+#endif
+}
+, date_provider_(server.dispatcher().timeSource()),
+    admin_filter_chain_(std::make_shared<AdminFilterChain>()),
+    local_reply_(LocalReply::Factory::createDefault()) {}
 
 Http::ServerConnectionPtr AdminImpl::createCodec(Network::Connection& connection,
                                                  const Buffer::Instance& data,
diff --git a/source/server/admin/admin.h b/source/server/admin/admin.h
index e99330c2c8..2a7c81971a 100644
--- a/source/server/admin/admin.h
+++ b/source/server/admin/admin.h
@@ -51,6 +51,10 @@
 
 #include "absl/strings/string_view.h"
 
+#if defined(ALIMESH)
+#include "contrib/server/admin/source/cluster_endpoints_handler.h"
+#endif
+
 namespace Envoy {
 namespace Server {
 
@@ -432,6 +436,9 @@ private:
   Server::ListenersHandler listeners_handler_;
   Server::ServerCmdHandler server_cmd_handler_;
   Server::ServerInfoHandler server_info_handler_;
+#if defined(ALIMESH)
+  Server::ClusterEndpointsHandler cluster_endpoints_handler_;
+#endif
   std::list<UrlHandler> handlers_;
   const uint32_t max_request_headers_kb_{Http::DEFAULT_MAX_REQUEST_HEADERS_KB};
   const uint32_t max_request_headers_count_{Http::DEFAULT_MAX_HEADERS_COUNT};
diff --git a/test/common/common/BUILD b/test/common/common/BUILD
index a4705d1bc4..f42d2b40f0 100644
--- a/test/common/common/BUILD
+++ b/test/common/common/BUILD
@@ -182,10 +182,10 @@ envoy_cc_benchmark_binary(
     deps = ["//source/common/common:minimal_logger_lib"],
 )
 
-envoy_benchmark_test(
-    name = "logger_speed_test_benchmark_test",
-    benchmark_binary = "logger_speed_test",
-)
+# envoy_benchmark_test(
+#     name = "logger_speed_test_benchmark_test",
+#     benchmark_binary = "logger_speed_test",
+# )
 
 envoy_cc_test(
     name = "logger_test",
diff --git a/test/common/common/base64_test.cc b/test/common/common/base64_test.cc
index e00ae7f998..3c6bf92a05 100644
--- a/test/common/common/base64_test.cc
+++ b/test/common/common/base64_test.cc
@@ -132,47 +132,6 @@ TEST(Base64Test, BinaryBufferEncode) {
   EXPECT_EQ("AAECAwgKCQCqvN4=", Base64::encode(buffer, 30));
 }
 
-TEST(Base64Test, CompletePadding) {
-  struct CompletePaddingBase64UrlTestCases {
-    std::string base64, base64_with_padding;
-  };
-
-  // For base64 encoding, there are only three length needed to test
-  // - 3n bytes => 4n bytes, no padding needed
-  // - 3n + 1 bytes => 4n + 2 bytes, 2 padding needed
-  // - 3n + 2 bytes => 4n + 3 bytes, 1 padding needed
-  CompletePaddingBase64UrlTestCases testCases[3] = {
-      // Payload text(3n bytes):
-      {"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG8iLCJpYXQiOjE1MTYyMzkwMjJ"
-       "9",
-       // No padding added.
-       "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG8iLCJpYXQiOjE1MTYyMzkwMjJ"
-       "9"},
-      // Payload text(3n + 1 bytes):
-      {"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2"
-       "MjM5MDIyfQ",
-       // 2 padding added.
-       "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2"
-       "MjM5MDIyfQ=="},
-      // Payload text(3n + 2 bytes):
-      {"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lZSIsImlhdCI6MTUx"
-       "NjIzOTAyMn0",
-       // 1 padding added.
-       "eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lZSIsImlhdCI6MTUx"
-       "NjIzOTAyMn0="}};
-  for (auto& tc : testCases) {
-    // Ensure these two base64 binaries are equivalent after decoding.
-    EXPECT_EQ(Base64::decodeWithoutPadding(tc.base64),
-              Base64::decodeWithoutPadding(tc.base64_with_padding));
-    // Ensure the `base64_with_padding` is correctly padded.
-    EXPECT_NE(Base64::decode(tc.base64_with_padding), "");
-
-    std::string base64_padded = tc.base64;
-    Base64::completePadding(base64_padded);
-    EXPECT_EQ(base64_padded, tc.base64_with_padding);
-  }
-}
-
 TEST(Base64UrlTest, EncodeString) {
   EXPECT_EQ("", Base64Url::encode("", 0));
   EXPECT_EQ("AAA", Base64Url::encode("\0\0", 2));
diff --git a/test/common/filter/config_discovery_impl_test.cc b/test/common/filter/config_discovery_impl_test.cc
index ede45f2577..50d285fc09 100644
--- a/test/common/filter/config_discovery_impl_test.cc
+++ b/test/common/filter/config_discovery_impl_test.cc
@@ -40,9 +40,11 @@ class FilterConfigDiscoveryTestBase : public testing::Test {
 public:
   FilterConfigDiscoveryTestBase() {
     // For server_factory_context
-    ON_CALL(factory_context_, scope()).WillByDefault(ReturnRef(scope_));
+    ON_CALL(factory_context_.server_factory_context_, scope()).WillByDefault(ReturnRef(scope_));
     ON_CALL(factory_context_, messageValidationContext())
         .WillByDefault(ReturnRef(validation_context_));
+    ON_CALL(factory_context_.server_factory_context_, messageValidationContext())
+        .WillByDefault(ReturnRef(validation_context_));
     EXPECT_CALL(validation_context_, dynamicValidationVisitor())
         .WillRepeatedly(ReturnRef(validation_visitor_));
     EXPECT_CALL(factory_context_, initManager()).WillRepeatedly(ReturnRef(init_manager_));
@@ -76,9 +78,9 @@ public:
   }
   ~FilterConfigDiscoveryImplTest() override { factory_context_.thread_local_.shutdownThread(); }
 
-  DynamicFilterConfigProviderPtr createProvider(std::string name, bool warm,
-                                                bool default_configuration,
-                                                bool last_filter_config = true) {
+  DynamicFilterConfigProviderPtr<Http::FilterFactoryCb>
+  createProvider(std::string name, bool warm, bool default_configuration,
+                 bool last_filter_config = true) {
 
     EXPECT_CALL(init_manager_, add(_));
     envoy::config::core::v3::ExtensionConfigSource config_source;
@@ -113,16 +115,20 @@ type_urls:
 
   void setup(bool warm = true, bool default_configuration = false, bool last_filter_config = true) {
     provider_ = createProvider("foo", warm, default_configuration, last_filter_config);
-    callbacks_ = factory_context_.cluster_manager_.subscription_factory_.callbacks_;
-    EXPECT_CALL(*factory_context_.cluster_manager_.subscription_factory_.subscription_, start(_));
+    callbacks_ =
+        factory_context_.server_factory_context_.cluster_manager_.subscription_factory_.callbacks_;
+    EXPECT_CALL(*factory_context_.server_factory_context_.cluster_manager_.subscription_factory_
+                     .subscription_,
+                start(_));
     if (!warm) {
       EXPECT_CALL(init_watcher_, ready());
     }
     init_manager_.initialize(init_watcher_);
   }
 
-  std::unique_ptr<FilterConfigProviderManager> filter_config_provider_manager_;
-  DynamicFilterConfigProviderPtr provider_;
+  std::unique_ptr<FilterConfigProviderManager<Http::FilterFactoryCb>>
+      filter_config_provider_manager_;
+  DynamicFilterConfigProviderPtr<Http::FilterFactoryCb> provider_;
   Config::SubscriptionCallbacks* callbacks_{};
 };
 
diff --git a/test/common/formatter/substitution_formatter_test.cc b/test/common/formatter/substitution_formatter_test.cc
index 6ca626f78d..cfae376d3a 100644
--- a/test/common/formatter/substitution_formatter_test.cc
+++ b/test/common/formatter/substitution_formatter_test.cc
@@ -694,6 +694,24 @@ TEST(SubstitutionFormatterTest, streamInfoFormatter) {
   }
 
   {
+    NiceMock<StreamInfo::MockStreamInfo> stream_info;
+    StreamInfoFormatter upstream_format("VIRTUAL_CLUSTER_NAME");
+    std::string virtual_cluster_name = "authN";
+    stream_info.setVirtualClusterName(virtual_cluster_name);
+    EXPECT_EQ("authN", upstream_format.format(request_headers, response_headers, response_trailers,
+                                              stream_info, body));
+  }
+
+  {
+    NiceMock<StreamInfo::MockStreamInfo> stream_info;
+    StreamInfoFormatter upstream_format("VIRTUAL_CLUSTER_NAME");
+    EXPECT_EQ(absl::nullopt, upstream_format.format(request_headers, response_headers,
+                                                    response_trailers, stream_info, body));
+  }
+
+  {
+    // Use a local stream info for these tests as as setSslConnection can only be called once.
+    NiceMock<StreamInfo::MockStreamInfo> stream_info;
     StreamInfoFormatter upstream_format("DOWNSTREAM_PEER_URI_SAN");
     auto connection_info = std::make_shared<Ssl::MockConnectionInfo>();
     const std::vector<std::string> sans{"san"};
diff --git a/test/common/grpc/grpc_client_integration.h b/test/common/grpc/grpc_client_integration.h
index 00aebe7cef..e0edd120ed 100644
--- a/test/common/grpc/grpc_client_integration.h
+++ b/test/common/grpc/grpc_client_integration.h
@@ -13,7 +13,7 @@ namespace Envoy {
 namespace Grpc {
 
 // Support parameterizing over state-of-the-world xDS vs delta xDS.
-enum class SotwOrDelta { Sotw, Delta };
+enum class SotwOrDelta { Sotw, Delta, UnifiedSotw, UnifiedDelta };
 
 class BaseGrpcClientIntegrationParamTest {
 public:
diff --git a/test/common/http/codes_speed_test.cc b/test/common/http/codes_speed_test.cc
index fc1d5f4ffa..b79addb45e 100644
--- a/test/common/http/codes_speed_test.cc
+++ b/test/common/http/codes_speed_test.cc
@@ -29,11 +29,20 @@ public:
   void addResponse(uint64_t code, bool canary, bool internal_request,
                    Stats::StatName request_vhost_name = Stats::StatName(),
                    Stats::StatName request_vcluster_name = Stats::StatName(),
+                   Stats::StatName request_route_name = Stats::StatName(),
                    Stats::StatName from_az = Stats::StatName(),
                    Stats::StatName to_az = Stats::StatName()) {
-    Http::CodeStats::ResponseStatInfo info{
-        global_store_,      cluster_scope_,        prefix_, code,  internal_request,
-        request_vhost_name, request_vcluster_name, from_az, to_az, canary};
+    Http::CodeStats::ResponseStatInfo info{global_store_,
+                                           cluster_scope_,
+                                           prefix_,
+                                           code,
+                                           internal_request,
+                                           request_vhost_name,
+                                           request_route_name,
+                                           request_vcluster_name,
+                                           from_az,
+                                           to_az,
+                                           canary};
 
     code_stats_.chargeResponseStat(info, false);
   }
@@ -52,10 +61,11 @@ public:
   }
 
   void responseTiming() {
+    Stats::StatName empty_stat_name;
     Http::CodeStats::ResponseTimingInfo info{
-        global_store_, cluster_scope_, prefix_,     std::chrono::milliseconds(5),
-        true,          true,           vhost_name_, req_vcluster_name_,
-        from_az_,      to_az_};
+        global_store_, cluster_scope_, prefix_,         std::chrono::milliseconds(5), true,
+        true,          vhost_name_,    empty_stat_name, req_vcluster_name_,           from_az_,
+        to_az_};
     code_stats_.chargeResponseTiming(info);
   }
 
diff --git a/test/common/http/codes_test.cc b/test/common/http/codes_test.cc
index 98f80b7483..ab65280aa5 100644
--- a/test/common/http/codes_test.cc
+++ b/test/common/http/codes_test.cc
@@ -37,9 +37,11 @@ public:
     Stats::StatName to_zone = pool_.add(to_az);
     Stats::StatName vhost_name = pool_.add(request_vhost_name);
     Stats::StatName vcluster_name = pool_.add(request_vcluster_name);
+    Stats::StatName empty_stat_name;
     Http::CodeStats::ResponseStatInfo info{
-        global_store_, cluster_scope_, prefix,    code,    internal_request,
-        vhost_name,    vcluster_name,  from_zone, to_zone, canary};
+        global_store_,    cluster_scope_, prefix,        code,
+        internal_request, vhost_name,     vcluster_name, empty_stat_name,
+        from_zone,        to_zone,        canary};
 
     code_stats_.chargeResponseStat(info, false);
   }
@@ -232,6 +234,7 @@ TEST_F(CodeUtilityTest, PerZoneStats) {
 TEST_F(CodeUtilityTest, ResponseTimingTest) {
   Stats::MockStore global_store;
   Stats::MockStore cluster_scope;
+  Stats::StatName empty_stat_name;
 
   Stats::StatNameManagedStorage prefix("prefix", *symbol_table_);
   Http::CodeStats::ResponseTimingInfo info{global_store,
@@ -242,6 +245,7 @@ TEST_F(CodeUtilityTest, ResponseTimingTest) {
                                            true,
                                            pool_.add("vhost_name"),
                                            pool_.add("req_vcluster_name"),
+                                           empty_stat_name,
                                            pool_.add("from_az"),
                                            pool_.add("to_az")};
 
diff --git a/test/common/http/conn_manager_impl_test.cc b/test/common/http/conn_manager_impl_test.cc
index 05a3a0d59d..9d2a11d6f2 100644
--- a/test/common/http/conn_manager_impl_test.cc
+++ b/test/common/http/conn_manager_impl_test.cc
@@ -2162,7 +2162,8 @@ TEST_F(HttpConnectionManagerImplTest, TestAccessLogWithInvalidRequest) {
 
 class StreamErrorOnInvalidHttpMessageTest : public HttpConnectionManagerImplTest {
 public:
-  void sendInvalidRequestAndVerifyConnectionState(bool stream_error_on_invalid_http_message) {
+  void sendInvalidRequestAndVerifyConnectionState(bool stream_error_on_invalid_http_message,
+                                                  bool send_complete_request = true) {
     setup(false, "");
 
     EXPECT_CALL(*codec_, dispatch(_))
@@ -2172,7 +2173,7 @@ public:
           // These request headers are missing the necessary ":host"
           RequestHeaderMapPtr headers{
               new TestRequestHeaderMapImpl{{":method", "GET"}, {":path", "/"}}};
-          decoder_->decodeHeaders(std::move(headers), true);
+          decoder_->decodeHeaders(std::move(headers), send_complete_request);
           data.drain(0);
           return Http::okStatus();
         }));
@@ -2190,6 +2191,19 @@ public:
         .WillOnce(Return(stream_error_on_invalid_http_message));
     EXPECT_CALL(*filter, encodeComplete());
     EXPECT_CALL(*filter, encodeHeaders(_, true));
+    if (!stream_error_on_invalid_http_message) {
+      EXPECT_CALL(filter_callbacks_.connection_, close(_)).Times(AnyNumber());
+      if (send_complete_request) {
+        // The request is complete, so we should not flush close.
+        EXPECT_CALL(filter_callbacks_.connection_, close(Network::ConnectionCloseType::FlushWrite))
+            .Times(AnyNumber());
+      } else {
+        // If the request isn't complete, avoid a FIN/RST race with delay close.
+        EXPECT_CALL(filter_callbacks_.connection_,
+                    close(Network::ConnectionCloseType::FlushWriteAndDelay))
+            .Times(AnyNumber());
+      }
+    }
     EXPECT_CALL(response_encoder_, encodeHeaders(_, true))
         .WillOnce(Invoke([&](const ResponseHeaderMap& headers, bool) -> void {
           EXPECT_EQ("400", headers.getStatusValue());
@@ -2215,6 +2229,12 @@ TEST_F(StreamErrorOnInvalidHttpMessageTest, ConnectionTerminatedIfCodecStreamErr
   sendInvalidRequestAndVerifyConnectionState(false);
 }
 
+TEST_F(StreamErrorOnInvalidHttpMessageTest,
+       ConnectionTerminatedWithDelayIfCodecStreamErrorIsFalse) {
+  // Same as above, only with an incomplete request.
+  sendInvalidRequestAndVerifyConnectionState(false, false);
+}
+
 TEST_F(StreamErrorOnInvalidHttpMessageTest, ConnectionOpenIfCodecStreamErrorIsTrue) {
   sendInvalidRequestAndVerifyConnectionState(true);
 }
@@ -3365,7 +3385,7 @@ TEST_F(HttpConnectionManagerImplTest, Http10Rejected) {
     decoder_ = &conn_manager_->newStream(response_encoder_);
     RequestHeaderMapPtr headers{
         new TestRequestHeaderMapImpl{{":authority", "host"}, {":method", "GET"}, {":path", "/"}}};
-    decoder_->decodeHeaders(std::move(headers), true);
+    decoder_->decodeHeaders(std::move(headers), false);
     data.drain(4);
     return Http::okStatus();
   }));
@@ -3375,6 +3395,12 @@ TEST_F(HttpConnectionManagerImplTest, Http10Rejected) {
         EXPECT_EQ("426", headers.getStatusValue());
         EXPECT_EQ("close", headers.getConnectionValue());
       }));
+  // No delay close for HTTP/1.0, even if the request is not complete.
+  // Note there may be more than one close: the important thing is one does not
+  // kick off delay.
+  EXPECT_CALL(filter_callbacks_.connection_, close(_)).Times(AnyNumber());
+  EXPECT_CALL(filter_callbacks_.connection_, close(Network::ConnectionCloseType::FlushWrite))
+      .Times(AnyNumber());
 
   Buffer::OwnedImpl fake_input("1234");
   conn_manager_->onData(fake_input, false);
diff --git a/test/common/http/header_map_impl_test.cc b/test/common/http/header_map_impl_test.cc
index ce4bb8a7cc..d06806f23a 100644
--- a/test/common/http/header_map_impl_test.cc
+++ b/test/common/http/header_map_impl_test.cc
@@ -423,9 +423,8 @@ TEST_P(HeaderMapImplTest, AllInlineHeaders) {
     INLINE_REQ_RESP_STRING_HEADERS(TEST_INLINE_STRING_HEADER_FUNCS)
   }
   {
-    // No request trailer O(1) headers.
-  }
-  {
+      // No request trailer O(1) headers.
+  } {
     auto header_map = ResponseHeaderMapImpl::create();
     INLINE_RESP_STRING_HEADERS(TEST_INLINE_STRING_HEADER_FUNCS)
     INLINE_REQ_RESP_STRING_HEADERS(TEST_INLINE_STRING_HEADER_FUNCS)
@@ -796,6 +795,88 @@ TEST_P(HeaderMapImplTest, SetReferenceKey) {
   EXPECT_EQ("monde", headers.get(foo)[0]->value().getStringView());
 }
 
+
+#if defined(ALIMESH)
+TEST_P(HeaderMapImplTest, OriginalHost) {
+  // Normal case.
+  {
+    TestRequestHeaderMapImpl headers;
+    headers.setHost("blah");
+    headers.setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost,
+                            headers.getHostValue());
+    EXPECT_EQ("blah", headers.getHostValue());
+
+    headers.setHost("example");
+    EXPECT_EQ("example", headers.getHostValue());
+
+    const auto original_host =
+        headers.getByKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost);
+    EXPECT_EQ("blah", original_host.value());
+  }
+
+  // Normal case.
+  {
+    TestRequestHeaderMapImpl headers;
+    headers.setHost("www.example.com");
+    headers.setReferenceKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost,
+                            headers.getHostValue());
+    EXPECT_EQ("www.example.com", headers.getHostValue());
+
+    headers.setHost("test.com");
+    EXPECT_EQ("test.com", headers.getHostValue());
+
+    const auto original_host =
+        headers.getByKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost);
+    EXPECT_EQ("www.example.com", original_host.value());
+  }
+
+  // The header 'EnvoyOriginalHost' value is overwritten.
+  {
+    TestRequestHeaderMapImpl headers;
+    headers.setHost("blah");
+    headers.setReference(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost,
+                         headers.getHostValue());
+    EXPECT_EQ("blah", headers.getHostValue());
+
+    headers.setHost("example");
+    EXPECT_EQ("example", headers.getHostValue());
+
+    const auto original_host =
+        headers.getByKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost);
+    EXPECT_EQ("exam", original_host.value());
+  }
+
+  // The header 'EnvoyOriginalHost' value is overwritten.
+  {
+    TestRequestHeaderMapImpl headers;
+    headers.setHost("www.example.com");
+    headers.setReference(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost,
+                         headers.getHostValue());
+    EXPECT_EQ("www.example.com", headers.getHostValue());
+
+    headers.setHost("test.com");
+    EXPECT_EQ("test.com", headers.getHostValue());
+
+    const auto original_host =
+        headers.getByKey(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost);
+    EXPECT_NE("test.com", original_host.value());
+  }
+}
+#endif
+
+TEST_P(HeaderMapImplTest, SetReferenceKeyTest111) {
+  TestRequestHeaderMapImpl headers;
+  //headers.setReferenceKey(Headers::get().Host, "blah");
+  headers.setHost("blah");
+  EXPECT_EQ("blah", headers.getHostValue());
+
+  headers.setReference(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost, headers.getHostValue());
+  // headers.setReferenceKey(Headers::get().Host, "blahxxx");
+  headers.setHost("blahxxxx");
+  EXPECT_EQ("blahxxxx", headers.getHostValue());
+  EXPECT_EQ("blah", headers.get(Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost)[0]->value().getStringView());
+}
+
 TEST_P(HeaderMapImplTest, SetCopy) {
   TestRequestHeaderMapImpl headers;
   LowerCaseString foo("hello");
diff --git a/test/common/http/utility_test.cc b/test/common/http/utility_test.cc
index ae7073574d..5509c5ff3f 100644
--- a/test/common/http/utility_test.cc
+++ b/test/common/http/utility_test.cc
@@ -301,6 +301,92 @@ TEST(HttpUtility, appendVia) {
   }
 }
 
+TEST(HttpUtility, updateAuthority) {
+  {
+    TestRequestHeaderMapImpl headers;
+    Utility::updateAuthority(headers, "dns.name", true);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers;
+    Utility::updateAuthority(headers, "dns.name", false);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers;
+    Utility::updateAuthority(headers, "", true);
+    EXPECT_EQ("", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers;
+    Utility::updateAuthority(headers, "", false);
+    EXPECT_EQ("", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "host.com"}};
+    Utility::updateAuthority(headers, "dns.name", true);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("host.com", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "host.com"}};
+    Utility::updateAuthority(headers, "dns.name", false);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "host.com"}};
+    Utility::updateAuthority(headers, "", true);
+    EXPECT_EQ("", headers.get_(":authority"));
+    EXPECT_EQ("host.com", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "host.com"}};
+    Utility::updateAuthority(headers, "", false);
+    EXPECT_EQ("", headers.get_(":authority"));
+    EXPECT_EQ("", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "dns.name"}, {"x-forwarded-host", "host.com"}};
+    Utility::updateAuthority(headers, "newhost.com", true);
+    EXPECT_EQ("newhost.com", headers.get_(":authority"));
+    EXPECT_EQ("host.com,dns.name", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{":authority", "dns.name"}, {"x-forwarded-host", "host.com"}};
+    Utility::updateAuthority(headers, "newhost.com", false);
+    EXPECT_EQ("newhost.com", headers.get_(":authority"));
+    EXPECT_EQ("host.com", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{"x-forwarded-host", "host.com"}};
+    Utility::updateAuthority(headers, "dns.name", true);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("host.com", headers.get_("x-forwarded-host"));
+  }
+
+  {
+    TestRequestHeaderMapImpl headers{{"x-forwarded-host", "host.com"}};
+    Utility::updateAuthority(headers, "dns.name", false);
+    EXPECT_EQ("dns.name", headers.get_(":authority"));
+    EXPECT_EQ("host.com", headers.get_("x-forwarded-host"));
+  }
+}
+
 TEST(HttpUtility, createSslRedirectPath) {
   {
     TestRequestHeaderMapImpl headers{{":authority", "www.lyft.com"}, {":path", "/hello"}};
diff --git a/test/common/network/apple_dns_impl_test.cc b/test/common/network/apple_dns_impl_test.cc
index b7e7904ad7..df35c4063d 100644
--- a/test/common/network/apple_dns_impl_test.cc
+++ b/test/common/network/apple_dns_impl_test.cc
@@ -916,7 +916,7 @@ TEST_F(AppleDnsImplFakeApiTest, ResultWithNullAddress) {
 
   auto query = resolver_->resolve(
       hostname, Network::DnsLookupFamily::Auto,
-      [](DnsResolver::ResolutionStatus, std::list<DnsResponse>&&) -> void { FAIL(); });
+      [](DnsResolver::ResolutionStatus, std::list<DnsResponse> &&) -> void { FAIL(); });
   ASSERT_NE(nullptr, query);
 
   EXPECT_DEATH(reply_callback(nullptr, kDNSServiceFlagsAdd, 0, kDNSServiceErr_NoError,
diff --git a/test/common/network/cidr_range_test.cc b/test/common/network/cidr_range_test.cc
index 6232e910dd..f3abc89a1a 100644
--- a/test/common/network/cidr_range_test.cc
+++ b/test/common/network/cidr_range_test.cc
@@ -12,6 +12,10 @@
 
 #include "gtest/gtest.h"
 
+#if defined(ALIMESH)
+#include "test/test_common/environment.h"
+#endif
+
 // We are adding things into the std namespace.
 // Note that this is technically undefined behavior!
 namespace std {
diff --git a/test/common/network/udp_listener_impl_batch_writer_test.cc b/test/common/network/udp_listener_impl_batch_writer_test.cc
index 39b69e86c0..414cc968b8 100644
--- a/test/common/network/udp_listener_impl_batch_writer_test.cc
+++ b/test/common/network/udp_listener_impl_batch_writer_test.cc
@@ -92,6 +92,9 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, UdpListenerImplBatchWriterTest,
  *       total_bytes_sent counter is updated accordingly.
  */
 TEST_P(UdpListenerImplBatchWriterTest, SendData) {
+  if (!TestEnvironment::shouldRunTestForIpVersion(Network::Address::IpVersion::v6)) {
+    return;
+  }
   EXPECT_TRUE(udp_packet_writer_->isBatchMode());
   Address::InstanceConstSharedPtr send_from_addr = getNonDefaultSourceAddress();
 
@@ -177,6 +180,9 @@ TEST_P(UdpListenerImplBatchWriterTest, SendData) {
  *      Internal Buffer.
  */
 TEST_P(UdpListenerImplBatchWriterTest, WriteBlocked) {
+  if (!TestEnvironment::shouldRunTestForIpVersion(Network::Address::IpVersion::v6)) {
+    return;
+  }
   // Quic Mock Objects
   quic::test::MockQuicSyscallWrapper os_sys_calls;
   quic::ScopedGlobalSyscallWrapperOverride os_calls(&os_sys_calls);
diff --git a/test/common/network/udp_listener_impl_test.cc b/test/common/network/udp_listener_impl_test.cc
index a16a13e8f5..61a69a3f9a 100644
--- a/test/common/network/udp_listener_impl_test.cc
+++ b/test/common/network/udp_listener_impl_test.cc
@@ -107,6 +107,9 @@ INSTANTIATE_TEST_SUITE_P(IpVersions, UdpListenerImplTest,
  * Tests UDP listener for actual destination and data.
  */
 TEST_P(UdpListenerImplTest, UseActualDstUdp) {
+  if (!TestEnvironment::shouldRunTestForIpVersion(Network::Address::IpVersion::v6)) {
+    return;
+  }
   setup();
 
   // We send 2 packets
@@ -140,6 +143,9 @@ TEST_P(UdpListenerImplTest, UseActualDstUdp) {
 
 // Test a large datagram that gets dropped using recvmsg or recvmmsg if supported.
 TEST_P(UdpListenerImplTest, LargeDatagramRecvmmsg) {
+  if (!TestEnvironment::shouldRunTestForIpVersion(Network::Address::IpVersion::v6)) {
+    return;
+  }
   setup();
 
   // This will get dropped.
diff --git a/test/common/network/utility_test.cc b/test/common/network/utility_test.cc
index fac1300cf3..b9892ead84 100644
--- a/test/common/network/utility_test.cc
+++ b/test/common/network/utility_test.cc
@@ -353,6 +353,7 @@ TEST(NetworkUtility, LoopbackAddress) {
     Address::PipeInstance address("/foo");
     EXPECT_FALSE(Utility::isLoopbackAddress(address));
   }
+
   {
     Address::Ipv6Instance address("::1");
     EXPECT_TRUE(Utility::isLoopbackAddress(address));
@@ -532,7 +533,11 @@ TEST(PortRangeListTest, Normal) {
 
 // TODO(ccaraman): Support big-endian. These tests operate under the assumption that the machine
 // byte order is little-endian.
+#if defined(ALIMESH)
+TEST(AbslUint128, DISABLED_TestByteOrder) {
+#else
 TEST(AbslUint128, TestByteOrder) {
+#endif
   {
     Address::Ipv6Instance address("::1");
     uint64_t high = 0x100000000000000;
diff --git a/test/common/router/BUILD b/test/common/router/BUILD
index 596a8a86e7..0d6ca09fe0 100644
--- a/test/common/router/BUILD
+++ b/test/common/router/BUILD
@@ -33,6 +33,7 @@ envoy_cc_test_library(
         "//source/common/stream_info:filter_state_lib",
         "//test/extensions/filters/http/common:empty_http_filter_config_lib",
         "//test/fuzz:utility_lib",
+        "//test/mocks/router:router_mocks",
         "//test/mocks/server:instance_mocks",
         "//test/mocks/upstream:retry_priority_mocks",
         "//test/test_common:environment_lib",
@@ -44,6 +45,20 @@ envoy_cc_test_library(
     ],
 )
 
+envoy_cc_test(
+    name = "config_impl_integration_test",
+    srcs = [
+        "config_impl_integration_test.cc",
+    ],
+    deps = [
+        "//source/common/protobuf",
+        "//source/common/router:config_lib",
+        "//test/integration:http_integration_lib",
+        "//test/test_common:utility_lib",
+        "@envoy_api//envoy/config/endpoint/v3:pkg_cc_proto",
+    ],
+)
+
 envoy_cc_benchmark_binary(
     name = "config_impl_headermap_benchmark_test",
     srcs = ["config_impl_headermap_benchmark_test.cc"],
diff --git a/test/common/router/config_impl_integration_test.cc b/test/common/router/config_impl_integration_test.cc
new file mode 100644
index 0000000000..db68766c85
--- /dev/null
+++ b/test/common/router/config_impl_integration_test.cc
@@ -0,0 +1,144 @@
+#include <chrono>
+#include <cstdint>
+
+#include "envoy/config/endpoint/v3/endpoint_components.pb.h"
+
+#include "source/common/common/base64.h"
+#include "source/common/http/utility.h"
+#include "source/common/protobuf/protobuf.h"
+
+#include "test/integration/http_integration.h"
+#include "test/test_common/registry.h"
+
+#include "absl/strings/string_view.h"
+#include "gtest/gtest.h"
+
+namespace Envoy {
+namespace Router {
+namespace {
+
+class FakeClusterSpecifierPluginFactoryConfig : public ClusterSpecifierPluginFactoryConfig {
+public:
+  class FakeClusterSpecifierPlugin : public ClusterSpecifierPlugin {
+  public:
+    FakeClusterSpecifierPlugin(absl::string_view cluster) : cluster_name_(cluster) {}
+
+    RouteConstSharedPtr route(const RouteEntry& parent,
+                              const Http::RequestHeaderMap&) const override {
+      ASSERT(dynamic_cast<const RouteEntryImplBase*>(&parent) != nullptr);
+      return std::make_shared<RouteEntryImplBase::DynamicRouteEntry>(
+          dynamic_cast<const RouteEntryImplBase*>(&parent), cluster_name_);
+    }
+
+    const std::string cluster_name_;
+  };
+
+  FakeClusterSpecifierPluginFactoryConfig() = default;
+  ClusterSpecifierPluginSharedPtr
+  createClusterSpecifierPlugin(const Protobuf::Message& config,
+                               Server::Configuration::CommonFactoryContext&) override {
+    const auto& typed_config = dynamic_cast<const ProtobufWkt::Struct&>(config);
+    return std::make_shared<FakeClusterSpecifierPlugin>(
+        typed_config.fields().at("name").string_value());
+  }
+
+  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
+    return std::make_unique<ProtobufWkt::Struct>();
+  }
+
+  std::string name() const override { return "envoy.router.cluster_specifier_plugin.fake"; }
+};
+
+class ConfigImplIntegrationTest : public Envoy::HttpIntegrationTest, public testing::Test {
+public:
+  ConfigImplIntegrationTest()
+      : HttpIntegrationTest(Http::CodecType::HTTP1, Network::Address::IpVersion::v4) {}
+
+  void initializeRoute(const std::string& vhost_config_yaml) {
+    envoy::config::route::v3::VirtualHost vhost;
+    TestUtility::loadFromYaml(vhost_config_yaml, vhost);
+    config_helper_.addVirtualHost(vhost);
+    initialize();
+  }
+};
+
+static const std::string ClusterSpecifierPluginUnknownCluster =
+    R"EOF(
+name: test_cluster_specifier_plugin
+domains:
+- cluster.specifier.plugin
+routes:
+- name: test_route_1
+  match:
+    prefix: /test/route/1
+  route:
+    inline_cluster_specifier_plugin:
+      extension:
+        name: fake
+        typed_config:
+          "@type": type.googleapis.com/google.protobuf.Struct
+          value:
+            name: cluster_0
+- name: test_route_2
+  match:
+    prefix: /test/route/2
+  route:
+    inline_cluster_specifier_plugin:
+      extension:
+        name: fake
+        typed_config:
+          "@type": type.googleapis.com/google.protobuf.Struct
+          value:
+            name: cluster_unknown
+)EOF";
+
+TEST_F(ConfigImplIntegrationTest, ClusterSpecifierPluginTest) {
+  FakeClusterSpecifierPluginFactoryConfig factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  initializeRoute(ClusterSpecifierPluginUnknownCluster);
+
+  {
+    codec_client_ = makeHttpConnection(lookupPort("http"));
+
+    Http::TestResponseHeaderMapImpl response_headers{
+        {"server", "envoy"},
+        {":status", "200"},
+    };
+
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/test/route/1"},
+                                                   {":scheme", "http"},
+                                                   {":authority", "cluster.specifier.plugin"}};
+
+    auto response = sendRequestAndWaitForResponse(request_headers, 0, response_headers, 0);
+
+    ASSERT_TRUE(response->waitForEndStream());
+    EXPECT_TRUE(response->complete());
+    EXPECT_EQ(response->headers().getStatusValue(), "200");
+
+    cleanupUpstreamAndDownstream();
+  }
+
+  {
+    codec_client_ = makeHttpConnection(lookupPort("http"));
+
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/test/route/2"},
+                                                   {":scheme", "http"},
+                                                   {":authority", "cluster.specifier.plugin"}};
+
+    // Second route will be selected and unknown cluster name will be return by the cluster
+    // specifier plugin.
+    auto response = codec_client_->makeHeaderOnlyRequest(request_headers);
+    ASSERT_TRUE(response->waitForEndStream());
+    EXPECT_TRUE(response->complete());
+    EXPECT_THAT(response->headers(), Http::HttpStatusIs("503"));
+
+    cleanupUpstreamAndDownstream();
+  }
+}
+
+} // namespace
+} // namespace Router
+} // namespace Envoy
diff --git a/test/common/router/config_impl_test.cc b/test/common/router/config_impl_test.cc
index c540db9e12..7652fc001c 100644
--- a/test/common/router/config_impl_test.cc
+++ b/test/common/router/config_impl_test.cc
@@ -24,6 +24,7 @@
 #include "test/common/router/route_fuzz.pb.h"
 #include "test/extensions/filters/http/common/empty_http_filter_config.h"
 #include "test/fuzz/utility.h"
+#include "test/mocks/router/mocks.h"
 #include "test/mocks/server/instance.h"
 #include "test/mocks/upstream/retry_priority.h"
 #include "test/mocks/upstream/retry_priority_factory.h"
@@ -648,11 +649,13 @@ virtual_hosts:
     route:
       cluster: ats
       host_rewrite_header: x-rewrite-host
+      append_x_forwarded_host: true
   - match:
       path: "/do-not-rewrite-host-with-header-value"
     route:
       cluster: ats
       host_rewrite_header: x-rewrite-host
+      append_x_forwarded_host: true
   - match:
       path: "/rewrite-host-with-path-regex/envoyproxy.io"
     route:
@@ -662,6 +665,7 @@ virtual_hosts:
           google_re2: {}
           regex: "^/.+/(.+)$"
         substitution: \1
+      append_x_forwarded_host: true
   - match:
       prefix: "/"
     route:
@@ -935,6 +939,9 @@ virtual_hosts:
     EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value());
     route->finalizeRequestHeaders(headers, stream_info, true);
     EXPECT_EQ("new_host", headers.get_(Http::Headers::get().Host));
+    // Config setting append_x_forwarded_host is false (by default). Expect empty x-forwarded-host
+    // header value.
+    EXPECT_EQ("", headers.get_(Http::Headers::get().ForwardedHost));
   }
 
   // Rewrites host using supplied header.
@@ -945,6 +952,7 @@ virtual_hosts:
     EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value());
     route->finalizeRequestHeaders(headers, stream_info, true);
     EXPECT_EQ("rewrote", headers.get_(Http::Headers::get().Host));
+    EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost));
   }
 
   // Does not rewrite host because of missing header.
@@ -955,6 +963,7 @@ virtual_hosts:
     EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value());
     route->finalizeRequestHeaders(headers, stream_info, true);
     EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().Host));
+    EXPECT_EQ("", headers.get_(Http::Headers::get().ForwardedHost));
   }
 
   // Rewrites host using path.
@@ -965,6 +974,7 @@ virtual_hosts:
     EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value());
     route->finalizeRequestHeaders(headers, stream_info, true);
     EXPECT_EQ("envoyproxy.io", headers.get_(Http::Headers::get().Host));
+    EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost));
   }
 
   // Rewrites host using path, removes query parameters
@@ -975,6 +985,7 @@ virtual_hosts:
     EXPECT_FALSE(route->currentUrlPathAfterRewrite(headers).has_value());
     route->finalizeRequestHeaders(headers, stream_info, true);
     EXPECT_EQ("envoyproxy.io", headers.get_(Http::Headers::get().Host));
+    EXPECT_EQ("api.lyft.com", headers.get_(Http::Headers::get().ForwardedHost));
   }
 
   // Case sensitive rewrite matching test.
@@ -2924,6 +2935,419 @@ TEST_F(RouteMatcherTest, WeightedClusterHeader) {
   EXPECT_EQ("cluster2", config.route(headers, 560)->routeEntry()->clusterName());
 }
 
+TEST_F(RouteMatcherTest, InlineClusterSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: test
+          typed_config:
+            "@type": type.googleapis.com/google.protobuf.Struct
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<MockClusterSpecifierPluginFactoryConfig> factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  auto mock_cluster_specifier_plugin = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+
+  EXPECT_CALL(factory, createClusterSpecifierPlugin(_, _))
+      .WillOnce(Return(mock_cluster_specifier_plugin));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+
+  auto mock_route = std::make_shared<NiceMock<MockRoute>>();
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin, route(_, _)).WillOnce(Return(mock_route));
+
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get());
+}
+
+TEST_F(RouteMatcherTest, UnknownClusterSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: test
+          typed_config:
+            "@type": type.googleapis.com/google.protobuf.Struct
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  EXPECT_THROW_WITH_REGEX(
+      TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true), EnvoyException,
+      "Didn't find a registered implementation for.*");
+}
+
+TEST_F(RouteMatcherTest, UnknownClusterSpecifierPluginButOptional) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      inline_cluster_specifier_plugin:
+        extension:
+          name: test
+          typed_config:
+            "@type": type.googleapis.com/google.protobuf.Struct
+        is_optional: true
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_header: some_header
+      timeout: 0s
+  )EOF";
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  EXPECT_NO_THROW(TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true));
+}
+
+TEST_F(RouteMatcherTest, ClusterSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: test1
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test1
+- extension:
+    name: test2
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test2
+- extension:
+    name: test3
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test3
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      cluster_specifier_plugin: test2
+  - match:
+      prefix: "/bar"
+    route:
+      cluster_specifier_plugin: test3
+  )EOF";
+
+  NiceMock<MockClusterSpecifierPluginFactoryConfig> factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  auto mock_cluster_specifier_plugin_1 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_2 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_3 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+
+  EXPECT_CALL(factory, createClusterSpecifierPlugin(_, _))
+      .WillRepeatedly(Invoke(
+          [mock_cluster_specifier_plugin_1, mock_cluster_specifier_plugin_2,
+           mock_cluster_specifier_plugin_3](
+              const Protobuf::Message& config,
+              Server::Configuration::CommonFactoryContext&) -> ClusterSpecifierPluginSharedPtr {
+            const auto& typed_config = dynamic_cast<const ProtobufWkt::Struct&>(config);
+            if (auto iter = typed_config.fields().find("a"); iter == typed_config.fields().end()) {
+              return nullptr;
+            } else if (iter->second.string_value() == "test1") {
+              return mock_cluster_specifier_plugin_1;
+            } else if (iter->second.string_value() == "test2") {
+              return mock_cluster_specifier_plugin_2;
+            } else if (iter->second.string_value() == "test3") {
+              return mock_cluster_specifier_plugin_3;
+            }
+            return nullptr;
+          }));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+
+  auto mock_route = std::make_shared<NiceMock<MockRoute>>();
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_2, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get());
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_3, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/bar", "GET"), 0).get());
+}
+
+#if defined(ALIMESH)
+TEST_F(RouteMatcherTest, WeightedClusterSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: test1
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test1
+- extension:
+    name: test2
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test2
+- extension:
+    name: test3
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test3
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: cluster1
+          weight: 50
+        - name: cluster2
+          weight: 50
+        total_weight: 100
+        cluster_specifier_plugin: test2
+  - match:
+      prefix: "/bar"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: cluster1
+          weight: 50
+        - name: cluster2
+          weight: 50
+        total_weight: 100
+        cluster_specifier_plugin: test3
+  )EOF";
+
+  NiceMock<MockClusterSpecifierPluginFactoryConfig> factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  auto mock_cluster_specifier_plugin_1 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_2 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_3 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+
+  factory_context_.cluster_manager_.initializeClusters({"cluster1", "cluster2"}, {});
+
+  EXPECT_CALL(factory, createClusterSpecifierPlugin(_, _))
+      .WillRepeatedly(Invoke(
+          [mock_cluster_specifier_plugin_1, mock_cluster_specifier_plugin_2,
+           mock_cluster_specifier_plugin_3](
+              const Protobuf::Message& config,
+              Server::Configuration::CommonFactoryContext&) -> ClusterSpecifierPluginSharedPtr {
+            const auto& typed_config = dynamic_cast<const ProtobufWkt::Struct&>(config);
+            if (auto iter = typed_config.fields().find("a"); iter == typed_config.fields().end()) {
+              return nullptr;
+            } else if (iter->second.string_value() == "test1") {
+              return mock_cluster_specifier_plugin_1;
+            } else if (iter->second.string_value() == "test2") {
+              return mock_cluster_specifier_plugin_2;
+            } else if (iter->second.string_value() == "test3") {
+              return mock_cluster_specifier_plugin_3;
+            }
+            return nullptr;
+          }));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+
+  auto mock_route = std::make_shared<NiceMock<MockRoute>>();
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_2, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get());
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_3, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/bar", "GET"), 0).get());
+}
+
+TEST_F(RouteMatcherTest, WeightedClusterInlineSpecifierPlugin) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: cluster1
+          weight: 50
+        - name: cluster2
+          weight: 50
+        total_weight: 100
+        inline_cluster_specifier_plugin:
+          extension:
+            name: test2
+            typed_config:
+              "@type": type.googleapis.com/google.protobuf.Struct
+              value:
+                a: test2
+  - match:
+      prefix: "/bar"
+    route:
+      weighted_clusters:
+        clusters:
+        - name: cluster1
+          weight: 50
+        - name: cluster2
+          weight: 50
+        total_weight: 100
+        inline_cluster_specifier_plugin:
+          extension:
+            name: test3
+            typed_config:
+              "@type": type.googleapis.com/google.protobuf.Struct
+              value:
+                a: test3
+  )EOF";
+
+  NiceMock<MockClusterSpecifierPluginFactoryConfig> factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  auto mock_cluster_specifier_plugin_1 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_2 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_3 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+
+  factory_context_.cluster_manager_.initializeClusters({"cluster1", "cluster2"}, {});
+
+  EXPECT_CALL(factory, createClusterSpecifierPlugin(_, _))
+      .WillRepeatedly(Invoke(
+          [mock_cluster_specifier_plugin_1, mock_cluster_specifier_plugin_2,
+           mock_cluster_specifier_plugin_3](
+              const Protobuf::Message& config,
+              Server::Configuration::CommonFactoryContext&) -> ClusterSpecifierPluginSharedPtr {
+            const auto& typed_config = dynamic_cast<const ProtobufWkt::Struct&>(config);
+            if (auto iter = typed_config.fields().find("a"); iter == typed_config.fields().end()) {
+              return nullptr;
+            } else if (iter->second.string_value() == "test1") {
+              return mock_cluster_specifier_plugin_1;
+            } else if (iter->second.string_value() == "test2") {
+              return mock_cluster_specifier_plugin_2;
+            } else if (iter->second.string_value() == "test3") {
+              return mock_cluster_specifier_plugin_3;
+            }
+            return nullptr;
+          }));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+
+  auto mock_route = std::make_shared<NiceMock<MockRoute>>();
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_2, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/foo", "GET"), 0).get());
+
+  EXPECT_CALL(*mock_cluster_specifier_plugin_3, route(_, _)).WillOnce(Return(mock_route));
+  EXPECT_EQ(mock_route.get(), config.route(genHeaders("some_cluster", "/bar", "GET"), 0).get());
+}
+#endif
+
+TEST_F(RouteMatcherTest, UnknownClusterSpecifierPluginName) {
+  const std::string yaml = R"EOF(
+cluster_specifier_plugins:
+- extension:
+    name: test1
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test1
+- extension:
+    name: test2
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test2
+- extension:
+    name: test3
+    typed_config:
+      "@type": type.googleapis.com/google.protobuf.Struct
+      value:
+        a: test3
+virtual_hosts:
+- name: local_service
+  domains:
+  - "*"
+  routes:
+  - match:
+      prefix: "/foo"
+    route:
+      cluster_specifier_plugin: test2
+  - match:
+      prefix: "/bar"
+    route:
+      # Unknown cluster specifier plugin name.
+      cluster_specifier_plugin: test4
+  )EOF";
+
+  NiceMock<MockClusterSpecifierPluginFactoryConfig> factory;
+  Registry::InjectFactory<ClusterSpecifierPluginFactoryConfig> registered(factory);
+
+  auto mock_cluster_specifier_plugin_1 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_2 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+  auto mock_cluster_specifier_plugin_3 = std::make_shared<NiceMock<MockClusterSpecifierPlugin>>();
+
+  EXPECT_CALL(factory, createClusterSpecifierPlugin(_, _))
+      .WillRepeatedly(Invoke(
+          [mock_cluster_specifier_plugin_1, mock_cluster_specifier_plugin_2,
+           mock_cluster_specifier_plugin_3](
+              const Protobuf::Message& config,
+              Server::Configuration::CommonFactoryContext&) -> ClusterSpecifierPluginSharedPtr {
+            const auto& typed_config = dynamic_cast<const ProtobufWkt::Struct&>(config);
+            if (auto iter = typed_config.fields().find("a"); iter == typed_config.fields().end()) {
+              return nullptr;
+            } else if (iter->second.string_value() == "test1") {
+              return mock_cluster_specifier_plugin_1;
+            } else if (iter->second.string_value() == "test2") {
+              return mock_cluster_specifier_plugin_2;
+            } else if (iter->second.string_value() == "test3") {
+              return mock_cluster_specifier_plugin_3;
+            }
+            return nullptr;
+          }));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  EXPECT_THROW_WITH_MESSAGE(
+      TestConfigImpl(parseRouteConfigurationFromYaml(yaml), factory_context_, true), EnvoyException,
+      "Unknown cluster specifier plugin name: test4 is used in the route");
+}
+
 TEST_F(RouteMatcherTest, ContentType) {
   const std::string yaml = R"EOF(
 virtual_hosts:
@@ -7742,6 +8166,325 @@ virtual_hosts:
       internal_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(200)));
 }
 
+#if defined(ALIMESH)
+TEST_F(RouteConfigurationV2, InternalActiveRedirectIsDisabledWhenNotSpecifiedInRouteAction) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [idle.lyft.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/regex"
+        route:
+          cluster: some-cluster
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("idle.lyft.com", "/regex", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_FALSE(internal_active_redirect_policy.enabled());
+}
+
+TEST_F(RouteConfigurationV2, DefaultInternalActiveRedirectPolicyIsSensible) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [idle.lyft.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/regex"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_url: "taobao.com"
+              redirect_response_codes: [404]
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("idle.lyft.com", "/regex", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(503)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(200)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(302)));
+  EXPECT_EQ(1, internal_active_redirect_policy.maxInternalRedirects());
+  EXPECT_TRUE(internal_active_redirect_policy.predicates().empty());
+  EXPECT_FALSE(internal_active_redirect_policy.isCrossSchemeRedirectAllowed());
+  EXPECT_EQ("taobao.com", internal_active_redirect_policy.redirectUrl());
+}
+
+TEST_F(RouteConfigurationV2, InternalActiveRedirectPolicyDropsInvalidRedirectCode) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [idle.lyft.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/regex"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_url: "taobao.com"
+              redirect_response_codes: [301, 302, 303, 304, 307, 308, 503, 500, 404]
+              request_headers_to_add:
+                - header:
+                    key: x-req-cluster
+                    value: cluster1
+                  append: true
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("idle.lyft.com", "/regex", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+  // The 301, 302, 303, 307, 308 is invalid code.
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(301)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(302)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(303)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(307)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(308)));
+  // No configured code.
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(304)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(305)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(306)));
+  // The configured code.
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(503)));
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(500)));
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(404)));
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  Http::TestRequestHeaderMapImpl header_map{{":method", "POST"}};
+  internal_active_redirect_policy.evaluateHeaders(header_map, &stream_info);
+  EXPECT_TRUE(header_map.has("x-req-cluster"));
+  EXPECT_FALSE(header_map.has("x-client-ip"));
+}
+
+TEST_F(RouteConfigurationV2, InternalActiveRedirectPolicyDropsInvalidRedirectCodeCauseEmptySet) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [idle.lyft.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/regex"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_response_codes: [200, 301]
+              redirect_url_rewrite_regex:
+                pattern:
+                  google_re2: {}
+                  regex: "^/.+/(.+)$"
+                substitution: \1
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("idle.lyft.com", "/regex", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(302)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(301)));
+  EXPECT_FALSE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(200)));
+}
+
+TEST_F(RouteConfigurationV2, InternalActiveRedirectPolicyWithRedirectUrlRewriteRegex) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [idle.lyft.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/regex"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_response_codes: [200, 301]
+              redirect_url_rewrite_regex:
+                pattern:
+                  google_re2: {}
+                  regex: "^/.+/(.+)$"
+                substitution: \1
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("idle.lyft.com", "/regex", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+
+  std::string path("/rewrite-host-with-path-regex/envoyproxy.io");
+  EXPECT_EQ("envoyproxy.io", internal_active_redirect_policy.redirectUrl(path));
+}
+
+TEST_F(RouteConfigurationV2,
+       InternalActiveRedirectPolicyWithRedirectUrlWithYoukuKrakenRewriteRegex) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [act.youku.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/yep/page/kraken/m_pre/i_just_test"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_response_codes: [503]
+              redirect_url_rewrite_regex:
+                pattern:
+                  google_re2: {}
+                  regex: (\W|^)kraken
+                substitution: test
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("act.youku.com", "/yep/page/kraken/m_pre/i_just_test", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+
+  std::string path("/yep/page/kraken/m_pre/i_just_test");
+  EXPECT_EQ("/yep/pagetest/m_pre/i_just_test", internal_active_redirect_policy.redirectUrl(path));
+}
+
+TEST_F(RouteConfigurationV2, InternalActiveRedirectPolicyWithRedirectUrlHostRewrite) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [act.youku.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/yep/i_just_test"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_response_codes: [503]
+              redirect_url: /yep/page/kraken/m_pre/i_just_test
+              host_rewrite_literal: taobao.com
+
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("act.youku.com", "/yep/i_just_test", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+
+  EXPECT_EQ("/yep/page/kraken/m_pre/i_just_test", internal_active_redirect_policy.redirectUrl());
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  Http::TestRequestHeaderMapImpl header_map{{":method", "POST"}};
+  internal_active_redirect_policy.evaluateHeaders(header_map, &stream_info);
+  EXPECT_EQ("taobao.com", header_map.getHostValue());
+}
+
+TEST_F(RouteConfigurationV2, InternalActiveRedirectPolicyWithMultiPolicies) {
+  const std::string yaml = R"EOF(
+virtual_hosts:
+  - name: regex
+    domains: [act.youku.com]
+    routes:
+      - match:
+          safe_regex:
+            google_re2: {}
+            regex: "/yep/i_just_test"
+        route:
+          cluster: some-cluster
+          internal_active_redirect_policy:
+            policies:
+            - redirect_response_codes: [503]
+              redirect_url: /yep/page/kraken/m_pre/i_just_test
+              host_rewrite_literal: taobao.com
+            - redirect_response_codes: [505]
+              redirect_url: /yep/page/kraken/m_pre/i_just_test_505
+              host_rewrite_literal: taobao.com
+            - redirect_response_codes: [404]
+              redirect_url: /yep/page/kraken/m_pre/i_just_test_404
+              host_rewrite_literal: taobao.com
+  )EOF";
+
+  factory_context_.cluster_manager_.initializeClusters({"some-cluster"}, {});
+  TestConfigImpl config(parseRouteConfigurationFromYaml(yaml), factory_context_, true);
+  Http::TestRequestHeaderMapImpl headers =
+      genRedirectHeaders("act.youku.com", "/yep/i_just_test", true, false);
+  const auto& internal_active_redirect_policy =
+      config.route(headers, 0)->routeEntry()->internalActiveRedirectPolicy();
+  EXPECT_TRUE(internal_active_redirect_policy.enabled());
+
+  EXPECT_EQ("/yep/page/kraken/m_pre/i_just_test", internal_active_redirect_policy.redirectUrl());
+
+  NiceMock<Envoy::StreamInfo::MockStreamInfo> stream_info;
+  Http::TestRequestHeaderMapImpl header_map{{":method", "POST"}};
+  internal_active_redirect_policy.evaluateHeaders(header_map, &stream_info);
+  EXPECT_EQ("taobao.com", header_map.getHostValue());
+
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(404)));
+  EXPECT_EQ("/yep/page/kraken/m_pre/i_just_test_404",
+            internal_active_redirect_policy.redirectUrl());
+
+  EXPECT_TRUE(
+      internal_active_redirect_policy.shouldRedirectForResponseCode(static_cast<Http::Code>(505)));
+  EXPECT_EQ("/yep/page/kraken/m_pre/i_just_test_505",
+            internal_active_redirect_policy.redirectUrl());
+}
+
+#endif
+
 class PerFilterConfigsTest : public testing::Test, public ConfigImplTestBase {
 public:
   PerFilterConfigsTest()
@@ -8417,6 +9160,23 @@ virtual_hosts:
       },
       genHeaders("bat.com", "/", "GET"));
   EXPECT_NE(nullptr, dynamic_cast<const SslRedirectRoute*>(accepted_route.get()));
+#if defined(ALIMESH)
+  EXPECT_EQ(Http::Code::MovedPermanently,
+            dynamic_cast<const SslRedirectRoute*>(accepted_route.get())
+                ->directResponseEntry()
+                ->responseCode());
+  RouteConstSharedPtr accepted_route_post = config.route(
+      [](RouteConstSharedPtr, RouteEvalStatus) -> RouteMatchStatus {
+        ADD_FAILURE() << "RouteCallback should not be invoked since there are no matching "
+                         "route to override";
+        return RouteMatchStatus::Continue;
+      },
+      genHeaders("bat.com", "/", "POST"));
+  EXPECT_EQ(Http::Code::PermanentRedirect,
+            dynamic_cast<const SslRedirectRoute*>(accepted_route_post.get())
+                ->directResponseEntry()
+                ->responseCode());
+#endif
 }
 
 TEST_F(RouteMatchOverrideTest, NullRouteOnRequireTlsInternal) {
diff --git a/test/common/router/retry_state_impl_test.cc b/test/common/router/retry_state_impl_test.cc
index 1640683d81..f2199dda95 100644
--- a/test/common/router/retry_state_impl_test.cc
+++ b/test/common/router/retry_state_impl_test.cc
@@ -44,9 +44,10 @@ public:
   }
 
   void setup(Http::RequestHeaderMap& request_headers) {
-    state_ = RetryStateImpl::create(policy_, request_headers, cluster_, &virtual_cluster_, runtime_,
-                                    random_, dispatcher_, test_time_.timeSystem(),
-                                    Upstream::ResourcePriority::Default);
+
+    state_ = RetryStateImpl::create(policy_, request_headers, cluster_, &virtual_cluster_,
+                                    route_stats_context_, runtime_, random_, dispatcher_,
+                                    test_time_.timeSystem(), Upstream::ResourcePriority::Default);
   }
 
   void expectTimerCreateAndEnable() {
@@ -131,6 +132,11 @@ public:
   NiceMock<TestRetryPolicy> policy_;
   NiceMock<Upstream::MockClusterInfo> cluster_;
   TestVirtualCluster virtual_cluster_;
+  Stats::IsolatedStoreImpl stats_store_;
+  Stats::StatNameManagedStorage stat_name_{"fake_route", stats_store_.symbolTable()};
+  RouteStatNames stat_names_{stats_store_.symbolTable()};
+  RouteStatsContext route_stats_context_{stats_store_, stat_names_, stat_name_.statName(),
+                                         "fake_route"};
   NiceMock<Runtime::MockLoader> runtime_;
   NiceMock<Random::MockRandomGenerator> random_;
   Event::MockDispatcher dispatcher_;
@@ -168,10 +174,14 @@ TEST_F(RouterRetryStateImplTest, PolicyRefusedStream) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_.value());
 }
 
+
+
 TEST_F(RouterRetryStateImplTest, Policy5xxResetOverflow) {
   Http::TestRequestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}};
   setup(request_headers);
@@ -193,8 +203,10 @@ TEST_F(RouterRetryStateImplTest, Policy5xxRemoteReset) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, Policy5xxRemote503) {
@@ -275,8 +287,10 @@ TEST_F(RouterRetryStateImplTest, PolicyGatewayErrorRemoteReset) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, PolicyGrpcCancelled) {
@@ -317,8 +331,10 @@ TEST_F(RouterRetryStateImplTest, Policy5xxRemote200RemoteReset) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, RuntimeGuard) {
@@ -666,8 +682,10 @@ TEST_F(RouterRetryStateImplTest, PolicyResetRemoteReset) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, PolicyLimitedByRequestHeaders) {
@@ -746,8 +764,10 @@ TEST_F(RouterRetryStateImplTest, RouteConfigNoRetriesAllowed) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(0UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(0UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, RouteConfigNoHeaderConfig) {
@@ -773,6 +793,7 @@ TEST_F(RouterRetryStateImplTest, NoAvailableRetries) {
   EXPECT_EQ(RetryStatus::NoOverflow, state_->shouldRetryReset(connect_failure_, callback_));
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_overflow_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_overflow_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_overflow_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, MaxRetriesHeader) {
@@ -809,6 +830,9 @@ TEST_F(RouterRetryStateImplTest, MaxRetriesHeader) {
   EXPECT_EQ(3UL, virtual_cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(0UL, virtual_cluster_.stats().upstream_rq_retry_success_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(3UL, route_stats_context_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(0UL, route_stats_context_.stats().upstream_rq_retry_success_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, Backoff) {
@@ -844,6 +868,8 @@ TEST_F(RouterRetryStateImplTest, Backoff) {
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_success_.value());
   EXPECT_EQ(3UL, virtual_cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_success_.value());
+  EXPECT_EQ(3UL, route_stats_context_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_success_.value());
   EXPECT_EQ(0UL, cluster_.circuit_breakers_stats_.rq_retry_open_.value());
 }
 
@@ -1094,8 +1120,10 @@ TEST_F(RouterRetryStateImplTest, ZeroMaxRetriesHeader) {
 
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(1UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(0UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(0UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(0UL, route_stats_context_.stats().upstream_rq_retry_.value());
 }
 
 // Check that if there are 0 remaining retries available but we get
@@ -1114,8 +1142,10 @@ TEST_F(RouterRetryStateImplTest, NoPreferredOverLimitExceeded) {
 
   EXPECT_EQ(0UL, cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(0UL, virtual_cluster_.stats().upstream_rq_retry_limit_exceeded_.value());
+  EXPECT_EQ(0UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
   EXPECT_EQ(1UL, cluster_.stats().upstream_rq_retry_.value());
   EXPECT_EQ(1UL, virtual_cluster_.stats().upstream_rq_retry_.value());
+  EXPECT_EQ(0UL, route_stats_context_.stats().upstream_rq_retry_limit_exceeded_.value());
 }
 
 TEST_F(RouterRetryStateImplTest, BudgetAvailableRetries) {
diff --git a/test/common/router/router_2_test.cc b/test/common/router/router_2_test.cc
index 4b6b9ddd72..26930235fe 100644
--- a/test/common/router/router_2_test.cc
+++ b/test/common/router/router_2_test.cc
@@ -336,6 +336,9 @@ TEST_F(RouterTestChildSpan, BasicFlow) {
   EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _))
       .WillOnce(Return(child_span));
   EXPECT_CALL(callbacks_, tracingConfig());
+#if defined(ALIMESH)
+  EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().PeerIpv4), Eq("10.0.0.5")));
+#endif
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -382,6 +385,9 @@ TEST_F(RouterTestChildSpan, ResetFlow) {
   EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _))
       .WillOnce(Return(child_span));
   EXPECT_CALL(callbacks_, tracingConfig());
+#if defined(ALIMESH)
+  EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().PeerIpv4), Eq("10.0.0.5")));
+#endif
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -432,6 +438,9 @@ TEST_F(RouterTestChildSpan, CancelFlow) {
   EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _))
       .WillOnce(Return(child_span));
   EXPECT_CALL(callbacks_, tracingConfig());
+#if defined(ALIMESH)
+  EXPECT_CALL(*child_span, setTag(Eq(Tracing::Tags::get().PeerIpv4), Eq("10.0.0.5")));
+#endif
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -479,6 +488,9 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) {
   EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _))
       .WillOnce(Return(child_span_1));
   EXPECT_CALL(callbacks_, tracingConfig());
+#if defined(ALIMESH)
+  EXPECT_CALL(*child_span_1, setTag(Eq(Tracing::Tags::get().PeerIpv4), Eq("10.0.0.5")));
+#endif
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -519,6 +531,9 @@ TEST_F(RouterTestChildSpan, ResetRetryFlow) {
   EXPECT_CALL(callbacks_.active_span_, spawnChild_(_, "router fake_cluster egress", _))
       .WillOnce(Return(child_span_2));
   EXPECT_CALL(callbacks_, tracingConfig());
+#if defined(ALIMESH)
+  EXPECT_CALL(*child_span_2, setTag(Eq(Tracing::Tags::get().PeerIpv4), Eq("10.0.0.5")));
+#endif
   EXPECT_CALL(*child_span_2, setTag(Eq(Tracing::Tags::get().RetryCount), Eq("1")));
 
   router_.retry_state_->callback_();
diff --git a/test/common/router/router_test.cc b/test/common/router/router_test.cc
index 1ff5661d20..ccd19e7ea9 100644
--- a/test/common/router/router_test.cc
+++ b/test/common/router/router_test.cc
@@ -55,6 +55,7 @@ using testing::AtLeast;
 using testing::Eq;
 using testing::InSequence;
 using testing::Invoke;
+using testing::InvokeWithoutArgs;
 using testing::MockFunction;
 using testing::NiceMock;
 using testing::Property;
@@ -323,7 +324,7 @@ TEST_F(RouterTest, MissingRequiredHeaders) {
       sendLocalReply(Http::Code::ServiceUnavailable,
                      testing::Eq("missing required header: :method"), _, _,
                      "filter_removed_required_request_headers{missing required header: :method}"))
-      .WillOnce(testing::InvokeWithoutArgs([] {}));
+      .WillOnce(InvokeWithoutArgs([] {}));
   router_.decodeHeaders(headers, true);
   router_.onDestroy();
 }
@@ -3775,8 +3776,7 @@ TEST_F(RouterTest, RetryUpstreamResetResponseStarted) {
   // Normally, sendLocalReply will actually send the reply, but in this case the
   // HCM will detect the headers have already been sent and not route through
   // the encoder again.
-  EXPECT_CALL(callbacks_, sendLocalReply(_, _, _, _, _)).WillOnce(testing::InvokeWithoutArgs([] {
-  }));
+  EXPECT_CALL(callbacks_, sendLocalReply(_, _, _, _, _)).WillOnce(InvokeWithoutArgs([] {}));
   encoder1.stream_.resetStream(Http::StreamResetReason::RemoteReset);
   // For normal HTTP, once we have a 200 we consider this a success, even if a
   // later reset occurs.
@@ -4736,6 +4736,33 @@ TEST_F(RouterTest, HttpInternalRedirectSucceeded) {
                    .value());
 }
 
+TEST_F(RouterTest, HttpInternalRedirectMatchedToDirectResponseSucceeded) {
+  NiceMock<MockDirectResponseEntry> direct_response;
+  std::string route_name("route-test-name");
+  EXPECT_CALL(direct_response, routeName()).WillOnce(ReturnRef(route_name));
+
+  enableRedirects();
+  sendRequest();
+  EXPECT_CALL(callbacks_, clearRouteCache()).WillOnce(InvokeWithoutArgs([&]() -> void {
+    // Direct message route should be matched after internal redirect
+    EXPECT_CALL(*callbacks_.route_, routeEntry()).WillRepeatedly(Return(nullptr));
+    EXPECT_CALL(*callbacks_.route_, directResponseEntry()).WillRepeatedly(Return(&direct_response));
+  }));
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+  EXPECT_EQ(1, callbacks_.streamInfo()
+                   .filterState()
+                   ->getDataMutable<StreamInfo::UInt32Accessor>("num_internal_redirects")
+                   .value());
+}
+
 TEST_F(RouterTest, InternalRedirectStripsFragment) {
   enableRedirects();
   default_request_headers_.setForwardedProto("http");
@@ -4821,6 +4848,264 @@ TEST_F(RouterTest, CrossSchemeRedirectAllowedByPolicy) {
   router_.onDestroy();
 }
 
+#if defined(ALIMESH)
+TEST_F(RouterTest, InternalActiveRedirectRejectedWhenReachingMaxInternalRedirect) {
+  enableActiveRedirects("http://www.foo.com", 3);
+  setNumPreviousRedirect(3);
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+  EXPECT_EQ(1UL,
+            stats_store_.counter("test.passthrough_internal_redirect_too_many_redirects").value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedWithEmptyLocation) {
+  enableActiveRedirects("");
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+  EXPECT_EQ(1UL, stats_store_.counter("test.passthrough_internal_redirect_bad_location").value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedWithInvalidLocation) {
+  enableActiveRedirects("h");
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+  EXPECT_EQ(1UL, stats_store_.counter("test.passthrough_internal_redirect_bad_location").value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedWithoutCompleteRequest) {
+  enableActiveRedirects("http://www.foo.com", 3);
+
+  sendRequest(false);
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedWithoutLocation) {
+  enableActiveRedirects("");
+
+  sendRequest();
+
+  redirect_headers_->removeLocation();
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedWithBody) {
+  enableActiveRedirects("http://www.foo.com");
+
+  sendRequest();
+
+  Buffer::InstancePtr body_data(new Buffer::OwnedImpl("random_fake_data"));
+  EXPECT_CALL(callbacks_, decodingBuffer()).WillRepeatedly(Return(body_data.get()));
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+  Buffer::OwnedImpl data("1234567890");
+  response_decoder_->decodeData(data, true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+}
+
+TEST_F(RouterTest, CrossSchemeActiveRedirectRejectedByPolicy) {
+  enableActiveRedirects("https://www.foo.com");
+
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+  EXPECT_EQ(1UL, stats_store_.counter("test.passthrough_internal_redirect_unsafe_scheme").value());
+}
+
+TEST_F(RouterTest, InternalActiveRedirectRejectedByPredicate) {
+  enableActiveRedirects("http://www.foo.com/some/path");
+  sendRequest();
+
+  auto mock_predicate = std::make_shared<NiceMock<MockInternalRedirectPredicate>>();
+
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, predicates())
+      .WillOnce(Return(std::vector<InternalRedirectPredicateSharedPtr>({mock_predicate})));
+  EXPECT_CALL(*mock_predicate, acceptTargetRoute(_, _, _, _)).WillOnce(Return(false));
+  ON_CALL(*mock_predicate, name()).WillByDefault(Return("mock_predicate"));
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), true);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_failed_total")
+                    .value());
+  EXPECT_EQ(1UL, stats_store_.counter("test.passthrough_internal_redirect_predicate").value());
+
+  // Make sure the original host/path is preserved.
+  EXPECT_EQ("host", default_request_headers_.getHostValue());
+  EXPECT_EQ("/", default_request_headers_.getPathValue());
+  // Make sure x-envoy-original-url is not set for unsuccessful redirect.
+  EXPECT_EQ(nullptr, default_request_headers_.EnvoyOriginalUrl());
+}
+
+TEST_F(RouterTest, HttpInternalActiveRedirectSucceeded) {
+  enableActiveRedirects("http://www.foo.com/some/path", 3);
+  setNumPreviousRedirect(2);
+  default_request_headers_.setForwardedProto("http");
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+  response_decoder_->decodeHeaders(std::move(redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+  EXPECT_EQ(3, callbacks_.streamInfo()
+                   .filterState()
+                   ->getDataMutable<StreamInfo::UInt32Accessor>("num_internal_redirects")
+                   .value());
+}
+
+TEST_F(RouterTest, HttpsInternalActiveRedirectSucceeded) {
+  auto ssl_connection = std::make_shared<Ssl::MockConnectionInfo>();
+  enableActiveRedirects("https://www.foo.com", 3);
+  setNumPreviousRedirect(1);
+  default_request_headers_.setScheme("https");
+
+  sendRequest();
+
+  EXPECT_CALL(connection_, ssl()).WillOnce(Return(ssl_connection));
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+}
+
+TEST_F(RouterTest, CrossSchemeActiveRedirectAllowedByPolicy) {
+  auto ssl_connection = std::make_shared<Ssl::MockConnectionInfo>();
+  enableActiveRedirects("http://www.redirect-url.com", 1);
+  default_request_headers_.setScheme("https");
+
+  sendRequest();
+
+  EXPECT_CALL(connection_, ssl()).WillOnce(Return(ssl_connection));
+  EXPECT_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_,
+              isCrossSchemeRedirectAllowed())
+      .WillOnce(Return(true));
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+  EXPECT_EQ("www.redirect-url.com", std::string(default_request_headers_.getHostValue()));
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+}
+
+TEST_F(RouterTest, UseOriginalHost) {
+  auto ssl_connection = std::make_shared<Ssl::MockConnectionInfo>();
+  enableActiveRedirects("http://www.redirect-url.com", 1, true);
+  default_request_headers_.setHost("original-test-host.com");
+
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+  EXPECT_EQ("original-test-host.com", std::string(default_request_headers_.getHostValue()));
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+}
+
+TEST_F(RouterTest, ForcedAddHeaderBeforeRouteMatcher) {
+  auto ssl_connection = std::make_shared<Ssl::MockConnectionInfo>();
+  enableActiveRedirects("http://www.redirect-url.com", 1, false, true);
+
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, recreateStream(_)).WillOnce(Return(true));
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+  EXPECT_EQ(1U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+  EXPECT_EQ(true, default_request_headers_.has("test_added_header"));
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+}
+
+TEST_F(RouterTest, ForcedAddHeaderBeforeRouteMatcherWithRouteFailure) {
+  auto ssl_connection = std::make_shared<Ssl::MockConnectionInfo>();
+  enableActiveRedirects("http://www.redirect-url.com", 1, false, true);
+
+  sendRequest();
+
+  EXPECT_CALL(callbacks_, clearRouteCache());
+  EXPECT_CALL(callbacks_, route()).WillOnce(Return(nullptr));;
+  EXPECT_CALL(callbacks_, recreateStream(_)).Times(0);
+  response_decoder_->decodeHeaders(std::move(active_redirect_headers_), false);
+  EXPECT_EQ(0U, cm_.thread_local_cluster_.cluster_.info_->stats_store_
+                    .counter("upstream_internal_redirect_succeeded_total")
+                    .value());
+  EXPECT_EQ(true, default_request_headers_.has("test_added_header"));
+  // In production, the HCM recreateStream would have called this.
+  router_.onDestroy();
+}
+#endif
+
 TEST_F(RouterTest, Shadow) {
   ShadowPolicyPtr policy = std::make_unique<TestShadowPolicy>("foo", "bar");
   callbacks_.route_->route_entry_.shadow_policies_.push_back(std::move(policy));
@@ -5946,6 +6231,9 @@ TEST_F(RouterTest, CanaryStatusTrue) {
   Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"},
                                          {"x-envoy-internal", "true"}};
   HttpTestUtility::addDefaultHeaders(headers);
+  const absl::optional<std::string> virtual_cluster_name =
+      absl::optional<std::string>("fake_virtual_cluster");
+  EXPECT_CALL(callbacks_.stream_info_, setVirtualClusterName(virtual_cluster_name));
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -5983,6 +6271,9 @@ TEST_F(RouterTest, CanaryStatusFalse) {
   Http::TestRequestHeaderMapImpl headers{{"x-envoy-upstream-alt-stat-name", "alt_stat"},
                                          {"x-envoy-internal", "true"}};
   HttpTestUtility::addDefaultHeaders(headers);
+  const absl::optional<std::string> virtual_cluster_name =
+      absl::optional<std::string>("fake_virtual_cluster");
+  EXPECT_CALL(callbacks_.stream_info_, setVirtualClusterName(virtual_cluster_name));
   router_.decodeHeaders(headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
@@ -5999,7 +6290,11 @@ TEST_F(RouterTest, CanaryStatusFalse) {
                 .value());
 }
 
+#if defined(ALIMESH)
+TEST_F(RouterTest, DISABLED_AutoHostRewriteEnabled) {
+#else
 TEST_F(RouterTest, AutoHostRewriteEnabled) {
+#endif
   NiceMock<Http::MockRequestEncoder> encoder;
   std::string req_host{"foo.bar.com"};
 
@@ -6011,6 +6306,7 @@ TEST_F(RouterTest, AutoHostRewriteEnabled) {
   Http::TestRequestHeaderMapImpl outgoing_headers;
   HttpTestUtility::addDefaultHeaders(outgoing_headers);
   outgoing_headers.setHost(cm_.thread_local_cluster_.conn_pool_.host_->hostname_);
+  outgoing_headers.setForwardedHost(req_host);
 
   EXPECT_CALL(callbacks_.route_->route_entry_, timeout())
       .WillOnce(Return(std::chrono::milliseconds(0)));
@@ -6036,6 +6332,7 @@ TEST_F(RouterTest, AutoHostRewriteEnabled) {
         EXPECT_EQ(host_address_, host->address());
       }));
   EXPECT_CALL(callbacks_.route_->route_entry_, autoHostRewrite()).WillOnce(Return(true));
+  EXPECT_CALL(callbacks_.route_->route_entry_, appendXfh()).WillOnce(Return(true));
   router_.decodeHeaders(incoming_headers, true);
   EXPECT_EQ(1U,
             callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());
diff --git a/test/common/router/router_test_base.cc b/test/common/router/router_test_base.cc
index dc598c6e4f..7acb133787 100644
--- a/test/common/router/router_test_base.cc
+++ b/test/common/router/router_test_base.cc
@@ -250,6 +250,44 @@ void RouterTestBase::setNumPreviousRedirect(uint32_t num_previous_redirects) {
       StreamInfo::FilterState::StateType::Mutable, StreamInfo::FilterState::LifeSpan::Request);
 }
 
+#if defined(ALIMESH)
+void RouterTestBase::enableActiveRedirects(std::string redirect_url,
+                                           uint32_t max_internal_redirects,
+                                           bool forced_use_original_host,
+                                           bool forced_add_header_before_route_matcher) {
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, enabled())
+      .WillByDefault(Return(true));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_,
+          shouldRedirectForResponseCode(_))
+      .WillByDefault(Return(true));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, maxInternalRedirects())
+      .WillByDefault(Return(max_internal_redirects));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_,
+          isCrossSchemeRedirectAllowed())
+      .WillByDefault(Return(false));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, redirectUrl(_))
+      .WillByDefault(Return(redirect_url));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, evaluateHeaders(_, _))
+      .WillByDefault(Invoke([&](Http::HeaderMap& headers, const StreamInfo::StreamInfo*) -> void {
+        const Envoy::Http::LowerCaseString key("test_added_header");
+        headers.addCopy(key, 1111);
+      }));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_, forcedUseOriginalHost())
+      .WillByDefault(Return(forced_use_original_host));
+  ON_CALL(callbacks_.route_->route_entry_.internal_active_redirect_policy_,
+          forcedAddHeaderBeforeRouteMatcher())
+      .WillByDefault(Return(forced_add_header_before_route_matcher));
+  ON_CALL(callbacks_, connection()).WillByDefault(Return(&connection_));
+}
+
+void RouterTestBase::setNumPreviousActiveRedirect(uint32_t num_previous_redirects) {
+  callbacks_.streamInfo().filterState()->setData(
+      "num_internal_redirects",
+      std::make_shared<StreamInfo::UInt32AccessorImpl>(num_previous_redirects),
+      StreamInfo::FilterState::StateType::Mutable, StreamInfo::FilterState::LifeSpan::Request);
+}
+#endif
+
 void RouterTestBase::setIncludeAttemptCountInRequest(bool include) {
   ON_CALL(callbacks_.route_->route_entry_, includeAttemptCountInRequest())
       .WillByDefault(Return(include));
diff --git a/test/common/router/router_test_base.h b/test/common/router/router_test_base.h
index 0dff3f0ade..e9c0e253ae 100644
--- a/test/common/router/router_test_base.h
+++ b/test/common/router/router_test_base.h
@@ -30,8 +30,9 @@ public:
   // Filter
   RetryStatePtr createRetryState(const RetryPolicy&, Http::RequestHeaderMap&,
                                  const Upstream::ClusterInfo&, const VirtualCluster*,
-                                 Runtime::Loader&, Random::RandomGenerator&, Event::Dispatcher&,
-                                 TimeSource&, Upstream::ResourcePriority) override {
+                                 RouteStatsContextOptRef, Runtime::Loader&,
+                                 Random::RandomGenerator&, Event::Dispatcher&, TimeSource&,
+                                 Upstream::ResourcePriority) override {
     EXPECT_EQ(nullptr, retry_state_);
     retry_state_ = new NiceMock<MockRetryState>();
     if (reject_all_hosts_) {
@@ -45,6 +46,16 @@ public:
     return &downstream_connection_;
   }
 
+#if defined(ALIMESH)
+  Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers,
+                                          bool end_stream) override {
+    auto status = Filter::decodeHeaders(headers, end_stream);
+    // TODO: deletes the header and consider using custom headers.
+    headers.remove(Http::CustomHeaders::get().AliExtendedValues.TriStartTime);
+    return status;
+  }
+#endif
+
   NiceMock<Network::MockConnection> downstream_connection_;
   MockRetryState* retry_state_{};
   bool reject_all_hosts_ = false;
@@ -79,6 +90,15 @@ public:
                               absl::optional<Http::LowerCaseString> host_address_header_name);
   void testDoNotForward(absl::optional<Http::LowerCaseString> not_forwarded_header_name);
 
+#if defined(ALIMESH)
+  void enableActiveRedirects(std::string redirect_url, uint32_t max_internal_redirects = 1,
+                             bool forced_use_original_host = false,
+                             bool forced_add_header_before_route_matcher = false);
+  void setNumPreviousActiveRedirect(uint32_t num_previous_redirects);
+
+  Http::ResponseHeaderMapPtr active_redirect_headers_{
+      new Http::TestResponseHeaderMapImpl{{":status", "502"}, {"location", "http://www.foo.com"}}};
+#endif
   Event::SimulatedTimeSystem test_time_;
   std::string upstream_zone_{"to_az"};
   envoy::config::core::v3::Locality upstream_locality_;
diff --git a/test/common/router/router_upstream_log_test.cc b/test/common/router/router_upstream_log_test.cc
index 612790a8ee..802ac6cb05 100644
--- a/test/common/router/router_upstream_log_test.cc
+++ b/test/common/router/router_upstream_log_test.cc
@@ -64,8 +64,9 @@ public:
   // Filter
   RetryStatePtr createRetryState(const RetryPolicy&, Http::RequestHeaderMap&,
                                  const Upstream::ClusterInfo&, const VirtualCluster*,
-                                 Runtime::Loader&, Random::RandomGenerator&, Event::Dispatcher&,
-                                 TimeSource&, Upstream::ResourcePriority) override {
+                                 RouteStatsContextOptRef, Runtime::Loader&,
+                                 Random::RandomGenerator&, Event::Dispatcher&, TimeSource&,
+                                 Upstream::ResourcePriority) override {
     EXPECT_EQ(nullptr, retry_state_);
     retry_state_ = new NiceMock<MockRetryState>();
     return RetryStatePtr{retry_state_};
@@ -75,6 +76,16 @@ public:
     return &downstream_connection_;
   }
 
+#if defined(ALIMESH)
+  Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap& headers,
+                                          bool end_stream) override {
+    auto status = Filter::decodeHeaders(headers, end_stream);
+    // TODO: deletes the header and consider using custom headers.
+    headers.remove(Http::CustomHeaders::get().AliExtendedValues.TriStartTime);
+    return status;
+  }
+#endif
+
   NiceMock<Network::MockConnection> downstream_connection_;
   MockRetryState* retry_state_{};
 };
diff --git a/test/common/signal/fatal_action_test.cc b/test/common/signal/fatal_action_test.cc
index 5565c592ee..7680b17eea 100644
--- a/test/common/signal/fatal_action_test.cc
+++ b/test/common/signal/fatal_action_test.cc
@@ -66,6 +66,10 @@ protected:
   int counter_ = 0;
 };
 
+// A memory leak error occurred during test platform execution, which was verified to be a false
+// positive, so this unit test was shielded
+#if !defined(ALIMESH)
+
 TEST_F(FatalActionTest, ShouldNotBeAbleToRunActionsBeforeRegistration) {
   // Call the actions
   EXPECT_EQ(FatalErrorHandler::runSafeActions(), Status::ActionManagerUnset);
@@ -128,5 +132,7 @@ TEST_F(FatalActionTest, ShouldOnlyBeAbleToRunUnsafeActionsFromThreadThatRanSafeA
   fatal_action_thread->join();
 }
 
+#endif
+
 } // namespace FatalAction
 } // namespace Envoy
diff --git a/test/common/stream_info/test_util.h b/test/common/stream_info/test_util.h
index 8026bde7de..7698048f46 100644
--- a/test/common/stream_info/test_util.h
+++ b/test/common/stream_info/test_util.h
@@ -142,6 +142,14 @@ public:
     last_downstream_tx_byte_sent_ = timeSystem().monotonicTime();
   }
 
+  const absl::optional<std::string>& virtualClusterName() const override {
+    return virtual_cluster_name_;
+  }
+
+  void setVirtualClusterName(const absl::optional<std::string>& name)  {
+    virtual_cluster_name_ = name;
+  }
+
   void onRequestComplete() override { end_time_ = timeSystem().monotonicTime(); }
 
   void setUpstreamTiming(const Envoy::StreamInfo::UpstreamTiming& upstream_timing) override {
@@ -241,6 +249,7 @@ public:
   bool health_check_request_{};
   std::string route_name_;
   Network::Address::InstanceConstSharedPtr upstream_local_address_;
+  absl::optional<std::string> virtual_cluster_name_;
   Network::ConnectionInfoSetterSharedPtr downstream_connection_info_provider_{
       std::make_shared<Network::ConnectionInfoSetterImpl>(nullptr, nullptr)};
   Ssl::ConnectionInfoConstSharedPtr downstream_connection_info_;
diff --git a/test/common/upstream/load_balancer_impl_test.cc b/test/common/upstream/load_balancer_impl_test.cc
index 78e6d1f746..97931f4265 100644
--- a/test/common/upstream/load_balancer_impl_test.cc
+++ b/test/common/upstream/load_balancer_impl_test.cc
@@ -43,6 +43,9 @@ public:
     return std::chrono::time_point_cast<std::chrono::milliseconds>(edf_lb.latest_host_added_time_)
         .time_since_epoch();
   }
+  static double slowStartMinWeightPercent(const EdfLoadBalancerBase& edf_lb) {
+    return edf_lb.slow_start_min_weight_percent_;
+  }
 };
 
 namespace {
@@ -1587,6 +1590,26 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartWithDefaultParams) {
   const auto latest_host_added_time =
       EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
   EXPECT_EQ(std::chrono::milliseconds(0), latest_host_added_time);
+  const auto slow_start_min_weight_percent =
+      EdfLoadBalancerBasePeer::slowStartMinWeightPercent(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_DOUBLE_EQ(slow_start_min_weight_percent, 0.1);
+}
+
+TEST_P(RoundRobinLoadBalancerTest, SlowStartWithMinWeightPercent) {
+  round_robin_lb_config_.mutable_slow_start_config()->mutable_min_weight_percent()->set_value(30);
+  init(false);
+  const auto slow_start_window =
+      EdfLoadBalancerBasePeer::slowStartWindow(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_EQ(std::chrono::milliseconds(0), slow_start_window);
+  const auto aggression =
+      EdfLoadBalancerBasePeer::aggression(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_EQ(1.0, aggression);
+  const auto latest_host_added_time =
+      EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_EQ(std::chrono::milliseconds(0), latest_host_added_time);
+  const auto slow_start_min_weight_percent =
+      EdfLoadBalancerBasePeer::slowStartMinWeightPercent(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_DOUBLE_EQ(slow_start_min_weight_percent, 0.3);
 }
 
 TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWait) {
@@ -1623,7 +1646,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWait) {
       EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
   EXPECT_EQ(std::chrono::milliseconds(62000), latest_host_added_time_ms);
 
-  // host2 is 12 secs in slow start, the weight is scaled with time factor 12 / 60 == 0.2.
+  // host2 is 12 secs in slow start, the weight is scaled with time factor max(12 / 60, 0.1) = 0.2.
   simTime().advanceTimeWait(std::chrono::seconds(12));
 
   // Recalculate weights.
@@ -1710,7 +1733,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartWaitForPassingHC) {
   hostSet().runCallbacks({}, {});
 
   // We expect 3:1 ratio, as host2 is in slow start mode, its weight is scaled with time factor
-  // 5 / 10 == 0.5.
+  // max(6/10, 0.1) = 0.6.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
@@ -1754,7 +1777,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartWithRuntimeAggression) {
   EXPECT_EQ(std::chrono::milliseconds(1000), latest_host_added_time_ms);
 
   // We should see 2:1:1 ratio, as hosts 2 and 3 are in slow start, their weights are scaled with
-  // 0.5 factor.
+  // max(0.5,0.1)=0.5 factor.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[2], lb_->chooseHost(nullptr));
@@ -1774,8 +1797,8 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartWithRuntimeAggression) {
       EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
   EXPECT_EQ(std::chrono::milliseconds(10000), latest_host_added_time_ms);
 
-  // We should see 1:1:1:0 ratio, as host 2 and 3 weight is scaled with (9/10)^(1/1.5)=0.93 factor,
-  // host4 weight is 0.002.
+  // We should see 1:1:1:0 ratio, as host 2 and 3 weight is scaled with max((9/10)^(1/1.5),0.1)=0.93
+  // factor, host4 weight is 1*max(0.002,0.1)=0.1.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[2], lb_->chooseHost(nullptr));
@@ -1783,7 +1806,8 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartWithRuntimeAggression) {
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[2], lb_->chooseHost(nullptr));
 
-  // host4 is 9 seconds in slow start, it's weight is scaled with (9/10)^(1/1.5)=0.93 factor.
+  // host4 is 9 seconds in slow start, it's weight is scaled with max((9/10)^(1/1.5), 0.1)=0.93
+  // factor.
   simTime().advanceTimeWait(std::chrono::seconds(9));
   hostSet().runCallbacks({}, {});
 
@@ -1808,7 +1832,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitNonLinearAggression) {
   hostSet().healthy_hosts_ = {makeTestHost(info_, "tcp://127.0.0.1:80", simTime())};
   hostSet().hosts_ = hostSet().healthy_hosts_;
   simTime().advanceTimeWait(std::chrono::seconds(5));
-  // Host1 is 5 secs in slow start, its weight is scaled with (0.5/60)^(1/2)=0.28 factor.
+  // Host1 is 5 secs in slow start, its weight is scaled with max((5/60)^(1/2), 0.1)=0.28 factor.
   hostSet().runCallbacks({}, {});
 
   // Advance time, so that host1 is no longer in slow start.
@@ -1821,7 +1845,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitNonLinearAggression) {
 
   hostSet().healthy_hosts_.push_back(host2);
   hostSet().hosts_ = hostSet().healthy_hosts_;
-  // host2 weight is scaled with 0.004 factor.
+  // host2 weight is scaled with max((0.001/60)^(1/2), 0.1)=max(0.004, 0.1)=0.1 factor.
   hostSet().runCallbacks(hosts_added, {});
 
   // host2 is 6 secs in slow start.
@@ -1831,7 +1855,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitNonLinearAggression) {
   hostSet().runCallbacks({}, {});
 
   // We expect 3:1 ratio, as host2 is 6 secs in slow start mode and it's weight is scaled with
-  // pow(0.1, 0.5)==0.31 factor.
+  // max(pow(0.1, 0.5), 0.1)=0.31 factor.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
@@ -1844,7 +1868,7 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitNonLinearAggression) {
   hostSet().runCallbacks({}, {});
 
   // We still expect 5:3 ratio, as host2 is in slow start mode and it's weight is scaled with
-  // pow(0.43, 0.5)==0.65 factor.
+  // max(pow(0.43, 0.5), 0.1)=0.65 factor.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
@@ -1867,6 +1891,102 @@ TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitNonLinearAggression) {
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
 }
 
+TEST_P(RoundRobinLoadBalancerTest, SlowStartNoWaitMinWeightPercent35) {
+  round_robin_lb_config_.mutable_slow_start_config()->mutable_slow_start_window()->set_seconds(60);
+  round_robin_lb_config_.mutable_slow_start_config()->mutable_min_weight_percent()->set_value(35);
+  simTime().advanceTimeWait(std::chrono::seconds(1));
+  auto host1 = makeTestHost(info_, "tcp://127.0.0.1:80", simTime());
+  host_set_.hosts_ = {host1};
+
+  init(true);
+
+  // As no healthcheck is configured, hosts would enter slow start immediately.
+  HostVector empty;
+  HostVector hosts_added;
+  hosts_added.push_back(host1);
+  simTime().advanceTimeWait(std::chrono::seconds(5));
+  hostSet().runCallbacks(hosts_added, empty);
+  auto latest_host_added_time_ms =
+      EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_EQ(std::chrono::milliseconds(1000), latest_host_added_time_ms);
+
+  // Advance time, so that host is no longer in slow start.
+  simTime().advanceTimeWait(std::chrono::seconds(56));
+
+  hosts_added.clear();
+  auto host2 = makeTestHost(info_, "tcp://127.0.0.1:90", simTime());
+
+  hosts_added.push_back(host2);
+
+  hostSet().healthy_hosts_ = {host1, host2};
+  hostSet().hosts_ = hostSet().healthy_hosts_;
+  hostSet().runCallbacks(hosts_added, empty);
+
+  latest_host_added_time_ms =
+      EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(*lb_));
+  EXPECT_EQ(std::chrono::milliseconds(62000), latest_host_added_time_ms);
+
+  // host2 is 12 secs in slow start, the weight is scaled with time factor max(12 / 60, 0.35) =
+  // 0.35.
+  simTime().advanceTimeWait(std::chrono::seconds(12));
+
+  // Recalculate weights.
+  hostSet().runCallbacks(empty, empty);
+
+  // We expect 5:2 ratio, as host2 is in slow start mode and it's weight is scaled with
+  // 0.35 factor.
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[1,20/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[2,20/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[3,20/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[3,40/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[4,40/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[5,40/7]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[6,40/7]
+
+  // host2 is 30 secs in slow start, the weight is scaled with time factor max(30 / 60, 0.35) ==
+  // 0.5.
+  simTime().advanceTimeWait(std::chrono::seconds(18));
+
+  // Recalculate weights.
+  hostSet().runCallbacks(empty, empty);
+
+  // We expect 2:1 ratio, as host2 is in slow start mode and it's weight is scaled with
+  // 0.5 factor.
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[1,2]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[2,2]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[2,4]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[3,4]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[4,4]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[4,6]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_->chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[5,6]
+
+  // Advance time, so that there are no hosts in slow start.
+  simTime().advanceTimeWait(std::chrono::seconds(45));
+
+  // Recalculate weights.
+  hostSet().runCallbacks(empty, empty);
+
+  // Now expect 1:1 ratio.
+  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
+  EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
+  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_->chooseHost(nullptr));
+  EXPECT_EQ(hostSet().healthy_hosts_[1], lb_->chooseHost(nullptr));
+}
+
 class LeastRequestLoadBalancerTest : public LoadBalancerTestBase {
 public:
   LeastRequestLoadBalancer lb_{
@@ -2141,6 +2261,9 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartWithDefaultParams) {
   const auto latest_host_added_time =
       EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(lb_2));
   EXPECT_EQ(std::chrono::milliseconds(0), latest_host_added_time);
+  const auto slow_start_min_weight_percent =
+      EdfLoadBalancerBasePeer::slowStartMinWeightPercent(static_cast<EdfLoadBalancerBase&>(lb_2));
+  EXPECT_DOUBLE_EQ(slow_start_min_weight_percent, 0.1);
 }
 
 TEST_P(LeastRequestLoadBalancerTest, SlowStartNoWait) {
@@ -2156,7 +2279,7 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartNoWait) {
   hostSet().healthy_hosts_ = {makeTestHost(info_, "tcp://127.0.0.1:80", simTime())};
   hostSet().hosts_ = hostSet().healthy_hosts_;
   simTime().advanceTimeWait(std::chrono::seconds(5));
-  // Host1 is 5 secs in slow start, its weight is scaled with (5/60)^1=0.08 factor.
+  // Host1 is 5 secs in slow start, its weight is scaled with max((5/60)^1, 0.1)=0.1 factor.
   hostSet().runCallbacks({}, {});
 
   auto latest_host_added_time =
@@ -2178,7 +2301,7 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartNoWait) {
       EdfLoadBalancerBasePeer::latestHostAddedTime(static_cast<EdfLoadBalancerBase&>(lb_2));
   EXPECT_EQ(std::chrono::milliseconds(62000), latest_host_added_time);
 
-  // host2 is 20 secs in slow start, the weight is scaled with time factor 20 / 60 == 0.16.
+  // host2 is 20 secs in slow start, the weight is scaled with time factor max(20/60, 0.1) = 0.16.
   simTime().advanceTimeWait(std::chrono::seconds(10));
 
   // Recalculate weights.
@@ -2194,7 +2317,7 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartNoWait) {
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
 
-  // host2 is 50 secs in slow start, the weight is scaled with time factor 40 / 60 == 0.66.
+  // host2 is 50 secs in slow start, the weight is scaled with time factor max(40/60, 0.1) = 0.66.
   simTime().advanceTimeWait(std::chrono::seconds(30));
 
   // Recalculate weights.
@@ -2265,22 +2388,35 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartWaitForPassingHC) {
   hostSet().runCallbacks({}, {});
 
   // We expect 11:2 ratio, as host2 is in slow start mode, its weight is scaled with factor
-  // pow(0.1, 1.11)=0.07. Host1 is 7 seconds in slow start and its weight is scaled with active
-  // request and time bias 0.53 * pow(0.7, 1.11) = 0.36.
-
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
-  EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
+  // max(pow(0.1, 1.11), 0.1)=0.1. Host1 is 7 seconds in slow start and its weight is scaled with
+  // active request and time bias 0.53 * max(pow(0.7, 1.11), 0.1) = 0.36.
+
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[25/9, 10]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[50/9, 10]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[75/9, 10]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[100/9, 10]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[100/9, 20]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[125/9, 20]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[150/9, 20]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[175/9, 20]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[200/9, 20]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[200/9, 30]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[225/9, 30]
+  EXPECT_EQ(hostSet().healthy_hosts_[0],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[250/9, 30]
+  EXPECT_EQ(hostSet().healthy_hosts_[1],
+            lb_2.chooseHost(nullptr)); // before choose: edf.deadline[host1,host2]=[275/9, 30]
 
   simTime().advanceTimeWait(std::chrono::seconds(3));
   host1->healthFlagSet(Host::HealthFlag::FAILED_ACTIVE_HC);
@@ -2288,7 +2424,7 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartWaitForPassingHC) {
   hostSet().runCallbacks({}, {});
 
   // We expect 3:5 ratio, as host2 is 4 seconds in slow start, its weight is scaled with factor
-  // pow(0.4, 1.11)=0.36. Host1 is not in slow start and its weight is scaled with active
+  // max(pow(0.4, 1.11), 0.1)=0.36. Host1 is not in slow start and its weight is scaled with active
   // request bias = 0.53.
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
@@ -2299,13 +2435,13 @@ TEST_P(LeastRequestLoadBalancerTest, SlowStartWaitForPassingHC) {
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
 
-  // Host2 is 7 seconds in slow start, the weight is scaled with time factor 7 / 10 == 0.6.
+  // Host2 is 7 seconds in slow start, the weight is scaled with time factor 7 / 10 == 0.7.
   simTime().advanceTimeWait(std::chrono::seconds(3));
 
   hostSet().runCallbacks({}, {});
 
   // We expect 6:5 ratio, as host2 is in slow start mode, its weight is scaled with time factor
-  // pow(0.7, 1.11)=0.67. Host1 weight is scaled with active request bias = 0.53.
+  // max(pow(0.7, 1.11), 0.1)=0.67. Host1 weight is scaled with active request bias = 0.53.
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[0], lb_2.chooseHost(nullptr));
   EXPECT_EQ(hostSet().healthy_hosts_[1], lb_2.chooseHost(nullptr));
diff --git a/test/common/upstream/upstream_impl_test.cc b/test/common/upstream/upstream_impl_test.cc
index 79efee3c96..105063f071 100644
--- a/test/common/upstream/upstream_impl_test.cc
+++ b/test/common/upstream/upstream_impl_test.cc
@@ -1793,6 +1793,90 @@ TEST_F(StaticClusterImplTest, RingHash) {
   EXPECT_TRUE(cluster.info()->addedViaApi());
 }
 
+TEST_F(StaticClusterImplTest, RoundRobinWithSlowStart) {
+  const std::string yaml = R"EOF(
+    name: staticcluster
+    connect_timeout: 0.25s
+    type: static
+    lb_policy: ROUND_ROBIN
+    load_assignment:
+        endpoints:
+          - lb_endpoints:
+            - endpoint:
+                address:
+                  socket_address:
+                    address: 10.0.0.1
+                    port_value: 11001
+    round_robin_lb_config:
+      slow_start_config:
+        slow_start_window: 60s
+        aggression:
+          default_value: 2.0
+          runtime_key: a_key
+  )EOF";
+
+  envoy::config::cluster::v3::Cluster cluster_config = parseClusterFromV3Yaml(yaml);
+
+  Envoy::Stats::ScopePtr scope = stats_.createScope(fmt::format(
+      "cluster.{}.", cluster_config.alt_stat_name().empty() ? cluster_config.name()
+                                                            : cluster_config.alt_stat_name()));
+  Envoy::Server::Configuration::TransportSocketFactoryContextImpl factory_context(
+      admin_, ssl_context_manager_, *scope, cm_, local_info_, dispatcher_, stats_,
+      singleton_manager_, tls_, validation_visitor_, *api_, options_);
+  StaticClusterImpl cluster(cluster_config, runtime_, factory_context, std::move(scope), true);
+  cluster.initialize([] {});
+
+  EXPECT_EQ(LoadBalancerType::RoundRobin, cluster.info()->lbType());
+  auto slow_start_config = cluster.info()->lbRoundRobinConfig()->slow_start_config();
+  EXPECT_EQ(std::chrono::milliseconds(60000),
+            std::chrono::milliseconds(
+                DurationUtil::durationToMilliseconds(slow_start_config.slow_start_window())));
+  EXPECT_EQ(2.0, slow_start_config.aggression().default_value());
+  EXPECT_TRUE(cluster.info()->addedViaApi());
+}
+
+TEST_F(StaticClusterImplTest, LeastRequestWithSlowStart) {
+  const std::string yaml = R"EOF(
+    name: staticcluster
+    connect_timeout: 0.25s
+    type: static
+    lb_policy: least_request
+    load_assignment:
+        endpoints:
+          - lb_endpoints:
+            - endpoint:
+                address:
+                  socket_address:
+                    address: 10.0.0.1
+                    port_value: 11001
+    least_request_lb_config:
+      slow_start_config:
+        slow_start_window: 60s
+        aggression:
+          default_value: 2.0
+          runtime_key: a_key
+  )EOF";
+
+  envoy::config::cluster::v3::Cluster cluster_config = parseClusterFromV3Yaml(yaml);
+
+  Envoy::Stats::ScopePtr scope = stats_.createScope(fmt::format(
+      "cluster.{}.", cluster_config.alt_stat_name().empty() ? cluster_config.name()
+                                                            : cluster_config.alt_stat_name()));
+  Envoy::Server::Configuration::TransportSocketFactoryContextImpl factory_context(
+      admin_, ssl_context_manager_, *scope, cm_, local_info_, dispatcher_, stats_,
+      singleton_manager_, tls_, validation_visitor_, *api_, options_);
+  StaticClusterImpl cluster(cluster_config, runtime_, factory_context, std::move(scope), true);
+  cluster.initialize([] {});
+
+  EXPECT_EQ(LoadBalancerType::LeastRequest, cluster.info()->lbType());
+  auto slow_start_config = cluster.info()->lbLeastRequestConfig()->slow_start_config();
+  EXPECT_EQ(std::chrono::milliseconds(60000),
+            std::chrono::milliseconds(
+                DurationUtil::durationToMilliseconds(slow_start_config.slow_start_window())));
+  EXPECT_EQ(2.0, slow_start_config.aggression().default_value());
+  EXPECT_TRUE(cluster.info()->addedViaApi());
+}
+
 TEST_F(StaticClusterImplTest, OutlierDetector) {
   const std::string yaml = R"EOF(
     name: addressportconfig
diff --git a/test/config/utility.cc b/test/config/utility.cc
index a2d7c9df51..4158af993c 100644
--- a/test/config/utility.cc
+++ b/test/config/utility.cc
@@ -432,6 +432,34 @@ envoy::config::cluster::v3::Cluster ConfigHelper::buildStaticCluster(const std::
                   name, name, address, port, lb_policy));
 }
 
+envoy::config::cluster::v3::Cluster ConfigHelper::buildH1ClusterWithHighCircuitBreakersLimits(
+    const std::string& name, int port, const std::string& address, const std::string& lb_policy) {
+  return TestUtility::parseYaml<envoy::config::cluster::v3::Cluster>(
+      fmt::format(R"EOF(
+      name: {}
+      connect_timeout: 50s
+      type: STATIC
+      circuit_breakers:
+        thresholds:
+        - priority: DEFAULT
+          max_connections: 10000
+          max_pending_requests: 10000
+          max_requests: 10000
+          max_retries: 10000
+      load_assignment:
+        cluster_name: {}
+        endpoints:
+        - lb_endpoints:
+          - endpoint:
+              address:
+                socket_address:
+                  address: {}
+                  port_value: {}
+      lb_policy: {}
+    )EOF",
+                  name, name, address, port, lb_policy));
+}
+
 envoy::config::cluster::v3::Cluster ConfigHelper::buildCluster(const std::string& name,
                                                                const std::string& lb_policy) {
   API_NO_BOOST(envoy::config::cluster::v3::Cluster) cluster;
diff --git a/test/config/utility.h b/test/config/utility.h
index f188f8ea1b..6c62292349 100644
--- a/test/config/utility.h
+++ b/test/config/utility.h
@@ -150,6 +150,11 @@ public:
   buildStaticCluster(const std::string& name, int port, const std::string& address,
                      const std::string& lb_policy = "ROUND_ROBIN");
 
+  static envoy::config::cluster::v3::Cluster
+  buildH1ClusterWithHighCircuitBreakersLimits(const std::string& name, int port,
+                                              const std::string& address,
+                                              const std::string& lb_policy = "ROUND_ROBIN");
+
   // ADS configurations
   static envoy::config::cluster::v3::Cluster
   buildCluster(const std::string& name, const std::string& lb_policy = "ROUND_ROBIN");
diff --git a/test/config_test/BUILD b/test/config_test/BUILD
index 7104a8d336..a04ed9a83e 100644
--- a/test/config_test/BUILD
+++ b/test/config_test/BUILD
@@ -5,7 +5,7 @@ load(
     "envoy_package",
 )
 load("//source/extensions:all_extensions.bzl", "envoy_all_extensions")
-load("//bazel:repositories.bzl", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
+load("//bazel:repositories.bzl", "DARWIN_SKIP_TARGETS", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
 
 licenses(["notice"])  # Apache 2
 
@@ -60,6 +60,7 @@ envoy_cc_test_library(
     ] + select({
         "//bazel:windows_x86_64": envoy_all_extensions(WINDOWS_SKIP_TARGETS),
         "//bazel:linux_ppc": envoy_all_extensions(PPC_SKIP_TARGETS),
+        "//bazel:darwin": envoy_all_extensions(DARWIN_SKIP_TARGETS),
         "//conditions:default": envoy_all_extensions(),
     }),
 )
diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc
index d6f8d800f9..bd441e6a75 100644
--- a/test/config_test/config_test.cc
+++ b/test/config_test/config_test.cc
@@ -47,7 +47,7 @@ OptionsImpl asConfigYaml(const OptionsImpl& src, Api::Api& api) {
 
 static std::vector<absl::string_view> unsuported_win32_configs = {
 #if defined(WIN32) && !defined(SO_ORIGINAL_DST)
-    "configs_original-dst-cluster_proxy_config.yaml"
+    "configs_original-dst-cluster_proxy_config.yaml",
 #endif
 };
 
diff --git a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc
index 27a9a70b45..67461b23f4 100644
--- a/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc
+++ b/test/extensions/filters/common/ext_authz/ext_authz_http_impl_test.cc
@@ -328,6 +328,82 @@ TEST_F(ExtAuthzHttpClientTest, AllowedRequestHeadersPrefix) {
   EXPECT_EQ(fool[0]->value().getStringView(), "fool");
 }
 
+#if defined(ALIMESH)
+TEST_F(ExtAuthzHttpClientTest, IsAuthorizationPass) {
+  // 200 code without x-mse-external-authz-check-result
+  const auto expected_headers = TestCommon::makeHeaderValueOption({{":status", "200", false}});
+  auto check_response = TestCommon::makeMessageResponse(expected_headers);
+  EXPECT_TRUE(isAuthorizationPass(check_response->headers()));
+
+  // 200 code with x-mse-external-authz-check-result value is true
+  expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "200", false}, {"x-mse-external-authz-check-result", "true", false}});
+  check_response = TestCommon::makeMessageResponse(expected_headers);
+  EXPECT_TRUE(isAuthorizationPass(check_response->headers()));
+
+  // 200 code with x-mse-external-authz-check-result value is false
+  expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "200", false}, {"x-mse-external-authz-check-result", "false", false}});
+  check_response = TestCommon::makeMessageResponse(expected_headers);
+  EXPECT_FALSE(isAuthorizationPass(check_response->headers()));
+
+  // nor 200 code with x-mse-external-authz-check-result value is true
+  expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "503", false}, {"x-mse-external-authz-check-result", "true", false}});
+  check_response = TestCommon::makeMessageResponse(expected_headers);
+  EXPECT_FALSE(isAuthorizationPass(check_response->headers()));
+}
+
+TEST_F(ExtAuthzHttpClientTest, AuthorizationOkWithXMseExternalAuthzCheckResultTrue) {
+  const auto expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "200", false}, {"x-mse-external-authz-check-result", "true", false}});
+  const auto authz_response = TestCommon::makeAuthzResponse(CheckStatus::OK);
+  auto check_response = TestCommon::makeMessageResponse(expected_headers);
+  envoy::service::auth::v3::CheckRequest request;
+  client_->check(request_callbacks_, request, parent_span_, stream_info_);
+
+  EXPECT_CALL(request_callbacks_,
+              onComplete_(WhenDynamicCastTo<ResponsePtr&>(AuthzOkResponse(authz_response))));
+  client_->onSuccess(async_request_, std::move(check_response));
+}
+
+TEST_F(ExtAuthzHttpClientTest, AuthorizationDeniedWithXMseExternalAuthzCheckResultTrueButCode403) {
+  const auto expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "403", false}, {"x-mse-external-authz-check-result", "true", false}});
+  const auto authz_response = TestCommon::makeAuthzResponse(
+      CheckStatus::Denied, Http::Code::Forbidden, EMPTY_STRING, expected_headers);
+  auto check_response = TestCommon::makeMessageResponse(expected_headers);
+
+  envoy::service::auth::v3::CheckRequest request;
+  client_->check(request_callbacks_, request, parent_span_, stream_info_);
+
+  // Check for child span tagging when the request is denied.
+  EXPECT_CALL(child_span_, setTag(Eq("ext_authz_http_status"), Eq("Forbidden")));
+  EXPECT_CALL(child_span_, setTag(Eq("ext_authz_status"), Eq("ext_authz_unauthorized")));
+  client_->onBeforeFinalizeUpstreamSpan(child_span_, &check_response->headers());
+
+  EXPECT_CALL(request_callbacks_,
+              onComplete_(WhenDynamicCastTo<ResponsePtr&>(AuthzDeniedResponse(authz_response))));
+  client_->onSuccess(async_request_, TestCommon::makeMessageResponse(expected_headers));
+}
+
+TEST_F(ExtAuthzHttpClientTest, AuthorizationDeniedWithCode200ButXMseExternalAuthzCheckResultFalse) {
+  const auto expected_body = std::string{"test"};
+  const auto expected_headers = TestCommon::makeHeaderValueOption(
+      {{":status", "200", false}, {"x-mse-external-authz-check-result", "false", false}});
+  const auto authz_response = TestCommon::makeAuthzResponse(CheckStatus::Denied, Http::Code::OK,
+                                                            expected_body, expected_headers);
+
+  envoy::service::auth::v3::CheckRequest request;
+  client_->check(request_callbacks_, request, parent_span_, stream_info_);
+
+  EXPECT_CALL(request_callbacks_,
+              onComplete_(WhenDynamicCastTo<ResponsePtr&>(AuthzDeniedResponse(authz_response))));
+  client_->onSuccess(async_request_,
+                     TestCommon::makeMessageResponse(expected_headers, expected_body));
+}
+#endif
+
 // Verify client response when authorization server returns a 200 OK.
 TEST_F(ExtAuthzHttpClientTest, AuthorizationOk) {
   const auto expected_headers = TestCommon::makeHeaderValueOption({{":status", "200", false}});
diff --git a/test/extensions/filters/http/cors/cors_filter_integration_test.cc b/test/extensions/filters/http/cors/cors_filter_integration_test.cc
index 00bd075b37..7ccd82561b 100644
--- a/test/extensions/filters/http/cors/cors_filter_integration_test.cc
+++ b/test/extensions/filters/http/cors/cors_filter_integration_test.cc
@@ -114,6 +114,12 @@ protected:
                       Http::TestResponseHeaderMapImpl& expected_response_headers) {
     response_headers.remove(Envoy::Http::LowerCaseString{"date"});
     response_headers.remove(Envoy::Http::LowerCaseString{"x-envoy-upstream-service-time"});
+#if defined(ALIMESH)
+    response_headers.remove(Envoy::Http::LowerCaseString{"req-cost-time"});
+    response_headers.remove(Envoy::Http::LowerCaseString{"req-start-time"});
+    response_headers.remove(Envoy::Http::LowerCaseString{"req-arrive-time"});
+    response_headers.remove(Envoy::Http::LowerCaseString{"resp-start-time"});
+#endif
     EXPECT_EQ(expected_response_headers, response_headers);
   }
 };
diff --git a/test/extensions/filters/http/cors/cors_filter_test.cc b/test/extensions/filters/http/cors/cors_filter_test.cc
index 31c7f211cd..8bec16d049 100644
--- a/test/extensions/filters/http/cors/cors_filter_test.cc
+++ b/test/extensions/filters/http/cors/cors_filter_test.cc
@@ -716,6 +716,61 @@ TEST(CorsFilterConfigTest, DEPRECATED_FEATURE_TEST(DeprecatedExtensionFilterName
           deprecated_name));
 }
 
+TEST_F(CorsFilterTest, OptionsRequestWithWildcardAllowMethods) {
+  Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"},
+                                                 {"origin", "www.envoyproxy.com"},
+                                                 {"access-control-request-method", "GET"}};
+
+  Http::TestResponseHeaderMapImpl response_headers{
+      {":status", "200"},
+      {"access-control-allow-origin", "www.envoyproxy.com"},
+      {"access-control-allow-methods", "GET"},
+      {"access-control-allow-headers", "content-type"},
+      {"access-control-max-age", "0"},
+  };
+
+  cors_policy_->allow_methods_ = "*";
+
+  EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true));
+
+  EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+            filter_.decodeHeaders(request_headers, false));
+  EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false));
+  EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_));
+
+  EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false));
+  EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false));
+  EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_));
+}
+
+TEST_F(CorsFilterTest, OptionsRequestWithWildcardAllowHeaders) {
+  Http::TestRequestHeaderMapImpl request_headers{{":method", "OPTIONS"},
+                                                 {"origin", "www.envoyproxy.com"},
+                                                 {"access-control-request-method", "GET"},
+                                                 {"access-control-request-headers", "test,pre"}};
+
+  Http::TestResponseHeaderMapImpl response_headers{
+      {":status", "200"},
+      {"access-control-allow-origin", "www.envoyproxy.com"},
+      {"access-control-allow-methods", "GET"},
+      {"access-control-allow-headers", "test,pre"},
+      {"access-control-max-age", "0"},
+  };
+
+  cors_policy_->allow_headers_ = "*";
+
+  EXPECT_CALL(decoder_callbacks_, encodeHeaders_(HeaderMapEqualRef(&response_headers), true));
+
+  EXPECT_EQ(Http::FilterHeadersStatus::StopIteration,
+            filter_.decodeHeaders(request_headers, false));
+  EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.decodeData(data_, false));
+  EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.decodeTrailers(request_trailers_));
+
+  EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_.encodeHeaders(response_headers_, false));
+  EXPECT_EQ(Http::FilterDataStatus::Continue, filter_.encodeData(data_, false));
+  EXPECT_EQ(Http::FilterTrailersStatus::Continue, filter_.encodeTrailers(response_trailers_));
+}
+
 } // namespace Cors
 } // namespace HttpFilters
 } // namespace Extensions
diff --git a/test/extensions/filters/http/tap/tap_filter_integration_test.cc b/test/extensions/filters/http/tap/tap_filter_integration_test.cc
index cfd7f76445..ba4263f7d1 100644
--- a/test/extensions/filters/http/tap/tap_filter_integration_test.cc
+++ b/test/extensions/filters/http/tap/tap_filter_integration_test.cc
@@ -272,8 +272,13 @@ tap_config:
   admin_response_->waitForBodyData(1);
   envoy::data::tap::v3::TraceWrapper trace;
   TestUtility::loadFromYaml(admin_response_->body(), trace);
+#if defined(ALIMESH)
+  EXPECT_EQ(trace.http_buffered_trace().request().headers().size(), 10);
+  EXPECT_EQ(trace.http_buffered_trace().response().headers().size(), 7);
+#else
   EXPECT_EQ(trace.http_buffered_trace().request().headers().size(), 8);
   EXPECT_EQ(trace.http_buffered_trace().response().headers().size(), 4);
+#endif
   admin_response_->clearBody();
 
   // Do a request which should not tap.
@@ -285,11 +290,16 @@ tap_config:
   // Wait for the tap message.
   admin_response_->waitForBodyData(1);
   TestUtility::loadFromYaml(admin_response_->body(), trace);
+#if defined(ALIMESH)
+  EXPECT_EQ(trace.http_buffered_trace().request().headers().size(), 9);
+  EXPECT_EQ(trace.http_buffered_trace().response().headers().size(), 8);
+#else
   EXPECT_EQ(trace.http_buffered_trace().request().headers().size(), 7);
+  EXPECT_EQ(trace.http_buffered_trace().response().headers().size(), 5);
+#endif
   EXPECT_EQ(
       "http",
       findHeader("x-forwarded-proto", trace.http_buffered_trace().request().headers())->value());
-  EXPECT_EQ(trace.http_buffered_trace().response().headers().size(), 5);
   EXPECT_NE(nullptr, findHeader("date", trace.http_buffered_trace().response().headers()));
   EXPECT_EQ("baz", findHeader("bar", trace.http_buffered_trace().response().headers())->value());
 
diff --git a/test/extensions/tracers/skywalking/trace_segment_reporter_test.cc b/test/extensions/tracers/skywalking/trace_segment_reporter_test.cc
index 9d3d89fb26..be500599a4 100644
--- a/test/extensions/tracers/skywalking/trace_segment_reporter_test.cc
+++ b/test/extensions/tracers/skywalking/trace_segment_reporter_test.cc
@@ -68,8 +68,9 @@ protected:
   NiceMock<Event::MockTimer>* timer_;
   Event::TimerCb timer_cb_;
   std::string test_string = "ABCDEFGHIJKLMN";
-  SkyWalkingTracerStats tracing_stats_{
-      SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(mock_scope_, "tracing.skywalking."))};
+  SkyWalkingTracerStatsSharedPtr tracing_stats_{
+      std::make_shared<SkyWalkingTracerStats>(SkyWalkingTracerStats{
+          SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(mock_scope_, "tracing.skywalking."))})};
   TraceSegmentReporterPtr reporter_;
 };
 
diff --git a/test/extensions/tracers/skywalking/tracer_test.cc b/test/extensions/tracers/skywalking/tracer_test.cc
index 014aa4b150..0d2298c3af 100644
--- a/test/extensions/tracers/skywalking/tracer_test.cc
+++ b/test/extensions/tracers/skywalking/tracer_test.cc
@@ -64,8 +64,9 @@ protected:
   NiceMock<Stats::MockIsolatedStatsStore>& mock_scope_ = context_.server_factory_context_.scope_;
   std::unique_ptr<NiceMock<Grpc::MockAsyncStream>> mock_stream_ptr_{nullptr};
   std::string test_string = "ABCDEFGHIJKLMN";
-  SkyWalkingTracerStats tracing_stats_{
-      SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(mock_scope_, "tracing.skywalking."))};
+  SkyWalkingTracerStatsSharedPtr tracing_stats_{
+      std::make_shared<SkyWalkingTracerStats>(SkyWalkingTracerStats{
+          SKYWALKING_TRACER_STATS(POOL_COUNTER_PREFIX(mock_scope_, "tracing.skywalking."))})};
   TracerPtr tracer_;
 };
 
diff --git a/test/extensions/transport_sockets/proxy_protocol/proxy_protocol_test.cc b/test/extensions/transport_sockets/proxy_protocol/proxy_protocol_test.cc
index 17c0fafd34..532b16fe0d 100644
--- a/test/extensions/transport_sockets/proxy_protocol/proxy_protocol_test.cc
+++ b/test/extensions/transport_sockets/proxy_protocol/proxy_protocol_test.cc
@@ -388,7 +388,6 @@ TEST_F(ProxyProtocolTest, V2IPV4DownstreamAddresses) {
   proxy_protocol_socket_->doWrite(msg, false);
 }
 
-// Test injects V2 PROXY protocol for downstream IPV6 addresses
 TEST_F(ProxyProtocolTest, V2IPV6DownstreamAddresses) {
   auto src_addr =
       Network::Address::InstanceConstSharedPtr(new Network::Address::Ipv6Instance("1:2:3::4", 8));
diff --git a/test/extensions/upstreams/http/tcp/upstream_request_test.cc b/test/extensions/upstreams/http/tcp/upstream_request_test.cc
index c5310d25fe..f9a1bcbdb1 100644
--- a/test/extensions/upstreams/http/tcp/upstream_request_test.cc
+++ b/test/extensions/upstreams/http/tcp/upstream_request_test.cc
@@ -146,7 +146,7 @@ TEST_F(TcpUpstreamTest, Basic) {
 
 TEST_F(TcpUpstreamTest, V1Header) {
   envoy::config::core::v3::ProxyProtocolConfig* proxy_config =
-      mock_router_filter_.route_entry_.connect_config_->mutable_proxy_protocol_config();
+      mock_router_filter_.route_.route_entry_.connect_config_->mutable_proxy_protocol_config();
   proxy_config->set_version(envoy::config::core::v3::ProxyProtocolConfig::V1);
   mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
       ->setRemoteAddress(std::make_shared<Network::Address::Ipv4Instance>("1.2.3.4", 5));
@@ -169,7 +169,7 @@ TEST_F(TcpUpstreamTest, V1Header) {
 
 TEST_F(TcpUpstreamTest, V2Header) {
   envoy::config::core::v3::ProxyProtocolConfig* proxy_config =
-      mock_router_filter_.route_entry_.connect_config_->mutable_proxy_protocol_config();
+      mock_router_filter_.route_.route_entry_.connect_config_->mutable_proxy_protocol_config();
   proxy_config->set_version(envoy::config::core::v3::ProxyProtocolConfig::V2);
   mock_router_filter_.client_connection_.stream_info_.downstream_connection_info_provider_
       ->setRemoteAddress(std::make_shared<Network::Address::Ipv4Instance>("1.2.3.4", 5));
diff --git a/test/integration/BUILD b/test/integration/BUILD
index 5e631735ef..8f0d1cf58c 100644
--- a/test/integration/BUILD
+++ b/test/integration/BUILD
@@ -111,10 +111,12 @@ envoy_proto_library(
 
 envoy_cc_test(
     name = "cds_integration_test",
+    size = "large",
     srcs = ["cds_integration_test.cc"],
     data = [
         "//test/config/integration/certs",
     ],
+    shard_count = 4,
     deps = [
         ":http_integration_lib",
         "//source/common/config:protobuf_link_hacks",
@@ -509,6 +511,7 @@ envoy_cc_test_library(
         "//source/extensions/filters/http/buffer:config",
         "//source/extensions/filters/http/health_check:config",
         "//test/common/http/http2:http2_frame",
+        "//test/integration/filters:buffer_continue_filter_lib",
         "//test/integration/filters:continue_after_local_reply_filter_lib",
         "//test/integration/filters:continue_headers_only_inject_body",
         "//test/integration/filters:encoder_decoder_buffer_filter_lib",
diff --git a/test/integration/cds_integration_test.cc b/test/integration/cds_integration_test.cc
index bbffa27e95..f7e2b27843 100644
--- a/test/integration/cds_integration_test.cc
+++ b/test/integration/cds_integration_test.cc
@@ -34,7 +34,15 @@ public:
   CdsIntegrationTest()
       : HttpIntegrationTest(Http::CodecType::HTTP2, ipVersion(),
                             ConfigHelper::discoveredClustersBootstrap(
-                                sotwOrDelta() == Grpc::SotwOrDelta::Sotw ? "GRPC" : "DELTA_GRPC")) {
+                                sotwOrDelta() == Grpc::SotwOrDelta::Sotw ||
+                                        sotwOrDelta() == Grpc::SotwOrDelta::UnifiedSotw
+                                    ? "GRPC"
+                                    : "DELTA_GRPC")),
+        cluster_creator_(&ConfigHelper::buildStaticCluster) {
+    if (sotwOrDelta() == Grpc::SotwOrDelta::UnifiedSotw ||
+        sotwOrDelta() == Grpc::SotwOrDelta::UnifiedDelta) {
+      config_helper_.addRuntimeOverride("envoy.reloadable_features.unified_mux", "true");
+    }
     use_lds_ = false;
     sotw_or_delta_ = sotwOrDelta();
   }
@@ -72,14 +80,14 @@ public:
     // Create the regular (i.e. not an xDS server) upstreams. We create them manually here after
     // initialize() because finalize() expects all fake_upstreams_ to correspond to a static
     // cluster in the bootstrap config - which we don't want since we're testing dynamic CDS!
-    addFakeUpstream(Http::CodecType::HTTP2);
-    addFakeUpstream(Http::CodecType::HTTP2);
-    cluster1_ = ConfigHelper::buildStaticCluster(
+    addFakeUpstream(upstream_codec_type_);
+    addFakeUpstream(upstream_codec_type_);
+    cluster1_ = cluster_creator_(
         ClusterName1, fake_upstreams_[UpstreamIndex1]->localAddress()->ip()->port(),
-        Network::Test::getLoopbackAddressString(ipVersion()));
-    cluster2_ = ConfigHelper::buildStaticCluster(
+        Network::Test::getLoopbackAddressString(ipVersion()), "ROUND_ROBIN");
+    cluster2_ = cluster_creator_(
         ClusterName2, fake_upstreams_[UpstreamIndex2]->localAddress()->ip()->port(),
-        Network::Test::getLoopbackAddressString(ipVersion()));
+        Network::Test::getLoopbackAddressString(ipVersion()), "ROUND_ROBIN");
 
     // Let Envoy establish its connection to the CDS server.
     acceptXdsConnection();
@@ -126,6 +134,10 @@ public:
   envoy::config::cluster::v3::Cluster cluster2_;
   // True if we decided not to run the test after all.
   bool test_skipped_{true};
+  Http::CodecType upstream_codec_type_{Http::CodecType::HTTP2};
+  std::function<envoy::config::cluster::v3::Cluster(const std::string&, int, const std::string&,
+                                                    const std::string&)>
+      cluster_creator_;
 };
 
 INSTANTIATE_TEST_SUITE_P(IpVersionsClientTypeDelta, CdsIntegrationTest,
@@ -301,5 +313,160 @@ TEST_P(CdsIntegrationTest, VersionsRememberedAfterReconnect) {
   ASSERT_TRUE(codec_client_->waitForDisconnect());
 }
 
+// This test verifies that Envoy can delete a cluster with a lot of idle connections.
+// The original problem was recursive closure of idle connections that can run out
+// of stack when there are a lot of idle connections.
+TEST_P(CdsIntegrationTest, CdsClusterDownWithLotsOfIdleConnections) {
+  constexpr int num_requests = 2000;
+  // Make upstream H/1 so it creates connection for each request
+  upstream_codec_type_ = Http::CodecType::HTTP1;
+  // Relax default circuit breaker limits and timeouts so Envoy can accumulate a lot of idle
+  // connections
+  cluster_creator_ = &ConfigHelper::buildH1ClusterWithHighCircuitBreakersLimits;
+  config_helper_.addConfigModifier(
+      [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
+              hcm) -> void {
+        hcm.mutable_route_config()
+            ->mutable_virtual_hosts(0)
+            ->mutable_routes(0)
+            ->mutable_route()
+            ->mutable_timeout()
+            ->set_seconds(600);
+        hcm.mutable_route_config()
+            ->mutable_virtual_hosts(0)
+            ->mutable_routes(0)
+            ->mutable_route()
+            ->mutable_idle_timeout()
+            ->set_seconds(600);
+      });
+  initialize();
+  std::vector<IntegrationStreamDecoderPtr> responses;
+  std::vector<FakeHttpConnectionPtr> upstream_connections;
+  std::vector<FakeStreamPtr> upstream_requests;
+  codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http"))));
+  // The first loop establishes a lot of open connections with active requests to upstream
+  for (int i = 0; i < num_requests; ++i) {
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/cluster1"},
+                                                   {":scheme", "http"},
+                                                   {":authority", "host"},
+                                                   {"x-lyft-user-id", absl::StrCat(i)}};
+
+    auto response = codec_client_->makeHeaderOnlyRequest(request_headers);
+    responses.push_back(std::move(response));
+
+    FakeHttpConnectionPtr fake_upstream_connection;
+    waitForNextUpstreamConnection({UpstreamIndex1}, TestUtility::DefaultTimeout,
+                                  fake_upstream_connection);
+    // Wait for the next stream on the upstream connection.
+    FakeStreamPtr upstream_request;
+    AssertionResult result =
+        fake_upstream_connection->waitForNewStream(*dispatcher_, upstream_request);
+    RELEASE_ASSERT(result, result.message());
+    // Wait for the stream to be completely received.
+    result = upstream_request->waitForEndStream(*dispatcher_);
+    RELEASE_ASSERT(result, result.message());
+    upstream_connections.push_back(std::move(fake_upstream_connection));
+    upstream_requests.push_back(std::move(upstream_request));
+  }
+
+  // This loop completes all requests making the all upstream connections idle
+  for (int i = 0; i < num_requests; ++i) {
+    // Send response headers, and end_stream if there is no response body.
+    upstream_requests[i]->encodeHeaders(default_response_headers_, true);
+    // Wait for the response to be read by the codec client.
+    RELEASE_ASSERT(responses[i]->waitForEndStream(), "unexpected timeout");
+    ASSERT_TRUE(responses[i]->complete());
+    EXPECT_EQ("200", responses[i]->headers().getStatusValue());
+  }
+
+  test_server_->waitForCounterGe("cluster_manager.cluster_added", 1);
+
+  // Tell Envoy that cluster_1 is gone. Envoy will try to close all idle connections
+  EXPECT_TRUE(compareDiscoveryRequest(Config::TypeUrl::get().Cluster, "55", {}, {}, {}));
+  sendDiscoveryResponse<envoy::config::cluster::v3::Cluster>(Config::TypeUrl::get().Cluster, {}, {},
+                                                             {ClusterName1}, "42");
+  // We can continue the test once we're sure that Envoy's ClusterManager has made use of
+  // the DiscoveryResponse that says cluster_1 is gone.
+  test_server_->waitForCounterGe("cluster_manager.cluster_removed", 1);
+
+  // If we made it this far then everything is ok.
+  for (int i = 0; i < num_requests; ++i) {
+    AssertionResult result = upstream_connections[i]->close();
+    RELEASE_ASSERT(result, result.message());
+    result = upstream_connections[i]->waitForDisconnect();
+    RELEASE_ASSERT(result, result.message());
+  }
+  upstream_connections.clear();
+  cleanupUpstreamAndDownstream();
+  ASSERT_TRUE(codec_client_->waitForDisconnect());
+}
+
+// This test verifies that Envoy can delete a cluster with a lot of connections in the connecting
+// state and associated pending requests. The recursion guard in the
+// ConnPoolImplBase::closeIdleConnectionsForDrainingPool() would fire if it was called recursively.
+//
+// Test is currently disabled as there is presently no reliable way of making upstream connections
+// hang in connecting state.
+TEST_P(CdsIntegrationTest, DISABLED_CdsClusterDownWithLotsOfConnectingConnections) {
+  // Use low number of pending connections to prevent bumping into the default
+  // limit of 128, since the upstream will be prevented below from
+  // accepting connections.
+  constexpr int num_requests = 64;
+  // Make upstream H/1 so it creates connection for each request
+  upstream_codec_type_ = Http::CodecType::HTTP1;
+  cluster_creator_ = &ConfigHelper::buildH1ClusterWithHighCircuitBreakersLimits;
+  config_helper_.addConfigModifier(
+      [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
+              hcm) -> void {
+        hcm.mutable_route_config()
+            ->mutable_virtual_hosts(0)
+            ->mutable_routes(0)
+            ->mutable_route()
+            ->mutable_timeout()
+            ->set_seconds(600);
+        hcm.mutable_route_config()
+            ->mutable_virtual_hosts(0)
+            ->mutable_routes(0)
+            ->mutable_route()
+            ->mutable_idle_timeout()
+            ->set_seconds(600);
+      });
+  initialize();
+  test_server_->waitForCounterGe("cluster_manager.cluster_added", 1);
+  std::vector<IntegrationStreamDecoderPtr> responses;
+  codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http"))));
+  // Stop upstream at UpstreamIndex1 dispatcher, to prevent it from accepting TCP connections.
+  // This will cause Envoy's connections to that upstream hang in the connecting state.
+  fake_upstreams_[UpstreamIndex1]->dispatcher()->exit();
+  for (int i = 0; i < num_requests; ++i) {
+    Http::TestRequestHeaderMapImpl request_headers{{":method", "GET"},
+                                                   {":path", "/cluster1"},
+                                                   {":scheme", "http"},
+                                                   {":authority", "host"},
+                                                   {"x-lyft-user-id", absl::StrCat(i)}};
+
+    auto response = codec_client_->makeHeaderOnlyRequest(request_headers);
+    responses.push_back(std::move(response));
+  }
+
+  // Wait for Envoy to try to establish all expected connections
+  test_server_->waitForCounterEq("cluster.cluster_1.upstream_cx_total", num_requests);
+
+  // Tell Envoy that cluster_1 is gone. Envoy will try to close all pending connections
+  EXPECT_TRUE(compareDiscoveryRequest(Config::TypeUrl::get().Cluster, "55", {}, {}, {}));
+  sendDiscoveryResponse<envoy::config::cluster::v3::Cluster>(Config::TypeUrl::get().Cluster, {}, {},
+                                                             {ClusterName1}, "42");
+  // We can continue the test once we're sure that Envoy's ClusterManager has made use of
+  // the DiscoveryResponse that says cluster_1 is gone.
+  test_server_->waitForCounterGe("cluster_manager.cluster_removed", 1);
+
+  cleanupUpstreamAndDownstream();
+  ASSERT_TRUE(codec_client_->waitForDisconnect());
+  // If we got here it means that the recursion guard in the
+  // ConnPoolImplBase::closeIdleConnectionsForDrainingPool() did not fire, which is what this test
+  // validates.
+}
+
 } // namespace
 } // namespace Envoy
diff --git a/test/integration/extension_discovery_integration_test.cc b/test/integration/extension_discovery_integration_test.cc
index 7a6457027f..f279a5e3d4 100644
--- a/test/integration/extension_discovery_integration_test.cc
+++ b/test/integration/extension_discovery_integration_test.cc
@@ -733,5 +733,60 @@ TEST_P(ExtensionDiscoveryIntegrationTest, BasicFailTerminalFilterNotAtEndOfFilte
   EXPECT_EQ("500", response->headers().getStatusValue());
 }
 
+// Validate that deleting listeners does not break active ECDS subscription.
+TEST_P(ExtensionDiscoveryIntegrationTest, ReloadBoth) {
+  on_server_init_function_ = [&]() { waitXdsStream(); };
+  addDynamicFilter("foo", false);
+  initialize();
+  test_server_->waitForCounterGe("listener_manager.lds.update_success", 1);
+  EXPECT_EQ(test_server_->server().initManager().state(), Init::Manager::State::Initializing);
+  registerTestServerPorts({"http"});
+  sendXdsResponse("foo", "1", denyPrivateConfig());
+  test_server_->waitForCounterGe("http.config_test.extension_config_discovery.foo.config_reload",
+                                 1);
+  test_server_->waitUntilListenersReady();
+  test_server_->waitForGaugeGe("listener_manager.workers_started", 1);
+  EXPECT_EQ(test_server_->server().initManager().state(), Init::Manager::State::Initialized);
+  Http::TestRequestHeaderMapImpl banned_request_headers{
+      {":method", "GET"}, {":path", "/private/key"}, {":scheme", "http"}, {":authority", "host"}};
+  codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http"))));
+  {
+    auto response = codec_client_->makeHeaderOnlyRequest(banned_request_headers);
+    ASSERT_TRUE(response->waitForEndStream());
+    ASSERT_TRUE(response->complete());
+    EXPECT_EQ("403", response->headers().getStatusValue());
+  }
+  codec_client_->close();
+
+  // Rename the listener to force delete the first listener and wait for the deletion.
+  listener_config_.set_name("updated");
+  sendLdsResponse("updated");
+  test_server_->waitForCounterGe("listener_manager.lds.update_success", 2);
+  test_server_->waitForGaugeEq("listener_manager.total_listeners_warming", 0);
+  test_server_->waitForGaugeEq("listener_manager.total_listeners_draining", 0);
+
+  // Verify ECDS is still applied on the new listener.
+  registerTestServerPorts({"http"});
+  codec_client_ = makeHttpConnection(makeClientConnection((lookupPort("http"))));
+  {
+    auto response = codec_client_->makeHeaderOnlyRequest(banned_request_headers);
+    ASSERT_TRUE(response->waitForEndStream());
+    ASSERT_TRUE(response->complete());
+    EXPECT_EQ("403", response->headers().getStatusValue());
+  }
+
+  // Update ECDS but keep the connection.
+  {
+    sendXdsResponse("foo", "2", allowAllConfig());
+    test_server_->waitForCounterGe("http.config_test.extension_config_discovery.foo.config_reload",
+                                   2);
+    auto response = codec_client_->makeHeaderOnlyRequest(banned_request_headers);
+    ASSERT_TRUE(response->waitForEndStream());
+    ASSERT_TRUE(response->complete());
+    EXPECT_EQ("200", response->headers().getStatusValue());
+  }
+  codec_client_->close();
+}
+
 } // namespace
 } // namespace Envoy
diff --git a/test/integration/filter_manager_integration_test.cc b/test/integration/filter_manager_integration_test.cc
index ee5db8d467..7a160aa2e8 100644
--- a/test/integration/filter_manager_integration_test.cc
+++ b/test/integration/filter_manager_integration_test.cc
@@ -458,6 +458,7 @@ TEST_P(InjectDataWithEchoFilterIntegrationTest, UsageOfInjectDataMethodsShouldBe
 }
 
 TEST_P(InjectDataWithEchoFilterIntegrationTest, FilterChainMismatch) {
+  useListenerAccessLog("%RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS%");
   useListenerAccessLog("%FILTER_CHAIN_NAME% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS%");
   config_helper_.addConfigModifier([](envoy::config::bootstrap::v3::Bootstrap& bootstrap) {
     bootstrap.mutable_static_resources()
diff --git a/test/integration/filters/BUILD b/test/integration/filters/BUILD
index 79e08f2533..beab9eccde 100644
--- a/test/integration/filters/BUILD
+++ b/test/integration/filters/BUILD
@@ -514,6 +514,20 @@ envoy_cc_test_library(
     ],
 )
 
+envoy_cc_test_library(
+    name = "buffer_continue_filter_lib",
+    srcs = [
+        "buffer_continue_filter.cc",
+    ],
+    deps = [
+        "//envoy/http:filter_interface",
+        "//envoy/registry",
+        "//envoy/server:filter_config_interface",
+        "//source/extensions/filters/http/common:pass_through_filter_lib",
+        "//test/extensions/filters/http/common:empty_http_filter_config_lib",
+    ],
+)
+
 envoy_cc_test_library(
     name = "test_socket_interface_lib",
     srcs = [
diff --git a/test/integration/filters/buffer_continue_filter.cc b/test/integration/filters/buffer_continue_filter.cc
new file mode 100644
index 0000000000..d5f5dadd69
--- /dev/null
+++ b/test/integration/filters/buffer_continue_filter.cc
@@ -0,0 +1,74 @@
+#include <string>
+
+#include "envoy/http/filter.h"
+#include "envoy/registry/registry.h"
+#include "envoy/server/filter_config.h"
+
+#include "source/extensions/filters/http/common/pass_through_filter.h"
+
+#include "test/extensions/filters/http/common/empty_http_filter_config.h"
+
+namespace Envoy {
+
+// A filter that buffers until the limit is reached and then continues.
+class BufferContinueStreamFilter : public Http::PassThroughFilter {
+public:
+  Http::FilterHeadersStatus decodeHeaders(Http::RequestHeaderMap&, bool end_stream) override {
+    return end_stream ? Http::FilterHeadersStatus::Continue
+                      : Http::FilterHeadersStatus::StopIteration;
+  }
+
+  Http::FilterDataStatus decodeData(Buffer::Instance&, bool end_stream) override {
+    return end_stream ? Http::FilterDataStatus::Continue
+                      : Http::FilterDataStatus::StopIterationAndBuffer;
+  }
+
+  Http::FilterHeadersStatus encodeHeaders(Http::ResponseHeaderMap& headers, bool) override {
+    response_headers_ = &headers;
+    return Http::FilterHeadersStatus::StopIteration;
+  }
+
+  Http::FilterDataStatus encodeData(Buffer::Instance& data, bool end_stream) override {
+    data_total_ += data.length();
+
+    const auto limit = encoder_callbacks_->encoderBufferLimit();
+    const auto header_size = response_headers_->byteSize();
+
+    if (limit && header_size + data_total_ > limit) {
+      // Give up since we've reached the buffer limit, Envoy should generate
+      // a 500 since it couldn't finished encoding.
+      return Http::FilterDataStatus::Continue;
+    }
+
+    encoder_callbacks_->addEncodedData(data, false);
+
+    if (!end_stream) {
+      return Http::FilterDataStatus::StopIterationAndBuffer;
+    }
+
+    return Http::FilterDataStatus::Continue;
+  }
+
+private:
+  Http::ResponseHeaderMap* response_headers_;
+  uint64_t data_total_{0};
+};
+
+class BufferContinueFilterConfig : public Extensions::HttpFilters::Common::EmptyHttpFilterConfig {
+public:
+  BufferContinueFilterConfig() : EmptyHttpFilterConfig("buffer-continue-filter") {}
+
+  Http::FilterFactoryCb createFilter(const std::string&,
+                                     Server::Configuration::FactoryContext&) override {
+    return [](Http::FilterChainFactoryCallbacks& callbacks) -> void {
+      callbacks.addStreamFilter(std::make_shared<::Envoy::BufferContinueStreamFilter>());
+    };
+  }
+};
+
+// perform static registration
+static Registry::RegisterFactory<BufferContinueFilterConfig,
+                                 Server::Configuration::NamedHttpFilterConfigFactory>
+    register_;
+
+} // namespace Envoy
diff --git a/test/integration/header_integration_test.cc b/test/integration/header_integration_test.cc
index 2ceef32088..436519450c 100644
--- a/test/integration/header_integration_test.cc
+++ b/test/integration/header_integration_test.cc
@@ -437,6 +437,13 @@ protected:
   void compareHeaders(Headers&& headers, const ExpectedHeaders& expected_headers) {
     headers.remove(Envoy::Http::LowerCaseString{"content-length"});
     headers.remove(Envoy::Http::LowerCaseString{"date"});
+#if defined(ALIMESH)
+    headers.remove(Envoy::Http::LowerCaseString{"req-start-time"});
+    headers.remove(Envoy::Http::LowerCaseString{"req-cost-time"});
+    headers.remove(Envoy::Http::LowerCaseString{"x-envoy-original-host"});
+    headers.remove(Envoy::Http::LowerCaseString{"req-arrive-time"});
+    headers.remove(Envoy::Http::LowerCaseString{"resp-start-time"});
+#endif
     if (!routerSuppressEnvoyHeaders()) {
       headers.remove(Envoy::Http::LowerCaseString{"x-envoy-expected-rq-timeout-ms"});
       headers.remove(Envoy::Http::LowerCaseString{"x-envoy-upstream-service-time"});
diff --git a/test/integration/http2_flood_integration_test.cc b/test/integration/http2_flood_integration_test.cc
index a5c9d864fb..779a4fd2a1 100644
--- a/test/integration/http2_flood_integration_test.cc
+++ b/test/integration/http2_flood_integration_test.cc
@@ -338,7 +338,11 @@ TEST_P(Http2FloodMitigationTest, Data) {
   // 9-byte frame header; 10 bytes per data frame, 10000 bytes total. The output buffer should also
   // contain response headers, which should be less than 100 bytes.
   EXPECT_LE(10000, buffer_factory->maxBufferSize());
+#if defined(ALIMESH)
+  EXPECT_GE(20000, buffer_factory->maxBufferSize());
+#else
   EXPECT_GE(10100, buffer_factory->maxBufferSize());
+#endif
 
   // The response pipeline input buffer could end up with the full upstream response in 1 go, but
   // there are no guarantees of that being the case.
diff --git a/test/integration/http_integration.cc b/test/integration/http_integration.cc
index dac1ce06c7..4d520b91ff 100644
--- a/test/integration/http_integration.cc
+++ b/test/integration/http_integration.cc
@@ -560,7 +560,12 @@ void HttpIntegrationTest::testRouterUpstreamProtocolError(const std::string& exp
   // TODO(mattklein123): Waiting for exact amount of data is a hack. This needs to
   // be fixed.
   std::string data;
+#if defined(ALIMESH)
+  // We added some custom TRI headers, so the request data changed.
+  ASSERT_TRUE(fake_upstream_connection->waitForData(247, &data));
+#else
   ASSERT_TRUE(fake_upstream_connection->waitForData(187, &data));
+#endif
   ASSERT_TRUE(fake_upstream_connection->write("bad protocol data!"));
   ASSERT_TRUE(fake_upstream_connection->waitForDisconnect());
   ASSERT_TRUE(codec_client_->waitForDisconnect());
@@ -665,6 +670,32 @@ void HttpIntegrationTest::testRouterVirtualClusters() {
   test_server_->waitForCounterEq("vhost.integration.vcluster.other.upstream_rq_total", 1);
 }
 
+// Make sure route level stats are generated correctly.
+void HttpIntegrationTest::testRouteStats() {
+  config_helper_.addConfigModifier(
+      [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
+             hcm) {
+        auto* route_config = hcm.mutable_route_config();
+        ASSERT_EQ(1, route_config->virtual_hosts_size());
+        auto* virtual_host = route_config->mutable_virtual_hosts(0);
+        auto* route = virtual_host->mutable_routes(0);
+        route->set_stat_prefix("test_route");
+      });
+  initialize();
+
+  codec_client_ = makeHttpConnection(lookupPort("http"));
+  Http::TestRequestHeaderMapImpl request_headers{{":method", "POST"},
+                                                 {":path", "/test/long/url"},
+                                                 {":scheme", "http"},
+                                                 {":authority", "sni.lyft.com"}};
+
+  auto response = sendRequestAndWaitForResponse(request_headers, 0, default_response_headers_, 0);
+  checkSimpleRequestSuccess(0, 0, response.get());
+
+  test_server_->waitForCounterEq("vhost.integration.route.test_route.upstream_rq_total", 1);
+  test_server_->waitForCounterEq("vhost.integration.route.test_route.upstream_rq_completed", 1);
+}
+
 void HttpIntegrationTest::testRouterUpstreamDisconnectBeforeRequestComplete() {
   initialize();
   codec_client_ = makeHttpConnection(lookupPort("http"));
@@ -1273,10 +1304,15 @@ void HttpIntegrationTest::testManyRequestHeaders(std::chrono::milliseconds time)
        {Http::Headers::get().Path, "/test/long/url"},
        {Http::Headers::get().Scheme, "http"},
        {Http::Headers::get().Host, "host"}});
-
+#if defined(ALIMESH)
+  for (int i = 0; i < 9000; i++) {
+    big_headers->addCopy(Http::LowerCaseString(std::to_string(i)), std::string(0, 'a'));
+  }
+#else
   for (int i = 0; i < 10000; i++) {
     big_headers->addCopy(Http::LowerCaseString(std::to_string(i)), std::string(0, 'a'));
   }
+#endif
   initialize();
 
   codec_client_ = makeHttpConnection(lookupPort("http"));
diff --git a/test/integration/http_integration.h b/test/integration/http_integration.h
index 6b01dd1b70..1deb5796c8 100644
--- a/test/integration/http_integration.h
+++ b/test/integration/http_integration.h
@@ -201,6 +201,7 @@ protected:
   void testRouterNotFound();
   void testRouterNotFoundWithBody();
   void testRouterVirtualClusters();
+  void testRouteStats();
   void testRouterUpstreamProtocolError(const std::string&, const std::string&);
 
   void testRouterRequestAndResponseWithBody(
diff --git a/test/integration/integration_test.cc b/test/integration/integration_test.cc
index 5e8d025aa1..7eb96d4d73 100644
--- a/test/integration/integration_test.cc
+++ b/test/integration/integration_test.cc
@@ -1278,6 +1278,8 @@ TEST_P(IntegrationTest, Connect) {
   EXPECT_EQ(normalizeDate(response1), normalizeDate(response2));
 }
 
+#if !defined(ALIMESH)
+
 // Test that Envoy by default returns HTTP code 502 on upstream protocol error.
 TEST_P(IntegrationTest, UpstreamProtocolErrorDefault) {
   testRouterUpstreamProtocolError("502", "UPE");
@@ -1290,6 +1292,8 @@ TEST_P(IntegrationTest, UpstreamProtocolErrorRuntimeOverwrite) {
   testRouterUpstreamProtocolError("503", "UC");
 }
 
+#endif
+
 TEST_P(IntegrationTest, TestHead) {
   initialize();
 
diff --git a/test/integration/protocol_integration_test.cc b/test/integration/protocol_integration_test.cc
index a33c7bc0e8..6079649674 100644
--- a/test/integration/protocol_integration_test.cc
+++ b/test/integration/protocol_integration_test.cc
@@ -72,6 +72,8 @@ TEST_P(DownstreamProtocolIntegrationTest, RouterNotFound) { testRouterNotFound()
 
 TEST_P(ProtocolIntegrationTest, RouterVirtualClusters) { testRouterVirtualClusters(); }
 
+TEST_P(ProtocolIntegrationTest, RouterStats) { testRouteStats(); }
+
 // Change the default route to be restrictive, and send a POST to an alternate route.
 TEST_P(DownstreamProtocolIntegrationTest, RouterNotFoundBodyNoBuffer) {
   testRouterNotFoundWithBody();
@@ -3200,4 +3202,56 @@ TEST_P(ProtocolIntegrationTest, FragmentStrippedFromPathWithOverride) {
   EXPECT_EQ("200", response->headers().getStatusValue());
 }
 
+// Test buffering and then continuing after too many response bytes to buffer.
+TEST_P(ProtocolIntegrationTest, BufferContinue) {
+  // Bytes sent is configured for http/2 flow control windows.
+  if (upstreamProtocol() != Http::CodecType::HTTP2) {
+    return;
+  }
+  config_helper_.addConfigModifier(
+      [&](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
+              hcm) -> void {
+        auto* route_config = hcm.mutable_route_config();
+        auto* virtual_host = route_config->mutable_virtual_hosts(0);
+        auto* header = virtual_host->mutable_response_headers_to_add()->Add()->mutable_header();
+        header->set_key("foo");
+        header->set_value("bar");
+      });
+
+  useAccessLog();
+  config_helper_.addFilter("{ name: buffer-continue-filter, typed_config: { \"@type\": "
+                           "type.googleapis.com/google.protobuf.Empty } }");
+  config_helper_.setBufferLimits(1024, 1024);
+  initialize();
+
+  // Send the request.
+  codec_client_ = makeHttpConnection(lookupPort("http"));
+  auto encoder_decoder = codec_client_->startRequest(default_request_headers_);
+  auto downstream_request = &encoder_decoder.first;
+  auto response = std::move(encoder_decoder.second);
+  Buffer::OwnedImpl data("HTTP body content goes here");
+  codec_client_->sendData(*downstream_request, data, true);
+  waitForNextUpstreamRequest();
+
+  // Send the response headers.
+  upstream_request_->encodeHeaders(default_response_headers_, false);
+
+  // Now send an overly large response body. At some point, too much data will
+  // be buffered, the stream will be reset, and the connection will disconnect.
+  upstream_request_->encodeData(512, false);
+  upstream_request_->encodeData(1024 * 100, false);
+
+  if (upstreamProtocol() == Http::CodecType::HTTP1) {
+    ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect());
+  } else {
+    ASSERT_TRUE(upstream_request_->waitForReset());
+    ASSERT_TRUE(fake_upstream_connection_->close());
+    ASSERT_TRUE(fake_upstream_connection_->waitForDisconnect());
+  }
+
+  ASSERT_TRUE(response->waitForEndStream());
+  EXPECT_TRUE(response->complete());
+  EXPECT_EQ("500", response->headers().getStatusValue());
+}
+
 } // namespace Envoy
diff --git a/test/integration/redirect_integration_test.cc b/test/integration/redirect_integration_test.cc
index a88b83a191..813defeaba 100644
--- a/test/integration/redirect_integration_test.cc
+++ b/test/integration/redirect_integration_test.cc
@@ -39,6 +39,15 @@ public:
         ->set_value(3);
     config_helper_.addVirtualHost(handle_max_3_hop);
 
+    auto handle_by_direct_response = config_helper_.createVirtualHost("handle.direct.response");
+    handle_by_direct_response.mutable_routes(0)->set_name("direct_response");
+    handle_by_direct_response.mutable_routes(0)->mutable_direct_response()->set_status(204);
+    handle_by_direct_response.mutable_routes(0)
+        ->mutable_direct_response()
+        ->mutable_body()
+        ->set_inline_string(EMPTY_STRING);
+    config_helper_.addVirtualHost(handle_by_direct_response);
+
     HttpProtocolIntegrationTest::initialize();
   }
 
@@ -597,6 +606,39 @@ TEST_P(RedirectIntegrationTest, InvalidRedirect) {
             response->headers().get(test_header_key_)[0]->value().getStringView());
 }
 
+TEST_P(RedirectIntegrationTest, InternalRedirectHandledByDirectResponse) {
+  useAccessLog("%RESPONSE_FLAGS% %RESPONSE_CODE% %RESPONSE_CODE_DETAILS% %RESP(test-header)%");
+  // Validate that header sanitization is only called once.
+  config_helper_.addConfigModifier(
+      [](envoy::extensions::filters::network::http_connection_manager::v3::HttpConnectionManager&
+             hcm) { hcm.set_via("via_value"); });
+  initialize();
+
+  codec_client_ = makeHttpConnection(lookupPort("http"));
+
+  default_request_headers_.setHost("handle.internal.redirect");
+  IntegrationStreamDecoderPtr response =
+      codec_client_->makeHeaderOnlyRequest(default_request_headers_);
+
+  waitForNextUpstreamRequest();
+
+  redirect_response_.setLocation("http://handle.direct.response/");
+  upstream_request_->encodeHeaders(redirect_response_, true);
+
+  ASSERT_TRUE(response->waitForEndStream());
+  ASSERT_TRUE(response->complete());
+  EXPECT_EQ("204", response->headers().getStatusValue());
+  EXPECT_EQ(1, test_server_->counter("cluster.cluster_0.upstream_internal_redirect_succeeded_total")
+                   ->value());
+  // 302 was never returned downstream
+  EXPECT_EQ(0, test_server_->counter("http.config_test.downstream_rq_3xx")->value());
+  EXPECT_EQ(1, test_server_->counter("http.config_test.downstream_rq_2xx")->value());
+  EXPECT_THAT(waitForAccessLog(access_log_name_, 0),
+              HasSubstr("302 internal_redirect test-header-value\n"));
+  // No test header
+  EXPECT_THAT(waitForAccessLog(access_log_name_, 1), HasSubstr("204 direct_response -\n"));
+}
+
 INSTANTIATE_TEST_SUITE_P(Protocols, RedirectIntegrationTest,
                          testing::ValuesIn(HttpProtocolIntegrationTest::getProtocolTestParams()),
                          HttpProtocolIntegrationTest::protocolTestParamsToString);
diff --git a/test/mocks/http/mocks.h b/test/mocks/http/mocks.h
index 11db504141..8656f772a9 100644
--- a/test/mocks/http/mocks.h
+++ b/test/mocks/http/mocks.h
@@ -838,7 +838,40 @@ MATCHER_P(HeaderMapEqual, rhs, "") {
 }
 
 MATCHER_P(HeaderMapEqualRef, rhs, "") {
-  const bool equal = (arg == *rhs);
+#if defined(ALIMESH)
+  bool equal = true;
+
+  auto getHeaderItems = [](const Envoy::Http::HeaderMap& header,
+                           std::vector<std::pair<absl::string_view, absl::string_view>>& dst) {
+    auto f = [&dst](const Envoy::Http::HeaderEntry& header) -> Envoy::Http::HeaderMap::Iterate {
+      dst.push_back(std::make_pair(header.key().getStringView(), header.value().getStringView()));
+      return Envoy::Http::HeaderMap::Iterate::Continue;
+    };
+
+    header.iterate(f);
+  };
+
+  std::vector<std::pair<absl::string_view, absl::string_view>> arg_header, rhs_header;
+
+  getHeaderItems(arg, arg_header);
+  getHeaderItems((*rhs), rhs_header);
+
+  auto i = arg_header.begin();
+  auto j = rhs_header.begin();
+
+  for (; i != arg_header.end(); ++i, ++j) {
+
+    if (i->first == "req-start-time") {
+      continue;
+    }
+    if (i->first != j->first || i->second != j->second) {
+      equal = false;
+      break;
+    }
+  }
+#else
+  const bool equal = (arg == *rhs)
+#endif
   if (!equal) {
     *result_listener << "\n"
                      << TestUtility::addLeftAndRightPadding("header map:") << "\n"
diff --git a/test/mocks/router/BUILD b/test/mocks/router/BUILD
index 1cfbbf669b..2a704b153d 100644
--- a/test/mocks/router/BUILD
+++ b/test/mocks/router/BUILD
@@ -16,6 +16,7 @@ envoy_cc_mock(
         "//envoy/event:dispatcher_interface",
         "//envoy/json:json_object_interface",
         "//envoy/local_info:local_info_interface",
+        "//envoy/router:cluster_specifier_plugin_interface",
         "//envoy/router:route_config_provider_manager_interface",
         "//envoy/router:router_interface",
         "//envoy/router:router_ratelimit_interface",
diff --git a/test/mocks/router/mocks.cc b/test/mocks/router/mocks.cc
index 8ab3d486fb..b78b29bca8 100644
--- a/test/mocks/router/mocks.cc
+++ b/test/mocks/router/mocks.cc
@@ -27,6 +27,12 @@ MockInternalRedirectPolicy::MockInternalRedirectPolicy() {
   ON_CALL(*this, enabled()).WillByDefault(Return(false));
 }
 
+#if defined(ALIMESH)
+MockInternalActiveRedirectPolicy::MockInternalActiveRedirectPolicy() {
+  ON_CALL(*this, enabled()).WillByDefault(Return(false));
+}
+#endif
+
 MockRetryState::MockRetryState() = default;
 
 void MockRetryState::expectHeadersRetry() {
@@ -103,6 +109,11 @@ MockRouteEntry::MockRouteEntry() {
   ON_CALL(*this, hedgePolicy()).WillByDefault(ReturnRef(hedge_policy_));
   ON_CALL(*this, routeName()).WillByDefault(ReturnRef(route_name_));
   ON_CALL(*this, connectConfig()).WillByDefault(ReturnRef(connect_config_));
+
+#if defined(ALIMESH)
+  ON_CALL(*this, internalActiveRedirectPolicy())
+      .WillByDefault(ReturnRef(internal_active_redirect_policy_));
+#endif
 }
 
 MockRouteEntry::~MockRouteEntry() = default;
@@ -157,5 +168,14 @@ MockScopedRouteConfigProvider::~MockScopedRouteConfigProvider() = default;
 MockGenericConnectionPoolCallbacks::MockGenericConnectionPoolCallbacks() {
   ON_CALL(*this, upstreamToDownstream()).WillByDefault(ReturnRef(upstream_to_downstream_));
 }
+
+MockClusterSpecifierPlugin::MockClusterSpecifierPlugin() {
+  ON_CALL(*this, route(_, _)).WillByDefault(Return(nullptr));
+}
+
+MockClusterSpecifierPluginFactoryConfig::MockClusterSpecifierPluginFactoryConfig() {
+  ON_CALL(*this, createClusterSpecifierPlugin(_, _)).WillByDefault(Return(nullptr));
+}
+
 } // namespace Router
 } // namespace Envoy
diff --git a/test/mocks/router/mocks.h b/test/mocks/router/mocks.h
index e9ccd1de05..ced5d02c80 100644
--- a/test/mocks/router/mocks.h
+++ b/test/mocks/router/mocks.h
@@ -17,6 +17,7 @@
 #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.pb.h"
 #include "envoy/http/hash_policy.h"
 #include "envoy/local_info/local_info.h"
+#include "envoy/router/cluster_specifier_plugin.h"
 #include "envoy/router/rds.h"
 #include "envoy/router/route_config_provider_manager.h"
 #include "envoy/router/router.h"
@@ -156,6 +157,22 @@ public:
   MOCK_METHOD(bool, isCrossSchemeRedirectAllowed, (), (const));
 };
 
+#if defined(ALIMESH)
+class MockInternalActiveRedirectPolicy : public InternalActiveRedirectPolicy {
+public:
+  MockInternalActiveRedirectPolicy();
+  MOCK_METHOD(bool, enabled, (), (const));
+  MOCK_METHOD(bool, shouldRedirectForResponseCode, (const Http::Code& response_code), (const));
+  MOCK_METHOD(std::vector<InternalRedirectPredicateSharedPtr>, predicates, (), (const));
+  MOCK_METHOD(uint32_t, maxInternalRedirects, (), (const));
+  MOCK_METHOD(bool, isCrossSchemeRedirectAllowed, (), (const));
+  MOCK_METHOD(void, evaluateHeaders, (Http::HeaderMap&, const StreamInfo::StreamInfo*), (const));
+  MOCK_METHOD(std::string, redirectUrl, (absl::optional<std::string>), (const));
+  MOCK_METHOD(bool, forcedUseOriginalHost, (), (const));
+  MOCK_METHOD(bool, forcedAddHeaderBeforeRouteMatcher, (), (const));
+};
+#endif
+
 class MockInternalRedirectPredicate : public InternalRedirectPredicate {
 public:
   MOCK_METHOD(bool, acceptTargetRoute, (StreamInfo::FilterState&, absl::string_view, bool, bool));
@@ -263,9 +280,11 @@ public:
 class TestVirtualCluster : public VirtualCluster {
 public:
   // Router::VirtualCluster
+  const absl::optional<std::string>& name() const override { return name_; }
   Stats::StatName statName() const override { return stat_name_.statName(); }
   VirtualClusterStats& stats() const override { return stats_; }
 
+  const absl::optional<std::string> name_ = "fake_virtual_cluster";
   Stats::TestUtil::TestSymbolTable symbol_table_;
   Stats::StatNameManagedStorage stat_name_{"fake_virtual_cluster", *symbol_table_};
   Stats::IsolatedStoreImpl stats_store_;
@@ -390,6 +409,7 @@ public:
   MOCK_METHOD(const VirtualCluster*, virtualCluster, (const Http::HeaderMap& headers), (const));
   MOCK_METHOD(const VirtualHost&, virtualHost, (), (const));
   MOCK_METHOD(bool, autoHostRewrite, (), (const));
+  MOCK_METHOD(bool, appendXfh, (), (const));
   MOCK_METHOD((const std::multimap<std::string, std::string>&), opaqueConfig, (), (const));
   MOCK_METHOD(bool, includeVirtualHostRateLimits, (), (const));
   MOCK_METHOD(const CorsPolicy*, corsPolicy, (), (const));
@@ -402,6 +422,14 @@ public:
   MOCK_METHOD(const UpgradeMap&, upgradeMap, (), (const));
   MOCK_METHOD(const std::string&, routeName, (), (const));
 
+#if defined(ALIMESH)
+  MOCK_METHOD(const InternalActiveRedirectPolicy&, internalActiveRedirectPolicy, (), (const));
+#endif
+
+  const RouteStatsContextOptRef routeStatsContext() const override {
+    return RouteStatsContextOptRef();
+  }
+
   std::string cluster_name_{"fake_cluster"};
   std::string route_name_{"fake_route_name"};
   std::multimap<std::string, std::string> opaque_config_;
@@ -419,6 +447,10 @@ public:
   testing::NiceMock<MockPathMatchCriterion> path_match_criterion_;
   UpgradeMap upgrade_map_;
   absl::optional<ConnectConfig> connect_config_;
+
+#if defined(ALIMESH)
+  testing::NiceMock<MockInternalActiveRedirectPolicy> internal_active_redirect_policy_;
+#endif
 };
 
 class MockDecorator : public Decorator {
@@ -568,7 +600,7 @@ class MockGenericConnPool : public GenericConnPool {
 
 class MockUpstreamToDownstream : public UpstreamToDownstream {
 public:
-  MOCK_METHOD(const RouteEntry&, routeEntry, (), (const));
+  MOCK_METHOD(const Route&, route, (), (const));
   MOCK_METHOD(const Network::Connection&, connection, (), (const));
 
   MOCK_METHOD(void, decodeData, (Buffer::Instance&, bool));
@@ -601,5 +633,27 @@ public:
   NiceMock<MockUpstreamToDownstream> upstream_to_downstream_;
 };
 
+class MockClusterSpecifierPlugin : public ClusterSpecifierPlugin {
+public:
+  MockClusterSpecifierPlugin();
+
+  MOCK_METHOD(RouteConstSharedPtr, route,
+              (const RouteEntry& parent, const Http::RequestHeaderMap& header), (const));
+};
+
+class MockClusterSpecifierPluginFactoryConfig : public ClusterSpecifierPluginFactoryConfig {
+public:
+  MockClusterSpecifierPluginFactoryConfig();
+  MOCK_METHOD(ClusterSpecifierPluginSharedPtr, createClusterSpecifierPlugin,
+              (const Protobuf::Message& config,
+               Server::Configuration::CommonFactoryContext& context));
+
+  ProtobufTypes::MessagePtr createEmptyConfigProto() override {
+    return std::make_unique<ProtobufWkt::Struct>();
+  }
+
+  std::string name() const override { return "envoy.router.cluster_specifier_plugin.mock"; }
+};
+
 } // namespace Router
 } // namespace Envoy
diff --git a/test/mocks/router/router_filter_interface.cc b/test/mocks/router/router_filter_interface.cc
index 9d175ee6cb..1e025fa431 100644
--- a/test/mocks/router/router_filter_interface.cc
+++ b/test/mocks/router/router_filter_interface.cc
@@ -20,9 +20,9 @@ MockRouterFilterInterface::MockRouterFilterInterface()
   ON_CALL(*this, upstreamRequests()).WillByDefault(ReturnRef(requests_));
   EXPECT_CALL(callbacks_.dispatcher_, pushTrackedObject(_)).Times(AnyNumber());
   EXPECT_CALL(callbacks_.dispatcher_, popTrackedObject(_)).Times(AnyNumber());
-  ON_CALL(*this, routeEntry()).WillByDefault(Return(&route_entry_));
+  ON_CALL(*this, route()).WillByDefault(Return(&route_));
   ON_CALL(callbacks_, connection()).WillByDefault(Return(&client_connection_));
-  route_entry_.connect_config_.emplace(RouteEntry::ConnectConfig());
+  route_.route_entry_.connect_config_.emplace(RouteEntry::ConnectConfig());
 }
 
 MockRouterFilterInterface::~MockRouterFilterInterface() = default;
diff --git a/test/mocks/router/router_filter_interface.h b/test/mocks/router/router_filter_interface.h
index d1349a4103..1a662e24ae 100644
--- a/test/mocks/router/router_filter_interface.h
+++ b/test/mocks/router/router_filter_interface.h
@@ -45,13 +45,17 @@ public:
   MOCK_METHOD(bool, downstreamEndStream, (), (const));
   MOCK_METHOD(uint32_t, attemptCount, (), (const));
   MOCK_METHOD(const VirtualCluster*, requestVcluster, (), (const));
-  MOCK_METHOD(const RouteEntry*, routeEntry, (), (const));
+  MOCK_METHOD(const Route*, route, (), (const));
   MOCK_METHOD(const std::list<UpstreamRequestPtr>&, upstreamRequests, (), (const));
   MOCK_METHOD(const UpstreamRequest*, finalUpstreamRequest, (), (const));
   MOCK_METHOD(TimeSource&, timeSource, ());
 
+  const RouteStatsContextOptRef routeStatsContext() const override {
+    return RouteStatsContextOptRef();
+  }
+
   NiceMock<Envoy::Http::MockStreamDecoderFilterCallbacks> callbacks_;
-  NiceMock<MockRouteEntry> route_entry_;
+  NiceMock<MockRoute> route_;
   NiceMock<Network::MockConnection> client_connection_;
 
   envoy::extensions::filters::http::router::v3::Router router_proto;
diff --git a/test/mocks/stream_info/mocks.cc b/test/mocks/stream_info/mocks.cc
index 49bdf235a5..77b7bb00f5 100644
--- a/test/mocks/stream_info/mocks.cc
+++ b/test/mocks/stream_info/mocks.cc
@@ -109,7 +109,12 @@ MockStreamInfo::MockStreamInfo()
   ON_CALL(*this, setRouteName(_)).WillByDefault(Invoke([this](const absl::string_view route_name) {
     route_name_ = std::string(route_name);
   }));
+  ON_CALL(*this, setVirtualClusterName(_))
+      .WillByDefault(Invoke([this](const absl::optional<std::string>& virtual_cluster_name) {
+        virtual_cluster_name_ = virtual_cluster_name;
+      }));
   ON_CALL(*this, getRouteName()).WillByDefault(ReturnRef(route_name_));
+  ON_CALL(*this, virtualClusterName()).WillByDefault(ReturnRef(virtual_cluster_name_));
   ON_CALL(*this, upstreamTransportFailureReason())
       .WillByDefault(ReturnRef(upstream_transport_failure_reason_));
   ON_CALL(*this, setConnectionID(_)).WillByDefault(Invoke([this](uint64_t id) {
diff --git a/test/mocks/stream_info/mocks.h b/test/mocks/stream_info/mocks.h
index 2d296f9697..c72285f8de 100644
--- a/test/mocks/stream_info/mocks.h
+++ b/test/mocks/stream_info/mocks.h
@@ -49,7 +49,10 @@ public:
   MOCK_METHOD(void, addBytesReceived, (uint64_t));
   MOCK_METHOD(uint64_t, bytesReceived, (), (const));
   MOCK_METHOD(void, setRouteName, (absl::string_view route_name));
+  MOCK_METHOD(void, setVirtualClusterName,
+              (const absl::optional<std::string>& virtual_cluster_name));
   MOCK_METHOD(const std::string&, getRouteName, (), (const));
+  MOCK_METHOD(const absl::optional<std::string>&, virtualClusterName, (), (const));
   MOCK_METHOD(absl::optional<Http::Protocol>, protocol, (), (const));
   MOCK_METHOD(void, protocol, (Http::Protocol protocol));
   MOCK_METHOD(absl::optional<uint32_t>, responseCode, (), (const));
@@ -132,6 +135,7 @@ public:
   std::string filter_chain_name_;
   absl::optional<uint64_t> upstream_connection_id_;
   absl::optional<uint32_t> attempt_count_;
+  absl::optional<std::string> virtual_cluster_name_;
 };
 
 } // namespace StreamInfo
diff --git a/test/mocks/thread_local/mocks.h b/test/mocks/thread_local/mocks.h
index 3fa0f8d347..6696703e89 100644
--- a/test/mocks/thread_local/mocks.h
+++ b/test/mocks/thread_local/mocks.h
@@ -73,6 +73,7 @@ public:
       EXPECT_TRUE(was_set_);
       parent_.runOnAllThreads([cb, this]() { cb(parent_.data_[index_]); }, main_callback);
     }
+    bool isShutdown() const override { return parent_.shutdown_; }
 
     void set(InitializeCb cb) override {
       was_set_ = true;
diff --git a/test/mocks/upstream/host.h b/test/mocks/upstream/host.h
index cd6cc8e21b..698e72c2c2 100644
--- a/test/mocks/upstream/host.h
+++ b/test/mocks/upstream/host.h
@@ -35,6 +35,10 @@ public:
   MOCK_METHOD(double, successRate, (DetectorHostMonitor::SuccessRateMonitorType type), (const));
   MOCK_METHOD(void, successRate,
               (DetectorHostMonitor::SuccessRateMonitorType type, double new_success_rate));
+
+#if defined(ALIMESH)
+  MOCK_METHOD(void, forceEjectHost, ());
+#endif
 };
 
 class MockEventLogger : public EventLogger {
diff --git a/test/server/BUILD b/test/server/BUILD
index 952131ac02..3c73052062 100644
--- a/test/server/BUILD
+++ b/test/server/BUILD
@@ -9,7 +9,7 @@ load(
     "envoy_select_hot_restart",
 )
 load("//source/extensions:all_extensions.bzl", "envoy_all_extensions")
-load("//bazel:repositories.bzl", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
+load("//bazel:repositories.bzl", "DARWIN_SKIP_TARGETS", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
 
 licenses(["notice"])  # Apache 2
 
@@ -377,6 +377,7 @@ envoy_cc_fuzz_test(
     ] + select({
         "//bazel:windows_x86_64": envoy_all_extensions(WINDOWS_SKIP_TARGETS),
         "//bazel:linux_ppc": envoy_all_extensions(PPC_SKIP_TARGETS),
+        "//bazel:darwin": envoy_all_extensions(DARWIN_SKIP_TARGETS),
         "//bazel:gcc_build": [],
         "//conditions:default": envoy_all_extensions(),
     }),
diff --git a/test/server/config_validation/BUILD b/test/server/config_validation/BUILD
index 626b0b9381..0874ffc288 100644
--- a/test/server/config_validation/BUILD
+++ b/test/server/config_validation/BUILD
@@ -1,6 +1,6 @@
 load("//bazel:envoy_build_system.bzl", "envoy_cc_fuzz_test", "envoy_cc_test", "envoy_cc_test_library", "envoy_package", "envoy_proto_library")
 load("//source/extensions:all_extensions.bzl", "envoy_all_extensions")
-load("//bazel:repositories.bzl", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
+load("//bazel:repositories.bzl", "DARWIN_SKIP_TARGETS", "PPC_SKIP_TARGETS", "WINDOWS_SKIP_TARGETS")
 
 licenses(["notice"])  # Apache 2
 
@@ -92,6 +92,7 @@ envoy_cc_fuzz_test(
     ] + select({
         "//bazel:windows_x86_64": envoy_all_extensions(WINDOWS_SKIP_TARGETS),
         "//bazel:linux_ppc": envoy_all_extensions(PPC_SKIP_TARGETS),
+        "//bazel:darwin": envoy_all_extensions(DARWIN_SKIP_TARGETS),
         "//bazel:gcc_build": [],
         "//conditions:default": envoy_all_extensions(),
     }),
diff --git a/test/test_common/delegating_route_utility.h b/test/test_common/delegating_route_utility.h
index 2189f88946..4a12b75f32 100644
--- a/test/test_common/delegating_route_utility.h
+++ b/test/test_common/delegating_route_utility.h
@@ -13,6 +13,9 @@ public:
       : DelegatingRouteEntry(std::move(base_route)), custom_cluster_name_(cluster_name_override) {}
 
   const std::string& clusterName() const override { return custom_cluster_name_; }
+  const RouteStatsContextOptRef routeStatsContext() const override {
+    return RouteStatsContextOptRef();
+  }
 
 private:
   const std::string custom_cluster_name_;
diff --git a/test/test_common/status_utility.h b/test/test_common/status_utility.h
index 7611830b26..fae63ce3bb 100644
--- a/test/test_common/status_utility.h
+++ b/test/test_common/status_utility.h
@@ -38,5 +38,115 @@ MATCHER_P(StatusIs, expected_code, "") {
   return true;
 }
 
+// A polymorphic matcher class for matching absl::Status or absl::StatusOr.
+// Not intended for direct use, see HasStatus, HasStatusCode, HasStatusMessage and IsOk
+// below.
+class StatusMatcher {
+public:
+  StatusMatcher(::testing::Matcher<absl::Status> matcher) : matcher_(matcher) {}
+
+  // NOLINTNEXTLINE(readability-identifier-naming)
+  bool MatchAndExplain(absl::Status status, ::testing::MatchResultListener* listener) const {
+    return matcher_.MatchAndExplain(status, listener);
+  }
+
+  template <typename T>
+  // NOLINTNEXTLINE(readability-identifier-naming)
+  bool MatchAndExplain(const absl::StatusOr<T>& status_or,
+                       ::testing::MatchResultListener* listener) const {
+    return ::testing::ExplainMatchResult(
+        ::testing::Property("status", &absl::StatusOr<T>::status, matcher_), status_or, listener);
+  }
+  // NOLINTNEXTLINE(readability-identifier-naming)
+  void DescribeTo(::std::ostream* os) const { matcher_.DescribeTo(os); }
+  // NOLINTNEXTLINE(readability-identifier-naming)
+  void DescribeNegationTo(::std::ostream* os) const {
+    *os << "not ";
+    matcher_.DescribeTo(os);
+  }
+
+private:
+  ::testing::Matcher<absl::Status> matcher_;
+};
+
+// Match status code in an absl::StatusOr or absl::Status, allowing arbitrary matchers,
+// e.g.
+// EXPECT_THAT(some_status_or, HasStatusCode(AnyOf(absl::StatusCode::kOk,
+//                                                 absl::StatusCode::kInvalidArgument)));
+template <typename InnerMatcher>
+// NOLINTNEXTLINE(readability-identifier-naming)
+::testing::PolymorphicMatcher<StatusMatcher> HasStatusCode(InnerMatcher m) {
+  return ::testing::MakePolymorphicMatcher(StatusMatcher(::testing::SafeMatcherCast<absl::Status>(
+      ::testing::Property("code", &absl::Status::code, m))));
+}
+
+// Match status message in an absl::StatusOr or absl::Status, allowing arbitrary matchers,
+// e.g.
+// EXPECT_THAT(some_status_or, HasStatusMessage(HasSubstr("cheese")));
+template <typename InnerMatcher>
+// NOLINTNEXTLINE(readability-identifier-naming)
+::testing::PolymorphicMatcher<StatusMatcher> HasStatusMessage(InnerMatcher m) {
+  return ::testing::MakePolymorphicMatcher(StatusMatcher(::testing::SafeMatcherCast<absl::Status>(
+      ::testing::Property("message", &absl::Status::message, m))));
+}
+
+// Match the status of an absl::StatusOr or absl::Status, e.g.
+// EXPECT_THAT(some_status_or, HasStatus(absl::InvalidArgumentError("oh no")));
+// One may also use a Status matcher, but see the other HasStatus below for a
+// more readable version of that.
+template <typename InnerMatcher>
+// NOLINTNEXTLINE(readability-identifier-naming)
+::testing::PolymorphicMatcher<StatusMatcher> HasStatus(InnerMatcher m) {
+  return ::testing::MakePolymorphicMatcher(
+      StatusMatcher(::testing::SafeMatcherCast<absl::Status>(m)));
+}
+
+// Match the code and message of an absl::StatusOr or absl::Status, e.g.
+// EXPECT_THAT(some_status_or, HasStatus(absl::StatusCode::kInvalidArgument, HasSubstr("cheese")));
+template <typename InnerMatcherCode, typename InnerMatcherMessage>
+// NOLINTNEXTLINE(readability-identifier-naming)
+::testing::PolymorphicMatcher<StatusMatcher> HasStatus(InnerMatcherCode code_matcher,
+                                                       InnerMatcherMessage message_matcher) {
+  return ::testing::MakePolymorphicMatcher(StatusMatcher(::testing::SafeMatcherCast<absl::Status>(
+      AllOf(::testing::Property("code", &absl::Status::code, code_matcher),
+            ::testing::Property("message", &absl::Status::message, message_matcher)))));
+}
+
+// Check that an absl::Status or absl::StatusOr is OK.
+//
+// For example:
+//
+// StatusOr<int> status_or(absl::InvalidArgumentError("bad argument!"));
+// EXPECT_THAT(status_or, IsOk());  // fails!
+//
+// NOLINTNEXTLINE(readability-identifier-naming)
+inline ::testing::PolymorphicMatcher<StatusMatcher> IsOk() {
+  return HasStatusCode(absl::StatusCode::kOk);
+}
+
+#ifndef EXPECT_OK
+// Fails if an absl::Status or absl::StatusOr is not OK.
+//
+// For example:
+//
+// StatusOr<int> status_or(absl::InvalidArgumentError("bad argument!"));
+// EXPECT_OK(status_or);  // fails!
+// absl::Status status{absl::OkStatus()};
+// EXPECT_OK(status);  // passes!
+#define EXPECT_OK(v) EXPECT_THAT((v), ::Envoy::StatusHelpers::IsOk())
+#endif // EXPECT_OK
+
+#ifndef ASSERT_OK
+// Asserts if an absl::Status or absl::StatusOr is not OK.
+//
+// For example:
+//
+// StatusOr<int> status_or(absl::InvalidArgumentError("bad argument!"));
+// ASSERT_OK(status_or);  // asserts!
+// absl::Status status{absl::OkStatus()};
+// ASSERT_OK(status);  // passes!
+#define ASSERT_OK(v) ASSERT_THAT((v), ::Envoy::StatusHelpers::IsOk())
+#endif // ASSERT_OK
+
 } // namespace StatusHelpers
 } // namespace Envoy
diff --git a/test/test_common/status_utility_test.cc b/test/test_common/status_utility_test.cc
new file mode 100644
index 0000000000..71ee8a5c67
--- /dev/null
+++ b/test/test_common/status_utility_test.cc
@@ -0,0 +1,141 @@
+#include "test/test_common/status_utility.h"
+
+namespace Envoy {
+namespace StatusHelpers {
+
+using ::testing::HasSubstr;
+
+template <typename T, typename MatcherT>
+std::string expectThatOutput(const T& value, MatcherT matcher) {
+  auto m = ::testing::SafeMatcherCast<T>(matcher);
+  if (m.Matches(value)) {
+    return "";
+  }
+  ::std::stringstream ss;
+  ss << "Value of: [variable_name]" << std::endl;
+  ss << "Expected: ";
+  m.DescribeTo(&ss);
+  ss << std::endl << "Actual: " << ::testing::PrintToString(value);
+  ::testing::StringMatchResultListener listener;
+  ::testing::ExplainMatchResult(matcher, value, &listener);
+  ss << std::endl << listener.str();
+  return ss.str();
+}
+
+TEST(StatusUtilityTest, ExpectOkForStatus) { EXPECT_OK(absl::OkStatus()); }
+
+TEST(StatusUtilityTest, ExpectOkForStatusOr) { EXPECT_OK(absl::StatusOr<int>{5}); }
+
+TEST(StatusUtilityTest, IsOkFailureForStatus) {
+  auto err = expectThatOutput(absl::FailedPreconditionError("whatever"), IsOk());
+  EXPECT_THAT(err, AllOf(HasSubstr("Expected: is an object whose property `code` is equal to OK"),
+                         HasSubstr("Actual: FAILED_PRECONDITION: whatever"),
+                         HasSubstr("whose property `code` is FAILED_PRECONDITION")));
+}
+
+TEST(StatusUtilityTest, IsOkFailureForStatusOr) {
+  auto err =
+      expectThatOutput(absl::StatusOr<int>{absl::FailedPreconditionError("whatever")}, IsOk());
+  EXPECT_THAT(err, AllOf(HasSubstr("whose property `status` is FAILED_PRECONDITION: whatever"),
+                         HasSubstr("whose property `code` is FAILED_PRECONDITION")));
+}
+
+TEST(StatusUtilityTest, HasStatusCodeSuccessForStatus) {
+  EXPECT_THAT(absl::FailedPreconditionError("whatever"),
+              HasStatusCode(absl::StatusCode::kFailedPrecondition));
+}
+
+TEST(StatusUtilityTest, HasStatusMessageSuccessForStatus) {
+  EXPECT_THAT(absl::FailedPreconditionError("whatever"), HasStatusMessage(HasSubstr("whatever")));
+}
+
+TEST(StatusUtilityTest, HasStatusCodeFailureForStatusOr) {
+  auto err = expectThatOutput(absl::StatusOr<int>{5},
+                              HasStatusCode(absl::StatusCode::kFailedPrecondition));
+  EXPECT_THAT(
+      err,
+      AllOf(
+          HasSubstr("Expected: is an object whose property `code` is equal to FAILED_PRECONDITION"),
+          HasSubstr("whose property `status` is OK")));
+}
+
+TEST(StatusUtilityTest, HasStatusMessageFailureForStatus) {
+  auto err = expectThatOutput(absl::InvalidArgumentError("oh no"), HasStatusMessage("whatever"));
+  EXPECT_THAT(err, HasSubstr("whose property `message` is \"oh no\""));
+}
+
+TEST(StatusUtilityTest, HasStatusFailureForStatusOr) {
+  auto err = expectThatOutput(absl::StatusOr<int>{absl::InvalidArgumentError("oh no")},
+                              HasStatus(absl::OkStatus()));
+  EXPECT_THAT(err, AllOf(HasSubstr("Expected: is equal to OK"),
+                         HasSubstr("whose property `status` is INVALID_ARGUMENT: oh no")));
+}
+
+TEST(StatusUtilityTest, HasStatusFailureForStatus) {
+  auto err = expectThatOutput(absl::InvalidArgumentError("oh no"), HasStatus(absl::OkStatus()));
+  EXPECT_THAT(err, AllOf(HasSubstr("Expected: is equal to OK"),
+                         HasSubstr("Actual: INVALID_ARGUMENT: oh no")));
+}
+
+TEST(StatusUtilityTest, HasStatusSuccessForStatusOr) {
+  auto status = absl::InvalidArgumentError("oh no");
+  EXPECT_THAT(absl::StatusOr<int>{status}, HasStatus(status));
+}
+
+TEST(StatusUtilityTest, HasStatusSuccessForStatus) {
+  auto status = absl::InvalidArgumentError("oh no");
+  EXPECT_THAT(status, HasStatus(status));
+}
+
+TEST(StatusUtilityTest, HasStatusTwoParamsFailureForStatusOr) {
+  auto err = expectThatOutput(absl::StatusOr<int>{absl::InvalidArgumentError("oh no")},
+                              HasStatus(absl::StatusCode::kOk, HasSubstr("whatever")));
+  EXPECT_THAT(
+      err,
+      AllOf(HasSubstr("Expected: (is an object whose property `code` is equal to OK) and (is an "
+                      "object whose property `message` has substring \"whatever\")"),
+            HasSubstr("whose property `status` is INVALID_ARGUMENT: oh no")));
+}
+
+TEST(StatusUtilityTest, HasStatusTwoParamsFailureForStatus) {
+  auto err = expectThatOutput(absl::InvalidArgumentError("oh no"),
+                              HasStatus(absl::StatusCode::kOk, HasSubstr("whatever")));
+  EXPECT_THAT(
+      err,
+      AllOf(HasSubstr("Expected: (is an object whose property `code` is equal to OK) and (is an "
+                      "object whose property `message` has substring \"whatever\")"),
+            HasSubstr("Actual: INVALID_ARGUMENT: oh no"),
+            HasSubstr("whose property `code` is INVALID_ARGUMENT")));
+}
+
+TEST(StatusUtilityTest, HasStatusTwoParamsSuccessForStatusOr) {
+  auto err = absl::InvalidArgumentError("oh no");
+  auto status_or = absl::StatusOr<int>{err};
+  EXPECT_THAT(status_or, HasStatus(absl::StatusCode::kInvalidArgument, HasSubstr("oh no")));
+}
+
+TEST(StatusUtilityTest, HasStatusTwoParamsSuccessForStatus) {
+  auto err = absl::InvalidArgumentError("oh no");
+  EXPECT_THAT(err, HasStatus(absl::StatusCode::kInvalidArgument, HasSubstr("oh no")));
+}
+
+TEST(StatusUtilityTest, IsOkAndHoldsSuccess) {
+  absl::StatusOr<int> five = 5;
+  EXPECT_THAT(five, IsOkAndHolds(5));
+}
+
+TEST(StatusUtilityTest, IsOkAndHoldsFailureByValue) {
+  ::testing::StringMatchResultListener listener;
+  ::testing::ExplainMatchResult(IsOkAndHolds(5), absl::StatusOr<int>{6}, &listener);
+  EXPECT_EQ("which has wrong value: 6", listener.str());
+}
+
+TEST(StatusUtilityTest, IsOkAndHoldsFailureByCode) {
+  ::testing::StringMatchResultListener listener;
+  ::testing::ExplainMatchResult(
+      IsOkAndHolds(5), absl::StatusOr<int>{absl::FailedPreconditionError("oh no")}, &listener);
+  EXPECT_EQ("which has unexpected status: FAILED_PRECONDITION: oh no", listener.str());
+}
+
+} // namespace StatusHelpers
+} // namespace Envoy
diff --git a/test/test_common/utility.cc b/test/test_common/utility.cc
index fe0db0bcf7..4d5b193355 100644
--- a/test/test_common/utility.cc
+++ b/test/test_common/utility.cc
@@ -71,6 +71,12 @@ bool TestUtility::headerMapEqualIgnoreOrder(const Http::HeaderMap& lhs,
   absl::flat_hash_set<std::string> rhs_keys;
   lhs.iterate([&lhs_keys](const Http::HeaderEntry& header) -> Http::HeaderMap::Iterate {
     const std::string key{header.key().getStringView()};
+#if defined(ALIMESH)
+    if (key == Http::CustomHeaders::get().AliExtendedValues.TriStartTime.get() ||
+        key == Http::CustomHeaders::get().AliExtendedValues.EnvoyOriginalHost.get()) {
+      return Http::HeaderMap::Iterate::Continue;
+    }
+#endif
     lhs_keys.insert(key);
     return Http::HeaderMap::Iterate::Continue;
   });
diff --git a/tools/code_format/check_format.py b/tools/code_format/check_format.py
index d01897fc33..ed193869ce 100755
--- a/tools/code_format/check_format.py
+++ b/tools/code_format/check_format.py
@@ -356,6 +356,11 @@ class FormatChecker:
         error_messages = []
 
         clang_format_abs_path = self.look_path(CLANG_FORMAT_PATH)
+        print('clang format path: {}'.format(clang_format_abs_path))
+        command = "%s --version" % (clang_format_abs_path)
+        if os.system(command) != 0:
+            error_messages.append("clang-format version error")
+
         if clang_format_abs_path:
             if not self.executable_by_others(clang_format_abs_path):
                 error_messages.append(
diff --git a/tools/code_format/check_shellcheck_format.sh b/tools/code_format/check_shellcheck_format.sh
index b09ba6cb08..9b1e08dd8c 100755
--- a/tools/code_format/check_shellcheck_format.sh
+++ b/tools/code_format/check_shellcheck_format.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -e
 
-EXCLUDED_SHELLFILES=${EXCLUDED_SHELLFILES:-".rst$|.md$"}
+EXCLUDED_SHELLFILES=${EXCLUDED_SHELLFILES:-"^.github|.rst$|.md$|.*aone.*|xsdk.BUILD"}
 SHEBANG_RE='^#!/bin/bash|^#!/bin/sh|^#!/usr/bin/env bash|^#!/usr/bin/env sh'
 
 
diff --git a/tools/proto_format/proto_sync.py b/tools/proto_format/proto_sync.py
index 8d878309c6..40983f8d59 100755
--- a/tools/proto_format/proto_sync.py
+++ b/tools/proto_format/proto_sync.py
@@ -44,6 +44,9 @@ CONTRIB_V3_ALLOW_LIST = [
     'envoy.extensions.filters.network.kafka_broker.v3',
     'envoy.extensions.filters.network.mysql_proxy.v3',
     'envoy.extensions.filters.network.rocketmq_proxy.v3',
+
+    # Ingress gateway.
+    'envoy.extensions.filters.http.http_dubbo_transcoder.v3',
 ]
 
 BUILD_FILE_TEMPLATE = string.Template(
diff --git a/tools/spelling/spelling_dictionary.txt b/tools/spelling/spelling_dictionary.txt
index f89846c06b..e1cdf5a94b 100644
--- a/tools/spelling/spelling_dictionary.txt
+++ b/tools/spelling/spelling_dictionary.txt
@@ -242,6 +242,7 @@ OSI
 OSS
 OSX
 OT
+OTLP
 OU
 OVFL
 PAYLOADLEN
@@ -1200,6 +1201,7 @@ tokenizing
 toolchain
 traceid
 traceparent
+tracestate
 transcode
 transcoded
 transcoder
@@ -1301,3 +1303,6 @@ crlf
 ep
 suri
 transid
+WAF
+TRI
+tmd
