Browse Source

[5280] leaseWipe4,6 implemented in lease managers (base and memfile)

Tomek Mrugalski 7 years ago
parent
commit
574356fa9e

+ 11 - 1
src/lib/dhcpsrv/cql_lease_mgr.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
+// Copyright (C) 2015 - 2017 Deutsche Telekom AG.
 //
 //
 // Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
 // Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
 //
 //
@@ -1885,6 +1885,16 @@ CqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
     return (result);
     return (result);
 }
 }
 
 
+size_t
+CqlLeaseMgr::wipeLeases4(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases4 is not implemented for Cassandra backend");
+}
+
+size_t
+CqlLeaseMgr::wipeLeases6(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases6 is not implemented for Cassandra backend");
+}
+
 std::string
 std::string
 CqlLeaseMgr::getName() const {
 CqlLeaseMgr::getName() const {
     std::string name = "";
     std::string name = "";

+ 23 - 1
src/lib/dhcpsrv/cql_lease_mgr.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
+// Copyright (C) 2015 - 2017 Deutsche Telekom AG.
 //
 //
 // Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
 // Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
 //
 //
@@ -379,6 +379,28 @@ public:
     /// @return Number of leases deleted.
     /// @return Number of leases deleted.
     virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t );
     virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t );
 
 
+    /// @brief Removes specified IPv4 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases4(const SubnetID& subnet_id);
+
+    /// @brief Removed specified IPv6 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases6(const SubnetID& subnet_id);
+
     /// @brief Return backend type
     /// @brief Return backend type
     ///
     ///
     /// @return Type of the backend.
     /// @return Type of the backend.

+ 21 - 0
src/lib/dhcpsrv/dhcpsrv_messages.mes

@@ -545,6 +545,27 @@ lease from the memory file database for the specified address.
 A debug message issued when the server is attempting to update IPv6
 A debug message issued when the server is attempting to update IPv6
 lease from the memory file database for the specified address.
 lease from the memory file database for the specified address.
 
 
+% DHCPSRV_MEMFILE_WIPE_LEASES4 removing all IPv4 leases from subnet %1
+This informational message is printed when removal of all leases from
+specified IPv4 subnet is commencing. This is a result of receiving administrative
+command.
+
+% DHCPSRV_MEMFILE_WIPE_LEASES4_FINISHED removing all IPv4 leases from subnet %1 finished, removed %2 leases
+This informational message is printed when removal of all leases from
+a specified IPv4 subnet has finished. The number of removed leases is
+printed.
+
+% DHCPSRV_MEMFILE_WIPE_LEASES6 removing all IPv6 leases from subnet %1
+This informational message is printed when removal of all leases from
+specified IPv6 subnet is commencing. This is a result of receiving administrative
+command.
+
+% DHCPSRV_MEMFILE_WIPE_LEASES6_FINISHED removing all IPv6 leases from subnet %1 finished, removed %2 leases
+This informational message is printed when removal of all leases from
+a specified IPv6 subnet has finished. The number of removed leases is
+printed.
+
+
 % DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE current configuration will result in opening multiple broadcast capable sockets on some interfaces and some DHCP messages may be duplicated
 % DHCPSRV_MULTIPLE_RAW_SOCKETS_PER_IFACE current configuration will result in opening multiple broadcast capable sockets on some interfaces and some DHCP messages may be duplicated
 A warning message issued when the current configuration indicates that multiple
 A warning message issued when the current configuration indicates that multiple
 sockets, capable of receiving broadcast traffic, will be opened on some of the
 sockets, capable of receiving broadcast traffic, will be opened on some of the

+ 19 - 5
src/lib/dhcpsrv/lease_mgr.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -539,6 +539,24 @@ public:
     /// @return A populated LeaseStatsQuery
     /// @return A populated LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
 
 
+    /// @brief Virtual method which removes specified leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @param subnet_id identifier of the subnet (or 0 for all subnets)
+    /// @return number of leases removed.
+    virtual size_t wipeLeases4(const SubnetID& subnet_id) = 0;
+
+    /// @brief Virtual method which removes specified leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @param subnet_id identifier of the subnet (or 0 for all subnets)
+    /// @return number of leases removed.
+    virtual size_t wipeLeases6(const SubnetID& subnet_id) = 0;
+
     /// @brief Return backend type
     /// @brief Return backend type
     ///
     ///
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
@@ -588,10 +606,6 @@ public:
     /// Rolls back all pending database operations.  On databases that don't
     /// Rolls back all pending database operations.  On databases that don't
     /// support transactions, this is a no-op.
     /// support transactions, this is a no-op.
     virtual void rollback() = 0;
     virtual void rollback() = 0;
-
-    /// @todo: Add host management here
-    /// As host reservation is outside of scope for 2012, support for hosts
-    /// is currently postponed.
 };
 };
 
 
 }; // end of isc::dhcp namespace
 }; // end of isc::dhcp namespace

+ 57 - 0
src/lib/dhcpsrv/memfile_lease_mgr.cc

@@ -1323,5 +1323,62 @@ Memfile_LeaseMgr::startLeaseStatsQuery6() {
     return(query);
     return(query);
 }
 }
 
 
+size_t Memfile_LeaseMgr::wipeLeases4(const SubnetID& subnet_id) {
+    LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES4)
+        .arg(subnet_id);
+
+    // Get the index by DUID, IAID, lease type.
+    const Lease4StorageSubnetIdIndex& idx = storage4_.get<SubnetIdIndexTag>();
+
+    // Try to get the lease using the DUID, IAID and lease type.
+    std::pair<Lease4StorageSubnetIdIndex::const_iterator,
+              Lease4StorageSubnetIdIndex::const_iterator> l =
+        idx.equal_range(subnet_id);
+
+    // Let's collect all leases.
+    Lease4Collection leases;
+    for(auto lease = l.first; lease != l.second; ++lease) {
+        leases.push_back(*lease);
+    }
+
+    size_t num = leases.size();
+    for (auto l = leases.begin(); l != leases.end(); ++l) {
+        deleteLease((*l)->addr_);
+    }
+    LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES4_FINISHED)
+        .arg(subnet_id).arg(num);
+
+    return (num);
+}
+
+size_t Memfile_LeaseMgr::wipeLeases6(const SubnetID& subnet_id) {
+    LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES6)
+        .arg(subnet_id);
+
+    // Get the index by DUID, IAID, lease type.
+    const Lease6StorageSubnetIdIndex& idx = storage6_.get<SubnetIdIndexTag>();
+
+    // Try to get the lease using the DUID, IAID and lease type.
+    std::pair<Lease6StorageSubnetIdIndex::const_iterator,
+              Lease6StorageSubnetIdIndex::const_iterator> l =
+        idx.equal_range(subnet_id);
+
+    // Let's collect all leases.
+    Lease6Collection leases;
+    for(auto lease = l.first; lease != l.second; ++lease) {
+        leases.push_back(*lease);
+    }
+
+    size_t num = leases.size();
+    for (auto l = leases.begin(); l != leases.end(); ++l) {
+        deleteLease((*l)->addr_);
+    }
+    LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_WIPE_LEASES6_FINISHED)
+        .arg(subnet_id).arg(num);
+
+    return (num);
+}
+
+
 } // end of namespace isc::dhcp
 } // end of namespace isc::dhcp
 } // end of namespace isc
 } // end of namespace isc

+ 18 - 0
src/lib/dhcpsrv/memfile_lease_mgr.h

@@ -332,6 +332,24 @@ public:
     /// @return Number of leases deleted.
     /// @return Number of leases deleted.
     virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs);
     virtual uint64_t deleteExpiredReclaimedLeases6(const uint32_t secs);
 
 
+    /// @brief Removes specified IPv4 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases4(const SubnetID& subnet_id);
+
+    /// @brief Removed specified IPv6 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases6(const SubnetID& subnet_id);
+
 private:
 private:
 
 
     /// @brief Deletes all expired-reclaimed leases.
     /// @brief Deletes all expired-reclaimed leases.

+ 24 - 0
src/lib/dhcpsrv/memfile_lease_storage.h

@@ -42,6 +42,9 @@ struct ClientIdSubnetIdIndexTag { };
 /// @brief Tag for indexes by client id, HW address and subnet id.
 /// @brief Tag for indexes by client id, HW address and subnet id.
 struct ClientIdHWAddressSubnetIdIndexTag { };
 struct ClientIdHWAddressSubnetIdIndexTag { };
 
 
+/// @brief Tag for indexs by subnet-id.
+struct SubnetIdIndexTag { };
+
 /// @name Multi index containers holding DHCPv4 and DHCPv6 leases.
 /// @name Multi index containers holding DHCPv4 and DHCPv6 leases.
 ///
 ///
 //@{
 //@{
@@ -103,6 +106,13 @@ typedef boost::multi_index_container<
                 boost::multi_index::const_mem_fun<Lease, int64_t,
                 boost::multi_index::const_mem_fun<Lease, int64_t,
                                                   &Lease::getExpirationTime>
                                                   &Lease::getExpirationTime>
             >
             >
+        >,
+
+        // Specification of the fourth index starts here.
+        // This index sorts leases by SubnetID.
+        boost::multi_index::ordered_non_unique<
+            boost::multi_index::tag<SubnetIdIndexTag>,
+            boost::multi_index::member<Lease, isc::dhcp::SubnetID, &Lease::subnet_id_>
         >
         >
      >
      >
 > Lease6Storage; // Specify the type name of this container.
 > Lease6Storage; // Specify the type name of this container.
@@ -210,7 +220,15 @@ typedef boost::multi_index_container<
                 boost::multi_index::const_mem_fun<Lease, int64_t,
                 boost::multi_index::const_mem_fun<Lease, int64_t,
                                                   &Lease::getExpirationTime>
                                                   &Lease::getExpirationTime>
             >
             >
+        >,
+
+        // Specification of the sixth index starts here.
+        // This index sorts leases by SubnetID.
+        boost::multi_index::ordered_non_unique<
+            boost::multi_index::tag<SubnetIdIndexTag>,
+            boost::multi_index::member<Lease, isc::dhcp::SubnetID, &Lease::subnet_id_>
         >
         >
+
     >
     >
 > Lease4Storage; // Specify the type name for this container.
 > Lease4Storage; // Specify the type name for this container.
 
 
@@ -229,6 +247,9 @@ typedef Lease6Storage::index<DuidIaidTypeIndexTag>::type Lease6StorageDuidIaidTy
 /// @brief DHCPv6 lease storage index by expiration time.
 /// @brief DHCPv6 lease storage index by expiration time.
 typedef Lease6Storage::index<ExpirationIndexTag>::type Lease6StorageExpirationIndex;
 typedef Lease6Storage::index<ExpirationIndexTag>::type Lease6StorageExpirationIndex;
 
 
+/// @brief DHCPv6 lease storage index by Subnet-id.
+typedef Lease6Storage::index<SubnetIdIndexTag>::type Lease6StorageSubnetIdIndex;
+
 /// @brief DHCPv4 lease storage index by address.
 /// @brief DHCPv4 lease storage index by address.
 typedef Lease4Storage::index<AddressIndexTag>::type Lease4StorageAddressIndex;
 typedef Lease4Storage::index<AddressIndexTag>::type Lease4StorageAddressIndex;
 
 
@@ -247,6 +268,9 @@ Lease4StorageClientIdSubnetIdIndex;
 typedef Lease4Storage::index<ClientIdHWAddressSubnetIdIndexTag>::type
 typedef Lease4Storage::index<ClientIdHWAddressSubnetIdIndexTag>::type
 Lease4StorageClientIdHWAddressSubnetIdIndex;
 Lease4StorageClientIdHWAddressSubnetIdIndex;
 
 
+/// @brief DHCPv4 lease storage index by client id, HW address and subnet id.
+typedef Lease4Storage::index<SubnetIdIndexTag>::type Lease4StorageSubnetIdIndex;
+
 //@}
 //@}
 } // end of isc::dhcp namespace
 } // end of isc::dhcp namespace
 } // end of isc namespace
 } // end of isc namespace

+ 8 - 0
src/lib/dhcpsrv/mysql_lease_mgr.cc

@@ -2100,7 +2100,15 @@ MySqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
     return (deleted_leases);
     return (deleted_leases);
 }
 }
 
 
+size_t
+MySqlLeaseMgr::wipeLeases4(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases4 is not implemented for MySQL backend");
+}
 
 
+size_t
+MySqlLeaseMgr::wipeLeases6(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases6 is not implemented for MySQL backend");
+}
 
 
 // Miscellaneous database methods.
 // Miscellaneous database methods.
 
 

+ 22 - 0
src/lib/dhcpsrv/mysql_lease_mgr.h

@@ -329,6 +329,28 @@ public:
     /// @return Number of leases deleted.
     /// @return Number of leases deleted.
     virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs);
     virtual uint64_t deleteExpiredReclaimedLeases4(const uint32_t secs);
 
 
+    /// @brief Removes specified IPv4 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases4(const SubnetID& subnet_id);
+
+    /// @brief Removed specified IPv6 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases6(const SubnetID& subnet_id);
+
     /// @brief Deletes all expired-reclaimed DHCPv6 leases.
     /// @brief Deletes all expired-reclaimed DHCPv6 leases.
     ///
     ///
     /// @param secs Number of seconds since expiration of leases before
     /// @param secs Number of seconds since expiration of leases before

+ 10 - 0
src/lib/dhcpsrv/pgsql_lease_mgr.cc

@@ -1363,6 +1363,16 @@ PgSqlLeaseMgr::startLeaseStatsQuery6() {
     return(query);
     return(query);
 }
 }
 
 
+size_t
+PgSqlLeaseMgr::wipeLeases4(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases4 is not implemented for PgSQL backend");
+}
+
+size_t
+PgSqlLeaseMgr::wipeLeases6(const SubnetID& /*subnet_id*/) {
+    isc_throw(NotImplemented, "wipeLeases6 is not implemented for PgSQL backend");
+}
+
 string
 string
 PgSqlLeaseMgr::getName() const {
 PgSqlLeaseMgr::getName() const {
     string name = "";
     string name = "";

+ 24 - 2
src/lib/dhcpsrv/pgsql_lease_mgr.h

@@ -319,7 +319,7 @@ public:
     /// invokes its start method, which fetches its statistical data
     /// invokes its start method, which fetches its statistical data
     /// result set by executing the RECOUNT_LEASE_STATS4 query.
     /// result set by executing the RECOUNT_LEASE_STATS4 query.
     /// The query object is then returned.
     /// The query object is then returned.
-    /// 
+    ///
     /// @return The populated query as a pointer to an LeaseStatsQuery
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
     virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
 
 
@@ -329,10 +329,32 @@ public:
     /// invokes its start method, which fetches its statistical data
     /// invokes its start method, which fetches its statistical data
     /// result set by executing the RECOUNT_LEASE_STATS6 query.
     /// result set by executing the RECOUNT_LEASE_STATS6 query.
     /// The query object is then returned.
     /// The query object is then returned.
-    /// 
+    ///
     /// @return The populated query as a pointer to an LeaseStatsQuery
     /// @return The populated query as a pointer to an LeaseStatsQuery
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
     virtual LeaseStatsQueryPtr startLeaseStatsQuery6();
 
 
+    /// @brief Removes specified IPv4 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases4(const SubnetID& subnet_id);
+
+    /// @brief Removed specified IPv6 leases.
+    ///
+    /// This rather dangerous method is able to remove all leases from specified
+    /// subnet.
+    ///
+    /// @todo: Not implemented yet.
+    ///
+    /// @param subnet_id identifier of the subnet
+    /// @return number of leases removed.
+    virtual size_t wipeLeases6(const SubnetID& subnet_id);
+
     /// @brief Return backend type
     /// @brief Return backend type
     ///
     ///
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)

+ 10 - 0
src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc

@@ -643,4 +643,14 @@ TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
     testDeleteExpiredReclaimedLeases4();
     testDeleteExpiredReclaimedLeases4();
 }
 }
 
 
+// Tests that leases from specific subnet can be removed.
+TEST_F(CqlLeaseMgrTest, DISABLED_wipeLeases4) {
+    testWipeLeases4();
+}
+
+// Tests that leases from specific subnet can be removed.
+TEST_F(CqlLeaseMgrTest, DISABLED_wipeLeases6) {
+    testWipeLeases6();
+}
+
 }; // Of anonymous namespace
 }; // Of anonymous namespace

+ 63 - 0
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc

@@ -2684,6 +2684,69 @@ GenericLeaseMgrTest::testRecountLeaseStats6() {
     ASSERT_NO_FATAL_FAILURE(checkLeaseStats(expectedStats));
     ASSERT_NO_FATAL_FAILURE(checkLeaseStats(expectedStats));
 }
 }
 
 
+void
+GenericLeaseMgrTest::testWipeLeases6() {
+    // Get the leases to be used for the test and add to the database
+    vector<Lease6Ptr> leases = createLeases6();
+    leases[0]->subnet_id_ = 1;
+    leases[1]->subnet_id_ = 1;
+    leases[2]->subnet_id_ = 1;
+    leases[3]->subnet_id_ = 22;
+    leases[4]->subnet_id_ = 333;
+    leases[5]->subnet_id_ = 333;
+    leases[6]->subnet_id_ = 333;
+    leases[7]->subnet_id_ = 333;
+
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // Let's try something simple. There shouldn't be any leases in
+    // subnet 2. The keep deleting the leases, perhaps in a different
+    // order they were added.
+    EXPECT_EQ(0, lmptr_->wipeLeases6(2));
+    EXPECT_EQ(4, lmptr_->wipeLeases6(333));
+    EXPECT_EQ(3, lmptr_->wipeLeases6(1));
+    EXPECT_EQ(1, lmptr_->wipeLeases6(22));
+
+    // All the leases should be gone now. Check that that repeated
+    // attempt to delete them will not result in any additional removals.
+    EXPECT_EQ(0, lmptr_->wipeLeases6(1));
+    EXPECT_EQ(0, lmptr_->wipeLeases6(22));
+    EXPECT_EQ(0, lmptr_->wipeLeases6(333));
+}
+
+void
+GenericLeaseMgrTest::testWipeLeases4() {
+    // Get the leases to be used for the test and add to the database
+    vector<Lease4Ptr> leases = createLeases4();
+    leases[0]->subnet_id_ = 1;
+    leases[1]->subnet_id_ = 1;
+    leases[2]->subnet_id_ = 1;
+    leases[3]->subnet_id_ = 22;
+    leases[4]->subnet_id_ = 333;
+    leases[5]->subnet_id_ = 333;
+    leases[6]->subnet_id_ = 333;
+    leases[7]->subnet_id_ = 333;
+
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // Let's try something simple. There shouldn't be any leases in
+    // subnet 2. The keep deleting the leases, perhaps in a different
+    // order they were added.
+    EXPECT_EQ(0, lmptr_->wipeLeases4(2));
+    EXPECT_EQ(4, lmptr_->wipeLeases4(333));
+    EXPECT_EQ(3, lmptr_->wipeLeases4(1));
+    EXPECT_EQ(1, lmptr_->wipeLeases4(22));
+
+    // All the leases should be gone now. Check that that repeated
+    // attempt to delete them will not result in any additional removals.
+    EXPECT_EQ(0, lmptr_->wipeLeases4(1));
+    EXPECT_EQ(0, lmptr_->wipeLeases4(22));
+    EXPECT_EQ(0, lmptr_->wipeLeases4(333));
+}
 
 
 }; // namespace test
 }; // namespace test
 }; // namespace dhcp
 }; // namespace dhcp

+ 13 - 0
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h

@@ -374,6 +374,19 @@ public:
     /// after altering the lease states in various ways.
     /// after altering the lease states in various ways.
     void testRecountLeaseStats6();
     void testRecountLeaseStats6();
 
 
+
+    /// @brief Check if wipeLeases4 works properly.
+    ///
+    /// This test creates a bunch of leases in several subnets and then
+    /// attempts to delete them, one subnet at a time.
+    void testWipeLeases4();
+
+    /// @brief Check if wipeLeases6 works properly.
+    ///
+    /// This test creates a bunch of leases in several subnets and then
+    /// attempts to delete them, one subnet at a time.
+    void testWipeLeases6();
+
     /// @brief String forms of IPv4 addresses
     /// @brief String forms of IPv4 addresses
     std::vector<std::string>  straddress4_;
     std::vector<std::string>  straddress4_;
 
 

+ 11 - 1
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012-2015 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2017 Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // This Source Code Form is subject to the terms of the Mozilla Public
 // This Source Code Form is subject to the terms of the Mozilla Public
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -223,6 +223,16 @@ public:
                   " is not implemented");
                   " is not implemented");
     }
     }
 
 
+    /// @brief Pretends to will all IPv4 leases from a subnet
+    virtual size_t wipeLeases4(const SubnetID&) {
+        isc_throw(NotImplemented, "ConreteLeaseMgr::wipeLeases4 not implemented");
+    }
+
+    /// @brief Pretends to will all IPv4 leases from a subnet
+    virtual size_t wipeLeases6(const SubnetID&) {
+        isc_throw(NotImplemented, "ConreteLeaseMgr::wipeLeases4 not implemented");
+    }
+
     /// @brief Returns backend type.
     /// @brief Returns backend type.
     ///
     ///
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
     /// Returns the type of the backend (e.g. "mysql", "memfile" etc.)

+ 12 - 0
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc

@@ -1894,4 +1894,16 @@ TEST_F(MemfileLeaseMgrTest, recountLeaseStats6) {
     testRecountLeaseStats6();
     testRecountLeaseStats6();
 }
 }
 
 
+// Tests that leases from specific subnet can be removed.
+TEST_F(MemfileLeaseMgrTest, wipeLeases4) {
+    startBackend(V4);
+    testWipeLeases4();
+}
+
+// Tests that leases from specific subnet can be removed.
+TEST_F(MemfileLeaseMgrTest, wipeLeases6) {
+    startBackend(V6);
+    testWipeLeases6();
+}
+
 }; // end of anonymous namespace
 }; // end of anonymous namespace

+ 10 - 0
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -487,4 +487,14 @@ TEST_F(MySqlLeaseMgrTest, recountLeaseStats6) {
     testRecountLeaseStats6();
     testRecountLeaseStats6();
 }
 }
 
 
+// Tests that leases from specific subnet can be removed.
+TEST_F(MySqlLeaseMgrTest, DISABLED_wipeLeases4) {
+    testWipeLeases4();
+}
+
+// Tests that leases from specific subnet can be removed.
+TEST_F(MySqlLeaseMgrTest, DISABLED_wipeLeases6) {
+    testWipeLeases6();
+}
+
 }; // Of anonymous namespace
 }; // Of anonymous namespace

+ 10 - 0
src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc

@@ -412,4 +412,14 @@ TEST_F(PgSqlLeaseMgrTest, recountLeaseStats6) {
     testRecountLeaseStats6();
     testRecountLeaseStats6();
 }
 }
 
 
+// Tests that leases from specific subnet can be removed.
+TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases4) {
+    testWipeLeases4();
+}
+
+// Tests that leases from specific subnet can be removed.
+TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases6) {
+    testWipeLeases6();
+}
+
 }; // namespace
 }; // namespace