11#include <boost/pointer_cast.hpp>
27 const uint8_t prefix_len) {
30 "increase prefix " << prefix <<
")");
34 const std::vector<uint8_t>& vec = prefix.toBytes();
36 if (prefix_len < 1 || prefix_len > 128) {
41 uint8_t n_bytes = (prefix_len - 1)/8;
42 uint8_t n_bits = 8 - (prefix_len - n_bytes*8);
43 uint8_t mask = 1 << n_bits;
52 uint8_t packed[V6ADDRESS_LEN];
55 memcpy(packed, &vec[0], V6ADDRESS_LEN);
58 if (packed[n_bytes] + uint16_t(mask) < 256u) {
59 packed[n_bytes] += mask;
64 packed[n_bytes] += mask;
67 for (
int i = n_bytes - 1; i >= 0; --i) {
81 const uint8_t prefix_len) {
90IterativeAllocator::pickAddressInternal(
const ClientClasses& client_classes,
96 IOAddress last = getSubnetState()->getLastAllocated();
98 bool retrying =
false;
107 PoolCollection::const_iterator it;
108 PoolCollection::const_iterator first = pools.end();
110 for (it = pools.begin(); it != pools.end(); ++it) {
111 if (!(*it)->clientSupported(client_classes)) {
114 if (first == pools.end()) {
117 if ((*it)->inRange(last)) {
123 if (first == pools.end()) {
124 isc_throw(AllocFailed,
"No allowed pools defined in selected subnet");
132 if (it == pools.end()) {
139 for (; it != pools.end(); ++it) {
140 if ((*it)->clientSupported(client_classes)) {
144 if (it == pools.end()) {
150 last = getPoolState(*it)->getLastAllocated();
151 valid = getPoolState(*it)->isLastAllocatedValid();
152 if (!valid && (last == (*it)->getFirstAddress())) {
154 getPoolState(*it)->setLastAllocated(last);
155 getSubnetState()->setLastAllocated(last);
159 if (valid && !(*it)->inRange(last)) {
161 getPoolState(*it)->resetLastAllocated();
162 getPoolState(*it)->setLastAllocated((*it)->getFirstAddress());
167 if ((*it)->inRange(next)) {
170 getPoolState(*it)->setLastAllocated(next);
171 getSubnetState()->setLastAllocated(next);
175 getPoolState(*it)->resetLastAllocated();
183 for (it = first; it != pools.end(); ++it) {
184 if ((*it)->clientSupported(client_classes)) {
185 getPoolState(*it)->setLastAllocated((*it)->getFirstAddress());
186 getPoolState(*it)->resetLastAllocated();
191 last = getPoolState(*first)->getLastAllocated();
192 getPoolState(*first)->setLastAllocated(last);
193 getSubnetState()->setLastAllocated(last);
198IterativeAllocator::pickPrefixInternal(
const ClientClasses& client_classes,
201 PrefixLenMatchType prefix_length_match,
203 uint8_t hint_prefix_length) {
204 uint8_t prefix_len = 0;
209 IOAddress last = getSubnetState()->getLastAllocated();
211 bool retrying =
false;
216 isc_throw(AllocFailed,
"No pools defined in selected subnet");
220 PoolCollection::const_iterator it;
221 PoolCollection::const_iterator first = pools.end();
223 for (it = pools.begin(); it != pools.end(); ++it) {
224 if (!(*it)->clientSupported(client_classes)) {
228 hint_prefix_length)) {
231 if (first == pools.end()) {
234 if ((*it)->inRange(last)) {
240 if (first == pools.end()) {
241 isc_throw(AllocFailed,
"No allowed pools defined in selected subnet");
249 if (it == pools.end()) {
256 for (; it != pools.end(); ++it) {
257 if ((*it)->clientSupported(client_classes)) {
259 hint_prefix_length)) {
265 if (it == pools.end()) {
271 last = getPoolState(*it)->getLastAllocated();
272 valid = getPoolState(*it)->isLastAllocatedValid();
273 if (!valid && (last == (*it)->getFirstAddress())) {
275 getPoolState(*it)->setLastAllocated(last);
276 getSubnetState()->setLastAllocated(last);
278 pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
290 if (valid && !(*it)->inRange(last)) {
292 getPoolState(*it)->resetLastAllocated();
293 getPoolState(*it)->setLastAllocated((*it)->getFirstAddress());
298 pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
307 prefix_len = pool6->getLength();
310 if ((*it)->inRange(next)) {
313 getPoolState(*it)->setLastAllocated(next);
314 getSubnetState()->setLastAllocated(next);
318 getPoolState(*it)->resetLastAllocated();
326 for (it = first; it != pools.end(); ++it) {
327 if ((*it)->clientSupported(client_classes)) {
329 hint_prefix_length)) {
332 getPoolState(*it)->setLastAllocated((*it)->getFirstAddress());
333 getPoolState(*it)->resetLastAllocated();
338 last = getPoolState(*first)->getLastAllocated();
339 getPoolState(*first)->setLastAllocated(last);
340 getSubnetState()->setLastAllocated(last);
342 pool6 = boost::dynamic_pointer_cast<Pool6>(*first);
353IterativeAllocator::getSubnetState()
const {
355 if (!subnet->getAllocationState(
pool_type_)) {
358 return (boost::dynamic_pointer_cast<SubnetIterativeAllocationState>(subnet->getAllocationState(
pool_type_)));
362IterativeAllocator::getPoolState(
const PoolPtr& pool)
const {
363 if (!pool->getAllocationState()) {
366 return (boost::dynamic_pointer_cast<PoolIterativeAllocationState>(pool->getAllocationState()));
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown when an unexpected error condition occurs.
The IOAddress class represents an IP addresses (version agnostic)
static IOAddress increase(const IOAddress &addr)
Returns an address increased by one.
static IOAddress fromBytes(short family, const uint8_t *data)
Creates an address from over wire data.
An exception that is thrown when allocation module fails (e.g.
Base class for all address/prefix allocation algorithms.
Lease::Type pool_type_
Defines pool type allocation.
WeakSubnetPtr subnet_
Weak pointer to the subnet owning the allocator.
static bool isValidPrefixPool(Allocator::PrefixLenMatchType prefix_length_match, PoolPtr pool, uint8_t hint_prefix_length)
Check if the pool matches the selection criteria relative to the provided hint prefix length.
Container for storing client class names.
static asiolink::IOAddress increasePrefix(const asiolink::IOAddress &prefix, const uint8_t prefix_len)
Returns the next prefix.
static asiolink::IOAddress increaseAddress(const asiolink::IOAddress &address, bool prefix, const uint8_t prefix_len)
Returns the next address or prefix.
IterativeAllocator(Lease::Type type, const WeakSubnetPtr &subnet)
Constructor.
static PoolIterativeAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from pool.
static SubnetIterativeAllocationStatePtr create(const SubnetPtr &subnet)
Factory function creating the state instance from subnet.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::weak_ptr< Subnet > WeakSubnetPtr
Weak pointer to the Subnet.
boost::shared_ptr< IdentifierBaseType > IdentifierBaseTypePtr
Shared pointer to a IdentifierType.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
boost::shared_ptr< PoolIterativeAllocationState > PoolIterativeAllocationStatePtr
Type of the pointer to the PoolIterativeAllocationState.
boost::shared_ptr< SubnetIterativeAllocationState > SubnetIterativeAllocationStatePtr
Type of the pointer to the SubnetIterativeAllocationState.
boost::shared_ptr< Pool6 > Pool6Ptr
a pointer an IPv6 Pool
Defines the logger used by the top-level component of kea-lfc.
Type
Type of lease or pool.