cfg_subnets6.h 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright (C) 2014-2015,2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #ifndef CFG_SUBNETS6_H
  7. #define CFG_SUBNETS6_H
  8. #include <asiolink/io_address.h>
  9. #include <dhcp/option.h>
  10. #include <cc/cfg_to_element.h>
  11. #include <dhcpsrv/subnet.h>
  12. #include <dhcpsrv/subnet_selector.h>
  13. #include <util/optional_value.h>
  14. #include <boost/shared_ptr.hpp>
  15. namespace isc {
  16. namespace dhcp {
  17. /// @brief Holds subnets configured for the DHCPv6 server.
  18. ///
  19. /// This class holds a collection of subnets configured for the DHCPv6 server.
  20. /// It allows for retrieving a subnet for the particular client using various
  21. /// parameters extracted from the DHCPv6 message. These parameters must be
  22. /// assigned to the appropriate members of the @c SubnetSelector structure.
  23. ///
  24. /// See @c CfgSubnets6::selectSubnet documentation for more details on how the subnet
  25. /// is selected for the client.
  26. class CfgSubnets6 : public isc::data::CfgToElement {
  27. public:
  28. /// @brief Adds new subnet to the configuration.
  29. ///
  30. /// @param subnet Pointer to the subnet being added.
  31. ///
  32. /// @throw isc::DuplicateSubnetID If the subnet id for the new subnet
  33. /// duplicates id of an existing subnet.
  34. void add(const Subnet6Ptr& subnet);
  35. /// @brief Returns pointer to the collection of all IPv6 subnets.
  36. ///
  37. /// This is used in a hook (subnet6_select), where the hook is able
  38. /// to choose a different subnet. Server code has to offer a list
  39. /// of possible choices (i.e. all subnets).
  40. ///
  41. /// @return A pointer to const Subnet6 collection
  42. const Subnet6Collection* getAll() const {
  43. return (&subnets_);
  44. }
  45. /// @brief Selects a subnet using parameters specified in the selector.
  46. ///
  47. /// This method tries to retrieve the subnet for the client using various
  48. /// parameters extracted from the client's message using the following
  49. /// logic.
  50. ///
  51. /// If the relay agent link address is set to zero it is assumed that
  52. /// the subnet is selected for the directly connected client.
  53. /// In this case it is checked if there is any subnet associated with the
  54. /// interface over which the message has been received. If there is no
  55. /// subnet explicitly associated with this interface the client's address
  56. /// will be used to check if the address is in range with any of the
  57. /// subnets.
  58. ///
  59. /// If the message was relayed it is possible that the relay agent has
  60. /// appended an Interface ID option. If this option is present, the method
  61. /// will check if it matches with any explicitly specified interface id
  62. /// for any subnet. If it does, the subnet is returned. Otherwise, the
  63. /// relay agents link address is used to select the subnet. In this case,
  64. /// the method will first check if this link address is explicitly
  65. /// associated with any subnet. If not, it is checked if the link address
  66. /// is in range with any of the subnets.
  67. ///
  68. /// @todo This method requires performance improvement! It currently
  69. /// iterates over all existing subnets (possibly a couple of times)
  70. /// to find the one which fulfils the search criteria. The subnet storage
  71. /// is implemented as a simple STL vector which precludes fast searches
  72. /// using specific keys. Hence, full scan is required. To improve the
  73. /// search performance a different container type is required, e.g.
  74. /// multi-index container, or something of a similar functionality.
  75. ///
  76. /// @param selector Const reference to the selector structure which holds
  77. /// various information extracted from the client's packet which are used
  78. /// to find appropriate subnet.
  79. ///
  80. /// @return Pointer to the selected subnet or NULL if no subnet found.
  81. Subnet6Ptr selectSubnet(const SubnetSelector& selector) const;
  82. /// @brief Selects the subnet using a specified address.
  83. ///
  84. /// This method searches for the subnet using the specified address. If
  85. /// the specified address is a link address on the relay agent (which is
  86. /// indicated by the 3rd argument) the method will first try to match the
  87. /// specified address with the relay addresses explicitly specified for
  88. /// existing subnets. If no match is found, the method will check if the
  89. /// address is in range with any of the subnets.
  90. ///
  91. /// If the address is not a relay agent link address (@c is_relay_address
  92. /// is set to false), the method will simply check if the address is in
  93. /// range with any of the subnets.
  94. ///
  95. /// @note This method is mainly to be used in unit tests, which often
  96. /// require sanity-checking if the subnet exists for the particular
  97. /// address. For other purposes the @c selectSubnet(SubnetSelector) should
  98. /// rather be used instead.
  99. ///
  100. /// @todo This method requires performance improvement! It currently
  101. /// iterates over all existing subnets (possibly a couple of times)
  102. /// to find the one which fulfils the search criteria. The subnet storage
  103. /// is implemented as a simple STL vector which precludes fast searches
  104. /// using specific keys. Hence, full scan is required. To improve the
  105. /// search performance a different container type is required, e.g.
  106. /// multi-index container, or something of a similar functionality.
  107. ///
  108. /// @param address Address for which the subnet is searched.
  109. /// @param client_classes Optional parameter specifying the classes that
  110. /// the client belongs to.
  111. /// @param is_relay_address Specifies if the provided address is an
  112. /// address of the relay agent (true) or not (false).
  113. ///
  114. /// @return Pointer to the selected subnet or NULL if no subnet found.
  115. Subnet6Ptr
  116. selectSubnet(const asiolink::IOAddress& address,
  117. const ClientClasses& client_classes = ClientClasses(),
  118. const bool is_relay_address = false) const;
  119. /// @brief Updates statistics.
  120. ///
  121. /// This method updates statistics that are affected by the newly committed
  122. /// configuration. In particular, it updates the number of available addresses
  123. /// and prefixes in each subnet. Other statistics may be added in the future. In
  124. /// general, these are statistics that are dependent only on configuration, so
  125. /// they are not expected to change until the next reconfiguration event.
  126. void updateStatistics();
  127. /// @brief Removes statistics.
  128. ///
  129. /// During commitment of a new configuration, we need to get rid of the old
  130. /// statistics for the old configuration. In particular, we need to remove
  131. /// anything related to subnets, as there may be fewer subnets in the new
  132. /// configuration and also subnet-ids may change.
  133. void removeStatistics();
  134. /// @brief Unparse a configuration object
  135. ///
  136. /// @return a pointer to unparsed configuration
  137. virtual isc::data::ElementPtr toElement() const;
  138. private:
  139. /// @brief Selects a subnet using the interface name.
  140. ///
  141. /// This method searches for the subnet using the name of the interface.
  142. /// If any of the subnets is explicitly associated with the interface
  143. /// name, the subnet is returned.
  144. ///
  145. /// @todo This method requires performance improvement! It currently
  146. /// iterates over all existing subnets to find the one which fulfils
  147. /// the search criteria. The subnet storage is implemented as a
  148. /// simple STL vector which precludes fast searches using specific
  149. /// keys. Hence, full scan is required. To improve the search
  150. /// performance a different container type is required, e.g.
  151. /// multi-index container, or something of a similar functionality.
  152. ///
  153. /// @param iface_name Interface name.
  154. /// @param client_classes Optional parameter specifying the classes that
  155. /// the client belongs to.
  156. ///
  157. /// @return Pointer to the selected subnet or NULL if no subnet found.
  158. Subnet6Ptr
  159. selectSubnet(const std::string& iface_name,
  160. const ClientClasses& client_classes) const;
  161. /// @brief Selects a subnet using Interface ID option.
  162. ///
  163. /// This method searches for the subnet using the Interface ID option
  164. /// inserted by the relay agent to the message from a client. If any
  165. /// of the subnets is explicitly associated with that interface id, the
  166. /// subnet is returned.
  167. ///
  168. /// @todo This method requires performance improvement! It currently
  169. /// iterates over all existing subnets to find the one which fulfils
  170. /// the search criteria. The subnet storage is implemented as a
  171. /// simple STL vector which precludes fast searches using specific
  172. /// keys. Hence, full scan is required. To improve the search
  173. /// performance a different container type is required, e.g.
  174. /// multi-index container, or something of a similar functionality.
  175. ///
  176. /// @param interface_id An instance of the Interface ID option received
  177. /// from the client.
  178. /// @param client_classes Optional parameter specifying the classes that
  179. /// the client belongs to.
  180. ///
  181. /// @return Pointer to the selected subnet or NULL if no subnet found.
  182. Subnet6Ptr
  183. selectSubnet(const OptionPtr& interface_id,
  184. const ClientClasses& client_classes) const;
  185. /// @brief Checks that the IPv6 subnet with the given id already exists.
  186. ///
  187. /// @param subnet Subnet for which this function will check if the other
  188. /// subnet with equal id already exists.
  189. ///
  190. /// @return true if the duplicate subnet exists.
  191. bool isDuplicate(const Subnet6& subnet) const;
  192. /// @brief A container for IPv6 subnets.
  193. Subnet6Collection subnets_;
  194. };
  195. /// @name Pointer to the @c CfgSubnets6 objects.
  196. //@{
  197. /// @brief Non-const pointer.
  198. typedef boost::shared_ptr<CfgSubnets6> CfgSubnets6Ptr;
  199. /// @brief Const pointer.
  200. typedef boost::shared_ptr<const CfgSubnets6> ConstCfgSubnets6Ptr;
  201. //@}
  202. }
  203. }
  204. #endif // CFG_SUBNETS6_H