subnet.h 24 KB

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