subnet.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678
  1. // Copyright (C) 2012-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 SUBNET_H
  7. #define SUBNET_H
  8. #include <asiolink/io_address.h>
  9. #include <cc/data.h>
  10. #include <dhcp/option_space_container.h>
  11. #include <dhcpsrv/assignable_network.h>
  12. #include <dhcpsrv/lease.h>
  13. #include <dhcpsrv/pool.h>
  14. #include <dhcpsrv/subnet_id.h>
  15. #include <dhcpsrv/triplet.h>
  16. #include <boost/multi_index/mem_fun.hpp>
  17. #include <boost/multi_index/indexed_by.hpp>
  18. #include <boost/multi_index/ordered_index.hpp>
  19. #include <boost/multi_index/random_access_index.hpp>
  20. #include <boost/multi_index_container.hpp>
  21. #include <boost/pointer_cast.hpp>
  22. #include <boost/shared_ptr.hpp>
  23. namespace isc {
  24. namespace dhcp {
  25. class Subnet : public data::CfgToElement {
  26. // Assignable network is our friend to allow it to call
  27. // @ref Subnet::setSharedNetwork private function.
  28. friend class AssignableNetwork;
  29. public:
  30. /// @brief checks if specified address is in range
  31. bool inRange(const isc::asiolink::IOAddress& addr) const;
  32. /// @brief checks if the specified address is in pools
  33. ///
  34. /// Note the difference between inRange() and inPool() for addresses
  35. /// (i.e. *not* prefixes). For a given subnet (e.g. 2001::/64) there
  36. /// may be one or more pools defined that may or may not cover
  37. /// entire subnet, e.g. pool 2001::1-2001::10). inPool() returning
  38. /// true implies inRange(), but the reverse implication is not
  39. /// always true. For the given example, 2001::1234:abcd would return
  40. /// true for inRange(), but false for inPool() check.
  41. ///
  42. /// @param type type of pools to iterate over
  43. /// @param addr this address will be checked if it belongs to any pools in
  44. /// that subnet
  45. /// @return true if the address is in any of the pools
  46. bool inPool(Lease::Type type, const isc::asiolink::IOAddress& addr) const;
  47. /// @brief returns the last address that was tried from this pool
  48. ///
  49. /// This method returns the last address that was attempted to be allocated
  50. /// from this subnet. This is used as helper information for the next
  51. /// iteration of the allocation algorithm.
  52. ///
  53. /// @todo: Define map<SubnetID, IOAddress> somewhere in the
  54. /// AllocEngine::IterativeAllocator and keep the data there
  55. ///
  56. /// @param type lease type to be returned
  57. /// @return address/prefix that was last tried from this pool
  58. isc::asiolink::IOAddress getLastAllocated(Lease::Type type) const;
  59. /// @brief sets the last address that was tried from this pool
  60. ///
  61. /// This method sets the last address that was attempted to be allocated
  62. /// from this subnet. This is used as helper information for the next
  63. /// iteration of the allocation algorithm.
  64. ///
  65. /// @todo: Define map<SubnetID, IOAddress> somewhere in the
  66. /// AllocEngine::IterativeAllocator and keep the data there
  67. /// @param addr address/prefix to that was tried last
  68. /// @param type lease type to be set
  69. void setLastAllocated(Lease::Type type,
  70. const isc::asiolink::IOAddress& addr);
  71. /// @brief Returns unique ID for that subnet
  72. /// @return unique ID for that subnet
  73. SubnetID getID() const { return (id_); }
  74. /// @brief Returns subnet parameters (prefix and prefix length)
  75. ///
  76. /// @return (prefix, prefix length) pair
  77. std::pair<isc::asiolink::IOAddress, uint8_t> get() const {
  78. return (std::make_pair(prefix_, prefix_len_));
  79. }
  80. /// @brief Adds a new pool for the subnet.
  81. ///
  82. /// This method checks that the address range represented by the pool
  83. /// matches the subnet prefix, if the pool type is different than
  84. /// IA_PD. The prefixes from the IA_PD pools don't need to match the
  85. /// prefix from the subnet from which they are handed out to the
  86. /// requesting router because the requesting router may use the
  87. /// delegated prefixes in different networks (using different subnets).
  88. ///
  89. /// A DHCPv4 pool being added must not overlap with any existing DHCPv4
  90. /// pool. A DHCPv6 pool being added must not overlap with any existing
  91. /// DHCPv6 pool.
  92. ///
  93. /// Pools held within a subnet are sorted by first pool address/prefix
  94. /// from the lowest to the highest.
  95. ///
  96. /// @param pool pool to be added
  97. ///
  98. /// @throw isc::BadValue if the pool type is invalid, the pool
  99. /// is not an IA_PD pool and the address range of this pool does not
  100. /// match the subnet prefix, or the pool overlaps with an existing pool
  101. /// within the subnet.
  102. void addPool(const PoolPtr& pool);
  103. /// @brief Deletes all pools of specified type
  104. ///
  105. /// This method is used for testing purposes only
  106. /// @param type type of pools to be deleted
  107. void delPools(Lease::Type type);
  108. /// @brief Returns a pool that specified address belongs to
  109. ///
  110. /// This method uses binary search to retrieve the pool. Thus, the number
  111. /// of comparisons performed by this method is logarithmic in the number
  112. /// of pools belonging to a subnet.
  113. ///
  114. /// If there is no pool that the address belongs to (hint is invalid), other
  115. /// pool of specified type will be returned.
  116. ///
  117. /// With anypool set to true, this is means give me a pool, preferably
  118. /// the one that addr belongs to. With anypool set to false, it means
  119. /// give me a pool that addr belongs to (or NULL if here is no such pool)
  120. ///
  121. /// @param type pool type that the pool is looked for
  122. /// @param addr address that the returned pool should cover (optional)
  123. /// @param anypool other pool may be returned as well, not only the one
  124. /// that addr belongs to
  125. /// @return found pool (or NULL)
  126. const PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress& addr,
  127. bool anypool = true) const;
  128. /// @brief Returns a pool without any address specified
  129. ///
  130. /// @param type pool type that the pool is looked for
  131. /// @return returns one of the pools defined
  132. PoolPtr getAnyPool(Lease::Type type) {
  133. return (getPool(type, default_pool()));
  134. }
  135. /// @brief Returns the default address that will be used for pool selection
  136. ///
  137. /// It must be implemented in derived classes (should return :: for Subnet6
  138. /// and 0.0.0.0 for Subnet4)
  139. virtual isc::asiolink::IOAddress default_pool() const = 0;
  140. /// @brief Returns all pools (const variant)
  141. ///
  142. /// The reference is only valid as long as the object that returned it.
  143. ///
  144. /// @param type lease type to be set
  145. /// @return a collection of all pools
  146. const PoolCollection& getPools(Lease::Type type) const;
  147. /// @brief Returns the number of possible leases for specified lease type
  148. ///
  149. /// @param type type of the lease
  150. uint64_t getPoolCapacity(Lease::Type type) const;
  151. /// @brief Returns textual representation of the subnet (e.g.
  152. /// "2001:db8::/64")
  153. ///
  154. /// @return textual representation
  155. virtual std::string toText() const;
  156. /// @brief Resets subnet-id counter to its initial value (1)
  157. ///
  158. /// This should be called during reconfiguration, before any new
  159. /// subnet objects are created. It will ensure that the subnet_id will
  160. /// be consistent between reconfigures.
  161. static void resetSubnetID() {
  162. static_id_ = 1;
  163. }
  164. /// @brief Retrieves pointer to a shared network associated with a subnet.
  165. ///
  166. /// By implementing it as a template function we overcome a need to
  167. /// include shared_network.h header file to specify return type explicitly.
  168. /// The header can't be included because it would cause circular dependency
  169. /// between subnet.h and shared_network.h.
  170. ///
  171. /// This method uses an argument to hold a return value to allow the compiler
  172. /// to infer the return type without a need to call this function with an
  173. /// explicit return type as template argument.
  174. ///
  175. /// @param [out] shared_network Pointer to the shared network where returned
  176. /// value should be assigned.
  177. ///
  178. /// @tparam Type of the shared network, i.e. @ref SharedNetwork4 or a
  179. /// @ref SharedNetwork6.
  180. template<typename SharedNetworkPtrType>
  181. void getSharedNetwork(SharedNetworkPtrType& shared_network) const {
  182. shared_network = boost::dynamic_pointer_cast<
  183. typename SharedNetworkPtrType::element_type>(shared_network_.lock());
  184. }
  185. private:
  186. /// @brief Assigns shared network to a subnet.
  187. ///
  188. /// This method replaces any shared network associated with a subnet with
  189. /// a new shared network.
  190. ///
  191. /// @param shared_network Pointer to a new shared network to be associated
  192. /// with the subnet.
  193. void setSharedNetwork(const NetworkPtr& shared_network) {
  194. shared_network_ = shared_network;
  195. }
  196. public:
  197. /// @brief Sets user context.
  198. /// @param ctx user context to be stored.
  199. void setContext(const data::ConstElementPtr& ctx) {
  200. user_context_ = ctx;
  201. }
  202. /// @brief Returns const pointer to the user context.
  203. data::ConstElementPtr getContext() const {
  204. return (user_context_);
  205. }
  206. protected:
  207. /// @brief Returns all pools (non-const variant)
  208. ///
  209. /// The reference is only valid as long as the object that returned it.
  210. ///
  211. /// @param type lease type to be set
  212. /// @return a collection of all pools
  213. PoolCollection& getPoolsWritable(Lease::Type type);
  214. /// @brief Protected constructor
  215. //
  216. /// By making the constructor protected, we make sure that no one will
  217. /// ever instantiate that class. Subnet4 and Subnet6 should be used instead.
  218. ///
  219. /// This constructor assigns a new subnet-id (see @ref generateNextID).
  220. /// This subnet-id has unique value that is strictly monotonously increasing
  221. /// for each subnet, until it is explicitly reset back to 1 during
  222. /// reconfiguration process.
  223. ///
  224. /// @param prefix subnet prefix
  225. /// @param len prefix length for the subnet
  226. /// @param id arbitrary subnet id, value of 0 triggers autogeneration
  227. /// of subnet id
  228. Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
  229. const SubnetID id);
  230. /// @brief virtual destructor
  231. ///
  232. /// A virtual destructor is needed because other classes
  233. /// derive from this class.
  234. virtual ~Subnet() { };
  235. /// @brief keeps the subnet-id value
  236. ///
  237. /// It is incremented every time a new Subnet object is created. It is reset
  238. /// (@ref resetSubnetID) every time reconfiguration
  239. /// occurs.
  240. ///
  241. /// Static value initialized in subnet.cc.
  242. static SubnetID static_id_;
  243. /// @brief returns the next unique Subnet-ID
  244. ///
  245. /// This method generates and returns the next unique subnet-id.
  246. /// It is a strictly monotonously increasing value (1,2,3,...) for
  247. /// each new Subnet object created. It can be explicitly reset
  248. /// back to 1 during reconfiguration (@ref resetSubnetID).
  249. ///
  250. /// @return the next unique Subnet-ID
  251. static SubnetID generateNextID() {
  252. return (static_id_++);
  253. }
  254. /// @brief Checks if used pool type is valid
  255. ///
  256. /// Allowed type for Subnet4 is Pool::TYPE_V4.
  257. /// Allowed types for Subnet6 are Pool::TYPE_{IA,TA,PD}.
  258. /// This method is implemented in derived classes.
  259. ///
  260. /// @param type type to be checked
  261. /// @throw BadValue if invalid value is used
  262. virtual void checkType(Lease::Type type) const = 0;
  263. /// @brief returns a sum of possible leases in all pools
  264. /// @param pools list of pools
  265. /// @return sum of possible leases
  266. uint64_t sumPoolCapacity(const PoolCollection& pools) const;
  267. /// @brief Checks if the specified pool overlaps with an existing pool.
  268. ///
  269. /// @param pool_type Pool type.
  270. /// @param pool Pointer to a pool for which the method should check if
  271. /// it overlaps with any existing pool within this subnet.
  272. ///
  273. /// @return true if pool overlaps with an existing pool of a specified
  274. /// type.
  275. bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
  276. /// @brief Unparse a subnet object.
  277. ///
  278. /// @return A pointer to unparsed subnet configuration.
  279. virtual data::ElementPtr toElement() const;
  280. /// @brief subnet-id
  281. ///
  282. /// Subnet-id is a unique value that can be used to find or identify
  283. /// a Subnet4 or Subnet6.
  284. SubnetID id_;
  285. /// @brief collection of IPv4 or non-temporary IPv6 pools in that subnet
  286. PoolCollection pools_;
  287. /// @brief collection of IPv6 temporary address pools in that subnet
  288. PoolCollection pools_ta_;
  289. /// @brief collection of IPv6 prefix pools in that subnet
  290. PoolCollection pools_pd_;
  291. /// @brief a prefix of the subnet
  292. isc::asiolink::IOAddress prefix_;
  293. /// @brief a prefix length of the subnet
  294. uint8_t prefix_len_;
  295. /// @brief last allocated address
  296. ///
  297. /// This is the last allocated address that was previously allocated from
  298. /// this particular subnet. Some allocation algorithms (e.g. iterative) use
  299. /// that value, others do not. It should be noted that although the value
  300. /// is usually correct, there are cases when it is invalid, e.g. after
  301. /// removing a pool, restarting or changing allocation algorithms. For
  302. /// that purpose it should be only considered a help that should not be
  303. /// fully trusted.
  304. isc::asiolink::IOAddress last_allocated_ia_;
  305. /// @brief last allocated temporary address
  306. ///
  307. /// See @ref last_allocated_ia_ for details.
  308. isc::asiolink::IOAddress last_allocated_ta_;
  309. /// @brief last allocated IPv6 prefix
  310. ///
  311. /// See @ref last_allocated_ia_ for details.
  312. isc::asiolink::IOAddress last_allocated_pd_;
  313. /// @brief Name of the network interface (if connected directly)
  314. std::string iface_;
  315. /// @brief Pointer to a shared network that subnet belongs to.
  316. WeakNetworkPtr shared_network_;
  317. /// @brief Pointer to the user context (may be NULL)
  318. data::ConstElementPtr user_context_;
  319. };
  320. /// @brief A generic pointer to either Subnet4 or Subnet6 object
  321. typedef boost::shared_ptr<Subnet> SubnetPtr;
  322. class Subnet4;
  323. /// @brief A const pointer to a @c Subnet4 object.
  324. typedef boost::shared_ptr<const Subnet4> ConstSubnet4Ptr;
  325. /// @brief A pointer to a @c Subnet4 object.
  326. typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
  327. /// @brief A configuration holder for IPv4 subnet.
  328. ///
  329. /// This class represents an IPv4 subnet.
  330. class Subnet4 : public Subnet, public Network4 {
  331. public:
  332. /// @brief Constructor with all parameters
  333. ///
  334. /// This constructor calls Subnet::Subnet, where subnet-id is generated.
  335. ///
  336. /// @param prefix Subnet4 prefix
  337. /// @param length prefix length
  338. /// @param t1 renewal timer (in seconds)
  339. /// @param t2 rebind timer (in seconds)
  340. /// @param valid_lifetime preferred lifetime of leases (in seconds)
  341. /// @param id arbitrary subnet id, default value of 0 triggers
  342. /// autogeneration of subnet id
  343. Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
  344. const Triplet<uint32_t>& t1,
  345. const Triplet<uint32_t>& t2,
  346. const Triplet<uint32_t>& valid_lifetime,
  347. const SubnetID id = 0);
  348. /// @brief Returns next subnet within shared network.
  349. ///
  350. /// If the current subnet doesn't belong to any shared network or if
  351. /// the next subnet is the same as first subnet (specified in the
  352. /// argument) a NULL pointer is returned.
  353. ///
  354. /// @param first_subnet Pointer to the subnet from which iterations have
  355. /// started.
  356. ///
  357. /// @return Pointer to the next subnet or NULL pointer if the next subnet
  358. /// is the first subnet or if the current subnet doesn't belong to a
  359. /// shared network.
  360. Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet) const;
  361. /// @brief Returns next subnet within shared network that matches
  362. /// client classes.
  363. ///
  364. /// @param first_subnet Pointer to the subnet from which iterations have
  365. /// started.
  366. /// @param client_classes List of classes that the client belongs to.
  367. /// The subnets not matching the classes aren't returned by this
  368. /// method.
  369. ///
  370. /// @return Pointer to the next subnet or NULL pointer if the next subnet
  371. /// is the first subnet or if the current subnet doesn't belong to a
  372. /// shared network.
  373. Subnet4Ptr getNextSubnet(const Subnet4Ptr& first_subnet,
  374. const ClientClasses& client_classes) const;
  375. /// @brief Checks whether this subnet and parent shared network supports
  376. /// the client that belongs to specified classes.
  377. ///
  378. /// This method extends the @ref Network::clientSupported method with
  379. /// additional checks whether shared network owning this class supports
  380. /// the client belonging to specified classes. If the class doesn't
  381. /// belong to a shared network this method only checks if the subnet
  382. /// supports specified classes.
  383. ///
  384. /// @param client_classes List of classes the client belongs to.
  385. /// @return true if client can be supported, false otherwise.
  386. virtual bool
  387. clientSupported(const isc::dhcp::ClientClasses& client_classes) const;
  388. /// @brief Sets siaddr for the Subnet4
  389. ///
  390. /// Will be used for siaddr field (the next server) that typically is used
  391. /// as TFTP server. If not specified, the default value of 0.0.0.0 is
  392. /// used.
  393. void setSiaddr(const isc::asiolink::IOAddress& siaddr);
  394. /// @brief Returns siaddr for this subnet
  395. ///
  396. /// @return siaddr value
  397. isc::asiolink::IOAddress getSiaddr() const;
  398. /// @brief Returns DHCP4o6 configuration parameters.
  399. ///
  400. /// This structure is always available. If the 4o6 is not enabled, its
  401. /// enabled_ field will be set to false.
  402. Cfg4o6& get4o6() {
  403. return (dhcp4o6_);
  404. }
  405. /// @brief Returns const DHCP4o6 configuration parameters.
  406. ///
  407. /// This structure is always available. If the 4o6 is not enabled, its
  408. /// enabled_ field will be set to false.
  409. const Cfg4o6& get4o6() const {
  410. return (dhcp4o6_);
  411. }
  412. /// @brief Unparse a subnet object.
  413. ///
  414. /// @return A pointer to unparsed subnet configuration.
  415. virtual data::ElementPtr toElement() const;
  416. private:
  417. /// @brief Returns default address for pool selection
  418. /// @return ANY IPv4 address
  419. virtual isc::asiolink::IOAddress default_pool() const {
  420. return (isc::asiolink::IOAddress("0.0.0.0"));
  421. }
  422. /// @brief Checks if used pool type is valid
  423. ///
  424. /// Allowed type for Subnet4 is Pool::TYPE_V4.
  425. ///
  426. /// @param type type to be checked
  427. /// @throw BadValue if invalid value is used
  428. virtual void checkType(Lease::Type type) const;
  429. /// @brief siaddr value for this subnet
  430. isc::asiolink::IOAddress siaddr_;
  431. /// @brief All the information related to DHCP4o6
  432. Cfg4o6 dhcp4o6_;
  433. };
  434. class Subnet6;
  435. /// @brief A const pointer to a @c Subnet6 object.
  436. typedef boost::shared_ptr<const Subnet6> ConstSubnet6Ptr;
  437. /// @brief A pointer to a Subnet6 object
  438. typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
  439. /// @brief A configuration holder for IPv6 subnet.
  440. ///
  441. /// This class represents an IPv6 subnet.
  442. class Subnet6 : public Subnet, public Network6 {
  443. public:
  444. /// @brief Constructor with all parameters
  445. ///
  446. /// This constructor calls Subnet::Subnet, where subnet-id is generated.
  447. ///
  448. /// @param prefix Subnet6 prefix
  449. /// @param length prefix length
  450. /// @param t1 renewal timer (in seconds)
  451. /// @param t2 rebind timer (in seconds)
  452. /// @param preferred_lifetime preferred lifetime of leases (in seconds)
  453. /// @param valid_lifetime preferred lifetime of leases (in seconds)
  454. /// @param id arbitrary subnet id, default value of 0 triggers
  455. /// autogeneration of subnet id
  456. Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
  457. const Triplet<uint32_t>& t1,
  458. const Triplet<uint32_t>& t2,
  459. const Triplet<uint32_t>& preferred_lifetime,
  460. const Triplet<uint32_t>& valid_lifetime,
  461. const SubnetID id = 0);
  462. /// @brief Returns next subnet within shared network.
  463. ///
  464. /// If the current subnet doesn't belong to any shared network or if
  465. /// the next subnet is the same as first subnet (specified in the
  466. /// arguments) a NULL pointer is returned.
  467. ///
  468. /// @param first_subnet Pointer to the subnet from which iterations have
  469. /// started.
  470. ///
  471. /// @return Pointer to the next subnet or NULL pointer if the next subnet
  472. /// is the first subnet or if the current subnet doesn't belong to a
  473. /// shared network.
  474. Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet) const;
  475. /// @brief Returns next subnet within shared network that matches
  476. /// client classes.
  477. ///
  478. /// @param first_subnet Pointer to the subnet from which iterations have
  479. /// started.
  480. /// @param client_classes List of classes that the client belongs to.
  481. /// The subnets not matching the classes aren't returned by this
  482. /// method.
  483. ///
  484. /// @return Pointer to the next subnet or NULL pointer if the next subnet
  485. /// is the first subnet or if the current subnet doesn't belong to a
  486. /// shared network.
  487. Subnet6Ptr getNextSubnet(const Subnet6Ptr& first_subnet,
  488. const ClientClasses& client_classes) const;
  489. /// @brief Checks whether this subnet and parent shared network supports
  490. /// the client that belongs to specified classes.
  491. ///
  492. /// This method extends the @ref Network::clientSupported method with
  493. /// additional checks whether shared network owning this class supports
  494. /// the client belonging to specified classes. If the class doesn't
  495. /// belong to a shared network this method only checks if the subnet
  496. /// supports specified classes.
  497. ///
  498. /// @param client_classes List of classes the client belongs to.
  499. /// @return true if client can be supported, false otherwise.
  500. virtual bool
  501. clientSupported(const isc::dhcp::ClientClasses& client_classes) const;
  502. /// @brief Unparse a subnet object.
  503. ///
  504. /// @return A pointer to unparsed subnet configuration.
  505. virtual data::ElementPtr toElement() const;
  506. private:
  507. /// @brief Returns default address for pool selection
  508. /// @return ANY IPv6 address
  509. virtual isc::asiolink::IOAddress default_pool() const {
  510. return (isc::asiolink::IOAddress("::"));
  511. }
  512. /// @brief Checks if used pool type is valid
  513. ///
  514. /// allowed types for Subnet6 are Pool::TYPE_{IA,TA,PD}.
  515. ///
  516. /// @param type type to be checked
  517. /// @throw BadValue if invalid value is used
  518. virtual void checkType(Lease::Type type) const;
  519. };
  520. /// @name Definition of the multi index container holding subnet information
  521. ///
  522. //@{
  523. /// @brief Tag for the random access index.
  524. struct SubnetRandomAccessIndexTag { };
  525. /// @brief Tag for the index for searching by subnet identifier.
  526. struct SubnetSubnetIdIndexTag { };
  527. /// @brief Tag for the index for searching by subnet prefix.
  528. struct SubnetPrefixIndexTag { };
  529. /// @brief Multi index container holding subnets.
  530. ///
  531. /// This multi index container can hold pointers to @ref Subnet4 or
  532. /// @ref Subnet6 objects representing subnets. It provides indexes for
  533. /// subnet lookups using subnet properties such as: subnet identifier
  534. /// or subnet prefix. It also provides a random access index which
  535. /// allows for using the container like a vector.
  536. ///
  537. /// The random access index is used by the DHCP servers which perform
  538. /// a full scan on subnets to find the one that matches some specific
  539. /// criteria for subnet selection.
  540. ///
  541. /// The remaining indexes are used for searching for a specific subnet
  542. /// as a result of receiving a command over the control API, e.g.
  543. /// when 'subnet-get' command is received.
  544. ///
  545. /// @todo We should consider optimizing subnet selection by leveraging
  546. /// the indexing capabilities of this container, e.g. searching for
  547. /// a subnet by interface name, relay address etc.
  548. ///
  549. /// @tparam SubnetType Type of the subnet: @ref Subnet4 or @ref Subnet6.
  550. template<typename SubnetType>
  551. using SubnetCollection = boost::multi_index_container<
  552. // Multi index container holds pointers to the subnets.
  553. boost::shared_ptr<SubnetType>,
  554. // The following holds all indexes.
  555. boost::multi_index::indexed_by<
  556. // First is the random access index allowing for accessing
  557. // objects just like we'd do with a vector.
  558. boost::multi_index::random_access<
  559. boost::multi_index::tag<SubnetRandomAccessIndexTag>
  560. >,
  561. // Second index allows for searching using subnet identifier.
  562. boost::multi_index::ordered_unique<
  563. boost::multi_index::tag<SubnetSubnetIdIndexTag>,
  564. boost::multi_index::const_mem_fun<Subnet, SubnetID, &Subnet::getID>
  565. >,
  566. // Third index allows for searching using an output from toText function.
  567. boost::multi_index::ordered_unique<
  568. boost::multi_index::tag<SubnetPrefixIndexTag>,
  569. boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
  570. >
  571. >
  572. >;
  573. /// @brief A collection of @c Subnet4 objects
  574. ///
  575. /// This container provides a set of indexes which can be used to retrieve
  576. /// subnets by various properties.
  577. typedef SubnetCollection<Subnet4> Subnet4Collection;
  578. /// @brief A collection of @c Subnet6 objects
  579. ///
  580. /// This container provides a set of indexes which can be used to retrieve
  581. /// subnets by various properties.
  582. typedef SubnetCollection<Subnet6> Subnet6Collection;
  583. //@}
  584. } // end of isc::dhcp namespace
  585. } // end of isc namespace
  586. #endif // SUBNET_H