simple_parser4.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (C) 2016-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. #include <dhcpsrv/parsers/simple_parser4.h>
  7. #include <cc/data.h>
  8. #include <boost/foreach.hpp>
  9. #include <iostream>
  10. using namespace isc::data;
  11. namespace isc {
  12. namespace dhcp {
  13. /// @brief This sets of arrays define the default values and
  14. /// values inherited (derived) between various scopes.
  15. ///
  16. /// Each of those is documented in @file simple_parser4.cc. This
  17. /// is different than most other comments in Kea code. The reason
  18. /// for placing those in .cc rather than .h file is that it
  19. /// is expected to be one centralized place to look at for
  20. /// the default values. This is expected to be looked at also by
  21. /// people who are not skilled in C or C++, so they may be
  22. /// confused with the differences between declaration and definition.
  23. /// As such, there's one file to look at that hopefully is readable
  24. /// without any C or C++ skills.
  25. ///
  26. /// @{
  27. /// @brief This table defines default values for option definitions in DHCPv4.
  28. ///
  29. /// Dhcp4 may contain an array called option-def that enumerates new option
  30. /// definitions. This array lists default values for those option definitions.
  31. const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
  32. { "record-types", Element::string, ""},
  33. { "space", Element::string, "dhcp4"},
  34. { "array", Element::boolean, "false"},
  35. { "encapsulate", Element::string, "" }
  36. };
  37. /// @brief This table defines default values for options in DHCPv4.
  38. ///
  39. /// Dhcp4 usually contains option values (option-data) defined in global,
  40. /// subnet, class or host reservations scopes. This array lists default values
  41. /// for those option-data declarations.
  42. const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = {
  43. { "space", Element::string, "dhcp4"},
  44. { "csv-format", Element::boolean, "true"},
  45. { "always-send", Element::boolean, "false"}
  46. };
  47. /// @brief This table defines default global values for DHCPv4
  48. ///
  49. /// Some of the global parameters defined in the global scope (i.e. directly
  50. /// in Dhcp4) are optional. If not defined, the following values will be
  51. /// used.
  52. const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
  53. { "renew-timer", Element::integer, "900" },
  54. { "rebind-timer", Element::integer, "1800" },
  55. { "valid-lifetime", Element::integer, "7200" },
  56. { "decline-probation-period", Element::integer, "86400" }, // 24h
  57. { "dhcp4o6-port", Element::integer, "0" },
  58. { "echo-client-id", Element::boolean, "true" },
  59. { "match-client-id", Element::boolean, "true" },
  60. { "next-server", Element::string, "0.0.0.0" }
  61. };
  62. /// @brief This table defines default values for each IPv4 subnet.
  63. ///
  64. /// Note: When updating this array, please also update SHARED_SUBNET4_DEFAULTS
  65. /// below. In most cases, those two should be kept in sync, except cases
  66. /// where a parameter can be derived from shared-networks, but is not
  67. /// defined on global level. Currently there are two such parameters:
  68. /// interface and reservation-mode
  69. const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
  70. { "id", Element::integer, "0" }, // 0 means autogenerate
  71. { "interface", Element::string, "" },
  72. { "client-class", Element::string, "" },
  73. { "reservation-mode", Element::string, "all" },
  74. { "4o6-interface", Element::string, "" },
  75. { "4o6-interface-id", Element::string, "" },
  76. { "4o6-subnet", Element::string, "" },
  77. };
  78. /// @brief This table defines default values for each IPv4 subnet that is
  79. /// part of a shared network
  80. ///
  81. /// This is mostly the same as @ref SUBNET4_DEFAULTS, except two parameters
  82. /// that can be derived from shared-network, but cannot from global scope.
  83. /// Those are: interface and reservation-mode.
  84. const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
  85. { "id", Element::integer, "0" }, // 0 means autogenerate
  86. { "client-class", Element::string, "" },
  87. { "4o6-interface", Element::string, "" },
  88. { "4o6-interface-id", Element::string, "" },
  89. { "4o6-subnet", Element::string, "" },
  90. };
  91. /// @brief This table defines default values for each IPv4 shared network.
  92. const SimpleDefaults SimpleParser4::SHARED_NETWORK4_DEFAULTS = {
  93. { "interface", Element::string, "" },
  94. { "reservation-mode", Element::string, "all" }
  95. };
  96. /// @brief This table defines default values for interfaces for DHCPv4.
  97. const SimpleDefaults SimpleParser4::IFACE4_DEFAULTS = {
  98. { "re-detect", Element::boolean, "true" }
  99. };
  100. /// @brief List of parameters that can be inherited to subnet4 scope.
  101. ///
  102. /// Some parameters may be defined on both global (directly in Dhcp4) and
  103. /// subnet (Dhcp4/subnet4/...) scope. If not defined in the subnet scope,
  104. /// the value is being inherited (derived) from the global scope. This
  105. /// array lists all of such parameters.
  106. ///
  107. /// This list is also used for inheriting from global to shared networks
  108. /// and from shared networks to subnets within it.
  109. const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
  110. "client-class",
  111. "interface",
  112. "match-client-id",
  113. "next-server",
  114. "rebind-timer",
  115. "relay",
  116. "renew-timer",
  117. "reservation-mode",
  118. "valid-lifetime"
  119. };
  120. /// @}
  121. /// ---------------------------------------------------------------------------
  122. /// --- end of default values -------------------------------------------------
  123. /// ---------------------------------------------------------------------------
  124. size_t SimpleParser4::setAllDefaults(isc::data::ElementPtr global) {
  125. size_t cnt = 0;
  126. // Set global defaults first.
  127. cnt = setDefaults(global, GLOBAL4_DEFAULTS);
  128. // Now set option definition defaults for each specified option definition
  129. ConstElementPtr option_defs = global->get("option-def");
  130. if (option_defs) {
  131. BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
  132. cnt += SimpleParser::setDefaults(option_def, OPTION4_DEF_DEFAULTS);
  133. }
  134. }
  135. // Set the defaults for option data
  136. ConstElementPtr options = global->get("option-data");
  137. if (options) {
  138. cnt += setListDefaults(options, OPTION4_DEFAULTS);
  139. }
  140. // Now set the defaults for defined subnets
  141. ConstElementPtr subnets = global->get("subnet4");
  142. if (subnets) {
  143. cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
  144. }
  145. // Set the defaults for interfaces config
  146. ConstElementPtr ifaces_cfg = global->get("interfaces-config");
  147. if (ifaces_cfg) {
  148. ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(ifaces_cfg);
  149. cnt += setDefaults(mutable_cfg, IFACE4_DEFAULTS);
  150. }
  151. // Set defaults for shared networks
  152. ConstElementPtr shared = global->get("shared-networks");
  153. if (shared) {
  154. BOOST_FOREACH(ElementPtr net, shared->listValue()) {
  155. cnt += setDefaults(net, SHARED_NETWORK4_DEFAULTS);
  156. ConstElementPtr subs = net->get("subnet4");
  157. if (subs) {
  158. cnt += setListDefaults(subs, SHARED_SUBNET4_DEFAULTS);
  159. }
  160. }
  161. }
  162. return (cnt);
  163. }
  164. size_t SimpleParser4::deriveParameters(isc::data::ElementPtr global) {
  165. size_t cnt = 0;
  166. // Now derive global parameters into subnets.
  167. ConstElementPtr subnets = global->get("subnet4");
  168. if (subnets) {
  169. BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
  170. cnt += SimpleParser::deriveParams(global, single_subnet,
  171. INHERIT_TO_SUBNET4);
  172. }
  173. }
  174. // Deriving parameters for shared networks is a bit more involved.
  175. // First, the shared-network level derives from global, and then
  176. // subnets within derive from it.
  177. ConstElementPtr shared = global->get("shared-networks");
  178. if (shared) {
  179. BOOST_FOREACH(ElementPtr net, shared->listValue()) {
  180. // First try to inherit the parameters from shared network,
  181. // if defined there.
  182. // Then try to inherit them from global.
  183. cnt += SimpleParser::deriveParams(global, net,
  184. INHERIT_TO_SUBNET4);
  185. // Now we need to go thrugh all the subnets in this net.
  186. subnets = net->get("subnet4");
  187. if (subnets) {
  188. BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
  189. cnt += SimpleParser::deriveParams(net, single_subnet,
  190. INHERIT_TO_SUBNET4);
  191. }
  192. }
  193. }
  194. }
  195. return (cnt);
  196. }
  197. };
  198. };