mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 05:55:28 +00:00
[#2815] Implement del6 function
This commit is contained in:
@@ -1179,13 +1179,40 @@ CfgHosts::delAll6(const SubnetID& subnet_id) {
|
||||
}
|
||||
|
||||
bool
|
||||
CfgHosts::del6(const SubnetID& /*subnet_id*/,
|
||||
const Host::IdentifierType& /*identifier_type*/,
|
||||
const uint8_t* /*identifier_begin*/,
|
||||
const size_t /*identifier_len*/) {
|
||||
/// @todo: Implement host removal
|
||||
isc_throw(NotImplemented, "sorry, not implemented");
|
||||
return (false);
|
||||
CfgHosts::del6(const SubnetID& subnet_id,
|
||||
const Host::IdentifierType& identifier_type,
|
||||
const uint8_t* identifier_begin,
|
||||
const size_t identifier_len) {
|
||||
HostContainerIndex0& idx = hosts_.get<0>();
|
||||
HostContainer6Index3& idx6 = hosts6_.get<3>();
|
||||
|
||||
const auto t = boost::make_tuple(std::vector<uint8_t>(identifier_begin,
|
||||
identifier_begin + identifier_len),
|
||||
identifier_type);
|
||||
const auto& range = idx.equal_range(t);
|
||||
size_t erased_hosts = 0;
|
||||
size_t erased_reservations = 0;
|
||||
for (auto key = range.first; key != range.second;) {
|
||||
if ((*key)->getIPv6SubnetID() != subnet_id) {
|
||||
++key;
|
||||
// Skip hosts from other subnets.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Delete host.
|
||||
key = idx.erase(key);
|
||||
erased_hosts++;
|
||||
// Delete reservations.
|
||||
erased_reservations += idx6.erase((*key)->getHostId());
|
||||
}
|
||||
|
||||
LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_DEL6)
|
||||
.arg(erased_hosts)
|
||||
.arg(erased_reservations)
|
||||
.arg(subnet_id)
|
||||
.arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
|
||||
|
||||
return (erased_hosts != 0);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@@ -179,10 +179,15 @@ struct HostResrv6Tuple {
|
||||
/// @brief Value of the IPv6 Subnet-id
|
||||
const SubnetID subnet_id_;
|
||||
|
||||
/// @brief Key extractor (used in the second composite key)
|
||||
const asiolink::IOAddress& getKey() const {
|
||||
/// @brief Key extractor used in the second composite key
|
||||
const asiolink::IOAddress& getPrefix() const {
|
||||
return (resrv_.getPrefix());
|
||||
}
|
||||
|
||||
/// @brief Key extractor used in the fourth composite key
|
||||
HostID getHostId() const {
|
||||
return (host_->getHostId());
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Multi-index container holding IPv6 reservations.
|
||||
@@ -204,7 +209,7 @@ typedef boost::multi_index_container<
|
||||
// Address is extracted by calling IPv6Resrv::getPrefix()
|
||||
// and it will return an IOAddress object.
|
||||
boost::multi_index::const_mem_fun<
|
||||
HostResrv6Tuple, const asiolink::IOAddress&, &HostResrv6Tuple::getKey>
|
||||
HostResrv6Tuple, const asiolink::IOAddress&, &HostResrv6Tuple::getPrefix>
|
||||
>,
|
||||
|
||||
// Second index is used to search by (subnet_id, address) pair.
|
||||
@@ -227,7 +232,7 @@ typedef boost::multi_index_container<
|
||||
// IPv6Resrv::getPrefix() and it will return an IOAddress object.
|
||||
boost::multi_index::const_mem_fun<
|
||||
HostResrv6Tuple, const asiolink::IOAddress&,
|
||||
&HostResrv6Tuple::getKey
|
||||
&HostResrv6Tuple::getPrefix
|
||||
>
|
||||
>
|
||||
>,
|
||||
@@ -237,6 +242,13 @@ typedef boost::multi_index_container<
|
||||
// Index using values returned by the @c Host::getIPv6SubnetID
|
||||
boost::multi_index::member<HostResrv6Tuple, const SubnetID,
|
||||
&HostResrv6Tuple::subnet_id_>
|
||||
>,
|
||||
|
||||
// Fourth index is used to search by increasing host id
|
||||
boost::multi_index::ordered_non_unique<
|
||||
// Index using values returned by the @c Host::getHostId
|
||||
boost::multi_index::const_mem_fun<HostResrv6Tuple, uint64_t,
|
||||
&HostResrv6Tuple::getHostId>
|
||||
>
|
||||
>
|
||||
> HostContainer6;
|
||||
@@ -271,6 +283,15 @@ typedef HostContainer6::nth_index<2>::type HostContainer6Index2;
|
||||
typedef std::pair<HostContainer6Index2::iterator,
|
||||
HostContainer6Index2::iterator> HostContainer6Index2Range;
|
||||
|
||||
/// @brief Fourth index type in the @c HostContainer6.
|
||||
///
|
||||
/// This index allows for searching for @c Host objects using a host id.
|
||||
typedef HostContainer6::nth_index<3>::type HostContainer6Index3;
|
||||
|
||||
/// @brief Results range returned using the @c HostContainer6Index3.
|
||||
typedef std::pair<HostContainer6Index3::iterator,
|
||||
HostContainer6Index3::iterator> HostContainer6Index3Range;
|
||||
|
||||
}; // end of isc::dhcp namespace
|
||||
}; // end of isc namespace
|
||||
|
||||
|
@@ -15,6 +15,7 @@ extern const isc::log::MessageID HOSTS_CFG_CACHE_HOST_DATA_SOURCE = "HOSTS_CFG_C
|
||||
extern const isc::log::MessageID HOSTS_CFG_CLOSE_HOST_DATA_SOURCE = "HOSTS_CFG_CLOSE_HOST_DATA_SOURCE";
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL = "HOSTS_CFG_DEL";
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL4 = "HOSTS_CFG_DEL4";
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL6 = "HOSTS_CFG_DEL6";
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET4 = "HOSTS_CFG_DEL_ALL_SUBNET4";
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET6 = "HOSTS_CFG_DEL_ALL_SUBNET6";
|
||||
extern const isc::log::MessageID HOSTS_CFG_GET_ALL = "HOSTS_CFG_GET_ALL";
|
||||
@@ -89,6 +90,7 @@ const char* values[] = {
|
||||
"HOSTS_CFG_CLOSE_HOST_DATA_SOURCE", "Closing host data source: %1",
|
||||
"HOSTS_CFG_DEL", "deleted %1 host(s) having %2 IPv6 reservation(s) for subnet id %3 and address %4",
|
||||
"HOSTS_CFG_DEL4", "deleted %1 host(s) for subnet id %2 and identifier %3",
|
||||
"HOSTS_CFG_DEL6", "deleted %1 host(s) having %2 IPv6 reservation(s) for subnet id %3 and identifier %4",
|
||||
"HOSTS_CFG_DEL_ALL_SUBNET4", "deleted all %1 host(s) for subnet id %2",
|
||||
"HOSTS_CFG_DEL_ALL_SUBNET6", "deleted all %1 host(s) having %2 IPv6 reservation(s) for subnet id %3",
|
||||
"HOSTS_CFG_GET_ALL", "get all hosts with reservations",
|
||||
|
@@ -16,6 +16,7 @@ extern const isc::log::MessageID HOSTS_CFG_CACHE_HOST_DATA_SOURCE;
|
||||
extern const isc::log::MessageID HOSTS_CFG_CLOSE_HOST_DATA_SOURCE;
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL;
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL4;
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL6;
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET4;
|
||||
extern const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET6;
|
||||
extern const isc::log::MessageID HOSTS_CFG_GET_ALL;
|
||||
|
@@ -39,11 +39,18 @@ The third argument is the subnet identifier. The fourth argument is the IP
|
||||
address.
|
||||
|
||||
% HOSTS_CFG_DEL4 deleted %1 host(s) for subnet id %2 and identifier %3
|
||||
This debug message is issued when reservations are deleted for the specified
|
||||
This debug message is issued when IPv4 reservations are deleted for the specified
|
||||
subnet and identifier. The first argument specifies how many hosts have been
|
||||
deleted. The second argument is the subnet identifier. The third argument is
|
||||
the identifier.
|
||||
|
||||
% HOSTS_CFG_DEL6 deleted %1 host(s) having %2 IPv6 reservation(s) for subnet id %3 and identifier %4
|
||||
This debug message is issued when IPv6 reservations are deleted for the
|
||||
specified subnet and identifier. The first argument specifies how many hosts
|
||||
have been deleted. The second argument specifies how many reservations have
|
||||
been deleted. The third argument is the subnet identifier. The fourth argument
|
||||
is the identifier.
|
||||
|
||||
% HOSTS_CFG_DEL_ALL_SUBNET4 deleted all %1 host(s) for subnet id %2
|
||||
This debug message is issued when all IPv4 reservations are deleted for
|
||||
the specified subnet. The first argument specifies how many reservations
|
||||
|
@@ -503,7 +503,7 @@ TEST_F(CfgHostsTest, deleteForIPv6) {
|
||||
{
|
||||
HostPtr host = HostPtr(new Host(duids_[i]->toText(), "duid",
|
||||
SUBNET_ID_UNUSED, subnet_id,
|
||||
IOAddress("0.0.0.0")));
|
||||
IOAddress::IPV4_ZERO_ADDRESS()));
|
||||
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
|
||||
increase(IOAddress(address), i)));
|
||||
cfg.add(host);
|
||||
@@ -600,6 +600,65 @@ TEST_F(CfgHostsTest, del4) {
|
||||
EXPECT_FALSE(host);
|
||||
}
|
||||
|
||||
// This test checks that the host and its reservations for the specified IPv6
|
||||
// subnet and identifier can be deleted.
|
||||
TEST_F(CfgHostsTest, del6) {
|
||||
CfgHosts cfg;
|
||||
|
||||
// Add hosts.
|
||||
size_t host_count = 20;
|
||||
size_t host_id = 5;
|
||||
SubnetID subnet_id(42);
|
||||
IOAddress address("2001:db8:1::1");
|
||||
|
||||
// Add half of the hosts with the same subnet ID but differ with DUID and
|
||||
// address.
|
||||
for (size_t i = 0; i < host_count / 2; i++) {
|
||||
HostPtr host = HostPtr(new Host(duids_[i]->toText(), "duid",
|
||||
SUBNET_ID_UNUSED, subnet_id,
|
||||
IOAddress::IPV4_ZERO_ADDRESS()));
|
||||
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
|
||||
increase(IOAddress(address), i)));
|
||||
cfg.add(host);
|
||||
}
|
||||
// Add half of the hosts with the same subnet DUID and address but
|
||||
// differ with address.
|
||||
for (size_t i = 0; i < host_count / 2; i++) {
|
||||
HostPtr host = HostPtr(new Host(duids_[host_id]->toText(), "duid",
|
||||
SUBNET_ID_UNUSED, SubnetID(subnet_id + i + 1),
|
||||
IOAddress::IPV4_ZERO_ADDRESS()));
|
||||
host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
|
||||
increase(address, host_id)));
|
||||
cfg.add(host);
|
||||
}
|
||||
|
||||
|
||||
// Get all inserted hosts.
|
||||
HostCollection hosts_by_subnet = cfg.getAll6(subnet_id);
|
||||
HostCollection hosts_by_address = cfg.getAll6(increase(address, host_id));
|
||||
HostPtr host = cfg.get6(subnet_id, Host::IdentifierType::IDENT_DUID,
|
||||
&duids_[host_id]->getDuid()[0],
|
||||
duids_[host_id]->getDuid().size());
|
||||
// Make sure the hosts and IP reservations were added.
|
||||
ASSERT_EQ(host_count / 2, hosts_by_subnet.size());
|
||||
ASSERT_EQ(host_count / 2 + 1, hosts_by_address.size());
|
||||
ASSERT_TRUE(host);
|
||||
|
||||
// Delete one host.
|
||||
EXPECT_TRUE(cfg.del6(subnet_id, Host::IdentifierType::IDENT_DUID,
|
||||
&duids_[host_id]->getDuid()[0], duids_[host_id]->getDuid().size()));
|
||||
|
||||
// Check if the host is actually deleted.
|
||||
hosts_by_subnet = cfg.getAll6(subnet_id);
|
||||
hosts_by_address = cfg.getAll6(increase(address, host_id));
|
||||
host = cfg.get6(subnet_id, Host::IdentifierType::IDENT_DUID,
|
||||
&duids_[host_id]->getDuid()[0],
|
||||
duids_[host_id]->getDuid().size());
|
||||
EXPECT_EQ((host_count / 2)-1, hosts_by_subnet.size());
|
||||
EXPECT_EQ(host_count / 2, hosts_by_address.size());
|
||||
EXPECT_FALSE(host);
|
||||
}
|
||||
|
||||
// This test checks that all reservations for the specified IPv4 subnet can
|
||||
// be deleted.
|
||||
TEST_F(CfgHostsTest, deleteAll4) {
|
||||
|
Reference in New Issue
Block a user