23#include <boost/lexical_cast.hpp>
24#include <boost/make_shared.hpp>
44prefixLessThanFirstAddress(
const IOAddress& prefix,
46 return (prefix < pool->getFirstAddress());
58comparePoolFirstAddress(
const PoolPtr& pool1,
60 return (pool1->getFirstAddress() < pool2->getFirstAddress());
70 : id_(id), prefix_(prefix), prefix_len_(len), shared_network_name_() {
71 if ((
id == SUBNET_ID_GLOBAL) || (
id == SUBNET_ID_UNUSED)) {
73 "Invalid id specified for subnet: " <<
id);
75 if ((prefix.isV6() && len > 128) || (prefix.isV4() && len > 32)) {
77 "Invalid prefix length specified for subnet: " << len);
86 return ((first <= addr) && (addr <= last));
91 std::stringstream tmp;
108 <<
static_cast<int>(type));
125 <<
static_cast<int>(type));
133 uint8_t hint_prefix_length)
const {
145 <<
static_cast<int>(type));
152 for (
auto const& p : pools) {
157 if (c > numeric_limits<uint128_t>::max() - sum) {
158 return (numeric_limits<uint128_t>::max());
171 for (
auto const& p : pools) {
172 if (!p->clientSupported(client_classes)) {
180 if (c > numeric_limits<uint128_t>::max() - sum) {
181 return (numeric_limits<uint128_t>::max());
194 uint8_t hint_prefix_length)
const {
196 for (
auto const& p : pools) {
197 if (!p->clientSupported(client_classes)) {
202 hint_prefix_length)) {
210 if (c > numeric_limits<uint128_t>::max() - sum) {
211 return (numeric_limits<uint128_t>::max());
220std::pair<IOAddress, uint8_t>
222 auto pos = prefix.find(
'/');
223 if ((pos == std::string::npos) ||
224 (pos == prefix.size() - 1) ||
230 IOAddress address(prefix.substr(0, pos));
231 int length = boost::lexical_cast<int>(prefix.substr(pos + 1));
232 return (std::make_pair(address,
static_cast<int>(length)));
247 const Triplet<uint32_t>& t1,
248 const Triplet<uint32_t>& t2,
249 const Triplet<uint32_t>& valid_lifetime,
252 if (!prefix.isV4()) {
254 <<
" specified in subnet4");
264 const Triplet<uint32_t>& t1,
265 const Triplet<uint32_t>& t2,
266 const Triplet<uint32_t>& valid_lifetime,
268 Subnet4Ptr subnet = boost::make_shared<Subnet4>
269 (prefix, length, t1, t2, valid_lifetime,
id);
271 boost::make_shared<IterativeAllocator>
284 return (network->getNextSubnet(first_subnet,
getID()));
304 subnet = network->getNextSubnet(first_subnet, subnet_id);
307 if (subnet && subnet->clientSupported(client_classes)) {
322 if (network && !network->clientSupported(client_classes)) {
343 <<
static_cast<int>(type));
361 <<
static_cast<int>(type));
373 return (alloc->second);
389 return (state->second);
398 bool anypool )
const {
406 if (!pools.empty()) {
416 std::upper_bound(pools.begin(), pools.end(), hint,
417 prefixLessThanFirstAddress);
419 if (ub != pools.begin()) {
421 if ((*ub)->inRange(hint)) {
427 if (!candidate && anypool) {
428 candidate = *pools.begin();
439 allocator.second->initAfterConfigure();
453 if (!pools.empty()) {
455 std::upper_bound(pools.begin(), pools.end(), hint,
456 prefixLessThanFirstAddress);
458 if (ub != pools.begin()) {
460 if ((*ub)->inRange(hint) &&
461 (*ub)->clientSupported(client_classes)) {
481 if (!
inRange(pool->getFirstAddress()) || !
inRange(pool->getLastAddress())) {
484 <<
", with the following address range: "
485 << pool->getFirstAddress() <<
"-"
486 << pool->getLastAddress() <<
" does not match"
487 <<
" the prefix of a subnet: "
489 <<
" to which it is being added");
494 bool overlaps =
false;
508 <<
", with the following address range: "
509 << pool->getFirstAddress() <<
"-"
510 << pool->getLastAddress() <<
" overlaps with "
511 "an existing pool in the subnet: "
513 <<
" to which it is being added");
519 pools_writable.push_back(pool);
522 std::sort(pools_writable.begin(), pools_writable.end(),
523 comparePoolFirstAddress);
540 for (
auto const& pool : pools) {
541 if (pool->inRange(addr)) {
560 for (
auto const& pool : pools) {
561 if (!pool->clientSupported(client_classes)) {
564 if (pool->inRange(addr)) {
574 auto const& pools =
getPools(pool_type);
595 auto const pool3_it =
596 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
597 prefixLessThanFirstAddress);
609 if (pool3_it != pools.begin()) {
610 PoolPtr pool1 = *(pool3_it - 1);
612 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
619 if (pool3_it != pools.end()) {
623 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
632 const Triplet<uint32_t>& t1,
633 const Triplet<uint32_t>& t2,
634 const Triplet<uint32_t>& preferred_lifetime,
635 const Triplet<uint32_t>& valid_lifetime,
638 if (!prefix.isV6()) {
640 <<
" specified in subnet6");
652 const Triplet<uint32_t>& t1,
653 const Triplet<uint32_t>& t2,
654 const Triplet<uint32_t>& preferred_lifetime,
655 const Triplet<uint32_t>& valid_lifetime,
657 Subnet6Ptr subnet = boost::make_shared<Subnet6>
658 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime,
id);
661 boost::make_shared<IterativeAllocator>
667 boost::make_shared<IterativeAllocator>
673 boost::make_shared<IterativeAllocator>
683 <<
"(" <<
static_cast<int>(type)
684 <<
"), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
693 return (network->getNextSubnet(first_subnet,
getID()));
713 subnet = network->getNextSubnet(first_subnet, subnet_id);
716 if (subnet && subnet->clientSupported(client_classes)) {
730 if (network && !network->clientSupported(client_classes)) {
757 if (allocator_type.empty()) {
760 if (allocator_type ==
"random") {
762 boost::make_shared<RandomAllocator>
766 for (
auto const& pool :
pools_) {
770 }
else if (allocator_type ==
"flq") {
772 boost::make_shared<FreeLeaseQueueAllocator>
776 for (
auto const& pool :
pools_) {
782 boost::make_shared<IterativeAllocator>
787 for (
auto const& pool :
pools_) {
799 merge(map, network_map);
808 for (
auto const& pool : pools) {
810 pool_list->add(pool->toElement());
812 map->set(
"pools", pool_list);
817std::pair<IOAddress, uint8_t>
820 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
821 (parsed.second > 32) || (parsed.second == 0)) {
830 if (allocator_type.empty()) {
833 if (allocator_type ==
"random") {
835 boost::make_shared<RandomAllocator>
838 boost::make_shared<RandomAllocator>
843 }
else if (allocator_type ==
"flq") {
844 isc_throw(
BadValue,
"Free Lease Queue allocator is not supported for IPv6 address pools");
848 boost::make_shared<IterativeAllocator>
855 if (pd_allocator_type.empty()) {
859 if (pd_allocator_type ==
"random") {
861 boost::make_shared<RandomAllocator>
865 }
else if (pd_allocator_type ==
"flq") {
867 boost::make_shared<FreeLeaseQueueAllocator>
873 boost::make_shared<IterativeAllocator>
878 for (
auto const& pool :
pools_) {
879 if (allocator_type ==
"random") {
887 if (allocator_type ==
"random") {
895 if (pd_allocator_type ==
"random") {
897 }
else if (pd_allocator_type ==
"flq") {
911 merge(map, network_map);
916 for (
auto const& pool : pools) {
918 pool_list->add(pool->toElement());
920 map->set(
"pools", pool_list);
925 for (
auto const& pool : pdpools) {
927 pdpool_list->add(pool->toElement());
929 map->set(
"pd-pools", pdpool_list);
934std::pair<IOAddress, uint8_t>
937 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
938 (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)
static ElementPtr create(const Position &pos=ZERO_POSITION())
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.
Specialization of the Network object for DHCPv4 case.
virtual data::ElementPtr toElement() const
Unparses network object.
Specialization of the Network object for DHCPv6 case.
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.
PoolCollection pools_ta_
collection of IPv6 temporary address pools in that subnet.
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.
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.
#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.
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)
Type
Type of lease or pool.
@ TYPE_TA
the lease contains temporary IPv6 address
@ 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