cfg_subnets4.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // Copyright (C) 2014-2015 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_SUBNETS4_H
  7. #define CFG_SUBNETS4_H
  8. #include <asiolink/io_address.h>
  9. #include <dhcpsrv/subnet.h>
  10. #include <dhcpsrv/subnet_selector.h>
  11. #include <boost/shared_ptr.hpp>
  12. namespace isc {
  13. namespace dhcp {
  14. /// @brief Holds subnets configured for the DHCPv4 server.
  15. ///
  16. /// This class holds a collection of subnets configured for the DHCPv4 server.
  17. /// It allows for retrieving a subnet for the particular client using various
  18. /// parameters extracted from the DHCPv4 message. These parameters must be
  19. /// assigned to the appropriate members of the @c CfgSubnets4::Selector
  20. /// structure.
  21. ///
  22. /// See @c CfgSubnets4::selectSubnet documentation for more details on how the
  23. /// subnet is selected for the client.
  24. class CfgSubnets4 {
  25. public:
  26. /// @brief Adds new subnet to the configuration.
  27. ///
  28. /// @param subnet Pointer to the subnet being added.
  29. ///
  30. /// @throw isc::DuplicateSubnetID If the subnet id for the new subnet
  31. /// duplicates id of an existing subnet.
  32. void add(const Subnet4Ptr& subnet);
  33. /// @brief Returns pointer to the collection of all IPv4 subnets.
  34. ///
  35. /// This is used in a hook (subnet4_select), where the hook is able
  36. /// to choose a different subnet. Server code has to offer a list
  37. /// of possible choices (i.e. all subnets).
  38. ///
  39. /// @return A pointer to const Subnet4 collection
  40. const Subnet4Collection* getAll() const {
  41. return (&subnets_);
  42. }
  43. /// @brief Returns pointer to the selected subnet.
  44. ///
  45. /// This method tries to retrieve the subnet for the client using various
  46. /// parameters extracted from the client's message using the following
  47. /// logic.
  48. ///
  49. /// First when link select suboption of relay agent information option
  50. /// or subnet select option in this order exists the address is used
  51. ///
  52. /// If the giaddr value is set in the selector it means that the client's
  53. /// message was relayed. The subnet configuration allows for setting the
  54. /// relay address for each subnet to indicate that the subnet must be
  55. /// assigned when the packet was transmitted over the particular relay.
  56. /// This method first tries to match the giaddr with the relay addresses
  57. /// specified for all subnets. If the relay address for the subnet is equal
  58. /// to the address of the relay through which the message was transmitted,
  59. /// the particular subnet is returned.
  60. ///
  61. /// If the giaddr is not matched with any of the relay addresses in any
  62. /// subnet or the message was not relayed, the method will need to try to
  63. /// match one of the addresses in the client's message with the prefixes
  64. /// of the existing subnets. Depending whether it is a relayed message,
  65. /// message from the renewing client or a new allocation, the server will
  66. /// pick one of the following addresses for this matching:
  67. /// - giaddr - for relayed message
  68. /// - ciaddr - for renewing or rebinding client
  69. /// - source address - for the renewing client which didn't provide ciaddr
  70. /// - address on the local server's interface if this is a new allocation
  71. /// requested by the directly connected client
  72. ///
  73. /// If the address matches with a subnet, the subnet is returned.
  74. ///
  75. /// @todo This method requires performance improvement! It currently
  76. /// iterates over all existing subnets (possibly a couple of times)
  77. /// to find the one which fulfils the search criteria. The subnet storage
  78. /// is implemented as a simple STL vector which precludes fast searches
  79. /// using specific keys. Hence, full scan is required. To improve the
  80. /// search performance a different container type is required, e.g.
  81. /// multi-index container, or something of a similar functionality.
  82. ///
  83. /// @param selector Const reference to the selector structure which holds
  84. /// various information extracted from the client's packet which are used
  85. /// to find appropriate subnet.
  86. ///
  87. /// @return Pointer to the selected subnet or NULL if no subnet found.
  88. /// @throw isc::BadValue if the values in the subnet selector are invalid
  89. /// or they are insufficient to select a subnet.
  90. Subnet4Ptr selectSubnet(const SubnetSelector& selector) const;
  91. /// @brief Returns pointer to a subnet if provided address is in its range.
  92. ///
  93. /// This method returns a pointer to the subnet if the address passed in
  94. /// parameter is in range with this subnet. This is mainly used for unit
  95. /// testing. This method is also called by the
  96. /// @c selectSubnet(SubnetSelector).
  97. ///
  98. /// @todo This method requires performance improvement! It currently
  99. /// iterates over all existing subnets to find the one which fulfils
  100. /// the search criteria. The subnet storage is implemented as a simple
  101. /// STL vector which precludes fast searches using specific keys.
  102. /// Hence, full scan is required. To improve the search performance a
  103. /// different container type is required, e.g. multi-index container,
  104. /// or something of a similar functionality.
  105. ///
  106. /// @param address Address for which the subnet is searched.
  107. /// @param client_classes Optional parameter specifying the classes that
  108. /// the client belongs to.
  109. ///
  110. /// @return Pointer to the selected subnet or NULL if no subnet found.
  111. Subnet4Ptr selectSubnet(const asiolink::IOAddress& address,
  112. const ClientClasses& client_classes
  113. = ClientClasses()) const;
  114. /// @brief Attempts to do subnet selection based on DHCP4o6 information
  115. ///
  116. /// The algorithm implemented is as follows:
  117. ///
  118. /// - First: try to match IPv6 subnet (4o6-subnet parameter) with the
  119. /// remote IPv6 address of the incoming packet
  120. /// - Second: try to match interface-id (4o6-interface-id parameter)
  121. /// with the interface-id option in the incoming 4o6 packet
  122. /// - Third: try to match interface-name (4o6-interface parameter)
  123. /// with the name of the interface the incoming 4o6 packet was
  124. /// received over.
  125. ///
  126. /// @todo: Add additional selection criteria. See
  127. /// http://kea.isc.org/wiki/ISC-DHCP4o6-Design for details.
  128. ///
  129. /// @param selector Const reference to the selector structure which holds
  130. /// various information extracted from the client's packet which are used
  131. /// to find appropriate subnet.
  132. /// @return Pointer to the selected subnet or NULL if no subnet found.
  133. Subnet4Ptr
  134. selectSubnet4o6(const SubnetSelector& selector) const;
  135. /// @brief Updates statistics.
  136. ///
  137. /// This method updates statistics that are affected by the newly committed
  138. /// configuration. In particular, it updates the number of available addresses
  139. /// in each subnet. Other statistics may be added in the future. In general,
  140. /// these are statistics that are dependant only on configuration, so they are
  141. /// not expected to change until the next reconfiguration event.
  142. void updateStatistics();
  143. /// @brief Removes statistics.
  144. ///
  145. /// During commitment of a new configuration, we need to get rid of the old
  146. /// statistics for the old configuration. In particular, we need to remove
  147. /// anything related to subnets, as there may be fewer subnets in the new
  148. /// configuration and also subnet-ids may change.
  149. void removeStatistics();
  150. private:
  151. /// @brief Checks that the IPv4 subnet with the given id already exists.
  152. ///
  153. /// @param subnet Subnet for which this function will check if the other
  154. /// subnet with equal id already exists.
  155. ///
  156. /// @return true if the duplicate subnet exists.
  157. bool isDuplicate(const Subnet4& subnet) const;
  158. /// @brief A container for IPv4 subnets.
  159. Subnet4Collection subnets_;
  160. };
  161. /// @name Pointer to the @c CfgSubnets4 objects.
  162. //@{
  163. /// @brief Non-const pointer.
  164. typedef boost::shared_ptr<CfgSubnets4> CfgSubnets4Ptr;
  165. /// @brief Const pointer.
  166. typedef boost::shared_ptr<const CfgSubnets4> ConstCfgSubnets4Ptr;
  167. //@}
  168. }
  169. }
  170. #endif // CFG_SUBNETS4_H