From 96e24d3ce84713cb5a6700f9b74cf3077f98362d Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Sat, 17 Jan 2026 00:29:04 +0000 Subject: [PATCH 1/5] Get the implementation compiling --- .../filters/http/peer_metadata/filter.cc | 26 ++++++++++++++++--- .../filters/http/peer_metadata/filter.h | 1 + 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/source/extensions/filters/http/peer_metadata/filter.cc b/source/extensions/filters/http/peer_metadata/filter.cc index f4b93cad446..d41e140f520 100644 --- a/source/extensions/filters/http/peer_metadata/filter.cc +++ b/source/extensions/filters/http/peer_metadata/filter.cc @@ -35,23 +35,35 @@ class XDSMethod : public DiscoveryMethod { public: XDSMethod(bool downstream, Server::Configuration::ServerFactoryContext& factory_context) : downstream_(downstream), - metadata_provider_(Extensions::Common::WorkloadDiscovery::GetProvider(factory_context)) {} + metadata_provider_(Extensions::Common::WorkloadDiscovery::GetProvider(factory_context)), + local_info_(factory_context.localInfo()) {} absl::optional derivePeerInfo(const StreamInfo::StreamInfo&, Http::HeaderMap&, Context&) const override; private: const bool downstream_; Extensions::Common::WorkloadDiscovery::WorkloadMetadataProviderSharedPtr metadata_provider_; + const LocalInfo::LocalInfo& local_info_; }; absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& info, - Http::HeaderMap&, Context&) const { + Http::HeaderMap& headers, Context&) const { if (!metadata_provider_) { return {}; } Network::Address::InstanceConstSharedPtr peer_address; if (downstream_) { - peer_address = info.downstreamAddressProvider().remoteAddress(); + const auto origin_network_header = headers.get(Headers::get().ExchangeMetadataOriginNetwork); + const auto& local_metadata = local_info_.node().metadata(); + const auto& it = local_metadata.fields().find("NETWORK"); + // We might not have a local network configured in the single cluster case, so default to empty. + auto local_network = it != local_metadata.fields().end() ? it->second.string_value() : ""; + if (!origin_network_header.empty() && origin_network_header[0]->value().getStringView() != local_network) { + ENVOY_LOG_MISC(info, "Origin network header present: {}; skipping downstream workload discovery", origin_network_header[0]->value().getStringView()); + peer_address = {}; + } else { + peer_address = info.downstreamAddressProvider().remoteAddress(); + } } else { if (info.upstreamInfo().has_value()) { auto upstream_host = info.upstreamInfo().value().get().upstreamHost(); @@ -64,6 +76,14 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& case Network::Address::Type::EnvoyInternal: if (upstream_host->metadata()) { const auto& filter_metadata = upstream_host->metadata()->filter_metadata(); + const auto& double_hbone_it = + filter_metadata.find("istio.double_hbone.hbone_target_address"); + // This is an E/W gateway endpoint, so we should explicitly not use workload discovery + if (double_hbone_it != filter_metadata.end()) { + ENVOY_LOG_MISC(info, "Skipping upstream workload discovery for an endpoint on a remote network"); + peer_address = nullptr; + break; + } const auto& it = filter_metadata.find("envoy.filters.listener.original_dst"); if (it != filter_metadata.end()) { const auto& destination_it = it->second.fields().find("local"); diff --git a/source/extensions/filters/http/peer_metadata/filter.h b/source/extensions/filters/http/peer_metadata/filter.h index 94da2a86c83..f57ac950868 100644 --- a/source/extensions/filters/http/peer_metadata/filter.h +++ b/source/extensions/filters/http/peer_metadata/filter.h @@ -32,6 +32,7 @@ using ::Envoy::Extensions::Filters::Common::Expr::CelStateType; struct HeaderValues { const Http::LowerCaseString ExchangeMetadataHeader{"x-envoy-peer-metadata"}; const Http::LowerCaseString ExchangeMetadataHeaderId{"x-envoy-peer-metadata-id"}; + const Http::LowerCaseString ExchangeMetadataOriginNetwork{"x-istio-origin-network"}; }; using Headers = ConstSingleton; From 03956dcf3d9b0f60e52876e0347d07f2b6796f1e Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Tue, 20 Jan 2026 20:10:31 +0000 Subject: [PATCH 2/5] Add tests for cross-network peer metadata Signed-off-by: Keith Mattix II --- .../filters/http/peer_metadata/filter.cc | 18 +++--- .../filters/http/peer_metadata/filter_test.cc | 62 +++++++++++++++++++ 2 files changed, 73 insertions(+), 7 deletions(-) diff --git a/source/extensions/filters/http/peer_metadata/filter.cc b/source/extensions/filters/http/peer_metadata/filter.cc index d41e140f520..e6736960337 100644 --- a/source/extensions/filters/http/peer_metadata/filter.cc +++ b/source/extensions/filters/http/peer_metadata/filter.cc @@ -76,13 +76,17 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& case Network::Address::Type::EnvoyInternal: if (upstream_host->metadata()) { const auto& filter_metadata = upstream_host->metadata()->filter_metadata(); - const auto& double_hbone_it = - filter_metadata.find("istio.double_hbone.hbone_target_address"); - // This is an E/W gateway endpoint, so we should explicitly not use workload discovery - if (double_hbone_it != filter_metadata.end()) { - ENVOY_LOG_MISC(info, "Skipping upstream workload discovery for an endpoint on a remote network"); - peer_address = nullptr; - break; + const auto& istio_it = filter_metadata.find("istio"); + if (istio_it != filter_metadata.end()) { + const auto& double_hbone_it = istio_it->second.fields().find("double_hbone"); + // This is an E/W gateway endpoint, so we should explicitly not use workload discovery + if (double_hbone_it != istio_it->second.fields().end()) { + ENVOY_LOG_MISC(info, "Skipping upstream workload discovery for an endpoint on a remote network"); + peer_address = nullptr; + break; + } + } else { + ENVOY_LOG_MISC(debug, "No istio metadata found on upstream host."); } const auto& it = filter_metadata.find("envoy.filters.listener.original_dst"); if (it != filter_metadata.end()) { diff --git a/source/extensions/filters/http/peer_metadata/filter_test.cc b/source/extensions/filters/http/peer_metadata/filter_test.cc index 995da18b224..5093787e53b 100644 --- a/source/extensions/filters/http/peer_metadata/filter_test.cc +++ b/source/extensions/filters/http/peer_metadata/filter_test.cc @@ -153,6 +153,29 @@ TEST_F(PeerMetadataTest, DownstreamXDS) { checkShared(false); } +TEST_F(PeerMetadataTest, DownstreamXDSCrossNetwork) { + request_headers_.setReference(Headers::get().ExchangeMetadataOriginNetwork, "remote-network"); + const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "default", "foo", "foo-service", + "v1alpha3", "", "", Istio::Common::WorkloadType::Pod, ""); + EXPECT_CALL(*metadata_provider_, GetMetadata(_)) + .WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address) + -> std::optional { + if (absl::StartsWith(address->asStringView(), "127.0.0.1")) { + return {pod}; + } + return {}; + })); + initialize(R"EOF( + downstream_discovery: + - workload_discovery: {} + )EOF"); + EXPECT_EQ(1, request_headers_.size()); // We don't remove the header because we terminate the tunnel that delivered it + EXPECT_EQ(0, response_headers_.size()); + checkNoPeer(true); // No downstream peer because it's a cross-network request + checkNoPeer(false); + checkShared(false); +} + TEST_F(PeerMetadataTest, UpstreamXDS) { const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service", "v1alpha3", "", "", Istio::Common::WorkloadType::Pod, ""); @@ -210,6 +233,45 @@ TEST_F(PeerMetadataTest, UpstreamXDSInternal) { checkPeerNamespace(false, "foo"); } +TEST_F(PeerMetadataTest, UpstreamXDSInternalCrossNetwork) { + Network::Address::InstanceConstSharedPtr upstream_address = + std::make_shared("internal_address", "endpoint_id"); + std::shared_ptr> upstream_host( + new NiceMock()); + EXPECT_CALL(*upstream_host, address()).WillRepeatedly(Return(upstream_address)); + stream_info_.upstreamInfo()->setUpstreamHost(upstream_host); + auto host_metadata = std::make_shared(); + ON_CALL(*upstream_host, metadata()).WillByDefault(testing::Return(host_metadata)); + TestUtility::loadFromYaml(R"EOF( + filter_metadata: + envoy.filters.listener.original_dst: + local: 127.0.0.100:80 + istio: + double_hbone: + hbone_target_address: 10.0.0.1 + )EOF", + *host_metadata); + + const WorkloadMetadataObject pod("pod-foo-1234", "my-cluster", "foo", "foo", "foo-service", + "v1alpha3", "", "", Istio::Common::WorkloadType::Pod, ""); + EXPECT_CALL(*metadata_provider_, GetMetadata(_)) + .WillRepeatedly(Invoke([&](const Network::Address::InstanceConstSharedPtr& address) + -> std::optional { + if (absl::StartsWith(address->asStringView(), "127.0.0.100")) { + return {pod}; + } + return {}; + })); + initialize(R"EOF( + upstream_discovery: + - workload_discovery: {} + )EOF"); + EXPECT_EQ(0, request_headers_.size()); + EXPECT_EQ(0, response_headers_.size()); + checkNoPeer(true); + checkNoPeer(false); // Shouldn't be any upstream filter state since it's a cross-network endpoint +} + TEST_F(PeerMetadataTest, DownstreamMXEmpty) { initialize(R"EOF( downstream_discovery: From 482f924db9d2d2019b37bd66d24314deb1ac24f1 Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Tue, 20 Jan 2026 20:15:15 +0000 Subject: [PATCH 3/5] clang-tidy Signed-off-by: Keith Mattix II --- source/extensions/filters/http/peer_metadata/filter_test.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/extensions/filters/http/peer_metadata/filter_test.cc b/source/extensions/filters/http/peer_metadata/filter_test.cc index 5093787e53b..7cacc1f2eea 100644 --- a/source/extensions/filters/http/peer_metadata/filter_test.cc +++ b/source/extensions/filters/http/peer_metadata/filter_test.cc @@ -169,7 +169,8 @@ TEST_F(PeerMetadataTest, DownstreamXDSCrossNetwork) { downstream_discovery: - workload_discovery: {} )EOF"); - EXPECT_EQ(1, request_headers_.size()); // We don't remove the header because we terminate the tunnel that delivered it + EXPECT_EQ(1, request_headers_.size()); // We don't remove the header because we terminate the + // tunnel that delivered it EXPECT_EQ(0, response_headers_.size()); checkNoPeer(true); // No downstream peer because it's a cross-network request checkNoPeer(false); From eec58abb8741aad8bd63a30b516fb719d6e17f92 Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Tue, 20 Jan 2026 20:18:31 +0000 Subject: [PATCH 4/5] One more tidy Signed-off-by: Keith Mattix II --- .../extensions/filters/http/peer_metadata/filter.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/extensions/filters/http/peer_metadata/filter.cc b/source/extensions/filters/http/peer_metadata/filter.cc index e6736960337..f72f889867d 100644 --- a/source/extensions/filters/http/peer_metadata/filter.cc +++ b/source/extensions/filters/http/peer_metadata/filter.cc @@ -58,8 +58,11 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& const auto& it = local_metadata.fields().find("NETWORK"); // We might not have a local network configured in the single cluster case, so default to empty. auto local_network = it != local_metadata.fields().end() ? it->second.string_value() : ""; - if (!origin_network_header.empty() && origin_network_header[0]->value().getStringView() != local_network) { - ENVOY_LOG_MISC(info, "Origin network header present: {}; skipping downstream workload discovery", origin_network_header[0]->value().getStringView()); + if (!origin_network_header.empty() && + origin_network_header[0]->value().getStringView() != local_network) { + ENVOY_LOG_MISC(info, + "Origin network header present: {}; skipping downstream workload discovery", + origin_network_header[0]->value().getStringView()); peer_address = {}; } else { peer_address = info.downstreamAddressProvider().remoteAddress(); @@ -81,7 +84,9 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& const auto& double_hbone_it = istio_it->second.fields().find("double_hbone"); // This is an E/W gateway endpoint, so we should explicitly not use workload discovery if (double_hbone_it != istio_it->second.fields().end()) { - ENVOY_LOG_MISC(info, "Skipping upstream workload discovery for an endpoint on a remote network"); + ENVOY_LOG_MISC( + info, + "Skipping upstream workload discovery for an endpoint on a remote network"); peer_address = nullptr; break; } From eb19beb2bce8765fdf0e65354c9ca4d35027ad57 Mon Sep 17 00:00:00 2001 From: Keith Mattix II Date: Fri, 23 Jan 2026 01:10:21 +0000 Subject: [PATCH 5/5] Switch to debug for logging Signed-off-by: Keith Mattix II --- source/extensions/filters/http/peer_metadata/filter.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/extensions/filters/http/peer_metadata/filter.cc b/source/extensions/filters/http/peer_metadata/filter.cc index f72f889867d..8b01e8685e8 100644 --- a/source/extensions/filters/http/peer_metadata/filter.cc +++ b/source/extensions/filters/http/peer_metadata/filter.cc @@ -60,7 +60,7 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& auto local_network = it != local_metadata.fields().end() ? it->second.string_value() : ""; if (!origin_network_header.empty() && origin_network_header[0]->value().getStringView() != local_network) { - ENVOY_LOG_MISC(info, + ENVOY_LOG_MISC(debug, "Origin network header present: {}; skipping downstream workload discovery", origin_network_header[0]->value().getStringView()); peer_address = {}; @@ -85,7 +85,7 @@ absl::optional XDSMethod::derivePeerInfo(const StreamInfo::StreamInfo& // This is an E/W gateway endpoint, so we should explicitly not use workload discovery if (double_hbone_it != istio_it->second.fields().end()) { ENVOY_LOG_MISC( - info, + debug, "Skipping upstream workload discovery for an endpoint on a remote network"); peer_address = nullptr; break;