Skip to content

Commit

Permalink
Merge 726a571 into 7990f73
Browse files Browse the repository at this point in the history
  • Loading branch information
antoniovleonti authored Dec 18, 2024
2 parents 7990f73 + 726a571 commit c86c974
Show file tree
Hide file tree
Showing 15 changed files with 317 additions and 21 deletions.
17 changes: 17 additions & 0 deletions api/envoy/type/matcher/v3/address.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto3";

package envoy.type.matcher.v3;

import "xds/core/v3/cidr.proto";

import "udpa/annotations/status.proto";

option java_package = "io.envoyproxy.envoy.type.matcher.v3";
option java_outer_classname = "AddressProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3;matcherv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

message AddressMatcher {
repeated xds.core.v3.CidrRange ranges = 1;
}
4 changes: 4 additions & 0 deletions api/envoy/type/matcher/v3/filter_state.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ syntax = "proto3";

package envoy.type.matcher.v3;

import "envoy/type/matcher/v3/address.proto";
import "envoy/type/matcher/v3/string.proto";

import "udpa/annotations/status.proto";
Expand All @@ -25,5 +26,8 @@ message FilterStateMatcher {

// Matches the filter state object as a string value.
StringMatcher string_match = 2;

// Matches the filter state object as a ip Instance.
AddressMatcher address_match = 3;
}
}
5 changes: 5 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,11 @@ new_features:
- area: grpc-json
change: |
Added a new http filter for :ref:`gRPC to JSON transcoding <config_http_filters_grpc_json_reverse_transcoder>`.
- area: matchers
change: |
Added new filter state matcher ip_range to
:ref:`FilterStateMatcher <envoy_api_msg_type.matcher.v3.FilterStateMatcher>` which attempts to
cast the filter state object to an IP and match it against a list of CidrRanges.
- area: attributes
change: |
added new ``xds.virtual_host_name`` and ``xds.virtual_host_metadata`` attributes support. See
Expand Down
1 change: 1 addition & 0 deletions envoy/network/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ envoy_cc_library(
deps = [
"//envoy/common:base_includes",
"//envoy/common:pure_lib",
"//envoy/stream_info:filter_state_interface",
],
)

Expand Down
14 changes: 14 additions & 0 deletions envoy/network/address.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "envoy/common/platform.h"
#include "envoy/common/pure.h"
#include "envoy/stream_info/filter_state.h"

#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"
Expand Down Expand Up @@ -238,6 +239,19 @@ class Instance {
virtual const Network::SocketInterface& socketInterface() const PURE;
};

/*
* Used to store Instance in filter state.
*/
class InstanceConstSharedPtrAccessor : public Envoy::StreamInfo::FilterState::Object {
public:
InstanceConstSharedPtrAccessor(InstanceConstSharedPtr ip) : ip_(std::move(ip)) {}

InstanceConstSharedPtr getIp() const { return ip_; }

private:
InstanceConstSharedPtr ip_;
};

} // namespace Address
} // namespace Network
} // namespace Envoy
14 changes: 14 additions & 0 deletions source/common/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ envoy_cc_library(
deps = [
":utility_lib",
"//envoy/common:matchers_interface",
"//source/common/common:filter_state_object_matchers_lib",
"//source/common/common:regex_lib",
"//source/common/config:metadata_lib",
"//source/common/config:utility_lib",
Expand All @@ -333,6 +334,19 @@ envoy_cc_library(
],
)

envoy_cc_library(
name = "filter_state_object_matchers_lib",
srcs = ["filter_state_object_matchers.cc"],
hdrs = ["filter_state_object_matchers.h"],
deps = [
"//envoy/common:exception_lib",
"//envoy/common:matchers_interface",
"//envoy/common:pure_lib",
"//source/common/network:cidr_range_interface",
"@com_google_absl//absl/status:statusor",
],
)

envoy_cc_library(
name = "random_generator_lib",
srcs = [
Expand Down
37 changes: 37 additions & 0 deletions source/common/common/filter_state_object_matchers.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "source/common/common/filter_state_object_matchers.h"

#include "envoy/common/exception.h"
#include "envoy/network/address.h"
#include "envoy/stream_info/filter_state.h"

#include "source/common/network/cidr_range.h"

#include "absl/status/statusor.h"
#include "xds/core/v3/cidr.pb.h"

namespace Envoy {
namespace Matchers {

FilterStateIpRangeMatcher::FilterStateIpRangeMatcher(
std::unique_ptr<Network::Address::IpList>&& ip_list)
: ip_list_(std::move(ip_list)) {}

bool FilterStateIpRangeMatcher::match(const StreamInfo::FilterState::Object& object) const {
const Network::Address::InstanceConstSharedPtrAccessor* ip =
dynamic_cast<const Network::Address::InstanceConstSharedPtrAccessor*>(&object);
if (ip == nullptr) {
return false;
}
return ip_list_->contains(*ip->getIp());
}

FilterStateStringMatcher::FilterStateStringMatcher(StringMatcherPtr&& string_matcher)
: string_matcher_(std::move(string_matcher)) {}

bool FilterStateStringMatcher::match(const StreamInfo::FilterState::Object& object) const {
const auto string_value = object.serializeAsString();
return string_value && string_matcher_->match(*string_value);
}

} // namespace Matchers
} // namespace Envoy
41 changes: 41 additions & 0 deletions source/common/common/filter_state_object_matchers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#pragma once

#include <memory>

#include "envoy/common/matchers.h"
#include "envoy/common/pure.h"
#include "envoy/stream_info/filter_state.h"

#include "source/common/network/cidr_range.h"

namespace Envoy {
namespace Matchers {

class FilterStateObjectMatcher {
public:
virtual bool match(const StreamInfo::FilterState::Object& object) const PURE;
virtual ~FilterStateObjectMatcher(){};
};

using FilterStateObjectMatcherPtr = std::unique_ptr<FilterStateObjectMatcher>;

class FilterStateIpRangeMatcher : public FilterStateObjectMatcher {
public:
FilterStateIpRangeMatcher(std::unique_ptr<Network::Address::IpList>&& ip_list);
bool match(const StreamInfo::FilterState::Object& object) const override;

private:
std::unique_ptr<Envoy::Network::Address::IpList> ip_list_;
};

class FilterStateStringMatcher : public FilterStateObjectMatcher {
public:
FilterStateStringMatcher(StringMatcherPtr&& string_matcher);
bool match(const StreamInfo::FilterState::Object& object) const override;

private:
const StringMatcherPtr string_matcher_;
};

} // namespace Matchers
} // namespace Envoy
42 changes: 33 additions & 9 deletions source/common/common/matchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
#include "envoy/type/matcher/v3/string.pb.h"
#include "envoy/type/matcher/v3/value.pb.h"

#include "source/common/common/filter_state_object_matchers.h"
#include "source/common/common/macros.h"
#include "source/common/common/regex.h"
#include "source/common/config/metadata.h"
#include "source/common/config/utility.h"
#include "source/common/http/path_utility.h"

#include "absl/status/statusor.h"
#include "absl/strings/match.h"
#include "filter_state_object_matchers.h"

namespace Envoy {
namespace Matchers {
Expand Down Expand Up @@ -122,31 +125,52 @@ MetadataMatcher::MetadataMatcher(const envoy::type::matcher::v3::MetadataMatcher
}

namespace {
StringMatcherPtr valueMatcherFromProto(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context) {

absl::StatusOr<FilterStateObjectMatcherPtr>
filterStateObjectMatcherFromProto(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context) {
switch (matcher.matcher_case()) {
case envoy::type::matcher::v3::FilterStateMatcher::MatcherCase::kStringMatch:
return std::make_unique<const StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>(
matcher.string_match(), context);
return std::make_unique<FilterStateStringMatcher>(
std::make_unique<const StringMatcherImpl<envoy::type::matcher::v3::StringMatcher>>(
matcher.string_match(), context));
break;
case envoy::type::matcher::v3::FilterStateMatcher::MatcherCase::kAddressMatch: {
auto ip_list = Network::Address::IpList::create(matcher.address_match().ranges());
if (!ip_list.ok()) {
return ip_list.status();
}
return std::make_unique<FilterStateIpRangeMatcher>(std::move(*ip_list));
break;
}
default:
PANIC_DUE_TO_PROTO_UNSET;
}
}

} // namespace

FilterStateMatcher::FilterStateMatcher(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context)
: key_(matcher.key()), value_matcher_(valueMatcherFromProto(matcher, context)) {}
absl::StatusOr<FilterStateMatcherPtr>
FilterStateMatcher::create(const envoy::type::matcher::v3::FilterStateMatcher& config,
Server::Configuration::CommonFactoryContext& context) {
absl::StatusOr<FilterStateObjectMatcherPtr> matcher =
filterStateObjectMatcherFromProto(config, context);
if (!matcher.ok()) {
return matcher.status();
}
return std::make_unique<FilterStateMatcher>(config.key(), std::move(*matcher));
}

FilterStateMatcher::FilterStateMatcher(std::string key,
FilterStateObjectMatcherPtr&& object_matcher)
: key_(key), object_matcher_(std::move(object_matcher)) {}

bool FilterStateMatcher::match(const StreamInfo::FilterState& filter_state) const {
const auto* object = filter_state.getDataReadOnlyGeneric(key_);
if (object == nullptr) {
return false;
}
const auto string_value = object->serializeAsString();
return string_value && value_matcher_->match(*string_value);
return object_matcher_->match(*object);
}

PathMatcherConstSharedPtr
Expand Down
12 changes: 9 additions & 3 deletions source/common/common/matchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "envoy/type/matcher/v3/string.pb.h"
#include "envoy/type/matcher/v3/value.pb.h"

#include "source/common/common/filter_state_object_matchers.h"
#include "source/common/common/regex.h"
#include "source/common/common/utility.h"
#include "source/common/protobuf/protobuf.h"
Expand Down Expand Up @@ -239,8 +240,7 @@ class MetadataMatcher {

class FilterStateMatcher {
public:
FilterStateMatcher(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context);
FilterStateMatcher(std::string key, FilterStateObjectMatcherPtr&& object_matcher);

/**
* Check whether the filter state object is matched to the matcher.
Expand All @@ -249,11 +249,17 @@ class FilterStateMatcher {
*/
bool match(const StreamInfo::FilterState& filter_state) const;

static absl::StatusOr<std::unique_ptr<FilterStateMatcher>>
create(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context);

private:
const std::string key_;
const StringMatcherPtr value_matcher_;
const FilterStateObjectMatcherPtr object_matcher_;
};

using FilterStateMatcherPtr = std::unique_ptr<FilterStateMatcher>;

class PathMatcher : public StringMatcher {
public:
PathMatcher(const envoy::type::matcher::v3::PathMatcher& path,
Expand Down
22 changes: 22 additions & 0 deletions source/common/network/cidr_range.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,15 @@ IpList::create(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRan
return ret;
}

absl::StatusOr<std::unique_ptr<IpList>>
IpList::create(const Protobuf::RepeatedPtrField<xds::core::v3::CidrRange>& cidrs) {
std::unique_ptr<IpList> ret = std::unique_ptr<IpList>(new IpList(cidrs));
if (!ret->error_.empty()) {
return absl::InvalidArgumentError(ret->error_);
}
return ret;
}

IpList::IpList(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs) {
ip_list_.reserve(cidrs.size());
for (const envoy::config::core::v3::CidrRange& entry : cidrs) {
Expand All @@ -228,6 +237,19 @@ IpList::IpList(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRan
}
}

IpList::IpList(const Protobuf::RepeatedPtrField<xds::core::v3::CidrRange>& cidrs) {
ip_list_.reserve(cidrs.size());
for (const xds::core::v3::CidrRange& entry : cidrs) {
absl::StatusOr<CidrRange> range_or_error = CidrRange::create(entry);
if (range_or_error.status().ok()) {
ip_list_.push_back(std::move(range_or_error.value()));
} else {
error_ = fmt::format("invalid ip/mask combo '{}/{}' (format is <ip>/<# mask bits>)",
entry.address_prefix(), entry.prefix_len().value());
}
}
}

bool IpList::contains(const Instance& address) const {
for (const CidrRange& entry : ip_list_) {
if (entry.isInRange(address)) {
Expand Down
5 changes: 4 additions & 1 deletion source/common/network/cidr_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ class IpList {
public:
static absl::StatusOr<std::unique_ptr<IpList>>
create(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs);
static absl::StatusOr<std::unique_ptr<IpList>>
create(const Protobuf::RepeatedPtrField<xds::core::v3::CidrRange>& cidrs);

IpList() = default;

Expand All @@ -140,7 +142,8 @@ class IpList {
const std::string& error() const { return error_; }

private:
explicit IpList(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs);
IpList(const Protobuf::RepeatedPtrField<envoy::config::core::v3::CidrRange>& cidrs);
IpList(const Protobuf::RepeatedPtrField<xds::core::v3::CidrRange>& cidrs);
std::vector<CidrRange> ip_list_;
std::string error_;
};
Expand Down
7 changes: 6 additions & 1 deletion source/extensions/filters/common/rbac/matchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -265,9 +265,14 @@ bool MetadataMatcher::matches(const Network::Connection&, const Envoy::Http::Req
return matcher_.match(info.dynamicMetadata());
}

FilterStateMatcher::FilterStateMatcher(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context)
: matcher_(THROW_OR_RETURN_VALUE(Envoy::Matchers::FilterStateMatcher::create(matcher, context),
Envoy::Matchers::FilterStateMatcherPtr)) {}

bool FilterStateMatcher::matches(const Network::Connection&, const Envoy::Http::RequestHeaderMap&,
const StreamInfo::StreamInfo& info) const {
return matcher_.match(info.filterState());
return matcher_->match(info.filterState());
}

bool PolicyMatcher::matches(const Network::Connection& connection,
Expand Down
5 changes: 2 additions & 3 deletions source/extensions/filters/common/rbac/matchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,13 @@ class MetadataMatcher : public Matcher {
class FilterStateMatcher : public Matcher {
public:
FilterStateMatcher(const envoy::type::matcher::v3::FilterStateMatcher& matcher,
Server::Configuration::CommonFactoryContext& context)
: matcher_(matcher, context) {}
Server::Configuration::CommonFactoryContext& context);

bool matches(const Network::Connection&, const Envoy::Http::RequestHeaderMap&,
const StreamInfo::StreamInfo& info) const override;

private:
const Envoy::Matchers::FilterStateMatcher matcher_;
const Envoy::Matchers::FilterStateMatcherPtr matcher_;
};

/**
Expand Down
Loading

0 comments on commit c86c974

Please sign in to comment.