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)
bool isV6() const
Convenience function to check for an IPv6 address.
std::vector< uint8_t > toBytes() const
Return address as set of bytes.
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.