25#include <boost/lexical_cast.hpp>
26#include <boost/make_shared.hpp>
46prefixLessThanFirstAddress(
const IOAddress& prefix,
48 return (prefix < pool->getFirstAddress());
60comparePoolFirstAddress(
const PoolPtr& pool1,
62 return (pool1->getFirstAddress() < pool2->getFirstAddress());
73 if ((
id == SUBNET_ID_GLOBAL) || (
id == SUBNET_ID_UNUSED)) {
75 "Invalid id specified for subnet: " <<
id);
77 if ((prefix.
isV6() && len > 128) || (prefix.
isV4() && len > 32)) {
79 "Invalid prefix length specified for subnet: " << len);
88 return ((first <= addr) && (addr <= last));
93 std::stringstream tmp;
108 <<
static_cast<int>(type));
123 <<
static_cast<int>(type));
131 uint8_t hint_prefix_length)
const {
141 <<
static_cast<int>(type));
148 for (
auto const& p : pools) {
153 if (c > numeric_limits<uint128_t>::max() - sum) {
154 return (numeric_limits<uint128_t>::max());
167 for (
auto const& p : pools) {
168 if (!p->clientSupported(client_classes)) {
176 if (c > numeric_limits<uint128_t>::max() - sum) {
177 return (numeric_limits<uint128_t>::max());
190 uint8_t hint_prefix_length)
const {
192 for (
auto const& p : pools) {
193 if (!p->clientSupported(client_classes)) {
198 hint_prefix_length)) {
206 if (c > numeric_limits<uint128_t>::max() - sum) {
207 return (numeric_limits<uint128_t>::max());
216std::pair<IOAddress, uint8_t>
218 auto pos = prefix.find(
'/');
219 if ((pos == std::string::npos) ||
220 (pos == prefix.size() - 1) ||
226 IOAddress address(prefix.substr(0, pos));
227 int length = boost::lexical_cast<int>(prefix.substr(pos + 1));
228 return (std::make_pair(address,
static_cast<int>(length)));
248 if (!prefix.
isV4()) {
249 isc_throw(BadValue,
"Non IPv4 prefix " << prefix.toText()
250 <<
" specified in subnet4");
264 Subnet4Ptr subnet = boost::make_shared<Subnet4>
265 (prefix, length, t1, t2, valid_lifetime,
id);
267 boost::make_shared<IterativeAllocator>
280 return (network->getNextSubnet(first_subnet,
getID()));
300 subnet = network->getNextSubnet(first_subnet, subnet_id);
303 if (subnet && subnet->clientSupported(client_classes)) {
318 if (network && !network->clientSupported(client_classes)) {
337 <<
static_cast<int>(type));
353 <<
static_cast<int>(type));
365 return (alloc->second);
381 return (state->second);
390 bool anypool )
const {
398 if (!pools.empty()) {
408 std::upper_bound(pools.begin(), pools.end(), hint,
409 prefixLessThanFirstAddress);
411 if (ub != pools.begin()) {
413 if ((*ub)->inRange(hint)) {
419 if (!candidate && anypool) {
420 candidate = *pools.begin();
431 allocator.second->initAfterConfigure();
445 if (!pools.empty()) {
447 std::upper_bound(pools.begin(), pools.end(), hint,
448 prefixLessThanFirstAddress);
450 if (ub != pools.begin()) {
452 if ((*ub)->inRange(hint) &&
453 (*ub)->clientSupported(client_classes)) {
473 if (!
inRange(pool->getFirstAddress()) || !
inRange(pool->getLastAddress())) {
476 <<
", with the following address range: "
477 << pool->getFirstAddress() <<
"-"
478 << pool->getLastAddress() <<
" does not match"
479 <<
" the prefix of a subnet: "
481 <<
" to which it is being added");
486 bool overlaps =
false;
499 <<
", with the following address range: "
500 << pool->getFirstAddress() <<
"-"
501 << pool->getLastAddress() <<
" overlaps with "
502 "an existing pool in the subnet: "
504 <<
" to which it is being added");
510 pools_writable.push_back(pool);
513 std::sort(pools_writable.begin(), pools_writable.end(),
514 comparePoolFirstAddress);
531 for (
auto const& pool : pools) {
532 if (pool->inRange(addr)) {
551 for (
auto const& pool : pools) {
552 if (!pool->clientSupported(client_classes)) {
555 if (pool->inRange(addr)) {
565 auto const& pools =
getPools(pool_type);
586 auto const pool3_it =
587 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
588 prefixLessThanFirstAddress);
600 if (pool3_it != pools.begin()) {
601 PoolPtr pool1 = *(pool3_it - 1);
603 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
610 if (pool3_it != pools.end()) {
614 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
629 if (!prefix.
isV6()) {
630 isc_throw(BadValue,
"Non IPv6 prefix " << prefix
631 <<
" specified in subnet6");
648 Subnet6Ptr subnet = boost::make_shared<Subnet6>
649 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime,
id);
652 boost::make_shared<IterativeAllocator>
658 boost::make_shared<IterativeAllocator>
668 <<
"(" <<
static_cast<int>(type)
669 <<
"), must be TYPE_NA or TYPE_PD for Subnet6");
678 return (network->getNextSubnet(first_subnet,
getID()));
698 subnet = network->getNextSubnet(first_subnet, subnet_id);
701 if (subnet && subnet->clientSupported(client_classes)) {
715 if (network && !network->clientSupported(client_classes)) {
742 if (allocator_type.empty()) {
745 if (allocator_type ==
"random") {
747 boost::make_shared<RandomAllocator>
751 for (
auto const& pool :
pools_) {
755 }
else if (allocator_type ==
"flq") {
757 boost::make_shared<FreeLeaseQueueAllocator>
761 for (
auto const& pool :
pools_) {
764 }
else if (allocator_type ==
"shared-flq") {
766 boost::make_shared<SharedFlqAllocator>
769 boost::make_shared<SubnetSflqAllocationState>());
773 boost::make_shared<IterativeAllocator>
778 for (
auto const& pool :
pools_) {
790 merge(map, network_map);
799 for (
auto const& pool : pools) {
801 pool_list->add(pool->toElement());
803 map->set(
"pools", pool_list);
808std::pair<IOAddress, uint8_t>
811 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
812 (parsed.second > 32) || (parsed.second == 0)) {
821 if (allocator_type.empty()) {
824 if (allocator_type ==
"random") {
826 boost::make_shared<RandomAllocator>
830 }
else if (allocator_type ==
"flq") {
831 isc_throw(
BadValue,
"Free Lease Queue allocator is not supported for IPv6 address pools");
832 }
else if (allocator_type ==
"shared-flq") {
834 boost::make_shared<SharedFlqAllocator>
837 boost::make_shared<SubnetSflqAllocationState>());
840 boost::make_shared<IterativeAllocator>
846 if (pd_allocator_type.empty()) {
850 if (pd_allocator_type ==
"random") {
852 boost::make_shared<RandomAllocator>
856 }
else if (pd_allocator_type ==
"flq") {
858 boost::make_shared<FreeLeaseQueueAllocator>
861 }
else if (pd_allocator_type ==
"shared-flq") {
863 boost::make_shared<SharedFlqAllocator>
866 boost::make_shared<SubnetSflqAllocationState>());
870 boost::make_shared<IterativeAllocator>
875 for (
auto const& pool :
pools_) {
876 if (allocator_type ==
"random") {
884 if (pd_allocator_type ==
"random") {
886 }
else if (pd_allocator_type ==
"flq") {
900 merge(map, network_map);
905 for (
auto const& pool : pools) {
907 pool_list->add(pool->toElement());
909 map->set(
"pools", pool_list);
914 for (
auto const& pool : pdpools) {
916 pdpool_list->add(pool->toElement());
918 map->set(
"pd-pools", pdpool_list);
923std::pair<IOAddress, uint8_t>
926 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
927 (parsed.second > 128) || (parsed.second == 0)) {
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.
bool isV4() const
Convenience function to check for an IPv4 address.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
PrefixLenMatchType
Type of preferred PD-pool prefix length selection criteria.
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.
virtual data::ElementPtr toElement() const
Unparses network object.
util::Optional< std::string > getDefaultPdAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns a default allocator type for prefix delegation.
void setPreferred(const isc::util::Triplet< uint32_t > &preferred)
Sets new preferred lifetime for a network.
virtual data::ElementPtr toElement() const
Unparses network object.
util::Optional< std::string > getPdAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns allocator type for prefix delegation.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports a client that belongs to the specified classes.
void setT2(const isc::util::Triplet< uint32_t > &t2)
Sets new rebind timer for a network.
util::Optional< std::string > getAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns allocator type.
util::Optional< std::string > getDefaultAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns a default allocator type.
void setT1(const isc::util::Triplet< uint32_t > &t1)
Sets new renew timer for a network.
void setValid(const isc::util::Triplet< uint32_t > &valid)
Sets new valid lifetime for a network.
static PoolFreeLeaseQueueAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from a pool.
static PoolIterativeAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from pool.
static PoolRandomAllocationStatePtr create(const PoolPtr &pool)
Factory function creating the state instance from pool.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
Cfg4o6 & get4o6()
Returns DHCP4o6 configuration parameters.
ConstSubnet4Ptr getNextSubnet(const ConstSubnet4Ptr &first_subnet) const
Returns next subnet within shared network.
virtual void createAllocators()
Instantiates the allocator and its state.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
static Subnet4Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id)
Factory function creating an instance of the Subnet4.
Subnet4(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id)
Constructor with all parameters.
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this subnet and parent shared network supports the client that belongs to specified cl...
static Subnet6Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &preferred_lifetime, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id)
Factory function creating an instance of the Subnet4.
static std::pair< asiolink::IOAddress, uint8_t > parsePrefix(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
virtual void createAllocators()
Instantiates the allocators and their states.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
ConstSubnet6Ptr getNextSubnet(const ConstSubnet6Ptr &first_subnet) const
Returns next subnet within shared network.
Subnet6(const isc::asiolink::IOAddress &prefix, uint8_t length, const util::Triplet< uint32_t > &t1, const util::Triplet< uint32_t > &t2, const util::Triplet< uint32_t > &preferred_lifetime, const util::Triplet< uint32_t > &valid_lifetime, const SubnetID id)
Constructor with all parameters.
static SubnetIterativeAllocationStatePtr create(const SubnetPtr &subnet)
Factory function creating the state instance from subnet.
isc::util::uint128_t getPoolCapacity(Lease::Type type) const
Returns the number of possible leases for specified lease type.
isc::asiolink::IOAddress prefix_
a prefix of the subnet.
SubnetID getID() const
Returns unique ID for that subnet.
uint8_t prefix_len_
a prefix length of the subnet.
isc::util::uint128_t sumPoolCapacity(const PoolCollection &pools) const
Returns a sum of possible leases in all pools.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
AllocatorPtr getAllocator(Lease::Type type) const
Returns lease allocator instance.
void getSharedNetwork(SharedNetworkPtrType &shared_network) const
Retrieves pointer to a shared network associated with a subnet.
void initAllocatorsAfterConfigure()
Calls initAfterConfigure for each allocator.
SubnetAllocationStatePtr getAllocationState(Lease::Type type) const
Returns subnet-specific allocation state.
void addPool(const PoolPtr &pool)
Adds a new pool for the subnet.
bool inRange(const isc::asiolink::IOAddress &addr) const
checks if specified address is in range.
std::map< Lease::Type, AllocatorPtr > allocators_
Lease allocators used by the subnet.
virtual std::string toText() const
Returns textual representation of the subnet (e.g.
void delPools(Lease::Type type)
Deletes all pools of specified type.
static std::pair< asiolink::IOAddress, uint8_t > parsePrefixCommon(const std::string &prefix)
Converts subnet prefix to a pair of prefix/length pair.
void setAllocator(Lease::Type type, const AllocatorPtr &allocator)
Sets new allocator instance.
PoolCollection pools_
collection of IPv4 or non-temporary IPv6 pools in that subnet.
PoolCollection & getPoolsWritable(Lease::Type type)
Returns all pools (non-const variant).
const PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress &addr, bool anypool=true) const
Returns a pool that specified address belongs to.
Subnet(const isc::asiolink::IOAddress &prefix, uint8_t len, const SubnetID id)
Protected constructor.
std::string shared_network_name_
Shared network name.
bool poolOverlaps(const Lease::Type &pool_type, const PoolPtr &pool) const
Checks if the specified pool overlaps with an existing pool.
PoolCollection pools_pd_
collection of IPv6 prefix pools in that subnet.
const PoolCollection & getPools(Lease::Type type) const
Returns all pools (const variant).
virtual void checkType(Lease::Type type) const =0
Checks if used pool type is valid.
std::map< Lease::Type, SubnetAllocationStatePtr > allocation_states_
Holds subnet-specific allocation state.
bool inPool(Lease::Type type, const isc::asiolink::IOAddress &addr) const
checks if the specified address is in pools.
void setAllocationState(Lease::Type type, const SubnetAllocationStatePtr &allocation_state)
Sets subnet-specific allocation state.
This template specifies a parameter value.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
IOAddress firstAddrInPrefix(const IOAddress &prefix, uint8_t len)
This code is based on similar code from the Dibbler project.
IOAddress lastAddrInPrefix(const IOAddress &prefix, uint8_t len)
returns a last address in a given prefix
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element. (on the first level).
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
boost::shared_ptr< const Subnet6 > ConstSubnet6Ptr
A const pointer to a Subnet6 object.
boost::shared_ptr< const Subnet4 > ConstSubnet4Ptr
A const pointer to a Subnet4 object.
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
std::vector< PoolPtr > PoolCollection
a container for either IPv4 or IPv6 Pools
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
boost::shared_ptr< Pool > PoolPtr
a pointer to either IPv4 or IPv6 Pool
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
boost::shared_ptr< Allocator > AllocatorPtr
Defines a pointer to an allocator.
boost::shared_ptr< SubnetAllocationState > SubnetAllocationStatePtr
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
boost::multiprecision::checked_uint128_t uint128_t
Defines the logger used by the top-level component of kea-lfc.
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
This structure contains information about DHCP4o6 (RFC7341).
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Type
Type of lease or pool.
@ TYPE_PD
the lease contains IPv6 prefix (for prefix delegation)
@ TYPE_NA
the lease contains non-temporary IPv6 address
static std::string typeToText(Type type)
returns text representation of a lease type