Line data Source code
1 : #include "source/common/upstream/default_local_address_selector_factory.h" 2 : 3 : #include "source/common/upstream/default_local_address_selector.h" 4 : 5 : namespace Envoy { 6 : namespace Upstream { 7 : 8 : namespace { 9 : constexpr absl::string_view kDefaultLocalAddressSelectorName = 10 : "envoy.upstream.local_address_selector.default_local_address_selector"; 11 : 12 : absl::Status 13 : validate(const std::vector<::Envoy::Upstream::UpstreamLocalAddress>& upstream_local_addresses, 14 159 : absl::optional<std::string> cluster_name) { 15 : 16 159 : if (upstream_local_addresses.empty()) { 17 0 : return absl::InvalidArgumentError( 18 0 : fmt::format("{}'s upstream binding config has no valid source address.", 19 0 : !(cluster_name.has_value()) ? "Bootstrap" 20 0 : : fmt::format("Cluster {}", cluster_name.value()))); 21 0 : } 22 : 23 159 : if (upstream_local_addresses.size() > 2) { 24 0 : return absl::InvalidArgumentError(fmt::format( 25 0 : "{}'s upstream binding config has more than one extra/additional source addresses. Only " 26 0 : "one extra/additional source can be supported in BindConfig's " 27 0 : "extra_source_addresses/additional_source_addresses field", 28 0 : !(cluster_name.has_value()) ? "Bootstrap" 29 0 : : fmt::format("Cluster {}", cluster_name.value()))); 30 0 : } 31 : // If we have exactly one upstream address, it needs to have a valid IP 32 : // version if non-null. This is enforced by the fact that BindConfig only 33 : // allows socket address. 34 159 : ASSERT(upstream_local_addresses.size() != 1 || upstream_local_addresses[0].address_ == nullptr || 35 159 : upstream_local_addresses[0].address_->ip() != nullptr); 36 : 37 : // If we have more than one upstream address, they need to have different IP versions. 38 159 : if (upstream_local_addresses.size() == 2) { 39 0 : ASSERT(upstream_local_addresses[0].address_ != nullptr && 40 0 : upstream_local_addresses[1].address_ != nullptr && 41 0 : upstream_local_addresses[0].address_->ip() != nullptr && 42 0 : upstream_local_addresses[1].address_->ip() != nullptr); 43 : 44 0 : if (upstream_local_addresses[0].address_->ip()->version() == 45 0 : upstream_local_addresses[1].address_->ip()->version()) { 46 0 : return absl::InvalidArgumentError(fmt::format( 47 0 : "{}'s upstream binding config has two same IP version source addresses. Only two " 48 0 : "different IP version source addresses can be supported in BindConfig's source_address " 49 0 : "and extra_source_addresses/additional_source_addresses fields", 50 0 : !(cluster_name.has_value()) ? "Bootstrap" 51 0 : : fmt::format("Cluster {}", cluster_name.value()))); 52 0 : } 53 0 : } 54 159 : return absl::OkStatus(); 55 159 : } 56 : 57 : } // namespace 58 : 59 190 : std::string DefaultUpstreamLocalAddressSelectorFactory::name() const { 60 190 : return std::string(kDefaultLocalAddressSelectorName); 61 190 : } 62 : 63 : absl::StatusOr<UpstreamLocalAddressSelectorConstSharedPtr> 64 : DefaultUpstreamLocalAddressSelectorFactory::createLocalAddressSelector( 65 : std::vector<::Envoy::Upstream::UpstreamLocalAddress> upstream_local_addresses, 66 159 : absl::optional<std::string> cluster_name) const { 67 159 : absl::Status status = validate(upstream_local_addresses, cluster_name); 68 159 : if (!status.ok()) { 69 0 : return status; 70 0 : } 71 159 : return std::make_shared<DefaultUpstreamLocalAddressSelector>(std::move(upstream_local_addresses)); 72 159 : } 73 : 74 : /** 75 : * Static registration for the default local address selector. @see RegisterFactory. 76 : */ 77 : REGISTER_FACTORY(DefaultUpstreamLocalAddressSelectorFactory, UpstreamLocalAddressSelectorFactory); 78 : 79 : } // namespace Upstream 80 : } // namespace Envoy