]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2815] Implement del4 function
authorSlawek Figiel <slawek@isc.org>
Thu, 6 Apr 2023 12:00:08 +0000 (14:00 +0200)
committerSlawek Figiel <slawek@isc.org>
Thu, 25 May 2023 11:29:28 +0000 (13:29 +0200)
src/lib/dhcpsrv/cfg_hosts.cc
src/lib/dhcpsrv/hosts_messages.cc
src/lib/dhcpsrv/hosts_messages.h
src/lib/dhcpsrv/hosts_messages.mes
src/lib/dhcpsrv/tests/cfg_hosts_unittest.cc

index 97fb3cb084819898cc14e3aac7f29032aafdef2b..e1da797ff9a0af68c23bc7ad2c324a5e1de4e6b6 100644 (file)
@@ -1131,13 +1131,33 @@ CfgHosts::delAll4(const SubnetID& subnet_id) {
 }
 
 bool
-CfgHosts::del4(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::del4(const SubnetID& subnet_id,
+               const Host::IdentifierType& identifier_type,
+               const uint8_t* identifier_begin,
+               const size_t identifier_len) {
+    HostContainerIndex0& idx = hosts_.get<0>();
+    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 = 0;
+    for (auto key = range.first; key != range.second;) {
+        if ((*key)->getIPv4SubnetID() != subnet_id) {
+            ++key;
+            // Skip hosts from other subnets.
+            continue;
+        }
+
+        key = idx.erase(key);
+        erased++;
+    }
+
+    LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_DEL4)
+        .arg(erased)
+        .arg(subnet_id)
+        .arg(Host::getIdentifierAsText(identifier_type, identifier_begin, identifier_len));
+
+    return (erased != 0);
 }
 
 size_t
index 0eaec09048864b6ad113eb9c2ee57d2507ef956e..c9d0b3f28c768a51db96eaec4455a27b339cc9f7 100644 (file)
@@ -14,6 +14,7 @@ extern const isc::log::MessageID HOSTS_CFG_ADD_HOST = "HOSTS_CFG_ADD_HOST";
 extern const isc::log::MessageID HOSTS_CFG_CACHE_HOST_DATA_SOURCE = "HOSTS_CFG_CACHE_HOST_DATA_SOURCE";
 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_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";
@@ -87,6 +88,7 @@ const char* values[] = {
     "HOSTS_CFG_CACHE_HOST_DATA_SOURCE", "get host cache data source: %1",
     "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_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",
index 937572c83a3ee38a39832fb4a448baed9984bd84..d6ed062d92abd52bd48bb601e16a9992d8bc2b18 100644 (file)
@@ -15,6 +15,7 @@ extern const isc::log::MessageID HOSTS_CFG_ADD_HOST;
 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_DEL_ALL_SUBNET4;
 extern const isc::log::MessageID HOSTS_CFG_DEL_ALL_SUBNET6;
 extern const isc::log::MessageID HOSTS_CFG_GET_ALL;
index 232845deea8923f7bbb86614e7416e0d069d3f18..1bf3ddba7a0d6299e6cadcff44e51b4c4b587498 100644 (file)
@@ -38,6 +38,12 @@ deleted. The second argument specifies how many reservations have been deleted.
 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
+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_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
index efb170c490288284f11310aba3a05b2a59a0d11f..65a2b5a65e5463d4ab043a009c141195c0e39972 100644 (file)
@@ -474,20 +474,20 @@ TEST_F(CfgHostsTest, deleteForIPv4) {
     }
 
     // Get all inserted hosts.
-    HostCollection hostsBySubnet = cfg.getAll4(subnet_id);
-    HostCollection hostsByAddress = cfg.getAll4(address);
+    HostCollection hosts_by_subnet = cfg.getAll4(subnet_id);
+    HostCollection hosts_by_address = cfg.getAll4(address);
     // Make sure the hosts and IP reservations were added.
-    ASSERT_EQ(host_count, hostsBySubnet.size());
-    ASSERT_EQ(1, hostsByAddress.size());
+    ASSERT_EQ(host_count, hosts_by_subnet.size());
+    ASSERT_EQ(1, hosts_by_address.size());
     
     // Delete one host.
     EXPECT_TRUE(cfg.del(subnet_id, address));
 
     // Check if the host is actually deleted.
-    hostsBySubnet = cfg.getAll4(subnet_id);
-    hostsByAddress = cfg.getAll4(address);
-    EXPECT_EQ(host_count-1, hostsBySubnet.size());
-    EXPECT_EQ(0, hostsByAddress.size());
+    hosts_by_subnet = cfg.getAll4(subnet_id);
+    hosts_by_address = cfg.getAll4(address);
+    EXPECT_EQ(host_count-1, hosts_by_subnet.size());
+    EXPECT_EQ(0, hosts_by_address.size());
 }
 
 // This test checks that the IPv6 reservation for the specified subnet ID and
@@ -511,20 +511,20 @@ TEST_F(CfgHostsTest, deleteForIPv6) {
     
 
     // Get all inserted hosts.
-    auto hostsBySubnetAndAddress = cfg.getAll6(subnet_id, address);
-    auto hostsBySubnet = cfg.getAll6(subnet_id);
+    auto hosts_by_subnet_and_address = cfg.getAll6(subnet_id, address);
+    auto hosts_by_subnet = cfg.getAll6(subnet_id);
     // Make sure the hosts and IP reservations were added.
-    ASSERT_EQ(1, hostsBySubnetAndAddress.size());
-    ASSERT_EQ(host_count, hostsBySubnet.size());
+    ASSERT_EQ(1, hosts_by_subnet_and_address.size());
+    ASSERT_EQ(host_count, hosts_by_subnet.size());
     
     // Delete one host.
     EXPECT_TRUE(cfg.del(subnet_id, address));
 
     // Check if the host is actually deleted.
-    hostsBySubnetAndAddress = cfg.getAll6(subnet_id, address);
-    hostsBySubnet = cfg.getAll6(subnet_id);
-    EXPECT_EQ(0, hostsBySubnetAndAddress.size());
-    EXPECT_EQ(host_count-1, hostsBySubnet.size());
+    hosts_by_subnet_and_address = cfg.getAll6(subnet_id, address);
+    hosts_by_subnet = cfg.getAll6(subnet_id);
+    EXPECT_EQ(0, hosts_by_subnet_and_address.size());
+    EXPECT_EQ(host_count-1, hosts_by_subnet.size());
 }
 
 // This test checks that false is returned for deleting the IPv4 reservation
@@ -545,6 +545,61 @@ TEST_F(CfgHostsTest, deleteForMissingIPv6) {
     EXPECT_FALSE(cfg.del(SubnetID(42), IOAddress(("2001:db8:1::1"))));
 }
 
+// This test checks that the reservation for the specified IPv4 subnet and
+// identifier can be deleted.
+TEST_F(CfgHostsTest, del4) {
+    CfgHosts cfg;
+
+    // Add hosts.
+    size_t host_count = 20;
+    size_t host_id = 5;
+    SubnetID subnet_id(42);
+    IOAddress address("10.0.0.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, SUBNET_ID_UNUSED,
+                                        increase(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",
+                                        SubnetID(subnet_id + i + 1), SUBNET_ID_UNUSED,
+                                        increase(address, host_id)));
+        cfg.add(host);
+    }
+
+
+    // Get all inserted hosts.
+    HostCollection hosts_by_subnet = cfg.getAll4(subnet_id);
+    HostCollection hosts_by_address = cfg.getAll4(increase(address, host_id));
+    HostPtr host = cfg.get4(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.del4(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.getAll4(subnet_id);
+    hosts_by_address = cfg.getAll4(increase(address, host_id));
+    host = cfg.get4(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) {