Commit d7d74b34 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3149] getAllocator() implemented

parent b190045d
......@@ -177,23 +177,44 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts,
bool ipv6)
:attempts_(attempts) {
Lease::Type pool_type = ipv6?Lease::TYPE_NA:Lease::TYPE_V4;
Lease::Type basic_type = ipv6?Lease::TYPE_NA:Lease::TYPE_V4;
// Initalize normal address allocators
switch (engine_type) {
case ALLOC_ITERATIVE:
allocator_.reset(new IterativeAllocator(pool_type));
allocators_[basic_type] = AllocatorPtr(new IterativeAllocator(basic_type));
break;
case ALLOC_HASHED:
allocator_.reset(new HashedAllocator(pool_type));
allocators_[basic_type] = AllocatorPtr(new HashedAllocator(basic_type));
break;
case ALLOC_RANDOM:
allocator_.reset(new RandomAllocator(pool_type));
allocators_[basic_type] = AllocatorPtr(new RandomAllocator(basic_type));
break;
default:
isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
}
// If this is IPv6 allocation engine, initalize also temporary addrs
// and prefixes
if (ipv6) {
switch (engine_type) {
case ALLOC_ITERATIVE:
allocators_[Lease::TYPE_TA] = AllocatorPtr(new IterativeAllocator(Lease::TYPE_TA));
allocators_[Lease::TYPE_PD] = AllocatorPtr(new IterativeAllocator(Lease::TYPE_PD));
break;
case ALLOC_HASHED:
allocators_[Lease::TYPE_TA] = AllocatorPtr(new HashedAllocator(Lease::TYPE_TA));
allocators_[Lease::TYPE_PD] = AllocatorPtr(new HashedAllocator(Lease::TYPE_PD));
break;
case ALLOC_RANDOM:
allocators_[Lease::TYPE_TA] = AllocatorPtr(new RandomAllocator(Lease::TYPE_TA));
allocators_[Lease::TYPE_PD] = AllocatorPtr(new RandomAllocator(Lease::TYPE_PD));
break;
default:
isc_throw(BadValue, "Invalid/unsupported allocation algorithm");
}
}
// Register hook points
hook_index_lease4_select_ = Hooks.hook_index_lease4_select_;
hook_index_lease6_select_ = Hooks.hook_index_lease6_select_;
......@@ -212,10 +233,11 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
const isc::hooks::CalloutHandlePtr& callout_handle) {
try {
// That check is not necessary. We create allocator in AllocEngine
// constructor
if (!allocator_) {
isc_throw(InvalidOperation, "No allocator selected");
AllocatorPtr allocator = getAllocator(type);
if (!allocator) {
isc_throw(InvalidOperation, "No allocator specified for "
<< Lease6::typeToText(type));
}
if (!subnet) {
......@@ -296,7 +318,7 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
unsigned int i = attempts_;
do {
IOAddress candidate = allocator_->pickAddress(subnet, duid, hint);
IOAddress candidate = allocator->pickAddress(subnet, duid, hint);
/// @todo: check if the address is reserved once we have host support
/// implemented
......@@ -366,9 +388,12 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
old_lease.reset();
try {
AllocatorPtr allocator = getAllocator(Lease::TYPE_V4);
// Allocator is always created in AllocEngine constructor and there is
// currently no other way to set it, so that check is not really necessary.
if (!allocator_) {
if (!allocator) {
isc_throw(InvalidOperation, "No allocator selected");
}
......@@ -467,7 +492,7 @@ AllocEngine::allocateAddress4(const SubnetPtr& subnet,
unsigned int i = attempts_;
do {
IOAddress candidate = allocator_->pickAddress(subnet, clientid, hint);
IOAddress candidate = allocator->pickAddress(subnet, clientid, hint);
/// @todo: check if the address is reserved once we have host support
/// implemented
......@@ -923,6 +948,16 @@ Lease4Ptr AllocEngine::createLease4(const SubnetPtr& subnet,
}
}
AllocEngine::AllocatorPtr AllocEngine::getAllocator(Lease::Type type) {
std::map<Lease::Type, AllocatorPtr>::const_iterator alloc = allocators_.find(type);
if (alloc == allocators_.end()) {
isc_throw(BadValue, "No allocator initialized for pool type "
<< Lease::typeToText(type));
}
return (alloc->second);
}
AllocEngine::~AllocEngine() {
// no need to delete allocator. smart_ptr will do the trick for us
}
......
......@@ -25,6 +25,8 @@
#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <map>
namespace isc {
namespace dhcp {
......@@ -94,6 +96,9 @@ protected:
Lease::Type pool_type_;
};
/// defines a pointer to allocator
typedef boost::shared_ptr<Allocator> AllocatorPtr;
/// @brief Address/prefix allocator that iterates over all addresses
///
/// This class implements iterative algorithm that returns all addresses in
......@@ -324,6 +329,12 @@ protected:
bool fake_allocation,
const isc::hooks::CalloutHandlePtr& callout_handle);
/// @brief returns allocator for a given pool type
/// @param type type of pool (V4, IA, TA or PD)
/// @throw BadValue if allocator for a given type is missing
/// @return pointer to allocator handing a given resource types
AllocatorPtr getAllocator(Lease::Type type);
/// @brief Destructor. Used during DHCPv6 service shutdown.
virtual ~AllocEngine();
private:
......@@ -456,7 +467,10 @@ private:
bool fake_allocation = false);
/// @brief a pointer to currently used allocator
boost::shared_ptr<Allocator> allocator_;
///
/// For IPv4, there will be only one allocator: TYPE_V4
/// For IPv6, there will be 3 allocators: TYPE_NA, TYPE_TA, TYPE_PD
std::map<Lease::Type, AllocatorPtr> allocators_;
/// @brief number of attempts before we give up lease allocation (0=unlimited)
unsigned int attempts_;
......
......@@ -32,6 +32,8 @@ Lease::Lease(const isc::asiolink::IOAddress& addr, uint32_t t1, uint32_t t2,
std::string
Lease::typeToText(Lease::Type type) {
switch (type) {
case Lease::TYPE_V4:
return string("V4");
case Lease::TYPE_NA:
return string("IA_NA");
case Lease::TYPE_TA:
......
......@@ -64,6 +64,7 @@ public:
// Expose internal classes for testing purposes
using AllocEngine::Allocator;
using AllocEngine::IterativeAllocator;
using AllocEngine::getAllocator;
};
/// @brief Used in Allocation Engine tests for IPv6
......@@ -209,8 +210,8 @@ public:
Lease4Ptr old_lease_; ///< Holds previous instance of the lease.
};
// This test checks if the Allocation Engine can be instantiated and that it
// parses parameters string properly.
// This test checks if the v6 Allocation Engine can be instantiated, parses
// parameters string and allocators are created.
TEST_F(AllocEngine6Test, constructor) {
boost::scoped_ptr<AllocEngine> x;
......@@ -218,7 +219,19 @@ TEST_F(AllocEngine6Test, constructor) {
ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_HASHED, 5)), NotImplemented);
ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_RANDOM, 5)), NotImplemented);
ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)));
ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100, true)));
// Check that allocator for normal addresses is created
ASSERT_TRUE(x->getAllocator(Lease::TYPE_NA));
// Check that allocator for temporary address is created
ASSERT_TRUE(x->getAllocator(Lease::TYPE_TA));
// Check that allocator for prefixes is created
ASSERT_TRUE(x->getAllocator(Lease::TYPE_PD));
// There should be no V4 allocator
EXPECT_THROW(x->getAllocator(Lease::TYPE_V4), BadValue);
}
// This test checks if the simple allocation can succeed
......@@ -632,6 +645,32 @@ TEST_F(AllocEngine6Test, requestReuseExpiredLease6) {
// --- IPv4 ---
// This test checks if the v4 Allocation Engine can be instantiated, parses
// parameters string and allocators are created.
TEST_F(AllocEngine4Test, constructor) {
boost::scoped_ptr<AllocEngine> x;
// Hashed and random allocators are not supported yet
ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_HASHED, 5, false)),
NotImplemented);
ASSERT_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_RANDOM, 5, false)),
NotImplemented);
// Create V4 (ipv6=false) Allocation Engine that will try at most
// 100 attempts to pick up a lease
ASSERT_NO_THROW(x.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100,
false)));
// There should be V4 allocator
ASSERT_TRUE(x->getAllocator(Lease::TYPE_V4));
// Check that allocators for V6 stuff are not created
EXPECT_THROW(x->getAllocator(Lease::TYPE_NA), BadValue);
EXPECT_THROW(x->getAllocator(Lease::TYPE_TA), BadValue);
EXPECT_THROW(x->getAllocator(Lease::TYPE_PD), BadValue);
}
// This test checks if the simple IPv4 allocation can succeed
TEST_F(AllocEngine4Test, simpleAlloc4) {
boost::scoped_ptr<AllocEngine> engine;
......
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