23 #include <boost/lexical_cast.hpp>
24 #include <boost/make_shared.hpp>
44 prefixLessThanFirstAddress(
const IOAddress& prefix,
46 return (prefix < pool->getFirstAddress());
58 comparePoolFirstAddress(
const PoolPtr& pool1,
60 return (pool1->getFirstAddress() < pool2->getFirstAddress());
73 : id_(id == 0 ? generateNextID() : id), prefix_(prefix),
75 shared_network_name_() {
76 if ((
id == 0) && (
id_ == 1)) {
81 if ((prefix.
isV6() && len > 128) ||
82 (prefix.
isV4() && len > 32)) {
84 "Invalid prefix length specified for subnet: " << len);
93 return ((first <= addr) && (addr <= last));
98 std::stringstream tmp;
115 <<
static_cast<int>(type));
132 <<
static_cast<int>(type));
140 uint8_t hint_prefix_length)
const {
152 <<
static_cast<int>(type));
159 for (
auto const& p : pools) {
164 if (c > numeric_limits<uint128_t>::max() - sum) {
165 return (numeric_limits<uint128_t>::max());
178 for (
auto const& p : pools) {
179 if (!p->clientSupported(client_classes)) {
187 if (c > numeric_limits<uint128_t>::max() - sum) {
188 return (numeric_limits<uint128_t>::max());
201 uint8_t hint_prefix_length)
const {
203 for (
auto const& p : pools) {
204 if (!p->clientSupported(client_classes)) {
209 hint_prefix_length)) {
217 if (c > numeric_limits<uint128_t>::max() - sum) {
218 return (numeric_limits<uint128_t>::max());
227 std::pair<IOAddress, uint8_t>
229 auto pos = prefix.find(
'/');
230 if ((pos == std::string::npos) ||
231 (pos == prefix.size() - 1) ||
237 IOAddress address(prefix.substr(0, pos));
238 int length = boost::lexical_cast<int>(prefix.substr(pos + 1));
239 return (std::make_pair(address,
static_cast<int>(length)));
259 if (!prefix.
isV4()) {
261 <<
" specified in subnet4");
275 Subnet4Ptr subnet = boost::make_shared<Subnet4>
276 (prefix, length, t1, t2, valid_lifetime,
id);
278 boost::make_shared<IterativeAllocator>
291 return (network->getNextSubnet(first_subnet,
getID()));
311 subnet = network->getNextSubnet(first_subnet, subnet_id);
314 if (subnet && subnet->clientSupported(client_classes)) {
329 if (network && !network->clientSupported(client_classes)) {
350 <<
static_cast<int>(type));
368 <<
static_cast<int>(type));
380 return (alloc->second);
396 return (state->second);
405 bool anypool )
const {
413 if (!pools.empty()) {
423 std::upper_bound(pools.begin(), pools.end(), hint,
424 prefixLessThanFirstAddress);
426 if (ub != pools.begin()) {
428 if ((*ub)->inRange(hint)) {
434 if (!candidate && anypool) {
435 candidate = *pools.begin();
446 allocator.second->initAfterConfigure();
460 if (!pools.empty()) {
462 std::upper_bound(pools.begin(), pools.end(), hint,
463 prefixLessThanFirstAddress);
465 if (ub != pools.begin()) {
467 if ((*ub)->inRange(hint) &&
468 (*ub)->clientSupported(client_classes)) {
488 if (!
inRange(pool->getFirstAddress()) || !
inRange(pool->getLastAddress())) {
491 <<
", with the following address range: "
492 << pool->getFirstAddress() <<
"-"
493 << pool->getLastAddress() <<
" does not match"
494 <<
" the prefix of a subnet: "
496 <<
" to which it is being added");
501 bool overlaps =
false;
515 <<
", with the following address range: "
516 << pool->getFirstAddress() <<
"-"
517 << pool->getLastAddress() <<
" overlaps with "
518 "an existing pool in the subnet: "
520 <<
" to which it is being added");
526 pools_writable.push_back(pool);
529 std::sort(pools_writable.begin(), pools_writable.end(),
530 comparePoolFirstAddress);
547 for (
const auto& pool : pools) {
548 if (pool->inRange(addr)) {
567 for (
const auto& pool : pools) {
568 if (!pool->clientSupported(client_classes)) {
571 if (pool->inRange(addr)) {
581 const auto& pools =
getPools(pool_type);
602 const auto pool3_it =
603 std::upper_bound(pools.begin(), pools.end(), pool->getFirstAddress(),
604 prefixLessThanFirstAddress);
616 if (pool3_it != pools.begin()) {
617 PoolPtr pool1 = *(pool3_it - 1);
619 if (pool->getFirstAddress() <= pool1->getLastAddress()) {
626 if (pool3_it != pools.end()) {
630 if (pool3->getFirstAddress() <= pool->getLastAddress()) {
645 if (!prefix.
isV6()) {
647 <<
" specified in subnet6");
664 Subnet6Ptr subnet = boost::make_shared<Subnet6>
665 (prefix, length, t1, t2, preferred_lifetime, valid_lifetime,
id);
668 boost::make_shared<IterativeAllocator>
674 boost::make_shared<IterativeAllocator>
680 boost::make_shared<IterativeAllocator>
690 <<
"(" <<
static_cast<int>(type)
691 <<
"), must be TYPE_NA, TYPE_TA or TYPE_PD for Subnet6");
700 return (network->getNextSubnet(first_subnet,
getID()));
720 subnet = network->getNextSubnet(first_subnet, subnet_id);
723 if (subnet && subnet->clientSupported(client_classes)) {
737 if (network && !network->clientSupported(client_classes)) {
764 if (allocator_type.empty()) {
767 if (allocator_type ==
"random") {
769 boost::make_shared<RandomAllocator>
773 for (
auto pool :
pools_) {
777 }
else if (allocator_type ==
"flq") {
779 boost::make_shared<FreeLeaseQueueAllocator>
783 for (
auto pool :
pools_) {
789 boost::make_shared<IterativeAllocator>
794 for (
auto pool :
pools_) {
806 merge(map, network_map);
815 for (
const auto& pool : pools) {
817 pool_list->add(pool->toElement());
819 map->set(
"pools", pool_list);
824 std::pair<IOAddress, uint8_t>
827 if (!parsed.first.isV4() || parsed.first.isV4Zero() ||
828 (parsed.second > 32) || (parsed.second == 0)) {
837 if (allocator_type.empty()) {
840 if (allocator_type ==
"random") {
842 boost::make_shared<RandomAllocator>
845 boost::make_shared<RandomAllocator>
850 }
else if (allocator_type ==
"flq") {
851 isc_throw(
BadValue,
"Free Lease Queue allocator is not supported for IPv6 address pools");
855 boost::make_shared<IterativeAllocator>
862 if (pd_allocator_type.empty()) {
866 if (pd_allocator_type ==
"random") {
868 boost::make_shared<RandomAllocator>
872 }
else if (pd_allocator_type ==
"flq") {
874 boost::make_shared<FreeLeaseQueueAllocator>
880 boost::make_shared<IterativeAllocator>
885 for (
auto pool :
pools_) {
886 if (allocator_type ==
"random") {
894 if (allocator_type ==
"random") {
902 if (pd_allocator_type ==
"random") {
904 }
else if (pd_allocator_type ==
"flq") {
918 merge(map, network_map);
923 for (
const auto& pool : pools) {
925 pool_list->add(pool->toElement());
927 map->set(
"pools", pool_list);
932 for (
const auto& pool : pdpools) {
934 pdpool_list->add(pool->toElement());
936 map->set(
"pd-pools", pdpool_list);
941 std::pair<IOAddress, uint8_t>
944 if (!parsed.first.isV6() || parsed.first.isV6Zero() ||
945 (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.
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 > getPdAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns 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 > getDefaultPdAllocatorType(const Inheritance &inheritance=Inheritance::ALL) const
Returns a default allocator type for prefix delegation.
virtual bool clientSupported(const isc::dhcp::ClientClasses &client_classes) const
Checks whether this network supports client that belongs to 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...
Subnet4Ptr getNextSubnet(const Subnet4Ptr &first_subnet) const
Returns next subnet within shared network.
Cfg4o6 & get4o6()
Returns DHCP4o6 configuration parameters.
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.
Subnet6Ptr getNextSubnet(const Subnet6Ptr &first_subnet) const
Returns next subnet within shared network.
virtual data::ElementPtr toElement() const
Unparse a subnet object.
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.
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.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
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
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
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
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.
const isc::log::MessageID DHCPSRV_CONFIGURED_SUBNET_WITHOUT_ID
boost::multiprecision::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_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