-// Copyright (C) 2015 - 2016 Deutsche Telekom AG.
+// Copyright (C) 2015 - 2017 Deutsche Telekom AG.
//
// Author: Razvan Becheriu <razvan.becheriu@qualitance.com>
//
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>
//
/// @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.
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
/// @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.)
/// 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
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
/// @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.
/// @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.
///
//@{
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.
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.
/// @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;
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
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.
/// @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
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 = "";
/// 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();
/// 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.)
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
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
/// 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
" 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.)
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
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
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