summaryrefslogtreecommitdiffstats
path: root/src/lib/dhcpsrv/pool.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/dhcpsrv/pool.h')
-rw-r--r--src/lib/dhcpsrv/pool.h515
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