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);
 
  282                isc_throw(Unexpected, 
"Wrong type of pool: " 
  290        if (valid && !(*it)->inRange(last)) {
 
  292            getPoolState(*it)->resetLastAllocated();
 
  293            getPoolState(*it)->setLastAllocated((*it)->getFirstAddress());
 
  298            pool6 = boost::dynamic_pointer_cast<Pool6>(*it);
 
  301                isc_throw(Unexpected, 
"Wrong type of pool: " 
  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);
 
  345        isc_throw(Unexpected, 
"Wrong type of pool: " 
  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...
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.
Lease::Type pool_type_
Defines pool type allocation.
Allocator(Lease::Type type, const WeakSubnetPtr &subnet)
Constructor.
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.