summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc')
-rw-r--r--src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc1556
1 files changed, 1556 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc b/src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc
new file mode 100644
index 0000000..e59ad5d
--- /dev/null
+++ b/src/lib/dhcpsrv/testutils/test_config_backend_dhcp6.cc
@@ -0,0 +1,1556 @@
+// Copyright (C) 2019-2021 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <database/database_connection.h>
+#include <test_config_backend_dhcp6.h>
+
+using namespace isc::data;
+using namespace isc::db;
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+bool
+TestConfigBackendDHCPv6::registerBackendType(ConfigBackendDHCPv6Mgr& mgr,
+ const std::string& db_type) {
+ return(mgr.registerBackendFactory(db_type,
+ [](const db::DatabaseConnection::ParameterMap& params)
+ -> dhcp::ConfigBackendDHCPv6Ptr {
+ return (TestConfigBackendDHCPv6Ptr(new TestConfigBackendDHCPv6(params)));
+ })
+ );
+}
+
+void
+TestConfigBackendDHCPv6::unregisterBackendType(ConfigBackendDHCPv6Mgr& mgr,
+ const std::string& db_type) {
+ mgr.unregisterBackendFactory(db_type);
+}
+
+Subnet6Ptr
+TestConfigBackendDHCPv6::getSubnet6(const db::ServerSelector& server_selector,
+ const std::string& subnet_prefix) const{
+ const auto& index = subnets_.get<SubnetPrefixIndexTag>();
+ auto subnet_it = index.find(subnet_prefix);
+ if (subnet_it == index.cend()) {
+ return (Subnet6Ptr());
+ }
+ Subnet6Ptr subnet = *subnet_it;
+ if (server_selector.amAny()) {
+ return (subnet);
+ }
+ if (server_selector.amUnassigned()) {
+ return (subnet->getServerTags().empty() ? subnet : Subnet6Ptr());
+ }
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ return (subnet);
+ }
+ }
+ return (subnet->hasAllServerTag() ? subnet : Subnet6Ptr());
+}
+
+Subnet6Ptr
+TestConfigBackendDHCPv6::getSubnet6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id) const {
+ const auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+ if (subnet_it == index.cend()) {
+ return (Subnet6Ptr());
+ }
+ Subnet6Ptr subnet = *subnet_it;
+ if (server_selector.amAny()) {
+ return (subnet);
+ }
+ if (server_selector.amUnassigned()) {
+ return (subnet->getServerTags().empty() ? subnet : Subnet6Ptr());
+ }
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ return (subnet);
+ }
+ }
+ return (subnet->hasAllServerTag() ? subnet : Subnet6Ptr());
+}
+
+Subnet6Collection
+TestConfigBackendDHCPv6::getAllSubnets6(const db::ServerSelector& server_selector) const {
+ Subnet6Collection subnets;
+ for (auto subnet : subnets_) {
+ if (server_selector.amAny()) {
+ subnets.insert(subnet);
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (subnet->getServerTags().empty()) {
+ subnets.insert(subnet);
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ subnets.insert(subnet);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (subnet->hasAllServerTag()) {
+ subnets.insert(subnet);
+ }
+ }
+ return (subnets);
+}
+
+Subnet6Collection
+TestConfigBackendDHCPv6::getModifiedSubnets6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ const auto& index = subnets_.get<SubnetModificationTimeIndexTag>();
+ Subnet6Collection subnets;
+ auto lb = index.lower_bound(modification_time);
+ for (auto subnet = lb; subnet != index.end(); ++subnet) {
+ if (server_selector.amAny()) {
+ subnets.insert(*subnet);
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if ((*subnet)->getServerTags().empty()) {
+ subnets.insert(*subnet);
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*subnet)->hasServerTag(ServerTag(tag))) {
+ subnets.insert(*subnet);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if ((*subnet)->hasAllServerTag()) {
+ subnets.insert(*subnet);
+ }
+ }
+ return (subnets);
+}
+
+Subnet6Collection
+TestConfigBackendDHCPv6::getSharedNetworkSubnets6(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) const {
+ Subnet6Collection subnets;
+
+ // Subnet collection does not include the index by shared network name.
+ // We need to iterate over the subnets and pick those that are associated
+ // with a shared network.
+ for (auto subnet : subnets_) {
+ // Skip subnets which do not match the server selector.
+ if (server_selector.amUnassigned() &&
+ !subnet->getServerTags().empty()) {
+ continue;
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !subnet->hasAllServerTag()) {
+ continue;
+ }
+ }
+
+ // The subnet can be associated with a shared network instance or
+ // it may just point to the shared network name. The former is
+ // the case when the subnet belongs to the server configuration.
+ // The latter is the case when the subnet is fetched from the
+ // database.
+ SharedNetwork6Ptr network;
+ subnet->getSharedNetwork(network);
+ if (((network && (network->getName() == shared_network_name)) ||
+ (subnet->getSharedNetworkName() == shared_network_name))) {
+ subnets.insert(subnet);
+ }
+ }
+ return (subnets);
+}
+
+SharedNetwork6Ptr
+TestConfigBackendDHCPv6::getSharedNetwork6(const db::ServerSelector& server_selector,
+ const std::string& name) const {
+ const auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ auto network_it = index.find(name);
+ if (network_it == index.cend()) {
+ return (SharedNetwork6Ptr());
+ }
+ SharedNetwork6Ptr network = *network_it;
+ if (server_selector.amAny()) {
+ return (network);
+ }
+ if (server_selector.amUnassigned()) {
+ return (network->getServerTags().empty() ? network : SharedNetwork6Ptr());
+ }
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (network->hasServerTag(ServerTag(tag))) {
+ return (network);
+ }
+ }
+ return (network->hasAllServerTag() ? network : SharedNetwork6Ptr());
+}
+
+SharedNetwork6Collection
+TestConfigBackendDHCPv6::getAllSharedNetworks6(const db::ServerSelector& server_selector) const{
+ SharedNetwork6Collection shared_networks;
+ for (auto shared_network : shared_networks_) {
+ if (server_selector.amAny()) {
+ shared_networks.push_back(shared_network);
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (shared_network->getServerTags().empty()) {
+ shared_networks.push_back(shared_network);
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (shared_network->hasServerTag(ServerTag(tag))) {
+ shared_networks.push_back(shared_network);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (shared_network->hasAllServerTag()) {
+ shared_networks.push_back(shared_network);
+ }
+ }
+ return (shared_networks);
+}
+
+SharedNetwork6Collection
+TestConfigBackendDHCPv6::getModifiedSharedNetworks6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ const auto& index = shared_networks_.get<SharedNetworkModificationTimeIndexTag>();
+ SharedNetwork6Collection shared_networks;
+ auto lb = index.lower_bound(modification_time);
+ for (auto shared_network = lb; shared_network != index.end(); ++shared_network) {
+ if (server_selector.amAny()) {
+ shared_networks.push_back(*shared_network);
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if ((*shared_network)->getServerTags().empty()) {
+ shared_networks.push_back(*shared_network);
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*shared_network)->hasServerTag(ServerTag(tag))) {
+ shared_networks.push_back(*shared_network);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if ((*shared_network)->hasAllServerTag()) {
+ shared_networks.push_back(*shared_network);
+ }
+ }
+ return (shared_networks);
+}
+
+OptionDefinitionPtr
+TestConfigBackendDHCPv6::getOptionDef6(const db::ServerSelector& server_selector,
+ const uint16_t code,
+ const std::string& space) const {
+ auto tags = server_selector.getTags();
+ auto candidate = OptionDefinitionPtr();
+ const auto& index = option_defs_.get<1>();
+ auto option_def_it_pair = index.equal_range(code);
+
+ for (auto option_def_it = option_def_it_pair.first;
+ option_def_it != option_def_it_pair.second;
+ ++option_def_it) {
+ if ((*option_def_it)->getOptionSpaceName() == space) {
+ for (auto tag : tags) {
+ if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+ return (*option_def_it);
+ }
+ }
+ if ((*option_def_it)->hasAllServerTag()) {
+ candidate = *option_def_it;
+ }
+ }
+ }
+ return (candidate);
+}
+
+OptionDefContainer
+TestConfigBackendDHCPv6::getAllOptionDefs6(const db::ServerSelector& server_selector) const {
+ auto tags = server_selector.getTags();
+ OptionDefContainer option_defs;
+ for (auto option_def : option_defs_) {
+ bool got = false;
+ if (server_selector.amUnassigned()) {
+ if (option_def->getServerTags().empty()) {
+ option_defs.push_back(option_def);
+ got = true;
+ }
+ } else {
+ for (auto tag : tags) {
+ if (option_def->hasServerTag(ServerTag(tag))) {
+ option_defs.push_back(option_def);
+ got = true;
+ break;
+ }
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (option_def->hasAllServerTag() && !server_selector.amUnassigned()) {
+ option_defs.push_back(option_def);
+ }
+ }
+ return (option_defs);
+}
+
+OptionDefContainer
+TestConfigBackendDHCPv6::getModifiedOptionDefs6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ auto tags = server_selector.getTags();
+ OptionDefContainer option_defs;
+ const auto& index = option_defs_.get<3>();
+ auto lb = index.lower_bound(modification_time);
+ for (auto option_def = lb; option_def != index.end(); ++option_def) {
+ bool got = false;
+ for (auto tag : tags) {
+ if ((*option_def)->hasServerTag(ServerTag(tag))) {
+ option_defs.push_back(*option_def);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if ((*option_def)->hasAllServerTag()) {
+ option_defs.push_back(*option_def);
+ }
+ }
+ return (option_defs);
+}
+
+OptionDescriptorPtr
+TestConfigBackendDHCPv6::getOption6(const db::ServerSelector& server_selector,
+ const uint16_t code,
+ const std::string& space) const {
+ auto tags = server_selector.getTags();
+ auto candidate = OptionDescriptorPtr();
+ const auto& index = options_.get<1>();
+ auto option_it_pair = index.equal_range(code);
+
+ for (auto option_it = option_it_pair.first; option_it != option_it_pair.second;
+ ++option_it) {
+ if (option_it->space_name_ == space) {
+ for (auto tag : tags) {
+ if (option_it->hasServerTag(ServerTag(tag))) {
+ return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
+ }
+ }
+ if (option_it->hasAllServerTag()) {
+ candidate = OptionDescriptorPtr(new OptionDescriptor(*option_it));
+ }
+ }
+ }
+
+ return (candidate);
+}
+
+OptionContainer
+TestConfigBackendDHCPv6::getAllOptions6(const db::ServerSelector& server_selector) const {
+ auto tags = server_selector.getTags();
+ OptionContainer options;
+ for (auto option : options_) {
+ bool got = false;
+ for (auto tag : tags) {
+ if (option.hasServerTag(ServerTag(tag))) {
+ options.push_back(option);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (option.hasAllServerTag()) {
+ options.push_back(option);
+ }
+ }
+ return (options);
+}
+
+OptionContainer
+TestConfigBackendDHCPv6::getModifiedOptions6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ auto tags = server_selector.getTags();
+ OptionContainer options;
+ const auto& index = options_.get<3>();
+ auto lb = index.lower_bound(modification_time);
+ for (auto option = lb; option != index.end(); ++option) {
+ bool got = false;
+ for (auto tag : tags) {
+ if (option->hasServerTag(ServerTag(tag))) {
+ options.push_back(*option);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (option->hasAllServerTag()) {
+ options.push_back(*option);
+ }
+ }
+ return (options);
+}
+
+StampedValuePtr
+TestConfigBackendDHCPv6::getGlobalParameter6(const db::ServerSelector& server_selector,
+ const std::string& name) const {
+ auto tags = server_selector.getTags();
+ auto candidate = StampedValuePtr();
+ const auto& index = globals_.get<StampedValueNameIndexTag>();
+ auto global_range = index.equal_range(name);
+ for (auto global_it = global_range.first; global_it != global_range.second;
+ ++global_it) {
+ for (auto tag : tags) {
+ if ((*global_it)->hasServerTag(ServerTag(tag))) {
+ return (*global_it);
+ }
+ }
+ if ((*global_it)->hasAllServerTag()) {
+ candidate = *global_it;
+ }
+ }
+
+ return (candidate);
+}
+
+
+StampedValueCollection
+TestConfigBackendDHCPv6::getAllGlobalParameters6(const db::ServerSelector& server_selector) const {
+ auto tags = server_selector.getTags();
+ StampedValueCollection globals;
+ for (auto global : globals_) {
+ bool got = false;
+ for (auto tag : tags) {
+ if (global->hasServerTag(ServerTag(tag))) {
+ globals.insert(global);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (global->hasAllServerTag()) {
+ globals.insert(global);
+ }
+ }
+ return (globals);
+}
+
+StampedValueCollection
+TestConfigBackendDHCPv6::getModifiedGlobalParameters6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ auto tags = server_selector.getTags();
+ StampedValueCollection globals;
+ const auto& index = globals_.get<StampedValueModificationTimeIndexTag>();
+ auto lb = index.lower_bound(modification_time);
+ for (auto global = lb; global != index.end(); ++global) {
+ bool got = false;
+ for (auto tag : tags) {
+ if ((*global)->hasServerTag(ServerTag(tag))) {
+ globals.insert(*global);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if ((*global)->hasAllServerTag()) {
+ globals.insert(*global);
+ }
+ }
+ return (globals);
+}
+
+ClientClassDefPtr
+TestConfigBackendDHCPv6::getClientClass6(const db::ServerSelector& server_selector,
+ const std::string& name) const {
+ ClientClassDefPtr client_class;
+ for (auto c : classes_) {
+ if (c->getName() == name) {
+ client_class = c;
+ break;
+ }
+ }
+ if (!client_class || server_selector.amAny()) {
+ return (client_class);
+ }
+ if (server_selector.amUnassigned()) {
+ return (client_class->getServerTags().empty() ? client_class : ClientClassDefPtr());
+ }
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (client_class->hasServerTag(ServerTag(tag))) {
+ return (client_class);
+ }
+ }
+ return (client_class->hasAllServerTag() ? client_class : ClientClassDefPtr());
+}
+
+ClientClassDictionary
+TestConfigBackendDHCPv6::getAllClientClasses6(const db::ServerSelector& server_selector) const {
+ auto tags = server_selector.getTags();
+ ClientClassDictionary all_classes;
+ for (auto client_class : classes_) {
+ if (server_selector.amAny()) {
+ all_classes.addClass(client_class);
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (client_class->getServerTags().empty()) {
+ all_classes.addClass(client_class);
+ }
+ continue;
+ }
+ bool got = false;
+ for (auto tag : tags) {
+ if (client_class->hasServerTag(ServerTag(tag))) {
+ all_classes.addClass(client_class);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (client_class->hasAllServerTag()) {
+ all_classes.addClass(client_class);
+ }
+ }
+ return (all_classes);
+}
+
+ClientClassDictionary
+TestConfigBackendDHCPv6::getModifiedClientClasses6(const db::ServerSelector& server_selector,
+ const boost::posix_time::ptime& modification_time) const {
+ auto tags = server_selector.getTags();
+ ClientClassDictionary modified_classes;
+ for (auto client_class : classes_) {
+ if (client_class->getModificationTime() >= modification_time) {
+ bool got = false;
+ for (auto tag : tags) {
+ if (client_class->hasServerTag(ServerTag(tag))) {
+ modified_classes.addClass(client_class);
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (client_class->hasAllServerTag()) {
+ modified_classes.addClass(client_class);
+ }
+ }
+ }
+ return (modified_classes);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateClientClass6(const db::ServerSelector& server_selector,
+ const ClientClassDefPtr& client_class,
+ const std::string& follow_class_name) {
+ int follow_class_index = -1;
+ if (!follow_class_name.empty()) {
+ for (auto i = 0; i < classes_.size(); ++i) {
+ if (classes_[i]->getName() == follow_class_name) {
+ follow_class_index = i;
+ break;
+ }
+ }
+ if (follow_class_index < 0) {
+ isc_throw(BadValue, "class " << follow_class_name << " does not exist");
+
+ }
+ }
+
+ mergeServerTags(client_class, server_selector);
+
+ int existing_class_index = -1;
+ for (auto i = 0; i < classes_.size(); ++i) {
+ if (classes_[i]->getName() == client_class->getName()) {
+ existing_class_index = i;
+ break;
+ }
+ }
+
+ if (follow_class_index < 0) {
+ if (existing_class_index >= 0) {
+ classes_[existing_class_index] = client_class;
+ } else {
+ classes_.push_back(client_class);
+ }
+ } else {
+ if (existing_class_index < 0) {
+ classes_.insert(classes_.begin() + follow_class_index + 1, client_class);
+ } else {
+ classes_.erase(classes_.begin() + existing_class_index);
+ classes_.insert(classes_.begin() + follow_class_index + 1, client_class);
+ }
+ }
+}
+
+AuditEntryCollection
+TestConfigBackendDHCPv6::getRecentAuditEntries(const db::ServerSelector&,
+ const boost::posix_time::ptime&,
+ const uint64_t&) const {
+ return (AuditEntryCollection());
+}
+
+ServerCollection
+TestConfigBackendDHCPv6::getAllServers6() const {
+ return (servers_);
+}
+
+ServerPtr
+TestConfigBackendDHCPv6::getServer6(const ServerTag& server_tag) const {
+ const auto& index = servers_.get<ServerTagIndexTag>();
+ auto server_it = index.find(server_tag.get());
+ return ((server_it != index.cend()) ? (*server_it) : ServerPtr());
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateSubnet6(const db::ServerSelector& server_selector,
+ const Subnet6Ptr& subnet) {
+ auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet->getID());
+
+ mergeServerTags(subnet, server_selector);
+
+ if (subnet_it != index.cend()) {
+ index.replace(subnet_it, subnet);
+ } else {
+ index.insert(subnet);
+ }
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateSharedNetwork6(const db::ServerSelector& server_selector,
+ const SharedNetwork6Ptr& shared_network) {
+ auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ auto network_it = index.find(shared_network->getName());
+
+ mergeServerTags(shared_network, server_selector);
+
+ if (network_it != index.cend()) {
+ index.replace(network_it, shared_network);
+ } else {
+ index.insert(shared_network);
+ }
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOptionDef6(const db::ServerSelector& server_selector,
+ const OptionDefinitionPtr& option_def) {
+ auto tag = getServerTag(server_selector);
+ option_def->setServerTag(tag);
+
+ // Index #1 is by option code.
+ auto& index1 = option_defs_.get<1>();
+ auto option_def_it_pair1 = index1.equal_range(option_def->getCode());
+
+ for (auto option_def_it = option_def_it_pair1.first;
+ option_def_it != option_def_it_pair1.second;
+ option_def_it++) {
+ auto existing_option_def = *option_def_it;
+ if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+ (existing_option_def->hasServerTag(ServerTag(tag)))) {
+ index1.replace(option_def_it, option_def);
+ return;
+ }
+ }
+
+ // Index #2 is by option name.
+ auto& index2 = option_defs_.get<2>();
+ auto option_def_it_pair2 = index2.equal_range(option_def->getName());
+
+ for (auto option_def_it = option_def_it_pair2.first;
+ option_def_it != option_def_it_pair2.second;
+ option_def_it++) {
+ auto existing_option_def = *option_def_it;
+ if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
+ (existing_option_def->hasServerTag(ServerTag(tag)))) {
+ index2.replace(option_def_it, option_def);
+ return;
+ }
+ }
+
+ option_defs_.push_back(option_def);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
+ const OptionDescriptorPtr& option) {
+ auto tag = getServerTag(server_selector);
+ option->setServerTag(tag);
+
+ auto& index = options_.get<1>();
+ auto option_it_pair = index.equal_range(option->option_->getType());
+
+ for (auto option_it = option_it_pair.first;
+ option_it != option_it_pair.second;
+ ++option_it) {
+ if ((option_it->space_name_ == option->space_name_) &&
+ (option_it->hasServerTag(ServerTag(tag)))) {
+ index.replace(option_it, *option);
+ return;
+ }
+ }
+
+ options_.push_back(*option);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name,
+ const OptionDescriptorPtr& option) {
+ auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ auto network_it = index.find(shared_network_name);
+
+ if (network_it == index.end()) {
+ isc_throw(BadValue, "attempted to create or update option in a non existing "
+ "shared network " << shared_network_name);
+ }
+
+ auto shared_network = *network_it;
+ bool found = false;
+ if (server_selector.amUnassigned()) {
+ if (shared_network->getServerTags().empty()) {
+ found = true;
+ }
+ } else if (server_selector.amAny()) {
+ found = true;
+ } else if (shared_network->hasAllServerTag()) {
+ found = true;
+ } else {
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (shared_network->hasServerTag(ServerTag(tag))) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ isc_throw(BadValue, "attempted to create or update option in a "
+ "shared network " << shared_network_name
+ << " not present in a selected server");
+ }
+
+ shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
+ shared_network->getCfgOption()->add(*option, option->space_name_);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id,
+ const OptionDescriptorPtr& option) {
+ auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+
+ if (subnet_it == index.cend()) {
+ isc_throw(BadValue, "attempted to create or update option in a non existing "
+ "subnet ID " << subnet_id);
+ }
+
+ auto subnet = *subnet_it;
+ bool found = false;
+ if (server_selector.amUnassigned()) {
+ if (subnet->getServerTags().empty()) {
+ found = true;
+ }
+ } else if (server_selector.amAny()) {
+ found = true;
+ } else if (subnet->hasAllServerTag()) {
+ found = true;
+ } else {
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ isc_throw(BadValue, "attempted to create or update option in a "
+ "subnet ID " << subnet_id
+ << " not present in a selected server");
+ }
+
+ subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
+ subnet->getCfgOption()->add(*option, option->space_name_);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
+ const asiolink::IOAddress& pool_start_address,
+ const asiolink::IOAddress& pool_end_address,
+ const OptionDescriptorPtr& option) {
+ auto not_in_selected_servers = false;
+ for (auto subnet : subnets_) {
+ // Get the pool: if it is not here we can directly go to the next subnet.
+ auto pool = subnet->getPool(Lease::TYPE_NA, pool_start_address);
+ if (!pool) {
+ continue;
+ }
+
+ // Verify the subnet is in a selected server.
+ if (server_selector.amUnassigned()) {
+ if (!subnet->getServerTags().empty()) {
+ not_in_selected_servers = true;
+ continue;
+ }
+ } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
+ auto in_tags = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ in_tags = true;
+ break;
+ }
+ }
+ if (!in_tags) {
+ // Records the fact a subnet was found but not in a server.
+ not_in_selected_servers = true;
+ continue;
+ }
+ }
+
+ // Update the option.
+ pool->getCfgOption()->del(option->space_name_, option->option_->getType());
+ pool->getCfgOption()->add(*option, option->space_name_);
+
+ return;
+ }
+
+ if (not_in_selected_servers) {
+ isc_throw(BadValue, "attempted to create or update option in "
+ "a pool " << pool_start_address
+ << " - " << pool_end_address
+ << " not present in a selected server");
+ } else {
+ isc_throw(BadValue, "attempted to create or update option in "
+ "a non existing pool " << pool_start_address
+ << " - " << pool_end_address);
+ }
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateOption6(const db::ServerSelector& server_selector,
+ const asiolink::IOAddress& pd_pool_prefix,
+ const uint8_t pd_pool_prefix_length,
+ const OptionDescriptorPtr& option) {
+ auto not_in_selected_servers = false;
+ for (auto subnet : subnets_) {
+ // Get the pd pool: if it is not here we can directly go to the next subnet.
+ auto pdpool = subnet->getPool(Lease::TYPE_PD, pd_pool_prefix);
+ if (!pdpool) {
+ continue;
+ }
+
+ // Verify the subnet is in a selected server.
+ if (server_selector.amUnassigned()) {
+ if (!subnet->getServerTags().empty()) {
+ not_in_selected_servers = true;
+ continue;
+ }
+ } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
+ auto in_tags = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ in_tags = true;
+ break;
+ }
+ }
+ if (!in_tags) {
+ // Records the fact a subnet was found but not in a server.
+ not_in_selected_servers = true;
+ continue;
+ }
+ }
+
+ // Update the option.
+ pdpool->getCfgOption()->del(option->space_name_, option->option_->getType());
+ pdpool->getCfgOption()->add(*option, option->space_name_);
+
+ return;
+ }
+
+ if (not_in_selected_servers) {
+ isc_throw(BadValue, "attempted to create or update option in "
+ "a prefix pool " << pd_pool_prefix
+ << "/" << static_cast<unsigned>(pd_pool_prefix_length)
+ << " not present in a selected server");
+ } else {
+ isc_throw(BadValue, "attempted to create or update option in "
+ "a non existing prefix pool " << pd_pool_prefix
+ << "/" << static_cast<unsigned>(pd_pool_prefix_length));
+ }
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateGlobalParameter6(const db::ServerSelector& server_selector,
+ const data::StampedValuePtr& value) {
+ auto tag = getServerTag(server_selector);
+ value->setServerTag(tag);
+
+ auto& index = globals_.get<StampedValueNameIndexTag>();
+ auto global_it_pair = index.equal_range(value->getName());
+
+ for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+ ++global_it) {
+ auto existing_value = *global_it;
+ if (existing_value->hasServerTag(ServerTag(tag))) {
+ index.replace(global_it, value);
+ return;
+ }
+ }
+
+ index.insert(value);
+}
+
+void
+TestConfigBackendDHCPv6::createUpdateServer6(const db::ServerPtr& server) {
+ auto& index = servers_.get<ServerTagIndexTag>();
+ auto server_it = index.find(server->getServerTagAsText());
+
+ if (server_it != index.end()) {
+ index.replace(server_it, server);
+
+ } else {
+ index.insert(server);
+ }
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteSubnet6(const db::ServerSelector& server_selector,
+ const std::string& subnet_prefix) {
+ auto& index = subnets_.get<SubnetPrefixIndexTag>();
+ auto subnet_it = index.find(subnet_prefix);
+ if (subnet_it == index.end()) {
+ return (0);
+ }
+ if ((server_selector.amUnassigned()) &&
+ !(*subnet_it)->getServerTags().empty()) {
+ return (0);
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*subnet_it)->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !(*subnet_it)->hasAllServerTag()) {
+ return (0);
+ }
+ }
+ return (index.erase(subnet_prefix));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteSubnet6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id) {
+ auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+ if (subnet_it == index.end()) {
+ return (0);
+ }
+ if ((server_selector.amUnassigned()) &&
+ !(*subnet_it)->getServerTags().empty()) {
+ return (0);
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*subnet_it)->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !(*subnet_it)->hasAllServerTag()) {
+ return (0);
+ }
+ }
+ return (index.erase(subnet_id));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllSubnets6(const db::ServerSelector& server_selector) {
+ // Collect subnet to remove by ID.
+ std::list<SubnetID> ids;
+ for (auto subnet : subnets_) {
+ if (server_selector.amAny()) {
+ ids.push_back(subnet->getID());
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (subnet->getServerTags().empty()) {
+ ids.push_back(subnet->getID());
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ ids.push_back(subnet->getID());
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (subnet->hasAllServerTag()) {
+ ids.push_back(subnet->getID());
+ }
+ }
+
+ // Erase subnets.
+ uint64_t erased = 0;
+ auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ for (auto subnet_id : ids) {
+ erased += index.erase(subnet_id);
+ }
+ return (erased);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteSharedNetworkSubnets6(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name) {
+ uint64_t cnt = 0;
+ for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ) {
+ // Skip subnets which do not match the server selector.
+ if (server_selector.amUnassigned() &&
+ !(*subnet)->getServerTags().empty()) {
+ ++subnet;
+ continue;
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*subnet)->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !(*subnet)->hasAllServerTag()) {
+ ++subnet;
+ continue;
+ }
+ }
+
+ SharedNetwork6Ptr network;
+ (*subnet)->getSharedNetwork(network);
+ if (network && (network->getName() == shared_network_name)) {
+ network->del((*subnet)->getID());
+ }
+
+ if ((network && (network->getName() == shared_network_name)) ||
+ ((*subnet)->getSharedNetworkName() == shared_network_name)) {
+ subnet = subnets_.erase(subnet);
+ ++cnt;
+ } else {
+ ++subnet;
+ }
+ }
+ return (cnt);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteSharedNetwork6(const db::ServerSelector& server_selector,
+ const std::string& name) {
+ auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ auto network_it = index.find(name);
+ if (network_it == index.end()) {
+ return (0);
+ }
+ if ((server_selector.amUnassigned()) &&
+ !(*network_it)->getServerTags().empty()) {
+ return (0);
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if ((*network_it)->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !(*network_it)->hasAllServerTag()) {
+ return (0);
+ }
+ }
+
+ // Remove this shared network.
+ for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
+ if ((*subnet)->getSharedNetworkName() == name) {
+ (*subnet)->setSharedNetworkName("");
+ }
+ }
+ (*network_it)->delAll();
+ return (index.erase(name));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllSharedNetworks6(const db::ServerSelector& server_selector) {
+ // Collect shared network to remove.
+ std::list<std::string> names;
+ for (auto shared_network : shared_networks_) {
+ if (server_selector.amAny()) {
+ names.push_back(shared_network->getName());
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (shared_network->getServerTags().empty()) {
+ names.push_back(shared_network->getName());
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (shared_network->hasServerTag(ServerTag(tag))) {
+ names.push_back(shared_network->getName());
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (shared_network->hasAllServerTag()) {
+ names.push_back(shared_network->getName());
+ }
+ }
+
+ // Erase shared networks.
+ uint64_t erased = 0;
+ auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ for (auto name : names) {
+ erased += index.erase(name);
+ }
+ return (erased);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOptionDef6(const db::ServerSelector& server_selector,
+ const uint16_t code,
+ const std::string& space) {
+ auto tag = getServerTag(server_selector);
+ uint64_t erased = 0;
+ for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
+ if (((*option_def_it)->getCode() == code) &&
+ ((*option_def_it)->getOptionSpaceName() == space) &&
+ ((*option_def_it)->hasServerTag(ServerTag(tag)))) {
+ option_def_it = option_defs_.erase(option_def_it);
+ ++erased;
+ } else {
+ ++option_def_it;
+ }
+ }
+ return (erased);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllOptionDefs6(const db::ServerSelector& server_selector) {
+ auto tag = getServerTag(server_selector);
+ uint64_t erased = 0;
+ for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
+ if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
+ option_def_it = option_defs_.erase(option_def_it);
+ ++erased;
+ } else {
+ ++option_def_it;
+ }
+ }
+ return (erased);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
+ const uint16_t code,
+ const std::string& space) {
+ auto tag = getServerTag(server_selector);
+ uint64_t erased = 0;
+ for (auto option_it = options_.begin(); option_it != options_.end(); ) {
+ if ((option_it->option_->getType() == code) &&
+ (option_it->space_name_ == space) &&
+ (option_it->hasServerTag(ServerTag(tag)))) {
+ option_it = options_.erase(option_it);
+ ++erased;
+ } else {
+ ++option_it;
+ }
+ }
+ return (erased);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
+ const std::string& shared_network_name,
+ const uint16_t code,
+ const std::string& space) {
+ auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
+ auto network_it = index.find(shared_network_name);
+
+ if (network_it == index.end()) {
+ isc_throw(BadValue, "attempted to delete an option in a non existing "
+ "shared network " << shared_network_name);
+ }
+
+ auto shared_network = *network_it;
+ bool found = false;
+ if (server_selector.amUnassigned()) {
+ if (shared_network->getServerTags().empty()) {
+ found = true;
+ }
+ } else if (server_selector.amAny()) {
+ found = true;
+ } else if (shared_network->hasAllServerTag()) {
+ found = true;
+ } else {
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (shared_network->hasServerTag(ServerTag(tag))) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ isc_throw(BadValue, "attempted to delete option in a "
+ "shared network " << shared_network_name
+ << " not present in a selected server");
+ }
+
+ return (shared_network->getCfgOption()->del(space, code));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id,
+ const uint16_t code,
+ const std::string& space) {
+ auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
+ auto subnet_it = index.find(subnet_id);
+
+ if (subnet_it == index.cend()) {
+ isc_throw(BadValue, "attempted to delete an option in a non existing "
+ "subnet ID " << subnet_id);
+ }
+
+ auto subnet = *subnet_it;
+ bool found = false;
+ if (server_selector.amUnassigned()) {
+ if (subnet->getServerTags().empty()) {
+ found = true;
+ }
+ } else if (server_selector.amAny()) {
+ found = true;
+ } else if (subnet->hasAllServerTag()) {
+ found = true;
+ } else {
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ found = true;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ isc_throw(BadValue, "attempted to delete option in a "
+ "subnet ID " << subnet_id
+ << " not present in a selected server");
+ }
+
+ return (subnet->getCfgOption()->del(space, code));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
+ const asiolink::IOAddress& pool_start_address,
+ const asiolink::IOAddress& pool_end_address,
+ const uint16_t code,
+ const std::string& space) {
+ auto not_in_selected_servers = false;
+ for (auto subnet : subnets_) {
+ // Get the pool: if it is not here we can directly go to the next subnet.
+
+ auto pool = subnet->getPool(Lease::TYPE_NA, pool_start_address);
+ if (!pool) {
+ continue;
+ }
+
+ // Verify the subnet is in a selected server.
+ if (server_selector.amUnassigned()) {
+ if (!subnet->getServerTags().empty()) {
+ not_in_selected_servers = true;
+ continue;
+ }
+ } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
+ auto in_tags = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ in_tags = true;
+ break;
+ }
+ }
+ if (!in_tags) {
+ // Records the fact a subnet was found but not in a server.
+ not_in_selected_servers = true;
+ continue;
+ }
+ }
+
+ return (pool->getCfgOption()->del(space, code));
+ }
+
+ if (not_in_selected_servers) {
+ isc_throw(BadValue, "attempted to delete an option in a pool "
+ << pool_start_address << " - " << pool_end_address
+ << " not present in a selected server");
+ } else {
+ isc_throw(BadValue, "attempted to delete an option in a non existing "
+ "pool " << pool_start_address << " - " << pool_end_address);
+ }
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
+ const asiolink::IOAddress& pd_pool_prefix,
+ const uint8_t pd_pool_prefix_length,
+ const uint16_t code,
+ const std::string& space) {
+ auto not_in_selected_servers = false;
+ for (auto subnet : subnets_) {
+ // Get the pd pool: if it is not here we can directly go to the next subnet.
+ auto pdpool = subnet->getPool(Lease::TYPE_PD, pd_pool_prefix);
+ if (!pdpool) {
+ continue;
+ }
+
+ // Verify the subnet is in a selected server.
+ if (server_selector.amUnassigned()) {
+ if (!subnet->getServerTags().empty()) {
+ not_in_selected_servers = true;
+ continue;
+ }
+ } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
+ auto in_tags = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (subnet->hasServerTag(ServerTag(tag))) {
+ in_tags = true;
+ break;
+ }
+ }
+ if (!in_tags) {
+ // Records the fact a subnet was found but not in a server.
+ not_in_selected_servers = true;
+ continue;
+ }
+ }
+
+ return (pdpool->getCfgOption()->del(space, code));
+ }
+
+ if (not_in_selected_servers) {
+ isc_throw(BadValue, "attempted to delete an option in "
+ "a prefix pool " << pd_pool_prefix
+ << "/" << static_cast<unsigned>(pd_pool_prefix_length)
+ << " not present in a selected server");
+ } else {
+ isc_throw(BadValue, "attempted to delete an option in "
+ "a non existing prefix pool " << pd_pool_prefix
+ << "/" << static_cast<unsigned>(pd_pool_prefix_length));
+ }
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteGlobalParameter6(const db::ServerSelector& server_selector,
+ const std::string& name) {
+ auto tag = getServerTag(server_selector);
+ auto& index = globals_.get<StampedValueNameIndexTag>();
+ auto global_it_pair = index.equal_range(name);
+
+ for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
+ ++global_it) {
+ auto value = *global_it;
+ if (value->hasServerTag(ServerTag(tag))) {
+ index.erase(global_it);
+ return (1);
+ }
+ }
+ return (0);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllGlobalParameters6(const db::ServerSelector& server_selector) {
+ auto tag = getServerTag(server_selector);
+ uint64_t cnt = 0;
+ for (auto global_it = globals_.begin(); global_it != globals_.end(); ) {
+ auto value = *global_it;
+ if (value->hasServerTag(ServerTag(tag))) {
+ global_it = globals_.erase(global_it);
+ cnt++;
+ } else {
+ ++global_it;
+ }
+ }
+ return (cnt);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteClientClass6(const db::ServerSelector& server_selector,
+ const std::string& name) {
+ ClientClassDefPtr existing_class;
+ auto c = classes_.begin();
+ for (; c != classes_.end(); ++c) {
+ if ((*c)->getName() == name) {
+ existing_class = (*c);
+ break;
+ }
+ }
+ if (!existing_class) {
+ return (0);
+ }
+ if ((server_selector.amUnassigned()) &&
+ !existing_class->getServerTags().empty()) {
+ return (0);
+ }
+ if (!server_selector.amAny()) {
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (existing_class->hasServerTag(ServerTag(tag))) {
+ got = true;
+ break;
+ }
+ }
+ if (!got && !existing_class->hasAllServerTag()) {
+ return (0);
+ }
+ }
+ classes_.erase(c);
+ return (1);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllClientClasses6(const db::ServerSelector& server_selector) {
+ uint64_t count = 0;
+ for (auto c = classes_.begin(); c != classes_.end(); ++c) {
+ auto client_class = *c;
+ if (server_selector.amAny()) {
+ c = classes_.erase(c);
+ ++count;
+ continue;
+ }
+ if (server_selector.amUnassigned()) {
+ if (client_class->getServerTags().empty()) {
+ c = classes_.erase(c);
+ ++count;
+ }
+ continue;
+ }
+ bool got = false;
+ auto tags = server_selector.getTags();
+ for (auto tag : tags) {
+ if (client_class->hasServerTag(ServerTag(tag))) {
+ c = classes_.erase(c);
+ ++count;
+ got = true;
+ break;
+ }
+ }
+ if (got) {
+ continue;
+ }
+ if (client_class->hasAllServerTag()) {
+ c = classes_.erase(c);
+ ++count;
+ }
+ }
+
+ return (count);
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteServer6(const ServerTag& server_tag) {
+ auto& index = servers_.get<ServerTagIndexTag>();
+ return (index.erase(server_tag.get()));
+}
+
+uint64_t
+TestConfigBackendDHCPv6::deleteAllServers6() {
+ auto servers_size = servers_.size();
+ servers_.clear();
+ return (servers_size);
+}
+
+} // namespace test
+} // namespace dhcp
+} // namespace isc