Commit 574356fa authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

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

parent d1be21aa
// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
// Copyright (C) 2015 - 2017 Deutsche Telekom AG.
//
// Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
//
......@@ -1885,6 +1885,16 @@ CqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
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
CqlLeaseMgr::getName() const {
std::string name = "";
......
// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
// Copyright (C) 2015 - 2017 Deutsche Telekom AG.
//
// Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
//
......@@ -379,6 +379,28 @@ public:
/// @return Number of leases deleted.
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
///
/// @return Type of the backend.
......
......@@ -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
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
A warning message issued when the current configuration indicates that multiple
sockets, capable of receiving broadcast traffic, will be opened on some of the
......
// 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
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -539,6 +539,24 @@ public:
/// @return A populated LeaseStatsQuery
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
///
/// 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
/// support transactions, this is a no-op.
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
......
......@@ -1323,5 +1323,62 @@ Memfile_LeaseMgr::startLeaseStatsQuery6() {
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
......@@ -332,6 +332,24 @@ public:
/// @return Number of leases deleted.
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:
/// @brief Deletes all expired-reclaimed leases.
......
......@@ -42,6 +42,9 @@ struct ClientIdSubnetIdIndexTag { };
/// @brief Tag for indexes by client id, HW address and subnet id.
struct ClientIdHWAddressSubnetIdIndexTag { };
/// @brief Tag for indexs by subnet-id.
struct SubnetIdIndexTag { };
/// @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,
&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.
......@@ -210,7 +220,15 @@ typedef boost::multi_index_container<
boost::multi_index::const_mem_fun<Lease, int64_t,
&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.
......@@ -229,6 +247,9 @@ typedef Lease6Storage::index<DuidIaidTypeIndexTag>::type Lease6StorageDuidIaidTy
/// @brief DHCPv6 lease storage index by expiration time.
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.
typedef Lease4Storage::index<AddressIndexTag>::type Lease4StorageAddressIndex;
......@@ -247,6 +268,9 @@ Lease4StorageClientIdSubnetIdIndex;
typedef Lease4Storage::index<ClientIdHWAddressSubnetIdIndexTag>::type
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 namespace
......
......@@ -2100,7 +2100,15 @@ MySqlLeaseMgr::deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
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.
......
......@@ -329,6 +329,28 @@ public:
/// @return Number of leases deleted.
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.
///
/// @param secs Number of seconds since expiration of leases before
......
......@@ -1363,6 +1363,16 @@ PgSqlLeaseMgr::startLeaseStatsQuery6() {
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
PgSqlLeaseMgr::getName() const {
string name = "";
......
......@@ -319,7 +319,7 @@ public:
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS4 query.
/// The query object is then returned.
///
///
/// @return The populated query as a pointer to an LeaseStatsQuery
virtual LeaseStatsQueryPtr startLeaseStatsQuery4();
......@@ -329,10 +329,32 @@ public:
/// invokes its start method, which fetches its statistical data
/// result set by executing the RECOUNT_LEASE_STATS6 query.
/// The query object is then returned.
///
///
/// @return The populated query as a pointer to an LeaseStatsQuery
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
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
......
......@@ -643,4 +643,14 @@ TEST_F(CqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
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
......@@ -2684,6 +2684,69 @@ GenericLeaseMgrTest::testRecountLeaseStats6() {
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 dhcp
......
......@@ -374,6 +374,19 @@ public:
/// after altering the lease states in various ways.
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
std::vector<std::string> straddress4_;
......
// 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
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -223,6 +223,16 @@ public:
" 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.
///
/// Returns the type of the backend (e.g. "mysql", "memfile" etc.)
......
......@@ -1894,4 +1894,16 @@ TEST_F(MemfileLeaseMgrTest, recountLeaseStats6) {
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
......@@ -487,4 +487,14 @@ TEST_F(MySqlLeaseMgrTest, recountLeaseStats6) {
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
......@@ -412,4 +412,14 @@ TEST_F(PgSqlLeaseMgrTest, recountLeaseStats6) {
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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment