cfg_db->createManagers();
// Reset counters related to connections as all managers have been recreated.
srv->getNetworkState()->reset(NetworkState::Origin::DB_CONNECTION);
- CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
+
} catch (const std::exception& ex) {
err << "Unable to open database: " << ex.what();
return (isc::config::createAnswer(CONTROL_RESULT_ERROR, err.str()));
}
return (ConstElementPtr());
+ }
+
+ // Initialize the allocators. If the user selected a Free Lease Queue Allocator
+ // for any of the subnets, the server will now populate free leases to the queue.
+ // It may take a while!
+ try {
+ CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->initAllocatorsAfterConfigure();
+
+ } catch (const std::exception& ex) {
+ err << "Error initializing the lease allocators: "
+ << ex.what();
}
isc::data::ConstElementPtr
}
return (ConstElementPtr());
+ // Initialize the allocators. If the user selected a Free Lease Queue Allocator
+ // for any of the subnets, the server will now populate free leases to the queue.
+ // It may take a while!
+ try {
+ CfgMgr::instance().getStagingCfg()->getCfgSubnets6()->initAllocatorsAfterConfigure();
+
+ } catch (const std::exception& ex) {
+ err << "Error initializing the lease allocators: " << ex.what();
+ }
+
}
isc::data::ConstElementPtr
This debug message is issued when a subnet is successfully removed from the
server configuration. The argument identifies the removed subnet.
+% DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES populating free address leases for the FLQ allocator in subnet %1; it can take a while!
+This informational message is issued when the server begins building a queue
+of free address leases for the given subnet. It can take a considerable amount
+of time, depending on the size of the address pools.
+
+% DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES_DONE populating free address leases for the FLQ allocator in subnet %1 completed
+This informational message is issued when the server ends building a queue
+of free address leases for a given subnet.
+
+% DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES populating free prefix leases for the FLQ allocator in subnet %1; it can take a while!
+This informational message is issued when the server begins building a queue
+of free leases for the given subnet. It can take a considerable amount of
+time, depending on the size of the delegated prefix pools.
+
+% DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES_DONE populating free prefix leases for the FLQ allocator in subnet %1 completed
+This informational message is issued when the server ends building a queue
+of free prefix leases for a given subnet.
+
% DHCPSRV_CFGMGR_IPV4_RESERVATIONS_NON_UNIQUE_IGNORED ignoring "ip-reservations-unique" setting because at least one of the host database backends does not support non-unique IP reservations in a subnet
This warning message is issued when the server failed to use the new setting
of the ip-reservations-unique global parameter configured via the configuration
#include <config.h>
#include <asiolink/addr_utilities.h>
+#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/flq_allocator.h>
#include <dhcpsrv/ip_range_permutation.h>
#include <dhcpsrv/lease_mgr_factory.h>
template<typename LeaseCollectionType>
void
FreeLeaseQueueAllocator::populateFreeAddressLeases(const LeaseCollectionType& leases, const PoolCollection& pools) {
+ auto subnet = subnet_.lock();
+ LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES)
+ .arg(subnet->toText());
+
// Let's iterate over the lease queue and index them with the
// unordered_set. Also, elminate the expired leases and those
// in the expired-reclaimed state.
}
}
}
+ LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_ADDRESS_LEASES_DONE)
+ .arg(subnet->toText());
}
void
FreeLeaseQueueAllocator::populateFreePrefixDelegationLeases(const Lease6Collection& leases, const PoolCollection& pools) {
+ auto subnet = subnet_.lock();
+ LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES)
+ .arg(subnet->toText());
+
// Let's iterate over the lease queue and index them with the
// unordered_set. Also, elminate the expired leases and those
// in the expired-reclaimed state.
}
}
}
+ LOG_INFO(dhcpsrv_logger, DHCPSRV_CFGMGR_FLQ_POPULATE_FREE_PREFIX_LEASES_DONE)
+ .arg(subnet->toText());
}
SubnetFreeLeaseQueueAllocationStatePtr
NetworkPtr& network) {
if (network_data->contains("allocator")) {
auto allocator_type = getString(network_data, "allocator");
- if ((allocator_type != "iterative") && (allocator_type != "random")) {
+ if ((allocator_type != "iterative") && (allocator_type != "random") &&
+ (allocator_type != "flq")) {
// Unsupported allocator type used.
- isc_throw(DhcpConfigError, "supported allocators are: iterative and random");
+ isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
}
network->setAllocatorType(allocator_type);
}
Network6Ptr& network) {
if (network_data->contains("pd-allocator")) {
auto allocator_type = getString(network_data, "pd-allocator");
- if ((allocator_type != "iterative") && (allocator_type != "random")) {
+ if ((allocator_type != "iterative") && (allocator_type != "random") &&
+ (allocator_type != "flq")) {
// Unsupported allocator type used.
- isc_throw(DhcpConfigError, "supported allocators are: iterative and random");
+ isc_throw(DhcpConfigError, "supported allocators are: iterative, random and flq");
}
network->setPdAllocatorType(allocator_type);
}
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/dhcpsrv_log.h>
+#include <dhcpsrv/flq_allocation_state.h>
+#include <dhcpsrv/flq_allocator.h>
#include <dhcpsrv/iterative_allocation_state.h>
#include <dhcpsrv/iterative_allocator.h>
#include <dhcpsrv/random_allocation_state.h>
if (sn4ptr->getAllocatorType() == "random") {
sn4ptr->setAllocator(Lease::TYPE_V4,
- boost::make_shared<RandomAllocator>
- (Lease::TYPE_V4, sn4ptr));
+ boost::make_shared<RandomAllocator>
+ (Lease::TYPE_V4, sn4ptr));
sn4ptr->setAllocationState(Lease::TYPE_V4, SubnetAllocationStatePtr());
for (auto pool : *pools_) {
pool->setAllocationState(PoolRandomAllocationState::create(pool));
}
+ } else if (sn4ptr->getAllocatorType() == "flq") {
+ sn4ptr->setAllocator(Lease::TYPE_V4,
+ boost::make_shared<FreeLeaseQueueAllocator>
+ (Lease::TYPE_V4, sn4ptr));
+ for (auto pool : *pools_) {
+ pool->setAllocationState(PoolFreeLeaseQueueAllocationState::create(pool));
+ }
+
} else {
for (auto pool : *pools_) {
pool->setAllocationState(PoolIterativeAllocationState::create(pool));
sn6ptr->setAllocationState(Lease::TYPE_NA, SubnetAllocationStatePtr());
sn6ptr->setAllocationState(Lease::TYPE_TA, SubnetAllocationStatePtr());
+ } else if (sn6ptr->getAllocatorType() == "flq") {
+ isc_throw(BadValue, "Free Lease Queue allocator is not supported for IPv6 address pools");
}
// Repeat the same for the delegated prefix allocator.
if (sn6ptr->getPdAllocatorType() == "random") {
sn6ptr->setAllocator(Lease::TYPE_PD,
- boost::make_shared<RandomAllocator>
- (Lease::TYPE_PD, sn6ptr));
+ boost::make_shared<RandomAllocator>
+ (Lease::TYPE_PD, sn6ptr));
sn6ptr->setAllocationState(Lease::TYPE_PD, SubnetAllocationStatePtr());
+ } else if (sn6ptr->getPdAllocatorType() == "flq") {
+ sn6ptr->setAllocator(Lease::TYPE_PD,
+ boost::make_shared<FreeLeaseQueueAllocator>
+ (Lease::TYPE_PD, sn6ptr));
+ sn6ptr->setAllocationState(Lease::TYPE_PD, SubnetAllocationStatePtr());
}
// Create states for the pools.
for (auto pool : *pools_) {
switch (pool->getType()) {
- case Lease::TYPE_V4:
case Lease::TYPE_NA:
case Lease::TYPE_TA:
if (sn6ptr->getAllocatorType() == "random") {
pool->setAllocationState(PoolRandomAllocationState::create(pool));
+
} else {
pool->setAllocationState(PoolIterativeAllocationState::create(pool));
}
case Lease::TYPE_PD:
if (sn6ptr->getPdAllocatorType() == "random") {
pool->setAllocationState(PoolRandomAllocationState::create(pool));
+
+ } else if (sn6ptr->getPdAllocatorType() == "flq") {
+ pool->setAllocationState(PoolFreeLeaseQueueAllocationState::create(pool));
+
} else {
pool->setAllocationState(PoolIterativeAllocationState::create(pool));
}
break;
+ default:
+ continue;
}
}
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfg_mac_source.h>
+#include <dhcpsrv/flq_allocator.h>
+#include <dhcpsrv/flq_allocation_state.h>
#include <dhcpsrv/iterative_allocator.h>
#include <dhcpsrv/iterative_allocation_state.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
EXPECT_TRUE(boost::dynamic_pointer_cast<RandomAllocator>(allocator));
}
+// This test verifies that Free Lease Queue allocator can be selected for
+// a subnet.
+TEST_F(ParseConfigTest, flqSubnetAllocator4) {
+ std::string config =
+ "{"
+ " \"subnet4\": [ {"
+ " \"subnet\": \"192.0.2.0/24\","
+ " \"id\": 1,"
+ " \"allocator\": \"flq\""
+ " } ]"
+ "}";
+
+ ElementPtr json = Element::fromJSON(config);
+ EXPECT_TRUE(json);
+ ConstElementPtr status = parseElementSet(json, false);
+ int rcode = 0;
+ ConstElementPtr comment = parseAnswer(rcode, status);
+ ASSERT_EQ(0, rcode);
+
+ auto subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets4()->getBySubnetId(1);
+ ASSERT_TRUE(subnet);
+
+ EXPECT_EQ("flq", subnet->getAllocatorType().get());
+ auto allocator = subnet->getAllocator(Lease::TYPE_V4);
+ ASSERT_TRUE(allocator);
+ EXPECT_TRUE(boost::dynamic_pointer_cast<FreeLeaseQueueAllocator>(allocator));
+}
+
// This test verifies that unknown allocator is rejected.
TEST_F(ParseConfigTest, invalidSubnetAllocator4) {
std::string config =
ASSERT_EQ(comment->getType(), Element::string);
EXPECT_EQ(1, rcode);
std::string expected = "Configuration parsing failed: ";
- expected += "supported allocators are: iterative and random";
+ expected += "supported allocators are: iterative, random and flq";
EXPECT_EQ(expected, comment->stringValue());
}
EXPECT_TRUE(boost::dynamic_pointer_cast<IterativeAllocator>(allocator));
}
+// This test verifies that FLQ allocator is not supported for
+// IPv6 address pools.
+TEST_F(ParseConfigTest, flqSubnetAllocator6) {
+ std::string config =
+ "{"
+ " \"subnet6\": [ {"
+ " \"subnet\": \"2001:db8:1::/64\","
+ " \"id\": 1,"
+ " \"allocator\": \"flq\""
+ " } ]"
+ "}";
+
+ ElementPtr json = Element::fromJSON(config);
+ EXPECT_TRUE(json);
+ ConstElementPtr status = parseElementSet(json, false);
+ int rcode = 0;
+ ConstElementPtr comment = parseAnswer(rcode, status);
+ ASSERT_TRUE(comment);
+ ASSERT_EQ(comment->getType(), Element::string);
+ EXPECT_EQ(1, rcode);
+ std::string expected = "Configuration parsing failed: ";
+ expected += "Free Lease Queue allocator is not supported for IPv6 address pools";
+ EXPECT_EQ(expected, comment->stringValue());
+}
+
// This test verifies that unknown allocator is rejected.
TEST_F(ParseConfigTest, invalidSubnetAllocator6) {
std::string config =
ASSERT_EQ(comment->getType(), Element::string);
EXPECT_EQ(1, rcode);
std::string expected = "Configuration parsing failed: ";
- expected += "supported allocators are: iterative and random";
+ expected += "supported allocators are: iterative, random and flq";
EXPECT_EQ(expected, comment->stringValue());
}
ASSERT_EQ(comment->getType(), Element::string);
EXPECT_EQ(1, rcode);
std::string expected = "Configuration parsing failed: ";
- expected += "supported allocators are: iterative and random";
+ expected += "supported allocators are: iterative, random and flq";
EXPECT_EQ(expected, comment->stringValue());
}