Commit 4b7664cc authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3171] IterativeAllocator::pickAddress() now handles prefixes as well

 - pickAddress() handles prefixes as well
 - Subnet::delPools() implemented
 - tests for iterating over address and prefix pools implemented.
parent e2954383
......@@ -137,6 +137,9 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
const DuidPtr&,
const IOAddress&) {
// Is this prefix allocation?
bool prefix = pool_type_ == Lease::TYPE_PD;
// Let's get the last allocated address. It is usually set correctly,
// but there are times when it won't be (like after removing a pool or
// perhaps restarting the server).
......@@ -169,7 +172,18 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Ok, we have a pool that the last address belonged to, let's use it.
IOAddress next = increaseAddress(last); // basically addr++
IOAddress next("::");
if (!prefix) {
next = increaseAddress(last); // basically addr++
} else {
Pool6Ptr pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
if (!pool6) {
// Something is gravely wrong here
isc_throw(InvalidParameter, "Wrong type of pool");
}
// Get the next prefix
next = increasePrefix(last, (pool6)->getLength());
}
if ((*it)->inRange(next)) {
// the next one is in the pool as well, so we haven't hit pool boundary yet
subnet->setLastAllocated(pool_type_, next);
......
......@@ -243,6 +243,25 @@ Subnet::addPool(const PoolPtr& pool) {
}
}
void
Subnet::delPools(Lease::Type type) {
switch (type) {
case Lease::TYPE_V4:
case Lease::TYPE_NA:
pools_.clear();
return;
case Lease::TYPE_TA:
pools_ta_.clear();
return;
case Lease::TYPE_PD:
pools_pd_.clear();
return;
default:
isc_throw(BadValue, "Invalid pool type specified: "
<< static_cast<int>(type));
}
}
void
Subnet::setIface(const std::string& iface_name) {
iface_ = iface_name;
......
......@@ -272,6 +272,13 @@ public:
/// @param pool pool to be added
void addPool(const PoolPtr& pool);
/// @brief Deletes all pools of specified type
///
/// This method is used for testing purposes only
/// @param type type of pools to be deleted
void delPools(Lease::Type type);
/// @brief Returns a pool that specified address belongs to
///
/// If there is no pool that the address belongs to (hint is invalid), other
......
......@@ -451,10 +451,100 @@ TEST_F(AllocEngine6Test, IterativeAllocator) {
}
}
// This test verifies that the allocator iterates over addresses properly
TEST_F(AllocEngine6Test, IterativeAllocatorAddrStep) {
NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
subnet_->delPools(Lease::TYPE_NA); // Get rid of default pool
Pool6Ptr pool1(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::1"),
IOAddress("2001:db8:1::5")));
Pool6Ptr pool2(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::100"),
IOAddress("2001:db8:1::100")));
Pool6Ptr pool3(new Pool6(Lease::TYPE_NA, IOAddress("2001:db8:1::105"),
IOAddress("2001:db8:1::106")));
subnet_->addPool(pool1);
subnet_->addPool(pool2);
subnet_->addPool(pool3);
// Let's check the first pool (5 addresses here)
EXPECT_EQ("2001:db8:1::1", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::3", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::4", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::5", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// The second pool is easy - only one address here
EXPECT_EQ("2001:db8:1::100", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// This is the third and last pool, with 2 addresses in it
EXPECT_EQ("2001:db8:1::105", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::106", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// We iterated over all addresses and reached to the end of the last pool.
// Let's wrap around and start from the beginning
EXPECT_EQ("2001:db8:1::1", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:1::2", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
}
TEST_F(AllocEngine6Test, IterativeAllocatorPrefixStep) {
NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_PD);
subnet_.reset(new Subnet6(IOAddress("2001:db8::"), 32, 1, 2, 3, 4));
Pool6Ptr pool1(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8::"), 56, 60));
Pool6Ptr pool2(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1::"), 48, 48));
Pool6Ptr pool3(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:2::"), 56, 64));
subnet_->addPool(pool1);
subnet_->addPool(pool2);
subnet_->addPool(pool3);
// We have a 2001:db8::/48 subnet that has 3 pools defined in it:
// 2001:db8::/56 split into /60 prefixes (16 leases) (or 2001:db8:0:X0::)
// 2001:db8:1::/48 split into a single /48 prefix (just 1 lease)
// 2001:db8:2::/56 split into /64 prefixes (256 leases) (or 2001:db8:2:XX::)
// First pool check (Let's check over all 16 leases)
EXPECT_EQ("2001:db8::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:20::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:30::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:40::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:50::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:60::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:70::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:80::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:90::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:a0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:b0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:c0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:d0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:e0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:f0::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// Second pool (just one lease here)
EXPECT_EQ("2001:db8:1::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// Third pool (256 leases, let's check first and last explictly and the
// rest over in a pool
EXPECT_EQ("2001:db8:2::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
for (int i = 1; i < 255; i++) {
stringstream exp;
exp << "2001:db8:2:" << hex << i << dec << "::";
EXPECT_EQ(exp.str(), alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
}
EXPECT_EQ("2001:db8:2:ff::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
// Ok, we've iterated over all prefixes in all pools. We now wrap around.
// We're looping over now (iterating over first pool again)
EXPECT_EQ("2001:db8::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
EXPECT_EQ("2001:db8:0:10::", alloc.pickAddress(subnet_, duid_, IOAddress("::")).toText());
}
// This test verifies that the iterative allocator can step over addresses
TEST_F(AllocEngine6Test, IterativeAllocatorAddressIncrease) {
NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_NA);
// Let's pick the first address
IOAddress addr1 = alloc.pickAddress(subnet_, duid_, IOAddress("2001:db8:1::10"));
......@@ -469,8 +559,11 @@ TEST_F(AllocEngine6Test, IterativeAllocatorAddrStep) {
checkAddrIncrease(alloc, "2001:db8::ffff", "2001:db8::1:0");
checkAddrIncrease(alloc, "::", "::1");
checkAddrIncrease(alloc, "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "::");
}
// Check that prefixes can be increased properly
// This test verifies that the allocator can step over prefixes
TEST_F(AllocEngine6Test, IterativeAllocatorPrefixIncrease) {
NakedAllocEngine::NakedIterativeAllocator alloc(Lease::TYPE_PD);
// For /128 prefix, increasePrefix should work the same as addressIncrease
checkPrefixIncrease(alloc, "2001:db8::9", 128, "2001:db8::a");
......
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