2
0
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:
Slawek Figiel
2023-04-06 17:00:08 +02:00
parent 9fe50d3ea9
commit de78b098d9
6 changed files with 130 additions and 13 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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",

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {