Line data Source code
1 : #pragma once 2 : 3 : #include "envoy/extensions/matching/common_inputs/network/v3/network_inputs.pb.h" 4 : #include "envoy/extensions/matching/common_inputs/network/v3/network_inputs.pb.validate.h" 5 : #include "envoy/matcher/matcher.h" 6 : #include "envoy/network/filter.h" 7 : #include "envoy/registry/registry.h" 8 : 9 : #include "source/common/network/utility.h" 10 : 11 : namespace Envoy { 12 : namespace Network { 13 : namespace Matching { 14 : 15 : template <class InputType, class ProtoType, class MatchingDataType> 16 : class BaseFactory : public Matcher::DataInputFactory<MatchingDataType> { 17 : protected: 18 40 : explicit BaseFactory(const std::string& name) : name_(name) {} 19 : 20 : public: 21 616 : std::string name() const override { return "envoy.matching.inputs." + name_; } 22 : 23 : Matcher::DataInputFactoryCb<MatchingDataType> 24 0 : createDataInputFactoryCb(const Protobuf::Message&, ProtobufMessage::ValidationVisitor&) override { 25 0 : return []() { return std::make_unique<InputType>(); }; 26 0 : }; 27 16 : ProtobufTypes::MessagePtr createEmptyConfigProto() override { 28 16 : return std::make_unique<ProtoType>(); 29 16 : } 30 : 31 : private: 32 : const std::string name_; 33 : }; 34 : 35 : template <class MatchingDataType> 36 : class DestinationIPInput : public Matcher::DataInput<MatchingDataType> { 37 : public: 38 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 39 0 : const auto& address = data.localAddress(); 40 : 41 0 : if (address.type() != Network::Address::Type::Ip) { 42 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 43 0 : } 44 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 45 0 : address.ip()->addressAsString()}; 46 0 : } 47 : }; 48 : 49 : template <class MatchingDataType> 50 : class DestinationIPInputBaseFactory 51 : : public BaseFactory< 52 : DestinationIPInput<MatchingDataType>, 53 : envoy::extensions::matching::common_inputs::network::v3::DestinationIPInput, 54 : MatchingDataType> { 55 : public: 56 : DestinationIPInputBaseFactory() 57 : : BaseFactory<DestinationIPInput<MatchingDataType>, 58 : envoy::extensions::matching::common_inputs::network::v3::DestinationIPInput, 59 6 : MatchingDataType>("destination_ip") {} 60 : }; 61 : 62 : DECLARE_FACTORY(DestinationIPInputFactory); 63 : DECLARE_FACTORY(UdpDestinationIPInputFactory); 64 : DECLARE_FACTORY(HttpDestinationIPInputFactory); 65 : 66 : // With the support of generic matching API, integer is allowed in inputs such as 67 : // `DestinationPortInput` and `SourcePortInput`. As a result, there is no longer a need for the 68 : // redundant conversion of int-to-string. We can change them here once IntInputMatcher (for integer 69 : // type input) is implemented. 70 : template <class MatchingDataType> 71 : class DestinationPortInput : public Matcher::DataInput<MatchingDataType> { 72 : public: 73 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 74 0 : const auto& address = data.localAddress(); 75 0 : if (address.type() != Network::Address::Type::Ip) { 76 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 77 0 : } 78 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 79 0 : absl::StrCat(address.ip()->port())}; 80 0 : } 81 : }; 82 : 83 : template <class MatchingDataType> 84 : class DestinationPortInputBaseFactory 85 : : public BaseFactory< 86 : DestinationPortInput<MatchingDataType>, 87 : envoy::extensions::matching::common_inputs::network::v3::DestinationPortInput, 88 : MatchingDataType> { 89 : public: 90 : DestinationPortInputBaseFactory() 91 : : BaseFactory<DestinationPortInput<MatchingDataType>, 92 : envoy::extensions::matching::common_inputs::network::v3::DestinationPortInput, 93 6 : MatchingDataType>("destination_port") {} 94 : }; 95 : 96 : DECLARE_FACTORY(DestinationPortInputFactory); 97 : DECLARE_FACTORY(UdpDestinationPortInputFactory); 98 : DECLARE_FACTORY(HttpDestinationPortInputFactory); 99 : 100 : template <class MatchingDataType> 101 : class SourceIPInput : public Matcher::DataInput<MatchingDataType> { 102 : public: 103 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 104 0 : const auto& address = data.remoteAddress(); 105 0 : if (address.type() != Network::Address::Type::Ip) { 106 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 107 0 : } 108 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 109 0 : address.ip()->addressAsString()}; 110 0 : } 111 : }; 112 : 113 : template <class MatchingDataType> 114 : class SourceIPInputBaseFactory 115 : : public BaseFactory<SourceIPInput<MatchingDataType>, 116 : envoy::extensions::matching::common_inputs::network::v3::SourceIPInput, 117 : MatchingDataType> { 118 : public: 119 : SourceIPInputBaseFactory() 120 : : BaseFactory<SourceIPInput<MatchingDataType>, 121 : envoy::extensions::matching::common_inputs::network::v3::SourceIPInput, 122 6 : MatchingDataType>("source_ip") {} 123 : }; 124 : 125 : DECLARE_FACTORY(SourceIPInputFactory); 126 : DECLARE_FACTORY(UdpSourceIPInputFactory); 127 : DECLARE_FACTORY(HttpSourceIPInputFactory); 128 : 129 : template <class MatchingDataType> 130 : class SourcePortInput : public Matcher::DataInput<MatchingDataType> { 131 : public: 132 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 133 0 : const auto& address = data.remoteAddress(); 134 0 : if (address.type() != Network::Address::Type::Ip) { 135 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 136 0 : } 137 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 138 0 : absl::StrCat(address.ip()->port())}; 139 0 : } 140 : }; 141 : 142 : template <class MatchingDataType> 143 : class SourcePortInputBaseFactory 144 : : public BaseFactory<SourcePortInput<MatchingDataType>, 145 : envoy::extensions::matching::common_inputs::network::v3::SourcePortInput, 146 : MatchingDataType> { 147 : public: 148 : SourcePortInputBaseFactory() 149 : : BaseFactory<SourcePortInput<MatchingDataType>, 150 : envoy::extensions::matching::common_inputs::network::v3::SourcePortInput, 151 6 : MatchingDataType>("source_port") {} 152 : }; 153 : 154 : DECLARE_FACTORY(SourcePortInputFactory); 155 : DECLARE_FACTORY(UdpSourcePortInputFactory); 156 : DECLARE_FACTORY(HttpSourcePortInputFactory); 157 : 158 : template <class MatchingDataType> 159 : class DirectSourceIPInput : public Matcher::DataInput<MatchingDataType> { 160 : public: 161 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 162 0 : const auto& address = data.connectionInfoProvider().directRemoteAddress(); 163 0 : if (address->type() != Network::Address::Type::Ip) { 164 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 165 0 : } 166 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 167 0 : address->ip()->addressAsString()}; 168 0 : } 169 : }; 170 : 171 : template <class MatchingDataType> 172 : class DirectSourceIPInputBaseFactory 173 : : public BaseFactory< 174 : DirectSourceIPInput<MatchingDataType>, 175 : envoy::extensions::matching::common_inputs::network::v3::DirectSourceIPInput, 176 : MatchingDataType> { 177 : public: 178 : DirectSourceIPInputBaseFactory() 179 : : BaseFactory<DirectSourceIPInput<MatchingDataType>, 180 : envoy::extensions::matching::common_inputs::network::v3::DirectSourceIPInput, 181 4 : MatchingDataType>("direct_source_ip") {} 182 : }; 183 : 184 : DECLARE_FACTORY(DirectSourceIPInputFactory); 185 : DECLARE_FACTORY(HttpDirectSourceIPInputFactory); 186 : 187 : template <class MatchingDataType> 188 : class SourceTypeInput : public Matcher::DataInput<MatchingDataType> { 189 : public: 190 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 191 0 : const bool is_local_connection = 192 0 : Network::Utility::isSameIpOrLoopback(data.connectionInfoProvider()); 193 0 : if (is_local_connection) { 194 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, "local"}; 195 0 : } 196 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 197 0 : } 198 : }; 199 : 200 : template <class MatchingDataType> 201 : class SourceTypeInputBaseFactory 202 : : public BaseFactory<SourceTypeInput<MatchingDataType>, 203 : envoy::extensions::matching::common_inputs::network::v3::SourceTypeInput, 204 : MatchingDataType> { 205 : public: 206 : SourceTypeInputBaseFactory() 207 : : BaseFactory<SourceTypeInput<MatchingDataType>, 208 : envoy::extensions::matching::common_inputs::network::v3::SourceTypeInput, 209 4 : MatchingDataType>("source_type") {} 210 : }; 211 : 212 : DECLARE_FACTORY(SourceTypeInputFactory); 213 : DECLARE_FACTORY(HttpSourceTypeInputFactory); 214 : 215 : template <class MatchingDataType> 216 : class ServerNameInput : public Matcher::DataInput<MatchingDataType> { 217 : public: 218 0 : Matcher::DataInputGetResult get(const MatchingDataType& data) const override { 219 0 : const auto server_name = data.connectionInfoProvider().requestedServerName(); 220 0 : if (!server_name.empty()) { 221 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, 222 0 : std::string(server_name)}; 223 0 : } 224 0 : return {Matcher::DataInputGetResult::DataAvailability::AllDataAvailable, absl::monostate()}; 225 0 : } 226 : }; 227 : 228 : template <class MatchingDataType> 229 : class ServerNameInputBaseFactory 230 : : public BaseFactory<ServerNameInput<MatchingDataType>, 231 : envoy::extensions::matching::common_inputs::network::v3::ServerNameInput, 232 : MatchingDataType> { 233 : public: 234 : ServerNameInputBaseFactory() 235 : : BaseFactory<ServerNameInput<MatchingDataType>, 236 : envoy::extensions::matching::common_inputs::network::v3::ServerNameInput, 237 4 : MatchingDataType>("server_name") {} 238 : }; 239 : 240 : DECLARE_FACTORY(ServerNameInputFactory); 241 : DECLARE_FACTORY(HttpServerNameInputFactory); 242 : 243 : class TransportProtocolInput : public Matcher::DataInput<MatchingData> { 244 : public: 245 : Matcher::DataInputGetResult get(const MatchingData& data) const override; 246 : }; 247 : 248 : class TransportProtocolInputFactory 249 : : public BaseFactory< 250 : TransportProtocolInput, 251 : envoy::extensions::matching::common_inputs::network::v3::TransportProtocolInput, 252 : MatchingData> { 253 : public: 254 2 : TransportProtocolInputFactory() : BaseFactory("transport_protocol") {} 255 : }; 256 : 257 : DECLARE_FACTORY(TransportProtocolInputFactory); 258 : 259 : class FilterStateInput : public Matcher::DataInput<MatchingData> { 260 : public: 261 : FilterStateInput( 262 : const envoy::extensions::matching::common_inputs::network::v3::FilterStateInput& input_config) 263 0 : : filter_state_key_(input_config.key()) {} 264 : 265 : Matcher::DataInputGetResult get(const MatchingData& data) const override; 266 : 267 : private: 268 : const std::string filter_state_key_; 269 : }; 270 : 271 : class FilterStateInputFactory : public Matcher::DataInputFactory<MatchingData> { 272 : public: 273 38 : std::string name() const override { return "envoy.matching.inputs.filter_state"; } 274 : 275 : Matcher::DataInputFactoryCb<MatchingData> createDataInputFactoryCb( 276 : const Protobuf::Message& message, 277 0 : ProtobufMessage::ValidationVisitor& message_validation_visitor) override { 278 0 : const auto& proto_config = MessageUtil::downcastAndValidate< 279 0 : const envoy::extensions::matching::common_inputs::network::v3::FilterStateInput&>( 280 0 : message, message_validation_visitor); 281 : 282 0 : return [proto_config]() { return std::make_unique<FilterStateInput>(proto_config); }; 283 0 : }; 284 : 285 1 : ProtobufTypes::MessagePtr createEmptyConfigProto() override { 286 1 : return std::make_unique< 287 1 : envoy::extensions::matching::common_inputs::network::v3::FilterStateInput>(); 288 1 : } 289 : }; 290 : 291 : DECLARE_FACTORY(FilterStateInputFactory); 292 : 293 : } // namespace Matching 294 : } // namespace Network 295 : } // namespace Envoy