diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 11:36:04 +0000 |
commit | 040eee1aa49b49df4698d83a05af57c220127fd1 (patch) | |
tree | f635435954e6ccde5eee9893889e24f30ca68346 /src/lib/dhcpsrv/pool.h | |
parent | Initial commit. (diff) | |
download | isc-kea-040eee1aa49b49df4698d83a05af57c220127fd1.tar.xz isc-kea-040eee1aa49b49df4698d83a05af57c220127fd1.zip |
Adding upstream version 2.2.0.upstream/2.2.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/dhcpsrv/pool.h')
-rw-r--r-- | src/lib/dhcpsrv/pool.h | 515 |
1 files changed, 515 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/pool.h b/src/lib/dhcpsrv/pool.h new file mode 100644 index 0000000..95f89cf --- /dev/null +++ b/src/lib/dhcpsrv/pool.h @@ -0,0 +1,515 @@ +// Copyright (C) 2012-2020 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef POOL_H +#define POOL_H + +#include <asiolink/io_address.h> +#include <cc/data.h> +#include <cc/user_context.h> +#include <dhcp/classify.h> +#include <dhcp/option6_pdexclude.h> +#include <dhcpsrv/cfg_option.h> +#include <dhcpsrv/lease.h> +#include <dhcpsrv/ip_range_permutation.h> + +#include <boost/shared_ptr.hpp> + +#include <vector> + +namespace isc { +namespace dhcp { + +/// @brief base class for Pool4 and Pool6 +/// +/// Stores information about pool of IPv4 or IPv6 addresses. +/// That is a basic component of a configuration. +class Pool : public isc::data::UserContext, public isc::data::CfgToElement { + +public: + /// @note: + /// PoolType enum was removed. Please use Lease::Type instead + + /// @brief returns Pool-id + /// + /// @return pool-id value + /// Pool-id is an unique value that can be used to identify a pool. + uint32_t getId() const { + return (id_); + } + + /// @brief Returns the first address in a pool. + /// + /// @return first address in a pool + const isc::asiolink::IOAddress& getFirstAddress() const { + return (first_); + } + + /// @brief Returns the last address in a pool. + /// @return last address in a pool + const isc::asiolink::IOAddress& getLastAddress() const { + return (last_); + } + + /// @brief Checks if a given address is in the range. + /// + /// @return true, if the address is in pool + bool inRange(const isc::asiolink::IOAddress& addr) const; + + /// @brief Returns pool type (v4, v6 non-temporary, v6 temp, v6 prefix) + /// @return returns pool type + Lease::Type getType() const { + return (type_); + } + + /// @brief returns textual representation of the pool + /// + /// @return textual representation + virtual std::string toText() const; + + /// @brief virtual destructor + /// + /// We need Pool to be a polymorphic class, so we could dynamic cast + /// from PoolPtr to Pool6Ptr if we need to. A class becomes polymorphic, + /// when there is at least one virtual method. + virtual ~Pool() { + } + + /// @brief Returns the number of all leases in this pool. + /// + /// Note that this is the upper bound, assuming that no leases are used + /// and there are no host reservations. This is just a theoretical calculation. + /// @return number of possible leases in this pool + uint64_t getCapacity() const { + return (capacity_); + } + + /// @brief Returns pointer to the option data configuration for this pool. + CfgOptionPtr getCfgOption() { + return (cfg_option_); + } + + /// @brief Returns const pointer to the option data configuration for + /// this pool. + ConstCfgOptionPtr getCfgOption() const { + return (cfg_option_); + } + + /// @brief Checks whether this pool supports client that belongs to + /// specified classes. + /// + /// @todo: currently doing the same as network which needs improving. + /// + /// @param client_classes list of all classes the client belongs to + /// @return true if client can be supported, false otherwise + bool clientSupported(const ClientClasses& client_classes) const; + + /// @brief Sets the supported class to class class_name + /// + /// @param class_name client class to be supported by this pool + void allowClientClass(const ClientClass& class_name); + + /// @brief returns the client class + /// + /// @note The returned reference is only valid as long as the object + /// returned is valid. + /// + /// @return client class @ref client_class_ + const ClientClass& getClientClass() const { + return (client_class_); + } + + /// @brief Adds class class_name to classes required to be evaluated + /// + /// @param class_name client class required to be evaluated + void requireClientClass(const ClientClass& class_name) { + if (!required_classes_.contains(class_name)) { + required_classes_.insert(class_name); + } + } + + /// @brief Returns classes which are required to be evaluated + const ClientClasses& getRequiredClasses() const { + return (required_classes_); + } + + /// @brief returns the last address that was tried from this pool + /// + /// @return address/prefix that was last tried from this pool + isc::asiolink::IOAddress getLastAllocated() const { + return last_allocated_; + } + + /// @brief checks if the last address is valid + /// @return true if the last address is valid + bool isLastAllocatedValid() const { + return last_allocated_valid_; + } + + /// @brief sets the last address that was tried from this pool + /// + /// @param addr address/prefix to that was tried last + void setLastAllocated(const isc::asiolink::IOAddress& addr) { + last_allocated_ = addr; + last_allocated_valid_ = true; + } + + /// @brief resets the last address to invalid + void resetLastAllocated() { + last_allocated_valid_ = false; + } + + /// @brief Unparse a pool object. + /// + /// @return A pointer to unparsed pool configuration. + virtual data::ElementPtr toElement() const; + + /// @brief Returns pointer to the permutation associated with the pool. + /// + /// @return Pointer to the address range permutation. + IPRangePermutationPtr getPermutation() const { + return (permutation_); + } + +protected: + + /// @brief protected constructor + /// + /// This constructor is protected to prevent anyone from instantiating + /// Pool class directly. Instances of Pool4 and Pool6 should be created + /// instead. + /// + /// @param type type of lease that will be served from this pool + /// @param first first address of a range + /// @param last last address of a range + Pool(Lease::Type type, + const isc::asiolink::IOAddress& first, + const isc::asiolink::IOAddress& last); + + /// @brief returns the next unique Pool-ID + /// + /// @return the next unique Pool-ID + static uint32_t getNextID() { + static uint32_t id = 0; + return (id++); + } + + /// @brief pool-id + /// + /// This ID is used to identify this specific pool. + uint32_t id_; + + /// @brief The first address in a pool + isc::asiolink::IOAddress first_; + + /// @brief The last address in a pool + isc::asiolink::IOAddress last_; + + /// @brief defines a lease type that will be served from this pool + Lease::Type type_; + + /// @brief Stores number of possible leases. + /// + /// This could be calculated on the fly, but the calculations are somewhat + /// involved, so it is more efficient to calculate it once and just store + /// the result. Note that for very large pools, the number is capped at + /// max value of uint64_t. + uint64_t capacity_; + + /// @brief Pointer to the option data configuration for this pool. + CfgOptionPtr cfg_option_; + + /// @brief Optional definition of a client class + /// + /// @ref Network::client_class_ + ClientClass client_class_; + + /// @brief Required classes + /// + /// @ref isc::dhcp::Network::required_classes_ + ClientClasses required_classes_; + + /// @brief Pointer to the user context (may be NULL) + data::ConstElementPtr user_context_; + + /// @brief Last allocated address + /// See @ref isc::dhcp::Subnet::last_allocated_ia_ + /// Initialized and reset to first + isc::asiolink::IOAddress last_allocated_; + + /// @brief Status of last allocated address + bool last_allocated_valid_; + + /// @brief Pointer to the permutation object. + /// + /// It may be initialized for some pools to provide address + /// or delegated prefix randomization capabilities. + IPRangePermutationPtr permutation_; +}; + +class Pool4; + +/// @brief a pointer an IPv4 Pool +typedef boost::shared_ptr<Pool4> Pool4Ptr; + +/// @brief Pool information for IPv4 addresses +/// +/// It holds information about pool4, i.e. a range of IPv4 address space that +/// is configured for DHCP allocation. +class Pool4 : public Pool { +public: + /// @brief the constructor for Pool4 "min-max" style definition + /// + /// @param first the first address in a pool + /// @param last the last address in a pool + Pool4(const isc::asiolink::IOAddress& first, + const isc::asiolink::IOAddress& last); + + /// @brief the constructor for Pool4 "prefix/len" style definition + /// + /// @param prefix specifies prefix of the pool + /// @param prefix_len specifies length of the prefix of the pool + Pool4(const isc::asiolink::IOAddress& prefix, + uint8_t prefix_len); + + /// @brief Factory function for creating an instance of the @c Pool4. + /// + /// This function should be used to create an instance of the pool + /// within a hooks library in cases when the library may be unloaded + /// before the object is destroyed. This ensures that the ownership + /// of the object by the Kea process is retained. + /// + /// @param first the first address in a pool + /// @param last the last address in a pool + /// + /// @return Pointer to the @c Pool4 instance. + static Pool4Ptr create(const isc::asiolink::IOAddress& first, + const isc::asiolink::IOAddress& last); + + /// @brief Factory function for creating an instance of the @c Pool4. + /// + /// This function should be used to create an instance of the pool + /// within a hooks library in cases when the library may be unloaded + /// before the object is destroyed. This ensures that the ownership + /// of the object by the Kea process is retained. + /// + /// @param prefix specifies prefix of the pool. + /// @param prefix_len specifies length of the prefix of the pool. + /// + /// @return Pointer to the @c Pool4 instance. + static Pool4Ptr create(const isc::asiolink::IOAddress& prefix, + uint8_t prefix_len); + + /// @brief Unparse a Pool4 object. + /// + /// @return A pointer to unparsed Pool4 configuration. + virtual data::ElementPtr toElement() const; +}; + +class Pool6; + +/// @brief a pointer an IPv6 Pool +typedef boost::shared_ptr<Pool6> Pool6Ptr; + +/// @brief Pool information for IPv6 addresses and prefixes +/// +/// It holds information about pool6, i.e. a range of IPv6 address space that +/// is configured for DHCP allocation. +class Pool6 : public Pool { +public: + + /// @brief the constructor for Pool6 "min-max" style definition + /// + /// @throw BadValue if PD is define (PD can be only prefix/len) + /// + /// @param type type of the pool (IA or TA) + /// @param first the first address in a pool + /// @param last the last address in a pool + Pool6(Lease::Type type, const isc::asiolink::IOAddress& first, + const isc::asiolink::IOAddress& last); + + /// @brief the constructor for Pool6 "prefix/len" style definition + /// + /// For addressed, this is just a prefix/len definition. For prefixes, + /// there is one extra additional parameter delegated_len. It specifies + /// a size of delegated prefixes that the pool will be split into. For + /// example pool 2001:db8::/56, delegated_len=64 means that there is a + /// pool 2001:db8::/56. It will be split into 256 prefixes of length /64, + /// e.g. 2001:db8:0:1::/64, 2001:db8:0:2::/64 etc. + /// + /// Naming convention: + /// A smaller prefix length yields a shorter prefix which describes a larger + /// set of addresses. A larger length yields a longer prefix which describes + /// a smaller set of addresses. + /// + /// Obviously, prefix_len must define shorter or equal prefix length than + /// delegated_len, so prefix_len <= delegated_len. Note that it is slightly + /// confusing: bigger (larger) prefix actually has smaller prefix length, + /// e.g. /56 is a bigger prefix than /64, but has shorter (smaller) prefix + /// length. + /// + /// @throw BadValue if delegated_len is defined for non-PD types or + /// when delegated_len < prefix_len + /// + /// @param type type of the pool (IA, TA or PD) + /// @param prefix specifies prefix of the pool + /// @param prefix_len specifies prefix length of the pool + /// @param delegated_len specifies length of the delegated prefixes + Pool6(Lease::Type type, const isc::asiolink::IOAddress& prefix, + uint8_t prefix_len, uint8_t delegated_len = 128); + + /// @brief Constructor for DHCPv6 prefix pool with an excluded prefix. + /// + /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len + /// is equal to 0, the excluded prefix is assumed to be unspecified for + /// the pool. In this case, the server will not send the Prefix Exclude + /// option to a client. + /// + /// @param prefix specified a prefix of the pool. + /// @param prefix_len specifies prefix length of the pool. + /// @param delegated_len specifies length of the delegated prefixes. + /// @param excluded_prefix specifies an excluded prefix as per RFC6603. + /// @param excluded_prefix_len specifies length of an excluded prefix. + Pool6(const asiolink::IOAddress& prefix, const uint8_t prefix_len, + const uint8_t delegated_len, + const asiolink::IOAddress& excluded_prefix, + const uint8_t excluded_prefix_len); + + /// @brief Factory function for creating an instance of the @c Pool6. + /// + /// This function should be used to create an instance of the pool + /// within a hooks library in cases when the library may be unloaded + /// before the object is destroyed. This ensures that the ownership + /// of the object by the Kea process is retained. + /// + /// @param type type of the pool (IA or TA) + /// @param first the first address in a pool + /// @param last the last address in a pool + /// + /// @return Pointer to the @c Pool6 instance. + static Pool6Ptr create(Lease::Type type, + const isc::asiolink::IOAddress& first, + const isc::asiolink::IOAddress& last); + + /// @brief Factory function for creating an instance of the @c Pool6. + /// + /// This function should be used to create an instance of the pool + /// within a hooks library in cases when the library may be unloaded + /// before the object is destroyed. This ensures that the ownership + /// of the object by the Kea process is retained. + /// + /// @param type type of the pool (IA, TA or PD) + /// @param prefix specifies prefix of the pool + /// @param prefix_len specifies prefix length of the pool + /// @param delegated_len specifies length of the delegated prefixes + /// + /// @return Pointer to the @c Pool6 instance. + static Pool6Ptr create(Lease::Type type, + const isc::asiolink::IOAddress& prefix, + uint8_t prefix_len, + uint8_t delegated_len = 128); + + /// @brief Factory function for creating an instance of the @c Pool6. + /// + /// If @c excluded_prefix is equal to '::' and the @c excluded_prefix_len + /// is equal to 0, the excluded prefix is assumed to be unspecified for + /// the pool. In this case, the server will not send the Prefix Exclude + /// option to a client. + /// + /// @param prefix specifies a prefix of the pool. + /// @param prefix_len specifies prefix length of the pool. + /// @param delegated_len specifies length of the delegated prefixes. + /// @param excluded_prefix specifies an excluded prefix as per RFC6603. + /// @param excluded_prefix_len specifies length of an excluded prefix. + /// + /// @return Pointer to the @c Pool6 instance. + static Pool6Ptr create(const asiolink::IOAddress& prefix, + const uint8_t prefix_len, + const uint8_t delegated_len, + const asiolink::IOAddress& excluded_prefix, + const uint8_t excluded_prefix_len); + + /// @brief returns pool type + /// + /// @return pool type + Lease::Type getType() const { + return (type_); + } + + /// @brief returns delegated prefix length + /// + /// This may be useful for "prefix/len" style definition for + /// addresses, but is mostly useful for prefix pools. + /// @return prefix length (1-128) + uint8_t getLength() const { + return (prefix_len_); + } + + /// @brief Returns instance of the pool specific Prefix Exclude option. + /// + /// @return An instance of the Prefix Exclude option (RFC 6603) or NULL + /// if such option hasn't been specified for the pool. + Option6PDExcludePtr getPrefixExcludeOption() const { + return (pd_exclude_option_); + } + + /// @brief Unparse a Pool6 object. + /// + /// @return A pointer to unparsed Pool6 configuration. + virtual data::ElementPtr toElement() const; + + /// @brief returns textual representation of the pool + /// + /// @return textual representation + virtual std::string toText() const; + +private: + + /// @brief Generic method initializing a DHCPv6 pool. + /// + /// This method should be called by the constructors to initialize + /// DHCPv6 pools. + /// + /// @param Lease/pool type. + /// @param prefix An address or delegated prefix (depending on the + /// pool type specified as @c type). + /// @param prefix_len Prefix length. If a pool is an address pool, + /// this value should be set to 128. + /// @param delegated_len Length of the delegated prefixes. If a pool + /// is an address pool, this value should be set to 128. + /// @param excluded_prefix An excluded prefix as per RFC6603. This + /// value should only be specified for prefix pools. The value of + /// '::' means "unspecified". + /// @param excluded_prefix_len Length of the excluded prefix. This + /// is only specified for prefix pools. The value of 0 should be + /// used when @c excluded_prefix is not specified. + void init(const Lease::Type& type, + const asiolink::IOAddress& prefix, + const uint8_t prefix_len, + const uint8_t delegated_len, + const asiolink::IOAddress& excluded_prefix, + const uint8_t excluded_prefix_len); + + /// @brief Defines prefix length (for TYPE_PD only) + uint8_t prefix_len_; + + /// @brief A pointer to the Prefix Exclude option (RFC 6603). + Option6PDExcludePtr pd_exclude_option_; + +}; + +/// @brief a pointer to either IPv4 or IPv6 Pool +typedef boost::shared_ptr<Pool> PoolPtr; + +/// @brief a container for either IPv4 or IPv6 Pools +typedef std::vector<PoolPtr> PoolCollection; + + +} // end of isc::dhcp namespace +} // end of isc namespace + + +#endif // POOL_H |