Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ecds: hook UDP session filters with config provider #35713

Merged
merged 4 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions source/common/filter/config_discovery_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,41 @@ class UdpListenerDynamicFilterConfigProviderImpl
}
};

class UdpSessionDynamicFilterConfigProviderImpl
: public DynamicFilterConfigProviderImpl<Network::UdpSessionFilterFactoryCb> {
public:
UdpSessionDynamicFilterConfigProviderImpl(
FilterConfigSubscriptionSharedPtr& subscription,
const absl::flat_hash_set<std::string>& require_type_urls,
Server::Configuration::ServerFactoryContext&,
Server::Configuration::FactoryContext& factory_context,
ProtobufTypes::MessagePtr&& default_config, bool last_filter_in_filter_chain,
const std::string& filter_chain_type, absl::string_view stat_prefix,
const Network::ListenerFilterMatcherSharedPtr& listener_filter_matcher)
: DynamicFilterConfigProviderImpl<Network::UdpSessionFilterFactoryCb>(
subscription, require_type_urls, factory_context.serverFactoryContext().threadLocal(),
std::move(default_config), last_filter_in_filter_chain, filter_chain_type, stat_prefix,
listener_filter_matcher),
factory_context_(factory_context) {}

void validateMessage(const std::string&, const Protobuf::Message&,
const std::string&) const override {
// UDP session filters don't use the concept of terminal filters.
}

protected:
Server::Configuration::FactoryContext& factory_context_;

private:
absl::StatusOr<Network::UdpSessionFilterFactoryCb>
instantiateFilterFactory(const Protobuf::Message& message) const override {
auto* factory =
Registry::FactoryRegistry<Server::Configuration::NamedUdpSessionFilterConfigFactory>::
getFactoryByType(message.GetTypeName());
return factory->createFilterFactoryFromProto(message, factory_context_);
}
};

class QuicListenerDynamicFilterConfigProviderImpl
: public ListenerDynamicFilterConfigProviderImpl<Network::QuicListenerFilterFactoryCb> {
public:
Expand Down Expand Up @@ -774,6 +809,19 @@ class UdpListenerFilterConfigProviderManagerImpl
const std::string getConfigDumpType() const override { return "ecds_filter_udp_listener"; }
};

// UDP session filter
class UdpSessionFilterConfigProviderManagerImpl
: public FilterConfigProviderManagerImpl<
Server::Configuration::NamedUdpSessionFilterConfigFactory,
Network::UdpSessionFilterFactoryCb, Server::Configuration::FactoryContext,
UdpSessionDynamicFilterConfigProviderImpl> {
public:
absl::string_view statPrefix() const override { return "udp_session_filter."; }

protected:
const std::string getConfigDumpType() const override { return "ecds_filter_udp_session"; }
};

// QUIC listener filter
class QuicListenerFilterConfigProviderManagerImpl
: public FilterConfigProviderManagerImpl<
Expand Down
18 changes: 17 additions & 1 deletion source/extensions/filters/udp/udp_proxy/config.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "source/extensions/filters/udp/udp_proxy/config.h"

#include "source/common/filter/config_discovery_impl.h"
#include "source/common/formatter/substitution_format_string.h"

namespace Envoy {
Expand Down Expand Up @@ -88,6 +89,8 @@ UdpProxyFilterConfigImpl::UdpProxyFilterConfigImpl(
stats_(generateStats(config.stat_prefix(), context.scope())),
// Default prefer_gro to true for upstream client traffic.
upstream_socket_config_(config.upstream_socket_config(), true),
udp_session_filter_config_provider_manager_(
createSingletonUdpSessionFilterConfigProviderManager(context.serverFactoryContext())),
random_generator_(context.serverFactoryContext().api().randomGenerator()) {
if (use_per_packet_load_balancing_ && config.has_tunneling_config()) {
throw EnvoyException(
Expand Down Expand Up @@ -149,12 +152,25 @@ UdpProxyFilterConfigImpl::UdpProxyFilterConfigImpl(
Server::Configuration::NamedUdpSessionFilterConfigFactory>(filter);
ProtobufTypes::MessagePtr message = Envoy::Config::Utility::translateToFactoryConfig(
filter, context.messageValidationVisitor(), factory);

Network::UdpSessionFilterFactoryCb callback =
factory.createFilterFactoryFromProto(*message, context);
filter_factories_.push_back(callback);
filter_factories_.push_back(
udp_session_filter_config_provider_manager_->createStaticFilterConfigProvider(
callback, filter.name()));
}
}

SINGLETON_MANAGER_REGISTRATION(udp_session_filter_config_provider_manager);

std::shared_ptr<UdpSessionFilterConfigProviderManager>
UdpProxyFilterConfigImpl::createSingletonUdpSessionFilterConfigProviderManager(
Server::Configuration::ServerFactoryContext& context) {
return context.singletonManager().getTyped<UdpSessionFilterConfigProviderManager>(
SINGLETON_MANAGER_REGISTERED_NAME(udp_session_filter_config_provider_manager),
[] { return std::make_shared<Filter::UdpSessionFilterConfigProviderManagerImpl>(); });
}

static Registry::RegisterFactory<UdpProxyFilterConfigFactory,
Server::Configuration::NamedUdpListenerFilterConfigFactory>
register_;
Expand Down
23 changes: 20 additions & 3 deletions source/extensions/filters/udp/udp_proxy/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.pb.h"
#include "envoy/extensions/filters/udp/udp_proxy/v3/udp_proxy.pb.validate.h"
#include "envoy/filter/config_provider_manager.h"
#include "envoy/server/filter_config.h"

#include "source/extensions/filters/udp/udp_proxy/udp_proxy_filter.h"
Expand Down Expand Up @@ -106,6 +107,12 @@ class TunnelingConfigImpl : public UdpTunnelingConfig {
bool propagate_response_trailers_;
};

using UdpSessionFilterConfigProviderManager =
Filter::FilterConfigProviderManager<Network::UdpSessionFilterFactoryCb,
Server::Configuration::FactoryContext>;
using UdpSessionFilterFactoriesList =
std::vector<Filter::FilterConfigProviderPtr<Network::UdpSessionFilterFactoryCb>>;

class UdpProxyFilterConfigImpl : public UdpProxyFilterConfig,
public UdpSessionFilterChainFactory,
Logger::Loggable<Logger::Id::config> {
Expand Down Expand Up @@ -151,8 +158,12 @@ class UdpProxyFilterConfigImpl : public UdpProxyFilterConfig,

// UdpSessionFilterChainFactory
void createFilterChain(Network::UdpSessionFilterChainFactoryCallbacks& callbacks) const override {
for (const Network::UdpSessionFilterFactoryCb& factory : filter_factories_) {
factory(callbacks);
for (const auto& filter_config_provider : filter_factories_) {
auto config = filter_config_provider->config();
if (config.has_value()) {
ohadvano marked this conversation as resolved.
Show resolved Hide resolved
Network::UdpSessionFilterFactoryCb& factory = config.value();
factory(callbacks);
}
}
};

Expand All @@ -164,6 +175,10 @@ class UdpProxyFilterConfigImpl : public UdpProxyFilterConfig,
POOL_GAUGE_PREFIX(scope, final_prefix))};
}

std::shared_ptr<UdpSessionFilterConfigProviderManager>
createSingletonUdpSessionFilterConfigProviderManager(
Server::Configuration::ServerFactoryContext& context);

Upstream::ClusterManager& cluster_manager_;
TimeSource& time_source_;
Router::RouterConstSharedPtr router_;
Expand All @@ -178,7 +193,9 @@ class UdpProxyFilterConfigImpl : public UdpProxyFilterConfig,
std::vector<AccessLog::InstanceSharedPtr> session_access_logs_;
std::vector<AccessLog::InstanceSharedPtr> proxy_access_logs_;
UdpTunnelingConfigPtr tunneling_config_;
std::list<Network::UdpSessionFilterFactoryCb> filter_factories_;
std::shared_ptr<UdpSessionFilterConfigProviderManager>
udp_session_filter_config_provider_manager_;
UdpSessionFilterFactoriesList filter_factories_;
Random::RandomGenerator& random_generator_;
};

Expand Down
41 changes: 38 additions & 3 deletions test/common/filter/config_discovery_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,22 @@ class TestUdpListenerFilterFactory
std::string name() const override { return "envoy.test.filter"; }
};

class TestUdpSessionFilterFactory
: public TestFilterFactory,
public Server::Configuration::NamedUdpSessionFilterConfigFactory {
public:
Network::UdpSessionFilterFactoryCb
createFilterFactoryFromProto(const Protobuf::Message&,
Server::Configuration::FactoryContext&) override {
created_ = true;
return [](Network::UdpSessionFilterChainFactoryCallbacks&) -> void {};
}
ProtobufTypes::MessagePtr createEmptyConfigProto() override {
return std::make_unique<ProtobufWkt::StringValue>();
}
std::string name() const override { return "envoy.test.filter"; }
};

class TestQuicListenerFilterFactory
: public TestFilterFactory,
public Server::Configuration::NamedQuicListenerFilterConfigFactory {
Expand Down Expand Up @@ -374,6 +390,23 @@ class UdpListenerFilterConfigDiscoveryImplTest
}
};

// UDP session filter test
class UdpSessionFilterConfigDiscoveryImplTest
: public FilterConfigDiscoveryImplTest<
Network::UdpSessionFilterFactoryCb, Server::Configuration::FactoryContext,
UdpSessionFilterConfigProviderManagerImpl, TestUdpSessionFilterFactory,
Server::Configuration::NamedUdpSessionFilterConfigFactory,
Server::Configuration::MockFactoryContext> {
public:
const std::string getFilterType() const override { return "udp_session"; }
const std::string getConfigReloadCounter() const override {
return "extension_config_discovery.udp_session_filter.foo.config_reload";
}
const std::string getConfigFailCounter() const override {
return "extension_config_discovery.udp_session_filter.foo.config_fail";
}
};

// QUIC listener filter test
class QuicListenerFilterConfigDiscoveryImplTest
: public FilterConfigDiscoveryImplTest<
Expand All @@ -393,7 +426,8 @@ class QuicListenerFilterConfigDiscoveryImplTest

/***************************************************************************************
* Parameterized test for *
* HTTP filter, Network filter, TCP listener filter And UDP listener filter *
* HTTP filter, Network filter, TCP listener filter, UDP session filter and *
* UDP listener filter *
* *
***************************************************************************************/
template <typename FilterConfigDiscoveryTestType>
Expand All @@ -404,7 +438,7 @@ using FilterConfigDiscoveryTestTypes = ::testing::Types<
HttpFilterConfigDiscoveryImplTest, HttpUpstreamFilterConfigDiscoveryImplTest,
NetworkFilterConfigDiscoveryImplTest, NetworkUpstreamFilterConfigDiscoveryImplTest,
TcpListenerFilterConfigDiscoveryImplTest, UdpListenerFilterConfigDiscoveryImplTest,
QuicListenerFilterConfigDiscoveryImplTest>;
UdpSessionFilterConfigDiscoveryImplTest, QuicListenerFilterConfigDiscoveryImplTest>;

TYPED_TEST_SUITE(FilterConfigDiscoveryImplTestParameter, FilterConfigDiscoveryTestTypes);

Expand Down Expand Up @@ -646,7 +680,8 @@ TYPED_TEST(FilterConfigDiscoveryImplTestParameter, TerminalFilterInvalid) {
EXPECT_CALL(config_discovery_test.init_watcher_, ready());

if (config_discovery_test.getFilterType() == "listener" ||
config_discovery_test.getFilterType() == "upstream_network") {
config_discovery_test.getFilterType() == "upstream_network" ||
config_discovery_test.getFilterType() == "udp_session") {
ASSERT_TRUE(config_discovery_test.callbacks_
->onConfigUpdate(decoded_resources.refvec_, response.version_info())
.ok());
Expand Down
Loading