16#include <boost/lexical_cast.hpp>
17#include <boost/make_shared.hpp>
35 return (prefix < pool->getFirstAddress());
47comparePoolFirstAddress(
const PoolPtr& pool1,
const PoolPtr& pool2) {
48 return (pool1->getFirstAddress() < pool2->getFirstAddress());
61 : id_(id == 0 ? generateNextID() : id), prefix_(prefix),
66 last_allocated_time_(),
67 shared_network_name_(),
68 mutex_(new std::mutex) {
69 if ((prefix.
isV6() && len > 128) ||
70 (prefix.
isV4() && len > 32)) {
72 "Invalid prefix length specified for subnet: " << len);
87 return ((first <= addr) && (addr <= last));
91 if (MultiThreadingMgr::instance().getMode()) {
92 std::lock_guard<std::mutex> lock(*mutex_);
93 return (getLastAllocatedInternal(type));
95 return (getLastAllocatedInternal(type));
116boost::posix_time::ptime
118 if (MultiThreadingMgr::instance().getMode()) {
119 std::lock_guard<std::mutex> lock(*mutex_);
120 return (getLastAllocatedTimeInternal(lease_type));
122 return (getLastAllocatedTimeInternal(lease_type));
126boost::posix_time::ptime
127Subnet::getLastAllocatedTimeInternal(
const Lease::Type& lease_type)
const {
135 return (boost::posix_time::neg_infin);
140 if (MultiThreadingMgr::instance().getMode()) {
141 std::lock_guard<std::mutex> lock(*mutex_);
142 setLastAllocatedInternal(type, addr);
144 setLastAllocatedInternal(type, addr);
148void Subnet::setLastAllocatedInternal(
Lease::Type type,
175 std::stringstream tmp;
192 <<
static_cast<int>(type));
209 <<
static_cast<int>(type));
216 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
217 uint64_t x = (*p)->getCapacity();
221 if (x > std::numeric_limits<uint64_t>::max() - sum) {
222 return (std::numeric_limits<uint64_t>::max());
235 for (PoolCollection::const_iterator p = pools.begin(); p != pools.end(); ++p) {
236 if (!(*p)->clientSupported(client_classes)) {
239 uint64_t x = (*p)->getCapacity();
243 if (x > std::numeric_limits<uint64_t>::max() - sum) {
244 return (std::numeric_limits<uint64_t>::max());
253std::pair<IOAddress, uint8_t>
255 auto pos = prefix.find(
'/');
256 if ((pos == std::string::npos) ||
257 (pos == prefix.size() - 1) ||
263 IOAddress address(prefix.substr(0, pos));
264 int length = boost::lexical_cast<int>(prefix.substr(pos + 1));
265 return (std::make_pair(address,
static_cast<int>(length)));
285 if (!prefix.
isV4()) {
287 <<
" specified in subnet4");
302 Subnet4Ptr subnet = boost::make_shared<Subnet4>
303 (prefix, length, t1, t2, valid_lifetime,
id);
312 return (network->getNextSubnet(first_subnet,
getID()));
332 subnet = network->getNextSubnet(first_subnet, subnet_id);
335 if (subnet && subnet->clientSupported(client_classes)) {
350 if (network && !network->clientSupported(client_classes)) {
371 <<
static_cast<int>(type));
389 <<
static_cast<int>(type));
394 bool anypool )
const {
402 if (!pools.empty()) {
411 PoolCollection::const_iterator ub =
412 std::upper_bound(pools.begin(), pools.end(), hint,
413 prefixLessThanFirstAddress);
415 if (ub != pools.begin()) {
417 if ((*ub)->inRange(hint)) {
423 if (!candidate && anypool) {
424 candidate = *pools.begin();
442 if (!pools.empty()) {
443 PoolCollection::const_iterator ub =
444 std::upper_bound(pools.begin(), pools.end(), hint,
445 prefixLessThanFirstAddress);
447 if (ub != pools.begin()) {
449 if ((*ub)->inRange(hint) &&
450 (*ub)->clientSupported(client_classes)) {
470 if (!
inRange(pool->getFirstAddress()) || !
inRange(pool->getLastAddress())) {
473 <<
", with the following address range: "
474 << pool->getFirstAddress() <<
"-"
475 << pool->getLastAddress() <<
" does not match"
476 <<
" the prefix of a subnet: "
478 <<
" to which it is being added");
483 bool overlaps =
false;
497 <<
", with the following address range: "
498 << pool->getFirstAddress() <<
"-"
499 << pool->getLastAddress() <<
" overlaps with "
500 "an existing pool in the subnet: "
502 <<
" to which it is being added");
508 pools_writable.push_back(pool);
511 std::sort(pools_writable.begin(), pools_writable.end(),
512 comparePoolFirstAddress);
530 for (PoolCollection::const_iterator pool = pools.begin();
531 pool != pools.end(); ++pool) {
532 if ((*pool)->inRange(addr)) {
552 for (PoolCollection::const_iterator pool = pools.begin();
553 pool != pools.end(); ++pool) {
554 if (!(*pool)->clientSupported(client_classes)) {
557 if ((*pool)->inRange(addr)) {
588 PoolCollection::const_iterator pool3_it =
589 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
590 prefixLessThanFirstAddress);
598 if (pool3_it != pools.begin()) {
600 PoolPtr pool3 = *(pool3_it - 1);
601 if (pool3->getFirstAddress() == pool->getFirstAddress()) {
608 if (pool3_it != pools.end()) {
612 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
619 if (pool3_it != pools.begin()) {
620 PoolPtr pool1 = *(pool3_it - 1);
622 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
638 if (!prefix.
isV6()) {
640 <<
" specified in subnet6");
657 Subnet6Ptr subnet = boost::make_shared<Subnet6>
658 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime,
id);
666 <<
"(" <<
static_cast<int>(type)
667 <<
"), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
676 return (network->getNextSubnet(first_subnet,
getID()));
696 subnet = network->getNextSubnet(first_subnet, subnet_id);
699 if (subnet && subnet->clientSupported(client_classes)) {
713 if (network && !network->clientSupported(client_classes)) {
729 map->set(
"id", Element::create(
static_cast<long long>(
id)));
732 map->set(
"subnet", Element::create(
toText()));
743 merge(map, network_map);
752 for (PoolCollection::const_iterator pool = pools.cbegin();
753 pool != pools.cend(); ++pool) {
755 pool_list->add((*pool)->toElement());
757 map->set(
"pools", pool_list);
762std::pair<IOAddress, uint8_t>
765 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
766 (parsed.second > 32) || (parsed.second == 0)) {
778 merge(map, network_map);
783 for (PoolCollection::const_iterator pool = pools.cbegin();
784 pool != pools.cend(); ++pool) {
786 pool_list->add((*pool)->toElement());
788 map->set(
"pools", pool_list);
792 ElementPtr pdpool_list = Element::createList();
793 for (PoolCollection::const_iterator pool = pdpools.cbegin();
794 pool != pdpools.cend(); ++pool) {
796 pdpool_list->add((*pool)->toElement());
798 map->set(
"pd-pools", pdpool_list);
803std::pair<IOAddress, uint8_t>
806 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
807 (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)
std::string toText() const
Convert the address to a string.
bool isV6() const
Convenience function to check for an IPv6 address.
bool isV4() const
Convenience function to check for an IPv4 address.
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.
void setPreferred(const Triplet< uint32_t > &preferred)
Sets new preferred lifetime for a network.
virtual data::ElementPtr toElement() const
Unparses network object.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports client that belongs to specified classes.
void setValid(const Triplet< uint32_t > &valid)
Sets new valid lifetime for a network.
void setT2(const Triplet< uint32_t > &t2)
Sets new rebind timer for a network.
void setT1(const Triplet< uint32_t > &t1)
Sets new renew timer for a network.
Subnet4(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
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 Subnet4Ptr create(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Factory function creating an instance of the Subnet4.
Cfg4o6 & get4o6()
Returns DHCP4o6 configuration parameters.
Subnet4Ptr getNextSubnet(const Subnet4Ptr &first_subnet) const
Returns next subnet within shared network.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
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 Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &preferred_lifetime, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
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.
Subnet6(const isc::asiolink::IOAddress &prefix, uint8_t length, const Triplet< uint32_t > &t1, const Triplet< uint32_t > &t2, const Triplet< uint32_t > &preferred_lifetime, const Triplet< uint32_t > &valid_lifetime, const SubnetID id=0)
Constructor with all parameters.
Subnet6Ptr getNextSubnet(const Subnet6Ptr &first_subnet) const
Returns next subnet within shared network.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
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.
std::map< Lease::Type, boost::posix_time::ptime > last_allocated_time_
Timestamp indicating when a lease of a specified type has been last allocated from this subnet.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
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 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.
isc::asiolink::IOAddress last_allocated_pd_
last allocated IPv6 prefix.
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.
PoolCollection pools_
collection of IPv4 or non-temporary IPv6 pools in that subnet.
PoolCollection & getPoolsWritable(Lease::Type type)
Returns all pools (non-const variant).
isc::asiolink::IOAddress getLastAllocated(Lease::Type type) const
returns the last address that was tried from this subnet.
void setLastAllocated(Lease::Type type, const isc::asiolink::IOAddress &addr)
sets the last address that was tried from this subnet.
const PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress &addr, bool anypool=true) const
Returns a pool that specified address belongs to.
isc::asiolink::IOAddress last_allocated_ia_
last allocated address.
Subnet(const isc::asiolink::IOAddress &prefix, uint8_t len, const SubnetID id)
Protected constructor.
boost::posix_time::ptime getLastAllocatedTime(const Lease::Type &lease_type) const
Returns the timestamp when the setLastAllocated function was called.
uint64_t sumPoolCapacity(const PoolCollection &pools) const
Returns a sum of possible leases in all pools.
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).
static SubnetID static_id_
keeps the subnet-id value.
virtual void checkType(Lease::Type type) const =0
Checks if used pool type is valid.
uint64_t getPoolCapacity(Lease::Type type) const
Returns the number of possible leases for specified lease type.
bool inPool(Lease::Type type, const isc::asiolink::IOAddress &addr) const
checks if the specified address is in pools.
isc::asiolink::IOAddress last_allocated_ta_
last allocated temporary address.
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.
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< Subnet4 > Subnet4Ptr
A 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
Unique identifier for a subnet (both v4 and v6)
boost::shared_ptr< Network > NetworkPtr
Pointer to the Network object.
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
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_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