In order to support this construct, Kea uses the option's ``client-classes``
list in addition to code and space to uniquely identifiy each option. This
is important to keep in mind when using the Management API to alter your
-configuration. As of Kea 3.1 (applies to DHCPv4 commands only), commands which
-get, set, or delete an individual option now accept an optional ``client-classes``
-parameter in addition to ``code`` and ``space`` parameters.
+configuration. As of Kea 3.1.1 commands which get, set, or delete an
+individual option now accept an optional ``client-classes`` parameter in
+addition to ``code`` and ``space`` parameters.
If the ``client-classes`` parameter is omitted:
These commands are used to delete a global DHCP option from the
database. The option is identified by an option code and option space.
-As of Kea 3.1, an optional ``client-classes`` parameter may also be
+As of Kea 3.1.1 an optional ``client-classes`` parameter may also be
specified (see :ref:`cb-cmds-option-class-tags-as-keys`).
For example:
The option is identified by the code and option space. The top-level
option spaces where DHCP standard options belong are called "dhcp4" and
"dhcp6" for the DHCPv4 and DHCPv6 servers, respectively.
-As of Kea 3.1, an optional ``client-classes`` parameter may also be
+As of Kea 3.1.1, an optional ``client-classes`` parameter may also be
specified (see :ref:`cb-cmds-option-class-tags-as-keys`).
The following command retrieves the IPv6 "DNS Servers" (code 23) option
These commands are used to delete a shared-network-specific DHCP
option from the database. The option is identified by an option code
-and option space and as of Kea 3.1, an optional ``client-classes``
+and option space and as of Kea 3.1.1, an optional ``client-classes``
parameter may also be specified (see :ref:`cb-cmds-option-class-tags-as-keys`).
These parameters are passed within the ``options`` list.
Another list, ``shared-networks``, contains a map
These commands are used to delete an address-pool-specific DHCP
option from the database. The option is identified by an option code
-and option space, and as of Kea 3.1, an optional ``client-classes`` parameter
+and option space, and as of Kea 3.1.1, an optional ``client-classes`` parameter
may also be specified (see :ref:`cb-cmds-option-class-tags-as-keys`).
These parameters are passed within the ``options`` list.
Another list, ``pools``, contains a map with the
These commands are used to delete a subnet-specific DHCP option
from the database. The option is identified by an option code
-and option space, and, as of Kea 3.1, an optional ``client-casses``
+and option space, and, as of Kea 3.1.1, an optional ``client-casses``
parameter (see :ref:`cb-cmds-option-class-tags-as-keys`).
These parameters are passed within the ``options`` list.
Another list, ``subnets``, contains a map with the
MySqlBinding::createNull(),
MySqlBinding::createString(tag),
MySqlBinding::createInteger<uint8_t>(option->option_->getType()),
- MySqlBinding::condCreateString(option->space_name_)
+ MySqlBinding::condCreateString(option->space_name_),
+ createInputClientClassesBinding(option->client_classes_)
};
MySqlTransaction transaction(conn_);
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6,
in_bindings) == 0) {
- // Remove the 3 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 3);
+ // Remove the 4 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 4);
insertOption6(server_selector, in_bindings);
}
MySqlBinding::createNull(),
MySqlBinding::createInteger<uint32_t>(static_cast<uint32_t>(subnet_id)),
MySqlBinding::createInteger<uint16_t>(option->option_->getType()),
- MySqlBinding::condCreateString(option->space_name_)
+ MySqlBinding::condCreateString(option->space_name_),
+ createInputClientClassesBinding(option->client_classes_)
};
boost::scoped_ptr<MySqlTransaction> transaction;
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SUBNET_ID,
in_bindings) == 0) {
- // Remove the 3 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 3);
+ // Remove the 4 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 4);
insertOption6(server_selector, in_bindings);
}
in_bindings.push_back(MySqlBinding::createInteger<uint64_t>(pool_id));
in_bindings.push_back(MySqlBinding::createInteger<uint16_t>(option->option_->getType()));
in_bindings.push_back(MySqlBinding::condCreateString(option->space_name_));
+ in_bindings.push_back(createInputClientClassesBinding(option->client_classes_));
MySqlTransaction transaction(conn_);
MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_POOL_ID :
MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_PD_POOL_ID);
if (conn_.updateDeleteQuery(index, in_bindings) == 0) {
- // Remove the 3 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 3);
+ // Remove the 4 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 4);
insertOption6(server_selector, in_bindings);
}
MySqlBinding::createNull(),
MySqlBinding::createString(shared_network_name),
MySqlBinding::createInteger<uint16_t>(option->option_->getType()),
- MySqlBinding::condCreateString(option->space_name_)
+ MySqlBinding::condCreateString(option->space_name_),
+ createInputClientClassesBinding(option->client_classes_)
};
boost::scoped_ptr<MySqlTransaction> transaction;
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::
UPDATE_OPTION6_SHARED_NETWORK,
in_bindings) == 0) {
- // Remove the 3 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 3);
+ // Remove the 4 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 4);
insertOption6(server_selector, in_bindings);
}
MySqlBinding::createNull(),
MySqlBinding::createString(client_class->getName()),
MySqlBinding::createInteger<uint8_t>(option->option_->getType()),
- MySqlBinding::condCreateString(option->space_name_)
+ MySqlBinding::condCreateString(option->space_name_),
+ createInputClientClassesBinding(option->client_classes_)
};
// Create scoped audit revision. As long as this instance exists
if (conn_.updateDeleteQuery(MySqlConfigBackendDHCPv6Impl::
UPDATE_OPTION6_CLIENT_CLASS,
in_bindings) == 0) {
- // Remove the 3 bindings used only in case of update.
- in_bindings.resize(in_bindings.size() - 3);
+ // Remove the 4 bindings used only in case of update.
+ in_bindings.resize(in_bindings.size() - 4);
insertOption6(server_selector, in_bindings);
}
}
/// @param server_selector Server selector.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint16_t>(code),
- MySqlBinding::createString(space)
+ MySqlBinding::createString(space),
+ createClientClassesForWhereClause(client_classes)
};
// Run DELETE.
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const ServerSelector& server_selector,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint32_t>(static_cast<uint32_t>(subnet_id)),
MySqlBinding::createInteger<uint16_t>(code),
- MySqlBinding::createString(space)
+ MySqlBinding::createString(space),
+ createClientClassesForWhereClause(client_classes)
};
// Run DELETE.
/// @param pool_end_address Upper bound pool address.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const db::ServerSelector& server_selector,
const IOAddress& pool_start_address,
const IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint16_t>(code),
MySqlBinding::createString(space),
+ createClientClassesForWhereClause(client_classes),
MySqlBinding::createString(pool_start_address.toText()),
MySqlBinding::createString(pool_end_address.toText())
};
/// @param pd_pool_prefix_length Length of the pd pool prefix.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t 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) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createInteger<uint16_t>(code),
MySqlBinding::createString(space),
+ createClientClassesForWhereClause(client_classes),
MySqlBinding::createString(pd_pool_prefix.toText()),
MySqlBinding::createInteger<uint8_t>(pd_pool_prefix_length)
};
/// option belongs to
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
MySqlBindingCollection in_bindings = {
MySqlBinding::createString(shared_network_name),
MySqlBinding::createInteger<uint16_t>(code),
- MySqlBinding::createString(space)
+ MySqlBinding::createString(space),
+ createClientClassesForWhereClause(client_classes)
};
// Run DELETE.
MYSQL_GET_OPTION_DEF(dhcp6, AND d.modification_ts >= ?)
},
- // Retrieves global option by code and space.
+ // Retrieves global option by code, space and client-classes.
{ MySqlConfigBackendDHCPv6Impl::GET_OPTION6_CODE_SPACE,
- MYSQL_GET_OPTION6(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_GET_OPTION6(AND o.scope_id = 0 AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Retrieves all global options.
// Update existing global option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6,
- MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 0 AND o.code = ? AND o.space = ?
+ AND o.client_classes = ?)
},
// Update existing subnet level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SUBNET_ID,
- MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?
+ AND o.client_classes = ?)
},
// Update existing pool level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_POOL_ID,
- MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 5 AND o.pool_id = ? AND o.code = ? AND o.space = ?
+ AND o.client_classes = ?)
},
// Update existing pd pool level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_PD_POOL_ID,
- MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 6 AND o.pd_pool_id = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 6 AND o.pd_pool_id = ? AND o.code = ? AND o.space = ?
+ AND o.client_classes = ?)
},
// Update existing shared network level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SHARED_NETWORK,
- MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ?
+ AND o.space = ? AND o.client_classes = ?)
},
// Update existing client class level option.
{ MySqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_CLIENT_CLASS,
- MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 2 AND o.dhcp_client_class = ? AND o.code = ? AND o.space = ?)
+ MYSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 2 AND o.dhcp_client_class = ? AND o.code = ?
+ AND o.space = ? AND o.client_classes = ?)
},
// Update existing client class with specifying its position.
// Delete single global option.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6,
- MYSQL_DELETE_OPTION_WITH_TAG(dhcp6, AND o.scope_id = 0 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_WITH_TAG(dhcp6, AND o.scope_id = 0 AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Delete all global options which are unassigned to any servers.
// Delete single option from a subnet.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SUBNET_ID,
MYSQL_DELETE_OPTION_NO_TAG(dhcp6,
- WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?)
+ WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = ? AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Delete single option from a pool.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_POOL_RANGE,
- MYSQL_DELETE_OPTION_POOL_RANGE(dhcp6, o.scope_id = 5 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_POOL_RANGE(dhcp6, o.scope_id = 5 AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Delete single option from a pd pool.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_PD_POOL,
- MYSQL_DELETE_OPTION_PD_POOL(o.scope_id = 6 AND o.code = ? AND o.space = ?)
+ MYSQL_DELETE_OPTION_PD_POOL(o.scope_id = 6 AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Delete single option from a shared network.
{ MySqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SHARED_NETWORK,
MYSQL_DELETE_OPTION_NO_TAG(dhcp6,
- WHERE o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?)
+ WHERE o.scope_id = 4 AND o.shared_network_name = ? AND o.code = ? AND o.space = ?
+ AND o.client_classes LIKE ?)
},
// Delete options belonging to a subnet.
OptionDescriptorPtr
MySqlConfigBackendDHCPv6::getOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) const {
+ const std::string& space,
+ const ClientClassesPtr client_classes) const {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_GET_OPTION6)
.arg(code).arg(space);
return (impl_->getOption(MySqlConfigBackendDHCPv6Impl::GET_OPTION6_CODE_SPACE,
- Option::V6, server_selector, code, space));
+ Option::V6, server_selector, code, space, client_classes));
}
OptionContainer
uint64_t
MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_OPTION6)
.arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, code, space);
+ uint64_t result = impl_->deleteOption6(server_selector, code, space, client_classes);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_OPTION6_RESULT)
.arg(result);
return (result);
MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION6)
.arg(shared_network_name).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), shared_network_name,
- code, space);
+ code, space, client_classes);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_SHARED_NETWORK_OPTION6_RESULT)
.arg(result);
return (result);
MySqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION6)
.arg(subnet_id).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), subnet_id, code, space);
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), subnet_id, code, space,
+ client_classes);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_SUBNET_ID_OPTION6_RESULT)
.arg(result);
return (result);
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION6)
.arg(pool_start_address.toText()).arg(pool_end_address.toText()).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pool_start_address,
- pool_end_address, code, space);
+ pool_end_address, code, space, client_classes);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_OPTION6_RESULT)
.arg(result);
return (result);
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6)
.arg(pd_pool_prefix.toText()).arg(pd_pool_prefix_length).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pd_pool_prefix,
- pd_pool_prefix_length, code, space);
+ pd_pool_prefix_length, code, space, client_classes);
LOG_DEBUG(mysql_cb_logger, DBGLVL_TRACE_BASIC, MYSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6_RESULT)
.arg(result);
return (result);
/// @brief Retrieves single option by code and space.
///
/// @param server_selector Server selector.
+ /// @param code code of the option to be deleted.
+ /// @param space option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
/// @throw NotImplemented if server selector is "unassigned".
virtual OptionDescriptorPtr
getOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space) const;
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr()) const;
/// @brief Retrieves all global options.
///
/// @param server_selector Server selector.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes shared network level option.
///
/// option belongs to
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
+ /// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes subnet level option.
///
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
- deleteOption6(const db::ServerSelector& server_selector, const SubnetID& subnet_id,
- const uint16_t code, const std::string& space);
+ deleteOption6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id,
+ const uint16_t code,
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pool level option.
///
/// deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes prefix delegation pool level option.
///
/// delegation pool to which the deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes global parameter.
///
in_bindings.push_back(MySqlBinding::createInteger<uint16_t>(code));
}
in_bindings.push_back(MySqlBinding::createString(space));
+ in_bindings.push_back(createClientClassesForWhereClause(client_classes));
- /// @todo TKM Remove the if when v6 is ready.
- if (universe == Option::V4) {
- in_bindings.push_back(createClientClassesForWhereClause(client_classes));
- }
getOptions(index, in_bindings, universe, options);
return (options.empty() ? OptionDescriptorPtr() :
OptionDescriptor::create(*options.begin()));
getModifiedOptionDefs6Test();
}
+TEST_F(MySqlConfigBackendDHCPv6Test, globalOption6WithClientClassesTest) {
+ globalOption6WithClientClassesTest();
+}
+
+TEST_F(MySqlConfigBackendDHCPv6Test, getAllOptions6WithClientClassesTest) {
+ getAllOptions6WithClientClassesTest();
+}
+
TEST_F(MySqlConfigBackendDHCPv6Test, createUpdateDeleteOption6Test) {
createUpdateDeleteOption6Test();
}
multipleAuditEntriesTest();
}
+TEST_F(MySqlConfigBackendDHCPv6Test, sharedNetworkOption6WithClientClassesTest) {
+ sharedNetworkOption6WithClientClassesTest();
+}
+
+TEST_F(MySqlConfigBackendDHCPv6Test, subnetOption6WithClientClassesTest) {
+ subnetOption6WithClientClassesTest();
+}
+
+TEST_F(MySqlConfigBackendDHCPv6Test, poolOption6WithClientClassesTest) {
+ poolOption6WithClientClassesTest();
+}
+
+TEST_F(MySqlConfigBackendDHCPv6Test, pdPoolOption6WithClientClassesTest) {
+ pdPoolOption6WithClientClassesTest();
+}
+
/// @brief Test fixture for verifying database connection loss-recovery
/// behavior.
class MySqlConfigBackendDHCPv6DbLostCallbackTest : public GenericConfigBackendDbLostCallbackTest {
in_bindings.add(tag);
in_bindings.add(option->option_->getType());
in_bindings.addOptional(option->space_name_);
+ addClientClassesBinding(in_bindings, option->client_classes_);
// Start transaction.
PgSqlTransaction transaction(conn_);
in_bindings.add(subnet_id);
in_bindings.add(option->option_->getType());
in_bindings.addOptional(option->space_name_);
+ addClientClassesBinding(in_bindings, option->client_classes_);
// Start transaction.
PgSqlTransaction transaction(conn_);
in_bindings.add(pool_id);
in_bindings.add(option->option_->getType());
in_bindings.addOptional(option->space_name_);
+ addClientClassesBinding(in_bindings, option->client_classes_);
// Start transaction.
PgSqlTransaction transaction(conn_);
in_bindings.add(shared_network_name);
in_bindings.add(option->option_->getType());
in_bindings.addOptional(option->space_name_);
+ addClientClassesBinding(in_bindings, option->client_classes_);
// Start transaction.
PgSqlTransaction transaction(conn_);
in_bindings.add(class_name);
in_bindings.add(option->option_->getType());
in_bindings.addOptional(option->space_name_);
+ addClientClassesBinding(in_bindings, option->client_classes_);
// Create scoped audit revision. As long as this instance exists
// no new audit revisions are created in any subsequent calls.
/// @param server_selector Server selector.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
PsqlBindArray in_bindings;
in_bindings.add(code);
in_bindings.add(space);
+ addClientClassesForWhereClause(in_bindings, client_classes);
// Run DELETE.
return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6,
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const ServerSelector& server_selector,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
PsqlBindArray in_bindings;
in_bindings.add(subnet_id);
in_bindings.add(code);
in_bindings.add(space);
+ addClientClassesForWhereClause(in_bindings, client_classes);
// Run DELETE.
return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SUBNET_ID,
/// @param pool_end_address Upper bound pool address.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const db::ServerSelector& server_selector,
const IOAddress& pool_start_address,
const IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
PsqlBindArray in_bindings;
in_bindings.addInet6(pool_start_address);
in_bindings.addInet6(pool_end_address);
in_bindings.add(code);
in_bindings.add(space);
+ addClientClassesForWhereClause(in_bindings, client_classes);
// Run DELETE.
return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_POOL_RANGE,
/// @param pd_pool_prefix_length Length of the pd pool prefix.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t 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) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
PsqlBindArray in_bindings;
in_bindings.addTempString(pd_pool_prefix.toText());
in_bindings.add(pd_pool_prefix_length);
in_bindings.add(code);
in_bindings.add(space);
+ addClientClassesForWhereClause(in_bindings, client_classes);
// Run DELETE.
return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_PD_POOL,
/// option belongs to
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
/// @return Number of deleted options.
uint64_t deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
PsqlBindArray in_bindings;
in_bindings.add(shared_network_name);
in_bindings.add(code);
in_bindings.add(space);
+ addClientClassesForWhereClause(in_bindings, client_classes);
// Run DELETE.
return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SHARED_NETWORK,
// Retrieves global option by code and space.
{
// PgSqlConfigBackendDHCPv6Impl::GET_OPTION6_CODE_SPACE,
- 3,
+ 4,
{
OID_VARCHAR, // 1 server_tag
OID_INT2, // 2 code
- OID_VARCHAR // 3 space
+ OID_VARCHAR, // 3 space
+ OID_TEXT // 4 client_classes
},
"GET_OPTION6_CODE_SPACE",
- PGSQL_GET_OPTION6(AND o.scope_id = 0 AND o.code = $2 AND o.space = $3)
+ PGSQL_GET_OPTION6(AND o.scope_id = 0 AND o.code = $2 AND o.space = $3
+ AND o.client_classes LIKE $4)
},
// Retrieves all global options.
// Update existing global option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_VARCHAR, // 16 server_tag
OID_INT2, // 17 code (of option to update)
OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6",
- PGSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 0 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_WITH_TAG(AND o.scope_id = 0 AND o.code = $17 AND o.space = $18
+ AND o.client_classes = $19)
},
// Update existing subnet level option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SUBNET_ID,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_INT8, // 15 pd_pool_id
OID_INT8, // 16 subnet_id (of option to update)
OID_INT2, // 17 code (of option to update)
- OID_VARCHAR // 18 space (of option to update)
+ OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6_SUBNET_ID",
- PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 1 AND o.dhcp6_subnet_id = $16 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 1 AND o.dhcp6_subnet_id = $16 AND o.code = $17
+ AND o.space = $18 AND o.client_classes = $19)
},
// Update existing pool level option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_POOL_ID,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_INT8, // 15 pd_pool_id
OID_INT8, // 16 pool_id (of option to update)
OID_INT2, // 17 code (of option to update)
- OID_VARCHAR // 18 space (of option to update)
+ OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6_POOL_ID",
- PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 5 AND o.pool_id = $16 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 5 AND o.pool_id = $16 AND o.code = $17
+ AND o.space = $18 AND o.client_classes = $19)
},
// Update existing pd pool level option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_PD_POOL_ID,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_INT8, // 15 pd_pool_id
OID_INT8, // 16 pd_pool_id (of option to update)
OID_INT2, // 17 code (of option to update)
- OID_VARCHAR // 18 space (of option to update)
+ OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6_PD_POOL_ID",
- PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 6 AND o.pd_pool_id = $16 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 6 AND o.pd_pool_id = $16 AND o.code = $17
+ AND o.space = $18 AND o.client_classes = $19)
},
// Update existing shared network level option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_SHARED_NETWORK,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_INT8, // 15 pd_pool_id
OID_VARCHAR, // 16 shared_network_name (of option to update)
OID_INT2, // 17 code (of option to update)
- OID_VARCHAR // 18 space (of option to update)
+ OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6_SHARED_NETWORK",
- PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 4 AND o.shared_network_name = $16 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 4 AND o.shared_network_name = $16 AND o.code = $17
+ AND o.space = $18 AND o.client_classes = $19)
},
// Update existing client class level option.
{
// PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6_CLIENT_CLASS,
- 18,
+ 19,
{
OID_INT2, // 1 code
OID_BYTEA, // 2 value
OID_INT8, // 15 pd_pool_id
OID_VARCHAR, // 16 client_class (of option to update)
OID_INT2, // 17 code (of option to update)
- OID_VARCHAR // 18 space (of option to update)
+ OID_VARCHAR, // 18 space (of option to update)
+ OID_TEXT // 19 client_classes (of option to update)
},
"UPDATE_OPTION6_CLIENT_CLASS",
- PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 2 AND o.dhcp_client_class = $16 AND o.code = $17 AND o.space = $18)
+ PGSQL_UPDATE_OPTION6_NO_TAG(o.scope_id = 2 AND o.dhcp_client_class = $16 AND o.code = $17
+ AND o.space = $18 AND o.client_classes = $19)
},
// Update existing client class with specifying its position.
// Delete single global option.
{
// PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6,
- 3,
+ 4,
{
OID_VARCHAR, // 1 server_tag
OID_INT2, // 2 code
- OID_VARCHAR // 3 space
+ OID_VARCHAR, // 3 space
+ OID_TEXT // 4 client_classes
},
"DELETE_OPTION6",
- PGSQL_DELETE_OPTION_WITH_TAG(dhcp6, AND o.scope_id = 0 AND o.code = $2 AND o.space = $3)
+ PGSQL_DELETE_OPTION_WITH_TAG(dhcp6, AND o.scope_id = 0 AND o.code = $2 AND o.space = $3
+ AND o.client_classes LIKE $4)
},
// Delete all global options which are unassigned to any servers.
// Delete single option from a subnet.
{
// PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SUBNET_ID,
- 3,
+ 4,
{
- OID_INT8, // 1 subnet_id
- OID_INT2, // 2 code
- OID_VARCHAR // 3 space
+ OID_INT8, // 1 subnet_id
+ OID_INT2, // 2 code
+ OID_VARCHAR, // 3 space
+ OID_TEXT // 4 client_classes
},
"DELETE_OPTION6_SUBNET_ID",
PGSQL_DELETE_OPTION_NO_TAG(dhcp6,
- WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = $1 AND o.code = $2 AND o.space = $3)
+ WHERE o.scope_id = 1 AND o.dhcp6_subnet_id = $1 AND o.code = $2 AND o.space = $3
+ AND o.client_classes LIKE $4)
},
// Delete single option from a pool.
{
// PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_POOL_RANGE,
- 4,
+ 5,
{
- OID_TEXT, // 1 start_address - cast as inet
- OID_TEXT, // 2 start_address - cast as inet
- OID_INT2, // 3 code
- OID_VARCHAR // 4 space
+ OID_TEXT, // 1 start_address - cast as inet
+ OID_TEXT, // 2 start_address - cast as inet
+ OID_INT2, // 3 code
+ OID_VARCHAR, // 4 space
+ OID_TEXT // 5 client_classes
},
"DELETE_OPTION6_POOL_RANGE",
- PGSQL_DELETE_OPTION_POOL_RANGE(dhcp6, o.scope_id = 5 AND o.code = $3 AND o.space = $4)
+ PGSQL_DELETE_OPTION_POOL_RANGE(dhcp6, o.scope_id = 5 AND o.code = $3 AND o.space = $4
+ AND o.client_classes LIKE $5)
},
// Delete single option from a pd pool.
{
// PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_PD_POOL,
- 4,
+ 5,
{
- OID_TEXT, // 1 prefix
- OID_INT2, // 2 prefix_length
- OID_INT2, // 3 code
- OID_VARCHAR // 4 space
+ OID_TEXT, // 1 prefix
+ OID_INT2, // 2 prefix_length
+ OID_INT2, // 3 code
+ OID_VARCHAR, // 4 space
+ OID_TEXT // 5 client_classes
},
"DELETE_OPTION6_PD_POOL",
- PGSQL_DELETE_OPTION_PD_POOL(o.scope_id = 6 AND o.code = $3 AND o.space = $4)
+ PGSQL_DELETE_OPTION_PD_POOL(o.scope_id = 6 AND o.code = $3 AND o.space = $4
+ AND o.client_classes LIKE $5)
},
// Delete single option from a shared network.
{
// PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6_SHARED_NETWORK,
- 3,
+ 4,
{
OID_VARCHAR, // 1 shared_network_name
OID_INT2, // 2 code
- OID_VARCHAR // 3 space
+ OID_VARCHAR, // 3 space
+ OID_TEXT // 4 client_classes
},
"DELETE_OPTION6_SHARED_NETWORK",
PGSQL_DELETE_OPTION_NO_TAG(dhcp6,
- WHERE o.scope_id = 4 AND o.shared_network_name = $1 AND o.code = $2 AND o.space = $3)
+ WHERE o.scope_id = 4 AND o.shared_network_name = $1 AND o.code = $2 AND o.space = $3
+ AND o.client_classes LIKE $4)
},
// Delete options belonging to a subnet.
OptionDescriptorPtr
PgSqlConfigBackendDHCPv6::getOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) const {
+ const std::string& space,
+ const ClientClassesPtr client_classes) const {
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_GET_OPTION6)
.arg(code).arg(space);
return (impl_->getOption(PgSqlConfigBackendDHCPv6Impl::GET_OPTION6_CODE_SPACE,
- Option::V6, server_selector, code, space));
+ Option::V6, server_selector, code, space, client_classes));
}
OptionContainer
uint64_t
PgSqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_OPTION6)
.arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(server_selector, code, space);
+ uint64_t result = impl_->deleteOption6(server_selector, code, space, client_classes);
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_OPTION6_RESULT)
.arg(result);
return (result);
PgSqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_SHARED_NETWORK_OPTION6)
.arg(shared_network_name).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), shared_network_name,
- code, space);
+ code, space, client_classes);
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_SHARED_NETWORK_OPTION6_RESULT)
.arg(result);
return (result);
PgSqlConfigBackendDHCPv6::deleteOption6(const ServerSelector& /* server_selector */,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_SUBNET_ID_OPTION6)
.arg(subnet_id).arg(code).arg(space);
- uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), subnet_id, code, space);
+ uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), subnet_id, code, space,
+ client_classes);
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_SUBNET_ID_OPTION6_RESULT)
.arg(result);
return (result);
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
/// @todo In the future we might use the server selector to make sure that the
/// option is only deleted if the pool belongs to a given server. For now, we
/// just delete it when there is a match with the parent object.
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_POOL_OPTION6)
.arg(pool_start_address.toText()).arg(pool_end_address.toText()).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pool_start_address,
- pool_end_address, code, space);
+ pool_end_address, code, space, client_classes);
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_POOL_OPTION6_RESULT)
.arg(result);
return (result);
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6)
.arg(pd_pool_prefix.toText()).arg(pd_pool_prefix_length).arg(code).arg(space);
uint64_t result = impl_->deleteOption6(ServerSelector::ANY(), pd_pool_prefix,
- pd_pool_prefix_length, code, space);
+ pd_pool_prefix_length, code, space, client_classes);
LOG_DEBUG(pgsql_cb_logger, DBGLVL_TRACE_BASIC, PGSQL_CB_DELETE_BY_POOL_PREFIX_OPTION6_RESULT)
.arg(result);
return (result);
/// @brief Retrieves single option by code and space.
///
/// @param server_selector Server selector.
+ /// @param code Code of the option to be deleted.
+ /// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
/// @throw NotImplemented if server selector is "unassigned".
virtual OptionDescriptorPtr
getOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space) const;
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr()) const;
/// @brief Retrieves all global options.
///
/// @param server_selector Server selector.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes shared network level option.
///
/// option belongs to
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
+ /// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes subnet level option.
///
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector, const SubnetID& subnet_id,
- const uint16_t code, const std::string& space);
+ const uint16_t code, const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pool level option.
///
/// deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes prefix delegation pool level option.
///
/// delegation pool to which the deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
/// @throw NotImplemented if server selector is "unassigned".
virtual uint64_t
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes global parameter.
///
in_bindings.add(tag);
in_bindings.add(code);
in_bindings.add(space);
- /// @todo TKM remove if when v6 is ready.
- if (universe == Option::V4) {
- addClientClassesForWhereClause(in_bindings, client_classes);
- }
+ addClientClassesForWhereClause(in_bindings, client_classes);
getOptions(index, in_bindings, universe, options);
return (options.empty() ? OptionDescriptorPtr() :
getModifiedOptions6Test();
}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, globalOption6WithClientClassesTest) {
+ globalOption6WithClientClassesTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getAllOptions6WithClientClassesTest) {
+ getAllOptions6WithClientClassesTest();
+}
+
TEST_F(PgSqlConfigBackendDHCPv6Test, createUpdateDeleteSubnetOption6Test) {
createUpdateDeleteSubnetOption6Test();
}
multipleAuditEntriesTest();
}
+TEST_F(PgSqlConfigBackendDHCPv6Test, sharedNetworkOption6WithClientClassesTest) {
+ sharedNetworkOption6WithClientClassesTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, subnetOption6WithClientClassesTest) {
+ subnetOption6WithClientClassesTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, poolOption6WithClientClassesTest) {
+ poolOption6WithClientClassesTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, pdPoolOption6WithClientClassesTest) {
+ pdPoolOption6WithClientClassesTest();
+}
+
/// @brief Test fixture for verifying database connection loss-recovery
/// behavior.
class PgSqlConfigBackendDHCPv6DbLostCallbackTest : public GenericConfigBackendDbLostCallbackTest {
/// @param server_selector Server selector.
/// @param code Option code.
/// @param space Option space.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space) const = 0;
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr()) const = 0;
/// @brief Retrieves all global options.
///
/// @param server_selector Server selector.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) = 0;
+ const std::string& space,
+ ClientClassesPtr client_classes = ClientClassesPtr()) = 0;
/// @brief Deletes shared network level option.
///
/// belongs to.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
+ /// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::ServerSelector& selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) = 0;
+ const std::string& space,
+ ClientClassesPtr client_classes = ClientClassesPtr()) = 0;
/// @brief Deletes subnet level option.
///
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) = 0;
+ const std::string& space,
+ ClientClassesPtr client_classes = ClientClassesPtr()) = 0;
/// @brief Deletes pool level option.
///
/// deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
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) = 0;
+ const std::string& space,
+ ClientClassesPtr client_classes = ClientClassesPtr()) = 0;
/// @brief Deletes prefix delegation pool level option.
///
/// pool to which the deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
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) = 0;
+ const std::string& space,
+ ClientClassesPtr client_classes = ClientClassesPtr()) = 0;
/// @brief Deletes global parameter.
///
ConfigBackendPoolDHCPv6::getOption6(const BackendSelector& backend_selector,
const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) const {
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) const {
OptionDescriptorPtr option;
getPropertyPtrConst<OptionDescriptorPtr, uint16_t, const std::string&>
(&ConfigBackendDHCPv6::getOption6, backend_selector, server_selector,
- option, code, space);
+ option, code, space, client_classes);
return (option);
}
ConfigBackendPoolDHCPv6::deleteOption6(const BackendSelector& backend_selector,
const ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
- return (createUpdateDeleteProperty<uint64_t, uint16_t, const std::string&>
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) {
+ return (createUpdateDeleteProperty<uint64_t, uint16_t, const std::string&,
+ const ClientClassesPtr>
(&ConfigBackendDHCPv6::deleteOption6, backend_selector, server_selector,
- code, space));
+ code, space, client_classes));
}
uint64_t
const ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) {
return (createUpdateDeleteProperty<uint64_t, const std::string&, uint16_t,
- const std::string&>
+ const std::string&,
+ const ClientClassesPtr>
(&ConfigBackendDHCPv6::deleteOption6, backend_selector, server_selector,
- shared_network_name, code, space));
+ shared_network_name, code, space, client_classes));
}
uint64_t
const ServerSelector& server_selector,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
- return (createUpdateDeleteProperty<uint64_t, const SubnetID&, uint16_t, const std::string&>
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) {
+ return (createUpdateDeleteProperty<uint64_t, const SubnetID&, uint16_t,
+ const std::string&,
+ const ClientClassesPtr>
(&ConfigBackendDHCPv6::deleteOption6, backend_selector, server_selector,
- subnet_id, code, space));
+ subnet_id, code, space, client_classes));
}
uint64_t
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) {
return (createUpdateDeleteProperty<uint64_t, const IOAddress&, const IOAddress&,
- uint16_t, const std::string&>
+ uint16_t, const std::string&,
+ const ClientClassesPtr>
(&ConfigBackendDHCPv6::deleteOption6, backend_selector, server_selector,
- pool_start_address, pool_end_address, code, space));
+ pool_start_address, pool_end_address, code, space, client_classes));
}
uint64_t
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes
+ /* = ClientClassesPtr() */) {
return (createUpdateDeleteProperty<uint64_t, const IOAddress&, uint8_t,
- uint16_t, const std::string&>
+ uint16_t, const std::string&,
+ const ClientClassesPtr>
(&ConfigBackendDHCPv6::deleteOption6, backend_selector, server_selector,
- pd_pool_prefix, pd_pool_prefix_length, code, space));
+ pd_pool_prefix, pd_pool_prefix_length, code, space, client_classes));
}
uint64_t
/// @param server_selector Server selector.
/// @param code Option code.
/// @param space Option space.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption6(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) const;
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr()) const;
/// @brief Retrieves all global options.
///
/// @param server_selector Server selector.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes shared network level option.
///
/// belongs to.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
+ /// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes subnet level option.
///
/// belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::BackendSelector& backend_selector,
const db::ServerSelector& server_selector,
const SubnetID& subnet_id,
- const uint16_t code, const std::string& space);
+ const uint16_t code, const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pool level option.
///
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes prefix delegation pool level option.
///
/// pool to which the deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::BackendSelector& backend_selector,
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes global parameter.
///
void getModifiedOptions4Test();
/// @brief Creates a list of string options with and without client_class tags.
- /// It creates 3 DHO_TCODE options and 2 DHO_PCODE options.
+ /// It creates 2 DHO_TCODE options and 3 DHO_PCODE options.
std::list<OptionDescriptorPtr> makeClassTaggedOptions();
/// @brief Updates the value of each string option in the list.
void
GenericConfigBackendDHCPv6Test::TearDown() {
cbptr_.reset();
- // If data wipe enabled, delete transient data otherwise destroy the schema.
- destroySchema();
+ if (getenv("KEA_UNIT_TEST_KEEP_SCHEMA")) {
+ std::cout << "KEA_UNIT_TEST_KEEP_SCHEMA set, avoid schema destruction" << std::endl;
+ } else {
+ // If data wipe enabled, delete transient data otherwise destroy the schema.
+ destroySchema();
+ }
}
db::AuditEntryCollection
}
}
+std::list<OptionDescriptorPtr>
+GenericConfigBackendDHCPv6Test::makeClassTaggedOptions() {
+ // Describes an option to create.
+ struct OptData {
+ uint16_t code_;
+ std::string value_;
+ std::string cclass_;
+ };
+
+ // List of options to create.
+ // Using timezone options as they are handy string options.
+ std::list<OptData> opts_to_make = {
+ { D6O_NEW_TZDB_TIMEZONE, "T100", "cc-one" },
+ { D6O_NEW_POSIX_TIMEZONE, "P100", "cc-one" },
+ { D6O_NEW_POSIX_TIMEZONE, "P300", "" },
+ { D6O_NEW_TZDB_TIMEZONE, "T200", "" },
+ { D6O_NEW_POSIX_TIMEZONE, "P200", "cc-two" }
+ };
+
+ std::list<OptionDescriptorPtr> tagged_options;
+ for (auto const& opt_to_make : opts_to_make) {
+ OptionDescriptor desc = createOption<OptionString>(Option::V6, opt_to_make.code_,
+ true, false, false, opt_to_make.value_);
+ desc.space_name_ = DHCP6_OPTION_SPACE;
+ if (!opt_to_make.cclass_.empty()) {
+ desc.addClientClass(opt_to_make.cclass_);
+ }
+
+ tagged_options.push_back(OptionDescriptorPtr(new OptionDescriptor(desc)));
+ }
+
+ return (tagged_options);
+}
+
+void
+GenericConfigBackendDHCPv6Test::updateClassTaggedOptions(
+ std::list<OptionDescriptorPtr>& options) {
+ for (auto& desc : options) {
+ OptionStringPtr opt = boost::dynamic_pointer_cast<OptionString>(desc->option_);
+ ASSERT_TRUE(opt);
+ std::string new_value(opt->getValue() + std::string(".") + opt->getValue());
+ opt->setValue(new_value);
+ }
+}
+
+// Macro the make SCOPED_TRACE around equivalance function more compact and helpful.
+#define SCOPED_OPT_COMPARE(exp_opt,test_opt)\
+{\
+ std::stringstream oss;\
+ oss << "Options not equal:\n"\
+ << " exp_opt: " << exp_opt.option_->toText() << "\n"\
+ << " test_opt: " << (test_opt.option_ ? test_opt.option_->toText() : "<null>") << "\n";\
+ SCOPED_TRACE(oss.str());\
+ testOptionsEquivalent(exp_opt,test_opt);\
+}
+
+// Verify that one can add multiple global instances of the same option code
+// and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv6Test::globalOption6WithClientClassesTest() {
+ // Add the options to global scope.
+ auto ref_options = makeClassTaggedOptions();
+ for (auto const& ref_option : ref_options) {
+ // Add option to the config back end.
+ cbptr_->createUpdateOption6(ServerSelector::ALL(), ref_option);
+ }
+
+ // Make sure that we can find each option.
+ OptionDescriptorPtr found_option;
+ for (auto const& ref_option : ref_options) {
+ // Find the option by code and client_classes.
+ found_option = cbptr_->getOption6(ServerSelector::ALL(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses());
+ ASSERT_TRUE(found_option) << "ref_option" << ref_option->option_->toText()
+ << ", cc: " << ref_option->client_classes_.toText();
+ SCOPED_OPT_COMPARE((*ref_option), (*found_option));
+ }
+
+ // Update the option values.
+ updateClassTaggedOptions(ref_options);
+
+ // Update each option in the backend.
+ for (auto const& ref_option : ref_options) {
+ // Update option in the config back end.
+ cbptr_->createUpdateOption6(ServerSelector::ALL(), ref_option);
+
+ // Fetch and verify the updated option.
+ found_option = cbptr_->getOption6(ServerSelector::ALL(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses());
+ ASSERT_TRUE(found_option);
+ SCOPED_OPT_COMPARE((*ref_option), (*found_option));
+ }
+
+ // Delete each option from the backend.
+ for (auto const& ref_option : ref_options) {
+ ClientClassesPtr cclasses = ref_option->copyClientClasses();
+
+ // Delete the option by code and client_classes.
+ ASSERT_EQ(1, cbptr_->deleteOption6(ServerSelector::ALL(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ cclasses));
+
+ // Finding the option by code and client_classes should fail.
+ found_option = cbptr_->getOption6(ServerSelector::ALL(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ cclasses);
+ ASSERT_FALSE(found_option);
+ }
+}
+
+void
+GenericConfigBackendDHCPv6Test::getAllOptions6WithClientClassesTest() {
+ // Describes an option to create.
+ struct OptData {
+ uint16_t code_;
+ uint32_t value_;
+ std::string cclass_;
+ ServerSelector server_;
+ };
+
+ auto server1 = ServerSelector::ONE("server1");
+ auto server2 = ServerSelector::ONE("server2");
+ auto all = ServerSelector::ALL();
+ // List of options to create.
+ std::list<OptData> opts_to_make = {
+ { 231, 1, "cc-1", server1 },
+ { 231, 2, "cc-2", server1 },
+ { 232, 3, "cc-3", server1 },
+ { 232, 4, "cc-3", server2 },
+ { 233, 5, "cc-4", server1 },
+ { 233, 6, "cc-4", all },
+ { 234, 7, "cc-5", all }
+ };
+
+ // Create two servers.
+ ASSERT_NO_THROW_LOG(cbptr_->createUpdateServer6(test_servers_[1]));
+ ASSERT_NO_THROW_LOG(cbptr_->createUpdateServer6(test_servers_[2]));
+
+ // Add all of the global options.
+ std::vector<OptionDescriptorPtr> ref_options;
+ for (auto const& opt_to_make : opts_to_make) {
+ OptionDescriptor desc = createOption<OptionInt<uint32_t>>(Option::V6, opt_to_make.code_,
+ true, false, false, opt_to_make.value_);
+ desc.space_name_ = DHCP6_OPTION_SPACE;
+ if (!opt_to_make.cclass_.empty()) {
+ desc.addClientClass(opt_to_make.cclass_);
+ }
+
+ ref_options.push_back(OptionDescriptorPtr(new OptionDescriptor(desc)));
+ ASSERT_NO_THROW_LOG(cbptr_->createUpdateOption6(opt_to_make.server_, ref_options.back()));
+ }
+
+ // Try to fetch the collection of global options for the server1.
+ // Build list of options we expect to get back.
+ std::vector<OptionDescriptorPtr> exp_options;
+ exp_options.push_back(ref_options[0]);
+ exp_options.push_back(ref_options[1]);
+ exp_options.push_back(ref_options[2]);
+ exp_options.push_back(ref_options[4]);
+ exp_options.push_back(ref_options[6]);
+
+ OptionContainer returned_options;
+ ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions6(server1));
+ ASSERT_EQ(returned_options.size(), exp_options.size());
+ auto exp_option = exp_options.begin();
+ for (auto returned_option : returned_options) {
+ testOptionsEquivalent(*(*exp_option), returned_option);
+ ++exp_option;
+ }
+
+ // Try to fetch the collection of global options for the server2.
+ // Build list of options we expect to get back.
+ exp_options.clear();
+ exp_options.push_back(ref_options[3]);
+ exp_options.push_back(ref_options[5]);
+ exp_options.push_back(ref_options[6]);
+
+ ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions6(server2));
+ ASSERT_EQ(returned_options.size(), exp_options.size());
+ exp_option = exp_options.begin();
+ for (auto returned_option : returned_options) {
+ testOptionsEquivalent(*(*exp_option), returned_option);
+ ++exp_option;
+ }
+
+ // Try to fetch the collection of global options for the server1.
+ // Build list of options we expect to get back.
+ exp_options.clear();
+ exp_options.push_back(ref_options[5]);
+ exp_options.push_back(ref_options[6]);
+
+ ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions6(all));
+ ASSERT_EQ(returned_options.size(), exp_options.size());
+ exp_option = exp_options.begin();
+ for (auto returned_option : returned_options) {
+ testOptionsEquivalent(*(*exp_option), returned_option);
+ ++exp_option;
+ }
+}
+
void
GenericConfigBackendDHCPv6Test::createUpdateDeleteSubnetOption6Test() {
// Insert new subnet.
// It should succeed for any server.
EXPECT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(), subnet->getID(),
opt_posix_timezone->option_->getType(),
- opt_posix_timezone->space_name_));
+ opt_posix_timezone->space_name_,
+ opt_posix_timezone->copyClientClasses()));
returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(),
subnet->getID());
distance--;
}
}
+
+// Verify that one can add multiple instances of the same option code
+// to a shared-network and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv6Test::sharedNetworkOption6WithClientClassesTest() {
+ // Make a network with options.
+ SharedNetwork6Ptr network(new SharedNetwork6("net1"));
+ auto ref_options = makeClassTaggedOptions();
+ for (auto const& ref_option : ref_options) {
+ network->getCfgOption()->add(*ref_option, ref_option->space_name_);
+ }
+
+ // Add the network to config back end.
+ cbptr_->createUpdateSharedNetwork6(ServerSelector::ALL(), network);
+
+ // Fetch the network.
+ SharedNetwork6Ptr returned_network = cbptr_->getSharedNetwork6(ServerSelector::ALL(),
+ network->getName());
+ ASSERT_TRUE(returned_network);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_network->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can set the options individually.
+ updateClassTaggedOptions(ref_options);
+ for (auto const& ref_option : ref_options) {
+ cbptr_->createUpdateOption6(ServerSelector::ALL(), network->getName(), ref_option);
+ }
+
+ // Re-fetch the network.
+ returned_network = cbptr_->getSharedNetwork6(ServerSelector::ALL(), network->getName());
+ ASSERT_TRUE(returned_network);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_network->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can delete the options individually.
+ for (auto const& ref_option : ref_options) {
+ ASSERT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
+ network->getName(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses()));
+ }
+
+ // Re-fetch the network.
+ returned_network = cbptr_->getSharedNetwork6(ServerSelector::ALL(), network->getName());
+ ASSERT_TRUE(returned_network);
+
+ // Make sure that CfgOption is empty
+ auto cfg_option = returned_network->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+ EXPECT_TRUE(cfg_option->empty());
+}
+
+// Verify that one can add multiple instances of the same option code
+// to a subnet and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv6Test::subnetOption6WithClientClassesTest() {
+ // Make a subnet with options.
+ Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 64,
+ 30, 40, 50, 60, 1024));
+ auto ref_options = makeClassTaggedOptions();
+ for (auto const& ref_option : ref_options) {
+ subnet->getCfgOption()->add(*ref_option, ref_option->space_name_);
+ }
+
+ // Add the subnet to config back end.
+ cbptr_->createUpdateSubnet6(ServerSelector::ALL(), subnet);
+
+ // Fetch the subnet.
+ Subnet6Ptr returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_subnet->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can set the options individually.
+ updateClassTaggedOptions(ref_options);
+ for (auto const& ref_option : ref_options) {
+ cbptr_->createUpdateOption6(ServerSelector::ALL(), subnet->getID(), ref_option);
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_subnet->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can delete the options individually.
+ for (auto const& ref_option : ref_options) {
+ ASSERT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
+ subnet->getID(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses()));
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ // Make sure that CfgOption is empty
+ auto cfg_option = returned_subnet->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+ EXPECT_TRUE(cfg_option->empty());
+}
+
+// Verify that one can add multiple instances of the same option code
+// to a pool and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv6Test::poolOption6WithClientClassesTest() {
+ // Make subnet with a pool with options.
+ Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 64,
+ 30, 40, 50, 60, 1024));
+
+ Pool6Ptr pool(new Pool6(Lease::TYPE_NA,
+ IOAddress("2001:db8::10"), IOAddress("2001:db8::20")));
+ subnet->addPool(pool);
+
+ // Add the options to the pool.
+ auto ref_options = makeClassTaggedOptions();
+ for (auto const& ref_option : ref_options) {
+ pool->getCfgOption()->add(*ref_option, ref_option->space_name_);
+ }
+
+ // Add the subnet to config back end.
+ cbptr_->createUpdateSubnet6(ServerSelector::ALL(), subnet);
+
+ // Fetch this subnet by subnet identifier.
+ Subnet6Ptr returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(),
+ subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ PoolPtr returned_pool = returned_subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8::10"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_pool->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can set the options individually.
+ updateClassTaggedOptions(ref_options);
+ for (auto const& ref_option : ref_options) {
+ cbptr_->createUpdateOption6(ServerSelector::ALL(),
+ pool->getFirstAddress(),
+ pool->getLastAddress(),
+ ref_option);
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ returned_pool = returned_subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8::10"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_pool->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can delete the options individually.
+ for (auto const& ref_option : ref_options) {
+ ASSERT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
+ pool->getFirstAddress(),
+ pool->getLastAddress(),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses()));
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ returned_pool = returned_subnet->getPool(Lease::TYPE_NA, IOAddress("2001:db8::10"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption is empty
+ auto cfg_option = returned_pool->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+ EXPECT_TRUE(cfg_option->empty());
+}
+
+// Verify that one can add multiple instances of the same option code
+// to a pd pool and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv6Test::pdPoolOption6WithClientClassesTest() {
+ // Make subnet with a pool with options.
+ Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 64,
+ 30, 40, 50, 60, 1024));
+
+ const PoolPtr pool(new Pool6(Lease::TYPE_PD,
+ IOAddress("2001:db8:a::"), 48, 64));
+ auto pool_len = prefixLengthFromRange(pool->getFirstAddress(),
+ pool->getLastAddress());
+ subnet->addPool(pool);
+
+ // Add the options to the pool.
+ auto ref_options = makeClassTaggedOptions();
+ for (auto const& ref_option : ref_options) {
+ pool->getCfgOption()->add(*ref_option, ref_option->space_name_);
+ }
+
+ // Add the subnet to config back end.
+ cbptr_->createUpdateSubnet6(ServerSelector::ALL(), subnet);
+
+ // Fetch this subnet by subnet identifier.
+ Subnet6Ptr returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(),
+ subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ PoolPtr returned_pool = returned_subnet->getPool(Lease::TYPE_PD,
+ IOAddress("2001:db8:a::"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_pool->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can set the options individually.
+ updateClassTaggedOptions(ref_options);
+
+ for (auto const& ref_option : ref_options) {
+ cbptr_->createUpdateOption6(ServerSelector::ALL(),
+ pool->getFirstAddress(),
+ static_cast<uint8_t>(pool_len),
+ ref_option);
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ returned_pool = returned_subnet->getPool(Lease::TYPE_PD,
+ IOAddress("2001:db8:a::"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption->get() with client_classes finds each ref option.
+ for (auto const& ref_option : ref_options) {
+ auto cfg_option = returned_pool->getCfgOption()->get(DHCP6_OPTION_SPACE,
+ ref_option->option_->getType(),
+ ref_option->client_classes_);
+ SCOPED_OPT_COMPARE((*ref_option), cfg_option);
+ }
+
+ // Now make sure that we can delete the options individually.
+ for (auto const& ref_option : ref_options) {
+ ASSERT_EQ(1, cbptr_->deleteOption6(ServerSelector::ANY(),
+ pool->getFirstAddress(),
+ static_cast<uint8_t>(pool_len),
+ ref_option->option_->getType(),
+ DHCP6_OPTION_SPACE,
+ ref_option->copyClientClasses()));
+ }
+
+ // Re-fetch the subnet.
+ returned_subnet = cbptr_->getSubnet6(ServerSelector::ALL(), subnet->getID());
+ ASSERT_TRUE(returned_subnet);
+
+ returned_pool = returned_subnet->getPool(Lease::TYPE_PD,
+ IOAddress("2001:db8:a::"));
+ ASSERT_TRUE(returned_pool);
+
+ // Make sure that CfgOption is empty
+ auto cfg_option = returned_pool->getCfgOption()->getAll(DHCP6_OPTION_SPACE);
+ EXPECT_TRUE(cfg_option->empty());
+}
/// @brief This test verifies that modified global options can be retrieved.
void getModifiedOptions6Test();
+ /// @brief Creates a list of string options with and without client_class tags.
+ /// It creates 2 D6O_NEW_TZDB_TIMEZONE options and 2 D6O_NEW_POSIX_TIMEZONE options.
+ std::list<OptionDescriptorPtr> makeClassTaggedOptions();
+
+ /// @brief Updates the value of each string option in the list.
+ void updateClassTaggedOptions(std::list<OptionDescriptorPtr>& options);
+
+ /// @brief This test verifies that multiple instances of an option can
+ /// be added to global scope and be distinguished from one another
+ /// by their client-classes content.
+ void globalOption6WithClientClassesTest();
+
+ /// @brief This test verifies that global options with varying client-classes
+ /// and varying server tags are handled properly.
+ void getAllOptions6WithClientClassesTest();
+
/// @brief This test verifies that subnet level option can be added, updated and
/// deleted.
void createUpdateDeleteSubnetOption6Test();
/// event and it does not matter).
void multipleAuditEntriesTest();
+ /// @brief This test verifies that multiple instances of an option can
+ /// be added to a shared-network and be distinguished from one another
+ /// by their client-classes content.
+ void sharedNetworkOption6WithClientClassesTest();
+
+ /// @brief This test verifies that multiple instances of an option can
+ /// be added to a subnet and be distinguished from one another
+ /// by their client-classes content.
+ void subnetOption6WithClientClassesTest();
+
+ /// @brief This test verifies that multiple instances of an option can
+ /// be added to a pool and be distinguished from one another
+ /// by their client-classes content.
+ void poolOption6WithClientClassesTest();
+
+ /// @brief This test verifies that multiple instances of an option can
+ /// be added to a pd pool and be distinguished from one another
+ /// by their client-classes content.
+ void pdPoolOption6WithClientClassesTest();
+
/// @brief Holds pointers to subnets used in tests.
std::vector<Subnet6Ptr> test_subnets_;
TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes) {
+ const ClientClassesPtr client_classes) {
auto tag = getServerTag(server_selector);
uint64_t erased = 0;
for (auto option_it = options_.begin(); option_it != options_.end(); ) {
const std::string& shared_network_name,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes) {
+ const ClientClassesPtr client_classes) {
auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
auto network_it = index.find(shared_network_name);
const SubnetID& subnet_id,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes) {
+ const ClientClassesPtr client_classes) {
auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
auto subnet_it = index.find(subnet_id);
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes) {
+ const ClientClassesPtr client_classes) {
auto not_in_selected_servers = false;
for (auto const& subnet : subnets_) {
// Get the pool: if it is not here we can directly go to the next subnet.
virtual uint64_t
deleteOption4(const db::ServerSelector& server_selector, const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes = ClientClassesPtr());
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes shared network level option.
///
const std::string& shared_network_name,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes = ClientClassesPtr());
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes subnet level option.
///
virtual uint64_t
deleteOption4(const db::ServerSelector& server_selector, const SubnetID& subnet_id,
const uint16_t code, const std::string& space,
- ClientClassesPtr client_classes = ClientClassesPtr());
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pool level option.
///
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
const std::string& space,
- ClientClassesPtr client_classes = ClientClassesPtr());
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes global parameter.
///
OptionDescriptorPtr
TestConfigBackendDHCPv6::getOption6(const db::ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) const {
+ const std::string& space,
+ const ClientClassesPtr client_classes) const {
auto const& tags = server_selector.getTags();
auto candidate = OptionDescriptorPtr();
auto const& index = options_.get<1>();
BOOST_FOREACH(auto const& option_it, option_it_pair) {
if (option_it.space_name_ == space) {
+ if (client_classes && (option_it.client_classes_ != *client_classes)) {
+ continue;
+ }
+
for (auto const& tag : tags) {
if (option_it.hasServerTag(ServerTag(tag))) {
return (OptionDescriptorPtr(new OptionDescriptor(option_it)));
}
}
+
if (option_it.hasAllServerTag()) {
candidate = OptionDescriptorPtr(new OptionDescriptor(option_it));
}
option_it != option_it_pair.second;
++option_it) {
if ((option_it->space_name_ == option->space_name_) &&
+ (option_it->client_classes_ == option->client_classes_) &&
(option_it->hasServerTag(ServerTag(tag)))) {
index.replace(option_it, *option);
return;
<< " not present in a selected server");
}
- shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
+ shared_network->getCfgOption()->del(option->space_name_, option->option_->getType(),
+ option->client_classes_);
shared_network->getCfgOption()->add(*option, option->space_name_);
}
<< " not present in a selected server");
}
- subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
+ subnet->getCfgOption()->del(option->space_name_, option->option_->getType(),
+ option->client_classes_);
subnet->getCfgOption()->add(*option, option->space_name_);
}
}
// Update the option.
- pool->getCfgOption()->del(option->space_name_, option->option_->getType());
+ pool->getCfgOption()->del(option->space_name_, option->option_->getType(),
+ option->client_classes_);
pool->getCfgOption()->add(*option, option->space_name_);
return;
}
// Update the option.
- pdpool->getCfgOption()->del(option->space_name_, option->option_->getType());
+ pdpool->getCfgOption()->del(option->space_name_, option->option_->getType(),
+ option->client_classes_);
pdpool->getCfgOption()->add(*option, option->space_name_);
return;
uint64_t
TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ ClientClassesPtr client_classes) {
auto const& 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->hasServerTag(ServerTag(tag))) &&
+ (!client_classes || (option_it->client_classes_ == *client_classes))) {
option_it = options_.erase(option_it);
++erased;
} else {
TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ ClientClassesPtr client_classes) {
auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
auto network_it = index.find(shared_network_name);
}
}
}
+
if (!found) {
isc_throw(BadValue, "attempted to delete option in a "
"shared network " << shared_network_name
<< " not present in a selected server");
}
+ if (client_classes) {
+ return (shared_network->getCfgOption()->del(space, code, *client_classes));
+ }
+
return (shared_network->getCfgOption()->del(space, code));
}
TestConfigBackendDHCPv6::deleteOption6(const db::ServerSelector& server_selector,
const SubnetID& subnet_id,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
auto subnet_it = index.find(subnet_id);
}
}
}
+
if (!found) {
isc_throw(BadValue, "attempted to delete option in a "
"subnet ID " << subnet_id
<< " not present in a selected server");
}
+ if (client_classes) {
+ return (subnet->getCfgOption()->del(space, code, *client_classes));
+ }
+
return (subnet->getCfgOption()->del(space, code));
}
const asiolink::IOAddress& pool_start_address,
const asiolink::IOAddress& pool_end_address,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
auto not_in_selected_servers = false;
for (auto const& subnet : subnets_) {
// Get the pool: if it is not here we can directly go to the next subnet.
}
}
+ if (client_classes) {
+ return (pool->getCfgOption()->del(space, code, *client_classes));
+ }
+
return (pool->getCfgOption()->del(space, code));
}
const asiolink::IOAddress& pd_pool_prefix,
const uint8_t pd_pool_prefix_length,
const uint16_t code,
- const std::string& space) {
+ const std::string& space,
+ const ClientClassesPtr client_classes) {
auto not_in_selected_servers = false;
for (auto const& subnet : subnets_) {
// Get the pd pool: if it is not here we can directly go to the next subnet.
}
}
+ if (client_classes) {
+ return (pdpool->getCfgOption()->del(space, code, *client_classes));
+ }
+
return (pdpool->getCfgOption()->del(space, code));
}
/// @brief Retrieves single option by code and space.
///
/// @param server_selector Server selector.
+ /// @param code Code of the option to be deleted.
+ /// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Pointer to the retrieved option descriptor or null if
/// no option was found.
virtual OptionDescriptorPtr
getOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space) const;
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr()) const;
/// @brief Retrieves all global options.
///
/// @param server_selector Server selector.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector, const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes shared network level option.
///
/// belongs to.
/// @param code Code of the option to be deleted.
/// @param space Option space of the option to be deleted.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
+ /// @return Number of deleted options.
virtual uint64_t
deleteOption6(const db::ServerSelector& server_selector,
const std::string& shared_network_name,
const uint16_t code,
- const std::string& space);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes subnet level option.
///
/// @param space Option space of the deleted option.
/// @return Number of deleted options.
virtual uint64_t
- deleteOption6(const db::ServerSelector& server_selector, const SubnetID& subnet_id,
- const uint16_t code, const std::string& space);
+ deleteOption6(const db::ServerSelector& server_selector,
+ const SubnetID& subnet_id,
+ const uint16_t code,
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pool level option.
///
/// deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
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);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes pd pool level option.
///
/// the deleted option belongs.
/// @param code Code of the deleted option.
/// @param space Option space of the deleted option.
+ /// @param client_classes Optional client classes list of the option to be deleted.
+ /// Defaults to an empty pointer.
/// @return Number of deleted options.
virtual uint64_t
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);
+ const std::string& space,
+ const ClientClassesPtr client_classes = ClientClassesPtr());
/// @brief Deletes global parameter.
///
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
- " \"client-classes\": [ <zero or more comma-separated strings> ],",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
" \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
"This command deletes a DHCPv6 global option from the configuration database."
],
"cmd-comment": [
- "This command includes a list with exactly one option specification, comprising an option name and code. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error."
+ "This command includes a list with exactly one option specification, comprising an option name, code, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). Specifying an empty list, a value of ``null``, or multiple server tags will result in an error."
],
"cmd-syntax": [
"{",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",
"This command fetches a global DHCPv6 option for the server from the specified database."
],
"cmd-comment": [
- "The option is identified by the pair of option code/space values. The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed, to fetch the global option instance shared by all servers."
+ "The option is identified by the pair of option code/space values, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). The ``server-tags`` list is mandatory and must contain exactly one server tag. Specifying an empty list, a value of ``null``, or multiple server tags will result in an error. The server tag \"all\" is allowed, to fetch the global option instance shared by all servers."
],
"cmd-syntax": [
"{",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" }",
"This command deletes a DHCPv6 option from a shared network from the configuration database."
],
"cmd-comment": [
- "This command includes two lists with exactly one name of the shared network and exactly one option specification, comprising an option name and code. Specifying an empty list, a value of ``null``, or a server tag will result in an error."
+ "This command includes two lists with exactly one name of the shared network and exactly one option specification, comprising an option name, code, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). Specifying an empty list, a value of ``null``, or a server tag will result in an error."
],
"cmd-syntax": [
"{",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" }",
"This command deletes a DHCPv6 option from a prefix delegation pool from the configuration database."
],
"cmd-comment": [
- "This command includes two lists with exactly one prefix delegation pool specification and exactly one option specification, comprising an option name and code. Specifying an empty list, a value of ``null``, or a server tag will result in an error."
+ "This command includes two lists with exactly one prefix delegation pool specification and exactly one option specification, comprising an option name, code, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). Specifying an empty list, a value of ``null``, or a server tag will result in an error."
],
"cmd-syntax": [
"{",
" \"pd-pools\": [",
" {",
" \"prefix\": <pool prefix (address part)>,",
- " \"prefix-len\": <pool prefix (length part)>",
+ " \"prefix-len\": <pool prefix (length part)>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"options\": [",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" }",
"This command deletes a DHCPv6 option from an address pool from the configuration database."
],
"cmd-comment": [
- "This command includes two lists with exactly one address pool specification and exactly one option specification, comprising an option name and code. Specifying an empty list, a value of ``null``, or a server tag will result in an error."
+ "This command includes two lists with exactly one address pool specification and exactly one option specification, comprising an option name, code, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). Specifying an empty list, a value of ``null``, or a server tag will result in an error."
],
"cmd-syntax": [
"{",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <one or more comma-separated strings> ]",
" }",
" ]",
" }",
"This command deletes a DHCPv6 option from a subnet from the configuration database."
],
"cmd-comment": [
- "This command includes two lists with exactly one ID of the subnet and exactly one option specification, comprising an option name and code. Specifying an empty list, a value of ``null``, or a server tag will result in an error."
+ "This command includes two lists with exactly one ID of the subnet and exactly one option specification, comprising an option name, code, and as of Kea 3.1.1, an optional client-classes parameter (see :ref:`cb-cmds-option-class-tags-as-keys`). Specifying an empty list, a value of ``null``, or a server tag will result in an error."
],
"cmd-syntax": [
"{",
" \"options\": [",
" {",
" \"code\": <option code>,",
- " \"space\": <option space>",
+ " \"space\": <option space>,",
+ " \"client-classes\": [ <zero or more comma-separated strings> ]",
" }",
" ],",
" \"remote\": {",