Skip to content

Commit 68d58a1

Browse files
authored
network ext_proc: add forwarding filter metadata support to the side service (envoyproxy#39255)
Risk Level: low Testing: unit and integration tests --------- Signed-off-by: Boteng Yao <[email protected]>
1 parent 5b8331d commit 68d58a1

File tree

5 files changed

+713
-2
lines changed

5 files changed

+713
-2
lines changed

api/envoy/extensions/filters/network/ext_proc/v3/ext_proc.proto

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ option (xds.annotations.v3.file_status).work_in_progress = true;
3434
//
3535
// By using the filter's processing mode, you can selectively choose which data
3636
// directions to process (read, write or both), allowing for efficient processing.
37-
// [#next-free-field: 6]
37+
// [#next-free-field: 7]
3838
message NetworkExternalProcessor {
3939
// The gRPC service that will process network traffic.
4040
// This service must implement the NetworkExternalProcessor service
@@ -64,6 +64,9 @@ message NetworkExternalProcessor {
6464
}];
6565

6666
string stat_prefix = 5 [(validate.rules).string = {min_len: 1}];
67+
68+
// Options related to the sending and receiving of dynamic metadata.
69+
MetadataOptions metadata_options = 6;
6770
}
6871

6972
// Options for controlling processing behavior.
@@ -86,3 +89,23 @@ message ProcessingMode {
8689
// Default: STREAMED
8790
DataSendMode process_write = 2;
8891
}
92+
93+
// The MetadataOptions structure defines options for sending dynamic metadata. Specifically,
94+
// which namespaces to send to the server.
95+
message MetadataOptions {
96+
message MetadataNamespaces {
97+
// Specifies a list of metadata namespaces whose values, if present,
98+
// will be passed to the ext_proc service as an opaque *protobuf::Struct*.
99+
repeated string untyped = 1;
100+
101+
// Specifies a list of metadata namespaces whose values, if present,
102+
// will be passed to the ext_proc service as a *protobuf::Any*. This allows
103+
// envoy and the external processing server to share the protobuf message
104+
// definition for safe parsing.
105+
repeated string typed = 2;
106+
}
107+
108+
// Describes which typed or untyped dynamic metadata namespaces to forward to
109+
// the external processing server.
110+
MetadataNamespaces forwarding_namespaces = 1;
111+
}

source/extensions/filters/network/ext_proc/ext_proc.cc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ void NetworkExtProcFilter::sendRequest(Buffer::Instance& data, bool end_stream,
164164

165165
// Prepare the request message
166166
ProcessingRequest request;
167+
addDynamicMetadata(request);
167168

168169
if (is_read) {
169170
auto* read_data = request.mutable_read_data();
@@ -270,6 +271,39 @@ void NetworkExtProcFilter::closeConnection(const std::string& reason) {
270271
stats_.connections_closed_.inc();
271272
}
272273

274+
void NetworkExtProcFilter::addDynamicMetadata(ProcessingRequest& req) {
275+
if (config_->untypedForwardingMetadataNamespaces().empty() &&
276+
config_->typedForwardingMetadataNamespaces().empty()) {
277+
return;
278+
}
279+
280+
envoy::config::core::v3::Metadata forwarding_metadata;
281+
282+
const auto& dynamic_metadata = read_callbacks_->connection().streamInfo().dynamicMetadata();
283+
const auto& connection_metadata = dynamic_metadata.filter_metadata();
284+
const auto& connection_typed_metadata = dynamic_metadata.typed_filter_metadata();
285+
286+
for (const auto& context_key : config_->untypedForwardingMetadataNamespaces()) {
287+
if (const auto metadata_it = connection_metadata.find(context_key);
288+
metadata_it != connection_metadata.end()) {
289+
(*forwarding_metadata.mutable_filter_metadata())[metadata_it->first] = metadata_it->second;
290+
}
291+
}
292+
293+
for (const auto& context_key : config_->typedForwardingMetadataNamespaces()) {
294+
if (const auto metadata_it = connection_typed_metadata.find(context_key);
295+
metadata_it != connection_typed_metadata.end()) {
296+
(*forwarding_metadata.mutable_typed_filter_metadata())[metadata_it->first] =
297+
metadata_it->second;
298+
}
299+
}
300+
301+
if (!forwarding_metadata.filter_metadata().empty() ||
302+
!forwarding_metadata.typed_filter_metadata().empty()) {
303+
*req.mutable_metadata() = std::move(forwarding_metadata);
304+
}
305+
}
306+
273307
} // namespace ExtProc
274308
} // namespace NetworkFilters
275309
} // namespace Extensions

source/extensions/filters/network/ext_proc/ext_proc.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ class Config {
4949
Stats::Scope& scope)
5050
: failure_mode_allow_(config.failure_mode_allow()),
5151
processing_mode_(config.processing_mode()), grpc_service_(config.grpc_service()),
52+
untyped_forwarding_namespaces_(
53+
config.metadata_options().forwarding_namespaces().untyped().begin(),
54+
config.metadata_options().forwarding_namespaces().untyped().end()),
55+
typed_forwarding_namespaces_(
56+
config.metadata_options().forwarding_namespaces().typed().begin(),
57+
config.metadata_options().forwarding_namespaces().typed().end()),
5258
stats_(generateStats(config.stat_prefix(), scope)) {};
5359

5460
bool failureModeAllow() const { return failure_mode_allow_; }
@@ -59,6 +65,14 @@ class Config {
5965

6066
const envoy::config::core::v3::GrpcService& grpcService() const { return grpc_service_; }
6167

68+
const std::vector<std::string>& untypedForwardingMetadataNamespaces() const {
69+
return untyped_forwarding_namespaces_;
70+
}
71+
72+
const std::vector<std::string>& typedForwardingMetadataNamespaces() const {
73+
return typed_forwarding_namespaces_;
74+
}
75+
6276
const NetworkExtProcStats& stats() const { return stats_; }
6377

6478
private:
@@ -70,6 +84,8 @@ class Config {
7084
const bool failure_mode_allow_;
7185
const envoy::extensions::filters::network::ext_proc::v3::ProcessingMode processing_mode_;
7286
const envoy::config::core::v3::GrpcService grpc_service_;
87+
const std::vector<std::string> untyped_forwarding_namespaces_;
88+
const std::vector<std::string> typed_forwarding_namespaces_;
7389
NetworkExtProcStats stats_;
7490
};
7591

@@ -137,6 +153,7 @@ class NetworkExtProcFilter : public Envoy::Network::Filter,
137153
void closeStream();
138154

139155
void sendRequest(Envoy::Buffer::Instance& data, bool end_stream, bool is_read);
156+
void addDynamicMetadata(ProcessingRequest& req);
140157

141158
Envoy::Network::FilterStatus handleStreamError();
142159
void closeConnection(const std::string& reason);

0 commit comments

Comments
 (0)