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

[master] Merge branch 'trac3150' (DHCP::CfgMgr support for PD)

Conflicts:
	ChangeLog
parents 7430591b e6f0e891
677. [func] tomek
libdhcpsrv: CfgMgr is now able to store IA, TA and PD pools in
Subnet6 structures.
(Trac #3150, git e6f0e89162bac0adae3ce3141437a282d5183162)
676. [bug] muks 676. [bug] muks
We now also allow the short name ("hmac-md5"), along with the long We now also allow the short name ("hmac-md5"), along with the long
name ("hmac-md5.sig-alg.reg.int") that was allowed before for name ("hmac-md5.sig-alg.reg.int") that was allowed before for
...@@ -21,7 +26,7 @@ ...@@ -21,7 +26,7 @@
for IAPREFIX (Option6_IAPrefix) has been added. for IAPREFIX (Option6_IAPrefix) has been added.
(Trac #3145, git 3a844e85ecc3067ccd1c01841f4a61366cb278f4) (Trac #3145, git 3a844e85ecc3067ccd1c01841f4a61366cb278f4)
672. [func] tmark 672. [func] tmark
Added b10-dhcp-ddnsupdate transaction base class, NameChangeTransaction. Added b10-dhcp-ddnsupdate transaction base class, NameChangeTransaction.
This class provides the common structure and methods to implement the state This class provides the common structure and methods to implement the state
models described in the DHCP_DDNS design, plus integration with DNSClient models described in the DHCP_DDNS design, plus integration with DNSClient
......
...@@ -135,7 +135,8 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast, ...@@ -135,7 +135,8 @@ Dhcpv4Srv::Dhcpv4Srv(uint16_t port, const char* dbconfig, const bool use_bcast,
.arg(LeaseMgrFactory::instance().getName()); .arg(LeaseMgrFactory::instance().getName());
// Instantiate allocation engine // Instantiate allocation engine
alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100)); alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100,
false /* false = IPv4 */));
// Register hook points // Register hook points
hook_index_pkt4_receive_ = Hooks.hook_index_pkt4_receive_; hook_index_pkt4_receive_ = Hooks.hook_index_pkt4_receive_;
......
...@@ -141,13 +141,13 @@ protected: ...@@ -141,13 +141,13 @@ protected:
/// ///
/// @param addr is the IPv6 prefix of the pool. /// @param addr is the IPv6 prefix of the pool.
/// @param len is the prefix length. /// @param len is the prefix length.
/// @param ptype is the type of IPv6 pool (Pool6::Pool6Type). Note this is /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
/// passed in as an int32_t and cast to Pool6Type to accommodate a /// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface. /// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object. /// @return returns a PoolPtr to the new Pool4 object.
PoolPtr poolMaker (IOAddress &addr, uint32_t len, int32_t ptype) PoolPtr poolMaker (IOAddress &addr, uint32_t len, int32_t ptype)
{ {
return (PoolPtr(new Pool6(static_cast<isc::dhcp::Pool6::Pool6Type> return (PoolPtr(new Pool6(static_cast<isc::dhcp::Pool::PoolType>
(ptype), addr, len))); (ptype), addr, len)));
} }
...@@ -155,13 +155,13 @@ protected: ...@@ -155,13 +155,13 @@ protected:
/// ///
/// @param min is the first IPv6 address in the pool. /// @param min is the first IPv6 address in the pool.
/// @param max is the last IPv6 address in the pool. /// @param max is the last IPv6 address in the pool.
/// @param ptype is the type of IPv6 pool (Pool6::Pool6Type). Note this is /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
/// passed in as an int32_t and cast to Pool6Type to accommodate a /// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface. /// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object. /// @return returns a PoolPtr to the new Pool4 object.
PoolPtr poolMaker (IOAddress &min, IOAddress &max, int32_t ptype) PoolPtr poolMaker (IOAddress &min, IOAddress &max, int32_t ptype)
{ {
return (PoolPtr(new Pool6(static_cast<isc::dhcp::Pool6::Pool6Type> return (PoolPtr(new Pool6(static_cast<isc::dhcp::Pool::PoolType>
(ptype), min, max))); (ptype), min, max)));
} }
}; };
......
...@@ -53,8 +53,8 @@ AllocEngineHooks Hooks; ...@@ -53,8 +53,8 @@ AllocEngineHooks Hooks;
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
AllocEngine::IterativeAllocator::IterativeAllocator() AllocEngine::IterativeAllocator::IterativeAllocator(Pool::PoolType lease_type)
:Allocator() { :Allocator(lease_type) {
} }
isc::asiolink::IOAddress isc::asiolink::IOAddress
...@@ -94,9 +94,9 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet, ...@@ -94,9 +94,9 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Let's get the last allocated address. It is usually set correctly, // 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 // but there are times when it won't be (like after removing a pool or
// perhaps restarting the server). // perhaps restarting the server).
IOAddress last = subnet->getLastAllocated(); IOAddress last = subnet->getLastAllocated(pool_type_);
const PoolCollection& pools = subnet->getPools(); const PoolCollection& pools = subnet->getPools(pool_type_);
if (pools.empty()) { if (pools.empty()) {
isc_throw(AllocFailed, "No pools defined in selected subnet"); isc_throw(AllocFailed, "No pools defined in selected subnet");
...@@ -117,7 +117,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet, ...@@ -117,7 +117,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
if (it == pools.end()) { if (it == pools.end()) {
// ok to access first element directly. We checked that pools is non-empty // ok to access first element directly. We checked that pools is non-empty
IOAddress next = pools[0]->getFirstAddress(); IOAddress next = pools[0]->getFirstAddress();
subnet->setLastAllocated(next); subnet->setLastAllocated(pool_type_, next);
return (next); return (next);
} }
...@@ -126,7 +126,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet, ...@@ -126,7 +126,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
IOAddress next = increaseAddress(last); // basically addr++ IOAddress next = increaseAddress(last); // basically addr++
if ((*it)->inRange(next)) { if ((*it)->inRange(next)) {
// the next one is in the pool as well, so we haven't hit pool boundary yet // the next one is in the pool as well, so we haven't hit pool boundary yet
subnet->setLastAllocated(next); subnet->setLastAllocated(pool_type_, next);
return (next); return (next);
} }
...@@ -136,18 +136,18 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet, ...@@ -136,18 +136,18 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Really out of luck today. That was the last pool. Let's rewind // Really out of luck today. That was the last pool. Let's rewind
// to the beginning. // to the beginning.
next = pools[0]->getFirstAddress(); next = pools[0]->getFirstAddress();
subnet->setLastAllocated(next); subnet->setLastAllocated(pool_type_, next);
return (next); return (next);
} }
// there is a next pool, let's try first address from it // there is a next pool, let's try first address from it
next = (*it)->getFirstAddress(); next = (*it)->getFirstAddress();
subnet->setLastAllocated(next); subnet->setLastAllocated(pool_type_, next);
return (next); return (next);
} }
AllocEngine::HashedAllocator::HashedAllocator() AllocEngine::HashedAllocator::HashedAllocator(Pool::PoolType lease_type)
:Allocator() { :Allocator(lease_type) {
isc_throw(NotImplemented, "Hashed allocator is not implemented"); isc_throw(NotImplemented, "Hashed allocator is not implemented");
} }
...@@ -159,8 +159,8 @@ AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&, ...@@ -159,8 +159,8 @@ AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&,
isc_throw(NotImplemented, "Hashed allocator is not implemented"); isc_throw(NotImplemented, "Hashed allocator is not implemented");
} }
AllocEngine::RandomAllocator::RandomAllocator() AllocEngine::RandomAllocator::RandomAllocator(Pool::PoolType lease_type)
:Allocator() { :Allocator(lease_type) {
isc_throw(NotImplemented, "Random allocator is not implemented"); isc_throw(NotImplemented, "Random allocator is not implemented");
} }
...@@ -173,17 +173,21 @@ AllocEngine::RandomAllocator::pickAddress(const SubnetPtr&, ...@@ -173,17 +173,21 @@ AllocEngine::RandomAllocator::pickAddress(const SubnetPtr&,
} }
AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts) AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts,
bool ipv6)
:attempts_(attempts) { :attempts_(attempts) {
Pool::PoolType pool_type = ipv6?Pool::TYPE_IA:Pool::TYPE_V4;
switch (engine_type) { switch (engine_type) {
case ALLOC_ITERATIVE: case ALLOC_ITERATIVE:
allocator_ = boost::shared_ptr<Allocator>(new IterativeAllocator()); allocator_.reset(new IterativeAllocator(pool_type));
break; break;
case ALLOC_HASHED: case ALLOC_HASHED:
allocator_ = boost::shared_ptr<Allocator>(new HashedAllocator()); allocator_.reset(new HashedAllocator(pool_type));
break; break;
case ALLOC_RANDOM: case ALLOC_RANDOM:
allocator_ = boost::shared_ptr<Allocator>(new RandomAllocator()); allocator_.reset(new RandomAllocator(pool_type));
break; break;
default: default:
......
...@@ -77,10 +77,21 @@ protected: ...@@ -77,10 +77,21 @@ protected:
pickAddress(const SubnetPtr& subnet, const DuidPtr& duid, pickAddress(const SubnetPtr& subnet, const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0; const isc::asiolink::IOAddress& hint) = 0;
/// @brief Default constructor.
///
/// Specifies which type of leases this allocator will assign
/// @param pool_type specifies pool type (addresses, temp. addr or prefixes)
Allocator(Pool::PoolType pool_type)
:pool_type_(pool_type) {
}
/// @brief virtual destructor /// @brief virtual destructor
virtual ~Allocator() { virtual ~Allocator() {
} }
protected: protected:
/// @brief defines lease type allocation
Pool::PoolType pool_type_;
}; };
/// @brief Address/prefix allocator that iterates over all addresses /// @brief Address/prefix allocator that iterates over all addresses
...@@ -95,7 +106,8 @@ protected: ...@@ -95,7 +106,8 @@ protected:
/// @brief default constructor /// @brief default constructor
/// ///
/// Does not do anything /// Does not do anything
IterativeAllocator(); /// @param type - specifies allocation type
IterativeAllocator(Pool::PoolType type);
/// @brief returns the next address from pools in a subnet /// @brief returns the next address from pools in a subnet
/// ///
...@@ -123,7 +135,8 @@ protected: ...@@ -123,7 +135,8 @@ protected:
public: public:
/// @brief default constructor (does nothing) /// @brief default constructor (does nothing)
HashedAllocator(); /// @param type - specifies allocation type
HashedAllocator(Pool::PoolType type);
/// @brief returns an address based on hash calculated from client's DUID. /// @brief returns an address based on hash calculated from client's DUID.
/// ///
...@@ -145,7 +158,8 @@ protected: ...@@ -145,7 +158,8 @@ protected:
public: public:
/// @brief default constructor (does nothing) /// @brief default constructor (does nothing)
RandomAllocator(); /// @param type - specifies allocation type
RandomAllocator(Pool::PoolType type);
/// @brief returns an random address from pool of specified subnet /// @brief returns an random address from pool of specified subnet
/// ///
...@@ -180,7 +194,8 @@ protected: ...@@ -180,7 +194,8 @@ protected:
/// @param engine_type selects allocation algorithm /// @param engine_type selects allocation algorithm
/// @param attempts number of attempts for each lease allocation before /// @param attempts number of attempts for each lease allocation before
/// we give up (0 means unlimited) /// we give up (0 means unlimited)
AllocEngine(AllocType engine_type, unsigned int attempts); /// @param ipv6 specifies if the engine should work for IPv4 or IPv6
AllocEngine(AllocType engine_type, unsigned int attempts, bool ipv6 = true);
/// @brief Returns IPv4 lease. /// @brief Returns IPv4 lease.
/// ///
......
...@@ -21,9 +21,9 @@ using namespace isc::asiolink; ...@@ -21,9 +21,9 @@ using namespace isc::asiolink;
namespace isc { namespace isc {
namespace dhcp { namespace dhcp {
Pool::Pool(const isc::asiolink::IOAddress& first, Pool::Pool(PoolType type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last) const isc::asiolink::IOAddress& last)
:id_(getNextID()), first_(first), last_(last) { :id_(getNextID()), first_(first), last_(last), type_(type) {
} }
bool Pool::inRange(const isc::asiolink::IOAddress& addr) const { bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
...@@ -32,7 +32,7 @@ bool Pool::inRange(const isc::asiolink::IOAddress& addr) const { ...@@ -32,7 +32,7 @@ bool Pool::inRange(const isc::asiolink::IOAddress& addr) const {
Pool4::Pool4(const isc::asiolink::IOAddress& first, Pool4::Pool4(const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last) const isc::asiolink::IOAddress& last)
:Pool(first, last) { :Pool(Pool::TYPE_V4, first, last) {
// check if specified address boundaries are sane // check if specified address boundaries are sane
if (!first.isV4() || !last.isV4()) { if (!first.isV4() || !last.isV4()) {
isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4"); isc_throw(BadValue, "Invalid Pool4 address boundaries: not IPv4");
...@@ -43,9 +43,8 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first, ...@@ -43,9 +43,8 @@ Pool4::Pool4(const isc::asiolink::IOAddress& first,
} }
} }
Pool4::Pool4(const isc::asiolink::IOAddress& prefix, Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len)
uint8_t prefix_len) :Pool(Pool::TYPE_V4, prefix, IOAddress("0.0.0.0")) {
:Pool(prefix, IOAddress("0.0.0.0")) {
// check if the prefix is sane // check if the prefix is sane
if (!prefix.isV4()) { if (!prefix.isV4()) {
...@@ -62,15 +61,21 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix, ...@@ -62,15 +61,21 @@ Pool4::Pool4(const isc::asiolink::IOAddress& prefix,
} }
Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first, Pool6::Pool6(PoolType type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last) const isc::asiolink::IOAddress& last)
:Pool(first, last), type_(type) { :Pool(type, first, last), prefix_len_(128) {
// check if specified address boundaries are sane // check if specified address boundaries are sane
if (!first.isV6() || !last.isV6()) { if (!first.isV6() || !last.isV6()) {
isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6"); isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
} }
if ( (type != Pool::TYPE_IA) && (type != Pool::TYPE_TA) &&
(type != Pool::TYPE_PD)) {
isc_throw(BadValue, "Invalid Pool6 type: " << static_cast<int>(type)
<< ", must be TYPE_IA, TYPE_TA or TYPE_PD");
}
if (last < first) { if (last < first) {
isc_throw(BadValue, "Upper boundary is smaller than lower boundary."); isc_throw(BadValue, "Upper boundary is smaller than lower boundary.");
// This check is a bit strict. If we decide that it is too strict, // This check is a bit strict. If we decide that it is too strict,
...@@ -88,23 +93,34 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first, ...@@ -88,23 +93,34 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
// parameters are for IA and TA only. There is another dedicated // parameters are for IA and TA only. There is another dedicated
// constructor for that (it uses prefix/length) // constructor for that (it uses prefix/length)
if ((type != TYPE_IA) && (type != TYPE_TA)) { if ((type != TYPE_IA) && (type != TYPE_TA)) {
isc_throw(BadValue, "Invalid Pool6 type specified"); isc_throw(BadValue, "Invalid Pool6 type specified:"
<< static_cast<int>(type));
} }
} }
Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix, Pool6::Pool6(PoolType type, const isc::asiolink::IOAddress& prefix,
uint8_t prefix_len) uint8_t prefix_len, uint8_t delegated_len /* = 128 */)
:Pool(prefix, IOAddress("::")), :Pool(type, prefix, IOAddress("::")), prefix_len_(delegated_len) {
type_(type) {
// check if the prefix is sane // check if the prefix is sane
if (!prefix.isV6()) { if (!prefix.isV6()) {
isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6"); isc_throw(BadValue, "Invalid Pool6 address boundaries: not IPv6");
} }
// check if the prefix length is sane // check if the prefix length is sane
if (prefix_len == 0 || prefix_len > 128) { if (prefix_len == 0 || prefix_len > 128) {
isc_throw(BadValue, "Invalid prefix length"); isc_throw(BadValue, "Invalid prefix length: " << prefix_len);
}
if (prefix_len > delegated_len) {
isc_throw(BadValue, "Delegated length (" << static_cast<int>(delegated_len)
<< ") must be longer than prefix length ("
<< static_cast<int>(prefix_len) << ")");
}
if ( ( (type == TYPE_IA) || (type == TYPE_TA)) && (delegated_len != 128)) {
isc_throw(BadValue, "For IA or TA pools, delegated prefix length must "
<< " be 128.");
} }
/// @todo: We should probably implement checks against weird addresses /// @todo: We should probably implement checks against weird addresses
......
...@@ -32,6 +32,25 @@ class Pool { ...@@ -32,6 +32,25 @@ class Pool {
public: public:
/// @brief specifies Pool type
///
/// Currently there are 3 pool types defined in DHCPv6:
/// - Non-temporary addresses (conveyed in IA_NA)
/// - Temporary addresses (conveyed in IA_TA)
/// - Delegated Prefixes (conveyed in IA_PD)
///
/// The fourth one (TYPE_V4) is used in DHCPv4 use cases when getPool()
/// code is shared between v4 and v6 code.
///
/// There is a new one being worked on (IA_PA, see draft-ietf-dhc-host-gen-id), but
/// support for it is not planned for now.
typedef enum {
TYPE_IA,
TYPE_TA,
TYPE_PD,
TYPE_V4
} PoolType;
/// @brief returns Pool-id /// @brief returns Pool-id
/// ///
/// @return pool-id value /// @return pool-id value
...@@ -58,6 +77,20 @@ public: ...@@ -58,6 +77,20 @@ public:
/// @return true, if the address is in pool /// @return true, if the address is in pool
bool inRange(const isc::asiolink::IOAddress& addr) const; bool inRange(const isc::asiolink::IOAddress& addr) const;
/// @brief Returns pool type (v4, v6 non-temporary, v6 temp, v6 prefix)
/// @return returns pool type
PoolType getType() const {
return (type_);
}
/// @brief virtual destructor
///
/// We need Pool to be a polymorphic class, so we could dynamic cast
/// from PoolPtr to Pool6Ptr if we need to. A class becomes polymorphic,
/// when there is at least one virtual method.
virtual ~Pool() {
}
protected: protected:
/// @brief protected constructor /// @brief protected constructor
...@@ -65,7 +98,12 @@ protected: ...@@ -65,7 +98,12 @@ protected:
/// This constructor is protected to prevent anyone from instantiating /// This constructor is protected to prevent anyone from instantiating
/// Pool class directly. Instances of Pool4 and Pool6 should be created /// Pool class directly. Instances of Pool4 and Pool6 should be created
/// instead. /// instead.
Pool(const isc::asiolink::IOAddress& first, ///
/// @param type type of the pool
/// @param first first address of a range
/// @param last last address of a range
Pool(PoolType type,
const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last); const isc::asiolink::IOAddress& last);
/// @brief returns the next unique Pool-ID /// @brief returns the next unique Pool-ID
...@@ -91,6 +129,9 @@ protected: ...@@ -91,6 +129,9 @@ protected:
/// ///
/// @todo: This field is currently not used. /// @todo: This field is currently not used.
std::string comments_; std::string comments_;
/// @brief defines a pool type
PoolType type_;
}; };
/// @brief Pool information for IPv4 addresses /// @brief Pool information for IPv4 addresses
...@@ -117,9 +158,6 @@ public: ...@@ -117,9 +158,6 @@ public:
/// @brief a pointer an IPv4 Pool /// @brief a pointer an IPv4 Pool
typedef boost::shared_ptr<Pool4> Pool4Ptr; typedef boost::shared_ptr<Pool4> Pool4Ptr;
/// @brief a container for IPv4 Pools
typedef std::vector<Pool4Ptr> Pool4Collection;
/// @brief Pool information for IPv6 addresses and prefixes /// @brief Pool information for IPv6 addresses and prefixes
/// ///
/// It holds information about pool6, i.e. a range of IPv6 address space that /// It holds information about pool6, i.e. a range of IPv6 address space that
...@@ -127,55 +165,70 @@ typedef std::vector<Pool4Ptr> Pool4Collection; ...@@ -127,55 +165,70 @@ typedef std::vector<Pool4Ptr> Pool4Collection;
class Pool6 : public Pool { class Pool6 : public Pool {
public: public:
/// @brief specifies Pool type
///
/// Currently there are 3 pool types defined in DHCPv6:
/// - Non-temporary addresses (conveyed in IA_NA)
/// - Temporary addresses (conveyed in IA_TA)
/// - Delegated Prefixes (conveyed in IA_PD)
/// There is a new one being worked on (IA_PA, see draft-ietf-dhc-host-gen-id), but
/// support for it is not planned for now.
typedef enum {
TYPE_IA,
TYPE_TA,
TYPE_PD
} Pool6Type;
/// @brief the constructor for Pool6 "min-max" style definition /// @brief the constructor for Pool6 "min-max" style definition
/// ///
/// @param type type of the pool (IA, TA or PD) /// @throw BadValue if PD is define (PD can be only prefix/len)
///
/// @param type type of the pool (IA or TA)
/// @param first the first address in a pool /// @param first the first address in a pool
/// @param last the last address in a pool /// @param last the last address in a pool
Pool6(Pool6Type type, const isc::asiolink::IOAddress& first, Pool6(PoolType type, const isc::asiolink::IOAddress& first,
const isc::asiolink::IOAddress& last); const isc::asiolink::IOAddress& last);
/// @brief the constructor for Pool6 "prefix/len" style definition /// @brief the constructor for Pool6 "prefix/len" style definition
/// ///
/// For addressed, this is just a prefix/len definition. For prefixes,
/// there is one extra additional parameter delegated_len. It specifies
/// a size of delegated prefixes that the pool will be split into. For
/// example pool 2001:db8::/56, delegated_len=64 means that there is a
/// pool 2001:db8::/56. It will be split into 256 prefixes of length /64,
/// e.g. 2001:db8:0:1::/64, 2001:db8:0:2::/64 etc.
///
/// Naming convention:
/// A smaller prefix length yields a shorter prefix which describes a larger
/// set of addresses. A larger length yields a longer prefix which describes
/// a smaller set of addresses.
///
/// Obviously, prefix_len must define shorter or equal prefix length than
/// delegated_len, so prefix_len <= delegated_len. Note that it is slightly
/// confusing: bigger (larger) prefix actually has smaller prefix length,
/// e.g. /56 is a bigger prefix than /64, but has shorter (smaller) prefix
/// length.
///
/// @throw BadValue if delegated_len is defined for non-PD types or
/// when delegated_len < prefix_len
///
/// @param type type of the pool (IA, TA or PD) /// @param type type of the pool (IA, TA or PD)
/// @param prefix specifies prefix of the pool /// @param prefix specifies prefix of the pool
/// @param prefix_len specifies length of the prefix of the pool /// @param prefix_len specifies prefix length of the pool
Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,