From b2164837a81d7aef9e8f1ac590d8a973b95acdba Mon Sep 17 00:00:00 2001 From: "Mark D. Roth" Date: Thu, 11 Feb 2021 12:47:05 -0800 Subject: [PATCH] xDS HTTP filter support for gRPC client --- BUILD | 47 ++ BUILD.gn | 10 + CMakeLists.txt | 12 + Makefile | 10 + build_autogenerated.yaml | 11 + config.m4 | 9 + config.w32 | 15 + gRPC-C++.podspec | 10 + gRPC-Core.podspec | 15 + grpc.gemspec | 10 + grpc.gyp | 5 + package.xml | 10 + .../filters/client_channel/client_channel.cc | 3 +- .../filters/client_channel/config_selector.h | 8 + .../filters/client_channel/dynamic_filters.cc | 13 +- .../resolver/xds/xds_resolver.cc | 259 ++++++-- .../filters/http/router/v3/router.upb.c | 41 ++ .../filters/http/router/v3/router.upb.h | 113 ++++ .../udpa/type/v1/typed_struct.upb.c | 33 + .../udpa/type/v1/typed_struct.upb.h | 77 +++ .../filters/http/router/v3/router.upbdefs.c | 76 +++ .../filters/http/router/v3/router.upbdefs.h | 35 ++ .../udpa/type/v1/typed_struct.upbdefs.c | 44 ++ .../udpa/type/v1/typed_struct.upbdefs.h | 35 ++ src/core/ext/xds/xds_api.cc | 580 +++++++++++++----- src/core/ext/xds/xds_api.h | 52 +- src/core/ext/xds/xds_client.cc | 10 +- src/core/ext/xds/xds_http_filters.cc | 107 ++++ src/core/ext/xds/xds_http_filters.h | 124 ++++ src/core/lib/channel/channel_stack.cc | 12 + src/core/lib/channel/channel_stack.h | 7 + src/core/lib/surface/lame_client.cc | 57 +- src/core/lib/surface/lame_client.h | 7 +- src/proto/grpc/testing/xds/v3/BUILD | 8 + .../xds/v3/http_connection_manager.proto | 22 + src/proto/grpc/testing/xds/v3/route.proto | 32 + src/proto/grpc/testing/xds/v3/router.proto | 28 + src/python/grpcio/grpc_core_dependencies.py | 5 + test/cpp/end2end/BUILD | 1 + test/cpp/end2end/xds_end2end_test.cc | 559 +++++++++++++++-- tools/codegen/core/gen_upb_api.sh | 2 + tools/doxygen/Doxyfile.c++.internal | 10 + tools/doxygen/Doxyfile.core.internal | 10 + 43 files changed, 2242 insertions(+), 292 deletions(-) create mode 100644 src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c create mode 100644 src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h create mode 100644 src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c create mode 100644 src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h create mode 100644 src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c create mode 100644 src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h create mode 100644 src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c create mode 100644 src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h create mode 100644 src/core/ext/xds/xds_http_filters.cc create mode 100644 src/core/ext/xds/xds_http_filters.h create mode 100644 src/proto/grpc/testing/xds/v3/router.proto diff --git a/BUILD b/BUILD index 2daac9131ea..778b365ff04 100644 --- a/BUILD +++ b/BUILD @@ -1375,6 +1375,7 @@ grpc_cc_library( "src/core/ext/xds/xds_certificate_provider.cc", "src/core/ext/xds/xds_client.cc", "src/core/ext/xds/xds_client_stats.cc", + "src/core/ext/xds/xds_http_filters.cc", "src/core/lib/security/credentials/xds/xds_credentials.cc", ], hdrs = [ @@ -1388,6 +1389,7 @@ grpc_cc_library( "src/core/ext/xds/xds_channel_args.h", "src/core/ext/xds/xds_client.h", "src/core/ext/xds/xds_client_stats.h", + "src/core/ext/xds/xds_http_filters.h", "src/core/lib/security/credentials/xds/xds_credentials.h", ], external_deps = [ @@ -1405,6 +1407,8 @@ grpc_cc_library( "grpc_client_channel", "grpc_secure", "grpc_transport_chttp2_client_secure", + "udpa_type_upb", + "udpa_type_upbdefs", ], ) @@ -2646,6 +2650,7 @@ grpc_cc_library( "src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c", "src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c", "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c", "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c", "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c", "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c", @@ -2679,6 +2684,7 @@ grpc_cc_library( "src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h", "src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h", "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h", "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h", "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h", "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h", @@ -2729,6 +2735,7 @@ grpc_cc_library( "src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c", @@ -2761,6 +2768,7 @@ grpc_cc_library( "src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h", @@ -3193,6 +3201,45 @@ grpc_cc_library( ], ) +grpc_cc_library( + name = "udpa_type_upb", + srcs = [ + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c", + ], + hdrs = [ + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h", + ], + external_deps = [ + "upb_lib", + "upb_lib_descriptor", + ], + language = "c++", + deps = [ + ":google_api_upb", + ":proto_gen_validate_upb", + ], +) + +grpc_cc_library( + name = "udpa_type_upbdefs", + srcs = [ + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c", + ], + hdrs = [ + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h", + ], + external_deps = [ + "upb_lib", + "upb_lib_descriptor_reflection", + "upb_textformat_lib", + ], + language = "c++", + deps = [ + ":google_api_upbdefs", + ":proto_gen_validate_upbdefs", + ], +) + # Once upb code-gen issue is resolved, replace grpc_health_upb with this. # grpc_upb_proto_library( # name = "grpc_health_upb", diff --git a/BUILD.gn b/BUILD.gn index 42d09d4f16c..ddaeda86644 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -462,6 +462,8 @@ config("grpc_config") { "src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h", "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c", "src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c", + "src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h", "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c", "src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h", "src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c", @@ -556,6 +558,8 @@ config("grpc_config") { "src/core/ext/upb-generated/udpa/annotations/versioning.upb.h", "src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c", "src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h", + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c", + "src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h", "src/core/ext/upb-generated/validate/validate.upb.c", "src/core/ext/upb-generated/validate/validate.upb.h", "src/core/ext/upb-generated/xds/core/v3/authority.upb.c", @@ -634,6 +638,8 @@ config("grpc_config") { "src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c", + "src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c", "src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h", "src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c", @@ -712,6 +718,8 @@ config("grpc_config") { "src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h", "src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c", "src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h", + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c", + "src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h", "src/core/ext/upbdefs-generated/validate/validate.upbdefs.c", "src/core/ext/upbdefs-generated/validate/validate.upbdefs.h", "src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c", @@ -744,6 +752,8 @@ config("grpc_config") { "src/core/ext/xds/xds_client.h", "src/core/ext/xds/xds_client_stats.cc", "src/core/ext/xds/xds_client_stats.h", + "src/core/ext/xds/xds_http_filters.cc", + "src/core/ext/xds/xds_http_filters.h", "src/core/ext/xds/xds_server_config_fetcher.cc", "src/core/lib/avl/avl.cc", "src/core/lib/avl/avl.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index f4eb3b63967..650d9a9976e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -502,6 +502,9 @@ protobuf_generate_grpc_cpp( protobuf_generate_grpc_cpp( src/proto/grpc/testing/xds/v3/route.proto ) +protobuf_generate_grpc_cpp( + src/proto/grpc/testing/xds/v3/router.proto +) protobuf_generate_grpc_cpp( src/proto/grpc/testing/xds/v3/string.proto ) @@ -1589,6 +1592,7 @@ add_library(grpc src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c + src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c @@ -1636,6 +1640,7 @@ add_library(grpc src/core/ext/upb-generated/udpa/annotations/status.upb.c src/core/ext/upb-generated/udpa/annotations/versioning.upb.c src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c + src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c src/core/ext/upb-generated/validate/validate.upb.c src/core/ext/upb-generated/xds/core/v3/authority.upb.c src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c @@ -1675,6 +1680,7 @@ add_library(grpc src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c + src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c @@ -1714,6 +1720,7 @@ add_library(grpc src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c + src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c src/core/ext/upbdefs-generated/validate/validate.upbdefs.c src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c @@ -1729,6 +1736,7 @@ add_library(grpc src/core/ext/xds/xds_certificate_provider.cc src/core/ext/xds/xds_client.cc src/core/ext/xds/xds_client_stats.cc + src/core/ext/xds/xds_http_filters.cc src/core/ext/xds/xds_server_config_fetcher.cc src/core/lib/avl/avl.cc src/core/lib/backoff/backoff.cc @@ -15710,6 +15718,10 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX) ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/route.grpc.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.cc + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.pb.h + ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/router.grpc.pb.h ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.grpc.pb.cc ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/xds/v3/string.pb.h diff --git a/Makefile b/Makefile index c8b6037044b..0d270f97ab6 100644 --- a/Makefile +++ b/Makefile @@ -1172,6 +1172,7 @@ LIBGRPC_SRC = \ src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c \ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c \ + src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \ @@ -1219,6 +1220,7 @@ LIBGRPC_SRC = \ src/core/ext/upb-generated/udpa/annotations/status.upb.c \ src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \ + src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c \ src/core/ext/upb-generated/validate/validate.upb.c \ src/core/ext/upb-generated/xds/core/v3/authority.upb.c \ src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c \ @@ -1258,6 +1260,7 @@ LIBGRPC_SRC = \ src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \ + src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \ @@ -1297,6 +1300,7 @@ LIBGRPC_SRC = \ src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \ + src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \ src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c \ src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c \ @@ -1312,6 +1316,7 @@ LIBGRPC_SRC = \ src/core/ext/xds/xds_certificate_provider.cc \ src/core/ext/xds/xds_client.cc \ src/core/ext/xds/xds_client_stats.cc \ + src/core/ext/xds/xds_http_filters.cc \ src/core/ext/xds/xds_server_config_fetcher.cc \ src/core/lib/avl/avl.cc \ src/core/lib/backoff/backoff.cc \ @@ -2698,6 +2703,7 @@ src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c: $(OPENS src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c: $(OPENSSL_DEP) +src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c: $(OPENSSL_DEP) @@ -2731,6 +2737,7 @@ src/core/ext/upb-generated/udpa/annotations/security.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/udpa/annotations/sensitive.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/udpa/annotations/status.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/udpa/annotations/versioning.upb.c: $(OPENSSL_DEP) +src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/xds/core/v3/authority.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c: $(OPENSSL_DEP) src/core/ext/upb-generated/xds/core/v3/context_params.upb.c: $(OPENSSL_DEP) @@ -2769,6 +2776,7 @@ src/core/ext/upbdefs-generated/envoy/config/route/v3/route_components.upbdefs.c: src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c: $(OPENSSL_DEP) +src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c: $(OPENSSL_DEP) @@ -2808,6 +2816,7 @@ src/core/ext/upbdefs-generated/udpa/annotations/security.upbdefs.c: $(OPENSSL_DE src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c: $(OPENSSL_DEP) +src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/validate/validate.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c: $(OPENSSL_DEP) src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c: $(OPENSSL_DEP) @@ -2823,6 +2832,7 @@ src/core/ext/xds/xds_bootstrap.cc: $(OPENSSL_DEP) src/core/ext/xds/xds_certificate_provider.cc: $(OPENSSL_DEP) src/core/ext/xds/xds_client.cc: $(OPENSSL_DEP) src/core/ext/xds/xds_client_stats.cc: $(OPENSSL_DEP) +src/core/ext/xds/xds_http_filters.cc: $(OPENSSL_DEP) src/core/ext/xds/xds_server_config_fetcher.cc: $(OPENSSL_DEP) src/core/lib/http/httpcli_security_connector.cc: $(OPENSSL_DEP) src/core/lib/security/authorization/authorization_engine.cc: $(OPENSSL_DEP) diff --git a/build_autogenerated.yaml b/build_autogenerated.yaml index 11573c2545d..b704e8f58c6 100644 --- a/build_autogenerated.yaml +++ b/build_autogenerated.yaml @@ -500,6 +500,7 @@ libs: - src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h - src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h - src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h + - src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h - src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h - src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h - src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h @@ -547,6 +548,7 @@ libs: - src/core/ext/upb-generated/udpa/annotations/status.upb.h - src/core/ext/upb-generated/udpa/annotations/versioning.upb.h - src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h + - src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h - src/core/ext/upb-generated/validate/validate.upb.h - src/core/ext/upb-generated/xds/core/v3/authority.upb.h - src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h @@ -586,6 +588,7 @@ libs: - src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h - src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h - src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h + - src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h - src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h - src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h - src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h @@ -625,6 +628,7 @@ libs: - src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h - src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h - src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h + - src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h - src/core/ext/upbdefs-generated/validate/validate.upbdefs.h - src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.h - src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.h @@ -642,6 +646,7 @@ libs: - src/core/ext/xds/xds_channel_args.h - src/core/ext/xds/xds_client.h - src/core/ext/xds/xds_client_stats.h + - src/core/ext/xds/xds_http_filters.h - src/core/lib/avl/avl.h - src/core/lib/backoff/backoff.h - src/core/lib/channel/channel_args.h @@ -1006,6 +1011,7 @@ libs: - src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c - src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c - src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c + - src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c - src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c - src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c - src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c @@ -1053,6 +1059,7 @@ libs: - src/core/ext/upb-generated/udpa/annotations/status.upb.c - src/core/ext/upb-generated/udpa/annotations/versioning.upb.c - src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c + - src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c - src/core/ext/upb-generated/validate/validate.upb.c - src/core/ext/upb-generated/xds/core/v3/authority.upb.c - src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c @@ -1092,6 +1099,7 @@ libs: - src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c - src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c - src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c + - src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c - src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c - src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c - src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c @@ -1131,6 +1139,7 @@ libs: - src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c - src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c - src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c + - src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c - src/core/ext/upbdefs-generated/validate/validate.upbdefs.c - src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c - src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c @@ -1146,6 +1155,7 @@ libs: - src/core/ext/xds/xds_certificate_provider.cc - src/core/ext/xds/xds_client.cc - src/core/ext/xds/xds_client_stats.cc + - src/core/ext/xds/xds_http_filters.cc - src/core/ext/xds/xds_server_config_fetcher.cc - src/core/lib/avl/avl.cc - src/core/lib/backoff/backoff.cc @@ -8020,6 +8030,7 @@ targets: - src/proto/grpc/testing/xds/v3/range.proto - src/proto/grpc/testing/xds/v3/regex.proto - src/proto/grpc/testing/xds/v3/route.proto + - src/proto/grpc/testing/xds/v3/router.proto - src/proto/grpc/testing/xds/v3/string.proto - src/proto/grpc/testing/xds/v3/tls.proto - test/cpp/end2end/test_service_impl.cc diff --git a/config.m4 b/config.m4 index cc6a6b1048b..fa847df36eb 100644 --- a/config.m4 +++ b/config.m4 @@ -177,6 +177,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c \ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c \ + src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c \ @@ -225,6 +226,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upb-generated/udpa/annotations/status.upb.c \ src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \ + src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c \ src/core/ext/upb-generated/validate/validate.upb.c \ src/core/ext/upb-generated/xds/core/v3/authority.upb.c \ src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c \ @@ -264,6 +266,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \ + src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c \ @@ -304,6 +307,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \ + src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \ src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c \ src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c \ @@ -319,6 +323,7 @@ if test "$PHP_GRPC" != "no"; then src/core/ext/xds/xds_certificate_provider.cc \ src/core/ext/xds/xds_client.cc \ src/core/ext/xds/xds_client_stats.cc \ + src/core/ext/xds/xds_http_filters.cc \ src/core/ext/xds/xds_server_config_fetcher.cc \ src/core/lib/avl/avl.cc \ src/core/lib/backoff/backoff.cc \ @@ -1053,6 +1058,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/route/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/config/trace/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/envoy/service/cluster/v3) @@ -1074,6 +1080,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/src/proto/grpc/lb/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/udpa/annotations) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/udpa/data/orca/v1) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/udpa/type/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/validate) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upb-generated/xds/core/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/annotations) @@ -1085,6 +1092,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/route/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/config/trace/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/envoy/service/cluster/v3) @@ -1101,6 +1109,7 @@ if test "$PHP_GRPC" != "no"; then PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/protobuf) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/google/rpc) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/udpa/annotations) + PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/udpa/type/v1) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/validate) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/upbdefs-generated/xds/core/v3) PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/xds) diff --git a/config.w32 b/config.w32 index 03662fc78a1..d45a565d962 100644 --- a/config.w32 +++ b/config.w32 @@ -144,6 +144,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upb-generated\\envoy\\config\\route\\v3\\scoped_route.upb.c " + "src\\core\\ext\\upb-generated\\envoy\\config\\trace\\v3\\http_tracer.upb.c " + "src\\core\\ext\\upb-generated\\envoy\\extensions\\clusters\\aggregate\\v3\\cluster.upb.c " + + "src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http\\router\\v3\\router.upb.c " + "src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3\\http_connection_manager.upb.c " + "src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\cert.upb.c " + "src\\core\\ext\\upb-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\common.upb.c " + @@ -192,6 +193,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upb-generated\\udpa\\annotations\\status.upb.c " + "src\\core\\ext\\upb-generated\\udpa\\annotations\\versioning.upb.c " + "src\\core\\ext\\upb-generated\\udpa\\data\\orca\\v1\\orca_load_report.upb.c " + + "src\\core\\ext\\upb-generated\\udpa\\type\\v1\\typed_struct.upb.c " + "src\\core\\ext\\upb-generated\\validate\\validate.upb.c " + "src\\core\\ext\\upb-generated\\xds\\core\\v3\\authority.upb.c " + "src\\core\\ext\\upb-generated\\xds\\core\\v3\\collection_entry.upb.c " + @@ -231,6 +233,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upbdefs-generated\\envoy\\config\\route\\v3\\scoped_route.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\envoy\\config\\trace\\v3\\http_tracer.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\clusters\\aggregate\\v3\\cluster.upbdefs.c " + + "src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\http\\router\\v3\\router.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3\\http_connection_manager.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\cert.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\transport_sockets\\tls\\v3\\common.upbdefs.c " + @@ -271,6 +274,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\sensitive.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\status.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\udpa\\annotations\\versioning.upbdefs.c " + + "src\\core\\ext\\upbdefs-generated\\udpa\\type\\v1\\typed_struct.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\validate\\validate.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\xds\\core\\v3\\authority.upbdefs.c " + "src\\core\\ext\\upbdefs-generated\\xds\\core\\v3\\collection_entry.upbdefs.c " + @@ -286,6 +290,7 @@ if (PHP_GRPC != "no") { "src\\core\\ext\\xds\\xds_certificate_provider.cc " + "src\\core\\ext\\xds\\xds_client.cc " + "src\\core\\ext\\xds\\xds_client_stats.cc " + + "src\\core\\ext\\xds\\xds_http_filters.cc " + "src\\core\\ext\\xds\\xds_server_config_fetcher.cc " + "src\\core\\lib\\avl\\avl.cc " + "src\\core\\lib\\backoff\\backoff.cc " + @@ -1071,6 +1076,9 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\clusters\\aggregate"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\clusters\\aggregate\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http\\router"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\http\\router\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3"); @@ -1117,6 +1125,8 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\udpa\\data"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\udpa\\data\\orca"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\udpa\\data\\orca\\v1"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\udpa\\type"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\udpa\\type\\v1"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\validate"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\xds"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upb-generated\\xds\\core"); @@ -1144,6 +1154,9 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\clusters\\aggregate"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\clusters\\aggregate\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\http"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\http\\router"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\http\\router\\v3"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\network"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\network\\http_connection_manager"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\envoy\\extensions\\filters\\network\\http_connection_manager\\v3"); @@ -1177,6 +1190,8 @@ if (PHP_GRPC != "no") { FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\google\\rpc"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa\\annotations"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa\\type"); + FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\udpa\\type\\v1"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\validate"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\xds"); FSO.CreateFolder(base_dir+"\\ext\\grpc\\src\\core\\ext\\upbdefs-generated\\xds\\core"); diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec index 61f45bb0a25..69f5b8290e0 100644 --- a/gRPC-C++.podspec +++ b/gRPC-C++.podspec @@ -315,6 +315,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h', 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h', @@ -363,6 +364,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/udpa/annotations/status.upb.h', 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.h', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h', 'src/core/ext/upb-generated/validate/validate.upb.h', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.h', 'src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h', @@ -402,6 +404,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h', @@ -442,6 +445,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.h', @@ -459,6 +463,7 @@ Pod::Spec.new do |s| 'src/core/ext/xds/xds_channel_args.h', 'src/core/ext/xds/xds_client.h', 'src/core/ext/xds/xds_client_stats.h', + 'src/core/ext/xds/xds_http_filters.h', 'src/core/lib/avl/avl.h', 'src/core/lib/backoff/backoff.h', 'src/core/lib/channel/channel_args.h', @@ -936,6 +941,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h', 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h', @@ -984,6 +990,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/udpa/annotations/status.upb.h', 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.h', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h', 'src/core/ext/upb-generated/validate/validate.upb.h', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.h', 'src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h', @@ -1023,6 +1030,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h', @@ -1063,6 +1071,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.h', @@ -1080,6 +1089,7 @@ Pod::Spec.new do |s| 'src/core/ext/xds/xds_channel_args.h', 'src/core/ext/xds/xds_client.h', 'src/core/ext/xds/xds_client_stats.h', + 'src/core/ext/xds/xds_http_filters.h', 'src/core/lib/avl/avl.h', 'src/core/lib/backoff/backoff.h', 'src/core/lib/channel/channel_args.h', diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 57b0e194884..91aebaa6dd6 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -442,6 +442,8 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c', @@ -538,6 +540,8 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.h', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h', 'src/core/ext/upb-generated/validate/validate.upb.c', 'src/core/ext/upb-generated/validate/validate.upb.h', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.c', @@ -616,6 +620,8 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c', @@ -696,6 +702,8 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.c', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c', @@ -728,6 +736,8 @@ Pod::Spec.new do |s| 'src/core/ext/xds/xds_client.h', 'src/core/ext/xds/xds_client_stats.cc', 'src/core/ext/xds/xds_client_stats.h', + 'src/core/ext/xds/xds_http_filters.cc', + 'src/core/ext/xds/xds_http_filters.h', 'src/core/ext/xds/xds_server_config_fetcher.cc', 'src/core/lib/avl/avl.cc', 'src/core/lib/avl/avl.h', @@ -1472,6 +1482,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h', 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.h', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h', @@ -1520,6 +1531,7 @@ Pod::Spec.new do |s| 'src/core/ext/upb-generated/udpa/annotations/status.upb.h', 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.h', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h', 'src/core/ext/upb-generated/validate/validate.upb.h', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.h', 'src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.h', @@ -1559,6 +1571,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.h', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.h', @@ -1599,6 +1612,7 @@ Pod::Spec.new do |s| 'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.h', 'src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.h', @@ -1616,6 +1630,7 @@ Pod::Spec.new do |s| 'src/core/ext/xds/xds_channel_args.h', 'src/core/ext/xds/xds_client.h', 'src/core/ext/xds/xds_client_stats.h', + 'src/core/ext/xds/xds_http_filters.h', 'src/core/lib/avl/avl.h', 'src/core/lib/backoff/backoff.h', 'src/core/lib/channel/channel_args.h', diff --git a/grpc.gemspec b/grpc.gemspec index 5c3d0a5ccad..f5065a5d22d 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -357,6 +357,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h ) s.files += %w( src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c ) s.files += %w( src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h ) + s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c ) + s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h ) s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c ) s.files += %w( src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h ) s.files += %w( src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c ) @@ -453,6 +455,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upb-generated/udpa/annotations/versioning.upb.h ) s.files += %w( src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c ) s.files += %w( src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h ) + s.files += %w( src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c ) + s.files += %w( src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h ) s.files += %w( src/core/ext/upb-generated/validate/validate.upb.c ) s.files += %w( src/core/ext/upb-generated/validate/validate.upb.h ) s.files += %w( src/core/ext/upb-generated/xds/core/v3/authority.upb.c ) @@ -531,6 +535,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h ) + s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c ) + s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c ) @@ -611,6 +617,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h ) + s.files += %w( src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c ) + s.files += %w( src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/validate/validate.upbdefs.c ) s.files += %w( src/core/ext/upbdefs-generated/validate/validate.upbdefs.h ) s.files += %w( src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c ) @@ -643,6 +651,8 @@ Gem::Specification.new do |s| s.files += %w( src/core/ext/xds/xds_client.h ) s.files += %w( src/core/ext/xds/xds_client_stats.cc ) s.files += %w( src/core/ext/xds/xds_client_stats.h ) + s.files += %w( src/core/ext/xds/xds_http_filters.cc ) + s.files += %w( src/core/ext/xds/xds_http_filters.h ) s.files += %w( src/core/ext/xds/xds_server_config_fetcher.cc ) s.files += %w( src/core/lib/avl/avl.cc ) s.files += %w( src/core/lib/avl/avl.h ) diff --git a/grpc.gyp b/grpc.gyp index 06527d923a6..15b2d727c38 100644 --- a/grpc.gyp +++ b/grpc.gyp @@ -591,6 +591,7 @@ 'src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c', 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c', @@ -638,6 +639,7 @@ 'src/core/ext/upb-generated/udpa/annotations/status.upb.c', 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.c', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c', 'src/core/ext/upb-generated/validate/validate.upb.c', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.c', 'src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c', @@ -677,6 +679,7 @@ 'src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c', @@ -716,6 +719,7 @@ 'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c', 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.c', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c', 'src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c', @@ -731,6 +735,7 @@ 'src/core/ext/xds/xds_certificate_provider.cc', 'src/core/ext/xds/xds_client.cc', 'src/core/ext/xds/xds_client_stats.cc', + 'src/core/ext/xds/xds_http_filters.cc', 'src/core/ext/xds/xds_server_config_fetcher.cc', 'src/core/lib/avl/avl.cc', 'src/core/lib/backoff/backoff.cc', diff --git a/package.xml b/package.xml index 4368ed9d9e3..56873582e2f 100644 --- a/package.xml +++ b/package.xml @@ -337,6 +337,8 @@ + + @@ -433,6 +435,8 @@ + + @@ -511,6 +515,8 @@ + + @@ -591,6 +597,8 @@ + + @@ -623,6 +631,8 @@ + + diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc index 1171f38aa74..455e1460c4f 100644 --- a/src/core/ext/filters/client_channel/client_channel.cc +++ b/src/core/ext/filters/client_channel/client_channel.cc @@ -2297,7 +2297,7 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked() { server_name_, retry_throttle_config.value().max_milli_tokens, retry_throttle_config.value().milli_token_ratio); } - // Construct per-LB filter stack. + // Construct dynamic filter stack. std::vector filters = config_selector->GetFilters(); filters.push_back(&kDynamicTerminationFilterVtable); @@ -2312,6 +2312,7 @@ void ChannelData::UpdateServiceConfigInDataPlaneLocked() { } grpc_channel_args* new_args = grpc_channel_args_copy_and_add( channel_args_, args_to_add.data(), args_to_add.size()); + new_args = config_selector->ModifyChannelArgs(new_args); RefCountedPtr dynamic_filters = DynamicFilters::Create(new_args, std::move(filters)); GPR_ASSERT(dynamic_filters != nullptr); diff --git a/src/core/ext/filters/client_channel/config_selector.h b/src/core/ext/filters/client_channel/config_selector.h index 6e41faaecaa..61916d2bc3a 100644 --- a/src/core/ext/filters/client_channel/config_selector.h +++ b/src/core/ext/filters/client_channel/config_selector.h @@ -82,8 +82,16 @@ class ConfigSelector : public RefCounted { return cs1->Equals(cs2); } + // The channel will call this when the resolver returns a new ConfigSelector + // to determine what set of dynamic filters will be configured. virtual std::vector GetFilters() { return {}; } + // Modifies channel args to be passed to the dynamic filter stack. + // Takes ownership of argument. Caller takes ownership of result. + virtual grpc_channel_args* ModifyChannelArgs(grpc_channel_args* args) { + return args; + } + virtual CallConfig GetCallConfig(GetCallConfigArgs args) = 0; grpc_arg MakeChannelArg() const; diff --git a/src/core/ext/filters/client_channel/dynamic_filters.cc b/src/core/ext/filters/client_channel/dynamic_filters.cc index afde3c751da..1286fcec42c 100644 --- a/src/core/ext/filters/client_channel/dynamic_filters.cc +++ b/src/core/ext/filters/client_channel/dynamic_filters.cc @@ -18,6 +18,7 @@ #include "src/core/ext/filters/client_channel/dynamic_filters.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/surface/lame_client.h" @@ -160,12 +161,16 @@ RefCountedPtr DynamicFilters::Create( // Attempt to create channel stack from requested filters. auto p = CreateChannelStack(args, std::move(filters)); if (p.second != GRPC_ERROR_NONE) { - // Initial pass failed. Create with lame filter. + // Channel stack creation failed with requested filters. + // Create with lame filter instead. grpc_error* error = p.second; - p = CreateChannelStack(args, {&grpc_lame_filter}); + grpc_arg error_arg = MakeLameClientErrorArg(error); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args, &error_arg, 1); + GRPC_ERROR_UNREF(error); + p = CreateChannelStack(new_args, {&grpc_lame_filter}); GPR_ASSERT(p.second == GRPC_ERROR_NONE); - grpc_channel_element* elem = grpc_channel_stack_element(p.first, 0); - SetLameFilterError(elem, error); + grpc_channel_args_destroy(new_args); } return MakeRefCounted(p.first); } diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc index 5e8620736c5..f95b957e26c 100644 --- a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -26,9 +26,11 @@ #include "src/core/ext/filters/client_channel/config_selector.h" #include "src/core/ext/filters/client_channel/resolver_registry.h" #include "src/core/ext/xds/xds_client.h" +#include "src/core/ext/xds/xds_http_filters.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/iomgr/closure.h" #include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/surface/lame_client.h" #include "src/core/lib/transport/timeout_encoding.h" namespace grpc_core { @@ -135,9 +137,7 @@ class XdsResolver : public Resolver { class XdsConfigSelector : public ConfigSelector { public: - XdsConfigSelector(RefCountedPtr resolver, - const std::vector& routes, - grpc_error* error); + XdsConfigSelector(RefCountedPtr resolver, grpc_error** error); ~XdsConfigSelector() override; const char* name() const override { return "XdsConfigSelector"; } @@ -151,26 +151,41 @@ class XdsResolver : public Resolver { CallConfig GetCallConfig(GetCallConfigArgs args) override; + std::vector GetFilters() override { + return filters_; + } + + grpc_channel_args* ModifyChannelArgs(grpc_channel_args* args) override; + private: struct Route { + struct ClusterWeightState { + uint32_t range_end; + absl::string_view cluster; + RefCountedPtr method_config; + + bool operator==(const ClusterWeightState& other) const; + }; + XdsApi::Route route; - absl::InlinedVector, 2> - weighted_cluster_state; RefCountedPtr method_config; - bool operator==(const Route& other) const { - return route == other.route && - weighted_cluster_state == other.weighted_cluster_state; - } + absl::InlinedVector weighted_cluster_state; + + bool operator==(const Route& other) const; }; using RouteTable = std::vector; void MaybeAddCluster(const std::string& name); - grpc_error* CreateMethodConfig(RefCountedPtr* method_config, - const XdsApi::Route& route); + grpc_error* CreateMethodConfig( + const XdsApi::Route& route, + const XdsApi::Route::ClusterWeight* cluster_weight, + RefCountedPtr* method_config); RefCountedPtr resolver_; RouteTable route_table_; std::map> clusters_; + std::vector filters_; + grpc_error* filter_error_ = GRPC_ERROR_NONE; }; void OnListenerUpdate(XdsApi::LdsUpdate listener); @@ -187,13 +202,20 @@ class XdsResolver : public Resolver { std::string server_name_; const grpc_channel_args* args_; grpc_pollset_set* interested_parties_; + RefCountedPtr xds_client_; + XdsClient::ListenerWatcherInterface* listener_watcher_ = nullptr; + // This will not contain the RouteConfiguration, even if it comes with the + // LDS response; instead, the relevant VirtualHost from the + // RouteConfiguration will be saved in current_virtual_host_. + XdsApi::LdsUpdate current_listener_; + std::string route_config_name_; XdsClient::RouteConfigWatcherInterface* route_config_watcher_ = nullptr; + XdsApi::RdsUpdate::VirtualHost current_virtual_host_; + ClusterState::ClusterStateMap cluster_state_map_; - std::vector current_update_; - XdsApi::Duration http_max_stream_duration_; }; // @@ -260,13 +282,35 @@ void XdsResolver::Notifier::RunInWorkSerializer(grpc_error* error) { delete this; } +// +// XdsResolver::XdsConfigSelector::Route +// + +bool MethodConfigsEqual(const ServiceConfig* sc1, const ServiceConfig* sc2) { + if (sc1 == nullptr) return sc2 == nullptr; + if (sc2 == nullptr) return false; + return sc1->json_string() == sc2->json_string(); +} + +bool XdsResolver::XdsConfigSelector::Route::ClusterWeightState::operator==( + const ClusterWeightState& other) const { + return range_end == other.range_end && cluster == other.cluster && + MethodConfigsEqual(method_config.get(), other.method_config.get()); +} + +bool XdsResolver::XdsConfigSelector::Route::operator==( + const Route& other) const { + return route == other.route && + weighted_cluster_state == other.weighted_cluster_state && + MethodConfigsEqual(method_config.get(), other.method_config.get()); +} + // // XdsResolver::XdsConfigSelector // XdsResolver::XdsConfigSelector::XdsConfigSelector( - RefCountedPtr resolver, - const std::vector& routes, grpc_error* error) + RefCountedPtr resolver, grpc_error** error) : resolver_(std::move(resolver)) { if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) { gpr_log(GPR_INFO, "[xds_resolver %p] creating XdsConfigSelector %p", @@ -281,8 +325,8 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector( // weighted_cluster_state field points to the memory in the route field, so // moving the entry in a reallocation will cause the string_view to point to // invalid data. - route_table_.reserve(routes.size()); - for (auto& route : routes) { + route_table_.reserve(resolver_->current_virtual_host_.routes.size()); + for (auto& route : resolver_->current_virtual_host_.routes) { if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) { gpr_log(GPR_INFO, "[xds_resolver %p] XdsConfigSelector %p: route: %s", resolver_.get(), this, route.ToString().c_str()); @@ -294,27 +338,95 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector( // one. if (!route.max_stream_duration.has_value()) { route_entry.route.max_stream_duration = - resolver_->http_max_stream_duration_; + resolver_->current_listener_.http_max_stream_duration; } - error = CreateMethodConfig(&route_entry.method_config, route_entry.route); if (route.weighted_clusters.empty()) { + *error = CreateMethodConfig(route_entry.route, nullptr, + &route_entry.method_config); MaybeAddCluster(route.cluster_name); } else { uint32_t end = 0; for (const auto& weighted_cluster : route_entry.route.weighted_clusters) { - MaybeAddCluster(weighted_cluster.name); + Route::ClusterWeightState cluster_weight_state; + *error = CreateMethodConfig(route_entry.route, &weighted_cluster, + &cluster_weight_state.method_config); + if (*error != GRPC_ERROR_NONE) return; end += weighted_cluster.weight; - route_entry.weighted_cluster_state.emplace_back(end, - weighted_cluster.name); + cluster_weight_state.range_end = end; + cluster_weight_state.cluster = weighted_cluster.name; + route_entry.weighted_cluster_state.push_back( + std::move(cluster_weight_state)); + MaybeAddCluster(weighted_cluster.name); + } + } + } + // Populate filter list. + if (XdsFaultInjectionEnabled()) { + bool found_router = false; + for (const auto& http_filter : resolver_->current_listener_.http_filters) { + // Stop at the router filter. It's a no-op for us, and we ignore + // anything that may come after it, for compatibility with Envoy. + if (http_filter.config.config_proto_type_name == + kXdsHttpRouterFilterConfigName) { + found_router = true; + break; } + // Find filter. This is guaranteed to succeed, because it's checked + // at config validation time in the XdsApi code. + const XdsHttpFilterImpl* filter_impl = + XdsHttpFilterRegistry::GetFilterForType( + http_filter.config.config_proto_type_name); + GPR_ASSERT(filter_impl != nullptr); + // Add C-core filter to list. + filters_.push_back(filter_impl->channel_filter()); + } + // For compatibility with Envoy, if the router filter is not + // configured, we fail all RPCs. + if (!found_router) { + filter_error_ = grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "no xDS HTTP router filter configured"), + GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE); + filters_.push_back(&grpc_lame_filter); } } } +XdsResolver::XdsConfigSelector::~XdsConfigSelector() { + if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) { + gpr_log(GPR_INFO, "[xds_resolver %p] destroying XdsConfigSelector %p", + resolver_.get(), this); + } + clusters_.clear(); + resolver_->MaybeRemoveUnusedClusters(); + GRPC_ERROR_UNREF(filter_error_); +} + +const XdsHttpFilterImpl::FilterConfig* FindFilterConfigOverride( + const std::string& instance_name, + const XdsApi::RdsUpdate::VirtualHost& vhost, const XdsApi::Route& route, + const XdsApi::Route::ClusterWeight* cluster_weight) { + // Check ClusterWeight, if any. + if (cluster_weight != nullptr) { + auto it = cluster_weight->typed_per_filter_config.find(instance_name); + if (it != cluster_weight->typed_per_filter_config.end()) return &it->second; + } + // Check Route. + auto it = route.typed_per_filter_config.find(instance_name); + if (it != route.typed_per_filter_config.end()) return &it->second; + // Check VirtualHost. + it = vhost.typed_per_filter_config.find(instance_name); + if (it != vhost.typed_per_filter_config.end()) return &it->second; + // Not found. + return nullptr; +} + grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig( - RefCountedPtr* method_config, const XdsApi::Route& route) { - grpc_error* error = GRPC_ERROR_NONE; + const XdsApi::Route& route, + const XdsApi::Route::ClusterWeight* cluster_weight, + RefCountedPtr* method_config) { std::vector fields; + // Set timeout. if (route.max_stream_duration.has_value() && (route.max_stream_duration->seconds != 0 || route.max_stream_duration->nanos != 0)) { @@ -322,6 +434,50 @@ grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig( route.max_stream_duration->seconds, route.max_stream_duration->nanos)); } + // Handle xDS HTTP filters. + std::map> per_filter_configs; + grpc_channel_args* args = grpc_channel_args_copy(resolver_->args_); + for (const auto& http_filter : resolver_->current_listener_.http_filters) { + // Stop at the router filter. It's a no-op for us, and we ignore + // anything that may come after it, for compatibility with Envoy. + if (http_filter.config.config_proto_type_name == + kXdsHttpRouterFilterConfigName) { + break; + } + // Find filter. This is guaranteed to succeed, because it's checked + // at config validation time in the XdsApi code. + const XdsHttpFilterImpl* filter_impl = + XdsHttpFilterRegistry::GetFilterForType( + http_filter.config.config_proto_type_name); + GPR_ASSERT(filter_impl != nullptr); + // Allow filter to add channel args that may affect service config + // parsing. + args = filter_impl->ModifyChannelArgs(args); + // Find config override, if any. + const XdsHttpFilterImpl::FilterConfig* config_override = + FindFilterConfigOverride(http_filter.name, + resolver_->current_virtual_host_, route, + cluster_weight); + // Generate service config for filter. + auto method_config_field = + filter_impl->GenerateServiceConfig(http_filter.config, config_override); + if (!method_config_field.ok()) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("failed to generate method config for HTTP filter ", + http_filter.name, ": ", + method_config_field.status().ToString()) + .c_str()); + } + per_filter_configs[method_config_field->service_config_field_name] + .push_back(method_config_field->element); + } + for (const auto& p : per_filter_configs) { + fields.emplace_back(absl::StrCat(" \"", p.first, "\": [\n", + absl::StrJoin(p.second, ",\n"), + "\n ]")); + } + // Construct service config. + grpc_error* error = GRPC_ERROR_NONE; if (!fields.empty()) { std::string json = absl::StrCat( "{\n" @@ -333,19 +489,20 @@ grpc_error* XdsResolver::XdsConfigSelector::CreateMethodConfig( absl::StrJoin(fields, ",\n"), "\n } ]\n" "}"); - *method_config = - ServiceConfig::Create(resolver_->args_, json.c_str(), &error); + *method_config = ServiceConfig::Create(args, json.c_str(), &error); } + grpc_channel_args_destroy(args); return error; } -XdsResolver::XdsConfigSelector::~XdsConfigSelector() { - if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_resolver_trace)) { - gpr_log(GPR_INFO, "[xds_resolver %p] destroying XdsConfigSelector %p", - resolver_.get(), this); - } - clusters_.clear(); - resolver_->MaybeRemoveUnusedClusters(); +grpc_channel_args* XdsResolver::XdsConfigSelector::ModifyChannelArgs( + grpc_channel_args* args) { + if (filter_error_ == GRPC_ERROR_NONE) return args; + grpc_arg error_arg = MakeLameClientErrorArg(filter_error_); + grpc_channel_args* new_args = + grpc_channel_args_copy_and_add(args, &error_arg, 1); + grpc_channel_args_destroy(args); + return new_args; } void XdsResolver::XdsConfigSelector::MaybeAddCluster(const std::string& name) { @@ -437,13 +594,15 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig( } // Found a route match absl::string_view cluster_name; + RefCountedPtr method_config; if (entry.route.weighted_clusters.empty()) { cluster_name = entry.route.cluster_name; + method_config = entry.method_config; } else { const uint32_t key = rand() % entry.weighted_cluster_state[entry.weighted_cluster_state.size() - 1] - .first; + .range_end; // Find the index in weighted clusters corresponding to key. size_t mid = 0; size_t start_index = 0; @@ -451,9 +610,9 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig( size_t index = 0; while (end_index > start_index) { mid = (start_index + end_index) / 2; - if (entry.weighted_cluster_state[mid].first > key) { + if (entry.weighted_cluster_state[mid].range_end > key) { end_index = mid; - } else if (entry.weighted_cluster_state[mid].first < key) { + } else if (entry.weighted_cluster_state[mid].range_end < key) { start_index = mid + 1; } else { index = mid + 1; @@ -461,8 +620,9 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig( } } if (index == 0) index = start_index; - GPR_ASSERT(entry.weighted_cluster_state[index].first > key); - cluster_name = entry.weighted_cluster_state[index].second; + GPR_ASSERT(entry.weighted_cluster_state[index].range_end > key); + cluster_name = entry.weighted_cluster_state[index].cluster; + method_config = entry.weighted_cluster_state[index].method_config; } auto it = clusters_.find(cluster_name); GPR_ASSERT(it != clusters_.end()); @@ -470,10 +630,10 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig( static_cast(resolver_->Ref().release()); ClusterState* cluster_state = it->second->Ref().release(); CallConfig call_config; - if (entry.method_config != nullptr) { - call_config.service_config = entry.method_config; + if (method_config != nullptr) { call_config.method_configs = - entry.method_config->GetMethodParsedConfigVector(grpc_empty_slice()); + method_config->GetMethodParsedConfigVector(grpc_empty_slice()); + call_config.service_config = std::move(method_config); } call_config.call_attributes[kXdsClusterAttribute] = it->first; call_config.on_call_committed = [resolver, cluster_state]() { @@ -577,10 +737,10 @@ void XdsResolver::OnListenerUpdate(XdsApi::LdsUpdate listener) { xds_client_->WatchRouteConfigData(route_config_name_, std::move(watcher)); } } - http_max_stream_duration_ = listener.http_max_stream_duration; + current_listener_ = std::move(listener); if (route_config_name_.empty()) { - GPR_ASSERT(listener.rds_update.has_value()); - OnRouteConfigUpdate(std::move(*listener.rds_update)); + GPR_ASSERT(current_listener_.rds_update.has_value()); + OnRouteConfigUpdate(std::move(*current_listener_.rds_update)); } } @@ -598,8 +758,8 @@ void XdsResolver::OnRouteConfigUpdate(XdsApi::RdsUpdate rds_update) { .c_str())); return; } - // Save the list of routes in the resolver. - current_update_ = std::move(vhost->routes); + // Save the virtual host in the resolver. + current_virtual_host_ = std::move(*vhost); // Send a new result to the channel. GenerateResult(); } @@ -618,7 +778,7 @@ void XdsResolver::OnResourceDoesNotExist() { "[xds_resolver %p] LDS/RDS resource does not exist -- clearing " "update and returning empty service config", this); - current_update_.clear(); + current_virtual_host_.routes.clear(); Result result; result.service_config = ServiceConfig::Create(args_, "{}", &result.service_config_error); @@ -660,12 +820,11 @@ grpc_error* XdsResolver::CreateServiceConfig( } void XdsResolver::GenerateResult() { - if (current_update_.empty()) return; + if (current_virtual_host_.routes.empty()) return; // First create XdsConfigSelector, which may add new entries to the cluster // state map, and then CreateServiceConfig for LB policies. grpc_error* error = GRPC_ERROR_NONE; - auto config_selector = - MakeRefCounted(Ref(), current_update_, error); + auto config_selector = MakeRefCounted(Ref(), &error); if (error != GRPC_ERROR_NONE) { OnError(error); return; diff --git a/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c b/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c new file mode 100644 index 00000000000..8e6ff697fc5 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c @@ -0,0 +1,41 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/extensions/filters/http/router/v3/router.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "envoy/extensions/filters/http/router/v3/router.upb.h" +#include "envoy/config/accesslog/v3/accesslog.upb.h" +#include "google/protobuf/wrappers.upb.h" +#include "udpa/annotations/status.upb.h" +#include "udpa/annotations/versioning.upb.h" +#include "validate/validate.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const envoy_extensions_filters_http_router_v3_Router_submsgs[2] = { + &envoy_config_accesslog_v3_AccessLog_msginit, + &google_protobuf_BoolValue_msginit, +}; + +static const upb_msglayout_field envoy_extensions_filters_http_router_v3_Router__fields[6] = { + {1, UPB_SIZE(4, 8), 1, 1, 11, 1}, + {2, UPB_SIZE(1, 1), 0, 0, 8, 1}, + {3, UPB_SIZE(8, 16), 0, 0, 11, 3}, + {4, UPB_SIZE(2, 2), 0, 0, 8, 1}, + {5, UPB_SIZE(12, 24), 0, 0, 9, 3}, + {6, UPB_SIZE(3, 3), 0, 0, 8, 1}, +}; + +const upb_msglayout envoy_extensions_filters_http_router_v3_Router_msginit = { + &envoy_extensions_filters_http_router_v3_Router_submsgs[0], + &envoy_extensions_filters_http_router_v3_Router__fields[0], + UPB_SIZE(16, 32), 6, false, 255, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h b/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h new file mode 100644 index 00000000000..2e7084ac970 --- /dev/null +++ b/src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h @@ -0,0 +1,113 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/extensions/filters/http/router/v3/router.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPB_H_ +#define ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPB_H_ + +#include "upb/msg.h" +#include "upb/decode.h" +#include "upb/decode_fast.h" +#include "upb/encode.h" + +#include "upb/port_def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +struct envoy_extensions_filters_http_router_v3_Router; +typedef struct envoy_extensions_filters_http_router_v3_Router envoy_extensions_filters_http_router_v3_Router; +extern const upb_msglayout envoy_extensions_filters_http_router_v3_Router_msginit; +struct envoy_config_accesslog_v3_AccessLog; +struct google_protobuf_BoolValue; +extern const upb_msglayout envoy_config_accesslog_v3_AccessLog_msginit; +extern const upb_msglayout google_protobuf_BoolValue_msginit; + + +/* envoy.extensions.filters.http.router.v3.Router */ + +UPB_INLINE envoy_extensions_filters_http_router_v3_Router *envoy_extensions_filters_http_router_v3_Router_new(upb_arena *arena) { + return (envoy_extensions_filters_http_router_v3_Router *)_upb_msg_new(&envoy_extensions_filters_http_router_v3_Router_msginit, arena); +} +UPB_INLINE envoy_extensions_filters_http_router_v3_Router *envoy_extensions_filters_http_router_v3_Router_parse(const char *buf, size_t size, + upb_arena *arena) { + envoy_extensions_filters_http_router_v3_Router *ret = envoy_extensions_filters_http_router_v3_Router_new(arena); + return (ret && upb_decode(buf, size, ret, &envoy_extensions_filters_http_router_v3_Router_msginit, arena)) ? ret : NULL; +} +UPB_INLINE envoy_extensions_filters_http_router_v3_Router *envoy_extensions_filters_http_router_v3_Router_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + envoy_extensions_filters_http_router_v3_Router *ret = envoy_extensions_filters_http_router_v3_Router_new(arena); + return (ret && _upb_decode(buf, size, ret, &envoy_extensions_filters_http_router_v3_Router_msginit, arena, options)) + ? ret : NULL; +} +UPB_INLINE char *envoy_extensions_filters_http_router_v3_Router_serialize(const envoy_extensions_filters_http_router_v3_Router *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &envoy_extensions_filters_http_router_v3_Router_msginit, arena, len); +} + +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_has_dynamic_stats(const envoy_extensions_filters_http_router_v3_Router *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE const struct google_protobuf_BoolValue* envoy_extensions_filters_http_router_v3_Router_dynamic_stats(const envoy_extensions_filters_http_router_v3_Router *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), const struct google_protobuf_BoolValue*); } +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_start_child_span(const envoy_extensions_filters_http_router_v3_Router *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool); } +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_has_upstream_log(const envoy_extensions_filters_http_router_v3_Router *msg) { return _upb_has_submsg_nohasbit(msg, UPB_SIZE(8, 16)); } +UPB_INLINE const struct envoy_config_accesslog_v3_AccessLog* const* envoy_extensions_filters_http_router_v3_Router_upstream_log(const envoy_extensions_filters_http_router_v3_Router *msg, size_t *len) { return (const struct envoy_config_accesslog_v3_AccessLog* const*)_upb_array_accessor(msg, UPB_SIZE(8, 16), len); } +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_suppress_envoy_headers(const envoy_extensions_filters_http_router_v3_Router *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool); } +UPB_INLINE upb_strview const* envoy_extensions_filters_http_router_v3_Router_strict_check_headers(const envoy_extensions_filters_http_router_v3_Router *msg, size_t *len) { return (upb_strview const*)_upb_array_accessor(msg, UPB_SIZE(12, 24), len); } +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_respect_expected_rq_timeout(const envoy_extensions_filters_http_router_v3_Router *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool); } + +UPB_INLINE void envoy_extensions_filters_http_router_v3_Router_set_dynamic_stats(envoy_extensions_filters_http_router_v3_Router *msg, struct google_protobuf_BoolValue* value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), struct google_protobuf_BoolValue*) = value; +} +UPB_INLINE struct google_protobuf_BoolValue* envoy_extensions_filters_http_router_v3_Router_mutable_dynamic_stats(envoy_extensions_filters_http_router_v3_Router *msg, upb_arena *arena) { + struct google_protobuf_BoolValue* sub = (struct google_protobuf_BoolValue*)envoy_extensions_filters_http_router_v3_Router_dynamic_stats(msg); + if (sub == NULL) { + sub = (struct google_protobuf_BoolValue*)_upb_msg_new(&google_protobuf_BoolValue_msginit, arena); + if (!sub) return NULL; + envoy_extensions_filters_http_router_v3_Router_set_dynamic_stats(msg, sub); + } + return sub; +} +UPB_INLINE void envoy_extensions_filters_http_router_v3_Router_set_start_child_span(envoy_extensions_filters_http_router_v3_Router *msg, bool value) { + *UPB_PTR_AT(msg, UPB_SIZE(1, 1), bool) = value; +} +UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_extensions_filters_http_router_v3_Router_mutable_upstream_log(envoy_extensions_filters_http_router_v3_Router *msg, size_t *len) { + return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_mutable_accessor(msg, UPB_SIZE(8, 16), len); +} +UPB_INLINE struct envoy_config_accesslog_v3_AccessLog** envoy_extensions_filters_http_router_v3_Router_resize_upstream_log(envoy_extensions_filters_http_router_v3_Router *msg, size_t len, upb_arena *arena) { + return (struct envoy_config_accesslog_v3_AccessLog**)_upb_array_resize_accessor2(msg, UPB_SIZE(8, 16), len, UPB_SIZE(2, 3), arena); +} +UPB_INLINE struct envoy_config_accesslog_v3_AccessLog* envoy_extensions_filters_http_router_v3_Router_add_upstream_log(envoy_extensions_filters_http_router_v3_Router *msg, upb_arena *arena) { + struct envoy_config_accesslog_v3_AccessLog* sub = (struct envoy_config_accesslog_v3_AccessLog*)_upb_msg_new(&envoy_config_accesslog_v3_AccessLog_msginit, arena); + bool ok = _upb_array_append_accessor2( + msg, UPB_SIZE(8, 16), UPB_SIZE(2, 3), &sub, arena); + if (!ok) return NULL; + return sub; +} +UPB_INLINE void envoy_extensions_filters_http_router_v3_Router_set_suppress_envoy_headers(envoy_extensions_filters_http_router_v3_Router *msg, bool value) { + *UPB_PTR_AT(msg, UPB_SIZE(2, 2), bool) = value; +} +UPB_INLINE upb_strview* envoy_extensions_filters_http_router_v3_Router_mutable_strict_check_headers(envoy_extensions_filters_http_router_v3_Router *msg, size_t *len) { + return (upb_strview*)_upb_array_mutable_accessor(msg, UPB_SIZE(12, 24), len); +} +UPB_INLINE upb_strview* envoy_extensions_filters_http_router_v3_Router_resize_strict_check_headers(envoy_extensions_filters_http_router_v3_Router *msg, size_t len, upb_arena *arena) { + return (upb_strview*)_upb_array_resize_accessor2(msg, UPB_SIZE(12, 24), len, UPB_SIZE(3, 4), arena); +} +UPB_INLINE bool envoy_extensions_filters_http_router_v3_Router_add_strict_check_headers(envoy_extensions_filters_http_router_v3_Router *msg, upb_strview val, upb_arena *arena) { + return _upb_array_append_accessor2(msg, UPB_SIZE(12, 24), UPB_SIZE(3, 4), &val, + arena); +} +UPB_INLINE void envoy_extensions_filters_http_router_v3_Router_set_respect_expected_rq_timeout(envoy_extensions_filters_http_router_v3_Router *msg, bool value) { + *UPB_PTR_AT(msg, UPB_SIZE(3, 3), bool) = value; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPB_H_ */ diff --git a/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c b/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c new file mode 100644 index 00000000000..24407fa6eac --- /dev/null +++ b/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c @@ -0,0 +1,33 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * udpa/type/v1/typed_struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include +#include "upb/msg.h" +#include "udpa/type/v1/typed_struct.upb.h" +#include "validate/validate.upb.h" +#include "google/protobuf/struct.upb.h" + +#include "upb/port_def.inc" + +static const upb_msglayout *const udpa_type_v1_TypedStruct_submsgs[1] = { + &google_protobuf_Struct_msginit, +}; + +static const upb_msglayout_field udpa_type_v1_TypedStruct__fields[2] = { + {1, UPB_SIZE(4, 8), 0, 0, 9, 1}, + {2, UPB_SIZE(12, 24), 1, 0, 11, 1}, +}; + +const upb_msglayout udpa_type_v1_TypedStruct_msginit = { + &udpa_type_v1_TypedStruct_submsgs[0], + &udpa_type_v1_TypedStruct__fields[0], + UPB_SIZE(16, 32), 2, false, 255, +}; + +#include "upb/port_undef.inc" + diff --git a/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h b/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h new file mode 100644 index 00000000000..2dd03ff12d7 --- /dev/null +++ b/src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h @@ -0,0 +1,77 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * udpa/type/v1/typed_struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPB_H_ +#define UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPB_H_ + +#include "upb/msg.h" +#include "upb/decode.h" +#include "upb/decode_fast.h" +#include "upb/encode.h" + +#include "upb/port_def.inc" + +#ifdef __cplusplus +extern "C" { +#endif + +struct udpa_type_v1_TypedStruct; +typedef struct udpa_type_v1_TypedStruct udpa_type_v1_TypedStruct; +extern const upb_msglayout udpa_type_v1_TypedStruct_msginit; +struct google_protobuf_Struct; +extern const upb_msglayout google_protobuf_Struct_msginit; + + +/* udpa.type.v1.TypedStruct */ + +UPB_INLINE udpa_type_v1_TypedStruct *udpa_type_v1_TypedStruct_new(upb_arena *arena) { + return (udpa_type_v1_TypedStruct *)_upb_msg_new(&udpa_type_v1_TypedStruct_msginit, arena); +} +UPB_INLINE udpa_type_v1_TypedStruct *udpa_type_v1_TypedStruct_parse(const char *buf, size_t size, + upb_arena *arena) { + udpa_type_v1_TypedStruct *ret = udpa_type_v1_TypedStruct_new(arena); + return (ret && upb_decode(buf, size, ret, &udpa_type_v1_TypedStruct_msginit, arena)) ? ret : NULL; +} +UPB_INLINE udpa_type_v1_TypedStruct *udpa_type_v1_TypedStruct_parse_ex(const char *buf, size_t size, + upb_arena *arena, int options) { + udpa_type_v1_TypedStruct *ret = udpa_type_v1_TypedStruct_new(arena); + return (ret && _upb_decode(buf, size, ret, &udpa_type_v1_TypedStruct_msginit, arena, options)) + ? ret : NULL; +} +UPB_INLINE char *udpa_type_v1_TypedStruct_serialize(const udpa_type_v1_TypedStruct *msg, upb_arena *arena, size_t *len) { + return upb_encode(msg, &udpa_type_v1_TypedStruct_msginit, arena, len); +} + +UPB_INLINE upb_strview udpa_type_v1_TypedStruct_type_url(const udpa_type_v1_TypedStruct *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview); } +UPB_INLINE bool udpa_type_v1_TypedStruct_has_value(const udpa_type_v1_TypedStruct *msg) { return _upb_hasbit(msg, 1); } +UPB_INLINE const struct google_protobuf_Struct* udpa_type_v1_TypedStruct_value(const udpa_type_v1_TypedStruct *msg) { return *UPB_PTR_AT(msg, UPB_SIZE(12, 24), const struct google_protobuf_Struct*); } + +UPB_INLINE void udpa_type_v1_TypedStruct_set_type_url(udpa_type_v1_TypedStruct *msg, upb_strview value) { + *UPB_PTR_AT(msg, UPB_SIZE(4, 8), upb_strview) = value; +} +UPB_INLINE void udpa_type_v1_TypedStruct_set_value(udpa_type_v1_TypedStruct *msg, struct google_protobuf_Struct* value) { + _upb_sethas(msg, 1); + *UPB_PTR_AT(msg, UPB_SIZE(12, 24), struct google_protobuf_Struct*) = value; +} +UPB_INLINE struct google_protobuf_Struct* udpa_type_v1_TypedStruct_mutable_value(udpa_type_v1_TypedStruct *msg, upb_arena *arena) { + struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)udpa_type_v1_TypedStruct_value(msg); + if (sub == NULL) { + sub = (struct google_protobuf_Struct*)_upb_msg_new(&google_protobuf_Struct_msginit, arena); + if (!sub) return NULL; + udpa_type_v1_TypedStruct_set_value(msg, sub); + } + return sub; +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPB_H_ */ diff --git a/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c b/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c new file mode 100644 index 00000000000..f1d9a578077 --- /dev/null +++ b/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c @@ -0,0 +1,76 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/extensions/filters/http/router/v3/router.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "upb/def.h" +#include "envoy/extensions/filters/http/router/v3/router.upbdefs.h" + +extern upb_def_init envoy_config_accesslog_v3_accesslog_proto_upbdefinit; +extern upb_def_init google_protobuf_wrappers_proto_upbdefinit; +extern upb_def_init udpa_annotations_status_proto_upbdefinit; +extern upb_def_init udpa_annotations_versioning_proto_upbdefinit; +extern upb_def_init validate_validate_proto_upbdefinit; +extern const upb_msglayout envoy_extensions_filters_http_router_v3_Router_msginit; + +static const upb_msglayout *layouts[1] = { + &envoy_extensions_filters_http_router_v3_Router_msginit, +}; + +static const char descriptor[909] = {'\n', '4', 'e', 'n', 'v', 'o', 'y', '/', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '/', 'f', 'i', 'l', 't', 'e', 'r', +'s', '/', 'h', 't', 't', 'p', '/', 'r', 'o', 'u', 't', 'e', 'r', '/', 'v', '3', '/', 'r', 'o', 'u', 't', 'e', 'r', '.', 'p', +'r', 'o', 't', 'o', '\022', '\'', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', 's', 'i', 'o', 'n', 's', '.', 'f', 'i', +'l', 't', 'e', 'r', 's', '.', 'h', 't', 't', 'p', '.', 'r', 'o', 'u', 't', 'e', 'r', '.', 'v', '3', '\032', ')', 'e', 'n', 'v', +'o', 'y', '/', 'c', 'o', 'n', 'f', 'i', 'g', '/', 'a', 'c', 'c', 'e', 's', 's', 'l', 'o', 'g', '/', 'v', '3', '/', 'a', 'c', +'c', 'e', 's', 's', 'l', 'o', 'g', '.', 'p', 'r', 'o', 't', 'o', '\032', '\036', 'g', 'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', +'t', 'o', 'b', 'u', 'f', '/', 'w', 'r', 'a', 'p', 'p', 'e', 'r', 's', '.', 'p', 'r', 'o', 't', 'o', '\032', '\035', 'u', 'd', 'p', +'a', '/', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 's', '/', 's', 't', 'a', 't', 'u', 's', '.', 'p', 'r', 'o', 't', +'o', '\032', '!', 'u', 'd', 'p', 'a', '/', 'a', 'n', 'n', 'o', 't', 'a', 't', 'i', 'o', 'n', 's', '/', 'v', 'e', 'r', 's', 'i', +'o', 'n', 'i', 'n', 'g', '.', 'p', 'r', 'o', 't', 'o', '\032', '\027', 'v', 'a', 'l', 'i', 'd', 'a', 't', 'e', '/', 'v', 'a', 'l', +'i', 'd', 'a', 't', 'e', '.', 'p', 'r', 'o', 't', 'o', '\"', '\255', '\004', '\n', '\006', 'R', 'o', 'u', 't', 'e', 'r', '\022', '?', '\n', +'\r', 'd', 'y', 'n', 'a', 'm', 'i', 'c', '_', 's', 't', 'a', 't', 's', '\030', '\001', ' ', '\001', '(', '\013', '2', '\032', '.', 'g', 'o', +'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '.', 'B', 'o', 'o', 'l', 'V', 'a', 'l', 'u', 'e', 'R', '\014', +'d', 'y', 'n', 'a', 'm', 'i', 'c', 'S', 't', 'a', 't', 's', '\022', '(', '\n', '\020', 's', 't', 'a', 'r', 't', '_', 'c', 'h', 'i', +'l', 'd', '_', 's', 'p', 'a', 'n', '\030', '\002', ' ', '\001', '(', '\010', 'R', '\016', 's', 't', 'a', 'r', 't', 'C', 'h', 'i', 'l', 'd', +'S', 'p', 'a', 'n', '\022', 'G', '\n', '\014', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', '_', 'l', 'o', 'g', '\030', '\003', ' ', '\003', '(', +'\013', '2', '$', '.', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'a', 'c', 'c', 'e', 's', 's', 'l', 'o', +'g', '.', 'v', '3', '.', 'A', 'c', 'c', 'e', 's', 's', 'L', 'o', 'g', 'R', '\013', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', 'L', +'o', 'g', '\022', '4', '\n', '\026', 's', 'u', 'p', 'p', 'r', 'e', 's', 's', '_', 'e', 'n', 'v', 'o', 'y', '_', 'h', 'e', 'a', 'd', +'e', 'r', 's', '\030', '\004', ' ', '\001', '(', '\010', 'R', '\024', 's', 'u', 'p', 'p', 'r', 'e', 's', 's', 'E', 'n', 'v', 'o', 'y', 'H', +'e', 'a', 'd', 'e', 'r', 's', '\022', '\307', '\001', '\n', '\024', 's', 't', 'r', 'i', 'c', 't', '_', 'c', 'h', 'e', 'c', 'k', '_', 'h', +'e', 'a', 'd', 'e', 'r', 's', '\030', '\005', ' ', '\003', '(', '\t', 'B', '\224', '\001', '\372', 'B', '\220', '\001', '\222', '\001', '\214', '\001', '\"', '\211', +'\001', 'r', '\206', '\001', 'R', '\036', 'x', '-', 'e', 'n', 'v', 'o', 'y', '-', 'u', 'p', 's', 't', 'r', 'e', 'a', 'm', '-', 'r', 'q', +'-', 't', 'i', 'm', 'e', 'o', 'u', 't', '-', 'm', 's', 'R', '&', 'x', '-', 'e', 'n', 'v', 'o', 'y', '-', 'u', 'p', 's', 't', +'r', 'e', 'a', 'm', '-', 'r', 'q', '-', 'p', 'e', 'r', '-', 't', 'r', 'y', '-', 't', 'i', 'm', 'e', 'o', 'u', 't', '-', 'm', +'s', 'R', '\023', 'x', '-', 'e', 'n', 'v', 'o', 'y', '-', 'm', 'a', 'x', '-', 'r', 'e', 't', 'r', 'i', 'e', 's', 'R', '\025', 'x', +'-', 'e', 'n', 'v', 'o', 'y', '-', 'r', 'e', 't', 'r', 'y', '-', 'g', 'r', 'p', 'c', '-', 'o', 'n', 'R', '\020', 'x', '-', 'e', +'n', 'v', 'o', 'y', '-', 'r', 'e', 't', 'r', 'y', '-', 'o', 'n', 'R', '\022', 's', 't', 'r', 'i', 'c', 't', 'C', 'h', 'e', 'c', +'k', 'H', 'e', 'a', 'd', 'e', 'r', 's', '\022', '=', '\n', '\033', 'r', 'e', 's', 'p', 'e', 'c', 't', '_', 'e', 'x', 'p', 'e', 'c', +'t', 'e', 'd', '_', 'r', 'q', '_', 't', 'i', 'm', 'e', 'o', 'u', 't', '\030', '\006', ' ', '\001', '(', '\010', 'R', '\030', 'r', 'e', 's', +'p', 'e', 'c', 't', 'E', 'x', 'p', 'e', 'c', 't', 'e', 'd', 'R', 'q', 'T', 'i', 'm', 'e', 'o', 'u', 't', ':', '0', '\232', '\305', +'\210', '\036', '+', '\n', ')', 'e', 'n', 'v', 'o', 'y', '.', 'c', 'o', 'n', 'f', 'i', 'g', '.', 'f', 'i', 'l', 't', 'e', 'r', '.', +'h', 't', 't', 'p', '.', 'r', 'o', 'u', 't', 'e', 'r', '.', 'v', '2', '.', 'R', 'o', 'u', 't', 'e', 'r', 'B', 'N', '\n', '5', +'i', 'o', '.', 'e', 'n', 'v', 'o', 'y', 'p', 'r', 'o', 'x', 'y', '.', 'e', 'n', 'v', 'o', 'y', '.', 'e', 'x', 't', 'e', 'n', +'s', 'i', 'o', 'n', 's', '.', 'f', 'i', 'l', 't', 'e', 'r', 's', '.', 'h', 't', 't', 'p', '.', 'r', 'o', 'u', 't', 'e', 'r', +'.', 'v', '3', 'B', '\013', 'R', 'o', 'u', 't', 'e', 'r', 'P', 'r', 'o', 't', 'o', 'P', '\001', '\272', '\200', '\310', '\321', '\006', '\002', '\020', +'\002', 'b', '\006', 'p', 'r', 'o', 't', 'o', '3', +}; + +static upb_def_init *deps[6] = { + &envoy_config_accesslog_v3_accesslog_proto_upbdefinit, + &google_protobuf_wrappers_proto_upbdefinit, + &udpa_annotations_status_proto_upbdefinit, + &udpa_annotations_versioning_proto_upbdefinit, + &validate_validate_proto_upbdefinit, + NULL +}; + +upb_def_init envoy_extensions_filters_http_router_v3_router_proto_upbdefinit = { + deps, + layouts, + "envoy/extensions/filters/http/router/v3/router.proto", + UPB_STRVIEW_INIT(descriptor, 909) +}; diff --git a/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h b/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h new file mode 100644 index 00000000000..dc91890ed65 --- /dev/null +++ b/src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h @@ -0,0 +1,35 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * envoy/extensions/filters/http/router/v3/router.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPBDEFS_H_ +#define ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPBDEFS_H_ + +#include "upb/def.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +#include "upb/def.h" + +#include "upb/port_def.inc" + +extern upb_def_init envoy_extensions_filters_http_router_v3_router_proto_upbdefinit; + +UPB_INLINE const upb_msgdef *envoy_extensions_filters_http_router_v3_Router_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &envoy_extensions_filters_http_router_v3_router_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "envoy.extensions.filters.http.router.v3.Router"); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* ENVOY_EXTENSIONS_FILTERS_HTTP_ROUTER_V3_ROUTER_PROTO_UPBDEFS_H_ */ diff --git a/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c b/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c new file mode 100644 index 00000000000..f786bff37ab --- /dev/null +++ b/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c @@ -0,0 +1,44 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * udpa/type/v1/typed_struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#include "upb/def.h" +#include "udpa/type/v1/typed_struct.upbdefs.h" + +extern upb_def_init validate_validate_proto_upbdefinit; +extern upb_def_init google_protobuf_struct_proto_upbdefinit; +extern const upb_msglayout udpa_type_v1_TypedStruct_msginit; + +static const upb_msglayout *layouts[1] = { + &udpa_type_v1_TypedStruct_msginit, +}; + +static const char descriptor[251] = {'\n', '\037', 'u', 'd', 'p', 'a', '/', 't', 'y', 'p', 'e', '/', 'v', '1', '/', 't', 'y', 'p', 'e', 'd', '_', 's', 't', 'r', 'u', +'c', 't', '.', 'p', 'r', 'o', 't', 'o', '\022', '\014', 'u', 'd', 'p', 'a', '.', 't', 'y', 'p', 'e', '.', 'v', '1', '\032', '\027', 'v', +'a', 'l', 'i', 'd', 'a', 't', 'e', '/', 'v', 'a', 'l', 'i', 'd', 'a', 't', 'e', '.', 'p', 'r', 'o', 't', 'o', '\032', '\034', 'g', +'o', 'o', 'g', 'l', 'e', '/', 'p', 'r', 'o', 't', 'o', 'b', 'u', 'f', '/', 's', 't', 'r', 'u', 'c', 't', '.', 'p', 'r', 'o', +'t', 'o', '\"', 'W', '\n', '\013', 'T', 'y', 'p', 'e', 'd', 'S', 't', 'r', 'u', 'c', 't', '\022', '\031', '\n', '\010', 't', 'y', 'p', 'e', +'_', 'u', 'r', 'l', '\030', '\001', ' ', '\001', '(', '\t', 'R', '\007', 't', 'y', 'p', 'e', 'U', 'r', 'l', '\022', '-', '\n', '\005', 'v', 'a', +'l', 'u', 'e', '\030', '\002', ' ', '\001', '(', '\013', '2', '\027', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'p', 'r', 'o', 't', 'o', 'b', +'u', 'f', '.', 'S', 't', 'r', 'u', 'c', 't', 'R', '\005', 'v', 'a', 'l', 'u', 'e', 'B', '2', '\n', '\034', 'c', 'o', 'm', '.', 'g', +'i', 't', 'h', 'u', 'b', '.', 'u', 'd', 'p', 'a', '.', 'u', 'd', 'p', 'a', '.', 't', 'y', 'p', 'e', '.', 'v', '1', 'B', '\020', +'T', 'y', 'p', 'e', 'd', 'S', 't', 'r', 'u', 'c', 't', 'P', 'r', 'o', 't', 'o', 'P', '\001', 'b', '\006', 'p', 'r', 'o', 't', 'o', +'3', +}; + +static upb_def_init *deps[3] = { + &validate_validate_proto_upbdefinit, + &google_protobuf_struct_proto_upbdefinit, + NULL +}; + +upb_def_init udpa_type_v1_typed_struct_proto_upbdefinit = { + deps, + layouts, + "udpa/type/v1/typed_struct.proto", + UPB_STRVIEW_INIT(descriptor, 251) +}; diff --git a/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h b/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h new file mode 100644 index 00000000000..d30baef2b22 --- /dev/null +++ b/src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h @@ -0,0 +1,35 @@ +/* This file was generated by upbc (the upb compiler) from the input + * file: + * + * udpa/type/v1/typed_struct.proto + * + * Do not edit -- your changes will be discarded when the file is + * regenerated. */ + +#ifndef UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPBDEFS_H_ +#define UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPBDEFS_H_ + +#include "upb/def.h" +#include "upb/port_def.inc" +#ifdef __cplusplus +extern "C" { +#endif + +#include "upb/def.h" + +#include "upb/port_def.inc" + +extern upb_def_init udpa_type_v1_typed_struct_proto_upbdefinit; + +UPB_INLINE const upb_msgdef *udpa_type_v1_TypedStruct_getmsgdef(upb_symtab *s) { + _upb_symtab_loaddefinit(s, &udpa_type_v1_typed_struct_proto_upbdefinit); + return upb_symtab_lookupmsg(s, "udpa.type.v1.TypedStruct"); +} + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "upb/port_undef.inc" + +#endif /* UDPA_TYPE_V1_TYPED_STRUCT_PROTO_UPBDEFS_H_ */ diff --git a/src/core/ext/xds/xds_api.cc b/src/core/ext/xds/xds_api.cc index ce58dd9a2e7..19640db2736 100644 --- a/src/core/ext/xds/xds_api.cc +++ b/src/core/ext/xds/xds_api.cc @@ -28,22 +28,6 @@ #include "absl/strings/str_format.h" #include "absl/strings/str_join.h" #include "absl/strings/str_split.h" - -#include "upb/upb.hpp" - -#include -#include -#include - -#include "src/core/ext/xds/xds_api.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/string.h" -#include "src/core/lib/gpr/useful.h" -#include "src/core/lib/gprpp/host_port.h" -#include "src/core/lib/iomgr/error.h" -#include "src/core/lib/iomgr/sockaddr_utils.h" -#include "src/core/lib/slice/slice_utils.h" - #include "envoy/config/cluster/v3/circuit_breaker.upb.h" #include "envoy/config/cluster/v3/cluster.upb.h" #include "envoy/config/cluster/v3/cluster.upbdefs.h" @@ -58,12 +42,14 @@ #include "envoy/config/endpoint/v3/load_report.upb.h" #include "envoy/config/listener/v3/api_listener.upb.h" #include "envoy/config/listener/v3/listener.upb.h" +#include "envoy/config/listener/v3/listener.upbdefs.h" #include "envoy/config/listener/v3/listener_components.upb.h" #include "envoy/config/route/v3/route.upb.h" #include "envoy/config/route/v3/route.upbdefs.h" #include "envoy/config/route/v3/route_components.upb.h" #include "envoy/extensions/clusters/aggregate/v3/cluster.upb.h" #include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h" +#include "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h" #include "envoy/extensions/transport_sockets/tls/v3/common.upb.h" #include "envoy/extensions/transport_sockets/tls/v3/tls.upb.h" #include "envoy/service/cluster/v3/cds.upb.h" @@ -86,8 +72,23 @@ #include "google/protobuf/struct.upb.h" #include "google/protobuf/wrappers.upb.h" #include "google/rpc/status.upb.h" +#include "udpa/type/v1/typed_struct.upb.h" #include "upb/text_encode.h" #include "upb/upb.h" +#include "upb/upb.hpp" + +#include +#include +#include + +#include "src/core/ext/xds/xds_api.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/string.h" +#include "src/core/lib/gpr/useful.h" +#include "src/core/lib/gprpp/host_port.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/slice/slice_utils.h" namespace grpc_core { @@ -137,6 +138,16 @@ bool XdsSecurityEnabled() { return parse_succeeded && parsed_value; } +// TODO(lidiz): This will be removed once the fault injection feature is +// fully integration-tested and enabled by default. +bool XdsFaultInjectionEnabled() { + char* value = gpr_getenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); + bool parsed_value; + bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value); + gpr_free(value); + return parse_succeeded && parsed_value; +} + // // XdsApi::Route // @@ -156,7 +167,20 @@ std::string XdsApi::Route::Matchers::ToString() const { } std::string XdsApi::Route::ClusterWeight::ToString() const { - return absl::StrFormat("{cluster=%s, weight=%d}", name, weight); + std::vector contents; + contents.push_back(absl::StrCat("cluster=", name)); + contents.push_back(absl::StrCat("weight=", weight)); + if (!typed_per_filter_config.empty()) { + std::vector parts; + for (const auto& p : typed_per_filter_config) { + const std::string& key = p.first; + const auto& config = p.second; + parts.push_back(absl::StrCat(key, "=", config.ToString())); + } + contents.push_back(absl::StrCat("typed_per_filter_config={", + absl::StrJoin(parts, ", "), "}")); + } + return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); } std::string XdsApi::Route::ToString() const { @@ -171,6 +195,15 @@ std::string XdsApi::Route::ToString() const { if (max_stream_duration.has_value()) { contents.push_back(max_stream_duration->ToString()); } + if (!typed_per_filter_config.empty()) { + contents.push_back("typed_per_filter_config={"); + for (const auto& p : typed_per_filter_config) { + const std::string& name = p.first; + const auto& config = p.second; + contents.push_back(absl::StrCat(" ", name, "=", config.ToString())); + } + contents.push_back("}"); + } return absl::StrJoin(contents, "\n"); } @@ -193,6 +226,14 @@ std::string XdsApi::RdsUpdate::ToString() const { vhosts.push_back("\n }\n"); } vhosts.push_back(" ]\n"); + vhosts.push_back(" typed_per_filter_config={\n"); + for (const auto& p : vhost.typed_per_filter_config) { + const std::string& name = p.first; + const auto& config = p.second; + vhosts.push_back( + absl::StrCat(" ", name, "=", config.ToString(), "\n")); + } + vhosts.push_back(" }\n"); vhosts.push_back("]\n"); } return absl::StrJoin(vhosts, ""); @@ -398,6 +439,14 @@ bool XdsApi::DownstreamTlsContext::Empty() const { return common_tls_context.Empty(); } +// +// XdsApi::LdsUpdate::HttpFilter +// + +std::string XdsApi::LdsUpdate::HttpFilter::ToString() const { + return absl::StrCat("{name=", name, ", config=", config.ToString(), "}"); +} + // // XdsApi::LdsUpdate // @@ -420,6 +469,14 @@ std::string XdsApi::LdsUpdate::ToString() const { absl::StrFormat("rds_update=%s", rds_update->ToString())); } } + if (!http_filters.empty()) { + std::vector filter_strings; + for (const auto& http_filter : http_filters) { + filter_strings.push_back(http_filter.ToString()); + } + contents.push_back(absl::StrCat("http_filters=[", + absl::StrJoin(filter_strings, ", "), "]")); + } return absl::StrCat("{", absl::StrJoin(contents, ", "), "}"); } @@ -563,39 +620,63 @@ XdsApi::XdsApi(XdsClient* client, TraceFlag* tracer, node_(node), build_version_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING, " ", grpc_version_string())), - user_agent_name_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING)) {} + user_agent_name_(absl::StrCat("gRPC C-core ", GPR_PLATFORM_STRING)) { + // Populate upb symtab with xDS proto messages that we want to print + // properly in logs. + // Note: This won't actually work properly until upb adds support for + // Any fields in textproto printing (internal b/178821188). + envoy_config_listener_v3_Listener_getmsgdef(symtab_.ptr()); + envoy_config_route_v3_RouteConfiguration_getmsgdef(symtab_.ptr()); + envoy_config_cluster_v3_Cluster_getmsgdef(symtab_.ptr()); + envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef(symtab_.ptr()); + envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_getmsgdef( + symtab_.ptr()); + // Load HTTP filter proto messages into the upb symtab. + XdsHttpFilterRegistry::PopulateSymtab(symtab_.ptr()); +} namespace { +struct EncodingContext { + XdsClient* client; + TraceFlag* tracer; + upb_symtab* symtab; + upb_arena* arena; + bool use_v3; +}; + // Works for both std::string and absl::string_view. template inline upb_strview StdStringToUpbString(const T& str) { return upb_strview_make(str.data(), str.size()); } -void PopulateMetadataValue(upb_arena* arena, google_protobuf_Value* value_pb, - const Json& value); +void PopulateMetadataValue(const EncodingContext& context, + google_protobuf_Value* value_pb, const Json& value); -void PopulateListValue(upb_arena* arena, google_protobuf_ListValue* list_value, +void PopulateListValue(const EncodingContext& context, + google_protobuf_ListValue* list_value, const Json::Array& values) { for (const auto& value : values) { - auto* value_pb = google_protobuf_ListValue_add_values(list_value, arena); - PopulateMetadataValue(arena, value_pb, value); + auto* value_pb = + google_protobuf_ListValue_add_values(list_value, context.arena); + PopulateMetadataValue(context, value_pb, value); } } -void PopulateMetadata(upb_arena* arena, google_protobuf_Struct* metadata_pb, +void PopulateMetadata(const EncodingContext& context, + google_protobuf_Struct* metadata_pb, const Json::Object& metadata) { for (const auto& p : metadata) { - google_protobuf_Value* value = google_protobuf_Value_new(arena); - PopulateMetadataValue(arena, value, p.second); + google_protobuf_Value* value = google_protobuf_Value_new(context.arena); + PopulateMetadataValue(context, value, p.second); google_protobuf_Struct_fields_set( - metadata_pb, StdStringToUpbString(p.first), value, arena); + metadata_pb, StdStringToUpbString(p.first), value, context.arena); } } -void PopulateMetadataValue(upb_arena* arena, google_protobuf_Value* value_pb, - const Json& value) { +void PopulateMetadataValue(const EncodingContext& context, + google_protobuf_Value* value_pb, const Json& value) { switch (value.type()) { case Json::Type::JSON_NULL: google_protobuf_Value_set_null_value(value_pb, 0); @@ -616,14 +697,14 @@ void PopulateMetadataValue(upb_arena* arena, google_protobuf_Value* value_pb, break; case Json::Type::OBJECT: { google_protobuf_Struct* struct_value = - google_protobuf_Value_mutable_struct_value(value_pb, arena); - PopulateMetadata(arena, struct_value, value.object_value()); + google_protobuf_Value_mutable_struct_value(value_pb, context.arena); + PopulateMetadata(context, struct_value, value.object_value()); break; } case Json::Type::ARRAY: { google_protobuf_ListValue* list_value = - google_protobuf_Value_mutable_list_value(value_pb, arena); - PopulateListValue(arena, list_value, value.array_value()); + google_protobuf_Value_mutable_list_value(value_pb, context.arena); + PopulateListValue(context, list_value, value.array_value()); break; } } @@ -650,7 +731,8 @@ std::string EncodeStringField(uint32_t field_number, const std::string& str) { EncodeVarint(str.size()) + str; } -void PopulateBuildVersion(upb_arena* arena, envoy_config_core_v3_Node* node_msg, +void PopulateBuildVersion(const EncodingContext& context, + envoy_config_core_v3_Node* node_msg, const std::string& build_version) { std::string encoded_build_version = EncodeStringField(5, build_version); // TODO(roth): This should use upb_msg_addunknown(), but that API is @@ -658,10 +740,11 @@ void PopulateBuildVersion(upb_arena* arena, envoy_config_core_v3_Node* node_msg, // API for now. Change this once we upgrade to a version of upb that // fixes this bug. _upb_msg_addunknown(node_msg, encoded_build_version.data(), - encoded_build_version.size(), arena); + encoded_build_version.size(), context.arena); } -void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node, bool use_v3, +void PopulateNode(const EncodingContext& context, + const XdsBootstrap::Node* node, const std::string& build_version, const std::string& user_agent_name, envoy_config_core_v3_Node* node_msg) { @@ -676,13 +759,13 @@ void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node, bool use_v3, } if (!node->metadata.object_value().empty()) { google_protobuf_Struct* metadata = - envoy_config_core_v3_Node_mutable_metadata(node_msg, arena); - PopulateMetadata(arena, metadata, node->metadata.object_value()); + envoy_config_core_v3_Node_mutable_metadata(node_msg, context.arena); + PopulateMetadata(context, metadata, node->metadata.object_value()); } if (!node->locality_region.empty() || !node->locality_zone.empty() || !node->locality_subzone.empty()) { envoy_config_core_v3_Locality* locality = - envoy_config_core_v3_Node_mutable_locality(node_msg, arena); + envoy_config_core_v3_Node_mutable_locality(node_msg, context.arena); if (!node->locality_region.empty()) { envoy_config_core_v3_Locality_set_region( locality, StdStringToUpbString(node->locality_region)); @@ -697,8 +780,8 @@ void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node, bool use_v3, } } } - if (!use_v3) { - PopulateBuildVersion(arena, node_msg, build_version); + if (!context.use_v3) { + PopulateBuildVersion(context, node_msg, build_version); } envoy_config_core_v3_Node_set_user_agent_name( node_msg, StdStringToUpbString(user_agent_name)); @@ -706,7 +789,7 @@ void PopulateNode(upb_arena* arena, const XdsBootstrap::Node* node, bool use_v3, node_msg, upb_strview_makez(grpc_version_string())); envoy_config_core_v3_Node_add_client_features( node_msg, upb_strview_makez("envoy.lb.does_not_support_overprovisioning"), - arena); + context.arena); } inline absl::string_view UpbStringToAbsl(const upb_strview& str) { @@ -718,24 +801,25 @@ inline std::string UpbStringToStdString(const upb_strview& str) { } void MaybeLogDiscoveryRequest( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryRequest* request) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_service_discovery_v3_DiscoveryRequest_getmsgdef(symtab); + envoy_service_discovery_v3_DiscoveryRequest_getmsgdef(context.symtab); char buf[10240]; upb_text_encode(request, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] constructed ADS request: %s", client, - buf); + gpr_log(GPR_DEBUG, "[xds_client %p] constructed ADS request: %s", + context.client, buf); } } grpc_slice SerializeDiscoveryRequest( - upb_arena* arena, envoy_service_discovery_v3_DiscoveryRequest* request) { + const EncodingContext& context, + envoy_service_discovery_v3_DiscoveryRequest* request) { size_t output_length; char* output = envoy_service_discovery_v3_DiscoveryRequest_serialize( - request, arena, &output_length); + request, context.arena, &output_length); return grpc_slice_from_copied_buffer(output, output_length); } @@ -766,6 +850,8 @@ grpc_slice XdsApi::CreateAdsRequest( const std::string& version, const std::string& nonce, grpc_error* error, bool populate_node) { upb::Arena arena; + const EncodingContext context = {client_, tracer_, symtab_.ptr(), arena.ptr(), + server.ShouldUseV3()}; // Create a request. envoy_service_discovery_v3_DiscoveryRequest* request = envoy_service_discovery_v3_DiscoveryRequest_new(arena.ptr()); @@ -805,69 +891,88 @@ grpc_slice XdsApi::CreateAdsRequest( envoy_config_core_v3_Node* node_msg = envoy_service_discovery_v3_DiscoveryRequest_mutable_node(request, arena.ptr()); - PopulateNode(arena.ptr(), node_, server.ShouldUseV3(), build_version_, - user_agent_name_, node_msg); + PopulateNode(context, node_, build_version_, user_agent_name_, node_msg); } // Add resource_names. for (const auto& resource_name : resource_names) { envoy_service_discovery_v3_DiscoveryRequest_add_resource_names( request, StdStringToUpbString(resource_name), arena.ptr()); } - MaybeLogDiscoveryRequest(client_, tracer_, symtab_.ptr(), request); - return SerializeDiscoveryRequest(arena.ptr(), request); + MaybeLogDiscoveryRequest(context, request); + return SerializeDiscoveryRequest(context, request); } namespace { void MaybeLogDiscoveryResponse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryResponse* response) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_service_discovery_v3_DiscoveryResponse_getmsgdef(symtab); + envoy_service_discovery_v3_DiscoveryResponse_getmsgdef(context.symtab); char buf[10240]; upb_text_encode(response, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] received response: %s", client, buf); + gpr_log(GPR_DEBUG, "[xds_client %p] received response: %s", context.client, + buf); + } +} + +void MaybeLogHttpConnectionManager( + const EncodingContext& context, + const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager* + http_connection_manager_config) { + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && + gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { + const upb_msgdef* msg_type = + envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_getmsgdef( + context.symtab); + char buf[10240]; + upb_text_encode(http_connection_manager_config, msg_type, nullptr, 0, buf, + sizeof(buf)); + gpr_log(GPR_DEBUG, "[xds_client %p] HttpConnectionManager: %s", + context.client, buf); } } void MaybeLogRouteConfiguration( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_config_route_v3_RouteConfiguration* route_config) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_config_route_v3_RouteConfiguration_getmsgdef(symtab); + envoy_config_route_v3_RouteConfiguration_getmsgdef(context.symtab); char buf[10240]; upb_text_encode(route_config, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] RouteConfiguration: %s", client, buf); + gpr_log(GPR_DEBUG, "[xds_client %p] RouteConfiguration: %s", context.client, + buf); } } -void MaybeLogCluster(XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, +void MaybeLogCluster(const EncodingContext& context, const envoy_config_cluster_v3_Cluster* cluster) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_config_cluster_v3_Cluster_getmsgdef(symtab); + envoy_config_cluster_v3_Cluster_getmsgdef(context.symtab); char buf[10240]; upb_text_encode(cluster, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] Cluster: %s", client, buf); + gpr_log(GPR_DEBUG, "[xds_client %p] Cluster: %s", context.client, buf); } } void MaybeLogClusterLoadAssignment( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_config_endpoint_v3_ClusterLoadAssignment* cla) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef(symtab); + envoy_config_endpoint_v3_ClusterLoadAssignment_getmsgdef( + context.symtab); char buf[10240]; upb_text_encode(cla, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] ClusterLoadAssignment: %s", client, - buf); + gpr_log(GPR_DEBUG, "[xds_client %p] ClusterLoadAssignment: %s", + context.client, buf); } } @@ -1064,7 +1169,84 @@ grpc_error* RouteRuntimeFractionParse( return GRPC_ERROR_NONE; } -grpc_error* RouteActionParse(const envoy_config_route_v3_Route* route_msg, +grpc_error* ExtractHttpFilterTypeName(const EncodingContext& context, + const google_protobuf_Any* any, + absl::string_view* filter_type) { + *filter_type = UpbStringToAbsl(google_protobuf_Any_type_url(any)); + if (*filter_type == "type.googleapis.com/udpa.type.v1.TypedStruct") { + upb_strview any_value = google_protobuf_Any_value(any); + const auto* typed_struct = udpa_type_v1_TypedStruct_parse( + any_value.data, any_value.size, context.arena); + if (typed_struct == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "could not parse TypedStruct from filter config"); + } + *filter_type = + UpbStringToAbsl(udpa_type_v1_TypedStruct_type_url(typed_struct)); + } + *filter_type = absl::StripPrefix(*filter_type, "type.googleapis.com/"); + return GRPC_ERROR_NONE; +} + +template +grpc_error* ParseTypedPerFilterConfig( + const EncodingContext& context, const ParentType* parent, + const EntryType* (*entry_func)(const ParentType*, size_t*), + upb_strview (*key_func)(const EntryType*), + const google_protobuf_Any* (*value_func)(const EntryType*), + XdsApi::TypedPerFilterConfig* typed_per_filter_config) { + size_t filter_it = UPB_MAP_BEGIN; + while (true) { + const auto* filter_entry = entry_func(parent, &filter_it); + if (filter_entry == nullptr) break; + absl::string_view key = UpbStringToAbsl(key_func(filter_entry)); + if (key.empty()) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING("empty filter name in map"); + } + const google_protobuf_Any* any = value_func(filter_entry); + bool is_optional = false; + absl::string_view filter_type = + UpbStringToAbsl(google_protobuf_Any_type_url(any)); + if (filter_type == + "type.googleapis.com/envoy.config.route.v3.FilterConfig") { + upb_strview any_value = google_protobuf_Any_value(any); + const auto* filter_config = envoy_config_route_v3_FilterConfig_parse( + any_value.data, any_value.size, context.arena); + if (filter_config == nullptr) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("could not parse FilterConfig wrapper for ", key) + .c_str()); + } + is_optional = + envoy_config_route_v3_FilterConfig_is_optional(filter_config); + any = envoy_config_route_v3_FilterConfig_config(filter_config); + } + grpc_error* error = ExtractHttpFilterTypeName(context, any, &filter_type); + if (error != GRPC_ERROR_NONE) return error; + const XdsHttpFilterImpl* filter_impl = + XdsHttpFilterRegistry::GetFilterForType(filter_type); + if (filter_impl == nullptr) { + if (is_optional) continue; + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("no filter registered for config type ", filter_type) + .c_str()); + } + absl::StatusOr filter_config = + filter_impl->GenerateFilterConfigOverride( + google_protobuf_Any_value(any), context.arena); + if (!filter_config.ok()) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("filter config for type ", filter_type, + " failed to parse: ", filter_config.status().ToString()) + .c_str()); + } + (*typed_per_filter_config)[std::string(key)] = std::move(*filter_config); + } + return GRPC_ERROR_NONE; +} + +grpc_error* RouteActionParse(const EncodingContext& context, + const envoy_config_route_v3_Route* route_msg, XdsApi::Route* route, bool* ignore_route) { if (!envoy_config_route_v3_Route_has_route(route_msg)) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( @@ -1117,6 +1299,18 @@ grpc_error* RouteActionParse(const envoy_config_route_v3_Route* route_msg, cluster.weight = google_protobuf_UInt32Value_value(weight); if (cluster.weight == 0) continue; sum_of_weights += cluster.weight; + if ((XdsSecurityEnabled() || XdsFaultInjectionEnabled()) && + context.use_v3) { + grpc_error* error = ParseTypedPerFilterConfig< + envoy_config_route_v3_WeightedCluster_ClusterWeight, + envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry>( + context, cluster_weight, + envoy_config_route_v3_WeightedCluster_ClusterWeight_typed_per_filter_config_next, + envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_key, + envoy_config_route_v3_WeightedCluster_ClusterWeight_TypedPerFilterConfigEntry_value, + &cluster.typed_per_filter_config); + if (error != GRPC_ERROR_NONE) return error; + } route->weighted_clusters.emplace_back(std::move(cluster)); } if (total_weight != sum_of_weights) { @@ -1156,16 +1350,16 @@ grpc_error* RouteActionParse(const envoy_config_route_v3_Route* route_msg, } grpc_error* RouteConfigParse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_config_route_v3_RouteConfiguration* route_config, XdsApi::RdsUpdate* rds_update) { - MaybeLogRouteConfiguration(client, tracer, symtab, route_config); + MaybeLogRouteConfiguration(context, route_config); // Get the virtual hosts. - size_t size; + size_t num_virtual_hosts; const envoy_config_route_v3_VirtualHost* const* virtual_hosts = - envoy_config_route_v3_RouteConfiguration_virtual_hosts(route_config, - &size); - for (size_t i = 0; i < size; ++i) { + envoy_config_route_v3_RouteConfiguration_virtual_hosts( + route_config, &num_virtual_hosts); + for (size_t i = 0; i < num_virtual_hosts; ++i) { rds_update->virtual_hosts.emplace_back(); XdsApi::RdsUpdate::VirtualHost& vhost = rds_update->virtual_hosts.back(); // Parse domains. @@ -1185,6 +1379,19 @@ grpc_error* RouteConfigParse( if (vhost.domains.empty()) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING("VirtualHost has no domains"); } + // Parse typed_per_filter_config. + if ((XdsSecurityEnabled() || XdsFaultInjectionEnabled()) && + context.use_v3) { + grpc_error* error = ParseTypedPerFilterConfig< + envoy_config_route_v3_VirtualHost, + envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry>( + context, virtual_hosts[i], + envoy_config_route_v3_VirtualHost_typed_per_filter_config_next, + envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_key, + envoy_config_route_v3_VirtualHost_TypedPerFilterConfigEntry_value, + &vhost.typed_per_filter_config); + if (error != GRPC_ERROR_NONE) return error; + } // Parse routes. size_t num_routes; const envoy_config_route_v3_Route* const* routes = @@ -1212,9 +1419,21 @@ grpc_error* RouteConfigParse( if (error != GRPC_ERROR_NONE) return error; error = RouteRuntimeFractionParse(match, &route); if (error != GRPC_ERROR_NONE) return error; - error = RouteActionParse(routes[j], &route, &ignore_route); + error = RouteActionParse(context, routes[j], &route, &ignore_route); if (error != GRPC_ERROR_NONE) return error; if (ignore_route) continue; + if ((XdsSecurityEnabled() || XdsFaultInjectionEnabled()) && + context.use_v3) { + grpc_error* error = ParseTypedPerFilterConfig< + envoy_config_route_v3_Route, + envoy_config_route_v3_Route_TypedPerFilterConfigEntry>( + context, routes[j], + envoy_config_route_v3_Route_typed_per_filter_config_next, + envoy_config_route_v3_Route_TypedPerFilterConfigEntry_key, + envoy_config_route_v3_Route_TypedPerFilterConfigEntry_value, + &route.typed_per_filter_config); + if (error != GRPC_ERROR_NONE) return error; + } vhost.routes.emplace_back(std::move(route)); } if (vhost.routes.empty()) { @@ -1337,20 +1556,20 @@ grpc_error* CommonTlsContextParse( } grpc_error* LdsResponseParseClient( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, upb_arena* arena, + const EncodingContext& context, const envoy_config_listener_v3_ApiListener* api_listener, XdsApi::LdsUpdate* lds_update) { lds_update->type = XdsApi::LdsUpdate::ListenerType::kHttpApiListener; const upb_strview encoded_api_listener = google_protobuf_Any_value( envoy_config_listener_v3_ApiListener_api_listener(api_listener)); - const envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager* - http_connection_manager = - envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse( - encoded_api_listener.data, encoded_api_listener.size, arena); + const auto* http_connection_manager = + envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_parse( + encoded_api_listener.data, encoded_api_listener.size, context.arena); if (http_connection_manager == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Could not parse HttpConnectionManager config from ApiListener"); } + MaybeLogHttpConnectionManager(context, http_connection_manager); if (XdsTimeoutEnabled()) { // Obtain max_stream_duration from Http Protocol Options. const envoy_config_core_v3_HttpProtocolOptions* options = @@ -1367,6 +1586,58 @@ grpc_error* LdsResponseParseClient( } } } + // Parse filters. + if ((XdsSecurityEnabled() || XdsFaultInjectionEnabled()) && context.use_v3) { + size_t num_filters = 0; + const auto* http_filters = + envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_http_filters( + http_connection_manager, &num_filters); + std::set names_seen; + for (size_t i = 0; i < num_filters; ++i) { + const auto* http_filter = http_filters[i]; + absl::string_view name = UpbStringToAbsl( + envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_name( + http_filter)); + if (name.empty()) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("empty filter name at index ", i).c_str()); + } + if (names_seen.find(name) != names_seen.end()) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("duplicate HTTP filter name: ", name).c_str()); + } + names_seen.insert(name); + const google_protobuf_Any* any = + envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_typed_config( + http_filter); + absl::string_view filter_type; + grpc_error* error = ExtractHttpFilterTypeName(context, any, &filter_type); + if (error != GRPC_ERROR_NONE) return error; + const XdsHttpFilterImpl* filter_impl = + XdsHttpFilterRegistry::GetFilterForType(filter_type); + if (filter_impl == nullptr) { + if (envoy_extensions_filters_network_http_connection_manager_v3_HttpFilter_is_optional( + http_filter)) { + continue; + } + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat("no filter registered for config type ", filter_type) + .c_str()); + } + absl::StatusOr filter_config = + filter_impl->GenerateFilterConfig(google_protobuf_Any_value(any), + context.arena); + if (!filter_config.ok()) { + return GRPC_ERROR_CREATE_FROM_COPIED_STRING( + absl::StrCat( + "filter config for type ", filter_type, + " failed to parse: ", filter_config.status().ToString()) + .c_str()); + } + lds_update->http_filters.emplace_back(XdsApi::LdsUpdate::HttpFilter{ + std::string(name), std::move(*filter_config)}); + } + } // Found inlined route_config. Parse it to find the cluster_name. if (envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_route_config( http_connection_manager)) { @@ -1374,21 +1645,19 @@ grpc_error* LdsResponseParseClient( envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_route_config( http_connection_manager); XdsApi::RdsUpdate rds_update; - grpc_error* error = - RouteConfigParse(client, tracer, symtab, route_config, &rds_update); + grpc_error* error = RouteConfigParse(context, route_config, &rds_update); if (error != GRPC_ERROR_NONE) return error; lds_update->rds_update = std::move(rds_update); return GRPC_ERROR_NONE; } // Validate that RDS must be used to get the route_config dynamically. - if (!envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_has_rds( - http_connection_manager)) { - return GRPC_ERROR_CREATE_FROM_STATIC_STRING( - "HttpConnectionManager neither has inlined route_config nor RDS."); - } const envoy_extensions_filters_network_http_connection_manager_v3_Rds* rds = envoy_extensions_filters_network_http_connection_manager_v3_HttpConnectionManager_rds( http_connection_manager); + if (rds == nullptr) { + return GRPC_ERROR_CREATE_FROM_STATIC_STRING( + "HttpConnectionManager neither has inlined route_config nor RDS."); + } // Check that the ConfigSource specifies ADS. const envoy_config_core_v3_ConfigSource* config_source = envoy_extensions_filters_network_http_connection_manager_v3_Rds_config_source( @@ -1409,13 +1678,15 @@ grpc_error* LdsResponseParseClient( } grpc_error* LdsResponseParseServer( - upb_arena* arena, const envoy_config_listener_v3_Listener* listener, - const std::string& /*listener_name*/, - const envoy_config_core_v3_Address* /*address*/, + const EncodingContext& context, + const envoy_config_listener_v3_Listener* listener, XdsApi::LdsUpdate* lds_update) { lds_update->type = XdsApi::LdsUpdate::ListenerType::kTcpListener; // TODO(yashykt): Support filter chain match. // Right now, we are supporting and expecting only one entry in filter_chains. + // As part of this, we'll need to refactor the code to process the + // HttpConnectionManager config so that it is shared with the client-side + // parsing. size_t size = 0; auto* filter_chains = envoy_config_listener_v3_Listener_filter_chains(listener, &size); @@ -1439,7 +1710,7 @@ grpc_error* LdsResponseParseServer( auto* downstream_tls_context = envoy_extensions_transport_sockets_tls_v3_DownstreamTlsContext_parse( encoded_downstream_tls_context.data, - encoded_downstream_tls_context.size, arena); + encoded_downstream_tls_context.size, context.arena); if (downstream_tls_context == nullptr) { return GRPC_ERROR_CREATE_FROM_STATIC_STRING( "Can't decode downstream tls context."); @@ -1475,11 +1746,11 @@ grpc_error* LdsResponseParseServer( } grpc_error* LdsResponseParse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryResponse* response, const std::set& expected_listener_names, XdsApi::LdsUpdateMap* lds_update_map, - std::set* resource_names_failed, upb_arena* arena) { + std::set* resource_names_failed) { std::vector errors; // Get the resources from the response. size_t size; @@ -1499,8 +1770,8 @@ grpc_error* LdsResponseParse( const upb_strview encoded_listener = google_protobuf_Any_value(resources[i]); const envoy_config_listener_v3_Listener* listener = - envoy_config_listener_v3_Listener_parse(encoded_listener.data, - encoded_listener.size, arena); + envoy_config_listener_v3_Listener_parse( + encoded_listener.data, encoded_listener.size, context.arena); if (listener == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat("resource index ", i, ": Can't decode listener.") @@ -1546,11 +1817,9 @@ grpc_error* LdsResponseParse( } grpc_error* error = GRPC_ERROR_NONE; if (api_listener != nullptr) { - error = LdsResponseParseClient(client, tracer, symtab, arena, - api_listener, &lds_update); + error = LdsResponseParseClient(context, api_listener, &lds_update); } else { - error = LdsResponseParseServer(arena, listener, listener_name, address, - &lds_update); + error = LdsResponseParseServer(context, listener, &lds_update); } if (error != GRPC_ERROR_NONE) { errors.push_back(grpc_error_add_child( @@ -1564,11 +1833,11 @@ grpc_error* LdsResponseParse( } grpc_error* RdsResponseParse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryResponse* response, const std::set& expected_route_configuration_names, XdsApi::RdsUpdateMap* rds_update_map, - std::set* resource_names_failed, upb_arena* arena) { + std::set* resource_names_failed) { std::vector errors; // Get the resources from the response. size_t size; @@ -1589,7 +1858,8 @@ grpc_error* RdsResponseParse( google_protobuf_Any_value(resources[i]); const envoy_config_route_v3_RouteConfiguration* route_config = envoy_config_route_v3_RouteConfiguration_parse( - encoded_route_config.data, encoded_route_config.size, arena); + encoded_route_config.data, encoded_route_config.size, + context.arena); if (route_config == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat("resource index ", i, ": Can't decode route_config.") @@ -1614,8 +1884,7 @@ grpc_error* RdsResponseParse( } // Parse the route_config. XdsApi::RdsUpdate& rds_update = (*rds_update_map)[route_config_name]; - grpc_error* error = - RouteConfigParse(client, tracer, symtab, route_config, &rds_update); + grpc_error* error = RouteConfigParse(context, route_config, &rds_update); if (error != GRPC_ERROR_NONE) { errors.push_back(grpc_error_add_child( GRPC_ERROR_CREATE_FROM_COPIED_STRING( @@ -1628,11 +1897,11 @@ grpc_error* RdsResponseParse( } grpc_error* CdsResponseParse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryResponse* response, const std::set& expected_cluster_names, XdsApi::CdsUpdateMap* cds_update_map, - std::set* resource_names_failed, upb_arena* arena) { + std::set* resource_names_failed) { std::vector errors; // Get the resources from the response. size_t size; @@ -1652,15 +1921,15 @@ grpc_error* CdsResponseParse( // Decode the cluster. const upb_strview encoded_cluster = google_protobuf_Any_value(resources[i]); const envoy_config_cluster_v3_Cluster* cluster = - envoy_config_cluster_v3_Cluster_parse(encoded_cluster.data, - encoded_cluster.size, arena); + envoy_config_cluster_v3_Cluster_parse( + encoded_cluster.data, encoded_cluster.size, context.arena); if (cluster == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat("resource index ", i, ": Can't decode cluster.") .c_str())); continue; } - MaybeLogCluster(client, tracer, symtab, cluster); + MaybeLogCluster(context, cluster); // Ignore unexpected cluster names. std::string cluster_name = UpbStringToStdString(envoy_config_cluster_v3_Cluster_name(cluster)); @@ -1737,7 +2006,7 @@ grpc_error* CdsResponseParse( aggregate_cluster_config = envoy_extensions_clusters_aggregate_v3_ClusterConfig_parse( aggregate_cluster_config_upb_strview.data, - aggregate_cluster_config_upb_strview.size, arena); + aggregate_cluster_config_upb_strview.size, context.arena); if (aggregate_cluster_config == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat(cluster_name, ": Can't parse aggregate cluster.") @@ -1872,7 +2141,7 @@ grpc_error* CdsResponseParse( auto* upstream_tls_context = envoy_extensions_transport_sockets_tls_v3_UpstreamTlsContext_parse( encoded_upstream_tls_context.data, - encoded_upstream_tls_context.size, arena); + encoded_upstream_tls_context.size, context.arena); if (upstream_tls_context == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat(cluster_name, @@ -2068,11 +2337,11 @@ grpc_error* DropParseAndAppend( } grpc_error* EdsResponseParse( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_discovery_v3_DiscoveryResponse* response, const std::set& expected_eds_service_names, XdsApi::EdsUpdateMap* eds_update_map, - std::set* resource_names_failed, upb_arena* arena) { + std::set* resource_names_failed) { std::vector errors; // Get the resources from the response. size_t size; @@ -2094,7 +2363,7 @@ grpc_error* EdsResponseParse( envoy_config_endpoint_v3_ClusterLoadAssignment* cluster_load_assignment = envoy_config_endpoint_v3_ClusterLoadAssignment_parse( encoded_cluster_load_assignment.data, - encoded_cluster_load_assignment.size, arena); + encoded_cluster_load_assignment.size, context.arena); if (cluster_load_assignment == nullptr) { errors.push_back(GRPC_ERROR_CREATE_FROM_COPIED_STRING( absl::StrCat("resource index ", i, @@ -2102,8 +2371,7 @@ grpc_error* EdsResponseParse( .c_str())); continue; } - MaybeLogClusterLoadAssignment(client, tracer, symtab, - cluster_load_assignment); + MaybeLogClusterLoadAssignment(context, cluster_load_assignment); // Check the EDS service name. Ignore unexpected names. std::string eds_service_name = UpbStringToStdString( envoy_config_endpoint_v3_ClusterLoadAssignment_cluster_name( @@ -2214,13 +2482,15 @@ void MoveUpdatesToFailedSet(UpdateMap* update_map, } // namespace XdsApi::AdsParseResult XdsApi::ParseAdsResponse( - const grpc_slice& encoded_response, + const XdsBootstrap::XdsServer& server, const grpc_slice& encoded_response, const std::set& expected_listener_names, const std::set& expected_route_configuration_names, const std::set& expected_cluster_names, const std::set& expected_eds_service_names) { AdsParseResult result; upb::Arena arena; + const EncodingContext context = {client_, tracer_, symtab_.ptr(), arena.ptr(), + server.ShouldUseV3()}; // Decode the response. const envoy_service_discovery_v3_DiscoveryResponse* response = envoy_service_discovery_v3_DiscoveryResponse_parse( @@ -2232,7 +2502,7 @@ XdsApi::AdsParseResult XdsApi::ParseAdsResponse( GRPC_ERROR_CREATE_FROM_STATIC_STRING("Can't decode DiscoveryResponse."); return result; } - MaybeLogDiscoveryResponse(client_, tracer_, symtab_.ptr(), response); + MaybeLogDiscoveryResponse(context, response); // Record the type_url, the version_info, and the nonce of the response. result.type_url = TypeUrlInternalToExternal(UpbStringToAbsl( envoy_service_discovery_v3_DiscoveryResponse_type_url(response))); @@ -2242,34 +2512,33 @@ XdsApi::AdsParseResult XdsApi::ParseAdsResponse( envoy_service_discovery_v3_DiscoveryResponse_nonce(response)); // Parse the response according to the resource type. if (IsLds(result.type_url)) { - result.parse_error = LdsResponseParse( - client_, tracer_, symtab_.ptr(), response, expected_listener_names, - &result.lds_update_map, &result.resource_names_failed, arena.ptr()); + result.parse_error = + LdsResponseParse(context, response, expected_listener_names, + &result.lds_update_map, &result.resource_names_failed); if (result.parse_error != GRPC_ERROR_NONE) { MoveUpdatesToFailedSet(&result.lds_update_map, &result.resource_names_failed); } } else if (IsRds(result.type_url)) { - result.parse_error = RdsResponseParse( - client_, tracer_, symtab_.ptr(), response, - expected_route_configuration_names, &result.rds_update_map, - &result.resource_names_failed, arena.ptr()); + result.parse_error = + RdsResponseParse(context, response, expected_route_configuration_names, + &result.rds_update_map, &result.resource_names_failed); if (result.parse_error != GRPC_ERROR_NONE) { MoveUpdatesToFailedSet(&result.rds_update_map, &result.resource_names_failed); } } else if (IsCds(result.type_url)) { - result.parse_error = CdsResponseParse( - client_, tracer_, symtab_.ptr(), response, expected_cluster_names, - &result.cds_update_map, &result.resource_names_failed, arena.ptr()); + result.parse_error = + CdsResponseParse(context, response, expected_cluster_names, + &result.cds_update_map, &result.resource_names_failed); if (result.parse_error != GRPC_ERROR_NONE) { MoveUpdatesToFailedSet(&result.cds_update_map, &result.resource_names_failed); } } else if (IsEds(result.type_url)) { - result.parse_error = EdsResponseParse( - client_, tracer_, symtab_.ptr(), response, expected_eds_service_names, - &result.eds_update_map, &result.resource_names_failed, arena.ptr()); + result.parse_error = + EdsResponseParse(context, response, expected_eds_service_names, + &result.eds_update_map, &result.resource_names_failed); if (result.parse_error != GRPC_ERROR_NONE) { MoveUpdatesToFailedSet(&result.eds_update_map, &result.resource_names_failed); @@ -2281,25 +2550,25 @@ XdsApi::AdsParseResult XdsApi::ParseAdsResponse( namespace { void MaybeLogLrsRequest( - XdsClient* client, TraceFlag* tracer, upb_symtab* symtab, + const EncodingContext& context, const envoy_service_load_stats_v3_LoadStatsRequest* request) { - if (GRPC_TRACE_FLAG_ENABLED(*tracer) && + if (GRPC_TRACE_FLAG_ENABLED(*context.tracer) && gpr_should_log(GPR_LOG_SEVERITY_DEBUG)) { const upb_msgdef* msg_type = - envoy_service_load_stats_v3_LoadStatsRequest_getmsgdef(symtab); + envoy_service_load_stats_v3_LoadStatsRequest_getmsgdef(context.symtab); char buf[10240]; upb_text_encode(request, msg_type, nullptr, 0, buf, sizeof(buf)); - gpr_log(GPR_DEBUG, "[xds_client %p] constructed LRS request: %s", client, - buf); + gpr_log(GPR_DEBUG, "[xds_client %p] constructed LRS request: %s", + context.client, buf); } } grpc_slice SerializeLrsRequest( - const envoy_service_load_stats_v3_LoadStatsRequest* request, - upb_arena* arena) { + const EncodingContext& context, + const envoy_service_load_stats_v3_LoadStatsRequest* request) { size_t output_length; char* output = envoy_service_load_stats_v3_LoadStatsRequest_serialize( - request, arena, &output_length); + request, context.arena, &output_length); return grpc_slice_from_copied_buffer(output, output_length); } @@ -2308,6 +2577,8 @@ grpc_slice SerializeLrsRequest( grpc_slice XdsApi::CreateLrsInitialRequest( const XdsBootstrap::XdsServer& server) { upb::Arena arena; + const EncodingContext context = {client_, tracer_, symtab_.ptr(), arena.ptr(), + server.ShouldUseV3()}; // Create a request. envoy_service_load_stats_v3_LoadStatsRequest* request = envoy_service_load_stats_v3_LoadStatsRequest_new(arena.ptr()); @@ -2315,25 +2586,25 @@ grpc_slice XdsApi::CreateLrsInitialRequest( envoy_config_core_v3_Node* node_msg = envoy_service_load_stats_v3_LoadStatsRequest_mutable_node(request, arena.ptr()); - PopulateNode(arena.ptr(), node_, server.ShouldUseV3(), build_version_, - user_agent_name_, node_msg); + PopulateNode(context, node_, build_version_, user_agent_name_, node_msg); envoy_config_core_v3_Node_add_client_features( node_msg, upb_strview_makez("envoy.lrs.supports_send_all_clusters"), arena.ptr()); - MaybeLogLrsRequest(client_, tracer_, symtab_.ptr(), request); - return SerializeLrsRequest(request, arena.ptr()); + MaybeLogLrsRequest(context, request); + return SerializeLrsRequest(context, request); } namespace { void LocalityStatsPopulate( + const EncodingContext& context, envoy_config_endpoint_v3_UpstreamLocalityStats* output, const XdsLocalityName& locality_name, - const XdsClusterLocalityStats::Snapshot& snapshot, upb_arena* arena) { + const XdsClusterLocalityStats::Snapshot& snapshot) { // Set locality. envoy_config_core_v3_Locality* locality = - envoy_config_endpoint_v3_UpstreamLocalityStats_mutable_locality(output, - arena); + envoy_config_endpoint_v3_UpstreamLocalityStats_mutable_locality( + output, context.arena); if (!locality_name.region().empty()) { envoy_config_core_v3_Locality_set_region( locality, StdStringToUpbString(locality_name.region())); @@ -2361,7 +2632,7 @@ void LocalityStatsPopulate( const XdsClusterLocalityStats::BackendMetric& metric_value = p.second; envoy_config_endpoint_v3_EndpointLoadMetricStats* load_metric = envoy_config_endpoint_v3_UpstreamLocalityStats_add_load_metric_stats( - output, arena); + output, context.arena); envoy_config_endpoint_v3_EndpointLoadMetricStats_set_metric_name( load_metric, StdStringToUpbString(metric_name)); envoy_config_endpoint_v3_EndpointLoadMetricStats_set_num_requests_finished_with_metric( @@ -2376,6 +2647,8 @@ void LocalityStatsPopulate( grpc_slice XdsApi::CreateLrsRequest( ClusterLoadReportMap cluster_load_report_map) { upb::Arena arena; + const EncodingContext context = {client_, tracer_, symtab_.ptr(), arena.ptr(), + false}; // Create a request. envoy_service_load_stats_v3_LoadStatsRequest* request = envoy_service_load_stats_v3_LoadStatsRequest_new(arena.ptr()); @@ -2402,8 +2675,7 @@ grpc_slice XdsApi::CreateLrsRequest( envoy_config_endpoint_v3_UpstreamLocalityStats* locality_stats = envoy_config_endpoint_v3_ClusterStats_add_upstream_locality_stats( cluster_stats, arena.ptr()); - LocalityStatsPopulate(locality_stats, locality_name, snapshot, - arena.ptr()); + LocalityStatsPopulate(context, locality_stats, locality_name, snapshot); } // Add dropped requests. uint64_t total_dropped_requests = 0; @@ -2432,8 +2704,8 @@ grpc_slice XdsApi::CreateLrsRequest( google_protobuf_Duration_set_seconds(load_report_interval, timespec.tv_sec); google_protobuf_Duration_set_nanos(load_report_interval, timespec.tv_nsec); } - MaybeLogLrsRequest(client_, tracer_, symtab_.ptr(), request); - return SerializeLrsRequest(request, arena.ptr()); + MaybeLogLrsRequest(context, request); + return SerializeLrsRequest(context, request); } grpc_error* XdsApi::ParseLrsResponse(const grpc_slice& encoded_response, diff --git a/src/core/ext/xds/xds_api.h b/src/core/ext/xds/xds_api.h index 88aeeb43a34..d7f3d90b955 100644 --- a/src/core/ext/xds/xds_api.h +++ b/src/core/ext/xds/xds_api.h @@ -36,6 +36,7 @@ #include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/xds/xds_bootstrap.h" #include "src/core/ext/xds/xds_client_stats.h" +#include "src/core/ext/xds/xds_http_filters.h" #include "src/core/lib/security/authorization/matchers.h" namespace grpc_core { @@ -45,6 +46,10 @@ namespace grpc_core { // default. bool XdsSecurityEnabled(); +// TODO(lidiz): This will be removed once the fault injection feature is +// fully integration-tested and enabled by default. +bool XdsFaultInjectionEnabled(); + class XdsClient; class XdsApi { @@ -58,13 +63,16 @@ class XdsApi { int64_t seconds = 0; int32_t nanos = 0; bool operator==(const Duration& other) const { - return (seconds == other.seconds && nanos == other.nanos); + return seconds == other.seconds && nanos == other.nanos; } std::string ToString() const { return absl::StrFormat("Duration seconds: %ld, nanos %d", seconds, nanos); } }; + using TypedPerFilterConfig = + std::map; + // TODO(donnadionne): When we can use absl::variant<>, consider using that // for: PathMatcher, HeaderMatcher, cluster_name and weighted_clusters struct Route { @@ -75,9 +83,9 @@ class XdsApi { absl::optional fraction_per_million; bool operator==(const Matchers& other) const { - return (path_matcher == other.path_matcher && - header_matchers == other.header_matchers && - fraction_per_million == other.fraction_per_million); + return path_matcher == other.path_matcher && + header_matchers == other.header_matchers && + fraction_per_million == other.fraction_per_million; } std::string ToString() const; }; @@ -91,8 +99,11 @@ class XdsApi { struct ClusterWeight { std::string name; uint32_t weight; + TypedPerFilterConfig typed_per_filter_config; + bool operator==(const ClusterWeight& other) const { - return (name == other.name && weight == other.weight); + return name == other.name && weight == other.weight && + typed_per_filter_config == other.typed_per_filter_config; } std::string ToString() const; }; @@ -103,11 +114,13 @@ class XdsApi { // not set. absl::optional max_stream_duration; + TypedPerFilterConfig typed_per_filter_config; + bool operator==(const Route& other) const { - return (matchers == other.matchers && - cluster_name == other.cluster_name && - weighted_clusters == other.weighted_clusters && - max_stream_duration == other.max_stream_duration); + return matchers == other.matchers && cluster_name == other.cluster_name && + weighted_clusters == other.weighted_clusters && + max_stream_duration == other.max_stream_duration && + typed_per_filter_config == other.typed_per_filter_config; } std::string ToString() const; }; @@ -116,9 +129,11 @@ class XdsApi { struct VirtualHost { std::vector domains; std::vector routes; + TypedPerFilterConfig typed_per_filter_config; bool operator==(const VirtualHost& other) const { - return domains == other.domains && routes == other.routes; + return domains == other.domains && routes == other.routes && + typed_per_filter_config == other.typed_per_filter_config; } }; @@ -214,11 +229,24 @@ class XdsApi { // Present only if it is inlined in the LDS response. absl::optional rds_update; + struct HttpFilter { + std::string name; + XdsHttpFilterImpl::FilterConfig config; + + bool operator==(const HttpFilter& other) const { + return name == other.name && config == other.config; + } + + std::string ToString() const; + }; + std::vector http_filters; + bool operator==(const LdsUpdate& other) const { return downstream_tls_context == other.downstream_tls_context && route_config_name == other.route_config_name && rds_update == other.rds_update && - http_max_stream_duration == other.http_max_stream_duration; + http_max_stream_duration == other.http_max_stream_duration && + http_filters == other.http_filters; } std::string ToString() const; @@ -397,7 +425,7 @@ class XdsApi { std::set resource_names_failed; }; AdsParseResult ParseAdsResponse( - const grpc_slice& encoded_response, + const XdsBootstrap::XdsServer& server, const grpc_slice& encoded_response, const std::set& expected_listener_names, const std::set& expected_route_configuration_names, const std::set& expected_cluster_names, diff --git a/src/core/ext/xds/xds_client.cc b/src/core/ext/xds/xds_client.cc index efc1661147b..fddf9f201b2 100644 --- a/src/core/ext/xds/xds_client.cc +++ b/src/core/ext/xds/xds_client.cc @@ -38,6 +38,7 @@ #include "src/core/ext/xds/xds_channel_args.h" #include "src/core/ext/xds/xds_client.h" #include "src/core/ext/xds/xds_client_stats.h" +#include "src/core/ext/xds/xds_http_filters.h" #include "src/core/lib/backoff/backoff.h" #include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" @@ -1161,7 +1162,8 @@ bool XdsClient::ChannelState::AdsCallState::OnResponseReceivedLocked() { recv_message_payload_ = nullptr; // Parse and validate the response. XdsApi::AdsParseResult result = xds_client()->api_.ParseAdsResponse( - response_slice, ResourceNamesForRequest(XdsApi::kLdsTypeUrl), + chand()->server_, response_slice, + ResourceNamesForRequest(XdsApi::kLdsTypeUrl), ResourceNamesForRequest(XdsApi::kRdsTypeUrl), ResourceNamesForRequest(XdsApi::kCdsTypeUrl), ResourceNamesForRequest(XdsApi::kEdsTypeUrl)); @@ -2196,13 +2198,17 @@ XdsApi::ClusterLoadReportMap XdsClient::BuildLoadReportSnapshotLocked( // accessors for global state // -void XdsClientGlobalInit() { g_mu = new Mutex; } +void XdsClientGlobalInit() { + g_mu = new Mutex; + XdsHttpFilterRegistry::Init(); +} void XdsClientGlobalShutdown() { delete g_mu; g_mu = nullptr; gpr_free(g_fallback_bootstrap_config); g_fallback_bootstrap_config = nullptr; + XdsHttpFilterRegistry::Shutdown(); } RefCountedPtr XdsClient::GetOrCreate(grpc_error** error) { diff --git a/src/core/ext/xds/xds_http_filters.cc b/src/core/ext/xds/xds_http_filters.cc new file mode 100644 index 00000000000..11b644339b6 --- /dev/null +++ b/src/core/ext/xds/xds_http_filters.cc @@ -0,0 +1,107 @@ +// +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include + +#include "src/core/ext/xds/xds_http_filters.h" + +#include "envoy/extensions/filters/http/router/v3/router.upb.h" +#include "envoy/extensions/filters/http/router/v3/router.upbdefs.h" + +namespace grpc_core { + +const char* kXdsHttpRouterFilterConfigName = + "envoy.extensions.filters.http.router.v3.Router"; + +namespace { + +class XdsHttpRouterFilter : public XdsHttpFilterImpl { + public: + void PopulateSymtab(upb_symtab* symtab) const override { + envoy_extensions_filters_http_router_v3_Router_getmsgdef(symtab); + } + + absl::StatusOr GenerateFilterConfig( + upb_strview serialized_filter_config, upb_arena* arena) const override { + if (envoy_extensions_filters_http_router_v3_Router_parse( + serialized_filter_config.data, serialized_filter_config.size, + arena) == nullptr) { + return absl::InvalidArgumentError("could not parse router filter config"); + } + return FilterConfig{kXdsHttpRouterFilterConfigName, Json()}; + } + + absl::StatusOr GenerateFilterConfigOverride( + upb_strview /*serialized_filter_config*/, + upb_arena* /*arena*/) const override { + return absl::InvalidArgumentError( + "router filter does not support config override"); + } + + // No-op -- this filter is special-cased by the xds resolver. + const grpc_channel_filter* channel_filter() const override { return nullptr; } + + // No-op -- this filter is special-cased by the xds resolver. + absl::StatusOr GenerateServiceConfig( + const FilterConfig& /*hcm_filter_config*/, + const FilterConfig* /*filter_config_override*/) const override { + return absl::UnimplementedError("router filter should never be called"); + } +}; + +using FilterOwnerList = std::vector>; +using FilterRegistryMap = std::map; + +FilterOwnerList* g_filters = nullptr; +FilterRegistryMap* g_filter_registry = nullptr; + +} // namespace + +void XdsHttpFilterRegistry::RegisterFilter( + std::unique_ptr filter, + const std::set& config_proto_type_names) { + for (auto config_proto_type_name : config_proto_type_names) { + (*g_filter_registry)[config_proto_type_name] = filter.get(); + } + g_filters->push_back(std::move(filter)); +} + +const XdsHttpFilterImpl* XdsHttpFilterRegistry::GetFilterForType( + absl::string_view proto_type_name) { + auto it = g_filter_registry->find(proto_type_name); + if (it == g_filter_registry->end()) return nullptr; + return it->second; +} + +void XdsHttpFilterRegistry::PopulateSymtab(upb_symtab* symtab) { + for (const auto& filter : *g_filters) { + filter->PopulateSymtab(symtab); + } +} + +void XdsHttpFilterRegistry::Init() { + g_filters = new FilterOwnerList; + g_filter_registry = new FilterRegistryMap; + RegisterFilter(absl::make_unique(), + {kXdsHttpRouterFilterConfigName}); +} + +void XdsHttpFilterRegistry::Shutdown() { + delete g_filter_registry; + delete g_filters; +} + +} // namespace grpc_core diff --git a/src/core/ext/xds/xds_http_filters.h b/src/core/ext/xds/xds_http_filters.h new file mode 100644 index 00000000000..61e96cde665 --- /dev/null +++ b/src/core/ext/xds/xds_http_filters.h @@ -0,0 +1,124 @@ +// +// Copyright 2021 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef GRPC_CORE_EXT_XDS_XDS_HTTP_FILTERS_H +#define GRPC_CORE_EXT_XDS_XDS_HTTP_FILTERS_H + +#include + +#include +#include +#include + +#include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "google/protobuf/any.upb.h" +#include "upb/def.h" + +#include + +#include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/json/json.h" + +namespace grpc_core { + +extern const char* kXdsHttpRouterFilterConfigName; + +class XdsHttpFilterImpl { + public: + struct FilterConfig { + absl::string_view config_proto_type_name; + Json config; + + bool operator==(const FilterConfig& other) const { + return config_proto_type_name == other.config_proto_type_name && + config == other.config; + } + std::string ToString() const { + return absl::StrCat("{config_proto_type_name=", config_proto_type_name, + " config=", config.Dump(), "}"); + } + }; + + // Service config data for the filter, returned by GenerateServiceConfig(). + struct ServiceConfigJsonEntry { + // The top-level field name in the method config. + // Filter implementations should use their primary config proto type + // name for this. + // The value of this field in the method config will be a JSON array, + // which will be populated with the elements returned by each filter + // instance. + std::string service_config_field_name; + // The element to add to the JSON array. + std::string element; + }; + + virtual ~XdsHttpFilterImpl() = default; + + // Loads the proto message into the upb symtab. + virtual void PopulateSymtab(upb_symtab* symtab) const = 0; + + // Generates a Config from the xDS filter config proto. + // Used for the top-level config in the HCM HTTP filter list. + virtual absl::StatusOr GenerateFilterConfig( + upb_strview serialized_filter_config, upb_arena* arena) const = 0; + + // Generates a Config from the xDS filter config proto. + // Used for the typed_per_filter_config override in VirtualHost and Route. + virtual absl::StatusOr GenerateFilterConfigOverride( + upb_strview serialized_filter_config, upb_arena* arena) const = 0; + + // C-core channel filter implementation. + virtual const grpc_channel_filter* channel_filter() const = 0; + + // Modifies channel args that may affect service config parsing (not + // visible to the channel as a whole). + // Takes ownership of args. Caller takes ownership of return value. + virtual grpc_channel_args* ModifyChannelArgs(grpc_channel_args* args) const { + return args; + } + + // Function to convert the Configs into a JSON string to be added to the + // per-method part of the service config. + // The hcm_filter_config comes from the HttpConnectionManager config. + // The filter_config_override comes from the first of the ClusterWeight, + // Route, or VirtualHost entries that it is found in, or null if + // there is no override in any of those locations. + virtual absl::StatusOr GenerateServiceConfig( + const FilterConfig& hcm_filter_config, + const FilterConfig* filter_config_override) const = 0; +}; + +class XdsHttpFilterRegistry { + public: + static void RegisterFilter( + std::unique_ptr filter, + const std::set& config_proto_type_names); + + static const XdsHttpFilterImpl* GetFilterForType( + absl::string_view proto_type_name); + + static void PopulateSymtab(upb_symtab* symtab); + + // Global init and shutdown. + static void Init(); + static void Shutdown(); +}; + +} // namespace grpc_core + +#endif /* GRPC_CORE_EXT_XDS_XDS_HTTP_FILTERS_H */ diff --git a/src/core/lib/channel/channel_stack.cc b/src/core/lib/channel/channel_stack.cc index e9b348972f2..60b83667c54 100644 --- a/src/core/lib/channel/channel_stack.cc +++ b/src/core/lib/channel/channel_stack.cc @@ -81,6 +81,18 @@ grpc_channel_element* grpc_channel_stack_last_element( return grpc_channel_stack_element(channel_stack, channel_stack->count - 1); } +size_t grpc_channel_stack_filter_instance_number( + grpc_channel_stack* channel_stack, grpc_channel_element* elem) { + size_t num_found = 0; + for (size_t i = 0; i < channel_stack->count; ++i) { + grpc_channel_element* element = + grpc_channel_stack_element(channel_stack, i); + if (element == elem) break; + if (element->filter == elem->filter) ++num_found; + } + return num_found; +} + grpc_call_element* grpc_call_stack_element(grpc_call_stack* call_stack, size_t index) { return CALL_ELEMS_FROM_STACK(call_stack) + index; diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index e297df9488d..1573ae1e056 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -204,6 +204,13 @@ grpc_channel_element* grpc_channel_stack_element(grpc_channel_stack* stack, /* Get the last channel element in a channel stack */ grpc_channel_element* grpc_channel_stack_last_element( grpc_channel_stack* stack); + +// A utility function for a filter to determine how many other instances +// of the same filter exist above it in the same stack. Intended to be +// used in the filter's init_channel_elem() method. +size_t grpc_channel_stack_filter_instance_number( + grpc_channel_stack* channel_stack, grpc_channel_element* elem); + /* Get a call stack element given a call stack and an index */ grpc_call_element* grpc_call_stack_element(grpc_call_stack* stack, size_t i); diff --git a/src/core/lib/surface/lame_client.cc b/src/core/lib/surface/lame_client.cc index d32cc28ea65..f92c1920df3 100644 --- a/src/core/lib/surface/lame_client.cc +++ b/src/core/lib/surface/lame_client.cc @@ -35,12 +35,20 @@ #include "src/core/lib/transport/connectivity_state.h" #include "src/core/lib/transport/static_metadata.h" +#define GRPC_ARG_LAME_FILTER_ERROR "grpc.lame_filter_error" + namespace grpc_core { namespace { struct ChannelData { - ChannelData() : state_tracker("lame_channel", GRPC_CHANNEL_SHUTDOWN) {} + explicit ChannelData(grpc_channel_element_args* args) + : state_tracker("lame_channel", GRPC_CHANNEL_SHUTDOWN) { + grpc_error* err = grpc_channel_args_find_pointer( + args->channel_args, GRPC_ARG_LAME_FILTER_ERROR); + if (err != nullptr) error = GRPC_ERROR_REF(err); + } + ~ChannelData() { GRPC_ERROR_UNREF(error); } grpc_error* error = GRPC_ERROR_NONE; @@ -105,9 +113,7 @@ static void lame_destroy_call_elem(grpc_call_element* /*elem*/, static grpc_error* lame_init_channel_elem(grpc_channel_element* elem, grpc_channel_element_args* args) { - GPR_ASSERT(args->is_first); - GPR_ASSERT(args->is_last); - new (elem->channel_data) ChannelData; + new (elem->channel_data) ChannelData(args); return GRPC_ERROR_NONE; } @@ -116,12 +122,25 @@ static void lame_destroy_channel_elem(grpc_channel_element* elem) { chand->~ChannelData(); } +// Channel arg vtable for a grpc_error*. +void* ErrorCopy(void* p) { + grpc_error* error = static_cast(p); + return GRPC_ERROR_REF(error); +} +void ErrorDestroy(void* p) { + grpc_error* error = static_cast(p); + GRPC_ERROR_UNREF(error); +} +int ErrorCompare(void* p, void* q) { return GPR_ICMP(p, q); } +const grpc_arg_pointer_vtable kLameFilterErrorArgVtable = { + ErrorCopy, ErrorDestroy, ErrorCompare}; + } // namespace -void SetLameFilterError(grpc_channel_element* elem, grpc_error* error) { - GPR_ASSERT(elem->filter == &grpc_lame_filter); - auto chand = static_cast(elem->channel_data); - chand->error = error; +grpc_arg MakeLameClientErrorArg(grpc_error* error) { + return grpc_channel_arg_pointer_create( + const_cast(GRPC_ARG_LAME_FILTER_ERROR), error, + &kLameFilterErrorArgVtable); } } // namespace grpc_core @@ -146,20 +165,20 @@ grpc_channel* grpc_lame_client_channel_create(const char* target, grpc_status_code error_code, const char* error_message) { grpc_core::ExecCtx exec_ctx; - grpc_channel_element* elem; - grpc_channel* channel = - grpc_channel_create(target, nullptr, GRPC_CLIENT_LAME_CHANNEL, nullptr); - elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); GRPC_API_TRACE( "grpc_lame_client_channel_create(target=%s, error_code=%d, " "error_message=%s)", 3, (target, (int)error_code, error_message)); - grpc_core::SetLameFilterError( - elem, grpc_error_set_str( - grpc_error_set_int( - GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"), - GRPC_ERROR_INT_GRPC_STATUS, error_code), - GRPC_ERROR_STR_GRPC_MESSAGE, - grpc_slice_from_static_string(error_message))); + grpc_error* error = grpc_error_set_str( + grpc_error_set_int( + GRPC_ERROR_CREATE_FROM_STATIC_STRING("lame client channel"), + GRPC_ERROR_INT_GRPC_STATUS, error_code), + GRPC_ERROR_STR_GRPC_MESSAGE, + grpc_slice_from_static_string(error_message)); + grpc_arg error_arg = grpc_core::MakeLameClientErrorArg(error); + grpc_channel_args args = {1, &error_arg}; + grpc_channel* channel = + grpc_channel_create(target, &args, GRPC_CLIENT_LAME_CHANNEL, nullptr); + GRPC_ERROR_UNREF(error); return channel; } diff --git a/src/core/lib/surface/lame_client.h b/src/core/lib/surface/lame_client.h index 8fd3f4eb6c3..94c7e553ad8 100644 --- a/src/core/lib/surface/lame_client.h +++ b/src/core/lib/surface/lame_client.h @@ -23,10 +23,11 @@ #include "src/core/lib/channel/channel_stack.h" -extern const grpc_channel_filter grpc_lame_filter; - namespace grpc_core { -void SetLameFilterError(grpc_channel_element* elem, grpc_error* error); +// Does NOT take ownership of error. +grpc_arg MakeLameClientErrorArg(grpc_error* error); } // namespace grpc_core +extern const grpc_channel_filter grpc_lame_filter; + #endif /* GRPC_CORE_LIB_SURFACE_LAME_CLIENT_H */ diff --git a/src/proto/grpc/testing/xds/v3/BUILD b/src/proto/grpc/testing/xds/v3/BUILD index 6d212fa72c1..024cd63d786 100644 --- a/src/proto/grpc/testing/xds/v3/BUILD +++ b/src/proto/grpc/testing/xds/v3/BUILD @@ -186,6 +186,7 @@ grpc_proto_library( srcs = [ "http_connection_manager.proto", ], + well_known_protos = True, deps = [ "config_source_proto", "protocol_proto", @@ -193,6 +194,13 @@ grpc_proto_library( ], ) +grpc_proto_library( + name = "router_proto", + srcs = [ + "router.proto", + ], +) + grpc_proto_library( name = "string_proto", srcs = [ diff --git a/src/proto/grpc/testing/xds/v3/http_connection_manager.proto b/src/proto/grpc/testing/xds/v3/http_connection_manager.proto index 786ac0f01dc..74477073c70 100644 --- a/src/proto/grpc/testing/xds/v3/http_connection_manager.proto +++ b/src/proto/grpc/testing/xds/v3/http_connection_manager.proto @@ -18,6 +18,8 @@ syntax = "proto3"; package envoy.extensions.filters.network.http_connection_manager.v3; +import "google/protobuf/any.proto"; + import "src/proto/grpc/testing/xds/v3/config_source.proto"; import "src/proto/grpc/testing/xds/v3/protocol.proto"; import "src/proto/grpc/testing/xds/v3/route.proto"; @@ -40,6 +42,11 @@ message HttpConnectionManager { ScopedRoutes scoped_routes = 31; } + // A list of individual HTTP filters that make up the filter chain for + // requests made to the connection manager. :ref:`Order matters ` + // as the filters are processed sequentially as request events happen. + repeated HttpFilter http_filters = 5; + // Additional settings for HTTP requests handled by the connection manager. These will be // applicable to both HTTP1 and HTTP2 requests. config.core.v3.HttpProtocolOptions common_http_protocol_options = 35; @@ -58,3 +65,18 @@ message Rds { message ScopedRoutes { } + +message HttpFilter { + // The name of the filter configuration. The name is used as a fallback to + // select an extension if the type of the configuration proto is not + // sufficient. It also serves as a resource name in ExtensionConfigDS. + string name = 1; + + oneof config_type { + // Filter specific configuration which depends on the filter being instantiated. See the supported + // filters for further documentation. + google.protobuf.Any typed_config = 4; + } + + bool is_optional = 6; +} diff --git a/src/proto/grpc/testing/xds/v3/route.proto b/src/proto/grpc/testing/xds/v3/route.proto index b7fc40b279e..baeaaf644d4 100644 --- a/src/proto/grpc/testing/xds/v3/route.proto +++ b/src/proto/grpc/testing/xds/v3/route.proto @@ -23,6 +23,7 @@ import "src/proto/grpc/testing/xds/v3/regex.proto"; import "src/proto/grpc/testing/xds/v3/percent.proto"; import "src/proto/grpc/testing/xds/v3/range.proto"; +import "google/protobuf/any.proto"; import "google/protobuf/duration.proto"; import "google/protobuf/wrappers.proto"; @@ -64,6 +65,13 @@ message VirtualHost { // 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; + + // 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.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter + // specific; see the :ref:`HTTP filter documentation ` + // for if and how it is utilized. + map typed_per_filter_config = 15; } // A route is both a specification of how to match a request as well as an indication of what to do @@ -88,6 +96,13 @@ message Route { // Return a redirect. RedirectAction redirect = 3; } + + // The typed_per_filter_config field can be used to provide route-specific + // configurations for filters. The key should match the filter name, such as + // *envoy.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter + // specific; see the :ref:`HTTP filter documentation ` for + // if and how it is utilized. + map typed_per_filter_config = 13; } // Compared to the :ref:`cluster ` field that specifies a @@ -108,6 +123,13 @@ message WeightedCluster { // 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; + + // 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.filters.http.buffer* for the HTTP buffer filter. Use of this field is filter + // specific; see the :ref:`HTTP filter documentation ` + // for if and how it is utilized. + map typed_per_filter_config = 10; } // Specifies one or more upstream clusters associated with the route. @@ -334,3 +356,13 @@ message RouteConfiguration { message RedirectAction { } + +message FilterConfig { + // The filter config. + google.protobuf.Any config = 1; + + // If true, the filter is optional, meaning that if the client does + // not support the specified filter, it may ignore the map entry rather + // than rejecting the config. + bool is_optional = 2; +} diff --git a/src/proto/grpc/testing/xds/v3/router.proto b/src/proto/grpc/testing/xds/v3/router.proto new file mode 100644 index 00000000000..00b11b37128 --- /dev/null +++ b/src/proto/grpc/testing/xds/v3/router.proto @@ -0,0 +1,28 @@ +// Copyright 2021 The gRPC Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Local copy of Envoy xDS proto file, used for testing only. + +syntax = "proto3"; + +package envoy.extensions.filters.http.router.v3; + +// [#protodoc-title: Router] +// Router :ref:`configuration overview `. +// [#extension: envoy.filters.http.router] + +// We don't actually use any of the fields in this message, but we need +// the message itself to signify which filter to use. +message Router { +} diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py index 68e641c8966..0cc1ff89eeb 100644 --- a/src/python/grpcio/grpc_core_dependencies.py +++ b/src/python/grpcio/grpc_core_dependencies.py @@ -153,6 +153,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c', 'src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c', 'src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c', + 'src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c', 'src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c', 'src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c', @@ -201,6 +202,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upb-generated/udpa/annotations/status.upb.c', 'src/core/ext/upb-generated/udpa/annotations/versioning.upb.c', 'src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c', + 'src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c', 'src/core/ext/upb-generated/validate/validate.upb.c', 'src/core/ext/upb-generated/xds/core/v3/authority.upb.c', 'src/core/ext/upb-generated/xds/core/v3/collection_entry.upb.c', @@ -240,6 +242,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upbdefs-generated/envoy/config/route/v3/scoped_route.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c', + 'src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c', 'src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/common.upbdefs.c', @@ -280,6 +283,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/upbdefs-generated/udpa/annotations/sensitive.upbdefs.c', 'src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c', 'src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c', + 'src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c', 'src/core/ext/upbdefs-generated/validate/validate.upbdefs.c', 'src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c', 'src/core/ext/upbdefs-generated/xds/core/v3/collection_entry.upbdefs.c', @@ -295,6 +299,7 @@ CORE_SOURCE_FILES = [ 'src/core/ext/xds/xds_certificate_provider.cc', 'src/core/ext/xds/xds_client.cc', 'src/core/ext/xds/xds_client_stats.cc', + 'src/core/ext/xds/xds_http_filters.cc', 'src/core/ext/xds/xds_server_config_fetcher.cc', 'src/core/lib/avl/avl.cc', 'src/core/lib/backoff/backoff.cc', diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD index d0bee59ff8b..f637482c610 100644 --- a/test/cpp/end2end/BUILD +++ b/test/cpp/end2end/BUILD @@ -544,6 +544,7 @@ grpc_cc_test( "//src/proto/grpc/testing/xds/v3:listener_proto", "//src/proto/grpc/testing/xds/v3:lrs_proto", "//src/proto/grpc/testing/xds/v3:route_proto", + "//src/proto/grpc/testing/xds/v3:router_proto", "//src/proto/grpc/testing/xds/v3:tls_proto", "//test/core/util:grpc_test_util", "//test/cpp/util:test_util", diff --git a/test/cpp/end2end/xds_end2end_test.cc b/test/cpp/end2end/xds_end2end_test.cc index e1033f2fdb3..cce899eb3e4 100644 --- a/test/cpp/end2end/xds_end2end_test.cc +++ b/test/cpp/end2end/xds_end2end_test.cc @@ -91,6 +91,7 @@ #include "src/proto/grpc/testing/xds/v3/listener.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/route.grpc.pb.h" +#include "src/proto/grpc/testing/xds/v3/router.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/tls.grpc.pb.h" namespace grpc { @@ -1580,6 +1581,13 @@ class XdsEnd2endTest : public ::testing::TestWithParam { // Initialize default xDS resources. // Construct LDS resource. default_listener_.set_name(kServerName); + HttpConnectionManager http_connection_manager; + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("router"); + filter->mutable_typed_config()->PackFrom( + envoy::extensions::filters::http::router::v3::Router()); + default_listener_.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); // Construct RDS resource. default_route_config_.set_name(kDefaultRouteConfigurationName); auto* virtual_host = default_route_config_.add_virtual_hosts(); @@ -1985,6 +1993,10 @@ class XdsEnd2endTest : public ::testing::TestWithParam { static Listener BuildListener(const RouteConfiguration& route_config) { HttpConnectionManager http_connection_manager; *(http_connection_manager.mutable_route_config()) = route_config; + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("router"); + filter->mutable_typed_config()->PackFrom( + envoy::extensions::filters::http::router::v3::Router()); Listener listener; listener.set_name(kServerName); listener.mutable_api_listener()->mutable_api_listener()->PackFrom( @@ -2603,6 +2615,8 @@ TEST_P(XdsResolverOnlyTest, RestartsRequestsUponReconnection) { // Manually configure use of RDS. auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); auto* rds = http_connection_manager.mutable_rds(); rds->set_route_config_name(kDefaultRouteConfigurationName); rds->mutable_config_source()->mutable_ads(); @@ -3004,7 +3018,7 @@ TEST_P(LdsTest, NoApiListener) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -3017,6 +3031,8 @@ TEST_P(LdsTest, NoApiListener) { TEST_P(LdsTest, WrongRouteSpecifier) { auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); http_connection_manager.mutable_scoped_routes(); listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); @@ -3024,7 +3040,7 @@ TEST_P(LdsTest, WrongRouteSpecifier) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -3038,6 +3054,8 @@ TEST_P(LdsTest, WrongRouteSpecifier) { TEST_P(LdsTest, RdsMissingConfigSource) { auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); http_connection_manager.mutable_rds()->set_route_config_name( kDefaultRouteConfigurationName); listener.mutable_api_listener()->mutable_api_listener()->PackFrom( @@ -3046,7 +3064,7 @@ TEST_P(LdsTest, RdsMissingConfigSource) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -3059,6 +3077,8 @@ TEST_P(LdsTest, RdsMissingConfigSource) { TEST_P(LdsTest, RdsConfigSourceDoesNotSpecifyAds) { auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); auto* rds = http_connection_manager.mutable_rds(); rds->set_route_config_name(kDefaultRouteConfigurationName); rds->mutable_config_source()->mutable_self(); @@ -3068,7 +3088,7 @@ TEST_P(LdsTest, RdsConfigSourceDoesNotSpecifyAds) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -3096,7 +3116,7 @@ TEST_P(LdsTest, MultipleBadResources) { EchoResponse response; grpc::Status status = stub2->Echo(&context, request, &response); EXPECT_FALSE(status.ok()); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -3109,6 +3129,196 @@ TEST_P(LdsTest, MultipleBadResources) { ": Listener has neither address nor ApiListener")))); } +// TODO(roth): Remove this test when we remove the +// GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION environment variable guard. +TEST_P(LdsTest, HttpFiltersEnabled) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + SetNextResolutionForLbChannelAllBalancers(); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + WaitForAllBackends(); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we fail RPCs if there is no router filter. +TEST_P(LdsTest, FailRpcsIfNoHttpRouterFilter) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + SetNextResolutionForLbChannelAllBalancers(); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + http_connection_manager.clear_http_filters(); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + Status status = SendRpc(); + EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); + EXPECT_EQ(status.error_message(), "no xDS HTTP router filter configured"); + // Wait until xDS server sees ACK. + while (balancers_[0]->ads_service()->lds_response_state().state == + AdsServiceImpl::ResponseState::SENT) { + CheckRpcSendFailure(); + } + const auto response_state = + balancers_[0]->ads_service()->lds_response_state(); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// TODO(lidiz): As part of adding the fault injection filter, add a test +// that we ignore filters after the router filter. + +// Test that we NACK empty filter names. +TEST_P(LdsTest, RejectsEmptyHttpFilterName) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + auto* filter = http_connection_manager.add_http_filters(); + filter->mutable_typed_config()->PackFrom(Listener()); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (balancers_[0]->ads_service()->lds_response_state().state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = + balancers_[0]->ads_service()->lds_response_state(); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("empty filter name at index 1")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK duplicate HTTP filter names. +TEST_P(LdsTest, RejectsDuplicateHttpFilterName) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + *http_connection_manager.add_http_filters() = + http_connection_manager.http_filters(0); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (balancers_[0]->ads_service()->lds_response_state().state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = + balancers_[0]->ads_service()->lds_response_state(); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("duplicate HTTP filter name: router")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unknown filter types. +TEST_P(LdsTest, RejectsUnknownHttpFilterType) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("unknown"); + filter->mutable_typed_config()->PackFrom(Listener()); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (balancers_[0]->ads_service()->lds_response_state().state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = + balancers_[0]->ads_service()->lds_response_state(); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("no filter registered for config type " + "envoy.config.listener.v3.Listener")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we ignore optional unknown filter types. +TEST_P(LdsTest, IgnoresOptionalUnknownHttpFilterType) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("unknown"); + filter->mutable_typed_config()->PackFrom(Listener()); + filter->set_is_optional(true); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + SetNextResolutionForLbChannelAllBalancers(); + WaitForAllBackends(); + EXPECT_EQ(balancers_[0]->ads_service()->lds_response_state().state, + AdsServiceImpl::ResponseState::ACKED); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unparseable filter configs. +TEST_P(LdsTest, RejectsUnparseableHttpFilterType) { + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + auto listener = default_listener_; + HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); + auto* filter = http_connection_manager.add_http_filters(); + filter->set_name("unknown"); + filter->mutable_typed_config()->PackFrom(listener); + filter->mutable_typed_config()->set_type_url( + "type.googleapis.com/envoy.extensions.filters.http.router.v3.Router"); + listener.mutable_api_listener()->mutable_api_listener()->PackFrom( + http_connection_manager); + SetListenerAndRouteConfiguration(0, listener, default_route_config_); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (balancers_[0]->ads_service()->lds_response_state().state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = + balancers_[0]->ads_service()->lds_response_state(); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT( + response_state.error_message, + ::testing::HasSubstr( + "filter config for type " + "envoy.extensions.filters.http.router.v3.Router failed to parse")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + using LdsRdsTest = BasicTest; // Tests that LDS client should send an ACK upon correct LDS response (with @@ -3160,7 +3370,7 @@ TEST_P(LdsRdsTest, NoMatchedDomain) { CheckRpcSendFailure(); // Do a bit of polling, to allow the ACK to get to the ADS server. channel_->WaitForConnected(grpc_timeout_milliseconds_to_deadline(100)); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -3207,7 +3417,7 @@ TEST_P(LdsRdsTest, RouteMatchHasQueryParameters) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3226,7 +3436,7 @@ TEST_P(LdsRdsTest, RouteMatchHasValidPrefixEmptyOrSingleSlash) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); (void)SendRpc(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -3240,7 +3450,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixNoLeadingSlash) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3256,7 +3466,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixExtraContent) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3272,7 +3482,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPrefixDoubleSlash) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3288,7 +3498,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathEmptyPath) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3304,7 +3514,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathNoLeadingSlash) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3320,7 +3530,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathTooManySlashes) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3336,7 +3546,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathOnlyOneSlash) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3352,7 +3562,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingService) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3368,7 +3578,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathMissingMethod) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No valid routes specified.")); @@ -3385,7 +3595,7 @@ TEST_P(LdsRdsTest, RouteMatchHasInvalidPathRegex) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr( @@ -3401,7 +3611,7 @@ TEST_P(LdsRdsTest, RouteHasNoRouteAction) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr("No RouteAction found in route.")); @@ -3419,7 +3629,7 @@ TEST_P(LdsRdsTest, RouteActionClusterHasEmptyClusterName) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( response_state.error_message, @@ -3447,7 +3657,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetHasIncorrectTotalWeightSet) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr( @@ -3474,7 +3684,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedClusterHasZeroTotalWeight) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( response_state.error_message, @@ -3502,7 +3712,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasEmptyClusterName) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( response_state.error_message, @@ -3530,7 +3740,7 @@ TEST_P(LdsRdsTest, RouteActionWeightedTargetClusterHasNoWeight) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, ::testing::HasSubstr( @@ -3550,7 +3760,7 @@ TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRegex) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( response_state.error_message, @@ -3572,7 +3782,7 @@ TEST_P(LdsRdsTest, RouteHeaderMatchInvalidRange) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( response_state.error_message, @@ -4634,6 +4844,8 @@ TEST_P(LdsRdsTest, XdsRoutingApplyXdsTimeout) { // Construct listener. auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); // Set up HTTP max_stream_duration of 3.5 seconds auto* duration = http_connection_manager.mutable_common_http_protocol_options() @@ -4772,6 +4984,8 @@ TEST_P(LdsRdsTest, XdsRoutingHttpTimeoutDisabled) { // Construct listener. auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); // Set up HTTP max_stream_duration of 3.5 seconds auto* duration = http_connection_manager.mutable_common_http_protocol_options() @@ -4837,6 +5051,8 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenXdsTimeoutExplicit0) { // Construct listener. auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); // Set up HTTP max_stream_duration of 3.5 seconds auto* duration = http_connection_manager.mutable_common_http_protocol_options() @@ -4910,14 +5126,16 @@ TEST_P(LdsRdsTest, XdsRoutingApplyApplicationTimeoutWhenHttpTimeoutExplicit0) { {"locality0", {g_port_saver->GetPort()}}, }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); + auto listener = default_listener_; HttpConnectionManager http_connection_manager; + listener.mutable_api_listener()->mutable_api_listener()->UnpackTo( + &http_connection_manager); // Set up HTTP max_stream_duration to be explicit 0 auto* duration = http_connection_manager.mutable_common_http_protocol_options() ->mutable_max_stream_duration(); duration->set_seconds(0); duration->set_nanos(0); - auto listener = default_listener_; listener.mutable_api_listener()->mutable_api_listener()->PackFrom( http_connection_manager); // Set listener and route config. @@ -5043,7 +5261,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatching) { EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); EXPECT_EQ(kNumEcho1Rpcs, backends_[1]->backend_service1()->request_count()); EXPECT_EQ(0, backends_[1]->backend_service2()->request_count()); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -5090,7 +5308,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialHeaderContentType) { CheckRpcSendOk(kNumEchoRpcs); EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -5158,7 +5376,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingSpecialCasesToIgnore) { EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); EXPECT_EQ(0, backends_[1]->backend_service()->request_count()); EXPECT_EQ(0, backends_[2]->backend_service()->request_count()); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -5215,7 +5433,7 @@ TEST_P(LdsRdsTest, XdsRoutingRuntimeFractionMatching) { (1 - kErrorTolerance)), ::testing::Le(static_cast(kNumRpcs) * 25 / 100 * (1 + kErrorTolerance)))); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -5314,7 +5532,7 @@ TEST_P(LdsRdsTest, XdsRoutingHeadersMatchingUnmatchCases) { EXPECT_EQ(kNumEchoRpcs, backends_[0]->backend_service()->request_count()); EXPECT_EQ(kNumEcho1Rpcs, backends_[0]->backend_service1()->request_count()); EXPECT_EQ(0, backends_[0]->backend_service2()->request_count()); - const auto& response_state = RouteConfigurationResponseState(0); + const auto response_state = RouteConfigurationResponseState(0); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::ACKED); } @@ -5381,6 +5599,253 @@ TEST_P(LdsRdsTest, XdsRoutingChangeRoutesWithoutChangingClusters) { EXPECT_EQ(1, backends_[1]->backend_service2()->request_count()); } +// Test that we NACK unknown filter types in VirtualHost. +TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInVirtualHost) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = + route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom(Listener()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("no filter registered for config type " + "envoy.config.listener.v3.Listener")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we ignore optional unknown filter types in VirtualHost. +TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInVirtualHost) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = + route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); + ::envoy::config::route::v3::FilterConfig filter_config; + filter_config.mutable_config()->PackFrom(Listener()); + filter_config.set_is_optional(true); + (*per_filter_config)["unknown"].PackFrom(filter_config); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + WaitForAllBackends(); + EXPECT_EQ(RouteConfigurationResponseState(0).state, + AdsServiceImpl::ResponseState::ACKED); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unparseable filter types in VirtualHost. +TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInVirtualHost) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = + route_config.mutable_virtual_hosts(0)->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom( + envoy::extensions::filters::http::router::v3::Router()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT( + response_state.error_message, + ::testing::HasSubstr("router filter does not support config override")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unknown filter types in Route. +TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInRoute) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom(Listener()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("no filter registered for config type " + "envoy.config.listener.v3.Listener")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we ignore optional unknown filter types in Route. +TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInRoute) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_typed_per_filter_config(); + ::envoy::config::route::v3::FilterConfig filter_config; + filter_config.mutable_config()->PackFrom(Listener()); + filter_config.set_is_optional(true); + (*per_filter_config)["unknown"].PackFrom(filter_config); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + WaitForAllBackends(); + EXPECT_EQ(RouteConfigurationResponseState(0).state, + AdsServiceImpl::ResponseState::ACKED); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unparseable filter types in Route. +TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInRoute) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* per_filter_config = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom( + envoy::extensions::filters::http::router::v3::Router()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT( + response_state.error_message, + ::testing::HasSubstr("router filter does not support config override")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unknown filter types in ClusterWeight. +TEST_P(LdsRdsTest, RejectsUnknownHttpFilterTypeInClusterWeight) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* cluster_weight = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_route() + ->mutable_weighted_clusters() + ->add_clusters(); + cluster_weight->set_name(kDefaultClusterName); + cluster_weight->mutable_weight()->set_value(100); + auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom(Listener()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT(response_state.error_message, + ::testing::HasSubstr("no filter registered for config type " + "envoy.config.listener.v3.Listener")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we ignore optional unknown filter types in ClusterWeight. +TEST_P(LdsRdsTest, IgnoresOptionalUnknownHttpFilterTypeInClusterWeight) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* cluster_weight = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_route() + ->mutable_weighted_clusters() + ->add_clusters(); + cluster_weight->set_name(kDefaultClusterName); + cluster_weight->mutable_weight()->set_value(100); + auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); + ::envoy::config::route::v3::FilterConfig filter_config; + filter_config.mutable_config()->PackFrom(Listener()); + filter_config.set_is_optional(true); + (*per_filter_config)["unknown"].PackFrom(filter_config); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + AdsServiceImpl::EdsResourceArgs args({ + {"locality0", GetBackendPorts()}, + }); + balancers_[0]->ads_service()->SetEdsResource( + BuildEdsResource(args, DefaultEdsServiceName())); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + WaitForAllBackends(); + EXPECT_EQ(RouteConfigurationResponseState(0).state, + AdsServiceImpl::ResponseState::ACKED); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// Test that we NACK unparseable filter types in ClusterWeight. +TEST_P(LdsRdsTest, RejectsUnparseableHttpFilterTypeInClusterWeight) { + if (GetParam().use_v2()) return; // Filters supported in v3 only. + gpr_setenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION", "true"); + RouteConfiguration route_config = default_route_config_; + auto* cluster_weight = route_config.mutable_virtual_hosts(0) + ->mutable_routes(0) + ->mutable_route() + ->mutable_weighted_clusters() + ->add_clusters(); + cluster_weight->set_name(kDefaultClusterName); + cluster_weight->mutable_weight()->set_value(100); + auto* per_filter_config = cluster_weight->mutable_typed_per_filter_config(); + (*per_filter_config)["unknown"].PackFrom( + envoy::extensions::filters::http::router::v3::Router()); + SetListenerAndRouteConfiguration(0, default_listener_, route_config); + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Wait until xDS server sees NACK. + do { + CheckRpcSendFailure(); + } while (RouteConfigurationResponseState(0).state == + AdsServiceImpl::ResponseState::SENT); + const auto response_state = RouteConfigurationResponseState(0); + EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); + EXPECT_THAT( + response_state.error_message, + ::testing::HasSubstr("router filter does not support config override")); + gpr_unsetenv("GRPC_XDS_EXPERIMENTAL_FAULT_INJECTION"); +} + +// TODO(lidiz): As part of adding the fault injection filter, add tests +// for overriding filter configs in the typed_per_filter_config fields in +// each of VirtualHost, Route, and ClusterWeight. + using CdsTest = BasicTest; // Tests that CDS client should send an ACK upon correct CDS response. @@ -5590,7 +6055,7 @@ TEST_P(CdsTest, LogicalDNSClusterTypeDisabled) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5612,7 +6077,7 @@ TEST_P(CdsTest, AggregateClusterTypeDisabled) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5628,7 +6093,7 @@ TEST_P(CdsTest, UnsupportedClusterType) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5655,7 +6120,7 @@ TEST_P(CdsTest, MultipleBadResources) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5675,7 +6140,7 @@ TEST_P(CdsTest, WrongEdsConfig) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5691,7 +6156,7 @@ TEST_P(CdsTest, WrongLbPolicy) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5707,7 +6172,7 @@ TEST_P(CdsTest, WrongLrsServer) { SetNextResolution({}); SetNextResolutionForLbChannelAllBalancers(); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5875,7 +6340,7 @@ TEST_P(XdsSecurityTest, transport_socket->set_name("envoy.transport_sockets.tls"); balancers_[0]->ads_service()->SetCdsResource(cluster); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5898,7 +6363,7 @@ TEST_P( transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); balancers_[0]->ads_service()->SetCdsResource(cluster); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5920,7 +6385,7 @@ TEST_P( transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); balancers_[0]->ads_service()->SetCdsResource(cluster); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -5950,7 +6415,7 @@ TEST_P(XdsSecurityTest, RegexSanMatcherDoesNotAllowIgnoreCase) { transport_socket->mutable_typed_config()->PackFrom(upstream_tls_context); balancers_[0]->ads_service()->SetCdsResource(cluster); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->cds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -6379,7 +6844,7 @@ TEST_P(XdsEnabledServerTest, BadLdsUpdateNoApiListenerNorAddress) { listener.add_filter_chains(); balancers_[0]->ads_service()->SetLdsResource(listener); CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -6403,7 +6868,7 @@ TEST_P(XdsEnabledServerTest, BadLdsUpdateBothApiListenerAndAddress) { listener.mutable_api_listener(); balancers_[0]->ads_service()->SetLdsResource(listener); CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT( @@ -6663,7 +7128,7 @@ TEST_P(XdsServerSecurityTest, TlsConfigurationWithoutRootProviderInstance) { transport_socket->mutable_typed_config()->PackFrom(downstream_tls_context); balancers_[0]->ads_service()->SetLdsResource(listener); CheckRpcSendFailure(1, RpcOptions().set_wait_for_ready(true)); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->lds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, @@ -6926,7 +7391,7 @@ TEST_P(EdsTest, NacksSparsePriorityList) { }); balancers_[0]->ads_service()->SetEdsResource(BuildEdsResource(args)); CheckRpcSendFailure(); - const auto& response_state = + const auto response_state = balancers_[0]->ads_service()->eds_response_state(); EXPECT_EQ(response_state.state, AdsServiceImpl::ResponseState::NACKED); EXPECT_THAT(response_state.error_message, diff --git a/tools/codegen/core/gen_upb_api.sh b/tools/codegen/core/gen_upb_api.sh index f7d62490af8..40b4c4c6126 100755 --- a/tools/codegen/core/gen_upb_api.sh +++ b/tools/codegen/core/gen_upb_api.sh @@ -76,6 +76,7 @@ proto_files=( \ "envoy/config/route/v3/scoped_route.proto" \ "envoy/config/trace/v3/http_tracer.proto" \ "envoy/extensions/clusters/aggregate/v3/cluster.proto" \ + "envoy/extensions/filters/http/router/v3/router.proto" \ "envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.proto" \ "envoy/extensions/transport_sockets/tls/v3/cert.proto" \ "envoy/extensions/transport_sockets/tls/v3/common.proto" \ @@ -126,6 +127,7 @@ proto_files=( \ "udpa/annotations/sensitive.proto" \ "udpa/annotations/status.proto" \ "udpa/annotations/versioning.proto" \ + "udpa/type/v1/typed_struct.proto" \ "xds/core/v3/authority.proto" \ "xds/core/v3/collection_entry.proto" \ "xds/core/v3/context_params.proto" \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 83db1fdac7a..7f56903de8a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1292,6 +1292,8 @@ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h \ +src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \ +src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \ @@ -1386,6 +1388,8 @@ src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \ src/core/ext/upb-generated/udpa/annotations/versioning.upb.h \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h \ +src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c \ +src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h \ src/core/ext/upb-generated/validate/validate.upb.c \ src/core/ext/upb-generated/validate/validate.upb.h \ src/core/ext/upb-generated/xds/core/v3/authority.upb.c \ @@ -1464,6 +1468,8 @@ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h \ +src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c \ +src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \ @@ -1542,6 +1548,8 @@ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h \ +src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c \ +src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.h \ src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c \ @@ -1574,6 +1582,8 @@ src/core/ext/xds/xds_client.cc \ src/core/ext/xds/xds_client.h \ src/core/ext/xds/xds_client_stats.cc \ src/core/ext/xds/xds_client_stats.h \ +src/core/ext/xds/xds_http_filters.cc \ +src/core/ext/xds/xds_http_filters.h \ src/core/ext/xds/xds_server_config_fetcher.cc \ src/core/lib/avl/avl.cc \ src/core/lib/avl/avl.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 852a6472ada..479c14784a8 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1128,6 +1128,8 @@ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.c \ src/core/ext/upb-generated/envoy/config/trace/v3/http_tracer.upb.h \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.c \ src/core/ext/upb-generated/envoy/extensions/clusters/aggregate/v3/cluster.upb.h \ +src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.c \ +src/core/ext/upb-generated/envoy/extensions/filters/http/router/v3/router.upb.h \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c \ src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h \ src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/cert.upb.c \ @@ -1222,6 +1224,8 @@ src/core/ext/upb-generated/udpa/annotations/versioning.upb.c \ src/core/ext/upb-generated/udpa/annotations/versioning.upb.h \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.c \ src/core/ext/upb-generated/udpa/data/orca/v1/orca_load_report.upb.h \ +src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.c \ +src/core/ext/upb-generated/udpa/type/v1/typed_struct.upb.h \ src/core/ext/upb-generated/validate/validate.upb.c \ src/core/ext/upb-generated/validate/validate.upb.h \ src/core/ext/upb-generated/xds/core/v3/authority.upb.c \ @@ -1300,6 +1304,8 @@ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/config/trace/v3/http_tracer.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/clusters/aggregate/v3/cluster.upbdefs.h \ +src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.c \ +src/core/ext/upbdefs-generated/envoy/extensions/filters/http/router/v3/router.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.c \ src/core/ext/upbdefs-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upbdefs.h \ src/core/ext/upbdefs-generated/envoy/extensions/transport_sockets/tls/v3/cert.upbdefs.c \ @@ -1378,6 +1384,8 @@ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/status.upbdefs.h \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.c \ src/core/ext/upbdefs-generated/udpa/annotations/versioning.upbdefs.h \ +src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.c \ +src/core/ext/upbdefs-generated/udpa/type/v1/typed_struct.upbdefs.h \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.c \ src/core/ext/upbdefs-generated/validate/validate.upbdefs.h \ src/core/ext/upbdefs-generated/xds/core/v3/authority.upbdefs.c \ @@ -1410,6 +1418,8 @@ src/core/ext/xds/xds_client.cc \ src/core/ext/xds/xds_client.h \ src/core/ext/xds/xds_client_stats.cc \ src/core/ext/xds/xds_client_stats.h \ +src/core/ext/xds/xds_http_filters.cc \ +src/core/ext/xds/xds_http_filters.h \ src/core/ext/xds/xds_server_config_fetcher.cc \ src/core/lib/README.md \ src/core/lib/avl/avl.cc \