BIND 10 trac3150, updated. 154fbc8f1d2a8de45de50799228a52585726d823 [3150] First part of prefix pool support
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Sep 10 18:39:25 UTC 2013
The branch, trac3150 has been updated
via 154fbc8f1d2a8de45de50799228a52585726d823 (commit)
from 48b5e32efb89d2c07b40c0d3e74200b56d984f75 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 154fbc8f1d2a8de45de50799228a52585726d823
Author: Tomek Mrugalski <tomasz at isc.org>
Date: Tue Sep 10 20:39:04 2013 +0200
[3150] First part of prefix pool support
-----------------------------------------------------------------------
Summary of changes:
src/bin/dhcp6/config_parser.cc | 12 +++----
src/lib/dhcpsrv/alloc_engine.cc | 28 ++++++++--------
src/lib/dhcpsrv/alloc_engine.h | 19 +++++++++--
src/lib/dhcpsrv/pool.cc | 4 +--
src/lib/dhcpsrv/pool.h | 41 +++++++++++++-----------
src/lib/dhcpsrv/subnet.cc | 40 ++++++++++++++++++++++-
src/lib/dhcpsrv/subnet.h | 34 ++++++++++++--------
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc | 8 ++---
src/lib/dhcpsrv/tests/subnet_unittest.cc | 8 ++---
9 files changed, 129 insertions(+), 65 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/dhcp6/config_parser.cc b/src/bin/dhcp6/config_parser.cc
index 63bda52..a5c179f 100644
--- a/src/bin/dhcp6/config_parser.cc
+++ b/src/bin/dhcp6/config_parser.cc
@@ -141,13 +141,13 @@ protected:
///
/// @param addr is the IPv6 prefix of the pool.
/// @param len is the prefix length.
- /// @param ptype is the type of IPv6 pool (Pool6::Pool6Type). Note this is
- /// passed in as an int32_t and cast to Pool6Type to accommodate a
+ /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
+ /// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object.
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)));
}
@@ -155,13 +155,13 @@ protected:
///
/// @param min is the first 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
- /// passed in as an int32_t and cast to Pool6Type to accommodate a
+ /// @param ptype is the type of IPv6 pool (Pool::PoolType). Note this is
+ /// passed in as an int32_t and cast to PoolType to accommodate a
/// polymorphic interface.
/// @return returns a PoolPtr to the new Pool4 object.
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)));
}
};
diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc
index 2bef8f8..24dee0b 100644
--- a/src/lib/dhcpsrv/alloc_engine.cc
+++ b/src/lib/dhcpsrv/alloc_engine.cc
@@ -53,8 +53,8 @@ AllocEngineHooks Hooks;
namespace isc {
namespace dhcp {
-AllocEngine::IterativeAllocator::IterativeAllocator()
- :Allocator() {
+AllocEngine::IterativeAllocator::IterativeAllocator(Pool::PoolType lease_type)
+ :Allocator(lease_type) {
}
isc::asiolink::IOAddress
@@ -94,7 +94,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// 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).
- IOAddress last = subnet->getLastAllocated();
+ IOAddress last = subnet->getLastAllocated(lease_type_);
const PoolCollection& pools = subnet->getPools();
@@ -117,7 +117,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
if (it == pools.end()) {
// ok to access first element directly. We checked that pools is non-empty
IOAddress next = pools[0]->getFirstAddress();
- subnet->setLastAllocated(next);
+ subnet->setLastAllocated(next, lease_type_);
return (next);
}
@@ -126,7 +126,7 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
IOAddress next = increaseAddress(last); // basically addr++
if ((*it)->inRange(next)) {
// the next one is in the pool as well, so we haven't hit pool boundary yet
- subnet->setLastAllocated(next);
+ subnet->setLastAllocated(next, lease_type_);
return (next);
}
@@ -136,18 +136,18 @@ AllocEngine::IterativeAllocator::pickAddress(const SubnetPtr& subnet,
// Really out of luck today. That was the last pool. Let's rewind
// to the beginning.
next = pools[0]->getFirstAddress();
- subnet->setLastAllocated(next);
+ subnet->setLastAllocated(next, lease_type_);
return (next);
}
// there is a next pool, let's try first address from it
next = (*it)->getFirstAddress();
- subnet->setLastAllocated(next);
+ subnet->setLastAllocated(next, lease_type_);
return (next);
}
-AllocEngine::HashedAllocator::HashedAllocator()
- :Allocator() {
+AllocEngine::HashedAllocator::HashedAllocator(Pool::PoolType lease_type)
+ :Allocator(lease_type) {
isc_throw(NotImplemented, "Hashed allocator is not implemented");
}
@@ -159,8 +159,8 @@ AllocEngine::HashedAllocator::pickAddress(const SubnetPtr&,
isc_throw(NotImplemented, "Hashed allocator is not implemented");
}
-AllocEngine::RandomAllocator::RandomAllocator()
- :Allocator() {
+AllocEngine::RandomAllocator::RandomAllocator(Pool::PoolType lease_type)
+ :Allocator(lease_type) {
isc_throw(NotImplemented, "Random allocator is not implemented");
}
@@ -177,13 +177,13 @@ AllocEngine::AllocEngine(AllocType engine_type, unsigned int attempts)
:attempts_(attempts) {
switch (engine_type) {
case ALLOC_ITERATIVE:
- allocator_ = boost::shared_ptr<Allocator>(new IterativeAllocator());
+ allocator_.reset(new IterativeAllocator(Pool6::TYPE_IA));
break;
case ALLOC_HASHED:
- allocator_ = boost::shared_ptr<Allocator>(new HashedAllocator());
+ allocator_.reset(new HashedAllocator(Pool6::TYPE_IA));
break;
case ALLOC_RANDOM:
- allocator_ = boost::shared_ptr<Allocator>(new RandomAllocator());
+ allocator_.reset(new RandomAllocator(Pool6::TYPE_IA));
break;
default:
diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h
index ad18b83..553d41b 100644
--- a/src/lib/dhcpsrv/alloc_engine.h
+++ b/src/lib/dhcpsrv/alloc_engine.h
@@ -77,10 +77,20 @@ protected:
pickAddress(const SubnetPtr& subnet, const DuidPtr& duid,
const isc::asiolink::IOAddress& hint) = 0;
+ /// @brief Default constructor.
+ ///
+ /// Specifies which type of leases this allocator will assign
+ Allocator(Pool::PoolType lease_type)
+ :lease_type_(lease_type) {
+ }
+
/// @brief virtual destructor
virtual ~Allocator() {
}
protected:
+
+ /// @brief defines lease type allocation
+ Pool::PoolType lease_type_;
};
/// @brief Address/prefix allocator that iterates over all addresses
@@ -95,7 +105,8 @@ protected:
/// @brief default constructor
///
/// Does not do anything
- IterativeAllocator();
+ /// @param type - specifies allocation type
+ IterativeAllocator(Pool::PoolType type);
/// @brief returns the next address from pools in a subnet
///
@@ -123,7 +134,8 @@ protected:
public:
/// @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.
///
@@ -145,7 +157,8 @@ protected:
public:
/// @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
///
diff --git a/src/lib/dhcpsrv/pool.cc b/src/lib/dhcpsrv/pool.cc
index f624a08..53b62ed 100644
--- a/src/lib/dhcpsrv/pool.cc
+++ b/src/lib/dhcpsrv/pool.cc
@@ -62,7 +62,7 @@ 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)
:Pool(first, last), type_(type) {
@@ -93,7 +93,7 @@ Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& first,
}
}
-Pool6::Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,
+Pool6::Pool6(PoolType type, const isc::asiolink::IOAddress& prefix,
uint8_t prefix_len, uint8_t delegated_len /* = 128 */)
:Pool(prefix, IOAddress("::")),
type_(type), prefix_len_(delegated_len) {
diff --git a/src/lib/dhcpsrv/pool.h b/src/lib/dhcpsrv/pool.h
index 6b58728..e63541d 100644
--- a/src/lib/dhcpsrv/pool.h
+++ b/src/lib/dhcpsrv/pool.h
@@ -32,6 +32,25 @@ class Pool {
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 = 0,
+ TYPE_TA = 1,
+ TYPE_PD = 2,
+ TYPE_V4 = 3
+ } PoolType;
+
/// @brief returns Pool-id
///
/// @return pool-id value
@@ -127,20 +146,6 @@ typedef std::vector<Pool4Ptr> Pool4Collection;
class Pool6 : public Pool {
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
///
/// @throw BadValue if PD is define (PD can be only prefix/len)
@@ -148,7 +153,7 @@ public:
/// @param type type of the pool (IA or TA)
/// @param first the first 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);
/// @brief the constructor for Pool6 "prefix/len" style definition
@@ -172,13 +177,13 @@ public:
/// @param prefix specifies prefix of the pool
/// @param prefix_len specifies prefix length of the pool
/// @param delegated_len specifies lenght of the delegated prefixes
- Pool6(Pool6Type type, const isc::asiolink::IOAddress& prefix,
+ Pool6(PoolType type, const isc::asiolink::IOAddress& prefix,
uint8_t prefix_len, uint8_t delegated_len = 128);
/// @brief returns pool type
///
/// @return pool type
- Pool6Type getType() const {
+ PoolType getType() const {
return (type_);
}
@@ -193,7 +198,7 @@ public:
private:
/// @brief defines a pool type
- Pool6Type type_;
+ PoolType type_;
/// @brief Defines prefix length (for TYPE_PD only)
uint8_t prefix_len_;
diff --git a/src/lib/dhcpsrv/subnet.cc b/src/lib/dhcpsrv/subnet.cc
index 50a0fee..9802a1c 100644
--- a/src/lib/dhcpsrv/subnet.cc
+++ b/src/lib/dhcpsrv/subnet.cc
@@ -30,7 +30,9 @@ Subnet::Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
const Triplet<uint32_t>& valid_lifetime)
:id_(getNextID()), prefix_(prefix), prefix_len_(len), t1_(t1),
t2_(t2), valid_(valid_lifetime),
- last_allocated_(lastAddrInPrefix(prefix, len)) {
+ last_allocated_ia_(lastAddrInPrefix(prefix, len)),
+ last_allocated_ta_(lastAddrInPrefix(prefix, len)),
+ last_allocated_pd_(lastAddrInPrefix(prefix, len)) {
if ((prefix.isV6() && len > 128) ||
(prefix.isV4() && len > 32)) {
isc_throw(BadValue,
@@ -86,6 +88,38 @@ Subnet::getOptionDescriptor(const std::string& option_space,
return (*range.first);
}
+isc::asiolink::IOAddress Subnet::getLastAllocated(Pool::PoolType type) const {
+ switch (type) {
+ case Pool::TYPE_V4:
+ case Pool::TYPE_IA:
+ return last_allocated_ia_;
+ case Pool::TYPE_TA:
+ return last_allocated_ta_;
+ case Pool::TYPE_PD:
+ return last_allocated_pd_;
+ default:
+ isc_throw(BadValue, "Pool type " << type << " not supported");
+ }
+}
+
+void Subnet::setLastAllocated(const isc::asiolink::IOAddress& addr,
+ Pool::PoolType type) {
+ switch (type) {
+ case Pool::TYPE_V4:
+ case Pool::TYPE_IA:
+ last_allocated_ia_ = addr;
+ return;
+ case Pool::TYPE_TA:
+ last_allocated_ta_ = addr;
+ return;
+ case Pool::TYPE_PD:
+ last_allocated_pd_ = addr;
+ return;
+ default:
+ isc_throw(BadValue, "Pool type " << type << " not supported");
+ }
+}
+
std::string
Subnet::toText() const {
std::stringstream tmp;
@@ -104,6 +138,10 @@ Subnet4::Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
}
}
+const PoolCollection& Subnet::getPools() const {
+ return pools_;
+}
+
void
Subnet::addPool(const PoolPtr& pool) {
IOAddress first_addr = pool->getFirstAddress();
diff --git a/src/lib/dhcpsrv/subnet.h b/src/lib/dhcpsrv/subnet.h
index 0ac5109..10d858e 100644
--- a/src/lib/dhcpsrv/subnet.h
+++ b/src/lib/dhcpsrv/subnet.h
@@ -240,10 +240,9 @@ public:
/// @todo: Define map<SubnetID, IOAddress> somewhere in the
/// AllocEngine::IterativeAllocator and keep the data there
///
- /// @return address that was last tried from this pool
- isc::asiolink::IOAddress getLastAllocated() const {
- return (last_allocated_);
- }
+ /// @param type lease type to be returned
+ /// @return address/prefix that was last tried from this pool
+ isc::asiolink::IOAddress getLastAllocated(Pool::PoolType type) const;
/// @brief sets the last address that was tried from this pool
///
@@ -253,9 +252,10 @@ public:
///
/// @todo: Define map<SubnetID, IOAddress> somewhere in the
/// AllocEngine::IterativeAllocator and keep the data there
- void setLastAllocated(const isc::asiolink::IOAddress& addr) {
- last_allocated_ = addr;
- }
+ /// @param addr address/prefix to that was tried last
+ /// @param type lease type to be set
+ void setLastAllocated(const isc::asiolink::IOAddress& addr,
+ Pool::PoolType type);
/// @brief returns unique ID for that subnet
/// @return unique ID for that subnet
@@ -280,7 +280,7 @@ public:
/// @brief Returns a pool without any address specified
/// @return returns one of the pools defined
- PoolPtr getPool() {
+ PoolPtr getAnyPool() {
return (getPool(default_pool()));
}
@@ -295,9 +295,7 @@ public:
/// The reference is only valid as long as the object that returned it.
///
/// @return a collection of all pools
- const PoolCollection& getPools() const {
- return pools_;
- }
+ const PoolCollection& getPools() const;
/// @brief sets name of the network interface for directly attached networks
///
@@ -377,7 +375,17 @@ protected:
/// removing a pool, restarting or changing allocation algorithms. For
/// that purpose it should be only considered a help that should not be
/// fully trusted.
- isc::asiolink::IOAddress last_allocated_;
+ isc::asiolink::IOAddress last_allocated_ia_;
+
+ /// @brief last allocated temporary address
+ ///
+ /// See @ref last_allocated_ia_ for details.
+ isc::asiolink::IOAddress last_allocated_ta_;
+
+ /// @brief last allocated IPv6 prefix
+ ///
+ /// See @ref last_allocated_ia_ for details.
+ isc::asiolink::IOAddress last_allocated_pd_;
/// @brief Name of the network interface (if connected directly)
std::string iface_;
@@ -493,7 +501,7 @@ protected:
/// @brief specifies optional interface-id
OptionPtr interface_id_;
- /// @brief collection of pools in that list
+ /// @brief collection of pools for non-temporary addresses
Pool6Collection pools_;
/// @brief a triplet with preferred lifetime (in seconds)
diff --git a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
index 083c20f..27e31d9 100644
--- a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
+++ b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
@@ -375,7 +375,7 @@ TEST_F(AllocEngine6Test, allocateAddress6Nulls) {
// pool
TEST_F(AllocEngine6Test, IterativeAllocator) {
boost::scoped_ptr<NakedAllocEngine::Allocator>
- alloc(new NakedAllocEngine::IterativeAllocator());
+ alloc(new NakedAllocEngine::IterativeAllocator(Pool6::TYPE_IA));
for (int i = 0; i < 1000; ++i) {
IOAddress candidate = alloc->pickAddress(subnet_, duid_, IOAddress("::"));
@@ -388,7 +388,7 @@ TEST_F(AllocEngine6Test, IterativeAllocator) {
// in all pools in specified subnet. It also must not pick the same address twice
// unless it runs out of pool space and must start over.
TEST_F(AllocEngine6Test, IterativeAllocator_manyPools6) {
- NakedAllocEngine::IterativeAllocator alloc;
+ NakedAllocEngine::IterativeAllocator alloc(Pool6::TYPE_IA);
// let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
for (int i = 2; i < 10; ++i) {
@@ -829,7 +829,7 @@ TEST_F(AllocEngine4Test, allocateAddress4Nulls) {
// pool
TEST_F(AllocEngine4Test, IterativeAllocator) {
boost::scoped_ptr<NakedAllocEngine::Allocator>
- alloc(new NakedAllocEngine::IterativeAllocator());
+ alloc(new NakedAllocEngine::IterativeAllocator(Pool6::TYPE_V4));
for (int i = 0; i < 1000; ++i) {
IOAddress candidate = alloc->pickAddress(subnet_, clientid_,
@@ -843,7 +843,7 @@ TEST_F(AllocEngine4Test, IterativeAllocator) {
// in all pools in specified subnet. It also must not pick the same address twice
// unless it runs out of pool space and must start over.
TEST_F(AllocEngine4Test, IterativeAllocator_manyPools4) {
- NakedAllocEngine::IterativeAllocator alloc;
+ NakedAllocEngine::IterativeAllocator alloc(Pool6::TYPE_V4);
// Let's start from 2, as there is 2001:db8:1::10 - 2001:db8:1::20 pool already.
for (int i = 2; i < 10; ++i) {
diff --git a/src/lib/dhcpsrv/tests/subnet_unittest.cc b/src/lib/dhcpsrv/tests/subnet_unittest.cc
index fbcebcb..14b01d4 100644
--- a/src/lib/dhcpsrv/tests/subnet_unittest.cc
+++ b/src/lib/dhcpsrv/tests/subnet_unittest.cc
@@ -69,7 +69,7 @@ TEST(Subnet4Test, Pool4InSubnet4) {
subnet->addPool(pool1);
// If there's only one pool, get that pool
- PoolPtr mypool = subnet->getPool();
+ PoolPtr mypool = subnet->getAnyPool();
EXPECT_EQ(mypool, pool1);
@@ -78,7 +78,7 @@ TEST(Subnet4Test, Pool4InSubnet4) {
// If there are more than one pool and we didn't provide hint, we
// should get the first pool
- mypool = subnet->getPool();
+ mypool = subnet->getAnyPool();
EXPECT_EQ(mypool, pool1);
@@ -215,7 +215,7 @@ TEST(Subnet6Test, Pool6InSubnet6) {
subnet->addPool(pool1);
// If there's only one pool, get that pool
- PoolPtr mypool = subnet->getPool();
+ PoolPtr mypool = subnet->getAnyPool();
EXPECT_EQ(mypool, pool1);
@@ -224,7 +224,7 @@ TEST(Subnet6Test, Pool6InSubnet6) {
// If there are more than one pool and we didn't provide hint, we
// should get the first pool
- mypool = subnet->getPool();
+ mypool = subnet->getAnyPool();
EXPECT_EQ(mypool, pool1);
More information about the bind10-changes
mailing list