You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by co...@apache.org on 2020/02/15 08:54:13 UTC

[dubbo] branch xds updated: add pilot-registry for xds (#5741)

This is an automated email from the ASF dual-hosted git repository.

codingsinger pushed a commit to branch xds
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/xds by this push:
     new c39faaa  add pilot-registry for xds (#5741)
c39faaa is described below

commit c39faaad3913560a8c83a7acc2258bd31f8cd5dd
Author: HzjNeverStop <44...@qq.com>
AuthorDate: Sat Feb 15 16:53:54 2020 +0800

    add pilot-registry for xds (#5741)
---
 dubbo-all/pom.xml                                  |   16 +
 .../dubbo/registry/support/AbstractRegistry.java   |   18 +
 dubbo-registry/dubbo-registry-pilot/pom.xml        |   33 +
 .../PilotRegistry.java                             |  132 +++
 .../PilotRegistryFactory.java                      |   25 +
 .../org.apache.dubbo.registry.RegistryFactory      |    1 +
 dubbo-registry/pom.xml                             |    1 +
 dubbo-remoting/dubbo-remoting-pilot/pom.xml        |   73 ++
 .../dubbo/remoting/pilot/AbstractPilotClient.java  |  115 ++
 .../apache/dubbo/remoting/pilot/ChildListener.java |   15 +
 .../org/apache/dubbo/remoting/pilot/Constants.java |   16 +
 .../apache/dubbo/remoting/pilot/PilotClient.java   |   64 +
 .../dubbo/remoting/pilot/PilotTransporter.java     |   18 +
 .../apache/dubbo/remoting/pilot/StateListener.java |   15 +
 .../dubbo/remoting/pilot/grpc/GrpcClient.java      |  113 ++
 .../dubbo/remoting/pilot/grpc/GrpcConnection.java  |  170 +++
 .../remoting/pilot/grpc/GrpcDiscoveryManager.java  |  130 ++
 .../dubbo/remoting/pilot/grpc/GrpcTransporter.java |   17 +
 .../dubbo/remoting/pilot/option/DiscoveryUtil.java |  221 ++++
 .../src/main/proto/envoy/admin/v2alpha/BUILD       |   65 +
 .../src/main/proto/envoy/admin/v2alpha/certs.proto |   57 +
 .../main/proto/envoy/admin/v2alpha/clusters.proto  |   85 ++
 .../proto/envoy/admin/v2alpha/config_dump.proto    |  180 +++
 .../main/proto/envoy/admin/v2alpha/memory.proto    |   37 +
 .../main/proto/envoy/admin/v2alpha/metrics.proto   |   26 +
 .../proto/envoy/admin/v2alpha/mutex_stats.proto    |   28 +
 .../proto/envoy/admin/v2alpha/server_info.proto    |  134 +++
 .../src/main/proto/envoy/admin/v2alpha/tap.proto   |   20 +
 .../src/main/proto/envoy/api/v2/BUILD              |  144 +++
 .../src/main/proto/envoy/api/v2/README.md          |    9 +
 .../src/main/proto/envoy/api/v2/auth/BUILD         |   35 +
 .../src/main/proto/envoy/api/v2/auth/cert.proto    |  380 ++++++
 .../src/main/proto/envoy/api/v2/cds.proto          |  605 ++++++++++
 .../src/main/proto/envoy/api/v2/cluster/BUILD      |   35 +
 .../envoy/api/v2/cluster/circuit_breaker.proto     |   57 +
 .../envoy/api/v2/cluster/outlier_detection.proto   |   83 ++
 .../src/main/proto/envoy/api/v2/core/BUILD         |  132 +++
 .../src/main/proto/envoy/api/v2/core/address.proto |  121 ++
 .../src/main/proto/envoy/api/v2/core/base.proto    |  256 ++++
 .../proto/envoy/api/v2/core/config_source.proto    |  124 ++
 .../proto/envoy/api/v2/core/grpc_service.proto     |  173 +++
 .../proto/envoy/api/v2/core/health_check.proto     |  266 +++++
 .../main/proto/envoy/api/v2/core/http_uri.proto    |   52 +
 .../main/proto/envoy/api/v2/core/protocol.proto    |   99 ++
 .../src/main/proto/envoy/api/v2/discovery.proto    |  208 ++++
 .../src/main/proto/envoy/api/v2/eds.proto          |  113 ++
 .../src/main/proto/envoy/api/v2/endpoint/BUILD     |   49 +
 .../proto/envoy/api/v2/endpoint/endpoint.proto     |  135 +++
 .../proto/envoy/api/v2/endpoint/load_report.proto  |  163 +++
 .../src/main/proto/envoy/api/v2/lds.proto          |  181 +++
 .../src/main/proto/envoy/api/v2/listener/BUILD     |   24 +
 .../proto/envoy/api/v2/listener/listener.proto     |  217 ++++
 .../src/main/proto/envoy/api/v2/ratelimit/BUILD    |   14 +
 .../proto/envoy/api/v2/ratelimit/ratelimit.proto   |   66 ++
 .../src/main/proto/envoy/api/v2/rds.proto          |  104 ++
 .../src/main/proto/envoy/api/v2/route/BUILD        |   24 +
 .../src/main/proto/envoy/api/v2/route/route.proto  | 1252 ++++++++++++++++++++
 .../src/main/proto/envoy/config/README.md          |    3 +
 .../src/main/proto/envoy/config/accesslog/v2/BUILD |   16 +
 .../main/proto/envoy/config/accesslog/v2/als.proto |   52 +
 .../proto/envoy/config/accesslog/v2/file.proto     |   32 +
 .../src/main/proto/envoy/config/bootstrap/v2/BUILD |   40 +
 .../envoy/config/bootstrap/v2/bootstrap.proto      |  216 ++++
 .../proto/envoy/config/common/tap/v2alpha/BUILD    |   12 +
 .../envoy/config/common/tap/v2alpha/common.proto   |   35 +
 .../src/main/proto/envoy/config/filter/README.md   |    4 +
 .../proto/envoy/config/filter/accesslog/v2/BUILD   |   28 +
 .../config/filter/accesslog/v2/accesslog.proto     |  228 ++++
 .../config/filter/dubbo/router/v2alpha1/BUILD      |    8 +
 .../filter/dubbo/router/v2alpha1/router.proto      |   14 +
 .../main/proto/envoy/config/filter/fault/v2/BUILD  |   13 +
 .../proto/envoy/config/filter/fault/v2/fault.proto |   66 ++
 .../proto/envoy/config/filter/http/buffer/v2/BUILD |    8 +
 .../config/filter/http/buffer/v2/buffer.proto      |   37 +
 .../envoy/config/filter/http/ext_authz/v2/BUILD    |   14 +
 .../filter/http/ext_authz/v2/ext_authz.proto       |  159 +++
 .../proto/envoy/config/filter/http/fault/v2/BUILD  |   13 +
 .../envoy/config/filter/http/fault/v2/fault.proto  |   89 ++
 .../http/grpc_http1_reverse_bridge/v2alpha1/BUILD  |    8 +
 .../v2alpha1/config.proto                          |   27 +
 .../proto/envoy/config/filter/http/gzip/v2/BUILD   |    8 +
 .../envoy/config/filter/http/gzip/v2/gzip.proto    |   75 ++
 .../config/filter/http/header_to_metadata/v2/BUILD |    9 +
 .../header_to_metadata/v2/header_to_metadata.proto |   73 ++
 .../envoy/config/filter/http/health_check/v2/BUILD |   21 +
 .../filter/http/health_check/v2/health_check.proto |   44 +
 .../envoy/config/filter/http/ip_tagging/v2/BUILD   |    9 +
 .../filter/http/ip_tagging/v2/ip_tagging.proto     |   55 +
 .../config/filter/http/jwt_authn/v2alpha/BUILD     |   13 +
 .../config/filter/http/jwt_authn/v2alpha/README.md |   31 +
 .../filter/http/jwt_authn/v2alpha/config.proto     |  436 +++++++
 .../proto/envoy/config/filter/http/lua/v2/BUILD    |    8 +
 .../envoy/config/filter/http/lua/v2/lua.proto      |   21 +
 .../envoy/config/filter/http/rate_limit/v2/BUILD   |   11 +
 .../filter/http/rate_limit/v2/rate_limit.proto     |   60 +
 .../proto/envoy/config/filter/http/rbac/v2/BUILD   |    9 +
 .../envoy/config/filter/http/rbac/v2/rbac.proto    |   38 +
 .../proto/envoy/config/filter/http/router/v2/BUILD |    9 +
 .../config/filter/http/router/v2/router.proto      |   39 +
 .../proto/envoy/config/filter/http/squash/v2/BUILD |    8 +
 .../config/filter/http/squash/v2/squash.proto      |   55 +
 .../envoy/config/filter/http/tap/v2alpha/BUILD     |   11 +
 .../envoy/config/filter/http/tap/v2alpha/tap.proto |   21 +
 .../envoy/config/filter/http/transcoder/v2/BUILD   |    8 +
 .../filter/http/transcoder/v2/transcoder.proto     |   95 ++
 .../filter/listener/original_src/v2alpha1/BUILD    |    8 +
 .../original_src/v2alpha1/original_src.proto       |   30 +
 .../config/filter/network/client_ssl_auth/v2/BUILD |    9 +
 .../client_ssl_auth/v2/client_ssl_auth.proto       |   41 +
 .../filter/network/dubbo_proxy/v2alpha1/BUILD      |   17 +
 .../filter/network/dubbo_proxy/v2alpha1/README.md  |    1 +
 .../network/dubbo_proxy/v2alpha1/dubbo_proxy.proto |   57 +
 .../network/dubbo_proxy/v2alpha1/route.proto       |  108 ++
 .../envoy/config/filter/network/ext_authz/v2/BUILD |    9 +
 .../filter/network/ext_authz/v2/ext_authz.proto    |   35 +
 .../network/http_connection_manager/v2/BUILD       |   29 +
 .../v2/http_connection_manager.proto               |  432 +++++++
 .../config/filter/network/mongo_proxy/v2/BUILD     |    9 +
 .../network/mongo_proxy/v2/mongo_proxy.proto       |   36 +
 .../filter/network/mysql_proxy/v1alpha1/BUILD      |    8 +
 .../network/mysql_proxy/v1alpha1/mysql_proxy.proto |   22 +
 .../config/filter/network/rate_limit/v2/BUILD      |   12 +
 .../filter/network/rate_limit/v2/rate_limit.proto  |   47 +
 .../envoy/config/filter/network/rbac/v2/BUILD      |    9 +
 .../envoy/config/filter/network/rbac/v2/rbac.proto |   52 +
 .../config/filter/network/redis_proxy/v2/BUILD     |    8 +
 .../network/redis_proxy/v2/redis_proxy.proto       |   57 +
 .../envoy/config/filter/network/tcp_proxy/v2/BUILD |   13 +
 .../filter/network/tcp_proxy/v2/tcp_proxy.proto    |  198 ++++
 .../filter/network/thrift_proxy/v2alpha1/BUILD     |   15 +
 .../filter/network/thrift_proxy/v2alpha1/README.md |    1 +
 .../network/thrift_proxy/v2alpha1/route.proto      |  130 ++
 .../thrift_proxy/v2alpha1/thrift_proxy.proto       |  122 ++
 .../config/filter/thrift/rate_limit/v2alpha1/BUILD |   12 +
 .../thrift/rate_limit/v2alpha1/rate_limit.proto    |   51 +
 .../config/filter/thrift/router/v2alpha1/BUILD     |    8 +
 .../filter/thrift/router/v2alpha1/router.proto     |   14 +
 .../envoy/config/grpc_credential/v2alpha/BUILD     |   17 +
 .../v2alpha/file_based_metadata.proto              |   28 +
 .../envoy/config/health_checker/redis/v2/BUILD     |    8 +
 .../config/health_checker/redis/v2/redis.proto     |   19 +
 .../src/main/proto/envoy/config/metrics/v2/BUILD   |   43 +
 .../envoy/config/metrics/v2/metrics_service.proto  |   21 +
 .../main/proto/envoy/config/metrics/v2/stats.proto |  332 ++++++
 .../main/proto/envoy/config/overload/v2alpha/BUILD |   14 +
 .../envoy/config/overload/v2alpha/overload.proto   |   78 ++
 .../src/main/proto/envoy/config/ratelimit/v2/BUILD |   20 +
 .../main/proto/envoy/config/ratelimit/v2/rls.proto |   26 +
 .../src/main/proto/envoy/config/rbac/v2alpha/BUILD |   26 +
 .../proto/envoy/config/rbac/v2alpha/rbac.proto     |  208 ++++
 .../resource_monitor/fixed_heap/v2alpha/BUILD      |    9 +
 .../fixed_heap/v2alpha/fixed_heap.proto            |   17 +
 .../injected_resource/v2alpha/BUILD                |    9 +
 .../v2alpha/injected_resource.proto                |   20 +
 .../envoy/config/retry/previous_priorities/BUILD   |   11 +
 .../previous_priorities_config.proto               |   44 +
 .../src/main/proto/envoy/config/trace/v2/BUILD     |   22 +
 .../main/proto/envoy/config/trace/v2/trace.proto   |  110 ++
 .../config/transport_socket/alts/v2alpha/BUILD     |   11 +
 .../transport_socket/alts/v2alpha/alts.proto       |   24 +
 .../config/transport_socket/tap/v2alpha/BUILD      |   12 +
 .../config/transport_socket/tap/v2alpha/tap.proto  |   26 +
 .../src/main/proto/envoy/data/accesslog/v2/BUILD   |   24 +
 .../proto/envoy/data/accesslog/v2/accesslog.proto  |  335 ++++++
 .../main/proto/envoy/data/cluster/v2alpha/BUILD    |   11 +
 .../cluster/v2alpha/outlier_detection_event.proto  |   77 ++
 .../src/main/proto/envoy/data/core/v2alpha/BUILD   |   15 +
 .../data/core/v2alpha/health_check_event.proto     |   85 ++
 .../src/main/proto/envoy/data/tap/v2alpha/BUILD    |   35 +
 .../main/proto/envoy/data/tap/v2alpha/common.proto |   31 +
 .../main/proto/envoy/data/tap/v2alpha/http.proto   |   60 +
 .../proto/envoy/data/tap/v2alpha/transport.proto   |   97 ++
 .../proto/envoy/data/tap/v2alpha/wrapper.proto     |   34 +
 .../src/main/proto/envoy/service/README.md         |    3 +
 .../main/proto/envoy/service/accesslog/v2/BUILD    |   23 +
 .../proto/envoy/service/accesslog/v2/als.proto     |   73 ++
 .../src/main/proto/envoy/service/auth/v2/BUILD     |   27 +
 .../envoy/service/auth/v2/attribute_context.proto  |  143 +++
 .../envoy/service/auth/v2/external_auth.proto      |   77 ++
 .../main/proto/envoy/service/auth/v2alpha/BUILD    |   12 +
 .../envoy/service/auth/v2alpha/external_auth.proto |   25 +
 .../main/proto/envoy/service/discovery/v2/BUILD    |   58 +
 .../proto/envoy/service/discovery/v2/ads.proto     |   38 +
 .../proto/envoy/service/discovery/v2/hds.proto     |  127 ++
 .../proto/envoy/service/discovery/v2/sds.proto     |   29 +
 .../main/proto/envoy/service/load_stats/v2/BUILD   |   22 +
 .../proto/envoy/service/load_stats/v2/lrs.proto    |   82 ++
 .../src/main/proto/envoy/service/metrics/v2/BUILD  |   24 +
 .../envoy/service/metrics/v2/metrics_service.proto |   41 +
 .../main/proto/envoy/service/ratelimit/v2/BUILD    |   24 +
 .../proto/envoy/service/ratelimit/v2/rls.proto     |   95 ++
 .../src/main/proto/envoy/service/tap/v2alpha/BUILD |   12 +
 .../proto/envoy/service/tap/v2alpha/common.proto   |  174 +++
 .../src/main/proto/envoy/service/trace/v2/BUILD    |   23 +
 .../envoy/service/trace/v2/trace_service.proto     |   46 +
 .../src/main/proto/envoy/type/BUILD                |   36 +
 .../src/main/proto/envoy/type/http_status.proto    |   85 ++
 .../src/main/proto/envoy/type/matcher/BUILD        |   67 ++
 .../main/proto/envoy/type/matcher/metadata.proto   |   95 ++
 .../src/main/proto/envoy/type/matcher/number.proto |   28 +
 .../src/main/proto/envoy/type/matcher/string.proto |   58 +
 .../src/main/proto/envoy/type/matcher/value.proto  |   62 +
 .../src/main/proto/envoy/type/percent.proto        |   52 +
 .../src/main/proto/envoy/type/range.proto          |   34 +
 .../src/main/proto/gogoproto/gogo.proto            |  144 +++
 .../src/main/proto/google/api/annotations.proto    |   31 +
 .../src/main/proto/google/api/http.proto           |  313 +++++
 .../src/main/proto/google/rpc/status.proto         |   92 ++
 .../src/main/proto/metrics.proto                   |   81 ++
 .../src/main/proto/trace.proto                     |  379 ++++++
 .../src/main/proto/validate/validate.proto         |  763 ++++++++++++
 ...rg.apache.dubbo.remoting.pilot.PilotTransporter |    1 +
 dubbo-remoting/pom.xml                             |    1 +
 213 files changed, 16294 insertions(+)

diff --git a/dubbo-all/pom.xml b/dubbo-all/pom.xml
index 6904795..c477006 100644
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@ -130,6 +130,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-pilot</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-rpc-api</artifactId>
             <version>${project.version}</version>
             <scope>compile</scope>
@@ -301,6 +308,13 @@
         </dependency>
         <dependency>
             <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-pilot</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
             <artifactId>dubbo-registry-sofa</artifactId>
             <version>${project.version}</version>
             <scope>compile</scope>
@@ -622,6 +636,7 @@
                                     <include>org.apache.dubbo:dubbo-remoting-p2p</include>
                                     <include>org.apache.dubbo:dubbo-remoting-http</include>
                                     <include>org.apache.dubbo:dubbo-remoting-zookeeper</include>
+                                    <include>org.apache.dubbo:dubbo-remoting-pilot</include>
                                     <include>org.apache.dubbo:dubbo-rpc-api</include>
                                     <include>org.apache.dubbo:dubbo-rpc-dubbo</include>
                                     <include>org.apache.dubbo:dubbo-rpc-injvm</include>
@@ -648,6 +663,7 @@
                                     <include>org.apache.dubbo:dubbo-registry-etcd3</include>
                                     <include>org.apache.dubbo:dubbo-registry-eureka</include>
                                     <include>org.apache.dubbo:dubbo-registry-nacos</include>
+                                    <include>org.apache.dubbo:dubbo-registry-pilot</include>
                                     <include>org.apache.dubbo:dubbo-registry-sofa</include>
                                     <include>org.apache.dubbo:dubbo-registry-multiple</include>
                                     <include>org.apache.dubbo:dubbo-monitor-api</include>
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistry.java
index a005f63..7a038e7 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/support/AbstractRegistry.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
@@ -356,6 +357,23 @@ public abstract class AbstractRegistry implements Registry {
         }
     }
 
+    protected void recoverSubscribed() throws Exception {
+        // subscribe
+        Map<URL, Set<NotifyListener>> recoverSubscribed = new HashMap<URL, Set<NotifyListener>>(getSubscribed());
+        if (! recoverSubscribed.isEmpty()) {
+            if (logger.isInfoEnabled()) {
+                logger.info("Recover subscribe url " + recoverSubscribed.keySet());
+            }
+            for (Map.Entry<URL, Set<NotifyListener>> entry : recoverSubscribed.entrySet()) {
+                URL url = entry.getKey();
+                for (NotifyListener listener : entry.getValue()) {
+                    url.addParameter(CommonConstants.CHECK_KEY, false);
+                    subscribe(url, listener);
+                }
+            }
+        }
+    }
+
     protected void notify(List<URL> urls) {
         if (CollectionUtils.isEmpty(urls)) {
             return;
diff --git a/dubbo-registry/dubbo-registry-pilot/pom.xml b/dubbo-registry/dubbo-registry-pilot/pom.xml
new file mode 100644
index 0000000..4a22c80
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-pilot/pom.xml
@@ -0,0 +1,33 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-registry</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dubbo-registry-pilot</artifactId>
+    <name>${project.artifactId}</name>
+    <description>The Pliot registry module of Dubbo project</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-registry-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-pilot</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+    </dependencies>
+
+
+</project>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistry.java b/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistry.java
new file mode 100644
index 0000000..579e512
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistry.java
@@ -0,0 +1,132 @@
+package org.apache.dubbo.registry.pilot;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.constants.RegistryConstants;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.registry.Constants;
+import org.apache.dubbo.registry.NotifyListener;
+import org.apache.dubbo.registry.support.FailbackRegistry;
+import org.apache.dubbo.remoting.pilot.ChildListener;
+import org.apache.dubbo.remoting.pilot.PilotClient;
+import org.apache.dubbo.remoting.pilot.PilotTransporter;
+import org.apache.dubbo.remoting.pilot.StateListener;
+import org.apache.dubbo.rpc.RpcException;
+
+import java.util.*;
+import java.util.concurrent.*;
+
+/**
+ * Support for pilot registry
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class PilotRegistry extends FailbackRegistry {
+
+    private final PilotClient pilotClient;
+    private final long notifyWaitTime;
+    private final int reconnectDelayTime;
+    private Map<NotifyListener, ChildListener> pilotListeners = new ConcurrentHashMap<>();
+    private ScheduledExecutorService reconnectSchedule;
+
+    public PilotRegistry(URL url, PilotTransporter pilotTransporter) {
+        super(url);
+        if (url.isAnyHost()) {
+            throw new IllegalStateException("Pilot registry address is invalid, url: " + url);
+        }
+
+        pilotClient = pilotTransporter.connect(url);
+        reconnectDelayTime = url.getParameter(Constants.REGISTRY_RETRY_PERIOD_KEY, Constants.DEFAULT_REGISTRY_RETRY_PERIOD);
+        pilotClient.addStateListener(state -> {
+            if (state == StateListener.CONNECTED) {
+                reconnectSchedule.schedule(() -> {
+                    try {
+                        if (pilotClient.isConnected()) {
+                            pilotClient.closeOldStream();
+                            pilotListeners.clear();
+                            recoverSubscribed();
+                        }
+                    } catch (Exception e) {
+                        logger.error(e.getMessage(), e);
+                    }
+                }, new Random().nextInt(reconnectDelayTime), TimeUnit.MILLISECONDS);
+            }
+        });
+        reconnectSchedule = Executors.newScheduledThreadPool(1,
+                new NamedThreadFactory("pilot-reconnect-executor"));
+        notifyWaitTime = url.getParameter(CommonConstants.TIMEOUT_KEY, DEFUALT_PILOT_SUBSCRIBE_WAIT_TIME);
+    }
+
+    @Override
+    public void doRegister(URL url) {
+        throw new UnsupportedOperationException("Pilot registry don't support register operation");
+    }
+
+    @Override
+    public void doUnregister(URL url) {
+        throw new UnsupportedOperationException("Pilot registry don't support unRegister operation");
+    }
+
+    @Override
+    public void doSubscribe(URL url, NotifyListener listener) {
+        try {
+            String service = url.getServiceInterface();
+            CountDownLatch notified = new CountDownLatch(1);
+            ChildListener childListener =
+                    Optional.ofNullable(pilotListeners.get(listener))
+                            .orElseGet(() -> {
+                                ChildListener watchListener, prev;
+                                prev = pilotListeners.putIfAbsent(listener, watchListener =
+                                        (path, urls) -> {
+                                            PilotRegistry.this.notify(url, listener,
+                                                    PilotRegistry.this.toUrlsWithEmpty(url, path, urls));
+                                            notified.countDown();
+                                        });
+                                return prev != null ? prev : watchListener;
+                            });
+            if (!pilotClient.isConnected()) {
+                throw new RpcException("Pilot is not connected");
+            }
+            this.pilotClient.addChildListener(service, childListener);
+            pilotClient.discoveryService(url);
+            //wait for first watch result
+            if (!notified.await(notifyWaitTime, TimeUnit.MILLISECONDS)) {
+                pilotListeners.remove(listener);
+                this.pilotClient.removeChildListener(service, childListener);
+                throw new RpcException("Receive none discovery response from pilot in " + notifyWaitTime + " ms");
+            }
+        } catch (Throwable e) {
+            throw new RpcException("Failed to subscribe " + url + " from pilot registry: " + getUrl() + " ,cause: " + e.getMessage(), e);
+        }
+    }
+
+    private List<URL> toUrlsWithEmpty(URL url, String path, List<URL> urls) {
+        if (urls == null || urls.isEmpty()) {
+            URL empty = url.setProtocol(RegistryConstants.EMPTY_PROTOCOL).addParameter(RegistryConstants.CATEGORY_KEY, RegistryConstants.PROVIDERS_CATEGORY);
+            Objects.requireNonNull(urls).add(empty);
+        }
+        return urls;
+    }
+
+    @Override
+    public void doUnsubscribe(URL url, NotifyListener listener) {
+        //doNothing
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return pilotClient.isConnected();
+    }
+
+    @Override
+    public void destroy() {
+        super.destroy();
+        try {
+            pilotClient.close();
+        } catch (Throwable t) {
+            logger.warn(t.getMessage(), t);
+        }
+    }
+
+    public static final int DEFUALT_PILOT_SUBSCRIBE_WAIT_TIME = 10 * 1000;
+}
diff --git a/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistryFactory.java b/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistryFactory.java
new file mode 100644
index 0000000..d55780e
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-pilot/src/main/java/org.apache.dubbo.registry.pilot/PilotRegistryFactory.java
@@ -0,0 +1,25 @@
+package org.apache.dubbo.registry.pilot;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.Registry;
+import org.apache.dubbo.registry.support.AbstractRegistryFactory;
+import org.apache.dubbo.remoting.pilot.PilotTransporter;
+
+/**
+ * pilot registryfactory
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class PilotRegistryFactory extends AbstractRegistryFactory {
+
+    private PilotTransporter pilotTransporter;
+
+    @Override
+    protected Registry createRegistry(URL url) {
+        return new PilotRegistry(url, pilotTransporter);
+    }
+
+    public void setPilotTransporter(PilotTransporter pilotTransporter) {
+        this.pilotTransporter = pilotTransporter;
+    }
+}
diff --git a/dubbo-registry/dubbo-registry-pilot/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-registry/dubbo-registry-pilot/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
new file mode 100644
index 0000000..bb6d135
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-pilot/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
@@ -0,0 +1 @@
+pilot=org.apache.dubbo.registry.pilot.PilotRegistryFactory
\ No newline at end of file
diff --git a/dubbo-registry/pom.xml b/dubbo-registry/pom.xml
index d141b29..c6672a9 100644
--- a/dubbo-registry/pom.xml
+++ b/dubbo-registry/pom.xml
@@ -41,5 +41,6 @@
         <module>dubbo-registry-multiple</module>
         <module>dubbo-registry-sofa</module>
         <module>dubbo-registry-eureka</module>
+        <module>dubbo-registry-pilot</module>
     </modules>
 </project>
diff --git a/dubbo-remoting/dubbo-remoting-pilot/pom.xml b/dubbo-remoting/dubbo-remoting-pilot/pom.xml
new file mode 100644
index 0000000..8227610
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/pom.xml
@@ -0,0 +1,73 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.dubbo</groupId>
+        <artifactId>dubbo-remoting</artifactId>
+        <version>${revision}</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+    <artifactId>dubbo-remoting-pilot</artifactId>
+    <packaging>jar</packaging>
+    <name>${project.artifactId}</name>
+    <description>The pilot remoting module of dubbo project</description>
+    <properties>
+        <skip_maven_deploy>false</skip_maven_deploy>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-remoting-api</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-common</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-protobuf</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>io.grpc</groupId>
+            <artifactId>grpc-stub</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.annotation</groupId>
+            <artifactId>javax.annotation-api</artifactId>
+            <version>1.3.2</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <extensions>
+            <extension>
+                <groupId>kr.motd.maven</groupId>
+                <artifactId>os-maven-plugin</artifactId>
+                <version>1.5.0.Final</version>
+            </extension>
+        </extensions>
+        <plugins>
+            <plugin>
+                <groupId>org.xolstice.maven.plugins</groupId>
+                <artifactId>protobuf-maven-plugin</artifactId>
+                <version>0.5.1</version>
+                <configuration>
+                    <protocArtifact>com.google.protobuf:protoc:3.6.1:exe:${os.detected.classifier}</protocArtifact>
+                    <pluginId>grpc-java</pluginId>
+                    <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.19.0:exe:${os.detected.classifier}</pluginArtifact>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>compile</goal>
+                            <goal>compile-custom</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
\ No newline at end of file
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/AbstractPilotClient.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/AbstractPilotClient.java
new file mode 100644
index 0000000..54db25b
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/AbstractPilotClient.java
@@ -0,0 +1,115 @@
+package org.apache.dubbo.remoting.pilot;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * abstract grpc support for pilot client
+ * @author hzj
+ * @date 2019/03/20
+ */
+public abstract class AbstractPilotClient implements PilotClient {
+
+    protected static final Logger logger = LoggerFactory.getLogger(AbstractPilotClient.class);
+    protected final URL url;
+    private final List<StateListener> stateListeners = new ArrayList<>();
+    private final Map<String, Set<ChildListener>> childListeners = new ConcurrentHashMap<>();
+    private volatile boolean closed = false;
+
+    public AbstractPilotClient(URL url) {
+        this.url = url;
+    }
+
+    @Override
+    public void discoveryService(URL url) { doDiscoveryService(url);}
+
+    @Override
+    public void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+        stateListeners.clear();
+        try {
+            doClose();
+        } catch (Throwable t) {
+            logger.warn(t.getMessage(), t);
+        }
+    }
+
+    @Override
+    public void closeOldStream() {
+        try {
+            childListeners.clear();
+            doCloseOldStream();
+        } catch (Throwable t) {
+            logger.warn(t.getMessage(), t);
+        }
+    }
+
+    protected void stateChanged(int state) {
+        for (StateListener sessionListener : getStateListeners()) {
+            sessionListener.stateChanged(state);
+        }
+    }
+
+    @Override
+    public void addStateListener(StateListener listener) {
+        stateListeners.add(listener);
+    }
+
+    @Override
+    public void removeStateListener(StateListener listener) {
+        stateListeners.remove(listener);
+    }
+
+    @Override
+    public List<StateListener> getStateListeners() {
+        return stateListeners;
+    }
+
+    @Override
+    public Set<ChildListener> addChildListener(String path, ChildListener listener) {
+        Set<ChildListener> listeners = childListeners.get(path);
+        if (listeners == null) {
+            childListeners.putIfAbsent(path, new HashSet<>());
+            listeners = childListeners.get(path);
+        }
+        listeners.add(listener);
+        return listeners;
+    }
+
+    @Override
+    public void removeChildListener(String path, ChildListener listener) {
+        Set<ChildListener> listeners = childListeners.get(path);
+        if (listeners != null) {
+            listeners.remove(listener);
+        }
+    }
+
+    @Override
+    public Set<ChildListener> getChildListeners(String path) {
+        Set<ChildListener> listeners = childListeners.get(path);
+        if (listeners == null) {
+            childListeners.putIfAbsent(path, new HashSet<>());
+            listeners = childListeners.get(path);
+        }
+        return listeners;
+    }
+
+    public void responseReceived(String path, List<URL> urls) {
+        for (ChildListener childListener : getChildListeners(path)) {
+            childListener.chiledChanged(path, urls);
+        }
+    }
+
+    abstract public void doDiscoveryService(URL url);
+
+    abstract public void doClose();
+
+    abstract public void doCloseOldStream();
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/ChildListener.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/ChildListener.java
new file mode 100644
index 0000000..5c6639f
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/ChildListener.java
@@ -0,0 +1,15 @@
+package org.apache.dubbo.remoting.pilot;
+
+import org.apache.dubbo.common.URL;
+
+import java.util.List;
+
+/**
+ * ChildListener
+ * @author hzj
+ * @date 2019/03/20
+ */
+public interface ChildListener {
+
+    void chiledChanged(String path, List<URL> urls);
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/Constants.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/Constants.java
new file mode 100644
index 0000000..16d9573
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/Constants.java
@@ -0,0 +1,16 @@
+package org.apache.dubbo.remoting.pilot;
+
+/**
+ * @author hzj
+ * @create 2020/1/11
+ */
+public interface Constants {
+
+    public static final String  SESSION_TIMEOUT_KEY                = "session";
+
+    public static final int     DEFAULT_SESSION_TIMEOUT            = 30 * 1000;
+
+    public static final String  REGISTRY_RECONNECT_PERIOD_KEY      = "reconnect.period";
+
+    public static final int     DEFAULT_REGISTRY_RECONNECT_PERIOD  = 3 * 1000;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotClient.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotClient.java
new file mode 100644
index 0000000..04739ef
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotClient.java
@@ -0,0 +1,64 @@
+package org.apache.dubbo.remoting.pilot;
+
+import org.apache.dubbo.common.URL;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * interface for pilot client
+ * @author hzj
+ * @date 2019/03/20
+ */
+public interface PilotClient {
+
+    /**
+     * send service subscribe request
+     */
+    void discoveryService(URL url);
+
+    /**
+     * check the connection status
+     */
+    boolean isConnected();
+
+    /**
+     * close channel
+     */
+    void close();
+
+    /**
+     * close all watch stream
+     */
+    void closeOldStream();
+
+    /**
+     * add connect state listener
+     */
+    void addStateListener(StateListener listener);
+
+    /**
+     * remove connect state listener
+     */
+    void removeStateListener(StateListener listener);
+
+    /**
+     * get connect state listeners
+     */
+    List<StateListener> getStateListeners();
+
+    /**
+     * add watch result listener
+     */
+    Set<ChildListener> addChildListener(String path, ChildListener listener);
+
+    /**
+     * remove watch result listener
+     */
+    void removeChildListener(String path, ChildListener listener);
+
+    /**
+     * get watch result listeners
+     */
+    Set<ChildListener> getChildListeners(String path);
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotTransporter.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotTransporter.java
new file mode 100644
index 0000000..f6bc6eb
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/PilotTransporter.java
@@ -0,0 +1,18 @@
+package org.apache.dubbo.remoting.pilot;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.Adaptive;
+import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.remoting.Constants;
+
+/**
+ * provider client to pilot registry
+ * @author hzj
+ * @date 2019/03/20
+ */
+@SPI("grpc")
+public interface PilotTransporter {
+
+    @Adaptive({Constants.CLIENT_KEY, Constants.TRANSPORTER_KEY})
+    PilotClient connect(URL url);
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/StateListener.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/StateListener.java
new file mode 100644
index 0000000..4e1700c
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/StateListener.java
@@ -0,0 +1,15 @@
+package org.apache.dubbo.remoting.pilot;
+
+/**
+ * StateListener
+ * @author hzj
+ * @date 2019/03/20
+ */
+public interface StateListener {
+
+    int DISCONNECTED = 0;
+
+    int CONNECTED = 1;
+
+    void stateChanged(int connected);
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcClient.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcClient.java
new file mode 100644
index 0000000..5db8ce2
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcClient.java
@@ -0,0 +1,113 @@
+package org.apache.dubbo.remoting.pilot.grpc;
+
+import io.envoyproxy.envoy.api.v2.DiscoveryResponse;
+import io.grpc.Channel;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.pilot.AbstractPilotClient;
+import org.apache.dubbo.remoting.pilot.Constants;
+import org.apache.dubbo.remoting.pilot.StateListener;
+import org.apache.dubbo.remoting.pilot.option.DiscoveryUtil;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * grpc support for pilot client
+ *
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class GrpcClient extends AbstractPilotClient {
+
+    private final GrpcConnection connectionManager;
+    private final GrpcDiscoveryManager discoveryManager;
+    private final RuntimeException failed;
+
+    public GrpcClient(URL url) {
+        super(url);
+        connectionManager = new GrpcConnection(url);
+        connectionManager.setConnectionStateListener((channel, state) -> {
+            if (state == StateListener.CONNECTED) {
+                this.stateChanged(StateListener.CONNECTED);
+            } else if (state == StateListener.DISCONNECTED) {
+                this.stateChanged(StateListener.DISCONNECTED);
+            }
+        });
+        connectionManager.start();
+        this.failed = new IllegalStateException("Pilot is not connected, url:" + this.url);
+
+        requiredNotNull(connectionManager.getChannel(), failed);
+        //build watch stream before subscribe
+        discoveryManager = new GrpcDiscoveryManager(this.url, connectionManager.getChannel(),
+                new GrpcDiscoveryManager.ResponseListener() {
+                    @Override
+                    public void receiveResponse(Channel channel, DiscoveryResponse response) {
+                        Map<String, List<URL>> responses = new ConcurrentHashMap<>();
+                        try {
+                            responses = DiscoveryUtil.discoveryResponseToUrls(response);
+                        } catch (Exception e) {
+                            logger.error("Failed to resolve response: " + response + " ,caused: " + e.getMessage(), e);
+                            return;
+                        }
+                        responses.forEach((path, urls) -> responseReceived(path, urls));
+                    }
+
+                    @Override
+                    public void receiveError(Channel channel, Throwable throwable) {
+                        try {
+                            Thread.sleep(Constants.DEFAULT_REGISTRY_RECONNECT_PERIOD * 5);
+                        } catch (InterruptedException e) {
+                            //ignore
+                        }
+                        if (!connectionManager.isConnected()) {
+                            logger.info("Disconnected from pilot server after receive Error: " + throwable
+                                    + " wait pilot connected to recover grpc stream");
+                            return;
+                        }
+                        logger.info("Recover grpc stream after receive Error: " + throwable);
+                        stateChanged(StateListener.CONNECTED);
+                    }
+                });
+        discoveryManager.buildDiscoveryStream();
+        CompletableFuture.runAsync(DiscoveryUtil::init);
+    }
+
+    @Override
+    public void doDiscoveryService(URL url) {
+        requiredNotNull(connectionManager.getChannel(), failed);
+        //stream was closed
+        if (!discoveryManager.isStarted()) {
+            discoveryManager.buildDiscoveryStream();
+        }
+        discoveryManager.sendDiscoveryRequest(DiscoveryUtil.urlToDiscoveryRequest(url));
+    }
+
+    @Override
+    public void doClose() {
+        if (discoveryManager != null) {
+            discoveryManager.closeDiscoveryStream();
+        }
+        connectionManager.close();
+    }
+
+    @Override
+    public void doCloseOldStream() {
+        if (discoveryManager != null) {
+            discoveryManager.closeOldDiscoveryStream();
+        }
+    }
+
+    @Override
+    public boolean isConnected() {
+        return connectionManager.isConnected();
+    }
+
+
+    private static void requiredNotNull(Object obj, RuntimeException exception) {
+        if (obj == null) {
+            throw exception;
+        }
+    }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcConnection.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcConnection.java
new file mode 100644
index 0000000..df84e02
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcConnection.java
@@ -0,0 +1,170 @@
+package org.apache.dubbo.remoting.pilot.grpc;
+
+import io.grpc.Channel;
+import io.grpc.ConnectivityState;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.remoting.pilot.Constants;
+import org.apache.dubbo.remoting.pilot.StateListener;
+
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * grpc connection manager
+ *
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class GrpcConnection {
+
+    private Logger logger = LoggerFactory.getLogger(GrpcConnection.class);
+
+    private final URL url;
+    private volatile boolean started = false;
+    private volatile boolean closed = false;
+    private volatile boolean connectState = false;
+    private final AtomicReference<ManagedChannel> channel = new AtomicReference<>();
+    private ScheduledFuture reconnectFuture;
+    private final ScheduledExecutorService reconnectNotify;
+    private long expirePeriod;
+    private CompletableFuture<ManagedChannel> completableFuture;
+    private ConnectionStateListener connectionStateListener;
+
+
+    public GrpcConnection(URL url) {
+        this.url = url;
+        this.expirePeriod = url.getParameter(Constants.SESSION_TIMEOUT_KEY, Constants.DEFAULT_SESSION_TIMEOUT);
+        if (expirePeriod <= 0) {
+            this.expirePeriod = Constants.DEFAULT_SESSION_TIMEOUT;
+        }
+        this.completableFuture = CompletableFuture.supplyAsync(() -> prepareClient(url));
+        this.reconnectNotify = Executors.newScheduledThreadPool(1,
+                new NamedThreadFactory("pilot-reconnect-notify", true));
+    }
+
+    private ManagedChannel prepareClient(URL url) {
+        int maxInboundMessageSize = DEFAULT_INBOUND_SIZE;
+        if (StringUtils.isNotEmpty(System.getProperty(GRPC_MAX_INBOUD_SIZE_KEY))) {
+            maxInboundMessageSize = Integer.valueOf(System.getProperty(GRPC_MAX_INBOUD_SIZE_KEY));
+        }
+
+        long keepAliveTime = DEFAULT_KEEPALIVE_TIME;
+        if (StringUtils.isNotEmpty(System.getProperty(GRPC_KEEPALIVE_TIME_KEY))) {
+            keepAliveTime = Integer.valueOf(System.getProperty(GRPC_KEEPALIVE_TIME_KEY));
+        }
+        ManagedChannel managedChannel = ManagedChannelBuilder
+                .forTarget(url.getBackupAddress())
+                .maxInboundMessageSize(maxInboundMessageSize)
+                .enableFullStreamDecompression()
+                .usePlaintext(true)
+                .keepAliveTime(keepAliveTime, TimeUnit.MILLISECONDS)
+                .keepAliveTimeout(DEFAULT_KEEPALIVE_TIMEOUT, TimeUnit.MILLISECONDS)
+                .keepAliveWithoutCalls(true)
+                .build();
+        return managedChannel;
+    }
+
+    public void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+
+        try {
+            if (started && reconnectFuture != null) {
+                started = false;
+                reconnectFuture.cancel(true);
+                reconnectNotify.shutdownNow();
+            }
+        } catch (Exception e) {
+            logger.warn("Failed to close grpc-reconnect-notify, url: " + url, e);
+        }
+
+        if (getChannel() != null) {
+            getChannel().shutdown();
+        }
+    }
+
+    public void start() {
+        if (!started) {
+            try {
+                ManagedChannel channel = completableFuture.get(expirePeriod, TimeUnit.MILLISECONDS);
+                this.setChannel(channel);
+                this.connectState = isConnected();
+                this.started = true;
+            } catch (Throwable t) {
+                logger.error("Failed to start pilot client in :[" + expirePeriod + "] milliseconds!, url: " + url, t);
+                completableFuture.whenComplete((c, e) -> {
+                    setChannel(c);
+                    if (e != null) {
+                        logger.error("Got an exception when trying to start pilot client, can not connect to pilot server, url: " + url, e);
+                    }
+                });
+            }
+        }
+        try {
+            this.reconnectFuture = reconnectNotify.scheduleWithFixedDelay(() -> {
+                boolean connected = isConnected();
+                if (connectState != connected) {
+                    int notifyState = connected ? StateListener.CONNECTED : StateListener.DISCONNECTED;
+                    if (connectionStateListener != null) {
+                        logger.warn("Grpc connective state changed from [" + !connected + "] to [" + connected + "]");
+                        connectionStateListener.stateChanged(getChannel(), notifyState);
+                    }
+                    connectState = connected;
+                }
+            }, 5 * Constants.DEFAULT_REGISTRY_RECONNECT_PERIOD, Constants.DEFAULT_REGISTRY_RECONNECT_PERIOD, TimeUnit.MILLISECONDS);
+        } catch (Throwable t) {
+            logger.error("Grpc monitor connect status failed", t);
+        }
+    }
+
+    public boolean isConnected() {
+        if (getChannel() == null) {
+            return false;
+        }
+        return ConnectivityState.READY == (getChannel().getState(true))
+                || ConnectivityState.IDLE == (getChannel().getState(true));
+    }
+
+    public ManagedChannel getChannel() {
+        if (channel.get() == null || (channel.get().isShutdown() || channel.get().isTerminated())) {
+            return null;
+        }
+        return this.channel.get();
+    }
+
+    public void setChannel(ManagedChannel channel) {
+        this.channel.set(channel);
+    }
+
+    public interface ConnectionStateListener {
+        /**
+         * Called when there is a state change in the connection
+         *
+         * @param channel  the channel
+         * @param newState the new state
+         */
+        void stateChanged(Channel channel, int newState);
+    }
+
+    public ConnectionStateListener getConnectionStateListener() {
+        return connectionStateListener;
+    }
+
+    public void setConnectionStateListener(ConnectionStateListener connectionStateListener) {
+        this.connectionStateListener = connectionStateListener;
+    }
+
+    public static final String GRPC_MAX_INBOUD_SIZE_KEY = "grpc.max.inbound.size";
+    public static final String GRPC_KEEPALIVE_TIME_KEY = "grpc.keepalive.time";
+    public static final int DEFAULT_INBOUND_SIZE = 100 * 1024 * 1024;
+    public static final int DEFAULT_KEEPALIVE_TIME = 60 * 1000;
+    public static final int DEFAULT_KEEPALIVE_TIMEOUT = 5 * 1000;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcDiscoveryManager.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcDiscoveryManager.java
new file mode 100644
index 0000000..39140bc
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcDiscoveryManager.java
@@ -0,0 +1,130 @@
+package org.apache.dubbo.remoting.pilot.grpc;
+
+import io.envoyproxy.envoy.api.v2.DiscoveryRequest;
+import io.envoyproxy.envoy.api.v2.DiscoveryResponse;
+import io.envoyproxy.envoy.service.discovery.v2.AggregatedDiscoveryServiceGrpc;
+import io.grpc.Channel;
+import io.grpc.ManagedChannel;
+import io.grpc.stub.ClientCallStreamObserver;
+import io.grpc.stub.ClientResponseObserver;
+import io.grpc.stub.StreamObserver;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * @author hzj
+ * @create 2019/6/26
+ */
+public class GrpcDiscoveryManager {
+    private Logger logger = LoggerFactory.getLogger(GrpcDiscoveryManager.class);
+    private volatile StreamObserver<DiscoveryRequest> discoveryStream;
+    private volatile ResponseListener responseListener;
+    private URL url;
+    private final ManagedChannel channel;
+    private volatile boolean started = false;
+
+    public GrpcDiscoveryManager(URL url, ManagedChannel channel, ResponseListener responseListener) {
+        this.url = url;
+        this.channel = channel;
+        this.responseListener = responseListener;
+    }
+
+
+    public synchronized void buildDiscoveryStream() {
+        if (started) {
+            return;
+        }
+        AggregatedDiscoveryServiceGrpc.AggregatedDiscoveryServiceStub stub
+                = AggregatedDiscoveryServiceGrpc.newStub(channel);
+        ClientResponseObserver<DiscoveryRequest, DiscoveryResponse> clientResponseObserver =
+                new ClientResponseObserver<DiscoveryRequest, DiscoveryResponse>() {
+
+                    @Override
+                    public void onNext(DiscoveryResponse response) {
+                        getResponseListener().receiveResponse(channel, response);
+                    }
+
+                    @Override
+                    public void onError(Throwable t) {
+                        if (t.getCause() instanceof CloseStreamException) {
+                            logger.warn("Close old pilot discovery stream, url: " + url);
+                            return;
+                        }
+                        logger.error("Receive onError response from pilot server, url: " + url + t.getMessage(), t);
+                        CompletableFuture.runAsync(()
+                                -> getResponseListener().receiveError(channel, t));
+                    }
+
+                    @Override
+                    public void onCompleted() {
+                        logger.error("Receive onCompleted response from pilot server, url: " + url);
+                        CompletableFuture.runAsync(()
+                                -> getResponseListener().receiveError(channel, new RuntimeException("Receive onCompleted")));
+                    }
+
+                    @Override
+                    public void beforeStart(ClientCallStreamObserver<DiscoveryRequest> requestStream) {
+                        logger.info("Init grpc discovery stream to pilot server, url:" + url);
+                    }
+                };
+        discoveryStream = stub.streamAggregatedResources(clientResponseObserver);
+        started = true;
+    }
+
+    public boolean isStarted() {
+        return started;
+    }
+
+    public void sendDiscoveryRequest(DiscoveryRequest request) {
+        this.discoveryStream.onNext(request);
+    }
+
+    public void closeOldDiscoveryStream() {
+        if (discoveryStream != null) {
+            this.discoveryStream.onError(closeStreamException);
+            this.discoveryStream = null;
+            started = false;
+        }
+    }
+
+    public void closeDiscoveryStream() {
+        if (discoveryStream != null) {
+            this.discoveryStream.onCompleted();
+            this.discoveryStream = null;
+        }
+    }
+
+    public ResponseListener getResponseListener() {
+        return responseListener;
+    }
+
+    public interface ResponseListener {
+        /**
+         * Called when there is a message from pilot
+         *
+         * @param channel  the channel
+         * @param response the response
+         */
+        void receiveResponse(Channel channel, DiscoveryResponse response);
+
+        /**
+         * Called when there is an error response from pilot
+         *
+         * @param channel the channel
+         * @param throwable the error
+         */
+        void receiveError(Channel channel, Throwable throwable);
+    }
+
+    public static class CloseStreamException extends RuntimeException {
+
+        public CloseStreamException(String message) {
+            super(message);
+        }
+    }
+
+    private static CloseStreamException closeStreamException = new CloseStreamException("Client close grpc stream");
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcTransporter.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcTransporter.java
new file mode 100644
index 0000000..01004e7
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/grpc/GrpcTransporter.java
@@ -0,0 +1,17 @@
+package org.apache.dubbo.remoting.pilot.grpc;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.pilot.PilotClient;
+import org.apache.dubbo.remoting.pilot.PilotTransporter;
+
+/**
+ * grpc support for pilot transporter
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class GrpcTransporter implements PilotTransporter {
+    @Override
+    public PilotClient connect(URL url) {
+        return new GrpcClient(url);
+    }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/option/DiscoveryUtil.java b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/option/DiscoveryUtil.java
new file mode 100644
index 0000000..06f0ddc
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/java/org/apache/dubbo/remoting/pilot/option/DiscoveryUtil.java
@@ -0,0 +1,221 @@
+package org.apache.dubbo.remoting.pilot.option;
+
+import com.google.protobuf.Any;
+import com.google.protobuf.ByteString;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.Value;
+import io.envoyproxy.envoy.api.v2.ClusterLoadAssignment;
+import io.envoyproxy.envoy.api.v2.DiscoveryRequest;
+import io.envoyproxy.envoy.api.v2.DiscoveryResponse;
+import io.envoyproxy.envoy.api.v2.core.Metadata;
+import io.envoyproxy.envoy.api.v2.core.Node;
+import io.envoyproxy.envoy.api.v2.core.SocketAddress;
+import io.envoyproxy.envoy.api.v2.endpoint.Endpoint;
+import io.envoyproxy.envoy.api.v2.endpoint.LbEndpoint;
+import io.envoyproxy.envoy.api.v2.endpoint.LocalityLbEndpoints;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Discovery model transfer util
+ * @author hzj
+ * @date 2019/03/20
+ */
+public class DiscoveryUtil {
+
+    private final static String NODE_ID = "sidecar~127.0.0.1~dubbo.default~default.svc.cluster.local";
+    private final static String RESOURCE_NAME_PREFIX = "outbound|0||";
+    private final static String RESOURCE_NAME_SUFFIX = ".apache.dubbo.service.svc.cluster.local";
+    private final static String TYPE_URL = "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment";
+    private final static String ISTIO_KEY = "istio";
+    private final static String SERVICE_NAME = "service_name";
+    private final static String PROTOCOL_KEY = "protocol";
+    private final static String GROUP_KEY = "service_group";
+    private final static String VERSION_KEY = "service_version";
+
+    /**
+     * warm up ClusterLoadAssignment.class
+     */
+    public static void init() {
+        ClusterLoadAssignment.getDefaultInstance().getDescriptorForType();
+    }
+
+    /**
+     * Example Struct of DiscoveryRequest
+     * {
+     *     "versionInfo":"2019-03-06T15:44:58+08:00/1455",
+     *     "resources":[
+     *         {
+     *             "@type":"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
+     *             "clusterName":"outbound|0||apache-dubbo-ChargeService.apache.dubbo.service.svc.cluster.local",
+     *             "endpoints":[
+     *                 {
+     *                     "locality":{
+     *                         "zone":"prod"
+     *                     },
+     *                     "lbEndpoints":[
+     *                         {
+     *                             "endpoint":{
+     *                                 "address":{
+     *                                     "socketAddress":{
+     *                                         "address":"11.22.33.44",
+     *                                         "portValue":7100
+     *                                     }
+     *                                 }
+     *                             },
+     *                             "metadata":{
+     *                                 "filterMetadata":{
+     *                                     "istio":{
+     *                                         "service_name":"apache.dubbo.demo.Test1",
+     *                                         "app_name":"test",
+     *                                         "namespace":"etcd3",
+     *                                         "protocol":"dubbo",
+     *                                         "weight":100,
+     *                                         "health_status":"UP",
+     *                                         "service_version":"v1.0.0",
+     *                                         "service_group":"default"
+     *                                         .......
+     *                                     }
+     *                                 }
+     *                             }
+     *                         }
+     *                     ]
+     *                 }
+     *             ]
+     *         }
+     *     ],
+     *     "typeUrl":"type.googleapis.com/envoy.api.v2.ClusterLoadAssignment",
+     *     "nonce":"fbf48761-bfd4-4041-b492-2ff0e1e3fabc"
+     * }
+     * @param url
+     * @return
+     */
+    public static DiscoveryRequest urlToDiscoveryRequest(URL url) {
+        DiscoveryRequest.Builder builder = DiscoveryRequest.newBuilder();
+        Node node = urlToDiscoveryRequestNode(url);
+        String resourceName = urlToDiscoveryRequestResourceName(url);
+        String typeUrl = urlToDiscoveryRequestTypeUrl(url);
+        builder.setNode(node);
+        builder.addResourceNamesBytes(ByteString.copyFromUtf8(resourceName));
+        builder.setTypeUrl(typeUrl);
+        return builder.build();
+    }
+
+    /**
+     * transfer url to Node
+     * @param url
+     * @return
+     */
+    public static Node urlToDiscoveryRequestNode(URL url) {
+        Node.Builder builder = Node.newBuilder();
+        String realNodeId = NODE_ID.replace("127.0.0.1", url.getHost());
+        builder.setId(realNodeId);
+        return builder.build();
+    }
+
+    /**
+     * transfer url to ResourceName
+     * @param url
+     * @return
+     */
+    public static String urlToDiscoveryRequestResourceName(URL url) {
+        return RESOURCE_NAME_PREFIX + url.getServiceInterface().replace('.', '-') + RESOURCE_NAME_SUFFIX;
+    }
+
+
+    /**
+     * transfer url to TypeURL
+     * @param url
+     * @return
+     */
+    public static String urlToDiscoveryRequestTypeUrl(URL url) {
+        return TYPE_URL;
+    }
+
+    /**
+     * transfer DiscoveryResponse to urls
+     * @param response
+     * @return
+     * @throws InvalidProtocolBufferException
+     */
+    public static Map<String, List<URL>> discoveryResponseToUrls(DiscoveryResponse response) throws InvalidProtocolBufferException {
+        Map<String, List<URL>> responses = new HashMap<>();
+        List<com.google.protobuf.Any> resources = response.getResourcesList();
+        for (Any any : resources) {
+            ClusterLoadAssignment clusterLoadAssignment = any.unpack(ClusterLoadAssignment.class);
+            String service = parseServiceFromClusterName(clusterLoadAssignment.getClusterName());
+            List<URL> urls = discoveryClusterLoadAssignmentToUrl(clusterLoadAssignment);
+            responses.put(service, urls);
+        }
+        return responses;
+    }
+
+    private static String parseServiceFromClusterName(String clusterName){
+        return clusterName
+                .replace(RESOURCE_NAME_PREFIX, "")
+                .replace(RESOURCE_NAME_SUFFIX, "")
+                .replace('-', '.')
+                .trim();
+    }
+
+    /**
+     * transfer clusterLoadAssignment to urls
+     * @param clusterLoadAssignment
+     * @return
+     */
+    private static List<URL> discoveryClusterLoadAssignmentToUrl(ClusterLoadAssignment clusterLoadAssignment) {
+        List<URL> urls = new ArrayList<>();
+        List<LocalityLbEndpoints> localityLbEndpoints = clusterLoadAssignment.getEndpointsList();
+        localityLbEndpoints.forEach(localityLbEndpoint -> {
+            String dc = localityLbEndpoint.getLocality().getZone();
+            List<LbEndpoint> lbEndpoints = localityLbEndpoint.getLbEndpointsList();
+            lbEndpoints.forEach(lbEndpoint -> {
+                URL url = discoveryLbEndPointToUrl(lbEndpoint);
+                url.addParameter("dc", dc);
+                urls.add(url);
+            });
+        } );
+        return urls;
+    }
+
+    private static URL discoveryLbEndPointToUrl(LbEndpoint lbEndpoint) {
+        Map<String, String> parameters = new HashMap<>();
+        /**
+         * parse endpoint
+         */
+        Endpoint endpoint = lbEndpoint.getEndpoint();
+        SocketAddress socketAddress = endpoint.getAddress().getSocketAddress();
+        String host = socketAddress.getAddress();
+        Integer port = socketAddress.getPortValue();
+        if (host == null || host.isEmpty() || port == 0) {
+            throw new RuntimeException("Invalid Socket address from pilot, host or port can not be empty");
+        }
+
+        /**
+         * parse metadata
+         */
+        Metadata metadata = lbEndpoint.getMetadata();
+        Map<String, Value> ext = metadata.getFilterMetadataMap().get(ISTIO_KEY).getFieldsMap();
+
+        /**
+         * ignore some fields
+         */
+        String protocol = ext.get(PROTOCOL_KEY).getStringValue();
+        String service = ext.get(SERVICE_NAME).getStringValue();
+        parameters.put(CommonConstants.PROTOCOL_KEY, protocol);
+        parameters.put(CommonConstants.INTERFACE_KEY, service);
+        if (StringUtils.isNotEmpty(ext.get(GROUP_KEY).getStringValue())) {
+            parameters.put(CommonConstants.GROUP_KEY, ext.get(GROUP_KEY).getStringValue());
+        }
+        if (StringUtils.isNotEmpty(ext.get(VERSION_KEY).getStringValue())) {
+            parameters.put(CommonConstants.VERSION_KEY, ext.get(VERSION_KEY).getStringValue());
+        }
+        return new URL(protocol, host, port, service, parameters);
+    }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/BUILD
new file mode 100644
index 0000000..3806af0
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/BUILD
@@ -0,0 +1,65 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "config_dump",
+    srcs = ["config_dump.proto"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/api/v2:cds",
+        "//envoy/api/v2:lds",
+        "//envoy/api/v2:rds",
+        "//envoy/config/bootstrap/v2:bootstrap",
+    ],
+)
+
+api_proto_library_internal(
+    name = "clusters",
+    srcs = ["clusters.proto"],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":metrics",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:health_check",
+        "//envoy/type:percent",
+    ],
+)
+
+api_proto_library_internal(
+    name = "metrics",
+    srcs = ["metrics.proto"],
+    visibility = ["//visibility:public"],
+)
+
+api_proto_library_internal(
+    name = "memory",
+    srcs = ["memory.proto"],
+    visibility = ["//visibility:public"],
+)
+
+api_proto_library_internal(
+    name = "mutex_stats",
+    srcs = ["mutex_stats.proto"],
+    visibility = ["//visibility:public"],
+)
+
+api_proto_library_internal(
+    name = "certs",
+    srcs = ["certs.proto"],
+    visibility = ["//visibility:public"],
+)
+
+api_proto_library_internal(
+    name = "server_info",
+    srcs = ["server_info.proto"],
+    visibility = ["//visibility:public"],
+)
+
+api_proto_library_internal(
+    name = "tap",
+    srcs = ["tap.proto"],
+    deps = [
+        "//envoy/service/tap/v2alpha:common",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/certs.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/certs.proto
new file mode 100644
index 0000000..c6d5e41
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/certs.proto
@@ -0,0 +1,57 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "CertsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+import "google/protobuf/timestamp.proto";
+
+// [#protodoc-title: Certificates]
+
+// Proto representation of certificate details. Admin endpoint uses this wrapper for `/certs` to
+// display certificate information. See :ref:`/certs <operations_admin_interface_certs>` for more
+// information.
+message Certificates {
+  // List of certificates known to an Envoy.
+  repeated Certificate certificates = 1;
+}
+
+message Certificate {
+
+  // Details of CA certificate.
+  repeated CertificateDetails ca_cert = 1;
+
+  // Details of Certificate Chain
+  repeated CertificateDetails cert_chain = 2;
+}
+
+message CertificateDetails {
+  // Path of the certificate.
+  string path = 1;
+
+  // Certificate Serial Number.
+  string serial_number = 2;
+
+  // List of Subject Alternate names.
+  repeated SubjectAlternateName subject_alt_names = 3;
+
+  // Minimum of days until expiration of certificate and it's chain.
+  uint64 days_until_expiration = 4;
+
+  // Indicates the time from which the certificate is valid.
+  google.protobuf.Timestamp valid_from = 5;
+
+  // Indicates the time at which the certificate expires.
+  google.protobuf.Timestamp expiration_time = 6;
+}
+
+message SubjectAlternateName {
+
+  // Subject Alternate Name.
+  oneof name {
+    string dns = 1;
+    string uri = 2;
+  }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/clusters.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/clusters.proto
new file mode 100644
index 0000000..be7011b
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/clusters.proto
@@ -0,0 +1,85 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "ClustersProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+import "envoy/admin/v2alpha/metrics.proto";
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/health_check.proto";
+import "envoy/type/percent.proto";
+
+// [#protodoc-title: Clusters]
+
+// Admin endpoint uses this wrapper for `/clusters` to display cluster status information.
+// See :ref:`/clusters <operations_admin_interface_clusters>` for more information.
+message Clusters {
+  // Mapping from cluster name to each cluster's status.
+  repeated ClusterStatus cluster_statuses = 1;
+}
+
+// Details an individual cluster's current status.
+message ClusterStatus {
+  // Name of the cluster.
+  string name = 1;
+
+  // Denotes whether this cluster was added via API or configured statically.
+  bool added_via_api = 2;
+
+  // The success rate threshold used in the last interval. The threshold is used to eject hosts
+  // based on their success rate. See
+  // :ref:`Cluster outlier detection <arch_overview_outlier_detection>` statistics
+  //
+  // Note: this field may be omitted in any of the three following cases:
+  //
+  // 1. There were not enough hosts with enough request volume to proceed with success rate based
+  //    outlier ejection.
+  // 2. The threshold is computed to be < 0 because a negative value implies that there was no
+  //    threshold for that interval.
+  // 3. Outlier detection is not enabled for this cluster.
+  envoy.type.Percent success_rate_ejection_threshold = 3;
+
+  // Mapping from host address to the host's current status.
+  repeated HostStatus host_statuses = 4;
+}
+
+// Current state of a particular host.
+message HostStatus {
+  // Address of this host.
+  envoy.api.v2.core.Address address = 1;
+
+  // List of stats specific to this host.
+  repeated SimpleMetric stats = 2;
+
+  // The host's current health status.
+  HostHealthStatus health_status = 3;
+
+  // Request success rate for this host over the last calculated interval.
+  //
+  // Note: the message will not be present if host did not have enough request volume to calculate
+  // success rate or the cluster did not have enough hosts to run through success rate outlier
+  // ejection.
+  envoy.type.Percent success_rate = 4;
+
+  // The host's weight. If not configured, the value defaults to 1.
+  uint32 weight = 5;
+}
+
+// Health status for a host.
+message HostHealthStatus {
+  // The host is currently failing active health checks.
+  bool failed_active_health_check = 1;
+
+  // The host is currently considered an outlier and has been ejected.
+  bool failed_outlier_check = 2;
+
+  // The host is currently being marked as degraded through active health checking.
+  bool failed_active_degraded_check = 4;
+
+  // Health status as reported by EDS. Note: only HEALTHY and UNHEALTHY are currently supported
+  // here.
+  // TODO(mrice32): pipe through remaining EDS health status possibilities.
+  envoy.api.v2.core.HealthStatus eds_health_status = 3;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/config_dump.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/config_dump.proto
new file mode 100644
index 0000000..cfc1cdd
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/config_dump.proto
@@ -0,0 +1,180 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "ConfigDumpProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+import "envoy/api/v2/cds.proto";
+import "envoy/api/v2/lds.proto";
+import "envoy/api/v2/rds.proto";
+import "envoy/config/bootstrap/v2/bootstrap.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/timestamp.proto";
+
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: ConfigDump]
+
+// The :ref:`/config_dump <operations_admin_interface_config_dump>` admin endpoint uses this wrapper
+// message to maintain and serve arbitrary configuration information from any component in Envoy.
+message ConfigDump {
+  // This list is serialized and dumped in its entirety at the
+  // :ref:`/config_dump <operations_admin_interface_config_dump>` endpoint.
+  //
+  // The following configurations are currently supported and will be dumped in the order given
+  // below:
+  //
+  // * *bootstrap*: :ref:`BootstrapConfigDump <envoy_api_msg_admin.v2alpha.BootstrapConfigDump>`
+  // * *clusters*: :ref:`ClustersConfigDump <envoy_api_msg_admin.v2alpha.ClustersConfigDump>`
+  // * *listeners*: :ref:`ListenersConfigDump <envoy_api_msg_admin.v2alpha.ListenersConfigDump>`
+  // * *routes*:  :ref:`RoutesConfigDump <envoy_api_msg_admin.v2alpha.RoutesConfigDump>`
+  repeated google.protobuf.Any configs = 1 [(gogoproto.nullable) = false];
+}
+
+// This message describes the bootstrap configuration that Envoy was started with. This includes
+// any CLI overrides that were merged. Bootstrap configuration information can be used to recreate
+// the static portions of an Envoy configuration by reusing the output as the bootstrap
+// configuration for another Envoy.
+message BootstrapConfigDump {
+  envoy.config.bootstrap.v2.Bootstrap bootstrap = 1 [(gogoproto.nullable) = false];
+
+  // The timestamp when the BootstrapConfig was last updated.
+  google.protobuf.Timestamp last_updated = 2;
+}
+
+// Envoy's listener manager fills this message with all currently known listeners. Listener
+// configuration information can be used to recreate an Envoy configuration by populating all
+// listeners as static listeners or by returning them in a LDS response.
+message ListenersConfigDump {
+  // This is the :ref:`version_info <envoy_api_field_DiscoveryResponse.version_info>` in the
+  // last processed LDS discovery response. If there are only static bootstrap listeners, this field
+  // will be "".
+  string version_info = 1;
+
+  // Describes a statically loaded cluster.
+  message StaticListener {
+    // The listener config.
+    envoy.api.v2.Listener listener = 1;
+
+    // The timestamp when the Listener was last updated.
+    google.protobuf.Timestamp last_updated = 2;
+  }
+
+  // Describes a dynamically loaded cluster via the LDS API.
+  message DynamicListener {
+    // This is the per-resource version information. This version is currently taken from the
+    // :ref:`version_info <envoy_api_field_DiscoveryResponse.version_info>` field at the time
+    // that the listener was loaded. In the future, discrete per-listener versions may be supported
+    // by the API.
+    string version_info = 1;
+
+    // The listener config.
+    envoy.api.v2.Listener listener = 2;
+
+    // The timestamp when the Listener was last updated.
+    google.protobuf.Timestamp last_updated = 3;
+  }
+
+  // The statically loaded listener configs.
+  repeated StaticListener static_listeners = 2 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded active listeners. These are listeners that are available to service
+  // data plane traffic.
+  repeated DynamicListener dynamic_active_listeners = 3 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded warming listeners. These are listeners that are currently undergoing
+  // warming in preparation to service data plane traffic. Note that if attempting to recreate an
+  // Envoy configuration from a configuration dump, the warming listeners should generally be
+  // discarded.
+  repeated DynamicListener dynamic_warming_listeners = 4 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded draining listeners. These are listeners that are currently undergoing
+  // draining in preparation to stop servicing data plane traffic. Note that if attempting to
+  // recreate an Envoy configuration from a configuration dump, the draining listeners should
+  // generally be discarded.
+  repeated DynamicListener dynamic_draining_listeners = 5 [(gogoproto.nullable) = false];
+}
+
+// Envoy's cluster manager fills this message with all currently known clusters. Cluster
+// configuration information can be used to recreate an Envoy configuration by populating all
+// clusters as static clusters or by returning them in a CDS response.
+message ClustersConfigDump {
+  // This is the :ref:`version_info <envoy_api_field_DiscoveryResponse.version_info>` in the
+  // last processed CDS discovery response. If there are only static bootstrap clusters, this field
+  // will be "".
+  string version_info = 1;
+
+  // Describes a statically loaded cluster.
+  message StaticCluster {
+    // The cluster config.
+    envoy.api.v2.Cluster cluster = 1;
+
+    // The timestamp when the Cluster was last updated.
+    google.protobuf.Timestamp last_updated = 2;
+  }
+
+  // Describes a dynamically loaded cluster via the CDS API.
+  message DynamicCluster {
+    // This is the per-resource version information. This version is currently taken from the
+    // :ref:`version_info <envoy_api_field_DiscoveryResponse.version_info>` field at the time
+    // that the cluster was loaded. In the future, discrete per-cluster versions may be supported by
+    // the API.
+    string version_info = 1;
+
+    // The cluster config.
+    envoy.api.v2.Cluster cluster = 2;
+
+    // The timestamp when the Cluster was last updated.
+    google.protobuf.Timestamp last_updated = 3;
+  }
+
+  // The statically loaded cluster configs.
+  repeated StaticCluster static_clusters = 2 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded active clusters. These are clusters that are available to service
+  // data plane traffic.
+  repeated DynamicCluster dynamic_active_clusters = 3 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded warming clusters. These are clusters that are currently undergoing
+  // warming in preparation to service data plane traffic. Note that if attempting to recreate an
+  // Envoy configuration from a configuration dump, the warming clusters should generally be
+  // discarded.
+  repeated DynamicCluster dynamic_warming_clusters = 4 [(gogoproto.nullable) = false];
+}
+
+// Envoy's RDS implementation fills this message with all currently loaded routes, as described by
+// their RouteConfiguration objects. Static routes configured in the bootstrap configuration are
+// separated from those configured dynamically via RDS. Route configuration information can be used
+// to recreate an Envoy configuration by populating all routes as static routes or by returning them
+// in RDS responses.
+message RoutesConfigDump {
+  message StaticRouteConfig {
+    // The route config.
+    envoy.api.v2.RouteConfiguration route_config = 1;
+
+    // The timestamp when the Route was last updated.
+    google.protobuf.Timestamp last_updated = 2;
+  }
+
+  message DynamicRouteConfig {
+    // This is the per-resource version information. This version is currently taken from the
+    // :ref:`version_info <envoy_api_field_DiscoveryResponse.version_info>` field at the time that
+    // the route configuration was loaded.
+    string version_info = 1;
+
+    // The route config.
+    envoy.api.v2.RouteConfiguration route_config = 2;
+
+    // The timestamp when the Route was last updated.
+    google.protobuf.Timestamp last_updated = 3;
+  }
+
+  // The statically loaded route configs.
+  repeated StaticRouteConfig static_route_configs = 2 [(gogoproto.nullable) = false];
+
+  // The dynamically loaded route configs.
+  repeated DynamicRouteConfig dynamic_route_configs = 3 [(gogoproto.nullable) = false];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/memory.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/memory.proto
new file mode 100644
index 0000000..d86e448
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/memory.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "MemoryProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+// [#protodoc-title: Memory]
+
+// Proto representation of the internal memory consumption of an Envoy instance. These represent
+// values extracted from an internal TCMalloc instance. For more information, see the section of the
+// docs entitled ["Generic Tcmalloc Status"](https://gperftools.github.io/gperftools/tcmalloc.html).
+message Memory {
+
+  // The number of bytes allocated by the heap for Envoy. This is an alias for
+  // `generic.current_allocated_bytes`.
+  uint64 allocated = 1;
+
+  // The number of bytes reserved by the heap but not necessarily allocated. This is an alias for
+  // `generic.heap_size`.
+  uint64 heap_size = 2;
+
+  // The number of bytes in free, unmapped pages in the page heap. These bytes always count towards
+  // virtual memory usage, and depending on the OS, typically do not count towards physical memory
+  // usage. This is an alias for `tcmalloc.pageheap_unmapped_bytes`.
+  uint64 pageheap_unmapped = 3;
+
+  // The number of bytes in free, mapped pages in the page heap. These bytes always count towards
+  // virtual memory usage, and unless the underlying memory is swapped out by the OS, they also
+  // count towards physical memory usage. This is an alias for `tcmalloc.pageheap_free_bytes`.
+  uint64 pageheap_free = 4;
+
+  // The amount of memory used by the TCMalloc thread caches (for small objects). This is an alias
+  // for `tcmalloc.current_total_thread_cache_bytes`.
+  uint64 total_thread_cache = 5;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/metrics.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/metrics.proto
new file mode 100644
index 0000000..9a91c74
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/metrics.proto
@@ -0,0 +1,26 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "MetricsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+// [#protodoc-title: Metrics]
+
+// Proto representation of an Envoy Counter or Gauge value.
+message SimpleMetric {
+  enum Type {
+    COUNTER = 0;
+    GAUGE = 1;
+  }
+
+  // Type of the metric represented.
+  Type type = 1;
+
+  // Current metric value.
+  uint64 value = 2;
+
+  // Name of the metric.
+  string name = 3;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/mutex_stats.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/mutex_stats.proto
new file mode 100644
index 0000000..272d722
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/mutex_stats.proto
@@ -0,0 +1,28 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "MutexStatsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+// [#protodoc-title: MutexStats]
+
+// Proto representation of the statistics collected upon absl::Mutex contention, if Envoy is run
+// under :option:`--enable-mutex-tracing`. For more information, see the `absl::Mutex`
+// [docs](https://abseil.io/about/design/mutex#extra-features).
+//
+// *NB*: The wait cycles below are measured by `absl::base_internal::CycleClock`, and may not
+// correspond to core clock frequency. For more information, see the `CycleClock`
+// [docs](https://github.com/abseil/abseil-cpp/blob/master/absl/base/internal/cycleclock.h).
+message MutexStats {
+
+  // The number of individual mutex contentions which have occurred since startup.
+  uint64 num_contentions = 1;
+
+  // The length of the current contention wait cycle.
+  uint64 current_wait_cycles = 2;
+
+  // The lifetime total of all contention wait cycles.
+  uint64 lifetime_wait_cycles = 3;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/server_info.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/server_info.proto
new file mode 100644
index 0000000..13dea7a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/server_info.proto
@@ -0,0 +1,134 @@
+syntax = "proto3";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "ServerInfoProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+import "google/protobuf/duration.proto";
+
+// [#protodoc-title: Server State]
+
+// Proto representation of the value returned by /server_info, containing
+// server version/server status information.
+message ServerInfo {
+  // Server version.
+  string version = 1;
+
+  enum State {
+    // Server is live and serving traffic.
+    LIVE = 0;
+    // Server is draining listeners in response to external health checks failing.
+    DRAINING = 1;
+    // Server has not yet completed cluster manager initialization.
+    PRE_INITIALIZING = 2;
+    // Server is running the cluster manager initialization callbacks (e.g., RDS).
+    INITIALIZING = 3;
+  }
+
+  // State of the server.
+  State state = 2;
+
+  // Uptime since current epoch was started.
+  google.protobuf.Duration uptime_current_epoch = 3;
+
+  // Uptime since the start of the first epoch.
+  google.protobuf.Duration uptime_all_epochs = 4;
+
+  // Command line options the server is currently running with.
+  CommandLineOptions command_line_options = 6;
+}
+
+message CommandLineOptions {
+  // See :option:`--base-id` for details.
+  uint64 base_id = 1;
+
+  // See :option:`--concurrency` for details.
+  uint32 concurrency = 2;
+
+  // See :option:`--config-path` for details.
+  string config_path = 3;
+
+  // See :option:`--config-yaml` for details.
+  string config_yaml = 4;
+
+  // See :option:`--allow-unknown-fields` for details.
+  bool allow_unknown_fields = 5;
+
+  // See :option:`--admin-address-path` for details.
+  string admin_address_path = 6;
+
+  enum IpVersion {
+    v4 = 0;
+    v6 = 1;
+  }
+
+  // See :option:`--local-address-ip-version` for details.
+  IpVersion local_address_ip_version = 7;
+
+  // See :option:`--log-level` for details.
+  string log_level = 8;
+
+  // See :option:`--component-log-level` for details.
+  string component_log_level = 9;
+
+  // See :option:`--log-format` for details.
+  string log_format = 10;
+
+  // See :option:`--log-path` for details.
+  string log_path = 11;
+
+  // See :option:`--hot-restart-version` for details.
+  bool hot_restart_version = 12;
+
+  // See :option:`--service-cluster` for details.
+  string service_cluster = 13;
+
+  // See :option:`--service-node` for details.
+  string service_node = 14;
+
+  // See :option:`--service-zone` for details.
+  string service_zone = 15;
+
+  // See :option:`--file-flush-interval-msec` for details.
+  google.protobuf.Duration file_flush_interval = 16;
+
+  // See :option:`--drain-time-s` for details.
+  google.protobuf.Duration drain_time = 17;
+
+  // See :option:`--parent-shutdown-time-s` for details.
+  google.protobuf.Duration parent_shutdown_time = 18;
+
+  enum Mode {
+    // Validate configs and then serve traffic normally.
+    Serve = 0;
+
+    // Validate configs and exit.
+    Validate = 1;
+
+    // Completely load and initialize the config, and then exit without running the listener loop.
+    InitOnly = 2;
+  }
+
+  // See :option:`--mode` for details.
+  Mode mode = 19;
+
+  // See :option:`--max-stats` for details.
+  uint64 max_stats = 20;
+
+  // See :option:`--max-obj-name-len` for details.
+  uint64 max_obj_name_len = 21;
+
+  // See :option:`--disable-hot-restart` for details.
+  bool disable_hot_restart = 22;
+
+  // See :option:`--enable-mutex-tracing` for details.
+  bool enable_mutex_tracing = 23;
+
+  // See :option:`--restart-epoch` for details.
+  uint32 restart_epoch = 24;
+
+  // See :option:`--cpuset-threads` for details.
+  bool cpuset_threads = 25;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/tap.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/tap.proto
new file mode 100644
index 0000000..789be14
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/admin/v2alpha/tap.proto
@@ -0,0 +1,20 @@
+syntax = "proto3";
+
+import "envoy/service/tap/v2alpha/common.proto";
+import "validate/validate.proto";
+
+package envoy.admin.v2alpha;
+
+option java_outer_classname = "TapProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.admin.v2alpha";
+
+// The /tap admin request body that is used to configure an active tap session.
+message TapRequest {
+  // The opaque configuration ID used to match the configuration to a loaded extension.
+  // A tap extension configures a similar opaque ID that is used to match.
+  string config_id = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The tap configuration to load.
+  service.tap.v2alpha.TapConfig tap_config = 2 [(validate.rules).message.required = true];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/BUILD
new file mode 100644
index 0000000..f0327f8
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/BUILD
@@ -0,0 +1,144 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_grpc_library", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+# Friends of core API packages - filters, services, service configs.
+# Package //envoy/api/v2 contains xDS and discovery definitions that should
+# be in //envoy/service/discovery, but remain here for backwards compatibility.
+package_group(
+    name = "friends",
+    packages = [
+        "//envoy/admin/...",
+        "//envoy/api/v2",
+        "//envoy/config/...",
+        "//envoy/data/...",
+        "//envoy/service/...",
+    ],
+)
+
+api_proto_library_internal(
+    name = "discovery",
+    srcs = ["discovery.proto"],
+    visibility = [":friends"],
+    deps = ["//envoy/api/v2/core:base"],
+)
+
+api_go_proto_library(
+    name = "discovery",
+    proto = ":discovery",
+    deps = ["//envoy/api/v2/core:base_go_proto"],
+)
+
+api_proto_library_internal(
+    name = "eds",
+    srcs = ["eds.proto"],
+    has_services = 1,
+    visibility = [":friends"],
+    deps = [
+        ":discovery",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:health_check",
+        "//envoy/api/v2/endpoint",
+        "//envoy/type:percent",
+    ],
+)
+
+api_go_grpc_library(
+    name = "eds",
+    proto = ":eds",
+    deps = [
+        ":discovery_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/core:health_check_go_proto",
+        "//envoy/api/v2/endpoint:endpoint_go_proto",
+        "//envoy/type:percent_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "cds",
+    srcs = ["cds.proto"],
+    has_services = 1,
+    visibility = [":friends"],
+    deps = [
+        ":discovery",
+        ":eds",
+        "//envoy/api/v2/auth:cert",
+        "//envoy/api/v2/cluster:circuit_breaker",
+        "//envoy/api/v2/cluster:outlier_detection",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:config_source",
+        "//envoy/api/v2/core:health_check",
+        "//envoy/api/v2/core:protocol",
+        "//envoy/api/v2/endpoint",
+        "//envoy/type:percent",
+    ],
+)
+
+api_go_grpc_library(
+    name = "cds",
+    proto = ":cds",
+    deps = [
+        ":discovery_go_proto",
+        ":eds_go_grpc",
+        "//envoy/api/v2/auth:cert_go_proto",
+        "//envoy/api/v2/cluster:circuit_breaker_go_proto",
+        "//envoy/api/v2/cluster:outlier_detection_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/core:config_source_go_proto",
+        "//envoy/api/v2/core:health_check_go_proto",
+        "//envoy/api/v2/core:protocol_go_proto",
+        "//envoy/api/v2/endpoint:endpoint_go_proto",
+        "//envoy/type:percent_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "lds",
+    srcs = ["lds.proto"],
+    has_services = 1,
+    visibility = [":friends"],
+    deps = [
+        ":discovery",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/listener",
+    ],
+)
+
+api_go_grpc_library(
+    name = "lds",
+    proto = ":lds",
+    deps = [
+        ":discovery_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/listener:listener_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "rds",
+    srcs = ["rds.proto"],
+    has_services = 1,
+    visibility = [":friends"],
+    deps = [
+        ":discovery",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/route",
+    ],
+)
+
+api_go_grpc_library(
+    name = "rds",
+    proto = ":rds",
+    deps = [
+        ":discovery_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/route:route_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/README.md b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/README.md
new file mode 100644
index 0000000..984be69
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/README.md
@@ -0,0 +1,9 @@
+Protocol buffer definitions for xDS and top-level resource API messages.
+
+Package group `//envoy/api/v2:friends` enumerates all consumers of the shared
+API messages. That includes package envoy.api.v2 itself, which contains several
+xDS definitions. Default visibility for all shared definitions should be set to
+`//envoy/api/v2:friends`.
+
+Additionally, packages envoy.api.v2.core and envoy.api.v2.auth are also
+consumed throughout the subpackages of `//envoy/api/v2`.
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/BUILD
new file mode 100644
index 0000000..acc28aa
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/BUILD
@@ -0,0 +1,35 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+package_group(
+    name = "friends",
+    includes = [
+        "//envoy/api/v2:friends",
+    ],
+    packages = [
+        "//envoy/api/v2/cluster",
+        "//envoy/api/v2/endpoint",
+        "//envoy/api/v2/listener",
+        "//envoy/api/v2/route",
+    ],
+)
+
+api_proto_library_internal(
+    name = "cert",
+    srcs = ["cert.proto"],
+    visibility = [":friends"],
+    deps = [
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:config_source",
+    ],
+)
+
+api_go_proto_library(
+    name = "cert",
+    proto = ":cert",
+    deps = [
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/core:config_source_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/cert.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/cert.proto
new file mode 100644
index 0000000..526caf2
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/auth/cert.proto
@@ -0,0 +1,380 @@
+syntax = "proto3";
+
+package envoy.api.v2.auth;
+
+option java_outer_classname = "CertProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.auth";
+option go_package = "auth";
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/core/config_source.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Common TLS configuration]
+
+message TlsParameters {
+  enum TlsProtocol {
+    // Envoy will choose the optimal TLS version.
+    TLS_AUTO = 0;
+
+    // TLS 1.0
+    TLSv1_0 = 1;
+
+    // TLS 1.1
+    TLSv1_1 = 2;
+
+    // TLS 1.2
+    TLSv1_2 = 3;
+
+    // TLS 1.3
+    TLSv1_3 = 4;
+  }
+
+  // Minimum TLS protocol version. By default, it's ``TLSv1_0``.
+  TlsProtocol tls_minimum_protocol_version = 1 [(validate.rules).enum.defined_only = true];
+
+  // Maximum TLS protocol version. By default, it's ``TLSv1_3`` for servers in non-FIPS builds, and
+  // ``TLSv1_2`` for clients and for servers using :ref:`BoringSSL FIPS <arch_overview_ssl_fips>`.
+  TlsProtocol tls_maximum_protocol_version = 2 [(validate.rules).enum.defined_only = true];
+
+  // If specified, the TLS listener will only support the specified `cipher list
+  // <https://commondatastorage.googleapis.com/chromium-boringssl-docs/ssl.h.html#Cipher-suite-configuration>`_
+  // when negotiating TLS 1.0-1.2 (this setting has no effect when negotiating TLS 1.3). If not
+  // specified, the default list will be used.
+  //
+  // In non-FIPS builds, the default cipher list is:
+  //
+  // .. code-block:: none
+  //
+  //   [ECDHE-ECDSA-AES128-GCM-SHA256|ECDHE-ECDSA-CHACHA20-POLY1305]
+  //   [ECDHE-RSA-AES128-GCM-SHA256|ECDHE-RSA-CHACHA20-POLY1305]
+  //   ECDHE-ECDSA-AES128-SHA
+  //   ECDHE-RSA-AES128-SHA
+  //   AES128-GCM-SHA256
+  //   AES128-SHA
+  //   ECDHE-ECDSA-AES256-GCM-SHA384
+  //   ECDHE-RSA-AES256-GCM-SHA384
+  //   ECDHE-ECDSA-AES256-SHA
+  //   ECDHE-RSA-AES256-SHA
+  //   AES256-GCM-SHA384
+  //   AES256-SHA
+  //
+  // In builds using :ref:`BoringSSL FIPS <arch_overview_ssl_fips>`, the default cipher list is:
+  //
+  // .. code-block:: none
+  //
+  //   ECDHE-ECDSA-AES128-GCM-SHA256
+  //   ECDHE-RSA-AES128-GCM-SHA256
+  //   ECDHE-ECDSA-AES128-SHA
+  //   ECDHE-RSA-AES128-SHA
+  //   AES128-GCM-SHA256
+  //   AES128-SHA
+  //   ECDHE-ECDSA-AES256-GCM-SHA384
+  //   ECDHE-RSA-AES256-GCM-SHA384
+  //   ECDHE-ECDSA-AES256-SHA
+  //   ECDHE-RSA-AES256-SHA
+  //   AES256-GCM-SHA384
+  //   AES256-SHA
+  repeated string cipher_suites = 3;
+
+  // If specified, the TLS connection will only support the specified ECDH
+  // curves. If not specified, the default curves will be used.
+  //
+  // In non-FIPS builds, the default curves are:
+  //
+  // .. code-block:: none
+  //
+  //   X25519
+  //   P-256
+  //
+  // In builds using :ref:`BoringSSL FIPS <arch_overview_ssl_fips>`, the default curve is:
+  //
+  // .. code-block:: none
+  //
+  //   P-256
+  repeated string ecdh_curves = 4;
+}
+
+message TlsCertificate {
+  // The TLS certificate chain.
+  core.DataSource certificate_chain = 1;
+
+  // The TLS private key.
+  core.DataSource private_key = 2;
+
+  // The password to decrypt the TLS private key. If this field is not set, it is assumed that the
+  // TLS private key is not password encrypted.
+  core.DataSource password = 3;
+
+  // [#not-implemented-hide:]
+  core.DataSource ocsp_staple = 4;
+
+  // [#not-implemented-hide:]
+  repeated core.DataSource signed_certificate_timestamp = 5;
+}
+
+message TlsSessionTicketKeys {
+  // Keys for encrypting and decrypting TLS session tickets. The
+  // first key in the array contains the key to encrypt all new sessions created by this context.
+  // All keys are candidates for decrypting received tickets. This allows for easy rotation of keys
+  // by, for example, putting the new key first, and the previous key second.
+  //
+  // If :ref:`session_ticket_keys <envoy_api_field_auth.DownstreamTlsContext.session_ticket_keys>`
+  // is not specified, the TLS library will still support resuming sessions via tickets, but it will
+  // use an internally-generated and managed key, so sessions cannot be resumed across hot restarts
+  // or on different hosts.
+  //
+  // Each key must contain exactly 80 bytes of cryptographically-secure random data. For
+  // example, the output of ``openssl rand 80``.
+  //
+  // .. attention::
+  //
+  //   Using this feature has serious security considerations and risks. Improper handling of keys
+  //   may result in loss of secrecy in connections, even if ciphers supporting perfect forward
+  //   secrecy are used. See https://www.imperialviolet.org/2013/06/27/botchingpfs.html for some
+  //   discussion. To minimize the risk, you must:
+  //
+  //   * Keep the session ticket keys at least as secure as your TLS certificate private keys
+  //   * Rotate session ticket keys at least daily, and preferably hourly
+  //   * Always generate keys using a cryptographically-secure random data source
+  repeated core.DataSource keys = 1 [(validate.rules).repeated .min_items = 1];
+}
+
+message CertificateValidationContext {
+  // TLS certificate data containing certificate authority certificates to use in verifying
+  // a presented peer certificate (e.g. server certificate for clusters or client certificate
+  // for listeners). If not specified and a peer certificate is presented it will not be
+  // verified. By default, a client certificate is optional, unless one of the additional
+  // options (:ref:`require_client_certificate
+  // <envoy_api_field_auth.DownstreamTlsContext.require_client_certificate>`,
+  // :ref:`verify_certificate_spki
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_spki>`,
+  // :ref:`verify_certificate_hash
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_hash>`, or
+  // :ref:`verify_subject_alt_name
+  // <envoy_api_field_auth.CertificateValidationContext.verify_subject_alt_name>`) is also
+  // specified.
+  //
+  // It can optionally contain certificate revocation lists, in which case Envoy will verify
+  // that the presented peer certificate has not been revoked by one of the included CRLs.
+  //
+  // See :ref:`the TLS overview <arch_overview_ssl_enabling_verification>` for a list of common
+  // system CA locations.
+  core.DataSource trusted_ca = 1;
+
+  // An optional list of base64-encoded SHA-256 hashes. If specified, Envoy will verify that the
+  // SHA-256 of the DER-encoded Subject Public Key Information (SPKI) of the presented certificate
+  // matches one of the specified values.
+  //
+  // A base64-encoded SHA-256 of the Subject Public Key Information (SPKI) of the certificate
+  // can be generated with the following command:
+  //
+  // .. code-block:: bash
+  //
+  //   $ openssl x509 -in path/to/client.crt -noout -pubkey \
+  //     | openssl pkey -pubin -outform DER \
+  //     | openssl dgst -sha256 -binary \
+  //     | openssl enc -base64
+  //   NvqYIYSbgK2vCJpQhObf77vv+bQWtc5ek5RIOwPiC9A=
+  //
+  // This is the format used in HTTP Public Key Pinning.
+  //
+  // When both:
+  // :ref:`verify_certificate_hash
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_hash>` and
+  // :ref:`verify_certificate_spki
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_spki>` are specified,
+  // a hash matching value from either of the lists will result in the certificate being accepted.
+  //
+  // .. attention::
+  //
+  //   This option is preferred over :ref:`verify_certificate_hash
+  //   <envoy_api_field_auth.CertificateValidationContext.verify_certificate_hash>`,
+  //   because SPKI is tied to a private key, so it doesn't change when the certificate
+  //   is renewed using the same private key.
+  repeated string verify_certificate_spki = 3
+      [(validate.rules).repeated .items.string = {min_bytes: 44, max_bytes: 44}];
+
+  // An optional list of hex-encoded SHA-256 hashes. If specified, Envoy will verify that
+  // the SHA-256 of the DER-encoded presented certificate matches one of the specified values.
+  //
+  // A hex-encoded SHA-256 of the certificate can be generated with the following command:
+  //
+  // .. code-block:: bash
+  //
+  //   $ openssl x509 -in path/to/client.crt -outform DER | openssl dgst -sha256 | cut -d" " -f2
+  //   df6ff72fe9116521268f6f2dd4966f51df479883fe7037b39f75916ac3049d1a
+  //
+  // A long hex-encoded and colon-separated SHA-256 (a.k.a. "fingerprint") of the certificate
+  // can be generated with the following command:
+  //
+  // .. code-block:: bash
+  //
+  //   $ openssl x509 -in path/to/client.crt -noout -fingerprint -sha256 | cut -d"=" -f2
+  //   DF:6F:F7:2F:E9:11:65:21:26:8F:6F:2D:D4:96:6F:51:DF:47:98:83:FE:70:37:B3:9F:75:91:6A:C3:04:9D:1A
+  //
+  // Both of those formats are acceptable.
+  //
+  // When both:
+  // :ref:`verify_certificate_hash
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_hash>` and
+  // :ref:`verify_certificate_spki
+  // <envoy_api_field_auth.CertificateValidationContext.verify_certificate_spki>` are specified,
+  // a hash matching value from either of the lists will result in the certificate being accepted.
+  repeated string verify_certificate_hash = 2
+      [(validate.rules).repeated .items.string = {min_bytes: 64, max_bytes: 95}];
+
+  // An optional list of Subject Alternative Names. If specified, Envoy will verify that the
+  // Subject Alternative Name of the presented certificate matches one of the specified values.
+  //
+  // .. attention::
+  //
+  //   Subject Alternative Names are easily spoofable and verifying only them is insecure,
+  //   therefore this option must be used together with :ref:`trusted_ca
+  //   <envoy_api_field_auth.CertificateValidationContext.trusted_ca>`.
+  repeated string verify_subject_alt_name = 4;
+
+  // [#not-implemented-hide:] Must present a signed time-stamped OCSP response.
+  google.protobuf.BoolValue require_ocsp_staple = 5;
+
+  // [#not-implemented-hide:] Must present signed certificate time-stamp.
+  google.protobuf.BoolValue require_signed_certificate_timestamp = 6;
+
+  // An optional `certificate revocation list
+  // <https://en.wikipedia.org/wiki/Certificate_revocation_list>`_
+  // (in PEM format). If specified, Envoy will verify that the presented peer
+  // certificate has not been revoked by this CRL. If this DataSource contains
+  // multiple CRLs, all of them will be used.
+  core.DataSource crl = 7;
+
+  // If specified, Envoy will not reject expired certificates.
+  bool allow_expired_certificate = 8;
+}
+
+// TLS context shared by both client and server TLS contexts.
+message CommonTlsContext {
+  // TLS protocol versions, cipher suites etc.
+  TlsParameters tls_params = 1;
+
+  // :ref:`Multiple TLS certificates <arch_overview_ssl_cert_select>` can be associated with the
+  // same context to allow both RSA and ECDSA certificates.
+  //
+  // Only a single TLS certificate is supported in client contexts. In server contexts, the first
+  // RSA certificate is used for clients that only support RSA and the first ECDSA certificate is
+  // used for clients that support ECDSA.
+  repeated TlsCertificate tls_certificates = 2;
+
+  // Configs for fetching TLS certificates via SDS API.
+  repeated SdsSecretConfig tls_certificate_sds_secret_configs = 6
+      [(validate.rules).repeated .max_items = 1];
+
+  message CombinedCertificateValidationContext {
+    // How to validate peer certificates.
+    CertificateValidationContext default_validation_context = 1
+        [(validate.rules).message.required = true];
+
+    // Config for fetching validation context via SDS API.
+    SdsSecretConfig validation_context_sds_secret_config = 2
+        [(validate.rules).message.required = true];
+  };
+
+  oneof validation_context_type {
+    // How to validate peer certificates.
+    CertificateValidationContext validation_context = 3;
+
+    // Config for fetching validation context via SDS API.
+    SdsSecretConfig validation_context_sds_secret_config = 7;
+
+    // Combined certificate validation context holds a default CertificateValidationContext
+    // and SDS config. When SDS server returns dynamic CertificateValidationContext, both dynamic
+    // and default CertificateValidationContext are merged into a new CertificateValidationContext
+    // for validation. This merge is done by Message::MergeFrom(), so dynamic
+    // CertificateValidationContext overwrites singular fields in default
+    // CertificateValidationContext, and concatenates repeated fields to default
+    // CertificateValidationContext, and logical OR is applied to boolean fields.
+    CombinedCertificateValidationContext combined_validation_context = 8;
+  }
+
+  // Supplies the list of ALPN protocols that the listener should expose. In
+  // practice this is likely to be set to one of two values (see the
+  // :ref:`codec_type
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.codec_type>`
+  // parameter in the HTTP connection manager for more information):
+  //
+  // * "h2,http/1.1" If the listener is going to support both HTTP/2 and HTTP/1.1.
+  // * "http/1.1" If the listener is only going to support HTTP/1.1.
+  //
+  // There is no default for this parameter. If empty, Envoy will not expose ALPN.
+  repeated string alpn_protocols = 4;
+
+  reserved 5;
+}
+
+message UpstreamTlsContext {
+  // Common TLS context settings.
+  CommonTlsContext common_tls_context = 1;
+
+  // SNI string to use when creating TLS backend connections.
+  string sni = 2 [(validate.rules).string.max_bytes = 255];
+
+  // If true, server-initiated TLS renegotiation will be allowed.
+  //
+  // .. attention::
+  //
+  //   TLS renegotiation is considered insecure and shouldn't be used unless absolutely necessary.
+  bool allow_renegotiation = 3;
+
+  // Maximum number of session keys (Pre-Shared Keys for TLSv1.3+, Session IDs and Session Tickets
+  // for TLSv1.2 and older) to store for the purpose of session resumption.
+  //
+  // Defaults to 1, setting this to 0 disables session resumption.
+  google.protobuf.UInt32Value max_session_keys = 4;
+}
+
+message DownstreamTlsContext {
+  // Common TLS context settings.
+  CommonTlsContext common_tls_context = 1;
+
+  // If specified, Envoy will reject connections without a valid client
+  // certificate.
+  google.protobuf.BoolValue require_client_certificate = 2;
+
+  // If specified, Envoy will reject connections without a valid and matching SNI.
+  // [#not-implemented-hide:]
+  google.protobuf.BoolValue require_sni = 3;
+
+  oneof session_ticket_keys_type {
+    // TLS session ticket key settings.
+    TlsSessionTicketKeys session_ticket_keys = 4;
+
+    // [#not-implemented-hide:]
+    SdsSecretConfig session_ticket_keys_sds_secret_config = 5;
+  }
+}
+
+// [#proto-status: experimental]
+message SdsSecretConfig {
+  // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to.
+  // When both name and config are specified, then secret can be fetched and/or reloaded via SDS.
+  // When only name is specified, then secret will be loaded from static resources [V2-API-DIFF].
+  string name = 1;
+  core.ConfigSource sds_config = 2;
+}
+
+// [#proto-status: experimental]
+message Secret {
+  // Name (FQDN, UUID, SPKI, SHA256, etc.) by which the secret can be uniquely referred to.
+  string name = 1;
+  oneof type {
+    TlsCertificate tls_certificate = 2;
+    TlsSessionTicketKeys session_ticket_keys = 3;
+    CertificateValidationContext validation_context = 4;
+  }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cds.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cds.proto
new file mode 100644
index 0000000..96587ae
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cds.proto
@@ -0,0 +1,605 @@
+syntax = "proto3";
+
+package envoy.api.v2;
+
+option java_outer_classname = "CdsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2";
+
+option java_generic_services = true;
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/auth/cert.proto";
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/core/config_source.proto";
+import "envoy/api/v2/discovery.proto";
+import "envoy/api/v2/core/health_check.proto";
+import "envoy/api/v2/core/protocol.proto";
+import "envoy/api/v2/cluster/circuit_breaker.proto";
+import "envoy/api/v2/cluster/outlier_detection.proto";
+import "envoy/api/v2/eds.proto";
+import "envoy/type/percent.proto";
+
+import "google/api/annotations.proto";
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
+
+// Return list of all clusters this proxy will load balance to.
+service ClusterDiscoveryService {
+  rpc StreamClusters(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
+  }
+
+  rpc DeltaClusters(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse) {
+  }
+
+  rpc FetchClusters(DiscoveryRequest) returns (DiscoveryResponse) {
+    option (google.api.http) = {
+      post: "/v2/discovery:clusters"
+      body: "*"
+    };
+  }
+}
+
+// [#protodoc-title: Clusters]
+
+// Configuration for a single upstream cluster.
+// [#comment:next free field: 39]
+message Cluster {
+  // Supplies the name of the cluster which must be unique across all clusters.
+  // The cluster name is used when emitting
+  // :ref:`statistics <config_cluster_manager_cluster_stats>` if :ref:`alt_stat_name
+  // <envoy_api_field_Cluster.alt_stat_name>` is not provided.
+  // Any ``:`` in the cluster name will be converted to ``_`` when emitting statistics.
+  // By default, the maximum length of a cluster name is limited to 60
+  // characters. This limit can be increased by setting the
+  // :option:`--max-obj-name-len` command line argument to the desired value.
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // An optional alternative to the cluster name to be used while emitting stats.
+  // Any ``:`` in the name will be converted to ``_`` when emitting statistics. This should not be
+  // confused with :ref:`Router Filter Header
+  // <config_http_filters_router_x-envoy-upstream-alt-stat-name>`.
+  string alt_stat_name = 28;
+
+  // Refer to :ref:`service discovery type <arch_overview_service_discovery_types>`
+  // for an explanation on each type.
+  enum DiscoveryType {
+    // Refer to the :ref:`static discovery type<arch_overview_service_discovery_types_static>`
+    // for an explanation.
+    STATIC = 0;
+
+    // Refer to the :ref:`strict DNS discovery
+    // type<arch_overview_service_discovery_types_strict_dns>`
+    // for an explanation.
+    STRICT_DNS = 1;
+
+    // Refer to the :ref:`logical DNS discovery
+    // type<arch_overview_service_discovery_types_logical_dns>`
+    // for an explanation.
+    LOGICAL_DNS = 2;
+
+    // Refer to the :ref:`service discovery type<arch_overview_service_discovery_types_eds>`
+    // for an explanation.
+    EDS = 3;
+
+    // Refer to the :ref:`original destination discovery
+    // type<arch_overview_service_discovery_types_original_destination>`
+    // for an explanation.
+    ORIGINAL_DST = 4;
+  }
+
+  // Extended cluster type.
+  message CustomClusterType {
+    // The type of the cluster to instantiate. The name must match a supported cluster type.
+    string name = 1 [(validate.rules).string.min_bytes = 1];
+
+    // Cluster specific configuration which depends on the cluster being instantiated.
+    // See the supported cluster for further documentation.
+    google.protobuf.Any typed_config = 2;
+  }
+
+  oneof cluster_discovery_type {
+    // The :ref:`service discovery type <arch_overview_service_discovery_types>`
+    // to use for resolving the cluster.
+    DiscoveryType type = 2 [(validate.rules).enum.defined_only = true];
+
+    // The custom cluster type.
+    CustomClusterType cluster_type = 38;
+  }
+
+  // Only valid when discovery type is EDS.
+  message EdsClusterConfig {
+    // Configuration for the source of EDS updates for this Cluster.
+    core.ConfigSource eds_config = 1;
+
+    // Optional alternative to cluster name to present to EDS. This does not
+    // have the same restrictions as cluster name, i.e. it may be arbitrary
+    // length.
+    string service_name = 2;
+  }
+  // Configuration to use for EDS updates for the Cluster.
+  EdsClusterConfig eds_cluster_config = 3;
+
+  // The timeout for new network connections to hosts in the cluster.
+  google.protobuf.Duration connect_timeout = 4 [
+    (validate.rules).duration.gt = {},
+    (gogoproto.stdduration) = true,
+    (gogoproto.nullable) = false
+  ];
+
+  // Soft limit on size of the cluster’s connections read and write buffers. If
+  // unspecified, an implementation defined default is applied (1MiB).
+  google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5;
+
+  // Refer to :ref:`load balancer type <arch_overview_load_balancing_types>` architecture
+  // overview section for information on each type.
+  enum LbPolicy {
+
+    // Refer to the :ref:`round robin load balancing
+    // policy<arch_overview_load_balancing_types_round_robin>`
+    // for an explanation.
+    ROUND_ROBIN = 0;
+
+    // Refer to the :ref:`least request load balancing
+    // policy<arch_overview_load_balancing_types_least_request>`
+    // for an explanation.
+    LEAST_REQUEST = 1;
+
+    // Refer to the :ref:`ring hash load balancing
+    // policy<arch_overview_load_balancing_types_ring_hash>`
+    // for an explanation.
+    RING_HASH = 2;
+
+    // Refer to the :ref:`random load balancing
+    // policy<arch_overview_load_balancing_types_random>`
+    // for an explanation.
+    RANDOM = 3;
+
+    // Refer to the :ref:`original destination load balancing
+    // policy<arch_overview_load_balancing_types_original_destination>`
+    // for an explanation.
+    ORIGINAL_DST_LB = 4;
+
+    // Refer to the :ref:`Maglev load balancing policy<arch_overview_load_balancing_types_maglev>`
+    // for an explanation.
+    MAGLEV = 5;
+  }
+  // The :ref:`load balancer type <arch_overview_load_balancing_types>` to use
+  // when picking a host in the cluster.
+  LbPolicy lb_policy = 6 [(validate.rules).enum.defined_only = true];
+
+  // If the service discovery type is
+  // :ref:`STATIC<envoy_api_enum_value_Cluster.DiscoveryType.STATIC>`,
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`
+  // or :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`,
+  // then hosts is required.
+  //
+  // .. attention::
+  //
+  //   **This field is deprecated**. Set the
+  //   :ref:`load_assignment<envoy_api_field_Cluster.load_assignment>` field instead.
+  //
+  repeated core.Address hosts = 7 [deprecated = true];
+
+  // Setting this is required for specifying members of
+  // :ref:`STATIC<envoy_api_enum_value_Cluster.DiscoveryType.STATIC>`,
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`
+  // or :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>` clusters.
+  // This field supersedes :ref:`hosts<envoy_api_field_Cluster.hosts>` field.
+  // [#comment:TODO(dio): Deprecate the hosts field and add it to DEPRECATED.md
+  // once load_assignment is implemented.]
+  //
+  // .. attention::
+  //
+  //   Setting this allows non-EDS cluster types to contain embedded EDS equivalent
+  //   :ref:`endpoint assignments<envoy_api_msg_ClusterLoadAssignment>`.
+  //   Setting this overrides :ref:`hosts<envoy_api_field_Cluster.hosts>` values.
+  //
+  ClusterLoadAssignment load_assignment = 33;
+
+  // Optional :ref:`active health checking <arch_overview_health_checking>`
+  // configuration for the cluster. If no
+  // configuration is specified no health checking will be done and all cluster
+  // members will be considered healthy at all times.
+  repeated core.HealthCheck health_checks = 8;
+
+  // Optional maximum requests for a single upstream connection. This parameter
+  // is respected by both the HTTP/1.1 and HTTP/2 connection pool
+  // implementations. If not specified, there is no limit. Setting this
+  // parameter to 1 will effectively disable keep alive.
+  google.protobuf.UInt32Value max_requests_per_connection = 9;
+
+  // Optional :ref:`circuit breaking <arch_overview_circuit_break>` for the cluster.
+  cluster.CircuitBreakers circuit_breakers = 10;
+
+  // The TLS configuration for connections to the upstream cluster. If no TLS
+  // configuration is specified, TLS will not be used for new connections.
+  //
+  // .. attention::
+  //
+  //   Server certificate verification is not enabled by default. Configure
+  //   :ref:`trusted_ca<envoy_api_field_auth.CertificateValidationContext.trusted_ca>` to enable
+  //   verification.
+  auth.UpstreamTlsContext tls_context = 11;
+
+  reserved 12;
+
+  // Additional options when handling HTTP requests. These options will be applicable to both
+  // HTTP1 and HTTP2 requests.
+  core.HttpProtocolOptions common_http_protocol_options = 29;
+
+  // Additional options when handling HTTP1 requests.
+  core.Http1ProtocolOptions http_protocol_options = 13;
+
+  // Even if default HTTP2 protocol options are desired, this field must be
+  // set so that Envoy will assume that the upstream supports HTTP/2 when
+  // making new HTTP connection pool connections. Currently, Envoy only
+  // supports prior knowledge for upstream connections. Even if TLS is used
+  // with ALPN, `http2_protocol_options` must be specified. As an aside this allows HTTP/2
+  // connections to happen over plain text.
+  core.Http2ProtocolOptions http2_protocol_options = 14;
+
+  // The extension_protocol_options field is used to provide extension-specific protocol options
+  // for upstream connections. The key should match the extension filter name, such as
+  // "envoy.filters.network.thrift_proxy". See the extension's documentation for details on
+  // specific options.
+  map<string, google.protobuf.Struct> extension_protocol_options = 35 [deprecated = true];
+
+  // The extension_protocol_options field is used to provide extension-specific protocol options
+  // for upstream connections. The key should match the extension filter name, such as
+  // "envoy.filters.network.thrift_proxy". See the extension's documentation for details on
+  // specific options.
+  map<string, google.protobuf.Any> typed_extension_protocol_options = 36;
+
+  reserved 15;
+
+  // If the DNS refresh rate is specified and the cluster type is either
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`,
+  // or :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`,
+  // this value is used as the cluster’s DNS refresh
+  // rate. If this setting is not specified, the value defaults to 5000ms. For
+  // cluster types other than
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`
+  // and :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`
+  // this setting is ignored.
+  google.protobuf.Duration dns_refresh_rate = 16
+      [(validate.rules).duration.gt = {}, (gogoproto.stdduration) = true];
+
+  // When V4_ONLY is selected, the DNS resolver will only perform a lookup for
+  // addresses in the IPv4 family. If V6_ONLY is selected, the DNS resolver will
+  // only perform a lookup for addresses in the IPv6 family. If AUTO is
+  // specified, the DNS resolver will first perform a lookup for addresses in
+  // the IPv6 family and fallback to a lookup for addresses in the IPv4 family.
+  // For cluster types other than
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>` and
+  // :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`,
+  // this setting is
+  // ignored.
+  enum DnsLookupFamily {
+    AUTO = 0;
+    V4_ONLY = 1;
+    V6_ONLY = 2;
+  }
+
+  // The DNS IP address resolution policy. If this setting is not specified, the
+  // value defaults to
+  // :ref:`AUTO<envoy_api_enum_value_Cluster.DnsLookupFamily.AUTO>`.
+  DnsLookupFamily dns_lookup_family = 17 [(validate.rules).enum.defined_only = true];
+
+  // If DNS resolvers are specified and the cluster type is either
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`,
+  // or :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`,
+  // this value is used to specify the cluster’s dns resolvers.
+  // If this setting is not specified, the value defaults to the default
+  // resolver, which uses /etc/resolv.conf for configuration. For cluster types
+  // other than
+  // :ref:`STRICT_DNS<envoy_api_enum_value_Cluster.DiscoveryType.STRICT_DNS>`
+  // and :ref:`LOGICAL_DNS<envoy_api_enum_value_Cluster.DiscoveryType.LOGICAL_DNS>`
+  // this setting is ignored.
+  repeated core.Address dns_resolvers = 18;
+
+  // If specified, outlier detection will be enabled for this upstream cluster.
+  // Each of the configuration values can be overridden via
+  // :ref:`runtime values <config_cluster_manager_cluster_runtime_outlier_detection>`.
+  cluster.OutlierDetection outlier_detection = 19;
+
+  // The interval for removing stale hosts from a cluster type
+  // :ref:`ORIGINAL_DST<envoy_api_enum_value_Cluster.DiscoveryType.ORIGINAL_DST>`.
+  // Hosts are considered stale if they have not been used
+  // as upstream destinations during this interval. New hosts are added
+  // to original destination clusters on demand as new connections are
+  // redirected to Envoy, causing the number of hosts in the cluster to
+  // grow over time. Hosts that are not stale (they are actively used as
+  // destinations) are kept in the cluster, which allows connections to
+  // them remain open, saving the latency that would otherwise be spent
+  // on opening new connections. If this setting is not specified, the
+  // value defaults to 5000ms. For cluster types other than
+  // :ref:`ORIGINAL_DST<envoy_api_enum_value_Cluster.DiscoveryType.ORIGINAL_DST>`
+  // this setting is ignored.
+  google.protobuf.Duration cleanup_interval = 20
+      [(validate.rules).duration.gt = {}, (gogoproto.stdduration) = true];
+
+  // Optional configuration used to bind newly established upstream connections.
+  // This overrides any bind_config specified in the bootstrap proto.
+  // If the address and port are empty, no bind will be performed.
+  core.BindConfig upstream_bind_config = 21;
+
+  // Optionally divide the endpoints in this cluster into subsets defined by
+  // endpoint metadata and selected by route and weighted cluster metadata.
+  message LbSubsetConfig {
+
+    // If NO_FALLBACK is selected, a result
+    // equivalent to no healthy hosts is reported. If ANY_ENDPOINT is selected,
+    // any cluster endpoint may be returned (subject to policy, health checks,
+    // etc). If DEFAULT_SUBSET is selected, load balancing is performed over the
+    // endpoints matching the values from the default_subset field.
+    enum LbSubsetFallbackPolicy {
+      NO_FALLBACK = 0;
+      ANY_ENDPOINT = 1;
+      DEFAULT_SUBSET = 2;
+    }
+
+    // The behavior used when no endpoint subset matches the selected route's
+    // metadata. The value defaults to
+    // :ref:`NO_FALLBACK<envoy_api_enum_value_Cluster.LbSubsetConfig.LbSubsetFallbackPolicy.NO_FALLBACK>`.
+    LbSubsetFallbackPolicy fallback_policy = 1 [(validate.rules).enum.defined_only = true];
+
+    // Specifies the default subset of endpoints used during fallback if
+    // fallback_policy is
+    // :ref:`DEFAULT_SUBSET<envoy_api_enum_value_Cluster.LbSubsetConfig.LbSubsetFallbackPolicy.DEFAULT_SUBSET>`.
+    // Each field in default_subset is
+    // compared to the matching LbEndpoint.Metadata under the *envoy.lb*
+    // namespace. It is valid for no hosts to match, in which case the behavior
+    // is the same as a fallback_policy of
+    // :ref:`NO_FALLBACK<envoy_api_enum_value_Cluster.LbSubsetConfig.LbSubsetFallbackPolicy.NO_FALLBACK>`.
+    google.protobuf.Struct default_subset = 2;
+
+    // Specifications for subsets.
+    message LbSubsetSelector {
+      // List of keys to match with the weighted cluster metadata.
+      repeated string keys = 1;
+    }
+
+    // For each entry, LbEndpoint.Metadata's
+    // *envoy.lb* namespace is traversed and a subset is created for each unique
+    // combination of key and value. For example:
+    //
+    // .. code-block:: json
+    //
+    //   { "subset_selectors": [
+    //       { "keys": [ "version" ] },
+    //       { "keys": [ "stage", "hardware_type" ] }
+    //   ]}
+    //
+    // A subset is matched when the metadata from the selected route and
+    // weighted cluster contains the same keys and values as the subset's
+    // metadata. The same host may appear in multiple subsets.
+    repeated LbSubsetSelector subset_selectors = 3;
+
+    // If true, routing to subsets will take into account the localities and locality weights of the
+    // endpoints when making the routing decision.
+    //
+    // There are some potential pitfalls associated with enabling this feature, as the resulting
+    // traffic split after applying both a subset match and locality weights might be undesirable.
+    //
+    // Consider for example a situation in which you have 50/50 split across two localities X/Y
+    // which have 100 hosts each without subsetting. If the subset LB results in X having only 1
+    // host selected but Y having 100, then a lot more load is being dumped on the single host in X
+    // than originally anticipated in the load balancing assignment delivered via EDS.
+    bool locality_weight_aware = 4;
+
+    // When used with locality_weight_aware, scales the weight of each locality by the ratio
+    // of hosts in the subset vs hosts in the original subset. This aims to even out the load
+    // going to an individual locality if said locality is disproportionally affected by the
+    // subset predicate.
+    bool scale_locality_weight = 5;
+
+    // If true, when a fallback policy is configured and its corresponding subset fails to find
+    // a host this will cause any host to be selected instead.
+    //
+    // This is useful when using the default subset as the fallback policy, given the default
+    // subset might become empty. With this option enabled, if that happens the LB will attempt
+    // to select a host from the entire cluster.
+    bool panic_mode_any = 6;
+  }
+
+  // Configuration for load balancing subsetting.
+  LbSubsetConfig lb_subset_config = 22;
+
+  // Specific configuration for the LeastRequest load balancing policy.
+  message LeastRequestLbConfig {
+    // The number of random healthy hosts from which the host with the fewest active requests will
+    // be chosen. Defaults to 2 so that we perform two-choice selection if the field is not set.
+    google.protobuf.UInt32Value choice_count = 1 [(validate.rules).uint32.gte = 2];
+  }
+
+  // Specific configuration for the :ref:`RingHash<arch_overview_load_balancing_types_ring_hash>`
+  // load balancing policy.
+  message RingHashLbConfig {
+    // Minimum hash ring size. The larger the ring is (that is, the more hashes there are for each
+    // provided host) the better the request distribution will reflect the desired weights. Defaults
+    // to 1024 entries, and limited to 8M entries. See also
+    // :ref:`maximum_ring_size<envoy_api_field_Cluster.RingHashLbConfig.maximum_ring_size>`.
+    google.protobuf.UInt64Value minimum_ring_size = 1 [(validate.rules).uint64.lte = 8388608];
+
+    // [#not-implemented-hide:] Hide from docs.
+    message DeprecatedV1 {
+      // Defaults to false, meaning that `xxHash <https://github.com/Cyan4973/xxHash>`_
+      // is to hash hosts onto the ketama ring.
+      google.protobuf.BoolValue use_std_hash = 1;
+    }
+
+    // Deprecated settings from v1 config.
+    // [#not-implemented-hide:] Hide from docs.
+    DeprecatedV1 deprecated_v1 = 2 [deprecated = true];
+
+    // The hash function used to hash hosts onto the ketama ring.
+    enum HashFunction {
+      // Use `xxHash <https://github.com/Cyan4973/xxHash>`_, this is the default hash function.
+      XX_HASH = 0;
+      // Use `MurmurHash2 <https://sites.google.com/site/murmurhash/>`_, this is compatible with
+      // std:hash<string> in GNU libstdc++ 3.4.20 or above. This is typically the case when compiled
+      // on Linux and not macOS.
+      MURMUR_HASH_2 = 1;
+    }
+
+    // The hash function used to hash hosts onto the ketama ring. The value defaults to
+    // :ref:`XX_HASH<envoy_api_enum_value_Cluster.RingHashLbConfig.HashFunction.XX_HASH>`.
+    HashFunction hash_function = 3 [(validate.rules).enum.defined_only = true];
+
+    // Maximum hash ring size. Defaults to 8M entries, and limited to 8M entries, but can be lowered
+    // to further constrain resource use. See also
+    // :ref:`minimum_ring_size<envoy_api_field_Cluster.RingHashLbConfig.minimum_ring_size>`.
+    google.protobuf.UInt64Value maximum_ring_size = 4 [(validate.rules).uint64.lte = 8388608];
+  }
+
+  // Specific configuration for the
+  // :ref:`Original Destination <arch_overview_load_balancing_types_original_destination>`
+  // load balancing policy.
+  message OriginalDstLbConfig {
+    // When true, :ref:`x-envoy-original-dst-host
+    // <config_http_conn_man_headers_x-envoy-original-dst-host>` can be used to override destination
+    // address.
+    //
+    // .. attention::
+    //
+    //   This header isn't sanitized by default, so enabling this feature allows HTTP clients to
+    //   route traffic to arbitrary hosts and/or ports, which may have serious security
+    //   consequences.
+    bool use_http_header = 1;
+  }
+
+  // Optional configuration for the load balancing algorithm selected by
+  // LbPolicy. Currently only
+  // :ref:`RING_HASH<envoy_api_enum_value_Cluster.LbPolicy.RING_HASH>` and
+  // :ref:`LEAST_REQUEST<envoy_api_enum_value_Cluster.LbPolicy.LEAST_REQUEST>`
+  // has additional configuration options.
+  // Specifying ring_hash_lb_config or least_request_lb_config without setting the corresponding
+  // LbPolicy will generate an error at runtime.
+  oneof lb_config {
+    // Optional configuration for the Ring Hash load balancing policy.
+    RingHashLbConfig ring_hash_lb_config = 23;
+    // Optional configuration for the Original Destination load balancing policy.
+    OriginalDstLbConfig original_dst_lb_config = 34;
+    // Optional configuration for the LeastRequest load balancing policy.
+    LeastRequestLbConfig least_request_lb_config = 37;
+  }
+
+  // Common configuration for all load balancer implementations.
+  message CommonLbConfig {
+    // Configures the :ref:`healthy panic threshold <arch_overview_load_balancing_panic_threshold>`.
+    // If not specified, the default is 50%.
+    //
+    // .. note::
+    //   The specified percent will be truncated to the nearest 1%.
+    envoy.type.Percent healthy_panic_threshold = 1;
+    // Configuration for :ref:`zone aware routing
+    // <arch_overview_load_balancing_zone_aware_routing>`.
+    message ZoneAwareLbConfig {
+      // Configures percentage of requests that will be considered for zone aware routing
+      // if zone aware routing is configured. If not specified, the default is 100%.
+      // * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`.
+      // * :ref:`Zone aware routing support <arch_overview_load_balancing_zone_aware_routing>`.
+      envoy.type.Percent routing_enabled = 1;
+      // Configures minimum upstream cluster size required for zone aware routing
+      // If upstream cluster size is less than specified, zone aware routing is not performed
+      // even if zone aware routing is configured. If not specified, the default is 6.
+      // * :ref:`runtime values <config_cluster_manager_cluster_runtime_zone_routing>`.
+      // * :ref:`Zone aware routing support <arch_overview_load_balancing_zone_aware_routing>`.
+      google.protobuf.UInt64Value min_cluster_size = 2;
+    }
+    // Configuration for :ref:`locality weighted load balancing
+    // <arch_overview_load_balancing_locality_weighted_lb>`
+    message LocalityWeightedLbConfig {
+    }
+    oneof locality_config_specifier {
+      ZoneAwareLbConfig zone_aware_lb_config = 2;
+      LocalityWeightedLbConfig locality_weighted_lb_config = 3;
+    }
+    // If set, all health check/weight/metadata updates that happen within this duration will be
+    // merged and delivered in one shot when the duration expires. The start of the duration is when
+    // the first update happens. This is useful for big clusters, with potentially noisy deploys
+    // that might trigger excessive CPU usage due to a constant stream of healthcheck state changes
+    // or metadata updates. The first set of updates to be seen apply immediately (e.g.: a new
+    // cluster).
+    //
+    // If this is not set, we default to a merge window of 1000ms. To disable it, set the merge
+    // window to 0.
+    //
+    // Note: merging does not apply to cluster membership changes (e.g.: adds/removes); this is
+    // because merging those updates isn't currently safe. See
+    // https://github.com/envoyproxy/envoy/pull/3941.
+    google.protobuf.Duration update_merge_window = 4;
+  }
+
+  // Common configuration for all load balancer implementations.
+  CommonLbConfig common_lb_config = 27;
+
+  // Optional custom transport socket implementation to use for upstream connections.
+  core.TransportSocket transport_socket = 24;
+
+  // The Metadata field can be used to provide additional information about the
+  // cluster. It can be used for stats, logging, and varying filter behavior.
+  // Fields should use reverse DNS notation to denote which entity within Envoy
+  // will need the information. For instance, if the metadata is intended for
+  // the Router filter, the filter name should be specified as *envoy.router*.
+  core.Metadata metadata = 25;
+
+  enum ClusterProtocolSelection {
+    // Cluster can only operate on one of the possible upstream protocols (HTTP1.1, HTTP2).
+    // If :ref:`http2_protocol_options <envoy_api_field_Cluster.http2_protocol_options>` are
+    // present, HTTP2 will be used, otherwise HTTP1.1 will be used.
+    USE_CONFIGURED_PROTOCOL = 0;
+    // Use HTTP1.1 or HTTP2, depending on which one is used on the downstream connection.
+    USE_DOWNSTREAM_PROTOCOL = 1;
+  }
+
+  // Determines how Envoy selects the protocol used to speak to upstream hosts.
+  ClusterProtocolSelection protocol_selection = 26;
+
+  // Optional options for upstream connections.
+  envoy.api.v2.UpstreamConnectionOptions upstream_connection_options = 30;
+
+  // If an upstream host becomes unhealthy (as determined by the configured health checks
+  // or outlier detection), immediately close all connections to the failed host.
+  //
+  // .. note::
+  //
+  //   This is currently only supported for connections created by tcp_proxy.
+  //
+  // .. note::
+  //
+  //   The current implementation of this feature closes all connections immediately when
+  //   the unhealthy status is detected. If there are a large number of connections open
+  //   to an upstream host that becomes unhealthy, Envoy may spend a substantial amount of
+  //   time exclusively closing these connections, and not processing any other traffic.
+  bool close_connections_on_host_health_failure = 31;
+
+  // If this cluster uses EDS or STRICT_DNS to configure its hosts, immediately drain
+  // connections from any hosts that are removed from service discovery.
+  //
+  // This only affects behavior for hosts that are being actively health checked.
+  // If this flag is not set to true, Envoy will wait until the hosts fail active health
+  // checking before removing it from the cluster.
+  bool drain_connections_on_host_removal = 32;
+}
+
+// An extensible structure containing the address Envoy should bind to when
+// establishing upstream connections.
+message UpstreamBindConfig {
+  // The address Envoy should bind to when establishing upstream connections.
+  core.Address source_address = 1;
+}
+
+message UpstreamConnectionOptions {
+  // If set then set SO_KEEPALIVE on the socket to enable TCP Keepalives.
+  core.TcpKeepalive tcp_keepalive = 1;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/BUILD
new file mode 100644
index 0000000..ab34f59
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/BUILD
@@ -0,0 +1,35 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "circuit_breaker",
+    srcs = ["circuit_breaker.proto"],
+    visibility = [
+        "//envoy/api/v2:__pkg__",
+    ],
+    deps = [
+        "//envoy/api/v2/core:base",
+    ],
+)
+
+api_go_proto_library(
+    name = "circuit_breaker",
+    proto = ":circuit_breaker",
+    deps = [
+        "//envoy/api/v2/core:base_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "outlier_detection",
+    srcs = ["outlier_detection.proto"],
+    visibility = [
+        "//envoy/api/v2:__pkg__",
+    ],
+)
+
+api_go_proto_library(
+    name = "outlier_detection",
+    proto = ":outlier_detection",
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/circuit_breaker.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/circuit_breaker.proto
new file mode 100644
index 0000000..50b20c0
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/circuit_breaker.proto
@@ -0,0 +1,57 @@
+syntax = "proto3";
+
+package envoy.api.v2.cluster;
+
+option java_outer_classname = "CircuitBreakerProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.cluster";
+option go_package = "cluster";
+option csharp_namespace = "Envoy.Api.V2.ClusterNS";
+
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Circuit breakers]
+
+// :ref:`Circuit breaking<arch_overview_circuit_break>` settings can be
+// specified individually for each defined priority.
+message CircuitBreakers {
+
+  // A Thresholds defines CircuitBreaker settings for a
+  // :ref:`RoutingPriority<envoy_api_enum_core.RoutingPriority>`.
+  message Thresholds {
+    // The :ref:`RoutingPriority<envoy_api_enum_core.RoutingPriority>`
+    // the specified CircuitBreaker settings apply to.
+    // [#comment:TODO(htuch): add (validate.rules).enum.defined_only = true once
+    // https://github.com/lyft/protoc-gen-validate/issues/42 is resolved.]
+    core.RoutingPriority priority = 1;
+
+    // The maximum number of connections that Envoy will make to the upstream
+    // cluster. If not specified, the default is 1024.
+    google.protobuf.UInt32Value max_connections = 2;
+
+    // The maximum number of pending requests that Envoy will allow to the
+    // upstream cluster. If not specified, the default is 1024.
+    google.protobuf.UInt32Value max_pending_requests = 3;
+
+    // The maximum number of parallel requests that Envoy will make to the
+    // upstream cluster. If not specified, the default is 1024.
+    google.protobuf.UInt32Value max_requests = 4;
+
+    // The maximum number of parallel retries that Envoy will allow to the
+    // upstream cluster. If not specified, the default is 3.
+    google.protobuf.UInt32Value max_retries = 5;
+  }
+
+  // If multiple :ref:`Thresholds<envoy_api_msg_cluster.CircuitBreakers.Thresholds>`
+  // are defined with the same :ref:`RoutingPriority<envoy_api_enum_core.RoutingPriority>`,
+  // the first one in the list is used. If no Thresholds is defined for a given
+  // :ref:`RoutingPriority<envoy_api_enum_core.RoutingPriority>`, the default values
+  // are used.
+  repeated Thresholds thresholds = 1;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/outlier_detection.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/outlier_detection.proto
new file mode 100644
index 0000000..cd33cde
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/cluster/outlier_detection.proto
@@ -0,0 +1,83 @@
+syntax = "proto3";
+
+package envoy.api.v2.cluster;
+
+option java_outer_classname = "OutlierDetectionProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.cluster";
+option csharp_namespace = "Envoy.Api.V2.ClusterNS";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Outlier detection]
+
+// See the :ref:`architecture overview <arch_overview_outlier_detection>` for
+// more information on outlier detection.
+message OutlierDetection {
+  // The number of consecutive 5xx responses before a consecutive 5xx ejection
+  // occurs. Defaults to 5.
+  google.protobuf.UInt32Value consecutive_5xx = 1;
+
+  // The time interval between ejection analysis sweeps. This can result in
+  // both new ejections as well as hosts being returned to service. Defaults
+  // to 10000ms or 10s.
+  google.protobuf.Duration interval = 2 [(validate.rules).duration.gt = {}];
+
+  // The base time that a host is ejected for. The real time is equal to the
+  // base time multiplied by the number of times the host has been ejected.
+  // Defaults to 30000ms or 30s.
+  google.protobuf.Duration base_ejection_time = 3 [(validate.rules).duration.gt = {}];
+
+  // The maximum % of an upstream cluster that can be ejected due to outlier
+  // detection. Defaults to 10% but will eject at least one host regardless of the value.
+  google.protobuf.UInt32Value max_ejection_percent = 4 [(validate.rules).uint32.lte = 100];
+
+  // The % chance that a host will be actually ejected when an outlier status
+  // is detected through consecutive 5xx. This setting can be used to disable
+  // ejection or to ramp it up slowly. Defaults to 100.
+  google.protobuf.UInt32Value enforcing_consecutive_5xx = 5 [(validate.rules).uint32.lte = 100];
+
+  // The % chance that a host will be actually ejected when an outlier status
+  // is detected through success rate statistics. This setting can be used to
+  // disable ejection or to ramp it up slowly. Defaults to 100.
+  google.protobuf.UInt32Value enforcing_success_rate = 6 [(validate.rules).uint32.lte = 100];
+
+  // The number of hosts in a cluster that must have enough request volume to
+  // detect success rate outliers. If the number of hosts is less than this
+  // setting, outlier detection via success rate statistics is not performed
+  // for any host in the cluster. Defaults to 5.
+  google.protobuf.UInt32Value success_rate_minimum_hosts = 7;
+
+  // The minimum number of total requests that must be collected in one
+  // interval (as defined by the interval duration above) to include this host
+  // in success rate based outlier detection. If the volume is lower than this
+  // setting, outlier detection via success rate statistics is not performed
+  // for that host. Defaults to 100.
+  google.protobuf.UInt32Value success_rate_request_volume = 8;
+
+  // This factor is used to determine the ejection threshold for success rate
+  // outlier ejection. The ejection threshold is the difference between the
+  // mean success rate, and the product of this factor and the standard
+  // deviation of the mean success rate: mean - (stdev *
+  // success_rate_stdev_factor). This factor is divided by a thousand to get a
+  // double. That is, if the desired factor is 1.9, the runtime value should
+  // be 1900. Defaults to 1900.
+  google.protobuf.UInt32Value success_rate_stdev_factor = 9;
+
+  // The number of consecutive gateway failures (502, 503, 504 status or
+  // connection errors that are mapped to one of those status codes) before a
+  // consecutive gateway failure ejection occurs. Defaults to 5.
+  google.protobuf.UInt32Value consecutive_gateway_failure = 10;
+
+  // The % chance that a host will be actually ejected when an outlier status
+  // is detected through consecutive gateway failures. This setting can be
+  // used to disable ejection or to ramp it up slowly. Defaults to 0.
+  google.protobuf.UInt32Value enforcing_consecutive_gateway_failure = 11
+      [(validate.rules).uint32.lte = 100];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/BUILD
new file mode 100644
index 0000000..b324a8a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/BUILD
@@ -0,0 +1,132 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_grpc_library", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+package_group(
+    name = "friends",
+    includes = [
+        "//envoy/api/v2:friends",
+    ],
+    packages = [
+        "//envoy/api/v2/auth",
+        "//envoy/api/v2/cluster",
+        "//envoy/api/v2/endpoint",
+        "//envoy/api/v2/listener",
+        "//envoy/api/v2/route",
+    ],
+)
+
+api_proto_library_internal(
+    name = "address",
+    srcs = ["address.proto"],
+    visibility = [
+        ":friends",
+    ],
+    deps = [":base"],
+)
+
+api_go_proto_library(
+    name = "address",
+    proto = ":address",
+    deps = [":base_go_proto"],
+)
+
+api_proto_library_internal(
+    name = "base",
+    srcs = ["base.proto"],
+    visibility = [
+        ":friends",
+    ],
+    deps = [
+        "//envoy/type:percent",
+    ],
+)
+
+api_go_proto_library(
+    name = "base",
+    proto = ":base",
+    deps = ["//envoy/type:percent_go_proto"],
+)
+
+api_proto_library_internal(
+    name = "health_check",
+    srcs = ["health_check.proto"],
+    visibility = [
+        ":friends",
+    ],
+    deps = [
+        ":base",
+        "//envoy/type:range",
+    ],
+)
+
+api_go_proto_library(
+    name = "health_check",
+    proto = ":health_check",
+    deps = [
+        ":base_go_proto",
+        "//envoy/type:range_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "config_source",
+    srcs = ["config_source.proto"],
+    visibility = [
+        ":friends",
+    ],
+    deps = [
+        ":base",
+        ":grpc_service",
+    ],
+)
+
+api_go_proto_library(
+    name = "config_source",
+    proto = ":config_source",
+    deps = [
+        ":base_go_proto",
+        ":grpc_service_go_proto",
+    ],
+)
+
+api_go_proto_library(
+    name = "http_uri",
+    proto = ":http_uri",
+)
+
+api_proto_library_internal(
+    name = "http_uri",
+    srcs = ["http_uri.proto"],
+    visibility = [
+        ":friends",
+    ],
+)
+
+api_proto_library_internal(
+    name = "grpc_service",
+    srcs = ["grpc_service.proto"],
+    visibility = [
+        ":friends",
+    ],
+    deps = [":base"],
+)
+
+api_go_proto_library(
+    name = "grpc_service",
+    proto = ":grpc_service",
+    deps = [":base_go_proto"],
+)
+
+api_proto_library_internal(
+    name = "protocol",
+    srcs = ["protocol.proto"],
+    visibility = [
+        ":friends",
+    ],
+)
+
+api_go_proto_library(
+    name = "protocol",
+    proto = ":protocol",
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/address.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/address.proto
new file mode 100644
index 0000000..6e76f5b
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/address.proto
@@ -0,0 +1,121 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "AddressProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Network addresses]
+
+message Pipe {
+  // Unix Domain Socket path. On Linux, paths starting with '@' will use the
+  // abstract namespace. The starting '@' is replaced by a null byte by Envoy.
+  // Paths starting with '@' will result in an error in environments other than
+  // Linux.
+  string path = 1 [(validate.rules).string.min_bytes = 1];
+}
+
+message SocketAddress {
+  enum Protocol {
+    option (gogoproto.goproto_enum_prefix) = false;
+    TCP = 0;
+    // [#not-implemented-hide:]
+    UDP = 1;
+  }
+  Protocol protocol = 1 [(validate.rules).enum.defined_only = true];
+  // The address for this socket. :ref:`Listeners <config_listeners>` will bind
+  // to the address. An empty address is not allowed. Specify ``0.0.0.0`` or ``::``
+  // to bind to any address. [#comment:TODO(zuercher) reinstate when implemented:
+  // It is possible to distinguish a Listener address via the prefix/suffix matching
+  // in :ref:`FilterChainMatch <envoy_api_msg_listener.FilterChainMatch>`.] When used
+  // within an upstream :ref:`BindConfig <envoy_api_msg_core.BindConfig>`, the address
+  // controls the source address of outbound connections. For :ref:`clusters
+  // <envoy_api_msg_Cluster>`, the cluster type determines whether the
+  // address must be an IP (*STATIC* or *EDS* clusters) or a hostname resolved by DNS
+  // (*STRICT_DNS* or *LOGICAL_DNS* clusters). Address resolution can be customized
+  // via :ref:`resolver_name <envoy_api_field_core.SocketAddress.resolver_name>`.
+  string address = 2 [(validate.rules).string.min_bytes = 1];
+  oneof port_specifier {
+    option (validate.required) = true;
+    uint32 port_value = 3 [(validate.rules).uint32.lte = 65535];
+    // This is only valid if :ref:`resolver_name
+    // <envoy_api_field_core.SocketAddress.resolver_name>` is specified below and the
+    // named resolver is capable of named port resolution.
+    string named_port = 4;
+  }
+  // The name of the resolver. This must have been registered with Envoy. If this is
+  // empty, a context dependent default applies. If address is a hostname this
+  // should be set for resolution other than DNS. If the address is a concrete
+  // IP address, no resolution will occur.
+  string resolver_name = 5;
+
+  // When binding to an IPv6 address above, this enables `IPv4 compatibility
+  // <https://tools.ietf.org/html/rfc3493#page-11>`_. Binding to ``::`` will
+  // allow both IPv4 and IPv6 connections, with peer IPv4 addresses mapped into
+  // IPv6 space as ``::FFFF:<IPv4-address>``.
+  bool ipv4_compat = 6;
+}
+
+message TcpKeepalive {
+  // Maximum number of keepalive probes to send without response before deciding
+  // the connection is dead. Default is to use the OS level configuration (unless
+  // overridden, Linux defaults to 9.)
+  google.protobuf.UInt32Value keepalive_probes = 1;
+  // The number of seconds a connection needs to be idle before keep-alive probes
+  // start being sent. Default is to use the OS level configuration (unless
+  // overridden, Linux defaults to 7200s (ie 2 hours.)
+  google.protobuf.UInt32Value keepalive_time = 2;
+  // The number of seconds between keep-alive probes. Default is to use the OS
+  // level configuration (unless overridden, Linux defaults to 75s.)
+  google.protobuf.UInt32Value keepalive_interval = 3;
+}
+
+message BindConfig {
+  // The address to bind to when creating a socket.
+  SocketAddress source_address = 1
+      [(validate.rules).message.required = true, (gogoproto.nullable) = false];
+
+  // Whether to set the *IP_FREEBIND* option when creating the socket. When this
+  // flag is set to true, allows the :ref:`source_address
+  // <envoy_api_field_UpstreamBindConfig.source_address>` to be an IP address
+  // that is not configured on the system running Envoy. When this flag is set
+  // to false, the option *IP_FREEBIND* is disabled on the socket. When this
+  // flag is not set (default), the socket is not modified, i.e. the option is
+  // neither enabled nor disabled.
+  google.protobuf.BoolValue freebind = 2;
+
+  // Additional socket options that may not be present in Envoy source code or
+  // precompiled binaries.
+  repeated SocketOption socket_options = 3;
+}
+
+// Addresses specify either a logical or physical address and port, which are
+// used to tell Envoy where to bind/listen, connect to upstream and find
+// management servers.
+message Address {
+  oneof address {
+    option (validate.required) = true;
+
+    SocketAddress socket_address = 1;
+    Pipe pipe = 2;
+  }
+}
+
+// CidrRange specifies an IP Address and a prefix length to construct
+// the subnet mask for a `CIDR <https://tools.ietf.org/html/rfc4632>`_ range.
+message CidrRange {
+  // IPv4 or IPv6 address, e.g. ``192.0.0.0`` or ``2001:db8::``.
+  string address_prefix = 1 [(validate.rules).string.min_bytes = 1];
+  // Length of prefix, e.g. 0, 32.
+  google.protobuf.UInt32Value prefix_len = 2 [(validate.rules).uint32.lte = 128];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/base.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/base.proto
new file mode 100644
index 0000000..07161c5
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/base.proto
@@ -0,0 +1,256 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "BaseProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+option go_package = "core";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+import "envoy/type/percent.proto";
+
+option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: Common types]
+
+// Identifies location of where either Envoy runs or where upstream hosts run.
+message Locality {
+  // Region this :ref:`zone <envoy_api_field_core.Locality.zone>` belongs to.
+  string region = 1;
+
+  // Defines the local service zone where Envoy is running. Though optional, it
+  // should be set if discovery service routing is used and the discovery
+  // service exposes :ref:`zone data <envoy_api_field_endpoint.LocalityLbEndpoints.locality>`,
+  // either in this message or via :option:`--service-zone`. The meaning of zone
+  // is context dependent, e.g. `Availability Zone (AZ)
+  // <https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html>`_
+  // on AWS, `Zone <https://cloud.google.com/compute/docs/regions-zones/>`_ on
+  // GCP, etc.
+  string zone = 2;
+
+  // When used for locality of upstream hosts, this field further splits zone
+  // into smaller chunks of sub-zones so they can be load balanced
+  // independently.
+  string sub_zone = 3;
+}
+
+// Identifies a specific Envoy instance. The node identifier is presented to the
+// management server, which may use this identifier to distinguish per Envoy
+// configuration for serving.
+message Node {
+  // An opaque node identifier for the Envoy node. This also provides the local
+  // service node name. It should be set if any of the following features are
+  // used: :ref:`statsd <arch_overview_statistics>`, :ref:`CDS
+  // <config_cluster_manager_cds>`, and :ref:`HTTP tracing
+  // <arch_overview_tracing>`, either in this message or via
+  // :option:`--service-node`.
+  string id = 1;
+
+  // Defines the local service cluster name where Envoy is running. Though
+  // optional, it should be set if any of the following features are used:
+  // :ref:`statsd <arch_overview_statistics>`, :ref:`health check cluster
+  // verification <envoy_api_field_core.HealthCheck.HttpHealthCheck.service_name>`,
+  // :ref:`runtime override directory <envoy_api_msg_config.bootstrap.v2.Runtime>`,
+  // :ref:`user agent addition
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.add_user_agent>`,
+  // :ref:`HTTP global rate limiting <config_http_filters_rate_limit>`,
+  // :ref:`CDS <config_cluster_manager_cds>`, and :ref:`HTTP tracing
+  // <arch_overview_tracing>`, either in this message or via
+  // :option:`--service-cluster`.
+  string cluster = 2;
+
+  // Opaque metadata extending the node identifier. Envoy will pass this
+  // directly to the management server.
+  google.protobuf.Struct metadata = 3;
+
+  // Locality specifying where the Envoy instance is running.
+  Locality locality = 4;
+
+  // This is motivated by informing a management server during canary which
+  // version of Envoy is being tested in a heterogeneous fleet. This will be set
+  // by Envoy in management server RPCs.
+  string build_version = 5;
+}
+
+// Metadata provides additional inputs to filters based on matched listeners,
+// filter chains, routes and endpoints. It is structured as a map, usually from
+// filter name (in reverse DNS format) to metadata specific to the filter. Metadata
+// key-values for a filter are merged as connection and request handling occurs,
+// with later values for the same key overriding earlier values.
+//
+// An example use of metadata is providing additional values to
+// http_connection_manager in the envoy.http_connection_manager.access_log
+// namespace.
+//
+// Another example use of metadata is to per service config info in cluster metadata, which may get
+// consumed by multiple filters.
+//
+// For load balancing, Metadata provides a means to subset cluster endpoints.
+// Endpoints have a Metadata object associated and routes contain a Metadata
+// object to match against. There are some well defined metadata used today for
+// this purpose:
+//
+// * ``{"envoy.lb": {"canary": <bool> }}`` This indicates the canary status of an
+//   endpoint and is also used during header processing
+//   (x-envoy-upstream-canary) and for stats purposes.
+message Metadata {
+  // Key is the reverse DNS filter name, e.g. com.acme.widget. The envoy.*
+  // namespace is reserved for Envoy's built-in filters.
+  map<string, google.protobuf.Struct> filter_metadata = 1;
+}
+
+// Runtime derived uint32 with a default when not specified.
+message RuntimeUInt32 {
+  // Default value if runtime value is not available.
+  uint32 default_value = 2;
+
+  // Runtime key to get value for comparison. This value is used if defined.
+  string runtime_key = 3 [(validate.rules).string.min_bytes = 1];
+}
+
+// Envoy supports :ref:`upstream priority routing
+// <arch_overview_http_routing_priority>` both at the route and the virtual
+// cluster level. The current priority implementation uses different connection
+// pool and circuit breaking settings for each priority level. This means that
+// even for HTTP/2 requests, two physical connections will be used to an
+// upstream host. In the future Envoy will likely support true HTTP/2 priority
+// over a single upstream connection.
+enum RoutingPriority {
+  DEFAULT = 0;
+  HIGH = 1;
+}
+
+// HTTP request method.
+enum RequestMethod {
+  option (gogoproto.goproto_enum_prefix) = false;
+  METHOD_UNSPECIFIED = 0;
+  GET = 1;
+  HEAD = 2;
+  POST = 3;
+  PUT = 4;
+  DELETE = 5;
+  CONNECT = 6;
+  OPTIONS = 7;
+  TRACE = 8;
+}
+
+// Header name/value pair.
+message HeaderValue {
+  // Header name.
+  string key = 1 [(validate.rules).string = {min_bytes: 1, max_bytes: 16384}];
+
+  // Header value.
+  //
+  // The same :ref:`format specifier <config_access_log_format>` as used for
+  // :ref:`HTTP access logging <config_access_log>` applies here, however
+  // unknown header values are replaced with the empty string instead of `-`.
+  string value = 2 [(validate.rules).string.max_bytes = 16384];
+}
+
+// Header name/value pair plus option to control append behavior.
+message HeaderValueOption {
+  // Header name/value pair that this option applies to.
+  HeaderValue header = 1 [(validate.rules).message.required = true];
+
+  // Should the value be appended? If true (default), the value is appended to
+  // existing values.
+  google.protobuf.BoolValue append = 2;
+}
+
+// Wrapper for a set of headers.
+message HeaderMap {
+  repeated HeaderValue headers = 1;
+}
+
+// Data source consisting of either a file or an inline value.
+message DataSource {
+  oneof specifier {
+    option (validate.required) = true;
+
+    // Local filesystem data source.
+    string filename = 1 [(validate.rules).string.min_bytes = 1];
+
+    // Bytes inlined in the configuration.
+    bytes inline_bytes = 2 [(validate.rules).bytes.min_len = 1];
+
+    // String inlined in the configuration.
+    string inline_string = 3 [(validate.rules).string.min_bytes = 1];
+  }
+}
+
+// Configuration for transport socket in :ref:`listeners <config_listeners>` and
+// :ref:`clusters <envoy_api_msg_Cluster>`. If the configuration is
+// empty, a default transport socket implementation and configuration will be
+// chosen based on the platform and existence of tls_context.
+message TransportSocket {
+  // The name of the transport socket to instantiate. The name must match a supported transport
+  // socket implementation.
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Implementation specific configuration which depends on the implementation being instantiated.
+  // See the supported transport socket implementations for further documentation.
+  oneof config_type {
+    google.protobuf.Struct config = 2 [deprecated = true];
+
+    google.protobuf.Any typed_config = 3;
+  }
+}
+
+// Generic socket option message. This would be used to set socket options that
+// might not exist in upstream kernels or precompiled Envoy binaries.
+message SocketOption {
+  // An optional name to give this socket option for debugging, etc.
+  // Uniqueness is not required and no special meaning is assumed.
+  string description = 1;
+  // Corresponding to the level value passed to setsockopt, such as IPPROTO_TCP
+  int64 level = 2;
+  // The numeric name as passed to setsockopt
+  int64 name = 3;
+  oneof value {
+    option (validate.required) = true;
+
+    // Because many sockopts take an int value.
+    int64 int_value = 4;
+    // Otherwise it's a byte buffer.
+    bytes buf_value = 5;
+  }
+  enum SocketState {
+    option (gogoproto.goproto_enum_prefix) = false;
+    // Socket options are applied after socket creation but before binding the socket to a port
+    STATE_PREBIND = 0;
+    // Socket options are applied after binding the socket to a port but before calling listen()
+    STATE_BOUND = 1;
+    // Socket options are applied after calling listen()
+    STATE_LISTENING = 2;
+  }
+  // The state in which the option will be applied. When used in BindConfig
+  // STATE_PREBIND is currently the only valid value.
+  SocketState state = 6
+      [(validate.rules).message.required = true, (validate.rules).enum.defined_only = true];
+}
+
+// Runtime derived FractionalPercent with defaults for when the numerator or denominator is not
+// specified via a runtime key.
+message RuntimeFractionalPercent {
+  // Default value if the runtime value's for the numerator/denominator keys are not available.
+  envoy.type.FractionalPercent default_value = 1 [(validate.rules).message.required = true];
+
+  // Runtime key for a YAML representation of a FractionalPercent.
+  string runtime_key = 2;
+}
+
+// Identifies a specific ControlPlane instance that Envoy is connected to.
+message ControlPlane {
+  // An opaque control plane identifier that uniquely identifies an instance
+  // of control plane. This can be used to identify which control plane instance,
+  // the Envoy is connected to.
+  string identifier = 1;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/config_source.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/config_source.proto
new file mode 100644
index 0000000..8b6014d
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/config_source.proto
@@ -0,0 +1,124 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "ConfigSourceProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "envoy/api/v2/core/grpc_service.proto";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Configuration sources]
+
+// API configuration source. This identifies the API type and cluster that Envoy
+// will use to fetch an xDS API.
+message ApiConfigSource {
+  // APIs may be fetched via either REST or gRPC.
+  enum ApiType {
+    // Ideally this would be 'reserved 0' but one can't reserve the default
+    // value. Instead we throw an exception if this is ever used.
+    UNSUPPORTED_REST_LEGACY = 0 [deprecated = true];
+    // REST-JSON v2 API. The `canonical JSON encoding
+    // <https://developers.google.com/protocol-buffers/docs/proto3#json>`_ for
+    // the v2 protos is used.
+    REST = 1;
+    // gRPC v2 API.
+    GRPC = 2;
+    // Using the delta xDS gRPC service, i.e. DeltaDiscovery{Request,Response}
+    // rather than Discovery{Request,Response}. Rather than sending Envoy the entire state
+    // with every update, the xDS server only sends what has changed since the last update.
+    //
+    // DELTA_GRPC is not yet entirely implemented! Initially, only CDS is available.
+    // Do not use for other xDSes. TODO(fredlas) update/remove this warning when appropriate.
+    DELTA_GRPC = 3;
+  }
+  ApiType api_type = 1 [(validate.rules).enum.defined_only = true];
+  // Cluster names should be used only with REST. If > 1
+  // cluster is defined, clusters will be cycled through if any kind of failure
+  // occurs.
+  //
+  // .. note::
+  //
+  //  The cluster with name ``cluster_name`` must be statically defined and its
+  //  type must not be ``EDS``.
+  repeated string cluster_names = 2;
+
+  // Multiple gRPC services be provided for GRPC. If > 1 cluster is defined,
+  // services will be cycled through if any kind of failure occurs.
+  repeated GrpcService grpc_services = 4;
+
+  // For REST APIs, the delay between successive polls.
+  google.protobuf.Duration refresh_delay = 3 [(gogoproto.stdduration) = true];
+
+  // For REST APIs, the request timeout. If not set, a default value of 1s will be used.
+  google.protobuf.Duration request_timeout = 5
+      [(validate.rules).duration.gt.seconds = 0, (gogoproto.stdduration) = true];
+
+  // For GRPC APIs, the rate limit settings. If present, discovery requests made by Envoy will be
+  // rate limited.
+  RateLimitSettings rate_limit_settings = 6;
+}
+
+// Aggregated Discovery Service (ADS) options. This is currently empty, but when
+// set in :ref:`ConfigSource <envoy_api_msg_core.ConfigSource>` can be used to
+// specify that ADS is to be used.
+message AggregatedConfigSource {
+}
+
+// Rate Limit settings to be applied for discovery requests made by Envoy.
+message RateLimitSettings {
+  // Maximum number of tokens to be used for rate limiting discovery request calls. If not set, a
+  // default value of 100 will be used.
+  google.protobuf.UInt32Value max_tokens = 1;
+
+  // Rate at which tokens will be filled per second. If not set, a default fill rate of 10 tokens
+  // per second will be used.
+  google.protobuf.DoubleValue fill_rate = 2 [(validate.rules).double.gt = 0.0];
+}
+
+// Configuration for :ref:`listeners <config_listeners>`, :ref:`clusters
+// <config_cluster_manager>`, :ref:`routes
+// <envoy_api_msg_RouteConfiguration>`, :ref:`endpoints
+// <arch_overview_service_discovery>` etc. may either be sourced from the
+// filesystem or from an xDS API source. Filesystem configs are watched with
+// inotify for updates.
+message ConfigSource {
+  oneof config_source_specifier {
+    option (validate.required) = true;
+    // Path on the filesystem to source and watch for configuration updates.
+    //
+    // .. note::
+    //
+    //  The path to the source must exist at config load time.
+    //
+    // .. note::
+    //
+    //   Envoy will only watch the file path for *moves.* This is because in general only moves
+    //   are atomic. The same method of swapping files as is demonstrated in the
+    //   :ref:`runtime documentation <config_runtime_symbolic_link_swap>` can be used here also.
+    string path = 1;
+    // API configuration source.
+    ApiConfigSource api_config_source = 2;
+    // When set, ADS will be used to fetch resources. The ADS API configuration
+    // source in the bootstrap configuration is used.
+    AggregatedConfigSource ads = 3;
+  }
+
+  // Optional initialization timeout.
+  // When this timeout is specified, Envoy will wait no longer than the specified time for first
+  // config response on this xDS subscription during the :ref:`initialization process
+  // <arch_overview_initialization>`. After reaching the timeout, Envoy will move to the next
+  // initialization phase, even if the first config is not delivered yet. The timer is activated
+  // when the xDS API subscription starts, and is disarmed on first config update or on error. 0
+  // means no timeout - Envoy will wait indefinitely for the first xDS config (unless another
+  // timeout applies). Default 0.
+  google.protobuf.Duration initial_fetch_timeout = 4;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/grpc_service.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/grpc_service.proto
new file mode 100644
index 0000000..0ee84e3
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/grpc_service.proto
@@ -0,0 +1,173 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "GrpcServiceProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/empty.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: gRPC services]
+
+// gRPC service configuration. This is used by :ref:`ApiConfigSource
+// <envoy_api_msg_core.ApiConfigSource>` and filter configurations.
+message GrpcService {
+  message EnvoyGrpc {
+    // The name of the upstream gRPC cluster. SSL credentials will be supplied
+    // in the :ref:`Cluster <envoy_api_msg_Cluster>` :ref:`tls_context
+    // <envoy_api_field_Cluster.tls_context>`.
+    string cluster_name = 1 [(validate.rules).string.min_bytes = 1];
+  }
+
+  // [#proto-status: draft]
+  message GoogleGrpc {
+    // The target URI when using the `Google C++ gRPC client
+    // <https://github.com/grpc/grpc>`_. SSL credentials will be supplied in
+    // :ref:`channel_credentials <envoy_api_field_core.GrpcService.GoogleGrpc.channel_credentials>`.
+    string target_uri = 1 [(validate.rules).string.min_bytes = 1];
+
+    // See https://grpc.io/grpc/cpp/structgrpc_1_1_ssl_credentials_options.html.
+    message SslCredentials {
+      // PEM encoded server root certificates.
+      DataSource root_certs = 1;
+
+      // PEM encoded client private key.
+      DataSource private_key = 2;
+
+      // PEM encoded client certificate chain.
+      DataSource cert_chain = 3;
+    }
+
+    // Local channel credentials. Only UDS is supported for now.
+    // See https://github.com/grpc/grpc/pull/15909.
+    message GoogleLocalCredentials {
+    }
+
+    // See https://grpc.io/docs/guides/auth.html#credential-types to understand Channel and Call
+    // credential types.
+    message ChannelCredentials {
+      oneof credential_specifier {
+        option (validate.required) = true;
+        SslCredentials ssl_credentials = 1;
+
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61
+        google.protobuf.Empty google_default = 2;
+
+        GoogleLocalCredentials local_credentials = 3;
+      }
+    }
+
+    ChannelCredentials channel_credentials = 2;
+
+    message CallCredentials {
+      message ServiceAccountJWTAccessCredentials {
+        string json_key = 1;
+        uint64 token_lifetime_seconds = 2;
+      }
+
+      message GoogleIAMCredentials {
+        string authorization_token = 1;
+        string authority_selector = 2;
+      }
+
+      message MetadataCredentialsFromPlugin {
+        string name = 1;
+        oneof config_type {
+          google.protobuf.Struct config = 2 [deprecated = true];
+
+          google.protobuf.Any typed_config = 3;
+        }
+      }
+
+      oneof credential_specifier {
+        option (validate.required) = true;
+
+        // Access token credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#ad3a80da696ffdaea943f0f858d7a360d.
+        string access_token = 1;
+
+        // Google Compute Engine credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a6beb3ac70ff94bd2ebbd89b8f21d1f61
+        google.protobuf.Empty google_compute_engine = 2;
+
+        // Google refresh token credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a96901c997b91bc6513b08491e0dca37c.
+        string google_refresh_token = 3;
+
+        // Service Account JWT Access credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a92a9f959d6102461f66ee973d8e9d3aa.
+        ServiceAccountJWTAccessCredentials service_account_jwt_access = 4;
+
+        // Google IAM credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a9fc1fc101b41e680d47028166e76f9d0.
+        GoogleIAMCredentials google_iam = 5;
+
+        // Custom authenticator credentials.
+        // https://grpc.io/grpc/cpp/namespacegrpc.html#a823c6a4b19ffc71fb33e90154ee2ad07.
+        // https://grpc.io/docs/guides/auth.html#extending-grpc-to-support-other-authentication-mechanisms.
+        MetadataCredentialsFromPlugin from_plugin = 6;
+      }
+    }
+
+    // A set of call credentials that can be composed with `channel credentials
+    // <https://grpc.io/docs/guides/auth.html#credential-types>`_.
+    repeated CallCredentials call_credentials = 3;
+
+    // The human readable prefix to use when emitting statistics for the gRPC
+    // service.
+    //
+    // .. csv-table::
+    //    :header: Name, Type, Description
+    //    :widths: 1, 1, 2
+    //
+    //    streams_total, Counter, Total number of streams opened
+    //    streams_closed_<gRPC status code>, Counter, Total streams closed with <gRPC status code>
+    string stat_prefix = 4 [(validate.rules).string.min_bytes = 1];
+
+    // The name of the Google gRPC credentials factory to use. This must have been registered with
+    // Envoy. If this is empty, a default credentials factory will be used that sets up channel
+    // credentials based on other configuration parameters.
+    string credentials_factory_name = 5;
+
+    // Additional configuration for site-specific customizations of the Google
+    // gRPC library.
+    google.protobuf.Struct config = 6;
+  }
+
+  oneof target_specifier {
+    option (validate.required) = true;
+
+    // Envoy's in-built gRPC client.
+    // See the :ref:`gRPC services overview <arch_overview_grpc_services>`
+    // documentation for discussion on gRPC client selection.
+    EnvoyGrpc envoy_grpc = 1;
+
+    // `Google C++ gRPC client <https://github.com/grpc/grpc>`_
+    // See the :ref:`gRPC services overview <arch_overview_grpc_services>`
+    // documentation for discussion on gRPC client selection.
+    GoogleGrpc google_grpc = 2;
+  }
+
+  // The timeout for the gRPC request. This is the timeout for a specific
+  // request.
+  google.protobuf.Duration timeout = 3;
+
+  // Field 4 reserved due to moving credentials inside the GoogleGrpc message
+  reserved 4;
+
+  // Additional metadata to include in streams initiated to the GrpcService.
+  // This can be used for scenarios in which additional ad hoc authorization
+  // headers (e.g. `x-foo-bar: baz-key`) are to be injected.
+  repeated HeaderValue initial_metadata = 5;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/health_check.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/health_check.proto
new file mode 100644
index 0000000..1ed9fa4
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/health_check.proto
@@ -0,0 +1,266 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "HealthCheckProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/type/range.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Health check]
+// * Health checking :ref:`architecture overview <arch_overview_health_checking>`.
+// * If health checking is configured for a cluster, additional statistics are emitted. They are
+//   documented :ref:`here <config_cluster_manager_cluster_stats>`.
+
+message HealthCheck {
+  // The time to wait for a health check response. If the timeout is reached the
+  // health check attempt will be considered a failure.
+  google.protobuf.Duration timeout = 1 [
+    (validate.rules).duration = {
+      required: true,
+      gt: {seconds: 0}
+    },
+    (gogoproto.stdduration) = true
+  ];
+
+  // The interval between health checks.
+  google.protobuf.Duration interval = 2 [
+    (validate.rules).duration = {
+      required: true,
+      gt: {seconds: 0}
+    },
+    (gogoproto.stdduration) = true
+  ];
+
+  // An optional jitter amount in milliseconds. If specified, during every
+  // interval Envoy will add interval_jitter to the wait time.
+  google.protobuf.Duration interval_jitter = 3;
+
+  // An optional jitter amount as a percentage of interval_ms. If specified,
+  // during every interval Envoy will add interval_ms *
+  // interval_jitter_percent / 100 to the wait time.
+  //
+  // If interval_jitter_ms and interval_jitter_percent are both set, both of
+  // them will be used to increase the wait time.
+  uint32 interval_jitter_percent = 18;
+
+  // The number of unhealthy health checks required before a host is marked
+  // unhealthy. Note that for *http* health checking if a host responds with 503
+  // this threshold is ignored and the host is considered unhealthy immediately.
+  google.protobuf.UInt32Value unhealthy_threshold = 4;
+
+  // The number of healthy health checks required before a host is marked
+  // healthy. Note that during startup, only a single successful health check is
+  // required to mark a host healthy.
+  google.protobuf.UInt32Value healthy_threshold = 5;
+
+  // [#not-implemented-hide:] Non-serving port for health checking.
+  google.protobuf.UInt32Value alt_port = 6;
+
+  // Reuse health check connection between health checks. Default is true.
+  google.protobuf.BoolValue reuse_connection = 7;
+
+  // Describes the encoding of the payload bytes in the payload.
+  message Payload {
+    oneof payload {
+      option (validate.required) = true;
+
+      // Hex encoded payload. E.g., "000000FF".
+      string text = 1 [(validate.rules).string.min_bytes = 1];
+
+      // [#not-implemented-hide:] Binary payload.
+      bytes binary = 2;
+    }
+  }
+
+  // [#comment:next free field: 10]
+  message HttpHealthCheck {
+    // The value of the host header in the HTTP health check request. If
+    // left empty (default value), the name of the cluster this health check is associated
+    // with will be used.
+    string host = 1;
+
+    // Specifies the HTTP path that will be requested during health checking. For example
+    // */healthcheck*.
+    string path = 2 [(validate.rules).string.min_bytes = 1];
+
+    // [#not-implemented-hide:] HTTP specific payload.
+    Payload send = 3;
+
+    // [#not-implemented-hide:] HTTP specific response.
+    Payload receive = 4;
+
+    // An optional service name parameter which is used to validate the identity of
+    // the health checked cluster. See the :ref:`architecture overview
+    // <arch_overview_health_checking_identity>` for more information.
+    string service_name = 5;
+
+    // Specifies a list of HTTP headers that should be added to each request that is sent to the
+    // health checked cluster. For more information, including details on header value syntax, see
+    // the documentation on :ref:`custom request headers
+    // <config_http_conn_man_headers_custom_request_headers>`.
+    repeated core.HeaderValueOption request_headers_to_add = 6
+        [(validate.rules).repeated .max_items = 1000];
+
+    // Specifies a list of HTTP headers that should be removed from each request that is sent to the
+    // health checked cluster.
+    repeated string request_headers_to_remove = 8;
+
+    // If set, health checks will be made using http/2.
+    bool use_http2 = 7;
+
+    // Specifies a list of HTTP response statuses considered healthy. If provided, replaces default
+    // 200-only policy - 200 must be included explicitly as needed. Ranges follow half-open
+    // semantics of :ref:`Int64Range <envoy_api_msg_type.Int64Range>`.
+    repeated envoy.type.Int64Range expected_statuses = 9;
+  }
+
+  message TcpHealthCheck {
+    // Empty payloads imply a connect-only health check.
+    Payload send = 1;
+
+    // When checking the response, “fuzzy” matching is performed such that each
+    // binary block must be found, and in the order specified, but not
+    // necessarily contiguous.
+    repeated Payload receive = 2;
+  }
+
+  message RedisHealthCheck {
+    // If set, optionally perform ``EXISTS <key>`` instead of ``PING``. A return value
+    // from Redis of 0 (does not exist) is considered a passing healthcheck. A return value other
+    // than 0 is considered a failure. This allows the user to mark a Redis instance for maintenance
+    // by setting the specified key to any value and waiting for traffic to drain.
+    string key = 1;
+  }
+
+  // `grpc.health.v1.Health
+  // <https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto>`_-based
+  // healthcheck. See `gRPC doc <https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_
+  // for details.
+  message GrpcHealthCheck {
+    // An optional service name parameter which will be sent to gRPC service in
+    // `grpc.health.v1.HealthCheckRequest
+    // <https://github.com/grpc/grpc/blob/master/src/proto/grpc/health/v1/health.proto#L20>`_.
+    // message. See `gRPC health-checking overview
+    // <https://github.com/grpc/grpc/blob/master/doc/health-checking.md>`_ for more information.
+    string service_name = 1;
+
+    // The value of the :authority header in the gRPC health check request. If
+    // left empty (default value), the name of the cluster this health check is associated
+    // with will be used.
+    string authority = 2;
+  }
+
+  // Custom health check.
+  message CustomHealthCheck {
+    // The registered name of the custom health checker.
+    string name = 1 [(validate.rules).string.min_bytes = 1];
+
+    // A custom health checker specific configuration which depends on the custom health checker
+    // being instantiated. See :api:`envoy/config/health_checker` for reference.
+    oneof config_type {
+      google.protobuf.Struct config = 2 [deprecated = true];
+
+      google.protobuf.Any typed_config = 3;
+    }
+  }
+
+  oneof health_checker {
+    option (validate.required) = true;
+
+    // HTTP health check.
+    HttpHealthCheck http_health_check = 8;
+
+    // TCP health check.
+    TcpHealthCheck tcp_health_check = 9;
+
+    // gRPC health check.
+    GrpcHealthCheck grpc_health_check = 11;
+
+    // Custom health check.
+    CustomHealthCheck custom_health_check = 13;
+  }
+
+  reserved 10; // redis_health_check is deprecated by :ref:`custom_health_check
+               // <envoy_api_field_core.HealthCheck.custom_health_check>`
+  reserved "redis_health_check";
+
+  // The "no traffic interval" is a special health check interval that is used when a cluster has
+  // never had traffic routed to it. This lower interval allows cluster information to be kept up to
+  // date, without sending a potentially large amount of active health checking traffic for no
+  // reason. Once a cluster has been used for traffic routing, Envoy will shift back to using the
+  // standard health check interval that is defined. Note that this interval takes precedence over
+  // any other.
+  //
+  // The default value for "no traffic interval" is 60 seconds.
+  google.protobuf.Duration no_traffic_interval = 12 [(validate.rules).duration.gt = {}];
+
+  // The "unhealthy interval" is a health check interval that is used for hosts that are marked as
+  // unhealthy. As soon as the host is marked as healthy, Envoy will shift back to using the
+  // standard health check interval that is defined.
+  //
+  // The default value for "unhealthy interval" is the same as "interval".
+  google.protobuf.Duration unhealthy_interval = 14 [(validate.rules).duration.gt = {}];
+
+  // The "unhealthy edge interval" is a special health check interval that is used for the first
+  // health check right after a host is marked as unhealthy. For subsequent health checks
+  // Envoy will shift back to using either "unhealthy interval" if present or the standard health
+  // check interval that is defined.
+  //
+  // The default value for "unhealthy edge interval" is the same as "unhealthy interval".
+  google.protobuf.Duration unhealthy_edge_interval = 15 [(validate.rules).duration.gt = {}];
+
+  // The "healthy edge interval" is a special health check interval that is used for the first
+  // health check right after a host is marked as healthy. For subsequent health checks
+  // Envoy will shift back to using the standard health check interval that is defined.
+  //
+  // The default value for "healthy edge interval" is the same as the default interval.
+  google.protobuf.Duration healthy_edge_interval = 16 [(validate.rules).duration.gt = {}];
+
+  // Specifies the path to the :ref:`health check event log <arch_overview_health_check_logging>`.
+  // If empty, no event log will be written.
+  string event_log_path = 17;
+
+  // If set to true, health check failure events will always be logged. If set to false, only the
+  // initial health check failure event will be logged.
+  // The default value is false.
+  bool always_log_health_check_failures = 19;
+}
+
+// Endpoint health status.
+enum HealthStatus {
+  // The health status is not known. This is interpreted by Envoy as *HEALTHY*.
+  UNKNOWN = 0;
+
+  // Healthy.
+  HEALTHY = 1;
+
+  // Unhealthy.
+  UNHEALTHY = 2;
+
+  // Connection draining in progress. E.g.,
+  // `<https://aws.amazon.com/blogs/aws/elb-connection-draining-remove-instances-from-service-with-care/>`_
+  // or
+  // `<https://cloud.google.com/compute/docs/load-balancing/enabling-connection-draining>`_.
+  // This is interpreted by Envoy as *UNHEALTHY*.
+  DRAINING = 3;
+
+  // Health check timed out. This is part of HDS and is interpreted by Envoy as
+  // *UNHEALTHY*.
+  TIMEOUT = 4;
+
+  // Degraded.
+  DEGRADED = 5;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/http_uri.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/http_uri.proto
new file mode 100644
index 0000000..21c66c7
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/http_uri.proto
@@ -0,0 +1,52 @@
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "HttpUriProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "google/protobuf/duration.proto";
+import "gogoproto/gogo.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: HTTP Service URI ]
+
+// Envoy external URI descriptor
+message HttpUri {
+  // The HTTP server URI. It should be a full FQDN with protocol, host and path.
+  //
+  // Example:
+  //
+  // .. code-block:: yaml
+  //
+  //    uri: https://www.googleapis.com/oauth2/v1/certs
+  //
+  string uri = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Specify how `uri` is to be fetched. Today, this requires an explicit
+  // cluster, but in the future we may support dynamic cluster creation or
+  // inline DNS resolution. See `issue
+  // <https://github.com/envoyproxy/envoy/issues/1606>`_.
+  oneof http_upstream_type {
+    option (validate.required) = true;
+    // A cluster is created in the Envoy "cluster_manager" config
+    // section. This field specifies the cluster name.
+    //
+    // Example:
+    //
+    // .. code-block:: yaml
+    //
+    //    cluster: jwks_cluster
+    //
+    string cluster = 2 [(validate.rules).string.min_bytes = 1];
+  }
+
+  // Sets the maximum duration in milliseconds that a response can take to arrive upon request.
+  google.protobuf.Duration timeout = 3 [
+    (validate.rules).duration.gte = {},
+    (validate.rules).duration.required = true,
+    (gogoproto.stdduration) = true
+  ];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/protocol.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/protocol.proto
new file mode 100644
index 0000000..200b851
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/core/protocol.proto
@@ -0,0 +1,99 @@
+// [#protodoc-title: Protocol options]
+
+syntax = "proto3";
+
+package envoy.api.v2.core;
+
+option java_outer_classname = "ProtocolProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.core";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Protocol options]
+
+// [#not-implemented-hide:]
+message TcpProtocolOptions {
+}
+
+message HttpProtocolOptions {
+  // The idle timeout for upstream connection pool connections. The idle timeout is defined as the
+  // period in which there are no active requests. If not set, there is no idle timeout. When the
+  // idle timeout is reached the connection will be closed. Note that request based timeouts mean
+  // that HTTP/2 PINGs will not keep the connection alive.
+  google.protobuf.Duration idle_timeout = 1 [(gogoproto.stdduration) = true];
+}
+
+message Http1ProtocolOptions {
+  // Handle HTTP requests with absolute URLs in the requests. These requests
+  // are generally sent by clients to forward/explicit proxies. This allows clients to configure
+  // envoy as their HTTP proxy. In Unix, for example, this is typically done by setting the
+  // *http_proxy* environment variable.
+  google.protobuf.BoolValue allow_absolute_url = 1;
+
+  // Handle incoming HTTP/1.0 and HTTP 0.9 requests.
+  // This is off by default, and not fully standards compliant. There is support for pre-HTTP/1.1
+  // style connect logic, dechunking, and handling lack of client host iff
+  // *default_host_for_http_10* is configured.
+  bool accept_http_10 = 2;
+
+  // A default host for HTTP/1.0 requests. This is highly suggested if *accept_http_10* is true as
+  // Envoy does not otherwise support HTTP/1.0 without a Host header.
+  // This is a no-op if *accept_http_10* is not true.
+  string default_host_for_http_10 = 3;
+}
+
+message Http2ProtocolOptions {
+  // `Maximum table size <https://httpwg.org/specs/rfc7541.html#rfc.section.4.2>`_
+  // (in octets) that the encoder is permitted to use for the dynamic HPACK table. Valid values
+  // range from 0 to 4294967295 (2^32 - 1) and defaults to 4096. 0 effectively disables header
+  // compression.
+  google.protobuf.UInt32Value hpack_table_size = 1;
+
+  // `Maximum concurrent streams <https://httpwg.org/specs/rfc7540.html#rfc.section.5.1.2>`_
+  // allowed for peer on one HTTP/2 connection. Valid values range from 1 to 2147483647 (2^31 - 1)
+  // and defaults to 2147483647.
+  google.protobuf.UInt32Value max_concurrent_streams = 2
+      [(validate.rules).uint32 = {gte: 1, lte: 2147483647}];
+
+  // `Initial stream-level flow-control window
+  // <https://httpwg.org/specs/rfc7540.html#rfc.section.6.9.2>`_ size. Valid values range from 65535
+  // (2^16 - 1, HTTP/2 default) to 2147483647 (2^31 - 1, HTTP/2 maximum) and defaults to 268435456
+  // (256 * 1024 * 1024).
+  //
+  // NOTE: 65535 is the initial window size from HTTP/2 spec. We only support increasing the default
+  // window size now, so it's also the minimum.
+
+  // This field also acts as a soft limit on the number of bytes Envoy will buffer per-stream in the
+  // HTTP/2 codec buffers. Once the buffer reaches this pointer, watermark callbacks will fire to
+  // stop the flow of data to the codec buffers.
+  google.protobuf.UInt32Value initial_stream_window_size = 3
+      [(validate.rules).uint32 = {gte: 65535, lte: 2147483647}];
+
+  // Similar to *initial_stream_window_size*, but for connection-level flow-control
+  // window. Currently, this has the same minimum/maximum/default as *initial_stream_window_size*.
+  google.protobuf.UInt32Value initial_connection_window_size = 4
+      [(validate.rules).uint32 = {gte: 65535, lte: 2147483647}];
+
+  // Allows proxying Websocket and other upgrades over H2 connect.
+  bool allow_connect = 5;
+
+  // [#not-implemented-hide:] Hiding until envoy has full metadata support.
+  // Still under implementation. DO NOT USE.
+  //
+  // Allows metadata. See [metadata
+  // docs](https://github.com/envoyproxy/envoy/blob/master/source/docs/h2_metadata.md) for more
+  // information.
+  bool allow_metadata = 6;
+}
+
+// [#not-implemented-hide:]
+message GrpcProtocolOptions {
+  Http2ProtocolOptions http2_protocol_options = 1;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/discovery.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/discovery.proto
new file mode 100644
index 0000000..c2f74a4
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/discovery.proto
@@ -0,0 +1,208 @@
+syntax = "proto3";
+
+package envoy.api.v2;
+
+option java_outer_classname = "DiscoveryProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/any.proto";
+import "google/rpc/status.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: Common discovery API components]
+
+// A DiscoveryRequest requests a set of versioned resources of the same type for
+// a given Envoy node on some API.
+message DiscoveryRequest {
+  // The version_info provided in the request messages will be the version_info
+  // received with the most recent successfully processed response or empty on
+  // the first request. It is expected that no new request is sent after a
+  // response is received until the Envoy instance is ready to ACK/NACK the new
+  // configuration. ACK/NACK takes place by returning the new API config version
+  // as applied or the previous API config version respectively. Each type_url
+  // (see below) has an independent version associated with it.
+  string version_info = 1;
+
+  // The node making the request.
+  core.Node node = 2;
+
+  // List of resources to subscribe to, e.g. list of cluster names or a route
+  // configuration name. If this is empty, all resources for the API are
+  // returned. LDS/CDS expect empty resource_names, since this is global
+  // discovery for the Envoy instance. The LDS and CDS responses will then imply
+  // a number of resources that need to be fetched via EDS/RDS, which will be
+  // explicitly enumerated in resource_names.
+  repeated string resource_names = 3;
+
+  // Type of the resource that is being requested, e.g.
+  // "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit
+  // in requests made via singleton xDS APIs such as CDS, LDS, etc. but is
+  // required for ADS.
+  string type_url = 4;
+
+  // nonce corresponding to DiscoveryResponse being ACK/NACKed. See above
+  // discussion on version_info and the DiscoveryResponse nonce comment. This
+  // may be empty if no nonce is available, e.g. at startup or for non-stream
+  // xDS implementations.
+  string response_nonce = 5;
+
+  // This is populated when the previous :ref:`DiscoveryResponse <envoy_api_msg_DiscoveryResponse>`
+  // failed to update configuration. The *message* field in *error_details* provides the Envoy
+  // internal exception related to the failure. It is only intended for consumption during manual
+  // debugging, the string provided is not guaranteed to be stable across Envoy versions.
+  google.rpc.Status error_detail = 6;
+}
+
+message DiscoveryResponse {
+  // The version of the response data.
+  string version_info = 1;
+
+  // The response resources. These resources are typed and depend on the API being called.
+  repeated google.protobuf.Any resources = 2 [(gogoproto.nullable) = false];
+
+  // [#not-implemented-hide:]
+  // Canary is used to support two Envoy command line flags:
+  //
+  // * --terminate-on-canary-transition-failure. When set, Envoy is able to
+  //   terminate if it detects that configuration is stuck at canary. Consider
+  //   this example sequence of updates:
+  //   - Management server applies a canary config successfully.
+  //   - Management server rolls back to a production config.
+  //   - Envoy rejects the new production config.
+  //   Since there is no sensible way to continue receiving configuration
+  //   updates, Envoy will then terminate and apply production config from a
+  //   clean slate.
+  // * --dry-run-canary. When set, a canary response will never be applied, only
+  //   validated via a dry run.
+  bool canary = 3;
+
+  // Type URL for resources. This must be consistent with the type_url in the
+  // Any messages for resources if resources is non-empty. This effectively
+  // identifies the xDS API when muxing over ADS.
+  string type_url = 4;
+
+  // For gRPC based subscriptions, the nonce provides a way to explicitly ack a
+  // specific DiscoveryResponse in a following DiscoveryRequest. Additional
+  // messages may have been sent by Envoy to the management server for the
+  // previous version on the stream prior to this DiscoveryResponse, that were
+  // unprocessed at response send time. The nonce allows the management server
+  // to ignore any further DiscoveryRequests for the previous version until a
+  // DiscoveryRequest bearing the nonce. The nonce is optional and is not
+  // required for non-stream based xDS implementations.
+  string nonce = 5;
+
+  // [#not-implemented-hide:]
+  // The control plane instance that sent the response.
+  core.ControlPlane control_plane = 6;
+}
+
+// DeltaDiscoveryRequest and DeltaDiscoveryResponse are used in a new gRPC
+// endpoint for Delta xDS.
+//
+// With Delta xDS, the DeltaDiscoveryResponses do not need to include a full
+// snapshot of the tracked resources. Instead, DeltaDiscoveryResponses are a
+// diff to the state of a xDS client.
+// In Delta XDS there are per resource versions, which allow tracking state at
+// the resource granularity.
+// An xDS Delta session is always in the context of a gRPC bidirectional
+// stream. This allows the xDS server to keep track of the state of xDS clients
+// connected to it.
+//
+// In Delta xDS the nonce field is required and used to pair
+// DeltaDiscoveryResponse to a DeltaDiscoveryRequest ACK or NACK.
+// Optionally, a response message level system_version_info is present for
+// debugging purposes only.
+//
+// DeltaDiscoveryRequest can be sent in 3 situations:
+//   1. Initial message in a xDS bidirectional gRPC stream.
+//   2. As a ACK or NACK response to a previous DeltaDiscoveryResponse.
+//      In this case the response_nonce is set to the nonce value in the Response.
+//      ACK or NACK is determined by the absence or presence of error_detail.
+//   3. Spontaneous DeltaDiscoveryRequest from the client.
+//      This can be done to dynamically add or remove elements from the tracked
+//      resource_names set. In this case response_nonce must be omitted.
+message DeltaDiscoveryRequest {
+  // The node making the request.
+  core.Node node = 1;
+
+  // Type of the resource that is being requested, e.g.
+  // "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment". This is implicit
+  // in requests made via singleton xDS APIs such as CDS, LDS, etc. but is
+  // required for ADS.
+  string type_url = 2;
+
+  // DeltaDiscoveryRequests allow the client to add or remove individual
+  // resources to the set of tracked resources in the context of a stream.
+  // All resource names in the resource_names_subscribe list are added to the
+  // set of tracked resources and all resource names in the resource_names_unsubscribe
+  // list are removed from the set of tracked resources.
+  // Unlike in state-of-the-world xDS, an empty resource_names_subscribe or
+  // resource_names_unsubscribe list simply means that no resources are to be
+  // added or removed to the resource list.
+  // The xDS server must send updates for all tracked resources but can also
+  // send updates for resources the client has not subscribed to. This behavior
+  // is similar to state-of-the-world xDS.
+  // These two fields can be set for all types of DeltaDiscoveryRequests
+  // (initial, ACK/NACK or spontaneous).
+  //
+  // A list of Resource names to add to the list of tracked resources.
+  repeated string resource_names_subscribe = 3;
+
+  // A list of Resource names to remove from the list of tracked resources.
+  repeated string resource_names_unsubscribe = 4;
+
+  // This map must be populated when the DeltaDiscoveryRequest is the
+  // first in a stream (assuming there are any resources - this field's purpose is to enable
+  // a session to continue in a reconnected gRPC stream, and so will not be used in the very
+  // first stream of a session). The keys are the resources names of the xDS resources
+  // known to the xDS client. The values in the map are the associated resource
+  // level version info.
+  map<string, string> initial_resource_versions = 5;
+
+  // When the DeltaDiscoveryRequest is a ACK or NACK message in response
+  // to a previous DeltaDiscoveryResponse, the response_nonce must be the
+  // nonce in the DeltaDiscoveryResponse.
+  // Otherwise response_nonce must be omitted.
+  string response_nonce = 6;
+
+  // This is populated when the previous :ref:`DiscoveryResponse <envoy_api_msg_DiscoveryResponse>`
+  // failed to update configuration. The *message* field in *error_details*
+  // provides the Envoy internal exception related to the failure.
+  google.rpc.Status error_detail = 7;
+}
+
+message DeltaDiscoveryResponse {
+  // The version of the response data (used for debugging).
+  string system_version_info = 1;
+
+  // The response resources. These are typed resources that match the type url
+  // in the DeltaDiscoveryRequest.
+  repeated Resource resources = 2 [(gogoproto.nullable) = false];
+
+  // Resources names of resources that have be deleted and to be removed from the xDS Client.
+  // Removed resources for missing resources can be ignored.
+  repeated string removed_resources = 6;
+
+  // The nonce provides a way for DeltaDiscoveryRequests to uniquely
+  // reference a DeltaDiscoveryResponse. The nonce is required.
+  string nonce = 5;
+}
+
+message Resource {
+  // The resource's name, to distinguish it from others of the same type of resource.
+  string name = 3;
+
+  // The resource level version. It allows xDS to track the state of individual
+  // resources.
+  string version = 1;
+
+  // The resource being tracked.
+  google.protobuf.Any resource = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/eds.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/eds.proto
new file mode 100644
index 0000000..6a687ce
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/eds.proto
@@ -0,0 +1,113 @@
+syntax = "proto3";
+
+package envoy.api.v2;
+
+option java_outer_classname = "EdsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2";
+
+option java_generic_services = true;
+
+import "envoy/api/v2/discovery.proto";
+import "envoy/api/v2/endpoint/endpoint.proto";
+import "envoy/type/percent.proto";
+
+import "google/api/annotations.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+import "google/protobuf/wrappers.proto";
+
+option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: EDS]
+// Endpoint discovery :ref:`architecture overview <arch_overview_service_discovery_types_eds>`
+
+service EndpointDiscoveryService {
+  // The resource_names field in DiscoveryRequest specifies a list of clusters
+  // to subscribe to updates for.
+  rpc StreamEndpoints(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
+  }
+
+  rpc FetchEndpoints(DiscoveryRequest) returns (DiscoveryResponse) {
+    option (google.api.http) = {
+      post: "/v2/discovery:endpoints"
+      body: "*"
+    };
+  }
+}
+
+// Each route from RDS will map to a single cluster or traffic split across
+// clusters using weights expressed in the RDS WeightedCluster.
+//
+// With EDS, each cluster is treated independently from a LB perspective, with
+// LB taking place between the Localities within a cluster and at a finer
+// granularity between the hosts within a locality. For a given cluster, the
+// effective weight of a host is its load_balancing_weight multiplied by the
+// load_balancing_weight of its Locality.
+message ClusterLoadAssignment {
+  // Name of the cluster. This will be the :ref:`service_name
+  // <envoy_api_field_Cluster.EdsClusterConfig.service_name>` value if specified
+  // in the cluster :ref:`EdsClusterConfig
+  // <envoy_api_msg_Cluster.EdsClusterConfig>`.
+  string cluster_name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // List of endpoints to load balance to.
+  repeated endpoint.LocalityLbEndpoints endpoints = 2 [(gogoproto.nullable) = false];
+
+  // Map of named endpoints that can be referenced in LocalityLbEndpoints.
+  map<string, endpoint.Endpoint> named_endpoints = 5;
+
+  // Load balancing policy settings.
+  message Policy {
+    reserved 1;
+
+    message DropOverload {
+      // Identifier for the policy specifying the drop.
+      string category = 1 [(validate.rules).string.min_bytes = 1];
+
+      // Percentage of traffic that should be dropped for the category.
+      envoy.type.FractionalPercent drop_percentage = 2;
+    }
+    // Action to trim the overall incoming traffic to protect the upstream
+    // hosts. This action allows protection in case the hosts are unable to
+    // recover from an outage, or unable to autoscale or unable to handle
+    // incoming traffic volume for any reason.
+    //
+    // At the client each category is applied one after the other to generate
+    // the 'actual' drop percentage on all outgoing traffic. For example:
+    //
+    // .. code-block:: json
+    //
+    //  { "drop_overloads": [
+    //      { "category": "throttle", "drop_percentage": 60 }
+    //      { "category": "lb", "drop_percentage": 50 }
+    //  ]}
+    //
+    // The actual drop percentages applied to the traffic at the clients will be
+    //    "throttle"_drop = 60%
+    //    "lb"_drop = 20%  // 50% of the remaining 'actual' load, which is 40%.
+    //    actual_outgoing_load = 20% // remaining after applying all categories.
+    repeated DropOverload drop_overloads = 2;
+
+    // Priority levels and localities are considered overprovisioned with this
+    // factor (in percentage). This means that we don't consider a priority
+    // level or locality unhealthy until the percentage of healthy hosts
+    // multiplied by the overprovisioning factor drops below 100.
+    // With the default value 140(1.4), Envoy doesn't consider a priority level
+    // or a locality unhealthy until their percentage of healthy hosts drops
+    // below 72%. For example:
+    //
+    // .. code-block:: json
+    //
+    //  { "overprovisioning_factor": 100 }
+    //
+    // Read more at :ref:`priority levels <arch_overview_load_balancing_priority_levels>` and
+    // :ref:`localities <arch_overview_load_balancing_locality_weighted_lb>`.
+    google.protobuf.UInt32Value overprovisioning_factor = 3 [(validate.rules).uint32.gt = 0];
+  }
+
+  // Load balancing policy settings.
+  Policy policy = 4;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/BUILD
new file mode 100644
index 0000000..0dead0f
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/BUILD
@@ -0,0 +1,49 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "endpoint",
+    srcs = ["endpoint.proto"],
+    visibility = ["//envoy/api/v2:friends"],
+    deps = [
+        "//envoy/api/v2/auth:cert",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:config_source",
+        "//envoy/api/v2/core:health_check",
+        "//envoy/api/v2/core:protocol",
+    ],
+)
+
+api_go_proto_library(
+    name = "endpoint",
+    proto = ":endpoint",
+    deps = [
+        "//envoy/api/v2/auth:cert_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/core:config_source_go_proto",
+        "//envoy/api/v2/core:health_check_go_proto",
+        "//envoy/api/v2/core:protocol_go_proto",
+    ],
+)
+
+api_proto_library_internal(
+    name = "load_report",
+    srcs = ["load_report.proto"],
+    visibility = ["//envoy/api/v2:friends"],
+    deps = [
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+    ],
+)
+
+api_go_proto_library(
+    name = "load_report",
+    proto = ":load_report",
+    deps = [
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/endpoint.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/endpoint.proto
new file mode 100644
index 0000000..1d5d07f
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/endpoint.proto
@@ -0,0 +1,135 @@
+syntax = "proto3";
+
+package envoy.api.v2.endpoint;
+
+option java_outer_classname = "EndpointProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.endpoint";
+option go_package = "endpoint";
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/core/health_check.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Endpoints]
+
+// Upstream host identifier.
+message Endpoint {
+  // The upstream host address.
+  //
+  // .. attention::
+  //
+  //   The form of host address depends on the given cluster type. For STATIC or EDS,
+  //   it is expected to be a direct IP address (or something resolvable by the
+  //   specified :ref:`resolver <envoy_api_field_core.SocketAddress.resolver_name>`
+  //   in the Address). For LOGICAL or STRICT DNS, it is expected to be hostname,
+  //   and will be resolved via DNS.
+  core.Address address = 1;
+
+  // The optional health check configuration.
+  message HealthCheckConfig {
+    // Optional alternative health check port value.
+    //
+    // By default the health check address port of an upstream host is the same
+    // as the host's serving address port. This provides an alternative health
+    // check port. Setting this with a non-zero value allows an upstream host
+    // to have different health check address port.
+    uint32 port_value = 1 [(validate.rules).uint32.lte = 65535];
+  }
+
+  // The optional health check configuration is used as configuration for the
+  // health checker to contact the health checked host.
+  //
+  // .. attention::
+  //
+  //   This takes into effect only for upstream clusters with
+  //   :ref:`active health checking <arch_overview_health_checking>` enabled.
+  HealthCheckConfig health_check_config = 2;
+}
+
+// An Endpoint that Envoy can route traffic to.
+message LbEndpoint {
+  // Upstream host identifier or a named reference.
+  oneof host_identifier {
+    Endpoint endpoint = 1;
+    string endpoint_name = 5;
+  }
+
+  // Optional health status when known and supplied by EDS server.
+  core.HealthStatus health_status = 2;
+
+  // The endpoint metadata specifies values that may be used by the load
+  // balancer to select endpoints in a cluster for a given request. The filter
+  // name should be specified as *envoy.lb*. An example boolean key-value pair
+  // is *canary*, providing the optional canary status of the upstream host.
+  // This may be matched against in a route's
+  // :ref:`RouteAction <envoy_api_msg_route.RouteAction>` metadata_match field
+  // to subset the endpoints considered in cluster load balancing.
+  core.Metadata metadata = 3;
+
+  // The optional load balancing weight of the upstream host, in the range 1 -
+  // 128. Envoy uses the load balancing weight in some of the built in load
+  // balancers. The load balancing weight for an endpoint is divided by the sum
+  // of the weights of all endpoints in the endpoint's locality to produce a
+  // percentage of traffic for the endpoint. This percentage is then further
+  // weighted by the endpoint's locality's load balancing weight from
+  // LocalityLbEndpoints. If unspecified, each host is presumed to have equal
+  // weight in a locality.
+  //
+  // .. attention::
+  //
+  //   The limit of 128 is somewhat arbitrary, but is applied due to performance
+  //   concerns with the current implementation and can be removed when
+  //   `this issue <https://github.com/envoyproxy/envoy/issues/1285>`_ is fixed.
+  google.protobuf.UInt32Value load_balancing_weight = 4
+      [(validate.rules).uint32 = {gte: 1, lte: 128}];
+}
+
+// A group of endpoints belonging to a Locality.
+// One can have multiple LocalityLbEndpoints for a locality, but this is
+// generally only done if the different groups need to have different load
+// balancing weights or different priorities.
+message LocalityLbEndpoints {
+  // Identifies location of where the upstream hosts run.
+  core.Locality locality = 1;
+
+  // The group of endpoints belonging to the locality specified.
+  repeated LbEndpoint lb_endpoints = 2 [(gogoproto.nullable) = false];
+
+  // Optional: Per priority/region/zone/sub_zone weight - range 1-128. The load
+  // balancing weight for a locality is divided by the sum of the weights of all
+  // localities  at the same priority level to produce the effective percentage
+  // of traffic for the locality.
+  //
+  // Locality weights are only considered when :ref:`locality weighted load
+  // balancing <arch_overview_load_balancing_locality_weighted_lb>` is
+  // configured. These weights are ignored otherwise. If no weights are
+  // specified when locality weighted load balancing is enabled, the locality is
+  // assigned no load.
+  //
+  // .. attention::
+  //
+  //   The limit of 128 is somewhat arbitrary, but is applied due to performance
+  //   concerns with the current implementation and can be removed when
+  //   `this issue <https://github.com/envoyproxy/envoy/issues/1285>`_ is fixed.
+  google.protobuf.UInt32Value load_balancing_weight = 3
+      [(validate.rules).uint32 = {gte: 1, lte: 128}];
+
+  // Optional: the priority for this LocalityLbEndpoints. If unspecified this will
+  // default to the highest priority (0).
+  //
+  // Under usual circumstances, Envoy will only select endpoints for the highest
+  // priority (0). In the event all endpoints for a particular priority are
+  // unavailable/unhealthy, Envoy will fail over to selecting endpoints for the
+  // next highest priority group.
+  //
+  // Priorities should range from 0 (highest) to N (lowest) without skipping.
+  uint32 priority = 5 [(validate.rules).uint32 = {lte: 128}];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/load_report.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/load_report.proto
new file mode 100644
index 0000000..e862074
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/endpoint/load_report.proto
@@ -0,0 +1,163 @@
+syntax = "proto3";
+
+package envoy.api.v2.endpoint;
+
+option java_outer_classname = "LoadReportProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.endpoint";
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// These are stats Envoy reports to GLB every so often. Report frequency is
+// defined by
+// :ref:`LoadStatsResponse.load_reporting_interval<envoy_api_field_load_stats.LoadStatsResponse.load_reporting_interval>`.
+// Stats per upstream region/zone and optionally per subzone.
+// [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs.
+message UpstreamLocalityStats {
+  // Name of zone, region and optionally endpoint group these metrics were
+  // collected from. Zone and region names could be empty if unknown.
+  core.Locality locality = 1;
+
+  // The total number of requests sent by this Envoy since the last report. This
+  // information is aggregated over all the upstream Endpoints. total_requests
+  // can be inferred from:
+  //
+  // .. code-block:: none
+  //
+  //   total_requests = total_successful_requests + total_requests_in_progress +
+  //     total_error_requests
+  //
+  // The total number of requests successfully completed by the endpoints in the
+  // locality.
+  uint64 total_successful_requests = 2;
+
+  // The total number of unfinished requests
+  uint64 total_requests_in_progress = 3;
+
+  // The total number of requests that failed due to errors at the endpoint,
+  // aggregated over all endpoints in the locality.
+  uint64 total_error_requests = 4;
+
+  // Stats for multi-dimensional load balancing.
+  repeated EndpointLoadMetricStats load_metric_stats = 5;
+
+  // Endpoint granularity stats information for this locality. This information
+  // is populated if the Server requests it by setting
+  // :ref:`LoadStatsResponse.report_endpoint_granularity<envoy_api_field_load_stats.LoadStatsResponse.report_endpoint_granularity>`.
+  repeated UpstreamEndpointStats upstream_endpoint_stats = 7;
+
+  // [#not-implemented-hide:] The priority of the endpoint group these metrics
+  // were collected from.
+  uint32 priority = 6;
+}
+
+message UpstreamEndpointStats {
+  // Upstream host address.
+  core.Address address = 1;
+
+  // Opaque and implementation dependent metadata of the
+  // endpoint. Envoy will pass this directly to the management server.
+  google.protobuf.Struct metadata = 6;
+
+  // The total number of requests successfully completed by the endpoint. A
+  // single HTTP or gRPC request or stream is counted as one request. A TCP
+  // connection is also treated as one request. There is no explicit
+  // total_requests field below for an endpoint, but it may be inferred from:
+  //
+  // .. code-block:: none
+  //
+  //   total_requests = total_successful_requests + total_requests_in_progress +
+  //     total_error_requests
+  //
+  // The total number of requests successfully completed by the endpoints in the
+  // locality. These include non-5xx responses for HTTP, where errors
+  // originate at the client and the endpoint responded successfully. For gRPC,
+  // the grpc-status values are those not covered by total_error_requests below.
+  uint64 total_successful_requests = 2;
+
+  // The total number of unfinished requests for this endpoint.
+  uint64 total_requests_in_progress = 3;
+
+  // The total number of requests that failed due to errors at the endpoint.
+  // For HTTP these are responses with 5xx status codes and for gRPC the
+  // grpc-status values:
+  //
+  //   - DeadlineExceeded
+  //   - Unimplemented
+  //   - Internal
+  //   - Unavailable
+  //   - Unknown
+  //   - DataLoss
+  uint64 total_error_requests = 4;
+
+  // Stats for multi-dimensional load balancing.
+  repeated EndpointLoadMetricStats load_metric_stats = 5;
+}
+
+// [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs.
+message EndpointLoadMetricStats {
+  // Name of the metric; may be empty.
+  string metric_name = 1;
+
+  // Number of calls that finished and included this metric.
+  uint64 num_requests_finished_with_metric = 2;
+
+  // Sum of metric values across all calls that finished with this metric for
+  // load_reporting_interval.
+  double total_metric_value = 3;
+}
+
+// Per cluster load stats. Envoy reports these stats a management server in a
+// :ref:`LoadStatsRequest<envoy_api_msg_load_stats.LoadStatsRequest>`
+// [#not-implemented-hide:] Not configuration. TBD how to doc proto APIs.
+// Next ID: 7
+message ClusterStats {
+  // The name of the cluster.
+  string cluster_name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The eds_cluster_config service_name of the cluster.
+  // It's possible that two clusters send the same service_name to EDS,
+  // in that case, the management server is supposed to do aggregation on the load reports.
+  string cluster_service_name = 6;
+
+  // Need at least one.
+  repeated UpstreamLocalityStats upstream_locality_stats = 2
+      [(validate.rules).repeated .min_items = 1];
+
+  // Cluster-level stats such as total_successful_requests may be computed by
+  // summing upstream_locality_stats. In addition, below there are additional
+  // cluster-wide stats. The following total_requests equality holds at the
+  // cluster-level:
+  //
+  // .. code-block:: none
+  //
+  //   sum_locality(total_successful_requests) + sum_locality(total_requests_in_progress) +
+  //     sum_locality(total_error_requests) + total_dropped_requests`
+  //
+  // The total number of dropped requests. This covers requests
+  // deliberately dropped by the drop_overload policy and circuit breaking.
+  uint64 total_dropped_requests = 3;
+
+  message DroppedRequests {
+    // Identifier for the policy specifying the drop.
+    string category = 1 [(validate.rules).string.min_bytes = 1];
+    // Total number of deliberately dropped requests for the category.
+    uint64 dropped_count = 2;
+  }
+  // Information about deliberately dropped requests for each category specified
+  // in the DropOverload policy.
+  repeated DroppedRequests dropped_requests = 5;
+
+  // Period over which the actual load report occurred. This will be guaranteed to include every
+  // request reported. Due to system load and delays between the *LoadStatsRequest* sent from Envoy
+  // and the *LoadStatsResponse* message sent from the management server, this may be longer than
+  // the requested load reporting interval in the *LoadStatsResponse*.
+  google.protobuf.Duration load_report_interval = 4;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/lds.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/lds.proto
new file mode 100644
index 0000000..4da5a46
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/lds.proto
@@ -0,0 +1,181 @@
+syntax = "proto3";
+
+package envoy.api.v2;
+
+option java_outer_classname = "LdsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2";
+
+option java_generic_services = true;
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/discovery.proto";
+import "envoy/api/v2/listener/listener.proto";
+
+import "google/api/annotations.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Listener]
+// Listener :ref:`configuration overview <config_listeners>`
+
+// The Envoy instance initiates an RPC at startup to discover a list of
+// listeners. Updates are delivered via streaming from the LDS server and
+// consist of a complete update of all listeners. Existing connections will be
+// allowed to drain from listeners that are no longer present.
+service ListenerDiscoveryService {
+  rpc StreamListeners(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
+  }
+
+  rpc FetchListeners(DiscoveryRequest) returns (DiscoveryResponse) {
+    option (google.api.http) = {
+      post: "/v2/discovery:listeners"
+      body: "*"
+    };
+  }
+}
+
+// [#comment:next free field: 16]
+message Listener {
+  // The unique name by which this listener is known. If no name is provided,
+  // Envoy will allocate an internal UUID for the listener. If the listener is to be dynamically
+  // updated or removed via :ref:`LDS <config_listeners_lds>` a unique name must be provided.
+  // By default, the maximum length of a listener's name is limited to 60 characters. This limit can
+  // be increased by setting the :option:`--max-obj-name-len` command line argument to the desired
+  // value.
+  string name = 1;
+
+  // The address that the listener should listen on. In general, the address must be unique, though
+  // that is governed by the bind rules of the OS. E.g., multiple listeners can listen on port 0 on
+  // Linux as the actual port will be allocated by the OS.
+  core.Address address = 2 [(validate.rules).message.required = true, (gogoproto.nullable) = false];
+
+  // A list of filter chains to consider for this listener. The
+  // :ref:`FilterChain <envoy_api_msg_listener.FilterChain>` with the most specific
+  // :ref:`FilterChainMatch <envoy_api_msg_listener.FilterChainMatch>` criteria is used on a
+  // connection.
+  //
+  // Example using SNI for filter chain selection can be found in the
+  // :ref:`FAQ entry <faq_how_to_setup_sni>`.
+  repeated listener.FilterChain filter_chains = 3
+      [(validate.rules).repeated .min_items = 1, (gogoproto.nullable) = false];
+
+  // If a connection is redirected using *iptables*, the port on which the proxy
+  // receives it might be different from the original destination address. When this flag is set to
+  // true, the listener hands off redirected connections to the listener associated with the
+  // original destination address. If there is no listener associated with the original destination
+  // address, the connection is handled by the listener that receives it. Defaults to false.
+  //
+  // .. attention::
+  //
+  //   This field is deprecated. Use :ref:`an original_dst <config_listener_filters_original_dst>`
+  //   :ref:`listener filter <envoy_api_field_Listener.listener_filters>` instead.
+  //
+  //   Note that hand off to another listener is *NOT* performed without this flag. Once
+  //   :ref:`FilterChainMatch <envoy_api_msg_listener.FilterChainMatch>` is implemented this flag
+  //   will be removed, as filter chain matching can be used to select a filter chain based on the
+  //   restored destination address.
+  google.protobuf.BoolValue use_original_dst = 4 [deprecated = true];
+
+  // Soft limit on size of the listener’s new connection read and write buffers.
+  // If unspecified, an implementation defined default is applied (1MiB).
+  google.protobuf.UInt32Value per_connection_buffer_limit_bytes = 5;
+
+  // Listener metadata.
+  core.Metadata metadata = 6;
+
+  // [#not-implemented-hide:]
+  message DeprecatedV1 {
+    // Whether the listener should bind to the port. A listener that doesn't
+    // bind can only receive connections redirected from other listeners that
+    // set use_original_dst parameter to true. Default is true.
+    //
+    // [V2-API-DIFF] This is deprecated in v2, all Listeners will bind to their
+    // port. An additional filter chain must be created for every original
+    // destination port this listener may redirect to in v2, with the original
+    // port specified in the FilterChainMatch destination_port field.
+    //
+    // [#comment:TODO(PiotrSikora): Remove this once verified that we no longer need it.]
+    google.protobuf.BoolValue bind_to_port = 1;
+  }
+
+  // [#not-implemented-hide:]
+  DeprecatedV1 deprecated_v1 = 7;
+
+  enum DrainType {
+    // Drain in response to calling /healthcheck/fail admin endpoint (along with the health check
+    // filter), listener removal/modification, and hot restart.
+    DEFAULT = 0;
+    // Drain in response to listener removal/modification and hot restart. This setting does not
+    // include /healthcheck/fail. This setting may be desirable if Envoy is hosting both ingress
+    // and egress listeners.
+    MODIFY_ONLY = 1;
+  }
+
+  // The type of draining to perform at a listener-wide level.
+  DrainType drain_type = 8;
+
+  // Listener filters have the opportunity to manipulate and augment the connection metadata that
+  // is used in connection filter chain matching, for example. These filters are run before any in
+  // :ref:`filter_chains <envoy_api_field_Listener.filter_chains>`. Order matters as the
+  // filters are processed sequentially right after a socket has been accepted by the listener, and
+  // before a connection is created.
+  repeated listener.ListenerFilter listener_filters = 9 [(gogoproto.nullable) = false];
+
+  // The timeout to wait for all listener filters to complete operation. If the timeout is reached,
+  // the accepted socket is closed without a connection being created. Specify 0 to disable the
+  // timeout. If not specified, a default timeout of 15s is used.
+  google.protobuf.Duration listener_filters_timeout = 15 [(gogoproto.stdduration) = true];
+
+  // Whether the listener should be set as a transparent socket.
+  // When this flag is set to true, connections can be redirected to the listener using an
+  // *iptables* *TPROXY* target, in which case the original source and destination addresses and
+  // ports are preserved on accepted connections. This flag should be used in combination with
+  // :ref:`an original_dst <config_listener_filters_original_dst>` :ref:`listener filter
+  // <envoy_api_field_Listener.listener_filters>` to mark the connections' local addresses as
+  // "restored." This can be used to hand off each redirected connection to another listener
+  // associated with the connection's destination address. Direct connections to the socket without
+  // using *TPROXY* cannot be distinguished from connections redirected using *TPROXY* and are
+  // therefore treated as if they were redirected.
+  // When this flag is set to false, the listener's socket is explicitly reset as non-transparent.
+  // Setting this flag requires Envoy to run with the *CAP_NET_ADMIN* capability.
+  // When this flag is not set (default), the socket is not modified, i.e. the transparent option
+  // is neither set nor reset.
+  google.protobuf.BoolValue transparent = 10;
+
+  // Whether the listener should set the *IP_FREEBIND* socket option. When this
+  // flag is set to true, listeners can be bound to an IP address that is not
+  // configured on the system running Envoy. When this flag is set to false, the
+  // option *IP_FREEBIND* is disabled on the socket. When this flag is not set
+  // (default), the socket is not modified, i.e. the option is neither enabled
+  // nor disabled.
+  google.protobuf.BoolValue freebind = 11;
+
+  // Additional socket options that may not be present in Envoy source code or
+  // precompiled binaries.
+  repeated core.SocketOption socket_options = 13;
+
+  // Whether the listener should accept TCP Fast Open (TFO) connections.
+  // When this flag is set to a value greater than 0, the option TCP_FASTOPEN is enabled on
+  // the socket, with a queue length of the specified size
+  // (see `details in RFC7413 <https://tools.ietf.org/html/rfc7413#section-5.1>`_).
+  // When this flag is set to 0, the option TCP_FASTOPEN is disabled on the socket.
+  // When this flag is not set (default), the socket is not modified,
+  // i.e. the option is neither enabled nor disabled.
+  //
+  // On Linux, the net.ipv4.tcp_fastopen kernel parameter must include flag 0x2 to enable
+  // TCP_FASTOPEN.
+  // See `ip-sysctl.txt <https://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt>`_.
+  //
+  // On macOS, only values of 0, 1, and unset are valid; other values may result in an error.
+  // To set the queue length on macOS, set the net.inet.tcp.fastopen_backlog kernel parameter.
+  google.protobuf.UInt32Value tcp_fast_open_queue_length = 12;
+
+  reserved 14;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/BUILD
new file mode 100644
index 0000000..9eb0c0e
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/BUILD
@@ -0,0 +1,24 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "listener",
+    srcs = ["listener.proto"],
+    visibility = ["//envoy/api/v2:friends"],
+    deps = [
+        "//envoy/api/v2/auth:cert",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+    ],
+)
+
+api_go_proto_library(
+    name = "listener",
+    proto = ":listener",
+    deps = [
+        "//envoy/api/v2/auth:cert_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/listener.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/listener.proto
new file mode 100644
index 0000000..96b7668
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/listener/listener.proto
@@ -0,0 +1,217 @@
+syntax = "proto3";
+
+package envoy.api.v2.listener;
+
+option java_outer_classname = "ListenerProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.listener";
+option go_package = "listener";
+option csharp_namespace = "Envoy.Api.V2.ListenerNS";
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/auth/cert.proto";
+import "envoy/api/v2/core/base.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: Listener components]
+// Listener :ref:`configuration overview <config_listeners>`
+
+message Filter {
+  // The name of the filter to instantiate. The name must match a supported
+  // filter. The built-in filters are:
+  //
+  // [#comment:TODO(mattklein123): Auto generate the following list]
+  // * :ref:`envoy.client_ssl_auth<config_network_filters_client_ssl_auth>`
+  // * :ref:`envoy.echo <config_network_filters_echo>`
+  // * :ref:`envoy.http_connection_manager <config_http_conn_man>`
+  // * :ref:`envoy.mongo_proxy <config_network_filters_mongo_proxy>`
+  // * :ref:`envoy.ratelimit <config_network_filters_rate_limit>`
+  // * :ref:`envoy.redis_proxy <config_network_filters_redis_proxy>`
+  // * :ref:`envoy.tcp_proxy <config_network_filters_tcp_proxy>`
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Filter specific configuration which depends on the filter being
+  // instantiated. See the supported filters for further documentation.
+  oneof config_type {
+    google.protobuf.Struct config = 2 [deprecated = true];
+
+    google.protobuf.Any typed_config = 4;
+  }
+
+  reserved 3;
+}
+
+// Specifies the match criteria for selecting a specific filter chain for a
+// listener.
+//
+// In order for a filter chain to be selected, *ALL* of its criteria must be
+// fulfilled by the incoming connection, properties of which are set by the
+// networking stack and/or listener filters.
+//
+// The following order applies:
+//
+// 1. Destination port.
+// 2. Destination IP address.
+// 3. Server name (e.g. SNI for TLS protocol),
+// 4. Transport protocol.
+// 5. Application protocols (e.g. ALPN for TLS protocol).
+// 6. Source type (e.g. any, local or external network).
+//
+// For criteria that allow ranges or wildcards, the most specific value in any
+// of the configured filter chains that matches the incoming connection is going
+// to be used (e.g. for SNI ``www.example.com`` the most specific match would be
+// ``www.example.com``, then ``*.example.com``, then ``*.com``, then any filter
+// chain without ``server_names`` requirements).
+//
+// [#comment: Implemented rules are kept in the preference order, with deprecated fields
+// listed at the end, because that's how we want to list them in the docs.
+//
+// [#comment:TODO(PiotrSikora): Add support for configurable precedence of the rules]
+message FilterChainMatch {
+  // Optional destination port to consider when use_original_dst is set on the
+  // listener in determining a filter chain match.
+  google.protobuf.UInt32Value destination_port = 8 [(validate.rules).uint32 = {gte: 1, lte: 65535}];
+
+  // If non-empty, an IP address and prefix length to match addresses when the
+  // listener is bound to 0.0.0.0/:: or when use_original_dst is specified.
+  repeated core.CidrRange prefix_ranges = 3;
+
+  // If non-empty, an IP address and suffix length to match addresses when the
+  // listener is bound to 0.0.0.0/:: or when use_original_dst is specified.
+  // [#not-implemented-hide:]
+  string address_suffix = 4;
+
+  // [#not-implemented-hide:]
+  google.protobuf.UInt32Value suffix_len = 5;
+
+  enum ConnectionSourceType {
+    // Any connection source matches.
+    ANY = 0;
+    // Match a connection originating from the same host.
+    LOCAL = 1;
+    // Match a connection originating from a different host.
+    EXTERNAL = 2;
+  }
+
+  // Specifies the connection source IP match type. Can be any, local or external network.
+  ConnectionSourceType source_type = 12 [(validate.rules).enum.defined_only = true];
+
+  // The criteria is satisfied if the source IP address of the downstream
+  // connection is contained in at least one of the specified subnets. If the
+  // parameter is not specified or the list is empty, the source IP address is
+  // ignored.
+  // [#not-implemented-hide:]
+  repeated core.CidrRange source_prefix_ranges = 6;
+
+  // The criteria is satisfied if the source port of the downstream connection
+  // is contained in at least one of the specified ports. If the parameter is
+  // not specified, the source port is ignored.
+  // [#not-implemented-hide:]
+  repeated google.protobuf.UInt32Value source_ports = 7;
+
+  // If non-empty, a list of server names (e.g. SNI for TLS protocol) to consider when determining
+  // a filter chain match. Those values will be compared against the server names of a new
+  // connection, when detected by one of the listener filters.
+  //
+  // The server name will be matched against all wildcard domains, i.e. ``www.example.com``
+  // will be first matched against ``www.example.com``, then ``*.example.com``, then ``*.com``.
+  //
+  // Note that partial wildcards are not supported, and values like ``*w.example.com`` are invalid.
+  //
+  // .. attention::
+  //
+  //   See the :ref:`FAQ entry <faq_how_to_setup_sni>` on how to configure SNI for more
+  //   information.
+  repeated string server_names = 11;
+
+  // If non-empty, a transport protocol to consider when determining a filter chain match.
+  // This value will be compared against the transport protocol of a new connection, when
+  // it's detected by one of the listener filters.
+  //
+  // Suggested values include:
+  //
+  // * ``raw_buffer`` - default, used when no transport protocol is detected,
+  // * ``tls`` - set by :ref:`envoy.listener.tls_inspector <config_listener_filters_tls_inspector>`
+  //   when TLS protocol is detected.
+  string transport_protocol = 9;
+
+  // If non-empty, a list of application protocols (e.g. ALPN for TLS protocol) to consider when
+  // determining a filter chain match. Those values will be compared against the application
+  // protocols of a new connection, when detected by one of the listener filters.
+  //
+  // Suggested values include:
+  //
+  // * ``http/1.1`` - set by :ref:`envoy.listener.tls_inspector
+  //   <config_listener_filters_tls_inspector>`,
+  // * ``h2`` - set by :ref:`envoy.listener.tls_inspector <config_listener_filters_tls_inspector>`
+  //
+  // .. attention::
+  //
+  //   Currently, only :ref:`TLS Inspector <config_listener_filters_tls_inspector>` provides
+  //   application protocol detection based on the requested
+  //   `ALPN <https://en.wikipedia.org/wiki/Application-Layer_Protocol_Negotiation>`_ values.
+  //
+  //   However, the use of ALPN is pretty much limited to the HTTP/2 traffic on the Internet,
+  //   and matching on values other than ``h2`` is going to lead to a lot of false negatives,
+  //   unless all connecting clients are known to use ALPN.
+  repeated string application_protocols = 10;
+
+  reserved 1;
+  reserved "sni_domains";
+}
+
+// A filter chain wraps a set of match criteria, an option TLS context, a set of filters, and
+// various other parameters.
+message FilterChain {
+  // The criteria to use when matching a connection to this filter chain.
+  FilterChainMatch filter_chain_match = 1;
+
+  // The TLS context for this filter chain.
+  auth.DownstreamTlsContext tls_context = 2;
+
+  // A list of individual network filters that make up the filter chain for
+  // connections established with the listener. Order matters as the filters are
+  // processed sequentially as connection events happen. Note: If the filter
+  // list is empty, the connection will close by default.
+  repeated Filter filters = 3 [(gogoproto.nullable) = false];
+
+  // Whether the listener should expect a PROXY protocol V1 header on new
+  // connections. If this option is enabled, the listener will assume that that
+  // remote address of the connection is the one specified in the header. Some
+  // load balancers including the AWS ELB support this option. If the option is
+  // absent or set to false, Envoy will use the physical peer address of the
+  // connection as the remote address.
+  google.protobuf.BoolValue use_proxy_proto = 4;
+
+  // [#not-implemented-hide:] filter chain metadata.
+  core.Metadata metadata = 5;
+
+  // See :ref:`base.TransportSocket<envoy_api_msg_core.TransportSocket>` description.
+  core.TransportSocket transport_socket = 6;
+}
+
+message ListenerFilter {
+  // The name of the filter to instantiate. The name must match a supported
+  // filter. The built-in filters are:
+  //
+  // [#comment:TODO(mattklein123): Auto generate the following list]
+  // * :ref:`envoy.listener.original_dst <config_listener_filters_original_dst>`
+  // * :ref:`envoy.listener.tls_inspector <config_listener_filters_tls_inspector>`
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Filter specific configuration which depends on the filter being instantiated.
+  // See the supported filters for further documentation.
+  oneof config_type {
+    google.protobuf.Struct config = 2 [deprecated = true];
+
+    google.protobuf.Any typed_config = 3;
+  }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/BUILD
new file mode 100644
index 0000000..5f2a920
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/BUILD
@@ -0,0 +1,14 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "ratelimit",
+    srcs = ["ratelimit.proto"],
+    visibility = ["//envoy/api/v2:friends"],
+)
+
+api_go_proto_library(
+    name = "ratelimit",
+    proto = ":ratelimit",
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/ratelimit.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/ratelimit.proto
new file mode 100644
index 0000000..8ebec71
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/ratelimit/ratelimit.proto
@@ -0,0 +1,66 @@
+syntax = "proto3";
+
+package envoy.api.v2.ratelimit;
+
+option java_outer_classname = "RatelimitProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.ratelimit";
+option go_package = "ratelimit";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: Common rate limit components]
+
+// A RateLimitDescriptor is a list of hierarchical entries that are used by the service to
+// determine the final rate limit key and overall allowed limit. Here are some examples of how
+// they might be used for the domain "envoy".
+//
+// .. code-block:: cpp
+//
+//   ["authenticated": "false"], ["remote_address": "10.0.0.1"]
+//
+// What it does: Limits all unauthenticated traffic for the IP address 10.0.0.1. The
+// configuration supplies a default limit for the *remote_address* key. If there is a desire to
+// raise the limit for 10.0.0.1 or block it entirely it can be specified directly in the
+// configuration.
+//
+// .. code-block:: cpp
+//
+//   ["authenticated": "false"], ["path": "/foo/bar"]
+//
+// What it does: Limits all unauthenticated traffic globally for a specific path (or prefix if
+// configured that way in the service).
+//
+// .. code-block:: cpp
+//
+//   ["authenticated": "false"], ["path": "/foo/bar"], ["remote_address": "10.0.0.1"]
+//
+// What it does: Limits unauthenticated traffic to a specific path for a specific IP address.
+// Like (1) we can raise/block specific IP addresses if we want with an override configuration.
+//
+// .. code-block:: cpp
+//
+//   ["authenticated": "true"], ["client_id": "foo"]
+//
+// What it does: Limits all traffic for an authenticated client "foo"
+//
+// .. code-block:: cpp
+//
+//   ["authenticated": "true"], ["client_id": "foo"], ["path": "/foo/bar"]
+//
+// What it does: Limits traffic to a specific path for an authenticated client "foo"
+//
+// The idea behind the API is that (1)/(2)/(3) and (4)/(5) can be sent in 1 request if desired.
+// This enables building complex application scenarios with a generic backend.
+message RateLimitDescriptor {
+  message Entry {
+    // Descriptor key.
+    string key = 1 [(validate.rules).string.min_bytes = 1];
+
+    // Descriptor value.
+    string value = 2 [(validate.rules).string.min_bytes = 1];
+  }
+
+  // Descriptor entries.
+  repeated Entry entries = 1 [(validate.rules).repeated .min_items = 1];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/rds.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/rds.proto
new file mode 100644
index 0000000..d75b68a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/rds.proto
@@ -0,0 +1,104 @@
+syntax = "proto3";
+
+package envoy.api.v2;
+
+option java_outer_classname = "RdsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2";
+
+option java_generic_services = true;
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/discovery.proto";
+import "envoy/api/v2/route/route.proto";
+
+import "google/api/annotations.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+
+// [#protodoc-title: HTTP route configuration]
+// * Routing :ref:`architecture overview <arch_overview_http_routing>`
+// * HTTP :ref:`router filter <config_http_filters_router>`
+
+// The resource_names field in DiscoveryRequest specifies a route configuration.
+// This allows an Envoy configuration with multiple HTTP listeners (and
+// associated HTTP connection manager filters) to use different route
+// configurations. Each listener will bind its HTTP connection manager filter to
+// a route table via this identifier.
+service RouteDiscoveryService {
+  rpc StreamRoutes(stream DiscoveryRequest) returns (stream DiscoveryResponse) {
+  }
+
+  rpc DeltaRoutes(stream DeltaDiscoveryRequest) returns (stream DeltaDiscoveryResponse) {
+  }
+
+  rpc FetchRoutes(DiscoveryRequest) returns (DiscoveryResponse) {
+    option (google.api.http) = {
+      post: "/v2/discovery:routes"
+      body: "*"
+    };
+  }
+}
+
+// [#comment:next free field: 9]
+message RouteConfiguration {
+  // The name of the route configuration. For example, it might match
+  // :ref:`route_config_name
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.Rds.route_config_name>` in
+  // :ref:`envoy_api_msg_config.filter.network.http_connection_manager.v2.Rds`.
+  string name = 1;
+
+  // An array of virtual hosts that make up the route table.
+  repeated route.VirtualHost virtual_hosts = 2 [(gogoproto.nullable) = false];
+
+  // Optionally specifies a list of HTTP headers that the connection manager
+  // will consider to be internal only. If they are found on external requests they will be cleaned
+  // prior to filter invocation. See :ref:`config_http_conn_man_headers_x-envoy-internal` for more
+  // information.
+  repeated string internal_only_headers = 3;
+
+  // Specifies a list of HTTP headers that should be added to each response that
+  // the connection manager encodes. Headers specified at this level are applied
+  // after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or
+  // :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on
+  // header value syntax, see the documentation on :ref:`custom request headers
+  // <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption response_headers_to_add = 4
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each response
+  // that the connection manager encodes.
+  repeated string response_headers_to_remove = 5;
+
+  // Specifies a list of HTTP headers that should be added to each request
+  // routed by the HTTP connection manager. Headers specified at this level are
+  // applied after headers from any enclosed :ref:`envoy_api_msg_route.VirtualHost` or
+  // :ref:`envoy_api_msg_route.RouteAction`. For more information, including details on
+  // header value syntax, see the documentation on :ref:`custom request headers
+  // <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption request_headers_to_add = 6
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each request
+  // routed by the HTTP connection manager.
+  repeated string request_headers_to_remove = 8;
+
+  // An optional boolean that specifies whether the clusters that the route
+  // table refers to will be validated by the cluster manager. If set to true
+  // and a route refers to a non-existent cluster, the route table will not
+  // load. If set to false and a route refers to a non-existent cluster, the
+  // route table will load and the router filter will return a 404 if the route
+  // is selected at runtime. This setting defaults to true if the route table
+  // is statically defined via the :ref:`route_config
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.route_config>`
+  // option. This setting default to false if the route table is loaded dynamically via the
+  // :ref:`rds
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.rds>`
+  // option. Users may which to override the default behavior in certain cases (for example when
+  // using CDS with a static route table).
+  google.protobuf.BoolValue validate_clusters = 7;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/BUILD
new file mode 100644
index 0000000..2fec56a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/BUILD
@@ -0,0 +1,24 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "route",
+    srcs = ["route.proto"],
+    visibility = ["//envoy/api/v2:friends"],
+    deps = [
+        "//envoy/api/v2/core:base",
+        "//envoy/type:percent",
+        "//envoy/type:range",
+    ],
+)
+
+api_go_proto_library(
+    name = "route",
+    proto = ":route",
+    deps = [
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/type:percent_go_proto",
+        "//envoy/type:range_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/route.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/route.proto
new file mode 100644
index 0000000..874f42e
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/api/v2/route/route.proto
@@ -0,0 +1,1252 @@
+syntax = "proto3";
+
+package envoy.api.v2.route;
+
+option java_outer_classname = "RouteProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.api.v2.route";
+option go_package = "route";
+option java_generic_services = true;
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/type/percent.proto";
+import "envoy/type/range.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.equal_all) = true;
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: HTTP route]
+// * Routing :ref:`architecture overview <arch_overview_http_routing>`
+// * HTTP :ref:`router filter <config_http_filters_router>`
+
+// The top level element in the routing configuration is a virtual host. Each virtual host has
+// a logical name as well as a set of domains that get routed to it based on the incoming request's
+// host header. This allows a single listener to service multiple top level domain path trees. Once
+// a virtual host is selected based on the domain, the routes are processed in order to see which
+// upstream cluster to route to or whether to perform a redirect.
+// [#comment:next free field: 17]
+message VirtualHost {
+  // The logical name of the virtual host. This is used when emitting certain
+  // statistics but is not relevant for routing.
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // A list of domains (host/authority header) that will be matched to this
+  // virtual host. Wildcard hosts are supported in the form of ``*.foo.com`` or
+  // ``*-bar.foo.com``.
+  //
+  // .. note::
+  //
+  //   The wildcard will not match the empty string.
+  //   e.g. ``*-bar.foo.com`` will match ``baz-bar.foo.com`` but not ``-bar.foo.com``.
+  //   Additionally, a special entry ``*`` is allowed which will match any
+  //   host/authority header. Only a single virtual host in the entire route
+  //   configuration can match on ``*``. A domain must be unique across all virtual
+  //   hosts or the config will fail to load.
+  repeated string domains = 2 [(validate.rules).repeated .min_items = 1];
+
+  // The list of routes that will be matched, in order, for incoming requests.
+  // The first route that matches will be used.
+  repeated Route routes = 3 [(gogoproto.nullable) = false];
+
+  enum TlsRequirementType {
+    // No TLS requirement for the virtual host.
+    NONE = 0;
+
+    // External requests must use TLS. If a request is external and it is not
+    // using TLS, a 301 redirect will be sent telling the client to use HTTPS.
+    EXTERNAL_ONLY = 1;
+
+    // All requests must use TLS. If a request is not using TLS, a 301 redirect
+    // will be sent telling the client to use HTTPS.
+    ALL = 2;
+  }
+
+  // Specifies the type of TLS enforcement the virtual host expects. If this option is not
+  // specified, there is no TLS requirement for the virtual host.
+  TlsRequirementType require_tls = 4;
+
+  // A list of virtual clusters defined for this virtual host. Virtual clusters
+  // are used for additional statistics gathering.
+  repeated VirtualCluster virtual_clusters = 5;
+
+  // Specifies a set of rate limit configurations that will be applied to the
+  // virtual host.
+  repeated RateLimit rate_limits = 6;
+
+  // Specifies a list of HTTP headers that should be added to each request
+  // handled by this virtual host. Headers specified at this level are applied
+  // after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the
+  // enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
+  // details on header value syntax, see the documentation on :ref:`custom request headers
+  // <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption request_headers_to_add = 7
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each request
+  // handled by this virtual host.
+  repeated string request_headers_to_remove = 13;
+
+  // Specifies a list of HTTP headers that should be added to each response
+  // handled by this virtual host. Headers specified at this level are applied
+  // after headers from enclosed :ref:`envoy_api_msg_route.Route` and before headers from the
+  // enclosing :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
+  // details on header value syntax, see the documentation on :ref:`custom request headers
+  // <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption response_headers_to_add = 10
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each response
+  // handled by this virtual host.
+  repeated string response_headers_to_remove = 11;
+
+  // Indicates that the virtual host has a CORS policy.
+  CorsPolicy cors = 8;
+
+  reserved 9;
+
+  // The per_filter_config field can be used to provide virtual host-specific
+  // configurations for filters. The key should match the filter name, such as
+  // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+  // specific; see the :ref:`HTTP filter documentation <config_http_filters>`
+  // for if and how it is utilized.
+  map<string, google.protobuf.Struct> per_filter_config = 12 [deprecated = true];
+
+  // The per_filter_config field can be used to provide virtual host-specific
+  // configurations for filters. The key should match the filter name, such as
+  // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+  // specific; see the :ref:`HTTP filter documentation <config_http_filters>`
+  // for if and how it is utilized.
+  map<string, google.protobuf.Any> typed_per_filter_config = 15;
+
+  // Decides whether the :ref:`x-envoy-attempt-count
+  // <config_http_filters_router_x-envoy-attempt-count>` header should be included
+  // in the upstream request. Setting this option will cause it to override any existing header
+  // value, so in the case of two Envoys on the request path with this option enabled, the upstream
+  // will see the attempt count as perceived by the second Envoy. Defaults to false.
+  // This header is unaffected by the
+  // :ref:`suppress_envoy_headers
+  // <envoy_api_field_config.filter.http.router.v2.Router.suppress_envoy_headers>` flag.
+  bool include_request_attempt_count = 14;
+
+  // Indicates the retry policy for all routes in this virtual host. Note that setting a
+  // route level entry will take precedence over this config and it'll be treated
+  // independently (e.g.: values are not inherited).
+  RetryPolicy retry_policy = 16;
+
+  // Indicates the hedge policy for all routes in this virtual host. Note that setting a
+  // route level entry will take precedence over this config and it'll be treated
+  // independently (e.g.: values are not inherited).
+  // [#not-implemented-hide:]
+  HedgePolicy hedge_policy = 17;
+}
+
+// A route is both a specification of how to match a request as well as an indication of what to do
+// next (e.g., redirect, forward, rewrite, etc.).
+//
+// .. attention::
+//
+//   Envoy supports routing on HTTP method via :ref:`header matching
+//   <envoy_api_msg_route.HeaderMatcher>`.
+// [#comment:next free field: 14]
+message Route {
+  // Route matching parameters.
+  RouteMatch match = 1 [(validate.rules).message.required = true, (gogoproto.nullable) = false];
+
+  oneof action {
+    option (validate.required) = true;
+
+    // Route request to some upstream cluster.
+    RouteAction route = 2;
+
+    // Return a redirect.
+    RedirectAction redirect = 3;
+
+    // Return an arbitrary HTTP response directly, without proxying.
+    DirectResponseAction direct_response = 7;
+  }
+
+  // The Metadata field can be used to provide additional information
+  // about the route. It can be used for configuration, stats, and logging.
+  // The metadata should go under the filter namespace that will need it.
+  // For instance, if the metadata is intended for the Router filter,
+  // the filter name should be specified as *envoy.router*.
+  core.Metadata metadata = 4;
+
+  // Decorator for the matched route.
+  Decorator decorator = 5;
+
+  reserved 6;
+
+  // The per_filter_config field can be used to provide route-specific
+  // configurations for filters. The key should match the filter name, such as
+  // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+  // specific; see the :ref:`HTTP filter documentation <config_http_filters>` for
+  // if and how it is utilized.
+  map<string, google.protobuf.Struct> per_filter_config = 8 [deprecated = true];
+
+  // The per_filter_config field can be used to provide route-specific
+  // configurations for filters. The key should match the filter name, such as
+  // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+  // specific; see the :ref:`HTTP filter documentation <config_http_filters>` for
+  // if and how it is utilized.
+  map<string, google.protobuf.Any> typed_per_filter_config = 13;
+
+  // Specifies a set of headers that will be added to requests matching this
+  // route. Headers specified at this level are applied before headers from the
+  // enclosing :ref:`envoy_api_msg_route.VirtualHost` and
+  // :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
+  // header value syntax, see the documentation on :ref:`custom request headers
+  // <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption request_headers_to_add = 9
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each request
+  // matching this route.
+  repeated string request_headers_to_remove = 12;
+
+  // Specifies a set of headers that will be added to responses to requests
+  // matching this route. Headers specified at this level are applied before
+  // headers from the enclosing :ref:`envoy_api_msg_route.VirtualHost` and
+  // :ref:`envoy_api_msg_RouteConfiguration`. For more information, including
+  // details on header value syntax, see the documentation on
+  // :ref:`custom request headers <config_http_conn_man_headers_custom_request_headers>`.
+  repeated core.HeaderValueOption response_headers_to_add = 10
+      [(validate.rules).repeated .max_items = 1000];
+
+  // Specifies a list of HTTP headers that should be removed from each response
+  // to requests matching this route.
+  repeated string response_headers_to_remove = 11;
+}
+
+// Compared to the :ref:`cluster <envoy_api_field_route.RouteAction.cluster>` field that specifies a
+// single upstream cluster as the target of a request, the :ref:`weighted_clusters
+// <envoy_api_field_route.RouteAction.weighted_clusters>` option allows for specification of
+// multiple upstream clusters along with weights that indicate the percentage of
+// traffic to be forwarded to each cluster. The router selects an upstream cluster based on the
+// weights.
+// [#comment:next free field: 11]
+message WeightedCluster {
+  message ClusterWeight {
+    // Name of the upstream cluster. The cluster must exist in the
+    // :ref:`cluster manager configuration <config_cluster_manager>`.
+    string name = 1 [(validate.rules).string.min_bytes = 1];
+
+    // An integer between 0 and :ref:`total_weight
+    // <envoy_api_field_route.WeightedCluster.total_weight>`. When a request matches the route,
+    // the choice of an upstream cluster is determined by its weight. The sum of weights across all
+    // entries in the clusters array must add up to the total_weight, which defaults to 100.
+    google.protobuf.UInt32Value weight = 2;
+
+    // Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints in
+    // the upstream cluster with metadata matching what is set in this field will be considered for
+    // load balancing. Note that this will be merged with what's provided in :ref:
+    // `RouteAction.MetadataMatch <envoy_api_field_route.RouteAction.metadata_match>`, with values
+    // here taking precedence. The filter name should be specified as *envoy.lb*.
+    core.Metadata metadata_match = 3;
+
+    // Specifies a list of headers to be added to requests when this cluster is selected
+    // through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
+    // Headers specified at this level are applied before headers from the enclosing
+    // :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and
+    // :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
+    // header value syntax, see the documentation on :ref:`custom request headers
+    // <config_http_conn_man_headers_custom_request_headers>`.
+    repeated core.HeaderValueOption request_headers_to_add = 4
+        [(validate.rules).repeated .max_items = 1000];
+
+    // Specifies a list of HTTP headers that should be removed from each request when
+    // this cluster is selected through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
+    repeated string request_headers_to_remove = 9;
+
+    // Specifies a list of headers to be added to responses when this cluster is selected
+    // through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
+    // Headers specified at this level are applied before headers from the enclosing
+    // :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_route.VirtualHost`, and
+    // :ref:`envoy_api_msg_RouteConfiguration`. For more information, including details on
+    // header value syntax, see the documentation on :ref:`custom request headers
+    // <config_http_conn_man_headers_custom_request_headers>`.
+    repeated core.HeaderValueOption response_headers_to_add = 5
+        [(validate.rules).repeated .max_items = 1000];
+
+    // Specifies a list of headers to be removed from responses when this cluster is selected
+    // through the enclosing :ref:`envoy_api_msg_route.RouteAction`.
+    repeated string response_headers_to_remove = 6;
+
+    reserved 7;
+
+    // The per_filter_config field can be used to provide weighted cluster-specific
+    // configurations for filters. The key should match the filter name, such as
+    // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+    // specific; see the :ref:`HTTP filter documentation <config_http_filters>`
+    // for if and how it is utilized.
+    map<string, google.protobuf.Struct> per_filter_config = 8 [deprecated = true];
+
+    // The per_filter_config field can be used to provide weighted cluster-specific
+    // configurations for filters. The key should match the filter name, such as
+    // *envoy.buffer* for the HTTP buffer filter. Use of this field is filter
+    // specific; see the :ref:`HTTP filter documentation <config_http_filters>`
+    // for if and how it is utilized.
+    map<string, google.protobuf.Any> typed_per_filter_config = 10;
+  }
+
+  // Specifies one or more upstream clusters associated with the route.
+  repeated ClusterWeight clusters = 1 [(validate.rules).repeated .min_items = 1];
+
+  // Specifies the total weight across all clusters. The sum of all cluster weights must equal this
+  // value, which must be greater than 0. Defaults to 100.
+  google.protobuf.UInt32Value total_weight = 3 [(validate.rules).uint32.gte = 1];
+
+  // Specifies the runtime key prefix that should be used to construct the
+  // runtime keys associated with each cluster. When the *runtime_key_prefix* is
+  // specified, the router will look for weights associated with each upstream
+  // cluster under the key *runtime_key_prefix* + "." + *cluster[i].name* where
+  // *cluster[i]* denotes an entry in the clusters array field. If the runtime
+  // key for the cluster does not exist, the value specified in the
+  // 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;
+}
+
+message RouteMatch {
+  oneof path_specifier {
+    option (validate.required) = true;
+
+    // If specified, the route is a prefix rule meaning that the prefix must
+    // match the beginning of the *:path* header.
+    string prefix = 1;
+
+    // If specified, the route is an exact path rule meaning that the path must
+    // exactly match the *:path* header once the query string is removed.
+    string path = 2;
+
+    // If specified, the route is a regular expression rule meaning that the
+    // regex must match the *:path* header once the query string is removed. The entire path
+    // (without the query string) must match the regex. The rule will not match if only a
+    // subsequence of the *:path* header matches the regex. The regex grammar is defined `here
+    // <https://en.cppreference.com/w/cpp/regex/ecmascript>`_.
+    //
+    // Examples:
+    //
+    // * The regex */b[io]t* matches the path */bit*
+    // * The regex */b[io]t* matches the path */bot*
+    // * The regex */b[io]t* does not match the path */bite*
+    // * The regex */b[io]t* does not match the path */bit/bot*
+    string regex = 3 [(validate.rules).string.max_bytes = 1024];
+  }
+
+  // Indicates that prefix/path matching should be case insensitive. The default
+  // is true.
+  google.protobuf.BoolValue case_sensitive = 4;
+
+  reserved 5;
+
+  // Indicates that the route should additionally match on a runtime key. Every time the route
+  // is considered for a match, it must also fall under the percentage of matches indicated by
+  // this field. For some fraction N/D, a random number in the range [0,D) is selected. If the
+  // number is <= the value of the numerator N, or if the key is not present, the default
+  // value, the router continues to evaluate the remaining match criteria. A runtime_fraction
+  // route configuration can be used to roll out route changes in a gradual manner without full
+  // code/config deploys. Refer to the :ref:`traffic shifting
+  // <config_http_conn_man_route_table_traffic_splitting_shift>` docs for additional documentation.
+  //
+  // .. note::
+  //
+  //    Parsing this field is implemented such that the runtime key's data may be represented
+  //    as a FractionalPercent proto represented as JSON/YAML and may also be represented as an
+  //    integer with the assumption that the value is an integral percentage out of 100. For
+  //    instance, a runtime key lookup returning the value "42" would parse as a FractionalPercent
+  //    whose numerator is 42 and denominator is HUNDRED. This preserves legacy semantics.
+  core.RuntimeFractionalPercent runtime_fraction = 9;
+
+  // Specifies a set of headers that the route should match on. The router will
+  // check the request’s headers against all the specified headers in the route
+  // config. A match will happen if all the headers in the route are present in
+  // the request with the same values (or based on presence if the value field
+  // is not in the config).
+  repeated HeaderMatcher headers = 6;
+
+  // Specifies a set of URL query parameters on which the route should
+  // match. The router will check the query string from the *path* header
+  // against all the specified query parameters. If the number of specified
+  // query parameters is nonzero, they all must match the *path* header's
+  // query string for a match to occur.
+  repeated QueryParameterMatcher query_parameters = 7;
+
+  message GrpcRouteMatchOptions {
+  }
+
+  // If specified, only gRPC requests will be matched. The router will check
+  // that the content-type header has a application/grpc or one of the various
+  // application/grpc+ values.
+  GrpcRouteMatchOptions grpc = 8;
+}
+
+// [#comment:next free field: 11]
+message CorsPolicy {
+  // Specifies the origins that will be allowed to do CORS requests.
+  //
+  // An origin is allowed if either allow_origin or allow_origin_regex match.
+  repeated string allow_origin = 1;
+
+  // Specifies regex patterns that match allowed origins.
+  //
+  // An origin is allowed if either allow_origin or allow_origin_regex match.
+  repeated string allow_origin_regex = 8 [(validate.rules).repeated .items.string.max_bytes = 1024];
+
+  // Specifies the content for the *access-control-allow-methods* header.
+  string allow_methods = 2;
+
+  // Specifies the content for the *access-control-allow-headers* header.
+  string allow_headers = 3;
+
+  // Specifies the content for the *access-control-expose-headers* header.
+  string expose_headers = 4;
+
+  // Specifies the content for the *access-control-max-age* header.
+  string max_age = 5;
+
+  // Specifies whether the resource allows credentials.
+  google.protobuf.BoolValue allow_credentials = 6;
+
+  oneof enabled_specifier {
+    // Specifies if CORS is enabled. Defaults to true. Only effective on route.
+    //
+    // .. attention::
+    //
+    //   **This field is deprecated**. Set the
+    //   :ref:`filter_enabled<envoy_api_field_route.CorsPolicy.filter_enabled>` field instead.
+    google.protobuf.BoolValue enabled = 7 [deprecated = true];
+
+    // Specifies if CORS is enabled.
+    //
+    // More information on how this can be controlled via runtime can be found
+    // :ref:`here <cors-runtime>`.
+    //
+    // .. note::
+    //
+    //   This field defaults to 100/:ref:`HUNDRED
+    //   <envoy_api_enum_type.FractionalPercent.DenominatorType>`.
+    core.RuntimeFractionalPercent filter_enabled = 9;
+  }
+
+  // Specifies if CORS policies are evaluated and tracked when filter is off but
+  // does not enforce any policies.
+  //
+  // More information on how this can be controlled via runtime can be found
+  // :ref:`here <cors-runtime>`.
+  //
+  // .. note::
+  //
+  //   This field defaults to 100/:ref:`HUNDRED
+  //   <envoy_api_enum_type.FractionalPercent.DenominatorType>`.
+  core.RuntimeFractionalPercent shadow_enabled = 10;
+}
+
+// [#comment:next free field: 27]
+message RouteAction {
+  oneof cluster_specifier {
+    option (validate.required) = true;
+
+    // Indicates the upstream cluster to which the request should be routed
+    // to.
+    string cluster = 1 [(validate.rules).string.min_bytes = 1];
+
+    // Envoy will determine the cluster to route to by reading the value of the
+    // HTTP header named by cluster_header from the request headers. If the
+    // header is not found or the referenced cluster does not exist, Envoy will
+    // return a 404 response.
+    //
+    // .. attention::
+    //
+    //   Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1
+    //   *Host* header. Thus, if attempting to match on *Host*, match on *:authority* instead.
+    string cluster_header = 2 [(validate.rules).string.min_bytes = 1];
+
+    // Multiple upstream clusters can be specified for a given route. The
+    // request is routed to one of the upstream clusters based on weights
+    // assigned to each cluster. See
+    // :ref:`traffic splitting <config_http_conn_man_route_table_traffic_splitting_split>`
+    // for additional documentation.
+    WeightedCluster weighted_clusters = 3;
+  }
+
+  enum ClusterNotFoundResponseCode {
+    // HTTP status code - 503 Service Unavailable.
+    SERVICE_UNAVAILABLE = 0;
+
+    // HTTP status code - 404 Not Found.
+    NOT_FOUND = 1;
+  }
+
+  // The HTTP status code to use when configured cluster is not found.
+  // The default response code is 503 Service Unavailable.
+  ClusterNotFoundResponseCode cluster_not_found_response_code = 20
+      [(validate.rules).enum.defined_only = true];
+
+  // Optional endpoint metadata match criteria used by the subset load balancer. Only endpoints
+  // in the upstream cluster with metadata matching what's set in this field will be considered
+  // for load balancing. If using :ref:`weighted_clusters
+  // <envoy_api_field_route.RouteAction.weighted_clusters>`, metadata will be merged, with values
+  // provided there taking precedence. The filter name should be specified as *envoy.lb*.
+  core.Metadata metadata_match = 4;
+
+  // Indicates that during forwarding, the matched prefix (or path) should be
+  // swapped with this value. This option allows application URLs to be rooted
+  // at a different path from those exposed at the reverse proxy layer. The router filter will
+  // place the original path before rewrite into the :ref:`x-envoy-original-path
+  // <config_http_filters_router_x-envoy-original-path>` header.
+  //
+  // .. attention::
+  //
+  //   Pay careful attention to the use of trailing slashes in the
+  //   :ref:`route's match <envoy_api_field_route.Route.match>` prefix value.
+  //   Stripping a prefix from a path requires multiple Routes to handle all cases. For example,
+  //   rewriting */prefix* to */* and */prefix/etc* to */etc* cannot be done in a single
+  //   :ref:`Route <envoy_api_msg_route.Route>`, as shown by the below config entries:
+  //
+  //   .. code-block:: yaml
+  //
+  //     - match:
+  //         prefix: "/prefix/"
+  //       route:
+  //         prefix_rewrite: "/"
+  //     - match:
+  //         prefix: "/prefix"
+  //       route:
+  //         prefix_rewrite: "/"
+  //
+  //   Having above entries in the config, requests to */prefix* will be stripped to */*, while
+  //   requests to */prefix/etc* will be stripped to */etc*.
+  string prefix_rewrite = 5;
+
+  oneof host_rewrite_specifier {
+    // Indicates that during forwarding, the host header will be swapped with
+    // this value.
+    string host_rewrite = 6;
+
+    // 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.
+    google.protobuf.BoolValue auto_host_rewrite = 7;
+  }
+
+  // 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.
+  //
+  // .. note::
+  //
+  //   This timeout includes all retries. See also
+  //   :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`,
+  //   :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the
+  //   :ref:`retry overview <arch_overview_http_routing_retry>`.
+  google.protobuf.Duration timeout = 8 [(gogoproto.stdduration) = true];
+
+  // Specifies the idle timeout for the route. If not specified, there is no per-route idle timeout,
+  // although the connection manager wide :ref:`stream_idle_timeout
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.stream_idle_timeout>`
+  // will still apply. A value of 0 will completely disable the route's idle timeout, even if a
+  // connection manager stream idle timeout is configured.
+  //
+  // The idle timeout is distinct to :ref:`timeout
+  // <envoy_api_field_route.RouteAction.timeout>`, which provides an upper bound
+  // on the upstream response time; :ref:`idle_timeout
+  // <envoy_api_field_route.RouteAction.idle_timeout>` instead bounds the amount
+  // of time the request's stream may be idle.
+  //
+  // After header decoding, the idle timeout will apply on downstream and
+  // upstream request events. Each time an encode/decode event for headers or
+  // data is processed for the stream, the timer will be reset. If the timeout
+  // fires, the stream is terminated with a 408 Request Timeout error code if no
+  // upstream response header has been received, otherwise a stream reset
+  // occurs.
+  google.protobuf.Duration idle_timeout = 24
+      [(validate.rules).duration.gt = {}, (gogoproto.stdduration) = true];
+
+  // Indicates that the route has a retry policy. Note that if this is set,
+  // it'll take precedence over the virtual host level retry policy entirely
+  // (e.g.: policies are not merged, most internal one becomes the enforced policy).
+  RetryPolicy retry_policy = 9;
+
+  // The router is capable of shadowing traffic from one cluster to another. The current
+  // implementation is "fire and forget," meaning Envoy will not wait for the shadow cluster to
+  // respond before returning the response from the primary cluster. All normal statistics are
+  // collected for the shadow cluster making this feature useful for testing.
+  //
+  // During shadowing, the host/authority header is altered such that *-shadow* is appended. This is
+  // useful for logging. For example, *cluster1* becomes *cluster1-shadow*.
+  message RequestMirrorPolicy {
+    // Specifies the cluster that requests will be mirrored to. The cluster must
+    // exist in the cluster manager configuration.
+    string cluster = 1 [(validate.rules).string.min_bytes = 1];
+
+    // If not specified, all requests to the target cluster will be mirrored. If
+    // specified, Envoy will lookup the runtime key to get the % of requests to
+    // mirror. Valid values are from 0 to 10000, allowing for increments of
+    // 0.01% of requests to be mirrored. If the runtime key is specified in the
+    // configuration but not present in runtime, 0 is the default and thus 0% of
+    // requests will be mirrored.
+    //
+    // .. attention::
+    //
+    //   **This field is deprecated**. Set the
+    //   :ref:`runtime_fraction
+    //   <envoy_api_field_route.RouteAction.RequestMirrorPolicy.runtime_fraction>` field instead.
+    string runtime_key = 2 [deprecated = true];
+
+    // If both :ref:`runtime_key
+    // <envoy_api_field_route.RouteAction.RequestMirrorPolicy.runtime_key>` and this field are not
+    // specified, all requests to the target cluster will be mirrored.
+    //
+    // If specified, this field takes precedence over the `runtime_key` field and requests must also
+    // fall under the percentage of matches indicated by this field.
+    //
+    // For some fraction N/D, a random number in the range [0,D) is selected. If the
+    // number is <= the value of the numerator N, or if the key is not present, the default
+    // value, the request will be mirrored.
+    //
+    // .. note::
+    //
+    //   Parsing this field is implemented such that the runtime key's data may be represented
+    //   as a :ref:`FractionalPercent <envoy_api_msg_type.FractionalPercent>` proto represented
+    //   as JSON/YAML and may also be represented as an integer with the assumption that the value
+    //   is an integral percentage out of 100. For instance, a runtime key lookup returning the
+    //   value "42" would parse as a `FractionalPercent` whose numerator is 42 and denominator is
+    //   HUNDRED. This is behaviour is different to that of the deprecated `runtime_key` field,
+    //   where the implicit denominator is 10000.
+    core.RuntimeFractionalPercent runtime_fraction = 3;
+  }
+
+  // Indicates that the route has a request mirroring policy.
+  RequestMirrorPolicy request_mirror_policy = 10;
+
+  // Optionally specifies the :ref:`routing priority <arch_overview_http_routing_priority>`.
+  // [#comment:TODO(htuch): add (validate.rules).enum.defined_only = true once
+  // https://github.com/lyft/protoc-gen-validate/issues/42 is resolved.]
+  core.RoutingPriority priority = 11;
+
+  // [#not-implemented-hide:]
+  repeated core.HeaderValueOption request_headers_to_add = 12 [deprecated = true];
+
+  // [#not-implemented-hide:]
+  repeated core.HeaderValueOption response_headers_to_add = 18 [deprecated = true];
+
+  // [#not-implemented-hide:]
+  repeated string response_headers_to_remove = 19 [deprecated = true];
+
+  // Specifies a set of rate limit configurations that could be applied to the
+  // route.
+  repeated RateLimit rate_limits = 13;
+
+  // Specifies if the rate limit filter should include the virtual host rate
+  // limits. By default, if the route configured rate limits, the virtual host
+  // :ref:`rate_limits <envoy_api_field_route.VirtualHost.rate_limits>` are not applied to the
+  // request.
+  google.protobuf.BoolValue include_vh_rate_limits = 14;
+
+  // Specifies the route's hashing policy if the upstream cluster uses a hashing :ref:`load balancer
+  // <arch_overview_load_balancing_types>`.
+  message HashPolicy {
+    message Header {
+      // The name of the request header that will be used to obtain the hash
+      // key. If the request header is not present, no hash will be produced.
+      string header_name = 1 [(validate.rules).string.min_bytes = 1];
+    }
+
+    // Envoy supports two types of cookie affinity:
+    //
+    // 1. Passive. Envoy takes a cookie that's present in the cookies header and
+    //    hashes on its value.
+    //
+    // 2. Generated. Envoy generates and sets a cookie with an expiration (TTL)
+    //    on the first request from the client in its response to the client,
+    //    based on the endpoint the request gets sent to. The client then
+    //    presents this on the next and all subsequent requests. The hash of
+    //    this is sufficient to ensure these requests get sent to the same
+    //    endpoint. The cookie is generated by hashing the source and
+    //    destination ports and addresses so that multiple independent HTTP2
+    //    streams on the same connection will independently receive the same
+    //    cookie, even if they arrive at the Envoy simultaneously.
+    message Cookie {
+      // The name of the cookie that will be used to obtain the hash key. If the
+      // cookie is not present and ttl below is not set, no hash will be
+      // produced.
+      string name = 1 [(validate.rules).string.min_bytes = 1];
+
+      // If specified, a cookie with the TTL will be generated if the cookie is
+      // not present. If the TTL is present and zero, the generated cookie will
+      // be a session cookie.
+      google.protobuf.Duration ttl = 2 [(gogoproto.stdduration) = true];
+
+      // The name of the path for the cookie. If no path is specified here, no path
+      // will be set for the cookie.
+      string path = 3;
+    }
+
+    message ConnectionProperties {
+      // Hash on source IP address.
+      bool source_ip = 1;
+    }
+
+    oneof policy_specifier {
+      option (validate.required) = true;
+
+      // Header hash policy.
+      Header header = 1;
+
+      // Cookie hash policy.
+      Cookie cookie = 2;
+
+      // Connection properties hash policy.
+      ConnectionProperties connection_properties = 3;
+    }
+
+    // The flag that shortcircuits the hash computing. This field provides a
+    // 'fallback' style of configuration: "if a terminal policy doesn't work,
+    // fallback to rest of the policy list", it saves time when the terminal
+    // policy works.
+    //
+    // If true, and there is already a hash computed, ignore rest of the
+    // list of hash polices.
+    // For example, if the following hash methods are configured:
+    //
+    //  ========= ========
+    //  specifier terminal
+    //  ========= ========
+    //  Header A  true
+    //  Header B  false
+    //  Header C  false
+    //  ========= ========
+    //
+    // The generateHash process ends if policy "header A" generates a hash, as
+    // it's a terminal policy.
+    bool terminal = 4;
+  }
+
+  // Specifies a list of hash policies to use for ring hash load balancing. Each
+  // hash policy is evaluated individually and the combined result is used to
+  // route the request. The method of combination is deterministic such that
+  // identical lists of hash policies will produce the same hash. Since a hash
+  // policy examines specific parts of a request, it can fail to produce a hash
+  // (i.e. if the hashed header is not present). If (and only if) all configured
+  // hash policies fail to generate a hash, no hash will be produced for
+  // the route. In this case, the behavior is the same as if no hash policies
+  // were specified (i.e. the ring hash load balancer will choose a random
+  // backend). If a hash policy has the "terminal" attribute set to true, and
+  // there is already a hash generated, the hash is returned immediately,
+  // ignoring the rest of the hash policy list.
+  repeated HashPolicy hash_policy = 15;
+
+  reserved 16;
+  reserved 22;
+
+  // Indicates that the route has a CORS policy.
+  CorsPolicy cors = 17;
+
+  reserved 21;
+
+  // If present, and the request is a gRPC request, use the
+  // `grpc-timeout header <https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md>`_,
+  // or its default value (infinity) instead of
+  // :ref:`timeout <envoy_api_field_route.RouteAction.timeout>`, but limit the applied timeout
+  // to the maximum value specified here. If configured as 0, the maximum allowed timeout for
+  // gRPC requests is infinity. If not configured at all, the `grpc-timeout` header is not used
+  // and gRPC requests time out like any other requests using
+  // :ref:`timeout <envoy_api_field_route.RouteAction.timeout>` or its default.
+  // This can be used to prevent unexpected upstream request timeouts due to potentially long
+  // time gaps between gRPC request and response in gRPC streaming mode.
+  google.protobuf.Duration max_grpc_timeout = 23 [(gogoproto.stdduration) = true];
+
+  // Allows enabling and disabling upgrades on a per-route basis.
+  // This overrides any enabled/disabled upgrade filter chain specified in the
+  // HttpConnectionManager
+  // :ref:upgrade_configs`
+  // <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.upgrade_configs>`
+  // but does not affect any custom filter chain specified there.
+  message UpgradeConfig {
+    // The case-insensitive name of this upgrade, e.g. "websocket".
+    // For each upgrade type present in upgrade_configs, requests with
+    // Upgrade: [upgrade_type] will be proxied upstream.
+    string upgrade_type = 1;
+    // Determines if upgrades are available on this route. Defaults to true.
+    google.protobuf.BoolValue enabled = 2;
+  };
+  repeated UpgradeConfig upgrade_configs = 25;
+
+  // Configures :ref:`internal redirect <arch_overview_internal_redirects>` behavior.
+  enum InternalRedirectAction {
+    PASS_THROUGH_INTERNAL_REDIRECT = 0;
+    HANDLE_INTERNAL_REDIRECT = 1;
+  }
+  InternalRedirectAction internal_redirect_action = 26;
+
+  // Indicates that the route has a hedge policy. Note that if this is set,
+  // it'll take precedence over the virtual host level hedge policy entirely
+  // (e.g.: policies are not merged, most internal one becomes the enforced policy).
+  // [#not-implemented-hide:]
+  HedgePolicy hedge_policy = 27;
+}
+
+// HTTP retry :ref:`architecture overview <arch_overview_http_routing_retry>`.
+message RetryPolicy {
+  // Specifies the conditions under which retry takes place. These are the same
+  // conditions documented for :ref:`config_http_filters_router_x-envoy-retry-on` and
+  // :ref:`config_http_filters_router_x-envoy-retry-grpc-on`.
+  string retry_on = 1;
+
+  // Specifies the allowed number of retries. This parameter is optional and
+  // defaults to 1. These are the same conditions documented for
+  // :ref:`config_http_filters_router_x-envoy-max-retries`.
+  google.protobuf.UInt32Value num_retries = 2;
+
+  // Specifies a non-zero upstream timeout per retry attempt. This parameter is optional. The
+  // same conditions documented for
+  // :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms` apply.
+  //
+  // .. note::
+  //
+  //   If left unspecified, Envoy will use the global
+  //   :ref:`route timeout <envoy_api_field_route.RouteAction.timeout>` for the request.
+  //   Consequently, when using a :ref:`5xx <config_http_filters_router_x-envoy-retry-on>` based
+  //   retry policy, a request that times out will not be retried as the total timeout budget
+  //   would have been exhausted.
+  google.protobuf.Duration per_try_timeout = 3 [(gogoproto.stdduration) = true];
+
+  message RetryPriority {
+    string name = 1 [(validate.rules).string.min_bytes = 1];
+    oneof config_type {
+      google.protobuf.Struct config = 2 [deprecated = true];
+
+      google.protobuf.Any typed_config = 3;
+    }
+  }
+
+  // Specifies an implementation of a RetryPriority which is used to determine the
+  // distribution of load across priorities used for retries. Refer to
+  // :ref:`retry plugin configuration <arch_overview_http_retry_plugins>` for more details.
+  RetryPriority retry_priority = 4;
+
+  message RetryHostPredicate {
+    string name = 1 [(validate.rules).string.min_bytes = 1];
+    oneof config_type {
+      google.protobuf.Struct config = 2 [deprecated = true];
+
+      google.protobuf.Any typed_config = 3;
+    }
+  }
+
+  // Specifies a collection of RetryHostPredicates that will be consulted when selecting a host
+  // for retries. If any of the predicates reject the host, host selection will be reattempted.
+  // Refer to :ref:`retry plugin configuration <arch_overview_http_retry_plugins>` for more
+  // details.
+  repeated RetryHostPredicate retry_host_predicate = 5;
+
+  // The maximum number of times host selection will be reattempted before giving up, at which
+  // point the host that was last selected will be routed to. If unspecified, this will default to
+  // retrying once.
+  int64 host_selection_retry_max_attempts = 6;
+
+  // HTTP status codes that should trigger a retry in addition to those specified by retry_on.
+  repeated uint32 retriable_status_codes = 7;
+}
+
+// HTTP request hedging TODO(mpuncel) docs
+// [#not-implemented-hide:]
+message HedgePolicy {
+  // Specifies the number of initial requests that should be sent upstream.
+  // Must be at least 1.
+  // Defaults to 1.
+  google.protobuf.UInt32Value initial_requests = 1 [(validate.rules).uint32.gte = 1];
+
+  // Specifies a probability that an additional upstream request should be sent
+  // on top of what is specified by initial_requests.
+  // Defaults to 0.
+  envoy.type.FractionalPercent additional_request_chance = 2;
+
+  // Indicates that a hedged request should be sent when the per-try timeout
+  // is hit. This will only occur if the retry policy also indicates that a
+  // timed out request should be retried. Defaults to false.
+  bool hedge_on_per_try_timeout = 3;
+}
+
+message RedirectAction {
+  // When the scheme redirection take place, the following rules apply:
+  //  1. If the source URI scheme is `http` and the port is explicitly
+  //     set to `:80`, the port will be removed after the redirection
+  //  2. If the source URI scheme is `https` and the port is explicitly
+  //     set to `:443`, the port will be removed after the redirection
+  oneof scheme_rewrite_specifier {
+    // The scheme portion of the URL will be swapped with "https".
+    bool https_redirect = 4;
+    // The scheme portion of the URL will be swapped with this value.
+    string scheme_redirect = 7;
+  }
+  // The host portion of the URL will be swapped with this value.
+  string host_redirect = 1;
+  // The port value of the URL will be swapped with this value.
+  uint32 port_redirect = 8;
+
+  oneof path_rewrite_specifier {
+    // The path portion of the URL will be swapped with this value.
+    string path_redirect = 2;
+
+    // Indicates that during redirection, the matched prefix (or path)
+    // should be swapped with this value. This option allows redirect URLs be dynamically created
+    // based on the request.
+    //
+    // .. attention::
+    //
+    //   Pay attention to the use of trailing slashes as mentioned in
+    //   :ref:`RouteAction's prefix_rewrite <envoy_api_field_route.RouteAction.prefix_rewrite>`.
+    string prefix_rewrite = 5;
+  }
+
+  enum RedirectResponseCode {
+    // Moved Permanently HTTP Status Code - 301.
+    MOVED_PERMANENTLY = 0;
+
+    // Found HTTP Status Code - 302.
+    FOUND = 1;
+
+    // See Other HTTP Status Code - 303.
+    SEE_OTHER = 2;
+
+    // Temporary Redirect HTTP Status Code - 307.
+    TEMPORARY_REDIRECT = 3;
+
+    // Permanent Redirect HTTP Status Code - 308.
+    PERMANENT_REDIRECT = 4;
+  }
+
+  // The HTTP status code to use in the redirect response. The default response
+  // code is MOVED_PERMANENTLY (301).
+  RedirectResponseCode response_code = 3 [(validate.rules).enum.defined_only = true];
+
+  // Indicates that during redirection, the query portion of the URL will
+  // be removed. Default value is false.
+  bool strip_query = 6;
+}
+
+message DirectResponseAction {
+  // Specifies the HTTP response status to be returned.
+  uint32 status = 1 [(validate.rules).uint32 = {gte: 100, lt: 600}];
+
+  // Specifies the content of the response body. If this setting is omitted,
+  // no body is included in the generated response.
+  //
+  // .. note::
+  //
+  //   Headers can be specified using *response_headers_to_add* in the enclosing
+  //   :ref:`envoy_api_msg_route.Route`, :ref:`envoy_api_msg_RouteConfiguration` or
+  //   :ref:`envoy_api_msg_route.VirtualHost`.
+  core.DataSource body = 2;
+}
+
+message Decorator {
+  // The operation name associated with the request matched to this route. If tracing is
+  // enabled, this information will be used as the span name reported for this request.
+  //
+  // .. note::
+  //
+  //   For ingress (inbound) requests, or egress (outbound) responses, this value may be overridden
+  //   by the :ref:`x-envoy-decorator-operation
+  //   <config_http_filters_router_x-envoy-decorator-operation>` header.
+  string operation = 1 [(validate.rules).string.min_bytes = 1];
+}
+
+// A virtual cluster is a way of specifying a regex matching rule against
+// certain important endpoints such that statistics are generated explicitly for
+// the matched requests. The reason this is useful is that when doing
+// prefix/path matching Envoy does not always know what the application
+// considers to be an endpoint. Thus, it’s impossible for Envoy to generically
+// emit per endpoint statistics. However, often systems have highly critical
+// endpoints that they wish to get “perfect” statistics on. Virtual cluster
+// statistics are perfect in the sense that they are emitted on the downstream
+// side such that they include network level failures.
+//
+// Documentation for :ref:`virtual cluster statistics <config_http_filters_router_stats>`.
+//
+// .. note::
+//
+//    Virtual clusters are a useful tool, but we do not recommend setting up a virtual cluster for
+//    every application endpoint. This is both not easily maintainable and as well the matching and
+//    statistics output are not free.
+message VirtualCluster {
+  // Specifies a regex pattern to use for matching requests. The entire path of the request
+  // must match the regex. The regex grammar used is defined `here
+  // <https://en.cppreference.com/w/cpp/regex/ecmascript>`_.
+  //
+  // Examples:
+  //
+  // * The regex */rides/\d+* matches the path */rides/0*
+  // * The regex */rides/\d+* matches the path */rides/123*
+  // * The regex */rides/\d+* does not match the path */rides/123/456*
+  string pattern = 1 [(validate.rules).string = {min_bytes: 1, max_bytes: 1024}];
+
+  //  Specifies the name of the virtual cluster. The virtual cluster name as well
+  // as the virtual host name are used when emitting statistics. The statistics are emitted by the
+  // router filter and are documented :ref:`here <config_http_filters_router_stats>`.
+  string name = 2 [(validate.rules).string.min_bytes = 1];
+
+  // Optionally specifies the HTTP method to match on. For example GET, PUT,
+  // etc.
+  // [#comment:TODO(htuch): add (validate.rules).enum.defined_only = true once
+  // https://github.com/lyft/protoc-gen-validate/issues/42 is resolved.]
+  core.RequestMethod method = 3;
+}
+
+// Global rate limiting :ref:`architecture overview <arch_overview_rate_limit>`.
+message RateLimit {
+  // Refers to the stage set in the filter. The rate limit configuration only
+  // applies to filters with the same stage number. The default stage number is
+  // 0.
+  //
+  // .. note::
+  //
+  //   The filter supports a range of 0 - 10 inclusively for stage numbers.
+  google.protobuf.UInt32Value stage = 1 [(validate.rules).uint32.lte = 10];
+
+  // The key to be set in runtime to disable this rate limit configuration.
+  string disable_key = 2;
+
+  message Action {
+    // The following descriptor entry is appended to the descriptor:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("source_cluster", "<local service cluster>")
+    //
+    // <local service cluster> is derived from the :option:`--service-cluster` option.
+    message SourceCluster {
+    }
+
+    // The following descriptor entry is appended to the descriptor:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("destination_cluster", "<routed target cluster>")
+    //
+    // Once a request matches against a route table rule, a routed cluster is determined by one of
+    // the following :ref:`route table configuration <envoy_api_msg_RouteConfiguration>`
+    // settings:
+    //
+    // * :ref:`cluster <envoy_api_field_route.RouteAction.cluster>` indicates the upstream cluster
+    //   to route to.
+    // * :ref:`weighted_clusters <envoy_api_field_route.RouteAction.weighted_clusters>`
+    //   chooses a cluster randomly from a set of clusters with attributed weight.
+    // * :ref:`cluster_header <envoy_api_field_route.RouteAction.cluster_header>` indicates which
+    //   header in the request contains the target cluster.
+    message DestinationCluster {
+    }
+
+    // The following descriptor entry is appended when a header contains a key that matches the
+    // *header_name*:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("<descriptor_key>", "<header_value_queried_from_header>")
+    message RequestHeaders {
+      // The header name to be queried from the request headers. The header’s
+      // value is used to populate the value of the descriptor entry for the
+      // descriptor_key.
+      string header_name = 1 [(validate.rules).string.min_bytes = 1];
+
+      // The key to use in the descriptor entry.
+      string descriptor_key = 2 [(validate.rules).string.min_bytes = 1];
+    }
+
+    // The following descriptor entry is appended to the descriptor and is populated using the
+    // trusted address from :ref:`x-forwarded-for <config_http_conn_man_headers_x-forwarded-for>`:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("remote_address", "<trusted address from x-forwarded-for>")
+    message RemoteAddress {
+    }
+
+    // The following descriptor entry is appended to the descriptor:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("generic_key", "<descriptor_value>")
+    message GenericKey {
+      // The value to use in the descriptor entry.
+      string descriptor_value = 1 [(validate.rules).string.min_bytes = 1];
+    }
+
+    // The following descriptor entry is appended to the descriptor:
+    //
+    // .. code-block:: cpp
+    //
+    //   ("header_match", "<descriptor_value>")
+    message HeaderValueMatch {
+      // The value to use in the descriptor entry.
+      string descriptor_value = 1 [(validate.rules).string.min_bytes = 1];
+
+      // If set to true, the action will append a descriptor entry when the
+      // request matches the headers. If set to false, the action will append a
+      // descriptor entry when the request does not match the headers. The
+      // default value is true.
+      google.protobuf.BoolValue expect_match = 2;
+
+      // Specifies a set of headers that the rate limit action should match
+      // on. The action will check the request’s headers against all the
+      // specified headers in the config. A match will happen if all the
+      // headers in the config are present in the request with the same values
+      // (or based on presence if the value field is not in the config).
+      repeated HeaderMatcher headers = 3 [(validate.rules).repeated .min_items = 1];
+    }
+
+    oneof action_specifier {
+      option (validate.required) = true;
+
+      // Rate limit on source cluster.
+      SourceCluster source_cluster = 1;
+
+      // Rate limit on destination cluster.
+      DestinationCluster destination_cluster = 2;
+
+      // Rate limit on request headers.
+      RequestHeaders request_headers = 3;
+
+      // Rate limit on remote address.
+      RemoteAddress remote_address = 4;
+
+      // Rate limit on a generic key.
+      GenericKey generic_key = 5;
+
+      // Rate limit on the existence of request headers.
+      HeaderValueMatch header_value_match = 6;
+    }
+  }
+
+  // A list of actions that are to be applied for this rate limit configuration.
+  // Order matters as the actions are processed sequentially and the descriptor
+  // is composed by appending descriptor entries in that sequence. If an action
+  // cannot append a descriptor entry, no descriptor is generated for the
+  // configuration. See :ref:`composing actions
+  // <config_http_filters_rate_limit_composing_actions>` for additional documentation.
+  repeated Action actions = 3 [(validate.rules).repeated .min_items = 1];
+}
+
+// .. attention::
+//
+//   Internally, Envoy always uses the HTTP/2 *:authority* header to represent the HTTP/1 *Host*
+//   header. Thus, if attempting to match on *Host*, match on *:authority* instead.
+//
+// .. attention::
+//
+//   To route on HTTP method, use the special HTTP/2 *:method* header. This works for both
+//   HTTP/1 and HTTP/2 as Envoy normalizes headers. E.g.,
+//
+//   .. code-block:: json
+//
+//     {
+//       "name": ":method",
+//       "exact_match": "POST"
+//     }
+//
+// .. attention::
+//   In the absence of any header match specifier, match will default to :ref:`present_match
+//   <envoy_api_field_route.HeaderMatcher.present_match>`. i.e, a request that has the :ref:`name
+//   <envoy_api_field_route.HeaderMatcher.name>` header will match, regardless of the header's
+//   value.
+//
+message HeaderMatcher {
+  // Specifies the name of the header in the request.
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  reserved 2; // value deprecated by :ref:`exact_match
+              // <envoy_api_field_route.HeaderMatcher.exact_match>`
+
+  reserved 3; // regex deprecated by :ref:`regex_match
+              // <envoy_api_field_route.HeaderMatcher.regex_match>`
+
+  // Specifies how the header match will be performed to route the request.
+  oneof header_match_specifier {
+    // If specified, header match will be performed based on the value of the header.
+    string exact_match = 4;
+
+    // If specified, this regex string is a regular expression rule which implies the entire request
+    // header value must match the regex. The rule will not match if only a subsequence of the
+    // request header value matches the regex. The regex grammar used in the value field is defined
+    // `here <https://en.cppreference.com/w/cpp/regex/ecmascript>`_.
+    //
+    // Examples:
+    //
+    // * The regex *\d{3}* matches the value *123*
+    // * The regex *\d{3}* does not match the value *1234*
+    // * The regex *\d{3}* does not match the value *123.456*
+    string regex_match = 5 [(validate.rules).string.max_bytes = 1024];
+
+    // If specified, header match will be performed based on range.
+    // The rule will match if the request header value is within this range.
+    // The entire request header value must represent an integer in base 10 notation: consisting of
+    // an optional plus or minus sign followed by a sequence of digits. The rule will not match if
+    // the header value does not represent an integer. Match will fail for empty values, floating
+    // point numbers or if only a subsequence of the header value is an integer.
+    //
+    // Examples:
+    //
+    // * For range [-10,0), route will match for header value -1, but not for 0, "somestring", 10.9,
+    //   "-1somestring"
+    envoy.type.Int64Range range_match = 6;
+
+    // If specified, header match will be performed based on whether the header is in the
+    // request.
+    bool present_match = 7;
+
+    // If specified, header match will be performed based on the prefix of the header value.
+    // Note: empty prefix is not allowed, please use present_match instead.
+    //
+    // Examples:
+    //
+    // * The prefix *abcd* matches the value *abcdxyz*, but not for *abcxyz*.
+    string prefix_match = 9 [(validate.rules).string.min_bytes = 1];
+
+    // If specified, header match will be performed based on the suffix of the header value.
+    // Note: empty suffix is not allowed, please use present_match instead.
+    //
+    // Examples:
+    //
+    // * The suffix *abcd* matches the value *xyzabcd*, but not for *xyzbcd*.
+    string suffix_match = 10 [(validate.rules).string.min_bytes = 1];
+  }
+
+  // If specified, the match result will be inverted before checking. Defaults to false.
+  //
+  // Examples:
+  //
+  // * The regex *\d{3}* does not match the value *1234*, so it will match when inverted.
+  // * The range [-10,0) will match the value -1, so it will not match when inverted.
+  bool invert_match = 8;
+}
+
+// Query parameter matching treats the query string of a request's :path header
+// as an ampersand-separated list of keys and/or key=value elements.
+message QueryParameterMatcher {
+  // Specifies the name of a key that must be present in the requested
+  // *path*'s query string.
+  string name = 1 [(validate.rules).string = {min_bytes: 1, max_bytes: 1024}];
+
+  // Specifies the value of the key. If the value is absent, a request
+  // that contains the key in its query string will match, whether the
+  // key appears with a value (e.g., "?debug=true") or not (e.g., "?debug")
+  string value = 3;
+
+  // Specifies whether the query parameter value is a regular expression.
+  // Defaults to false. The entire query parameter value (i.e., the part to
+  // the right of the equals sign in "key=value") must match the regex.
+  // E.g., the regex "\d+$" will match "123" but not "a123" or "123a".
+  google.protobuf.BoolValue regex = 4;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/README.md b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/README.md
new file mode 100644
index 0000000..279bd7c
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/README.md
@@ -0,0 +1,3 @@
+Protocol buffer definitions for Envoy's bootstrap, filter, and service configuration.
+
+Visibility should be constrained to none or `//envoy/config/bootstrap/v2` by default.
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/BUILD
new file mode 100644
index 0000000..d6fd2d3
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/BUILD
@@ -0,0 +1,16 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "als",
+    srcs = ["als.proto"],
+    deps = [
+        "//envoy/api/v2/core:grpc_service",
+    ],
+)
+
+api_proto_library_internal(
+    name = "file",
+    srcs = ["file.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/als.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/als.proto
new file mode 100644
index 0000000..c71fe70
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/als.proto
@@ -0,0 +1,52 @@
+syntax = "proto3";
+
+package envoy.config.accesslog.v2;
+
+option java_outer_classname = "AlsProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.accesslog.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/grpc_service.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: gRPC Access Log Service (ALS)]
+
+// Configuration for the built-in *envoy.http_grpc_access_log*
+// :ref:`AccessLog <envoy_api_msg_config.filter.accesslog.v2.AccessLog>`. This configuration will
+// populate :ref:`StreamAccessLogsMessage.http_logs
+// <envoy_api_field_service.accesslog.v2.StreamAccessLogsMessage.http_logs>`.
+message HttpGrpcAccessLogConfig {
+  CommonGrpcAccessLogConfig common_config = 1 [(validate.rules).message.required = true];
+
+  // Additional request headers to log in :ref:`HTTPRequestProperties.request_headers
+  // <envoy_api_field_data.accesslog.v2.HTTPRequestProperties.request_headers>`.
+  repeated string additional_request_headers_to_log = 2;
+
+  // Additional response headers to log in :ref:`HTTPResponseProperties.response_headers
+  // <envoy_api_field_data.accesslog.v2.HTTPResponseProperties.response_headers>`.
+  repeated string additional_response_headers_to_log = 3;
+
+  // Additional response trailers to log in :ref:`HTTPResponseProperties.response_trailers
+  // <envoy_api_field_data.accesslog.v2.HTTPResponseProperties.response_trailers>`.
+  repeated string additional_response_trailers_to_log = 4;
+}
+
+// Configuration for the built-in *envoy.tcp_grpc_access_log* type. This configuration will
+// populate *StreamAccessLogsMessage.tcp_logs*.
+// [#not-implemented-hide:]
+message TcpGrpcAccessLogConfig {
+  CommonGrpcAccessLogConfig common_config = 1 [(validate.rules).message.required = true];
+}
+
+// Common configuration for gRPC access logs.
+message CommonGrpcAccessLogConfig {
+  // The friendly name of the access log to be returned in :ref:`StreamAccessLogsMessage.Identifier
+  // <envoy_api_msg_service.accesslog.v2.StreamAccessLogsMessage.Identifier>`. This allows the
+  // access log server to differentiate between different access logs coming from the same Envoy.
+  string log_name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The gRPC service for the access log service.
+  envoy.api.v2.core.GrpcService grpc_service = 2 [(validate.rules).message.required = true];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/file.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/file.proto
new file mode 100644
index 0000000..48a1841
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/accesslog/v2/file.proto
@@ -0,0 +1,32 @@
+syntax = "proto3";
+
+package envoy.config.accesslog.v2;
+
+option java_outer_classname = "FileProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.accesslog.v2";
+option go_package = "v2";
+
+import "validate/validate.proto";
+import "google/protobuf/struct.proto";
+
+// [#protodoc-title: File access log]
+
+// Custom configuration for an :ref:`AccessLog <envoy_api_msg_config.filter.accesslog.v2.AccessLog>`
+// that writes log entries directly to a file. Configures the built-in *envoy.file_access_log*
+// AccessLog.
+message FileAccessLog {
+  // A path to a local file to which to write the access log entries.
+  string path = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Access log format. Envoy supports :ref:`custom access log formats
+  // <config_access_log_format>` as well as a :ref:`default format
+  // <config_access_log_default_format>`.
+  oneof access_log_format {
+    // Access log :ref:`format string<config_access_log_format_strings>`
+    string format = 2;
+
+    // Access log :ref:`format dictionary<config_access_log_format_dictionaries>`
+    google.protobuf.Struct json_format = 3;
+  }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/BUILD
new file mode 100644
index 0000000..455365a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/BUILD
@@ -0,0 +1,40 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "bootstrap",
+    srcs = ["bootstrap.proto"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/api/v2:cds",
+        "//envoy/api/v2:lds",
+        "//envoy/api/v2/auth:cert",
+        "//envoy/api/v2/core:address",
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:config_source",
+        "//envoy/config/metrics/v2:metrics_service",
+        "//envoy/config/metrics/v2:stats",
+        "//envoy/config/overload/v2alpha:overload",
+        "//envoy/config/ratelimit/v2:rls",
+        "//envoy/config/trace/v2:trace",
+    ],
+)
+
+api_go_proto_library(
+    name = "bootstrap",
+    proto = ":bootstrap",
+    deps = [
+        "//envoy/api/v2:cds_go_grpc",
+        "//envoy/api/v2:lds_go_grpc",
+        "//envoy/api/v2/auth:cert_go_proto",
+        "//envoy/api/v2/core:address_go_proto",
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/core:config_source_go_proto",
+        "//envoy/config/metrics/v2:metrics_service_go_proto",
+        "//envoy/config/metrics/v2:stats_go_proto",
+        "//envoy/config/overload/v2alpha:overload_go_proto",
+        "//envoy/config/ratelimit/v2:rls_go_grpc",
+        "//envoy/config/trace/v2:trace_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/bootstrap.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/bootstrap.proto
new file mode 100644
index 0000000..addcd97
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/bootstrap/v2/bootstrap.proto
@@ -0,0 +1,216 @@
+// [#protodoc-title: Bootstrap]
+// This proto is supplied via the :option:`-c` CLI flag and acts as the root
+// of the Envoy v2 configuration. See the :ref:`v2 configuration overview
+// <config_overview_v2_bootstrap>` for more detail.
+
+syntax = "proto3";
+
+package envoy.config.bootstrap.v2;
+
+option java_outer_classname = "BootstrapProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.bootstrap.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/address.proto";
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/auth/cert.proto";
+import "envoy/api/v2/core/config_source.proto";
+import "envoy/api/v2/cds.proto";
+import "envoy/api/v2/lds.proto";
+import "envoy/config/trace/v2/trace.proto";
+import "envoy/config/metrics/v2/stats.proto";
+import "envoy/config/overload/v2alpha/overload.proto";
+import "envoy/config/ratelimit/v2/rls.proto";
+
+import "google/protobuf/duration.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// Bootstrap :ref:`configuration overview <config_overview_v2_bootstrap>`.
+message Bootstrap {
+  // Node identity to present to the management server and for instance
+  // identification purposes (e.g. in generated headers).
+  envoy.api.v2.core.Node node = 1;
+
+  message StaticResources {
+    // Static :ref:`Listeners <envoy_api_msg_Listener>`. These listeners are
+    // available regardless of LDS configuration.
+    repeated envoy.api.v2.Listener listeners = 1 [(gogoproto.nullable) = false];
+
+    // If a network based configuration source is specified for :ref:`cds_config
+    // <envoy_api_field_config.bootstrap.v2.Bootstrap.DynamicResources.cds_config>`, it's necessary
+    // to have some initial cluster definitions available to allow Envoy to know
+    // how to speak to the management server. These cluster definitions may not
+    // use :ref:`EDS <arch_overview_dynamic_config_eds>` (i.e. they should be static
+    // IP or DNS-based).
+    repeated envoy.api.v2.Cluster clusters = 2 [(gogoproto.nullable) = false];
+
+    // These static secrets can be used by :ref:`SdsSecretConfig
+    // <envoy_api_msg_auth.SdsSecretConfig>`
+    repeated envoy.api.v2.auth.Secret secrets = 3 [(gogoproto.nullable) = false];
+  }
+  // Statically specified resources.
+  StaticResources static_resources = 2;
+
+  message DynamicResources {
+    // All :ref:`Listeners <envoy_api_msg_Listener>` are provided by a single
+    // :ref:`LDS <arch_overview_dynamic_config_lds>` configuration source.
+    envoy.api.v2.core.ConfigSource lds_config = 1;
+
+    // All post-bootstrap :ref:`Cluster <envoy_api_msg_Cluster>` definitions are
+    // provided by a single :ref:`CDS <arch_overview_dynamic_config_cds>`
+    // configuration source.
+    envoy.api.v2.core.ConfigSource cds_config = 2;
+
+    // A single :ref:`ADS <config_overview_v2_ads>` source may be optionally
+    // specified. This must have :ref:`api_type
+    // <envoy_api_field_core.ApiConfigSource.api_type>` :ref:`GRPC
+    // <envoy_api_enum_value_core.ApiConfigSource.ApiType.GRPC>`. Only
+    // :ref:`ConfigSources <envoy_api_msg_core.ConfigSource>` that have
+    // the :ref:`ads <envoy_api_field_core.ConfigSource.ads>` field set will be
+    // streamed on the ADS channel.
+    envoy.api.v2.core.ApiConfigSource ads_config = 3;
+
+    reserved 4;
+  }
+  // xDS configuration sources.
+  DynamicResources dynamic_resources = 3;
+
+  // Configuration for the cluster manager which owns all upstream clusters
+  // within the server.
+  ClusterManager cluster_manager = 4;
+
+  // Health discovery service config option.
+  // (:ref:`core.ApiConfigSource <envoy_api_msg_core.ApiConfigSource>`)
+  envoy.api.v2.core.ApiConfigSource hds_config = 14;
+
+  // Optional file system path to search for startup flag files.
+  string flags_path = 5;
+
+  // Optional set of stats sinks.
+  repeated envoy.config.metrics.v2.StatsSink stats_sinks = 6;
+
+  // Configuration for internal processing of stats.
+  envoy.config.metrics.v2.StatsConfig stats_config = 13;
+
+  // Optional duration between flushes to configured stats sinks. For
+  // performance reasons Envoy latches counters and only flushes counters and
+  // gauges at a periodic interval. If not specified the default is 5000ms (5
+  // seconds).
+  google.protobuf.Duration stats_flush_interval = 7 [(gogoproto.stdduration) = true];
+
+  // Optional watchdog configuration.
+  Watchdog watchdog = 8;
+
+  // Configuration for an external tracing provider. If not specified, no
+  // tracing will be performed.
+  envoy.config.trace.v2.Tracing tracing = 9;
+
+  reserved 10;
+
+  // Configuration for the runtime configuration provider. If not specified, a
+  // “null” provider will be used which will result in all defaults being used.
+  Runtime runtime = 11;
+
+  // Configuration for the local administration HTTP server.
+  Admin admin = 12;
+
+  // Optional overload manager configuration.
+  envoy.config.overload.v2alpha.OverloadManager overload_manager = 15;
+}
+
+// Administration interface :ref:`operations documentation
+// <operations_admin_interface>`.
+message Admin {
+  // The path to write the access log for the administration server. If no
+  // access log is desired specify ‘/dev/null’. This is only required if
+  // :ref:`address <envoy_api_field_config.bootstrap.v2.Admin.address>` is set.
+  string access_log_path = 1;
+
+  // The cpu profiler output path for the administration server. If no profile
+  // path is specified, the default is ‘/var/log/envoy/envoy.prof’.
+  string profile_path = 2;
+
+  // The TCP address that the administration server will listen on.
+  // If not specified, Envoy will not start an administration server.
+  envoy.api.v2.core.Address address = 3;
+}
+
+// Cluster manager :ref:`architecture overview <arch_overview_cluster_manager>`.
+message ClusterManager {
+  // Name of the local cluster (i.e., the cluster that owns the Envoy running
+  // this configuration). In order to enable :ref:`zone aware routing
+  // <arch_overview_load_balancing_zone_aware_routing>` this option must be set.
+  // If *local_cluster_name* is defined then :ref:`clusters
+  // <envoy_api_msg_Cluster>` must be defined in the :ref:`Bootstrap
+  // static cluster resources
+  // <envoy_api_field_config.bootstrap.v2.Bootstrap.StaticResources.clusters>`. This is unrelated to
+  // the :option:`--service-cluster` option which does not `affect zone aware
+  // routing <https://github.com/envoyproxy/envoy/issues/774>`_.
+  string local_cluster_name = 1;
+
+  message OutlierDetection {
+    // Specifies the path to the outlier event log.
+    string event_log_path = 1;
+  }
+  // Optional global configuration for outlier detection.
+  OutlierDetection outlier_detection = 2;
+
+  // Optional configuration used to bind newly established upstream connections.
+  // This may be overridden on a per-cluster basis by upstream_bind_config in the cds_config.
+  envoy.api.v2.core.BindConfig upstream_bind_config = 3;
+
+  // A management server endpoint to stream load stats to via
+  // *StreamLoadStats*. This must have :ref:`api_type
+  // <envoy_api_field_core.ApiConfigSource.api_type>` :ref:`GRPC
+  // <envoy_api_enum_value_core.ApiConfigSource.ApiType.GRPC>`.
+  envoy.api.v2.core.ApiConfigSource load_stats_config = 4;
+}
+
+// Envoy process watchdog configuration. When configured, this monitors for
+// nonresponsive threads and kills the process after the configured thresholds.
+message Watchdog {
+  // The duration after which Envoy counts a nonresponsive thread in the
+  // *server.watchdog_miss* statistic. If not specified the default is 200ms.
+  google.protobuf.Duration miss_timeout = 1;
+
+  // The duration after which Envoy counts a nonresponsive thread in the
+  // *server.watchdog_mega_miss* statistic. If not specified the default is
+  // 1000ms.
+  google.protobuf.Duration megamiss_timeout = 2;
+
+  // If a watched thread has been nonresponsive for this duration, assume a
+  // programming error and kill the entire Envoy process. Set to 0 to disable
+  // kill behavior. If not specified the default is 0 (disabled).
+  google.protobuf.Duration kill_timeout = 3;
+
+  // If at least two watched threads have been nonresponsive for at least this
+  // duration assume a true deadlock and kill the entire Envoy process. Set to 0
+  // to disable this behavior. If not specified the default is 0 (disabled).
+  google.protobuf.Duration multikill_timeout = 4;
+}
+
+// Runtime :ref:`configuration overview <config_runtime>`.
+message Runtime {
+  // The implementation assumes that the file system tree is accessed via a
+  // symbolic link. An atomic link swap is used when a new tree should be
+  // switched to. This parameter specifies the path to the symbolic link. Envoy
+  // will watch the location for changes and reload the file system tree when
+  // they happen.
+  string symlink_root = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Specifies the subdirectory to load within the root directory. This is
+  // useful if multiple systems share the same delivery mechanism. Envoy
+  // configuration elements can be contained in a dedicated subdirectory.
+  string subdirectory = 2;
+
+  // Specifies an optional subdirectory to load within the root directory. If
+  // specified and the directory exists, configuration values within this
+  // directory will override those found in the primary subdirectory. This is
+  // useful when Envoy is deployed across many different types of servers.
+  // Sometimes it is useful to have a per service cluster directory for runtime
+  // configuration. See below for exactly how the override directory is used.
+  string override_subdirectory = 3;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/BUILD
new file mode 100644
index 0000000..4b78057
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/BUILD
@@ -0,0 +1,12 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "common",
+    srcs = ["common.proto"],
+    visibility = ["//visibility:public"],
+    deps = [
+        "//envoy/service/tap/v2alpha:common",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/common.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/common.proto
new file mode 100644
index 0000000..a52016d
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/common/tap/v2alpha/common.proto
@@ -0,0 +1,35 @@
+syntax = "proto3";
+
+import "envoy/service/tap/v2alpha/common.proto";
+
+import "validate/validate.proto";
+
+package envoy.config.common.tap.v2alpha;
+
+option java_outer_classname = "CommonProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.common.tap.v2alpha";
+
+// [#protodoc-title: Common tap extension configuration]
+
+// Common configuration for all tap extensions.
+message CommonExtensionConfig {
+  oneof config_type {
+    option (validate.required) = true;
+
+    // If specified, the tap filter will be configured via an admin handler.
+    AdminConfig admin_config = 1;
+
+    // If specified, the tap filter will be configured via a static configuration that cannot be
+    // changed.
+    service.tap.v2alpha.TapConfig static_config = 2;
+  }
+}
+
+// Configuration for the admin handler. See :ref:`here <config_http_filters_tap_admin_handler>` for
+// more information.
+message AdminConfig {
+  // Opaque configuration ID. When requests are made to the admin handler, the passed opaque ID is
+  // matched to the configured filter opaque ID to determine which filter to configure.
+  string config_id = 1 [(validate.rules).string.min_bytes = 1];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/README.md b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/README.md
new file mode 100644
index 0000000..6ec297d
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/README.md
@@ -0,0 +1,4 @@
+Protocol buffer definitions for filters.
+
+Visibility of the definitions should be constrained to none except for
+shared definitions between explicitly enumerated filters (e.g. accesslog and fault definitions).
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/BUILD
new file mode 100644
index 0000000..fdbf376
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/BUILD
@@ -0,0 +1,28 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "accesslog",
+    srcs = ["accesslog.proto"],
+    visibility = [
+        "//envoy/config/filter/http/router/v2:__pkg__",
+        "//envoy/config/filter/network/http_connection_manager/v2:__pkg__",
+        "//envoy/config/filter/network/tcp_proxy/v2:__pkg__",
+    ],
+    deps = [
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/route",
+        "//envoy/type:percent",
+    ],
+)
+
+api_go_proto_library(
+    name = "accesslog",
+    proto = ":accesslog",
+    deps = [
+        "//envoy/api/v2/core:base_go_proto",
+        "//envoy/api/v2/route:route_go_proto",
+        "//envoy/type:percent_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/accesslog.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/accesslog.proto
new file mode 100644
index 0000000..da13fb7
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/accesslog/v2/accesslog.proto
@@ -0,0 +1,228 @@
+syntax = "proto3";
+
+package envoy.config.filter.accesslog.v2;
+
+option java_outer_classname = "AccesslogProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.accesslog.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/route/route.proto";
+import "envoy/type/percent.proto";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/struct.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: Common access log types]
+
+message AccessLog {
+  // The name of the access log implementation to instantiate. The name must
+  // match a statically registered access log. Current built-in loggers include:
+  //
+  // #. "envoy.file_access_log"
+  // #. "envoy.http_grpc_access_log"
+  string name = 1;
+
+  // Filter which is used to determine if the access log needs to be written.
+  AccessLogFilter filter = 2;
+
+  // Custom configuration that depends on the access log being instantiated. Built-in
+  // configurations include:
+  //
+  // #. "envoy.file_access_log": :ref:`FileAccessLog
+  //    <envoy_api_msg_config.accesslog.v2.FileAccessLog>`
+  // #. "envoy.http_grpc_access_log": :ref:`HttpGrpcAccessLogConfig
+  //    <envoy_api_msg_config.accesslog.v2.HttpGrpcAccessLogConfig>`
+  oneof config_type {
+    google.protobuf.Struct config = 3 [deprecated = true];
+
+    google.protobuf.Any typed_config = 4;
+  }
+}
+
+message AccessLogFilter {
+  oneof filter_specifier {
+    option (validate.required) = true;
+
+    // Status code filter.
+    StatusCodeFilter status_code_filter = 1;
+
+    // Duration filter.
+    DurationFilter duration_filter = 2;
+
+    // Not health check filter.
+    NotHealthCheckFilter not_health_check_filter = 3;
+
+    // Traceable filter.
+    TraceableFilter traceable_filter = 4;
+
+    // Runtime filter.
+    RuntimeFilter runtime_filter = 5;
+
+    // And filter.
+    AndFilter and_filter = 6;
+
+    // Or filter.
+    OrFilter or_filter = 7;
+
+    // Header filter.
+    HeaderFilter header_filter = 8;
+
+    // Response flag filter.
+    ResponseFlagFilter response_flag_filter = 9;
+
+    // gRPC status filter.
+    GrpcStatusFilter grpc_status_filter = 10;
+  }
+}
+
+// Filter on an integer comparison.
+message ComparisonFilter {
+  enum Op {
+    // =
+    EQ = 0;
+
+    // >=
+    GE = 1;
+
+    // <=
+    LE = 2;
+  }
+
+  // Comparison operator.
+  Op op = 1 [(validate.rules).enum.defined_only = true];
+
+  // Value to compare against.
+  envoy.api.v2.core.RuntimeUInt32 value = 2;
+}
+
+// Filters on HTTP response/status code.
+message StatusCodeFilter {
+  // Comparison.
+  ComparisonFilter comparison = 1 [(validate.rules).message.required = true];
+}
+
+// Filters on total request duration in milliseconds.
+message DurationFilter {
+  // Comparison.
+  ComparisonFilter comparison = 1 [(validate.rules).message.required = true];
+}
+
+// Filters for requests that are not health check requests. A health check
+// request is marked by the health check filter.
+message NotHealthCheckFilter {
+}
+
+// Filters for requests that are traceable. See the tracing overview for more
+// information on how a request becomes traceable.
+message TraceableFilter {
+}
+
+// Filters for random sampling of requests.
+message RuntimeFilter {
+  // Runtime key to get an optional overridden numerator for use in the *percent_sampled* field.
+  // If found in runtime, this value will replace the default numerator.
+  string runtime_key = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The default sampling percentage. If not specified, defaults to 0% with denominator of 100.
+  envoy.type.FractionalPercent percent_sampled = 2;
+
+  // By default, sampling pivots on the header
+  // :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` being present. If
+  // :ref:`x-request-id<config_http_conn_man_headers_x-request-id>` is present, the filter will
+  // consistently sample across multiple hosts based on the runtime key value and the value
+  // extracted from :ref:`x-request-id<config_http_conn_man_headers_x-request-id>`. If it is
+  // missing, or *use_independent_randomness* is set to true, the filter will randomly sample based
+  // on the runtime key value alone. *use_independent_randomness* can be used for logging kill
+  // switches within complex nested :ref:`AndFilter
+  // <envoy_api_msg_config.filter.accesslog.v2.AndFilter>` and :ref:`OrFilter
+  // <envoy_api_msg_config.filter.accesslog.v2.OrFilter>` blocks that are easier to reason about
+  // from a probability perspective (i.e., setting to true will cause the filter to behave like
+  // an independent random variable when composed within logical operator filters).
+  bool use_independent_randomness = 3;
+}
+
+// Performs a logical “and” operation on the result of each filter in filters.
+// Filters are evaluated sequentially and if one of them returns false, the
+// filter returns false immediately.
+message AndFilter {
+  repeated AccessLogFilter filters = 1 [(validate.rules).repeated .min_items = 2];
+}
+
+// Performs a logical “or” operation on the result of each individual filter.
+// Filters are evaluated sequentially and if one of them returns true, the
+// filter returns true immediately.
+message OrFilter {
+  repeated AccessLogFilter filters = 2 [(validate.rules).repeated .min_items = 2];
+}
+
+// Filters requests based on the presence or value of a request header.
+message HeaderFilter {
+  // Only requests with a header which matches the specified HeaderMatcher will pass the filter
+  // check.
+  envoy.api.v2.route.HeaderMatcher header = 1 [(validate.rules).message.required = true];
+}
+
+// Filters requests that received responses with an Envoy response flag set.
+// A list of the response flags can be found
+// in the access log formatter :ref:`documentation<config_access_log_format_response_flags>`.
+message ResponseFlagFilter {
+  // Only responses with the any of the flags listed in this field will be logged.
+  // This field is optional. If it is not specified, then any response flag will pass
+  // the filter check.
+  repeated string flags = 1 [(validate.rules).repeated .items.string = {
+    in: [
+      "LH",
+      "UH",
+      "UT",
+      "LR",
+      "UR",
+      "UF",
+      "UC",
+      "UO",
+      "NR",
+      "DI",
+      "FI",
+      "RL",
+      "UAEX",
+      "RLSE",
+      "DC",
+      "URX",
+      "SI"
+    ]
+  }];
+}
+
+// Filters gRPC requests based on their response status. If a gRPC status is not provided, the
+// filter will infer the status from the HTTP status code.
+message GrpcStatusFilter {
+  enum Status {
+    OK = 0;
+    CANCELED = 1;
+    UNKNOWN = 2;
+    INVALID_ARGUMENT = 3;
+    DEADLINE_EXCEEDED = 4;
+    NOT_FOUND = 5;
+    ALREADY_EXISTS = 6;
+    PERMISSION_DENIED = 7;
+    RESOURCE_EXHAUSTED = 8;
+    FAILED_PRECONDITION = 9;
+    ABORTED = 10;
+    OUT_OF_RANGE = 11;
+    UNIMPLEMENTED = 12;
+    INTERNAL = 13;
+    UNAVAILABLE = 14;
+    DATA_LOSS = 15;
+    UNAUTHENTICATED = 16;
+  }
+
+  // Logs only responses that have any one of the gRPC statuses in this field.
+  repeated Status statuses = 1 [(validate.rules).repeated .items.enum.defined_only = true];
+
+  // If included and set to true, the filter will instead block all responses with a gRPC status or
+  // inferred gRPC status enumerated in statuses, and allow all other responses.
+  bool exclude = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/BUILD
new file mode 100644
index 0000000..ce0ad0e
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/BUILD
@@ -0,0 +1,8 @@
+load("//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "router",
+    srcs = ["router.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/router.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/router.proto
new file mode 100644
index 0000000..37a5542
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/dubbo/router/v2alpha1/router.proto
@@ -0,0 +1,14 @@
+syntax = "proto3";
+
+package envoy.config.filter.dubbo.router.v2alpha1;
+
+option java_outer_classname = "RouterProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.dubbo.router.v2alpha1";
+option go_package = "v2alpha1";
+
+// [#protodoc-title: Router]
+// Dubbo router :ref:`configuration overview <config_dubbo_filters_router>`.
+
+message Router {
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/BUILD
new file mode 100644
index 0000000..35419a9
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/BUILD
@@ -0,0 +1,13 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "fault",
+    srcs = ["fault.proto"],
+    visibility = [
+        "//envoy/config/filter/http/fault/v2:__pkg__",
+        "//envoy/config/filter/network/mongo_proxy/v2:__pkg__",
+    ],
+    deps = ["//envoy/type:percent"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/fault.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/fault.proto
new file mode 100644
index 0000000..89d1dc2
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/fault/v2/fault.proto
@@ -0,0 +1,66 @@
+syntax = "proto3";
+
+package envoy.config.filter.fault.v2;
+
+option java_outer_classname = "FaultProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.fault.v2";
+option go_package = "v2";
+
+import "envoy/type/percent.proto";
+
+import "google/protobuf/duration.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: Common fault injection types]
+
+// Delay specification is used to inject latency into the
+// HTTP/gRPC/Mongo/Redis operation or delay proxying of TCP connections.
+message FaultDelay {
+  enum FaultDelayType {
+    // Fixed delay (step function).
+    FIXED = 0;
+  }
+
+  // Delay type to use (fixed|exponential|..). Currently, only fixed delay (step function) is
+  // supported.
+  FaultDelayType type = 1 [(validate.rules).enum.defined_only = true];
+
+  reserved 2;
+
+  oneof fault_delay_secifier {
+    option (validate.required) = true;
+    // Add a fixed delay before forwarding the operation upstream. See
+    // https://developers.google.com/protocol-buffers/docs/proto3#json for
+    // the JSON/YAML Duration mapping. For HTTP/Mongo/Redis, the specified
+    // delay will be injected before a new request/operation. For TCP
+    // connections, the proxying of the connection upstream will be delayed
+    // for the specified period. This is required if type is FIXED.
+    google.protobuf.Duration fixed_delay = 3
+        [(validate.rules).duration.gt = {}, (gogoproto.stdduration) = true];
+  }
+
+  // The percentage of operations/connections/requests on which the delay will be injected.
+  type.FractionalPercent percentage = 4;
+}
+
+// Describes a rate limit to be applied.
+message FaultRateLimit {
+  // Describes a fixed/constant rate limit.
+  message FixedLimit {
+    // The limit supplied in KiB/s.
+    uint64 limit_kbps = 1 [(validate.rules).uint64.gte = 1];
+  }
+
+  oneof limit_type {
+    option (validate.required) = true;
+
+    // A fixed rate limit.
+    FixedLimit fixed_limit = 1;
+  }
+
+  // The percentage of operations/connections/requests on which the rate limit will be injected.
+  type.FractionalPercent percentage = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/BUILD
new file mode 100644
index 0000000..e59429a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/BUILD
@@ -0,0 +1,8 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "buffer",
+    srcs = ["buffer.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/buffer.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/buffer.proto
new file mode 100644
index 0000000..6da5cbb
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/buffer/v2/buffer.proto
@@ -0,0 +1,37 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.buffer.v2;
+
+option java_outer_classname = "BufferProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.buffer.v2";
+option go_package = "v2";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: Buffer]
+// Buffer :ref:`configuration overview <config_http_filters_buffer>`.
+
+message Buffer {
+  reserved 2; // formerly max_request_time
+
+  // The maximum request size that the filter will buffer before the connection
+  // manager will stop buffering and return a 413 response.
+  google.protobuf.UInt32Value max_request_bytes = 1 [(validate.rules).uint32.gt = 0];
+}
+
+message BufferPerRoute {
+  oneof override {
+    option (validate.required) = true;
+
+    // Disable the buffer filter for this particular vhost or route.
+    bool disabled = 1 [(validate.rules).bool.const = true];
+
+    // Override the global configuration of the filter with this new config.
+    Buffer buffer = 2 [(validate.rules).message.required = true];
+  }
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/BUILD
new file mode 100644
index 0000000..a22408b
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/BUILD
@@ -0,0 +1,14 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "ext_authz",
+    srcs = ["ext_authz.proto"],
+    deps = [
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:grpc_service",
+        "//envoy/api/v2/core:http_uri",
+        "//envoy/type/matcher:string",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/ext_authz.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/ext_authz.proto
new file mode 100644
index 0000000..e79e598
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ext_authz/v2/ext_authz.proto
@@ -0,0 +1,159 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.ext_authz.v2;
+
+option java_outer_classname = "ExtAuthzProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.ext_authz.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/core/grpc_service.proto";
+import "envoy/api/v2/core/http_uri.proto";
+
+import "envoy/type/matcher/string.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: External Authorization]
+// External Authorization :ref:`configuration overview <config_http_filters_ext_authz>`.
+
+message ExtAuthz {
+  // External authorization service configuration.
+  oneof services {
+    // gRPC service configuration (default timeout: 200ms).
+    envoy.api.v2.core.GrpcService grpc_service = 1;
+
+    // HTTP service configuration (default timeout: 200ms).
+    HttpService http_service = 3;
+  }
+
+  //  Changes filter's behaviour on errors:
+  //
+  //  1. When set to true, the filter will *accept* client request even if the communication with
+  //  the authorization service has failed, or if the authorization service has returned a HTTP 5xx
+  //  error.
+  //
+  //  2. When set to false, ext-authz will *reject* client requests and return a *Forbidden*
+  //  response if the communication with the authorization service has failed, or if the
+  //  authorization service has returned a HTTP 5xx error.
+  //
+  // Note that errors can be *always* tracked in the :ref:`stats
+  // <config_http_filters_ext_authz_stats>`.
+  bool failure_mode_allow = 2;
+
+  // Sets the package version the gRPC service should use. This is particularly
+  // useful when transitioning from alpha to release versions assuming that both definitions are
+  // semantically compatible. Deprecation note: This field is deprecated and should only be used for
+  // version upgrade. See release notes for more details.
+  bool use_alpha = 4 [deprecated = true];
+}
+
+// HttpService is used for raw HTTP communication between the filter and the authorization service.
+// When configured, the filter will parse the client request and use these attributes to call the
+// authorization server. Depending on the response, the filter may reject or accept the client
+// request. Note that in any of these events, metadata can be added, removed or overridden by the
+// filter:
+//
+// *On authorization request*, a list of allowed request headers may be supplied. See
+// :ref:`allowed_headers
+// <envoy_api_field_config.filter.http.ext_authz.v2.AuthorizationRequest.allowed_headers>`
+// for details. Additional headers metadata may be added to the authorization request. See
+// :ref:`headers_to_add
+// <envoy_api_field_config.filter.http.ext_authz.v2.AuthorizationRequest.headers_to_add>` for
+// details.
+//
+// On authorization response status HTTP 200 OK, the filter will allow traffic to the upstream and
+// additional headers metadata may be added to the original client request. See
+// :ref:`allowed_upstream_headers
+// <envoy_api_field_config.filter.http.ext_authz.v2.AuthorizationResponse.allowed_upstream_headers>`
+// for details.
+//
+// On other authorization response statuses, the filter will not allow traffic. Additional headers
+// metadata as well as body may be added to the client's response. See :ref:`allowed_client_headers
+// <envoy_api_field_config.filter.http.ext_authz.v2.AuthorizationResponse.allowed_client_headers>`
+// for details.
+message HttpService {
+  // Sets the HTTP server URI which the authorization requests must be sent to.
+  envoy.api.v2.core.HttpUri server_uri = 1;
+
+  // Sets a prefix to the value of authorization request header *Path*.
+  string path_prefix = 2;
+
+  reserved 3;
+  reserved 4;
+  reserved 5;
+  reserved 6;
+
+  // Settings used for controlling authorization request metadata.
+  AuthorizationRequest authorization_request = 7;
+
+  // Settings used for controlling authorization response metadata.
+  AuthorizationResponse authorization_response = 8;
+}
+
+message AuthorizationRequest {
+  // Authorization request will include the client request headers that have a correspondent match
+  // in the :ref:`list <envoy_api_msg_type.matcher.ListStringMatcher>`. Note that in addition to the
+  // user's supplied matchers:
+  //
+  // 1. *Host*, *Method*, *Path* and *Content-Length* are automatically included to the list.
+  //
+  // 2. *Content-Length* will be set to 0 and the request to the authorization service will not have
+  // a message body.
+  //
+  envoy.type.matcher.ListStringMatcher allowed_headers = 1;
+
+  // Sets a list of headers that will be included to the request to authorization service. Note that
+  // client request of the same key will be overridden.
+  repeated envoy.api.v2.core.HeaderValue headers_to_add = 2;
+}
+
+message AuthorizationResponse {
+  // When this :ref:`list <envoy_api_msg_type.matcher.ListStringMatcher>` is set, authorization
+  // response headers that have a correspondent match will be added to the original client request.
+  // Note that coexistent headers will be overridden.
+  envoy.type.matcher.ListStringMatcher allowed_upstream_headers = 1;
+
+  // When this :ref:`list <envoy_api_msg_type.matcher.ListStringMatcher>`. is set, authorization
+  // response headers that have a correspondent match will be added to the client's response. Note
+  // that when this list is *not* set, all the authorization response headers, except *Authority
+  // (Host)* will be in the response to the client. When a header is included in this list, *Path*,
+  // *Status*, *Content-Length*, *WWWAuthenticate* and *Location* are automatically added.
+  envoy.type.matcher.ListStringMatcher allowed_client_headers = 2;
+}
+
+// Extra settings on a per virtualhost/route/weighted-cluster level.
+message ExtAuthzPerRoute {
+  oneof override {
+    option (validate.required) = true;
+
+    // Disable the ext auth filter for this particular vhost or route.
+    // If disabled is specified in multiple per-filter-configs, the most specific one will be used.
+    bool disabled = 1 [(validate.rules).bool.const = true];
+
+    // Check request settings for this route.
+    CheckSettings check_settings = 2 [(validate.rules).message.required = true];
+  }
+}
+
+// Extra settings for the check request. You can use this to provide extra context for the
+// external authorization server on specific virtual hosts \ routes. For example, adding a context
+// extension on the virtual host level can give the ext-authz server information on what virtual
+// host is used without needing to parse the host header. If CheckSettings is specified in multiple
+// per-filter-configs, they will be merged in order, and the result will be used.
+message CheckSettings {
+  // Context extensions to set on the CheckRequest's
+  // :ref:`AttributeContext.context_extensions<envoy_api_field_service.auth.v2.AttributeContext.context_extensions>`
+  //
+  // Merge semantics for this field are such that keys from more specific configs override.
+  //
+  // .. note::
+  //
+  //   These settings are only applied to a filter configured with a
+  //   :ref:`grpc_service<envoy_api_field_config.filter.http.ext_authz.v2.ExtAuthz.grpc_service>`.
+  map<string, string> context_extensions = 1;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/BUILD
new file mode 100644
index 0000000..e561e88
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/BUILD
@@ -0,0 +1,13 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "fault",
+    srcs = ["fault.proto"],
+    deps = [
+        "//envoy/api/v2/route",
+        "//envoy/config/filter/fault/v2:fault",
+        "//envoy/type:percent",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/fault.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/fault.proto
new file mode 100644
index 0000000..df42589
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/fault/v2/fault.proto
@@ -0,0 +1,89 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.fault.v2;
+
+option java_outer_classname = "FaultProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.fault.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/route/route.proto";
+import "envoy/config/filter/fault/v2/fault.proto";
+import "envoy/type/percent.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: Fault Injection]
+// Fault Injection :ref:`configuration overview <config_http_filters_fault_injection>`.
+
+message FaultAbort {
+  reserved 1;
+
+  oneof error_type {
+    option (validate.required) = true;
+
+    // HTTP status code to use to abort the HTTP request.
+    uint32 http_status = 2 [(validate.rules).uint32 = {gte: 200, lt: 600}];
+  }
+
+  // The percentage of requests/operations/connections that will be aborted with the error code
+  // provided.
+  type.FractionalPercent percentage = 3;
+}
+
+message HTTPFault {
+  // If specified, the filter will inject delays based on the values in the
+  // object.
+  filter.fault.v2.FaultDelay delay = 1;
+
+  // If specified, the filter will abort requests based on the values in
+  // the object. At least *abort* or *delay* must be specified.
+  FaultAbort abort = 2;
+
+  // Specifies the name of the (destination) upstream cluster that the
+  // filter should match on. Fault injection will be restricted to requests
+  // bound to the specific upstream cluster.
+  string upstream_cluster = 3;
+
+  // Specifies a set of headers that the filter should match on. The fault
+  // injection filter can be applied selectively to requests that match a set of
+  // headers specified in the fault filter config. The chances of actual fault
+  // injection further depend on the value of the :ref:`percentage
+  // <envoy_api_field_config.filter.http.fault.v2.FaultAbort.percentage>` field.
+  // The filter will check the request's headers against all the specified
+  // headers in the filter config. A match will happen if all the headers in the
+  // config are present in the request with the same values (or based on
+  // presence if the *value* field is not in the config).
+  repeated envoy.api.v2.route.HeaderMatcher headers = 4;
+
+  // Faults are injected for the specified list of downstream hosts. If this
+  // setting is not set, faults are injected for all downstream nodes.
+  // Downstream node name is taken from :ref:`the HTTP
+  // x-envoy-downstream-service-node
+  // <config_http_conn_man_headers_downstream-service-node>` header and compared
+  // against downstream_nodes list.
+  repeated string downstream_nodes = 5;
+
+  // The maximum number of faults that can be active at a single time via the configured fault
+  // filter. Note that because this setting can be overridden at the route level, it's possible
+  // for the number of active faults to be greater than this value (if injected via a different
+  // route). If not specified, defaults to unlimited. This setting can be overridden via
+  // `runtime <config_http_filters_fault_injection_runtime>` and any faults that are not injected
+  // due to overflow will be indicated via the `faults_overflow
+  // <config_http_filters_fault_injection_stats>` stat.
+  //
+  // .. attention::
+  //   Like other :ref:`circuit breakers <arch_overview_circuit_break>` in Envoy, this is a fuzzy
+  //   limit. It's possible for the number of active faults to rise slightly above the configured
+  //   amount due to the implementation details.
+  google.protobuf.UInt32Value max_active_faults = 6;
+
+  // The response rate limit to be applied to the response body of the stream.
+  //
+  // .. attention::
+  //  This is a per-stream limit versus a connection level limit. This means that concurrent streams
+  //  will each get an independent limit.
+  filter.fault.v2.FaultRateLimit response_rate_limit = 7;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/BUILD
new file mode 100644
index 0000000..7c1deb7
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/BUILD
@@ -0,0 +1,8 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library(
+    name = "config",
+    srcs = ["config.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/config.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/config.proto
new file mode 100644
index 0000000..0c33b6d
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/config.proto
@@ -0,0 +1,27 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.grpc_http1_reverse_bridge.v2alpha1;
+
+option java_outer_classname = "ConfigProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.grpc_http1_reverse_bridge.v2alpha1";
+option go_package = "v2";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: gRPC HTTP/1.1 Reverse Bridge]
+// gRPC HTTP/1.1 Reverse Bridge :ref:`configuration overview
+// <config_http_filters_grpc_http1_reverse_bridge>`.
+
+// gRPC reverse bridge filter configuration
+message FilterConfig {
+  // The content-type to pass to the upstream when the gRPC bridge filter is applied.
+  // The filter will also validate that the upstream responds with the same content type.
+  string content_type = 1 [(validate.rules).string.min_bytes = 1];
+
+  // If true, Envoy will assume that the upstream doesn't understand gRPC frames and
+  // strip the gRPC frame from the request, and add it back in to the response. This will
+  // hide the gRPC semantics from the upstream, allowing it to receive and respond with a
+  // simple binary encoded protobuf.
+  bool withhold_grpc_frames = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/BUILD
new file mode 100644
index 0000000..e34d73c
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/BUILD
@@ -0,0 +1,8 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "gzip",
+    srcs = ["gzip.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/gzip.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/gzip.proto
new file mode 100644
index 0000000..fb6b887
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/gzip/v2/gzip.proto
@@ -0,0 +1,75 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.gzip.v2;
+
+option java_outer_classname = "GzipProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.gzip.v2";
+option go_package = "v2";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: Gzip]
+// Gzip :ref:`configuration overview <config_http_filters_gzip>`.
+
+message Gzip {
+  // Value from 1 to 9 that controls the amount of internal memory used by zlib. Higher values
+  // use more memory, but are faster and produce better compression results. The default value is 5.
+  google.protobuf.UInt32Value memory_level = 1 [(validate.rules).uint32 = {gte: 1, lte: 9}];
+
+  // Minimum response length, in bytes, which will trigger compression. The default value is 30.
+  google.protobuf.UInt32Value content_length = 2 [(validate.rules).uint32.gte = 30];
+
+  message CompressionLevel {
+    enum Enum {
+      DEFAULT = 0;
+      BEST = 1;
+      SPEED = 2;
+    }
+  }
+
+  // A value used for selecting the zlib compression level. This setting will affect speed and
+  // amount of compression applied to the content. "BEST" provides higher compression at the cost of
+  // higher latency, "SPEED" provides lower compression with minimum impact on response time.
+  // "DEFAULT" provides an optimal result between speed and compression. This field will be set to
+  // "DEFAULT" if not specified.
+  CompressionLevel.Enum compression_level = 3 [(validate.rules).enum.defined_only = true];
+
+  enum CompressionStrategy {
+    DEFAULT = 0;
+    FILTERED = 1;
+    HUFFMAN = 2;
+    RLE = 3;
+  }
+
+  // A value used for selecting the zlib compression strategy which is directly related to the
+  // characteristics of the content. Most of the time "DEFAULT" will be the best choice, though
+  // there are situations which changing this parameter might produce better results. For example,
+  // run-length encoding (RLE) is typically used when the content is known for having sequences
+  // which same data occurs many consecutive times. For more information about each strategy, please
+  // refer to zlib manual.
+  CompressionStrategy compression_strategy = 4 [(validate.rules).enum.defined_only = true];
+
+  // Set of strings that allows specifying which mime-types yield compression; e.g.,
+  // application/json, text/html, etc. When this field is not defined, compression will be applied
+  // to the following mime-types: "application/javascript", "application/json",
+  // "application/xhtml+xml", "image/svg+xml", "text/css", "text/html", "text/plain", "text/xml".
+  repeated string content_type = 6 [(validate.rules).repeated = {max_items: 50}];
+
+  // If true, disables compression when the response contains an etag header. When it is false, the
+  // filter will preserve weak etags and remove the ones that require strong validation.
+  bool disable_on_etag_header = 7;
+
+  // If true, removes accept-encoding from the request headers before dispatching it to the upstream
+  // so that responses do not get compressed before reaching the filter.
+  bool remove_accept_encoding_header = 8;
+
+  // Value from 9 to 15 that represents the base two logarithmic of the compressor's window size.
+  // Larger window results in better compression at the expense of memory usage. The default is 12
+  // which will produce a 4096 bytes window. For more details about this parameter, please refer to
+  // zlib manual > deflateInit2.
+  google.protobuf.UInt32Value window_bits = 9 [(validate.rules).uint32 = {gte: 9, lte: 15}];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/BUILD
new file mode 100644
index 0000000..3f8503a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/BUILD
@@ -0,0 +1,9 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "header_to_metadata",
+    srcs = ["header_to_metadata.proto"],
+    deps = [],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/header_to_metadata.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/header_to_metadata.proto
new file mode 100644
index 0000000..2c8c606
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/header_to_metadata/v2/header_to_metadata.proto
@@ -0,0 +1,73 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.header_to_metadata.v2;
+
+option java_outer_classname = "HeaderToMetadataProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.header_to_metadata.v2";
+option go_package = "v2";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: Header-To-Metadata Filter]
+//
+// The configuration for transforming headers into metadata. This is useful
+// for matching load balancer subsets, logging, etc.
+//
+// Header to Metadata :ref:`configuration overview <config_http_filters_header_to_metadata>`.
+
+message Config {
+  enum ValueType {
+    STRING = 0;
+    NUMBER = 1;
+  }
+
+  message KeyValuePair {
+    // The namespace — if this is empty, the filter's namespace will be used.
+    string metadata_namespace = 1;
+
+    // The key to use within the namespace.
+    string key = 2 [(validate.rules).string.min_bytes = 1];
+
+    // The value to pair with the given key.
+    //
+    // When used for a `on_header_present` case, if value is non-empty it'll be used
+    // instead of the header value. If both are empty, no metadata is added.
+    //
+    // When used for a `on_header_missing` case, a non-empty value must be provided
+    // otherwise no metadata is added.
+    string value = 3;
+
+    // The value's type — defaults to string.
+    ValueType type = 4;
+  }
+
+  // A Rule defines what metadata to apply when a header is present or missing.
+  message Rule {
+    // The header that triggers this rule — required.
+    string header = 1 [(validate.rules).string.min_bytes = 1];
+
+    // If the header is present, apply this metadata KeyValuePair.
+    //
+    // If the value in the KeyValuePair is non-empty, it'll be used instead
+    // of the header value.
+    KeyValuePair on_header_present = 2;
+
+    // If the header is not present, apply this metadata KeyValuePair.
+    //
+    // The value in the KeyValuePair must be set, since it'll be used in lieu
+    // of the missing header value.
+    KeyValuePair on_header_missing = 3;
+
+    // Whether or not to remove the header after a rule is applied.
+    //
+    // This prevents headers from leaking.
+    bool remove = 4;
+  }
+
+  // The list of rules to apply to requests.
+  repeated Rule request_rules = 1;
+
+  // The list of rules to apply to responses.
+  repeated Rule response_rules = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/BUILD
new file mode 100644
index 0000000..9dc0af2
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/BUILD
@@ -0,0 +1,21 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_go_proto_library", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "health_check",
+    srcs = ["health_check.proto"],
+    deps = [
+        "//envoy/api/v2/route",
+        "//envoy/type:percent",
+    ],
+)
+
+api_go_proto_library(
+    name = "health_check",
+    proto = ":health_check",
+    deps = [
+        "//envoy/api/v2/route:route_go_proto",
+        "//envoy/type:percent_go_proto",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/health_check.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/health_check.proto
new file mode 100644
index 0000000..bc84337
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/health_check/v2/health_check.proto
@@ -0,0 +1,44 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.health_check.v2;
+
+option java_outer_classname = "HealthCheckProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.health_check.v2";
+option go_package = "v2";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/wrappers.proto";
+
+import "envoy/api/v2/route/route.proto";
+import "envoy/type/percent.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: Health check]
+// Health check :ref:`configuration overview <config_http_filters_health_check>`.
+
+message HealthCheck {
+  // Specifies whether the filter operates in pass through mode or not.
+  google.protobuf.BoolValue pass_through_mode = 1 [(validate.rules).message.required = true];
+
+  reserved 2;
+  reserved "endpoint";
+
+  // If operating in pass through mode, the amount of time in milliseconds
+  // that the filter should cache the upstream response.
+  google.protobuf.Duration cache_time = 3 [(gogoproto.stdduration) = true];
+
+  // If operating in non-pass-through mode, specifies a set of upstream cluster
+  // names and the minimum percentage of servers in each of those clusters that
+  // must be healthy or degraded in order for the filter to return a 200.
+  map<string, envoy.type.Percent> cluster_min_healthy_percentages = 4;
+
+  // Specifies a set of health check request headers to match on. The health check filter will
+  // check a request’s headers against all the specified headers. To specify the health check
+  // endpoint, set the ``:path`` header to match on.
+  repeated envoy.api.v2.route.HeaderMatcher headers = 5;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/BUILD
new file mode 100644
index 0000000..4c70019
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/BUILD
@@ -0,0 +1,9 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "ip_tagging",
+    srcs = ["ip_tagging.proto"],
+    deps = ["//envoy/api/v2/core:address"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto
new file mode 100644
index 0000000..4d0b4fe
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/ip_tagging/v2/ip_tagging.proto
@@ -0,0 +1,55 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.ip_tagging.v2;
+
+option java_outer_classname = "IpTaggingProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.ip_tagging.v2";
+option go_package = "v2";
+
+import "envoy/api/v2/core/address.proto";
+
+import "google/protobuf/wrappers.proto";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: IP tagging]
+// IP tagging :ref:`configuration overview <config_http_filters_ip_tagging>`.
+
+message IPTagging {
+
+  // The type of requests the filter should apply to. The supported types
+  // are internal, external or both. The
+  // :ref:`x-forwarded-for<config_http_conn_man_headers_x-forwarded-for_internal_origin>` header is
+  // used to determine if a request is internal and will result in
+  // :ref:`x-envoy-internal<config_http_conn_man_headers_x-envoy-internal>`
+  // being set. The filter defaults to both, and it will apply to all request types.
+  enum RequestType {
+    // Both external and internal requests will be tagged. This is the default value.
+    BOTH = 0;
+
+    // Only internal requests will be tagged.
+    INTERNAL = 1;
+
+    // Only external requests will be tagged.
+    EXTERNAL = 2;
+  }
+
+  // The type of request the filter should apply to.
+  RequestType request_type = 1 [(validate.rules).enum.defined_only = true];
+
+  // Supplies the IP tag name and the IP address subnets.
+  message IPTag {
+    // Specifies the IP tag name to apply.
+    string ip_tag_name = 1;
+
+    // A list of IP address subnets that will be tagged with
+    // ip_tag_name. Both IPv4 and IPv6 are supported.
+    repeated envoy.api.v2.core.CidrRange ip_list = 2;
+  }
+
+  // [#comment:TODO(ccaraman): Extend functionality to load IP tags from file system.
+  // Tracked by issue https://github.com/envoyproxy/envoy/issues/2695]
+  // The set of IP tags for the filter.
+  repeated IPTag ip_tags = 4 [(validate.rules).repeated .min_items = 1];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/BUILD
new file mode 100644
index 0000000..d637732
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/BUILD
@@ -0,0 +1,13 @@
+licenses(["notice"])  # Apache 2
+
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+api_proto_library_internal(
+    name = "jwt_authn",
+    srcs = ["config.proto"],
+    deps = [
+        "//envoy/api/v2/core:base",
+        "//envoy/api/v2/core:http_uri",
+        "//envoy/api/v2/route",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/README.md b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/README.md
new file mode 100644
index 0000000..9d08338
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/README.md
@@ -0,0 +1,31 @@
+# JWT Authentication HTTP filter config
+
+## Overview
+
+1. The proto file in this folder defines an HTTP filter config for "jwt_authn" filter.
+
+2. This filter will verify the JWT in the HTTP request as:
+    - The signature should be valid
+    - JWT should not be expired
+    - Issuer and audiences are valid and specified in the filter config.
+
+3. [JWK](https://tools.ietf.org/html/rfc7517#appendix-A) is needed to verify JWT signature. It can be fetched from a remote server or read from a local file. If the JWKS is fetched remotely, it will be cached by the filter.
+
+3. If a JWT is valid, the user is authenticated and the request will be forwarded to the backend server. If a JWT is not valid, the request will be rejected with an error message.
+
+## The locations to extract JWT
+
+JWT will be extracted from the HTTP headers or query parameters. The default location is the HTTP header:
+```
+Authorization: Bearer <token>
+```
+The next default location is in the query parameter as:
+```
+?access_token=<TOKEN>
+```
+
+If a custom location is desired, `from_headers` or `from_params` can be used to specify custom locations to extract JWT.
+
+## HTTP header to pass successfully verified JWT
+
+If a JWT is valid, its payload will be passed to the backend in a new HTTP header specified in `forward_payload_header` field. Its value is base64 encoded JWT payload in JSON.
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/config.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/config.proto
new file mode 100644
index 0000000..adb4461
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/jwt_authn/v2alpha/config.proto
@@ -0,0 +1,436 @@
+
+syntax = "proto3";
+
+package envoy.config.filter.http.jwt_authn.v2alpha;
+
+option java_outer_classname = "ConfigProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.jwt_authn.v2alpha";
+
+import "envoy/api/v2/core/base.proto";
+import "envoy/api/v2/core/http_uri.proto";
+import "envoy/api/v2/route/route.proto";
+import "google/protobuf/duration.proto";
+import "google/protobuf/empty.proto";
+import "google/protobuf/wrappers.proto";
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+option (gogoproto.stable_marshaler_all) = true;
+
+// [#protodoc-title: JWT Authentication]
+// JWT Authentication :ref:`configuration overview <config_http_filters_jwt_authn>`.
+
+// Please see following for JWT authentication flow:
+//
+// * `JSON Web Token (JWT) <https://tools.ietf.org/html/rfc7519>`_
+// * `The OAuth 2.0 Authorization Framework <https://tools.ietf.org/html/rfc6749>`_
+// * `OpenID Connect <http://openid.net/connect>`_
+//
+// A JwtProvider message specifies how a JSON Web Token (JWT) can be verified. It specifies:
+//
+// * issuer: the principal that issues the JWT. It has to match the one from the token.
+// * allowed audiences: the ones in the token have to be listed here.
+// * how to fetch public key JWKS to verify the token signature.
+// * how to extract JWT token in the request.
+// * how to pass successfully verified token payload.
+//
+// Example:
+//
+// .. code-block:: yaml
+//
+//     issuer: https://example.com
+//     audiences:
+//     - bookstore_android.apps.googleusercontent.com
+//     - bookstore_web.apps.googleusercontent.com
+//     remote_jwks:
+//       http_uri:
+//         uri: https://example.com/.well-known/jwks.json
+//         cluster: example_jwks_cluster
+//       cache_duration:
+//         seconds: 300
+//
+message JwtProvider {
+  // Specify the `principal <https://tools.ietf.org/html/rfc7519#section-4.1.1>`_ that issued
+  // the JWT, usually a URL or an email address.
+  //
+  // Example: https://securetoken.google.com
+  // Example: 1234567-compute@developer.gserviceaccount.com
+  //
+  string issuer = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The list of JWT `audiences <https://tools.ietf.org/html/rfc7519#section-4.1.3>`_ are
+  // allowed to access. A JWT containing any of these audiences will be accepted. If not specified,
+  // will not check audiences in the token.
+  //
+  // Example:
+  //
+  // .. code-block:: yaml
+  //
+  //     audiences:
+  //     - bookstore_android.apps.googleusercontent.com
+  //     - bookstore_web.apps.googleusercontent.com
+  //
+  repeated string audiences = 2;
+
+  // `JSON Web Key Set (JWKS) <https://tools.ietf.org/html/rfc7517#appendix-A>`_ is needed to
+  // validate signature of a JWT. This field specifies where to fetch JWKS.
+  oneof jwks_source_specifier {
+    option (validate.required) = true;
+
+    // JWKS can be fetched from remote server via HTTP/HTTPS. This field specifies the remote HTTP
+    // URI and how the fetched JWKS should be cached.
+    //
+    // Example:
+    //
+    // .. code-block:: yaml
+    //
+    //    remote_jwks:
+    //      http_uri:
+    //        uri: https://www.googleapis.com/oauth2/v1/certs
+    //        cluster: jwt.www.googleapis.com|443
+    //      cache_duration:
+    //        seconds: 300
+    //
+    RemoteJwks remote_jwks = 3;
+
+    // JWKS is in local data source. It could be either in a local file or embedded in the
+    // inline_string.
+    //
+    // Example: local file
+    //
+    // .. code-block:: yaml
+    //
+    //    local_jwks:
+    //      filename: /etc/envoy/jwks/jwks1.txt
+    //
+    // Example: inline_string
+    //
+    // .. code-block:: yaml
+    //
+    //    local_jwks:
+    //      inline_string: ACADADADADA
+    //
+    envoy.api.v2.core.DataSource local_jwks = 4;
+  }
+
+  // If false, the JWT is removed in the request after a success verification. If true, the JWT is
+  // not removed in the request. Default value is false.
+  bool forward = 5;
+
+  // Two fields below define where to extract the JWT from an HTTP request.
+  //
+  // If no explicit location is specified, the following default locations are tried in order:
+  //
+  // 1. The Authorization header using the `Bearer schema
+  // <https://tools.ietf.org/html/rfc6750#section-2.1>`_. Example::
+  //
+  //    Authorization: Bearer <token>.
+  //
+  // 2. `access_token <https://tools.ietf.org/html/rfc6750#section-2.3>`_ query parameter.
+  //
+  // Multiple JWTs can be verified for a request. Each JWT has to be extracted from the locations
+  // its provider specified or from the default locations.
+  //
+  // Specify the HTTP headers to extract JWT token. For examples, following config:
+  //
+  // .. code-block:: yaml
+  //
+  //   from_headers:
+  //   - name: x-goog-iap-jwt-assertion
+  //
+  // can be used to extract token from header::
+  //
+  //   x-goog-iap-jwt-assertion: <JWT>.
+  //
+  repeated JwtHeader from_headers = 6;
+
+  // JWT is sent in a query parameter. `jwt_params` represents the query parameter names.
+  //
+  // For example, if config is:
+  //
+  // .. code-block:: yaml
+  //
+  //   from_params:
+  //   - jwt_token
+  //
+  // The JWT format in query parameter is::
+  //
+  //    /path?jwt_token=<JWT>
+  //
+  repeated string from_params = 7;
+
+  // This field specifies the header name to forward a successfully verified JWT payload to the
+  // backend. The forwarded data is::
+  //
+  //    base64_encoded(jwt_payload_in_JSON)
+  //
+  // If it is not specified, the payload will not be forwarded.
+  string forward_payload_header = 8;
+
+  // If non empty, successfully verified JWT payloads will be written to StreamInfo DynamicMetadata
+  // in the format as: *namespace* is the jwt_authn filter name as **envoy.filters.http.jwt_authn**
+  // The value is the *protobuf::Struct*. The value of this field will be the key for its *fields*
+  // and the value is the *protobuf::Struct* converted from JWT JSON payload.
+  //
+  // For example, if payload_in_metadata is *my_payload*:
+  //
+  // .. code-block:: yaml
+  //
+  //   envoy.filters.http.jwt_authn:
+  //     my_payload:
+  //       iss: https://example.com
+  //       sub: test@example.com
+  //       aud: https://example.com
+  //       exp: 1501281058
+  //
+  string payload_in_metadata = 9;
+}
+
+// This message specifies how to fetch JWKS from remote and how to cache it.
+message RemoteJwks {
+  // The HTTP URI to fetch the JWKS. For example:
+  //
+  // .. code-block:: yaml
+  //
+  //    http_uri:
+  //      uri: https://www.googleapis.com/oauth2/v1/certs
+  //      cluster: jwt.www.googleapis.com|443
+  //
+  envoy.api.v2.core.HttpUri http_uri = 1;
+
+  // Duration after which the cached JWKS should be expired. If not specified, default cache
+  // duration is 5 minutes.
+  google.protobuf.Duration cache_duration = 2;
+}
+
+// This message specifies a header location to extract JWT token.
+message JwtHeader {
+  // The HTTP header name.
+  string name = 1 [(validate.rules).string.min_bytes = 1];
+
+  // The value prefix. The value format is "value_prefix<token>"
+  // For example, for "Authorization: Bearer <token>", value_prefix="Bearer " with a space at the
+  // end.
+  string value_prefix = 2;
+}
+
+// Specify a required provider with audiences.
+message ProviderWithAudiences {
+  // Specify a required provider name.
+  string provider_name = 1;
+
+  // This field overrides the one specified in the JwtProvider.
+  repeated string audiences = 2;
+}
+
+// This message specifies a Jwt requirement. An empty message means JWT verification is not
+// required. Here are some config examples:
+//
+// .. code-block:: yaml
+//
+//  # Example 1: not required with an empty message
+//
+//  # Example 2: require A
+//  provider_name: provider-A
+//
+//  # Example 3: require A or B
+//  requires_any:
+//    requirements:
+//      - provider_name: provider-A
+//      - provider_name: provider-B
+//
+//  # Example 4: require A and B
+//  requires_all:
+//    requirements:
+//      - provider_name: provider-A
+//      - provider_name: provider-B
+//
+//  # Example 5: require A and (B or C)
+//  requires_all:
+//    requirements:
+//      - provider_name: provider-A
+//      - requires_any:
+//        requirements:
+//          - provider_name: provider-B
+//          - provider_name: provider-C
+//
+//  # Example 6: require A or (B and C)
+//  requires_any:
+//    requirements:
+//      - provider_name: provider-A
+//      - requires_all:
+//        requirements:
+//          - provider_name: provider-B
+//          - provider_name: provider-C
+//
+message JwtRequirement {
+  oneof requires_type {
+    // Specify a required provider name.
+    string provider_name = 1;
+
+    // Specify a required provider with audiences.
+    ProviderWithAudiences provider_and_audiences = 2;
+
+    // Specify list of JwtRequirement. Their results are OR-ed.
+    // If any one of them passes, the result is passed.
+    JwtRequirementOrList requires_any = 3;
+
+    // Specify list of JwtRequirement. Their results are AND-ed.
+    // All of them must pass, if one of them fails or missing, it fails.
+    JwtRequirementAndList requires_all = 4;
+
+    // The requirement is always satisfied even if JWT is missing or the JWT
+    // verification fails. A typical usage is: this filter is used to only verify
+    // JWTs and pass the verified JWT payloads to another filter, the other filter
+    // will make decision. In this mode, all JWT tokens will be verified.
+    google.protobuf.Empty allow_missing_or_failed = 5;
+  }
+}
+
+// This message specifies a list of RequiredProvider.
+// Their results are OR-ed; if any one of them passes, the result is passed
+message JwtRequirementOrList {
+  // Specify a list of JwtRequirement.
+  repeated JwtRequirement requirements = 1 [(validate.rules).repeated .min_items = 2];
+}
+
+// This message specifies a list of RequiredProvider.
+// Their results are AND-ed; all of them must pass, if one of them fails or missing, it fails.
+message JwtRequirementAndList {
+  // Specify a list of JwtRequirement.
+  repeated JwtRequirement requirements = 1 [(validate.rules).repeated .min_items = 2];
+}
+
+// This message specifies a Jwt requirement for a specific Route condition.
+// Example 1:
+//
+// .. code-block:: yaml
+//
+//    - match:
+//        prefix: /healthz
+//
+// In above example, "requires" field is empty for /healthz prefix match,
+// it means that requests matching the path prefix don't require JWT authentication.
+//
+// Example 2:
+//
+// .. code-block:: yaml
+//
+//    - match:
+//        prefix: /
+//      requires: { provider_name: provider-A }
+//
+// In above example, all requests matched the path prefix require jwt authentication
+// from "provider-A".
+message RequirementRule {
+  // The route matching parameter. Only when the match is satisfied, the "requires" field will
+  // apply.
+  //
+  // For example: following match will match all requests.
+  //
+  // .. code-block:: yaml
+  //
+  //    match:
+  //      prefix: /
+  //
+  envoy.api.v2.route.RouteMatch match = 1 [(validate.rules).message.required = true];
+
+  // Specify a Jwt Requirement. Please detail comment in message JwtRequirement.
+  JwtRequirement requires = 2;
+}
+
+// This is the Envoy HTTP filter config for JWT authentication.
+//
+// For example:
+//
+// .. code-block:: yaml
+//
+//   providers:
+//      provider1:
+//        issuer: issuer1
+//        audiences:
+//        - audience1
+//        - audience2
+//        remote_jwks:
+//          http_uri:
+//            uri: https://example.com/.well-known/jwks.json
+//            cluster: example_jwks_cluster
+//      provider2:
+//        issuer: issuer2
+//        local_jwks:
+//          inline_string: jwks_string
+//
+//   rules:
+//      # Not jwt verification is required for /health path
+//      - match:
+//          prefix: /health
+//
+//      # Jwt verification for provider1 is required for path prefixed with "prefix"
+//      - match:
+//          prefix: /prefix
+//        requires:
+//          provider_name: provider1
+//
+//      # Jwt verification for either provider1 or provider2 is required for all other requests.
+//      - match:
+//          prefix: /
+//        requires:
+//          requires_any:
+//            requirements:
+//              - provider_name: provider1
+//              - provider_name: provider2
+//
+message JwtAuthentication {
+  // Map of provider names to JwtProviders.
+  //
+  // .. code-block:: yaml
+  //
+  //   providers:
+  //     provider1:
+  //        issuer: issuer1
+  //        audiences:
+  //        - audience1
+  //        - audience2
+  //        remote_jwks:
+  //          http_uri:
+  //            uri: https://example.com/.well-known/jwks.json
+  //            cluster: example_jwks_cluster
+  //      provider2:
+  //        issuer: provider2
+  //        local_jwks:
+  //          inline_string: jwks_string
+  //
+  map<string, JwtProvider> providers = 1;
+
+  // Specifies requirements based on the route matches. The first matched requirement will be
+  // applied. If there are overlapped match conditions, please put the most specific match first.
+  //
+  // Examples
+  //
+  // .. code-block:: yaml
+  //
+  // rules:
+  //   - match:
+  //       prefix: /healthz
+  //   - match:
+  //       prefix: /baz
+  //     requires:
+  //       provider_name: provider1
+  //   - match:
+  //       prefix: /foo
+  //     requires:
+  //       requires_any:
+  //         requirements:
+  //           - provider_name: provider1
+  //           - provider_name: provider2
+  //   - match:
+  //       prefix: /bar
+  //     requires:
+  //       requires_all:
+  //         requirements:
+  //           - provider_name: provider1
+  //           - provider_name: provider2
+  //
+  repeated RequirementRule rules = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/BUILD
new file mode 100644
index 0000000..6daf0c8
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/BUILD
@@ -0,0 +1,8 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "lua",
+    srcs = ["lua.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/lua.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/lua.proto
new file mode 100644
index 0000000..f29bcdb
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/lua/v2/lua.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.lua.v2;
+
+option java_outer_classname = "LuaProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.lua.v2";
+option go_package = "v2";
+
+import "validate/validate.proto";
+
+// [#protodoc-title: Lua]
+// Lua :ref:`configuration overview <config_http_filters_lua>`.
+
+message Lua {
+  // The Lua code that Envoy will execute. This can be a very small script that
+  // further loads code from disk if desired. Note that if JSON configuration is used, the code must
+  // be properly escaped. YAML configuration may be easier to read since YAML supports multi-line
+  // strings so complex scripts can be easily expressed inline in the configuration.
+  string inline_code = 1 [(validate.rules).string.min_bytes = 1];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/BUILD
new file mode 100644
index 0000000..d8fb8e7
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/BUILD
@@ -0,0 +1,11 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "rate_limit",
+    srcs = ["rate_limit.proto"],
+    deps = [
+        "//envoy/config/ratelimit/v2:rls",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/rate_limit.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/rate_limit.proto
new file mode 100644
index 0000000..9d93e4a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rate_limit/v2/rate_limit.proto
@@ -0,0 +1,60 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.rate_limit.v2;
+
+option java_outer_classname = "RateLimitProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.rate_limit.v2";
+option go_package = "v2";
+
+import "envoy/config/ratelimit/v2/rls.proto";
+
+import "google/protobuf/duration.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: Rate limit]
+// Rate limit :ref:`configuration overview <config_http_filters_rate_limit>`.
+
+message RateLimit {
+  // The rate limit domain to use when calling the rate limit service.
+  string domain = 1 [(validate.rules).string.min_bytes = 1];
+
+  // Specifies the rate limit configurations to be applied with the same
+  // stage number. If not set, the default stage number is 0.
+  //
+  // .. note::
+  //
+  //  The filter supports a range of 0 - 10 inclusively for stage numbers.
+  uint32 stage = 2 [(validate.rules).uint32.lte = 10];
+
+  // The type of requests the filter should apply to. The supported
+  // types are *internal*, *external* or *both*. A request is considered internal if
+  // :ref:`x-envoy-internal<config_http_conn_man_headers_x-envoy-internal>` is set to true. If
+  // :ref:`x-envoy-internal<config_http_conn_man_headers_x-envoy-internal>` is not set or false, a
+  // request is considered external. The filter defaults to *both*, and it will apply to all request
+  // types.
+  string request_type = 3;
+
+  // The timeout in milliseconds for the rate limit service RPC. If not
+  // set, this defaults to 20ms.
+  google.protobuf.Duration timeout = 4 [(gogoproto.stdduration) = true];
+
+  // The filter's behaviour in case the rate limiting service does
+  // not respond back. When it is set to true, Envoy will not allow traffic in case of
+  // communication failure between rate limiting service and the proxy.
+  // Defaults to false.
+  bool failure_mode_deny = 5;
+
+  // Specifies whether a `RESOURCE_EXHAUSTED` gRPC code must be returned instead
+  // of the default `UNAVAILABLE` gRPC code for a rate limited gRPC call. The
+  // HTTP code will be 200 for a gRPC response.
+  bool rate_limited_as_resource_exhausted = 6;
+
+  // Configuration for an external rate limit service provider. If not
+  // specified, any calls to the rate limit service will immediately return
+  // success.
+  envoy.config.ratelimit.v2.RateLimitServiceConfig rate_limit_service = 7
+      [(validate.rules).message.required = true];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/BUILD
new file mode 100644
index 0000000..9b95d40
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/BUILD
@@ -0,0 +1,9 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "rbac",
+    srcs = ["rbac.proto"],
+    deps = ["//envoy/config/rbac/v2alpha:rbac"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/rbac.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/rbac.proto
new file mode 100644
index 0000000..936d398
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/rbac/v2/rbac.proto
@@ -0,0 +1,38 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.rbac.v2;
+
+option java_outer_classname = "RbacProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.rbac.v2";
+option go_package = "v2";
+
+import "envoy/config/rbac/v2alpha/rbac.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: RBAC]
+// Role-Based Access Control :ref:`configuration overview <config_http_filters_rbac>`.
+
+// RBAC filter config.
+message RBAC {
+  // Specify the RBAC rules to be applied globally.
+  // If absent, no enforcing RBAC policy will be applied.
+  config.rbac.v2alpha.RBAC rules = 1;
+
+  // Shadow rules are not enforced by the filter (i.e., returning a 403)
+  // but will emit stats and logs and can be used for rule testing.
+  // If absent, no shadow RBAC policy will be applied.
+  config.rbac.v2alpha.RBAC shadow_rules = 2;
+}
+
+message RBACPerRoute {
+  reserved 1;
+
+  reserved "disabled";
+
+  // Override the global configuration of the filter with this new config.
+  // If absent, the global RBAC policy will be disabled for this route.
+  RBAC rbac = 2;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/BUILD
new file mode 100644
index 0000000..990d815
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/BUILD
@@ -0,0 +1,9 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "router",
+    srcs = ["router.proto"],
+    deps = ["//envoy/config/filter/accesslog/v2:accesslog"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/router.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/router.proto
new file mode 100644
index 0000000..02115cb
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/router/v2/router.proto
@@ -0,0 +1,39 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.router.v2;
+
+option java_outer_classname = "RouterProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.router.v2";
+option go_package = "v2";
+
+import "envoy/config/filter/accesslog/v2/accesslog.proto";
+
+import "google/protobuf/wrappers.proto";
+
+// [#protodoc-title: Router]
+// Router :ref:`configuration overview <config_http_filters_router>`.
+
+message Router {
+  // Whether the router generates dynamic cluster statistics. Defaults to
+  // true. Can be disabled in high performance scenarios.
+  google.protobuf.BoolValue dynamic_stats = 1;
+
+  // Whether to start a child span for egress routed calls. This can be
+  // useful in scenarios where other filters (auth, ratelimit, etc.) make
+  // outbound calls and have child spans rooted at the same ingress
+  // parent. Defaults to false.
+  bool start_child_span = 2;
+
+  // Configuration for HTTP upstream logs emitted by the router. Upstream logs
+  // are configured in the same way as access logs, but each log entry represents
+  // an upstream request. Presuming retries are configured, multiple upstream
+  // requests may be made for each downstream (inbound) request.
+  repeated envoy.config.filter.accesslog.v2.AccessLog upstream_log = 3;
+
+  // Do not add any additional *x-envoy-* headers to requests or responses. This
+  // only affects the :ref:`router filter generated *x-envoy-* headers
+  // <config_http_filters_router_headers_set>`, other Envoy filters and the HTTP
+  // connection manager may continue to set *x-envoy-* headers.
+  bool suppress_envoy_headers = 4;
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/BUILD
new file mode 100644
index 0000000..86bd4e8
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/BUILD
@@ -0,0 +1,8 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "squash",
+    srcs = ["squash.proto"],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/squash.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/squash.proto
new file mode 100644
index 0000000..006af43
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/squash/v2/squash.proto
@@ -0,0 +1,55 @@
+syntax = "proto3";
+
+package envoy.config.filter.http.squash.v2;
+
+option java_outer_classname = "SquashProto";
+option java_multiple_files = true;
+option java_package = "io.envoyproxy.envoy.config.filter.http.squash.v2";
+option go_package = "v2";
+
+import "google/protobuf/duration.proto";
+import "google/protobuf/struct.proto";
+
+import "validate/validate.proto";
+import "gogoproto/gogo.proto";
+
+// [#protodoc-title: Squash]
+// Squash :ref:`configuration overview <config_http_filters_squash>`.
+
+// [#proto-status: experimental]
+message Squash {
+  // The name of the cluster that hosts the Squash server.
+  string cluster = 1 [(validate.rules).string.min_bytes = 1];
+
+  // When the filter requests the Squash server to create a DebugAttachment, it will use this
+  // structure as template for the body of the request. It can contain reference to environment
+  // variables in the form of '{{ ENV_VAR_NAME }}'. These can be used to provide the Squash server
+  // with more information to find the process to attach the debugger to. For example, in a
+  // Istio/k8s environment, this will contain information on the pod:
+  //
+  // .. code-block:: json
+  //
+  //  {
+  //    "spec": {
+  //      "attachment": {
+  //        "pod": "{{ POD_NAME }}",
+  //        "namespace": "{{ POD_NAMESPACE }}"
+  //      },
+  //      "match_request": true
+  //    }
+  //  }
+  //
+  // (where POD_NAME, POD_NAMESPACE are configured in the pod via the Downward API)
+  google.protobuf.Struct attachment_template = 2;
+
+  // The timeout for individual requests sent to the Squash cluster. Defaults to 1 second.
+  google.protobuf.Duration request_timeout = 3 [(gogoproto.stdduration) = true];
+
+  // The total timeout Squash will delay a request and wait for it to be attached. Defaults to 60
+  // seconds.
+  google.protobuf.Duration attachment_timeout = 4 [(gogoproto.stdduration) = true];
+
+  // Amount of time to poll for the status of the attachment object in the Squash server
+  // (to check if has been attached). Defaults to 1 second.
+  google.protobuf.Duration attachment_poll_period = 5 [(gogoproto.stdduration) = true];
+}
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/BUILD b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/BUILD
new file mode 100644
index 0000000..f84625a
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/BUILD
@@ -0,0 +1,11 @@
+load("@envoy_api//bazel:api_build_system.bzl", "api_proto_library_internal")
+
+licenses(["notice"])  # Apache 2
+
+api_proto_library_internal(
+    name = "tap",
+    srcs = ["tap.proto"],
+    deps = [
+        "//envoy/config/common/tap/v2alpha:common",
+    ],
+)
diff --git a/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/tap.proto b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/tap.proto
new file mode 100644
index 0000000..10d7bdd
--- /dev/null
+++ b/dubbo-remoting/dubbo-remoting-pilot/src/main/proto/envoy/config/filter/http/tap/v2alpha/tap.proto
@@ -0,0 +1,21 @@
+syntax = "proto3";
... 7852 lines suppressed ...