subnet.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  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/classify.h>
  12. #include <dhcp/option_space_container.h>
  13. #include <dhcpsrv/cfg_option.h>
  14. #include <dhcpsrv/cfg_4o6.h>
  15. #include <dhcpsrv/lease.h>
  16. #include <dhcpsrv/pool.h>
  17. #include <dhcpsrv/subnet_id.h>
  18. #include <dhcpsrv/triplet.h>
  19. #include <boost/multi_index/mem_fun.hpp>
  20. #include <boost/multi_index/indexed_by.hpp>
  21. #include <boost/multi_index/ordered_index.hpp>
  22. #include <boost/multi_index/random_access_index.hpp>
  23. #include <boost/multi_index_container.hpp>
  24. #include <boost/shared_ptr.hpp>
  25. namespace isc {
  26. namespace dhcp {
  27. class Subnet {
  28. public:
  29. /// @brief Holds optional information about relay.
  30. ///
  31. /// In some cases it is beneficial to have additional information about
  32. /// a relay configured in the subnet. For now, the structure holds only
  33. /// IP address, but there may potentially be additional parameters added
  34. /// later, e.g. relay interface-id or relay-id.
  35. struct RelayInfo {
  36. /// @brief default and the only constructor
  37. ///
  38. /// @param addr an IP address of the relay (may be :: or 0.0.0.0)
  39. RelayInfo(const isc::asiolink::IOAddress& addr);
  40. /// @brief IP address of the relay
  41. isc::asiolink::IOAddress addr_;
  42. };
  43. /// @brief Specifies allowed host reservation mode.
  44. ///
  45. typedef enum {
  46. /// None - host reservation is disabled. No reservation types
  47. /// are allowed.
  48. HR_DISABLED,
  49. /// Only out-of-pool reservations is allowed. This mode
  50. /// allows AllocEngine to skip reservation checks when
  51. /// dealing with with addresses that are in pool.
  52. HR_OUT_OF_POOL,
  53. /// Both out-of-pool and in-pool reservations are allowed. This is the
  54. /// most flexible mode, where sysadmin have biggest liberty. However,
  55. /// there is a non-trivial performance penalty for it, as the
  56. /// AllocEngine code has to check whether there are reservations, even
  57. /// when dealing with reservations from within the dynamic pools.
  58. HR_ALL
  59. } HRMode;
  60. /// Pointer to the RelayInfo structure
  61. typedef boost::shared_ptr<Subnet::RelayInfo> RelayInfoPtr;
  62. /// @brief checks if specified address is in range
  63. bool inRange(const isc::asiolink::IOAddress& addr) const;
  64. /// @brief checks if the specified address is in pools
  65. ///
  66. /// Note the difference between inRange() and inPool() for addresses
  67. /// (i.e. *not* prefixes). For a given subnet (e.g. 2001::/64) there
  68. /// may be one or more pools defined that may or may not cover
  69. /// entire subnet, e.g. pool 2001::1-2001::10). inPool() returning
  70. /// true implies inRange(), but the reverse implication is not
  71. /// always true. For the given example, 2001::1234:abcd would return
  72. /// true for inRange(), but false for inPool() check.
  73. ///
  74. /// @param type type of pools to iterate over
  75. /// @param addr this address will be checked if it belongs to any pools in
  76. /// that subnet
  77. /// @return true if the address is in any of the pools
  78. bool inPool(Lease::Type type, const isc::asiolink::IOAddress& addr) const;
  79. /// @brief Return valid-lifetime for addresses in that prefix
  80. Triplet<uint32_t> getValid() const {
  81. return (valid_);
  82. }
  83. /// @brief Returns T1 (renew timer), expressed in seconds
  84. Triplet<uint32_t> getT1() const {
  85. return (t1_);
  86. }
  87. /// @brief Returns T2 (rebind timer), expressed in seconds
  88. Triplet<uint32_t> getT2() const {
  89. return (t2_);
  90. }
  91. /// @brief Returns pointer to the option data configuration for this subnet.
  92. CfgOptionPtr getCfgOption() {
  93. return (cfg_option_);
  94. }
  95. /// @brief Returns const pointer to the option data configuration for this
  96. /// subnet.
  97. ConstCfgOptionPtr getCfgOption() const {
  98. return (cfg_option_);
  99. }
  100. /// @brief returns the last address that was tried from this pool
  101. ///
  102. /// This method returns the last address that was attempted to be allocated
  103. /// from this subnet. This is used as helper information for the next
  104. /// iteration of the allocation algorithm.
  105. ///
  106. /// @todo: Define map<SubnetID, IOAddress> somewhere in the
  107. /// AllocEngine::IterativeAllocator and keep the data there
  108. ///
  109. /// @param type lease type to be returned
  110. /// @return address/prefix that was last tried from this pool
  111. isc::asiolink::IOAddress getLastAllocated(Lease::Type type) const;
  112. /// @brief sets the last address that was tried from this pool
  113. ///
  114. /// This method sets the last address that was attempted to be allocated
  115. /// from this subnet. This is used as helper information for the next
  116. /// iteration of the allocation algorithm.
  117. ///
  118. /// @todo: Define map<SubnetID, IOAddress> somewhere in the
  119. /// AllocEngine::IterativeAllocator and keep the data there
  120. /// @param addr address/prefix to that was tried last
  121. /// @param type lease type to be set
  122. void setLastAllocated(Lease::Type type,
  123. const isc::asiolink::IOAddress& addr);
  124. /// @brief Returns unique ID for that subnet
  125. /// @return unique ID for that subnet
  126. SubnetID getID() const { return (id_); }
  127. /// @brief Returns subnet parameters (prefix and prefix length)
  128. ///
  129. /// @return (prefix, prefix length) pair
  130. std::pair<isc::asiolink::IOAddress, uint8_t> get() const {
  131. return (std::make_pair(prefix_, prefix_len_));
  132. }
  133. /// @brief Adds a new pool for the subnet.
  134. ///
  135. /// This method checks that the address range represented by the pool
  136. /// matches the subnet prefix, if the pool type is different than
  137. /// IA_PD. The prefixes from the IA_PD pools don't need to match the
  138. /// prefix from the subnet from which they are handed out to the
  139. /// requesting router because the requesting router may use the
  140. /// delegated prefixes in different networks (using different subnets).
  141. ///
  142. /// A DHCPv4 pool being added must not overlap with any existing DHCPv4
  143. /// pool. A DHCPv6 pool being added must not overlap with any existing
  144. /// DHCPv6 pool.
  145. ///
  146. /// Pools held within a subnet are sorted by first pool address/prefix
  147. /// from the lowest to the highest.
  148. ///
  149. /// @param pool pool to be added
  150. ///
  151. /// @throw isc::BadValue if the pool type is invalid, the pool
  152. /// is not an IA_PD pool and the address range of this pool does not
  153. /// match the subnet prefix, or the pool overlaps with an existing pool
  154. /// within the subnet.
  155. void addPool(const PoolPtr& pool);
  156. /// @brief Deletes all pools of specified type
  157. ///
  158. /// This method is used for testing purposes only
  159. /// @param type type of pools to be deleted
  160. void delPools(Lease::Type type);
  161. /// @brief Returns a pool that specified address belongs to
  162. ///
  163. /// This method uses binary search to retrieve the pool. Thus, the number
  164. /// of comparisons performed by this method is logarithmic in the number
  165. /// of pools belonging to a subnet.
  166. ///
  167. /// If there is no pool that the address belongs to (hint is invalid), other
  168. /// pool of specified type will be returned.
  169. ///
  170. /// With anypool set to true, this is means give me a pool, preferably
  171. /// the one that addr belongs to. With anypool set to false, it means
  172. /// give me a pool that addr belongs to (or NULL if here is no such pool)
  173. ///
  174. /// @param type pool type that the pool is looked for
  175. /// @param addr address that the returned pool should cover (optional)
  176. /// @param anypool other pool may be returned as well, not only the one
  177. /// that addr belongs to
  178. /// @return found pool (or NULL)
  179. const PoolPtr getPool(Lease::Type type, const isc::asiolink::IOAddress& addr,
  180. bool anypool = true) const;
  181. /// @brief Returns a pool without any address specified
  182. ///
  183. /// @param type pool type that the pool is looked for
  184. /// @return returns one of the pools defined
  185. PoolPtr getAnyPool(Lease::Type type) {
  186. return (getPool(type, default_pool()));
  187. }
  188. /// @brief Returns the default address that will be used for pool selection
  189. ///
  190. /// It must be implemented in derived classes (should return :: for Subnet6
  191. /// and 0.0.0.0 for Subnet4)
  192. virtual isc::asiolink::IOAddress default_pool() const = 0;
  193. /// @brief Returns all pools (const variant)
  194. ///
  195. /// The reference is only valid as long as the object that returned it.
  196. ///
  197. /// @param type lease type to be set
  198. /// @return a collection of all pools
  199. const PoolCollection& getPools(Lease::Type type) const;
  200. /// @brief Returns the number of possible leases for specified lease type
  201. ///
  202. /// @param type type of the lease
  203. uint64_t getPoolCapacity(Lease::Type type) const;
  204. /// @brief Sets name of the network interface for directly attached networks
  205. ///
  206. /// @param iface_name name of the interface
  207. void setIface(const std::string& iface_name);
  208. /// @brief Network interface name used to reach subnet (or "" for remote
  209. /// subnets)
  210. /// @return network interface name for directly attached subnets or ""
  211. std::string getIface() const;
  212. /// @brief Returns textual representation of the subnet (e.g.
  213. /// "2001:db8::/64")
  214. ///
  215. /// @return textual representation
  216. virtual std::string toText() const;
  217. /// @brief Resets subnet-id counter to its initial value (1)
  218. ///
  219. /// This should be called during reconfiguration, before any new
  220. /// subnet objects are created. It will ensure that the subnet_id will
  221. /// be consistent between reconfigures.
  222. static void resetSubnetID() {
  223. static_id_ = 1;
  224. }
  225. /// @brief Sets information about relay
  226. ///
  227. /// In some situations where there are shared subnets (i.e. two different
  228. /// subnets are available on the same physical link), there is only one
  229. /// relay that handles incoming requests from clients. In such a case,
  230. /// the usual subnet selection criteria based on relay belonging to the
  231. /// subnet being selected are no longer sufficient and we need to explicitly
  232. /// specify a relay. One notable example of such uncommon, but valid
  233. /// scenario is a cable network, where there is only one CMTS (one relay),
  234. /// but there are 2 distinct subnets behind it: one for cable modems
  235. /// and another one for CPEs and other user equipment behind modems.
  236. /// From manageability perspective, it is essential that modems get addresses
  237. /// from different subnet, so users won't tinker with their modems.
  238. ///
  239. /// Setting this parameter is not needed in most deployments.
  240. /// This structure holds IP address only for now, but it is expected to
  241. /// be extended in the future.
  242. ///
  243. /// @param relay structure that contains relay information
  244. void setRelayInfo(const isc::dhcp::Subnet::RelayInfo& relay);
  245. /// @brief Returns const reference to relay information
  246. ///
  247. /// @note The returned reference is only valid as long as the object
  248. /// returned it is valid.
  249. ///
  250. /// @return const reference to the relay information
  251. const isc::dhcp::Subnet::RelayInfo& getRelayInfo() const {
  252. return (relay_);
  253. }
  254. /// @brief checks whether this subnet supports client that belongs to
  255. /// specified classes.
  256. ///
  257. /// This method checks whether a client that belongs to given classes can
  258. /// use this subnet. For example, if this class is reserved for client
  259. /// class "foo" and the client belongs to classes "foo", "bar" and "baz",
  260. /// it is supported. On the other hand, client belonging to classes
  261. /// "foobar" and "zyxxy" is not supported.
  262. ///
  263. /// @todo: Currently the logic is simple: client is supported if it belongs
  264. /// to any class mentioned in white_list_. We will eventually need a
  265. /// way to specify more fancy logic (e.g. to meet all classes, not just
  266. /// any)
  267. ///
  268. /// @param client_classes list of all classes the client belongs to
  269. /// @return true if client can be supported, false otherwise
  270. bool
  271. clientSupported(const isc::dhcp::ClientClasses& client_classes) const;
  272. /// @brief adds class class_name to the list of supported classes
  273. ///
  274. /// Also see explanation note in @ref white_list_.
  275. ///
  276. /// @param class_name client class to be supported by this subnet
  277. void
  278. allowClientClass(const isc::dhcp::ClientClass& class_name);
  279. /// @brief returns the client class white list
  280. ///
  281. /// @note The returned reference is only valid as long as the object
  282. /// returned it is valid.
  283. ///
  284. /// @return client classes @ref white_list_
  285. const isc::dhcp::ClientClasses& getClientClasses() const {
  286. return (white_list_);
  287. }
  288. /// @brief Specifies what type of Host Reservations are supported.
  289. ///
  290. /// Host reservations may be either in-pool (they reserve an address that
  291. /// is in the dynamic pool) or out-of-pool (they reserve an address that is
  292. /// not in the dynamic pool). HR may also be completely disabled for
  293. /// performance reasons.
  294. ///
  295. /// @return whether in-pool host reservations are allowed.
  296. HRMode
  297. getHostReservationMode() const {
  298. return (host_reservation_mode_);
  299. }
  300. /// @brief Sets host reservation mode.
  301. ///
  302. /// See @ref getHostReservationMode for details.
  303. ///
  304. /// @param mode mode to be set
  305. void setHostReservationMode(HRMode mode) {
  306. host_reservation_mode_ = mode;
  307. }
  308. protected:
  309. /// @brief Returns all pools (non-const variant)
  310. ///
  311. /// The reference is only valid as long as the object that returned it.
  312. ///
  313. /// @param type lease type to be set
  314. /// @return a collection of all pools
  315. PoolCollection& getPoolsWritable(Lease::Type type);
  316. /// @brief Protected constructor
  317. //
  318. /// By making the constructor protected, we make sure that no one will
  319. /// ever instantiate that class. Subnet4 and Subnet6 should be used instead.
  320. ///
  321. /// This constructor assigns a new subnet-id (see @ref generateNextID).
  322. /// This subnet-id has unique value that is strictly monotonously increasing
  323. /// for each subnet, until it is explicitly reset back to 1 during
  324. /// reconfiguration process.
  325. ///
  326. /// @param prefix subnet prefix
  327. /// @param len prefix length for the subnet
  328. /// @param t1 T1 (renewal-time) timer, expressed in seconds
  329. /// @param t2 T2 (rebind-time) timer, expressed in seconds
  330. /// @param valid_lifetime valid lifetime of leases in this subnet (in seconds)
  331. /// @param relay optional relay information (currently with address only)
  332. /// @param id arbitrary subnet id, value of 0 triggers autogeneration
  333. /// of subnet id
  334. Subnet(const isc::asiolink::IOAddress& prefix, uint8_t len,
  335. const Triplet<uint32_t>& t1,
  336. const Triplet<uint32_t>& t2,
  337. const Triplet<uint32_t>& valid_lifetime,
  338. const isc::dhcp::Subnet::RelayInfo& relay,
  339. const SubnetID id);
  340. /// @brief virtual destructor
  341. ///
  342. /// A virtual destructor is needed because other classes
  343. /// derive from this class.
  344. virtual ~Subnet() { };
  345. /// @brief keeps the subnet-id value
  346. ///
  347. /// It is incremented every time a new Subnet object is created. It is reset
  348. /// (@ref resetSubnetID) every time reconfiguration
  349. /// occurs.
  350. ///
  351. /// Static value initialized in subnet.cc.
  352. static SubnetID static_id_;
  353. /// @brief returns the next unique Subnet-ID
  354. ///
  355. /// This method generates and returns the next unique subnet-id.
  356. /// It is a strictly monotonously increasing value (1,2,3,...) for
  357. /// each new Subnet object created. It can be explicitly reset
  358. /// back to 1 during reconfiguration (@ref resetSubnetID).
  359. ///
  360. /// @return the next unique Subnet-ID
  361. static SubnetID generateNextID() {
  362. return (static_id_++);
  363. }
  364. /// @brief Checks if used pool type is valid
  365. ///
  366. /// Allowed type for Subnet4 is Pool::TYPE_V4.
  367. /// Allowed types for Subnet6 are Pool::TYPE_{IA,TA,PD}.
  368. /// This method is implemented in derived classes.
  369. ///
  370. /// @param type type to be checked
  371. /// @throw BadValue if invalid value is used
  372. virtual void checkType(Lease::Type type) const = 0;
  373. /// @brief returns a sum of possible leases in all pools
  374. /// @param pools list of pools
  375. /// @return sum of possible leases
  376. uint64_t sumPoolCapacity(const PoolCollection& pools) const;
  377. /// @brief Checks if the specified pool overlaps with an existing pool.
  378. ///
  379. /// @param pool_type Pool type.
  380. /// @param pool Pointer to a pool for which the method should check if
  381. /// it overlaps with any existing pool within this subnet.
  382. ///
  383. /// @return true if pool overlaps with an existing pool of a specified
  384. /// type.
  385. bool poolOverlaps(const Lease::Type& pool_type, const PoolPtr& pool) const;
  386. /// @brief Unparse a subnet object.
  387. ///
  388. /// @return A pointer to unparsed subnet configuration.
  389. virtual data::ElementPtr toElement() const = 0;
  390. /// @brief subnet-id
  391. ///
  392. /// Subnet-id is a unique value that can be used to find or identify
  393. /// a Subnet4 or Subnet6.
  394. SubnetID id_;
  395. /// @brief collection of IPv4 or non-temporary IPv6 pools in that subnet
  396. PoolCollection pools_;
  397. /// @brief collection of IPv6 temporary address pools in that subnet
  398. PoolCollection pools_ta_;
  399. /// @brief collection of IPv6 prefix pools in that subnet
  400. PoolCollection pools_pd_;
  401. /// @brief a prefix of the subnet
  402. isc::asiolink::IOAddress prefix_;
  403. /// @brief a prefix length of the subnet
  404. uint8_t prefix_len_;
  405. /// @brief a tripet (min/default/max) holding allowed renew timer values
  406. Triplet<uint32_t> t1_;
  407. /// @brief a tripet (min/default/max) holding allowed rebind timer values
  408. Triplet<uint32_t> t2_;
  409. /// @brief a tripet (min/default/max) holding allowed valid lifetime values
  410. Triplet<uint32_t> valid_;
  411. /// @brief last allocated address
  412. ///
  413. /// This is the last allocated address that was previously allocated from
  414. /// this particular subnet. Some allocation algorithms (e.g. iterative) use
  415. /// that value, others do not. It should be noted that although the value
  416. /// is usually correct, there are cases when it is invalid, e.g. after
  417. /// removing a pool, restarting or changing allocation algorithms. For
  418. /// that purpose it should be only considered a help that should not be
  419. /// fully trusted.
  420. isc::asiolink::IOAddress last_allocated_ia_;
  421. /// @brief last allocated temporary address
  422. ///
  423. /// See @ref last_allocated_ia_ for details.
  424. isc::asiolink::IOAddress last_allocated_ta_;
  425. /// @brief last allocated IPv6 prefix
  426. ///
  427. /// See @ref last_allocated_ia_ for details.
  428. isc::asiolink::IOAddress last_allocated_pd_;
  429. /// @brief Name of the network interface (if connected directly)
  430. std::string iface_;
  431. /// @brief Relay information
  432. ///
  433. /// See @ref RelayInfo for detailed description. This structure is public,
  434. /// so its fields are easily accessible. Making it protected would bring in
  435. /// the issue of returning references that may become stale after its parent
  436. /// subnet object disappears.
  437. RelayInfo relay_;
  438. /// @brief optional definition of a client class
  439. ///
  440. /// If defined, only clients belonging to that class will be allowed to use
  441. /// this particular subnet. The default value for this is an empty list,
  442. /// which means that any client is allowed, regardless of its class.
  443. ///
  444. /// @todo This is just a single list of allowed classes. We'll also need
  445. /// to add a black-list (only classes on the list are rejected, the rest
  446. /// are allowed). Implementing this will require more fancy parser logic,
  447. /// so it may be a while until we support this.
  448. ClientClasses white_list_;
  449. /// @brief Specifies host reservation mode
  450. ///
  451. /// See @ref HRMode type for details.
  452. HRMode host_reservation_mode_;
  453. private:
  454. /// @brief Pointer to the option data configuration for this subnet.
  455. CfgOptionPtr cfg_option_;
  456. };
  457. /// @brief A generic pointer to either Subnet4 or Subnet6 object
  458. typedef boost::shared_ptr<Subnet> SubnetPtr;
  459. /// @brief A configuration holder for IPv4 subnet.
  460. ///
  461. /// This class represents an IPv4 subnet.
  462. class Subnet4 : public Subnet {
  463. public:
  464. /// @brief Constructor with all parameters
  465. ///
  466. /// This constructor calls Subnet::Subnet, where subnet-id is generated.
  467. ///
  468. /// @param prefix Subnet4 prefix
  469. /// @param length prefix length
  470. /// @param t1 renewal timer (in seconds)
  471. /// @param t2 rebind timer (in seconds)
  472. /// @param valid_lifetime preferred lifetime of leases (in seconds)
  473. /// @param id arbitrary subnet id, default value of 0 triggers
  474. /// autogeneration of subnet id
  475. Subnet4(const isc::asiolink::IOAddress& prefix, uint8_t length,
  476. const Triplet<uint32_t>& t1,
  477. const Triplet<uint32_t>& t2,
  478. const Triplet<uint32_t>& valid_lifetime,
  479. const SubnetID id = 0);
  480. /// @brief Sets siaddr for the Subnet4
  481. ///
  482. /// Will be used for siaddr field (the next server) that typically is used
  483. /// as TFTP server. If not specified, the default value of 0.0.0.0 is
  484. /// used.
  485. void setSiaddr(const isc::asiolink::IOAddress& siaddr);
  486. /// @brief Returns siaddr for this subnet
  487. ///
  488. /// @return siaddr value
  489. isc::asiolink::IOAddress getSiaddr() const;
  490. /// @brief Sets the flag indicating if the client identifier should be
  491. /// used to identify the client's lease.
  492. ///
  493. /// @param match If this value is true, the client identifiers are not
  494. /// used for lease lookup.
  495. void setMatchClientId(const bool match) {
  496. match_client_id_ = match;
  497. }
  498. /// @brief Returns the flag indicating if the client identifiers should
  499. /// be used to identify the client's lease.
  500. ///
  501. /// @return true if client identifiers should be used, false otherwise.
  502. bool getMatchClientId() const {
  503. return (match_client_id_);
  504. }
  505. /// @brief Returns DHCP4o6 configuration parameters.
  506. ///
  507. /// This structure is always available. If the 4o6 is not enabled, its
  508. /// enabled_ field will be set to false.
  509. Cfg4o6& get4o6() {
  510. return (dhcp4o6_);
  511. }
  512. /// @brief Returns const DHCP4o6 configuration parameters.
  513. ///
  514. /// This structure is always available. If the 4o6 is not enabled, its
  515. /// enabled_ field will be set to false.
  516. const Cfg4o6& get4o6() const {
  517. return (dhcp4o6_);
  518. }
  519. /// @brief Unparse a subnet object.
  520. ///
  521. /// @return A pointer to unparsed subnet configuration.
  522. virtual data::ElementPtr toElement() const;
  523. private:
  524. /// @brief Returns default address for pool selection
  525. /// @return ANY IPv4 address
  526. virtual isc::asiolink::IOAddress default_pool() const {
  527. return (isc::asiolink::IOAddress("0.0.0.0"));
  528. }
  529. /// @brief Checks if used pool type is valid
  530. ///
  531. /// Allowed type for Subnet4 is Pool::TYPE_V4.
  532. ///
  533. /// @param type type to be checked
  534. /// @throw BadValue if invalid value is used
  535. virtual void checkType(Lease::Type type) const;
  536. /// @brief siaddr value for this subnet
  537. isc::asiolink::IOAddress siaddr_;
  538. /// @brief Should server use client identifiers for client lease
  539. /// lookup.
  540. bool match_client_id_;
  541. /// @brief All the information related to DHCP4o6
  542. Cfg4o6 dhcp4o6_;
  543. };
  544. /// @brief A const pointer to a @c Subnet4 object.
  545. typedef boost::shared_ptr<const Subnet4> ConstSubnet4Ptr;
  546. /// @brief A pointer to a @c Subnet4 object.
  547. typedef boost::shared_ptr<Subnet4> Subnet4Ptr;
  548. /// @brief A configuration holder for IPv6 subnet.
  549. ///
  550. /// This class represents an IPv6 subnet.
  551. class Subnet6 : public Subnet {
  552. public:
  553. /// @brief Constructor with all parameters
  554. ///
  555. /// This constructor calls Subnet::Subnet, where subnet-id is generated.
  556. ///
  557. /// @param prefix Subnet6 prefix
  558. /// @param length prefix length
  559. /// @param t1 renewal timer (in seconds)
  560. /// @param t2 rebind timer (in seconds)
  561. /// @param preferred_lifetime preferred lifetime of leases (in seconds)
  562. /// @param valid_lifetime preferred lifetime of leases (in seconds)
  563. /// @param id arbitrary subnet id, default value of 0 triggers
  564. /// autogeneration of subnet id
  565. Subnet6(const isc::asiolink::IOAddress& prefix, uint8_t length,
  566. const Triplet<uint32_t>& t1,
  567. const Triplet<uint32_t>& t2,
  568. const Triplet<uint32_t>& preferred_lifetime,
  569. const Triplet<uint32_t>& valid_lifetime,
  570. const SubnetID id = 0);
  571. /// @brief Returns preferred lifetime (in seconds)
  572. ///
  573. /// @return a triplet with preferred lifetime
  574. Triplet<uint32_t> getPreferred() const {
  575. return (preferred_);
  576. }
  577. /// @brief sets interface-id option (if defined)
  578. ///
  579. /// @param ifaceid pointer to interface-id option
  580. void setInterfaceId(const OptionPtr& ifaceid) {
  581. interface_id_ = ifaceid;
  582. }
  583. /// @brief returns interface-id value (if specified)
  584. /// @return interface-id option (if defined)
  585. OptionPtr getInterfaceId() const {
  586. return interface_id_;
  587. }
  588. /// @brief Enables or disables Rapid Commit option support for the subnet.
  589. ///
  590. /// @param rapid_commit A boolean value indicating that the Rapid Commit
  591. /// option support is enabled (if true), or disabled (if false).
  592. void setRapidCommit(const bool rapid_commit) {
  593. rapid_commit_ = rapid_commit;
  594. };
  595. /// @brief Returns boolean value indicating that the Rapid Commit option
  596. /// is supported or unsupported for the subnet.
  597. ///
  598. /// @return true if the Rapid Commit option is supported, false otherwise.
  599. bool getRapidCommit() const {
  600. return (rapid_commit_);
  601. }
  602. /// @brief Unparse a subnet object.
  603. ///
  604. /// @return A pointer to unparsed subnet configuration.
  605. virtual data::ElementPtr toElement() const;
  606. private:
  607. /// @brief Returns default address for pool selection
  608. /// @return ANY IPv6 address
  609. virtual isc::asiolink::IOAddress default_pool() const {
  610. return (isc::asiolink::IOAddress("::"));
  611. }
  612. /// @brief Checks if used pool type is valid
  613. ///
  614. /// allowed types for Subnet6 are Pool::TYPE_{IA,TA,PD}.
  615. ///
  616. /// @param type type to be checked
  617. /// @throw BadValue if invalid value is used
  618. virtual void checkType(Lease::Type type) const;
  619. /// @brief specifies optional interface-id
  620. OptionPtr interface_id_;
  621. /// @brief a triplet with preferred lifetime (in seconds)
  622. Triplet<uint32_t> preferred_;
  623. /// @brief A flag indicating if Rapid Commit option is supported
  624. /// for this subnet.
  625. ///
  626. /// It's default value is false, which indicates that the Rapid
  627. /// Commit is disabled for the subnet.
  628. bool rapid_commit_;
  629. };
  630. /// @brief A const pointer to a @c Subnet6 object.
  631. typedef boost::shared_ptr<const Subnet6> ConstSubnet6Ptr;
  632. /// @brief A pointer to a Subnet6 object
  633. typedef boost::shared_ptr<Subnet6> Subnet6Ptr;
  634. /// @name Definition of the multi index container holding subnet information
  635. ///
  636. //@{
  637. /// @brief Tag for the random access index.
  638. struct SubnetRandomAccessIndexTag { };
  639. /// @brief Tag for the index for searching by subnet identifier.
  640. struct SubnetIdIndexTag { };
  641. /// @brief Tag for the index for searching by subnet prefix.
  642. struct SubnetPrefixIndexTag { };
  643. /// @brief Multi index container holding subnets.
  644. ///
  645. /// This multi index container can hold pointers to @ref Subnet4 or
  646. /// @ref Subnet6 objects representing subnets. It provides indexes for
  647. /// subnet lookups using subnet properties such as: subnet identifier
  648. /// or subnet prefix. It also provides a random access index which
  649. /// allows for using the container like a vector.
  650. ///
  651. /// The random access index is used by the DHCP servers which perform
  652. /// a full scan on subnets to find the one that matches some specific
  653. /// criteria for subnet selection.
  654. ///
  655. /// The remaining indexes are used for searching for a specific subnet
  656. /// as a result of receiving a command over the control API, e.g.
  657. /// when 'subnet-get' command is received.
  658. ///
  659. /// @todo We should consider optimizing subnet selection by leveraging
  660. /// the indexing capabilities of this container, e.g. searching for
  661. /// a subnet by interface name, relay address etc.
  662. ///
  663. /// @tparam SubnetType Type of the subnet: @ref Subnet4 or @ref Subnet6.
  664. template<typename SubnetType>
  665. using SubnetCollection = boost::multi_index_container<
  666. // Multi index container holds pointers to the subnets.
  667. boost::shared_ptr<SubnetType>,
  668. // The following holds all indexes.
  669. boost::multi_index::indexed_by<
  670. // First is the random access index allowing for accessing
  671. // objects just like we'd do with a vector.
  672. boost::multi_index::random_access<
  673. boost::multi_index::tag<SubnetRandomAccessIndexTag>
  674. >,
  675. // Second index allows for searching using subnet identifier.
  676. boost::multi_index::ordered_unique<
  677. boost::multi_index::tag<SubnetIdIndexTag>,
  678. boost::multi_index::const_mem_fun<Subnet, SubnetID, &Subnet::getID>
  679. >,
  680. // Third index allows for searching using an output from toText function.
  681. boost::multi_index::ordered_unique<
  682. boost::multi_index::tag<SubnetTextIndexTag>,
  683. boost::multi_index::const_mem_fun<Subnet, std::string, &Subnet::toText>
  684. >
  685. >
  686. >;
  687. /// @brief A collection of @c Subnet4 objects
  688. ///
  689. /// This container provides a set of indexes which can be used to retrieve
  690. /// subnets by various properties.
  691. typedef SubnetCollection<Subnet4> Subnet4Collection;
  692. /// @brief A collection of @c Subnet6 objects
  693. ///
  694. /// This container provides a set of indexes which can be used to retrieve
  695. /// subnets by various properties.
  696. typedef SubnetCollection<Subnet6> Subnet6Collection;
  697. //@}
  698. } // end of isc::dhcp namespace
  699. } // end of isc namespace
  700. #endif // SUBNET_H