Kea  2.1.7-git
simple_parser4.cc
Go to the documentation of this file.
1 // Copyright (C) 2016-2022 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 
7 #include <config.h>
8 
10 #include <cc/data.h>
11 #include <boost/foreach.hpp>
12 #include <iostream>
13 
14 using namespace isc::data;
15 
16 namespace isc {
17 namespace dhcp {
32 
38 const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
39  { "valid-lifetime", Element::integer },
40  { "min-valid-lifetime", Element::integer },
41  { "max-valid-lifetime", Element::integer },
42  { "renew-timer", Element::integer },
43  { "rebind-timer", Element::integer },
44  { "decline-probation-period", Element::integer },
45  { "subnet4", Element::list },
46  { "shared-networks", Element::list },
47  { "interfaces-config", Element::map },
48  { "lease-database", Element::map },
49  { "hosts-database", Element::map },
50  { "hosts-databases", Element::list },
51  { "host-reservation-identifiers", Element::list },
52  { "client-classes", Element::list },
53  { "option-def", Element::list },
54  { "option-data", Element::list },
55  { "hooks-libraries", Element::list },
56  { "expired-leases-processing", Element::map },
57  { "dhcp4o6-port", Element::integer },
58  { "control-socket", Element::map },
59  { "dhcp-queue-control", Element::map },
60  { "dhcp-ddns", Element::map },
61  { "echo-client-id", Element::boolean },
62  { "match-client-id", Element::boolean },
63  { "authoritative", Element::boolean },
64  { "next-server", Element::string },
65  { "server-hostname", Element::string },
66  { "boot-file-name", Element::string },
67  { "user-context", Element::map },
68  { "comment", Element::string },
69  { "sanity-checks", Element::map },
70  { "reservations", Element::list },
71  { "config-control", Element::map },
72  { "server-tag", Element::string },
73  { "reservation-mode", Element::string },
74  { "reservations-global", Element::boolean },
75  { "reservations-in-subnet", Element::boolean },
76  { "reservations-out-of-pool", Element::boolean },
77  { "calculate-tee-times", Element::boolean },
78  { "t1-percent", Element::real },
79  { "t2-percent", Element::real },
80  { "loggers", Element::list },
81  { "hostname-char-set", Element::string },
82  { "hostname-char-replacement", Element::string },
83  { "ddns-send-updates", Element::boolean },
84  { "ddns-override-no-update", Element::boolean },
85  { "ddns-override-client-update", Element::boolean },
86  { "ddns-replace-client-name", Element::string },
87  { "ddns-generated-prefix", Element::string },
88  { "ddns-qualifying-suffix", Element::string },
89  { "store-extended-info", Element::boolean },
90  { "statistic-default-sample-count", Element::integer },
91  { "statistic-default-sample-age", Element::integer },
92  { "multi-threading", Element::map },
93  { "cache-threshold", Element::real },
94  { "cache-max-age", Element::integer },
95  { "early-global-reservations-lookup", Element::boolean },
96  { "ip-reservations-unique", Element::boolean },
97  { "reservations-lookup-first", Element::boolean },
98  { "ddns-update-on-renew", Element::boolean },
99  { "ddns-use-conflict-resolution", Element::boolean },
100  { "compatibility", Element::map },
101  { "parked-packet-limit", Element::integer },
102 };
103 
109 const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
110  { "valid-lifetime", Element::integer, "7200" },
111  { "decline-probation-period", Element::integer, "86400" }, // 24h
112  { "dhcp4o6-port", Element::integer, "0" },
113  { "echo-client-id", Element::boolean, "true" },
114  { "match-client-id", Element::boolean, "true" },
115  { "authoritative", Element::boolean, "false" },
116  { "next-server", Element::string, "0.0.0.0" },
117  { "server-hostname", Element::string, "" },
118  { "boot-file-name", Element::string, "" },
119  { "server-tag", Element::string, "" },
120  { "reservations-global", Element::boolean, "false" },
121  { "reservations-in-subnet", Element::boolean, "true" },
122  { "reservations-out-of-pool", Element::boolean, "false" },
123  { "calculate-tee-times", Element::boolean, "false" },
124  { "t1-percent", Element::real, ".50" },
125  { "t2-percent", Element::real, ".875" },
126  { "ddns-send-updates", Element::boolean, "true" },
127  { "ddns-override-no-update", Element::boolean, "false" },
128  { "ddns-override-client-update", Element::boolean, "false" },
129  { "ddns-replace-client-name", Element::string, "never" },
130  { "ddns-generated-prefix", Element::string, "myhost" },
131  { "ddns-qualifying-suffix", Element::string, "" },
132  { "hostname-char-set", Element::string, "[^A-Za-z0-9.-]" },
133  { "hostname-char-replacement", Element::string, "" },
134  { "store-extended-info", Element::boolean, "false" },
135  { "statistic-default-sample-count", Element::integer, "20" },
136  { "statistic-default-sample-age", Element::integer, "0" },
137  { "early-global-reservations-lookup", Element::boolean, "false" },
138  { "ip-reservations-unique", Element::boolean, "true" },
139  { "reservations-lookup-first", Element::boolean, "false" },
140  { "ddns-update-on-renew", Element::boolean, "false" },
141  { "ddns-use-conflict-resolution", Element::boolean, "true" },
142  { "parked-packet-limit", Element::integer, "256" },
143 };
144 
150 const SimpleKeywords SimpleParser4::OPTION4_DEF_PARAMETERS = {
151  { "name", Element::string },
152  { "code", Element::integer },
153  { "type", Element::string },
154  { "record-types", Element::string },
155  { "space", Element::string },
156  { "encapsulate", Element::string },
157  { "array", Element::boolean, },
158  { "user-context", Element::map },
159  { "comment", Element::string },
160  { "metadata", Element::map }
161 };
162 
167 const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
168  { "record-types", Element::string, ""},
169  { "space", Element::string, "dhcp4"}, // DHCP4_OPTION_SPACE
170  { "array", Element::boolean, "false"},
171  { "encapsulate", Element::string, "" }
172 };
173 
179 const SimpleKeywords SimpleParser4::OPTION4_PARAMETERS = {
180  { "name", Element::string },
181  { "data", Element::string },
182  { "code", Element::integer },
183  { "space", Element::string },
184  { "csv-format", Element::boolean },
185  { "always-send", Element::boolean },
186  { "user-context", Element::map },
187  { "comment", Element::string },
188  { "metadata", Element::map }
189 };
190 
196 const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = {
197  { "space", Element::string, "dhcp4"}, // DHCP4_OPTION_SPACE
198  { "csv-format", Element::boolean, "true"},
199  { "always-send", Element::boolean, "false"}
200 };
201 
207 const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
208  { "valid-lifetime", Element::integer },
209  { "min-valid-lifetime", Element::integer },
210  { "max-valid-lifetime", Element::integer },
211  { "renew-timer", Element::integer },
212  { "rebind-timer", Element::integer },
213  { "option-data", Element::list },
214  { "pools", Element::list },
215  { "subnet", Element::string },
216  { "interface", Element::string },
217  { "id", Element::integer },
218  { "client-class", Element::string },
219  { "require-client-classes", Element::list },
220  { "reservations", Element::list },
221  { "reservation-mode", Element::string },
222  { "reservations-global", Element::boolean },
223  { "reservations-in-subnet", Element::boolean },
224  { "reservations-out-of-pool", Element::boolean },
225  { "relay", Element::map },
226  { "match-client-id", Element::boolean },
227  { "authoritative", Element::boolean },
228  { "next-server", Element::string },
229  { "server-hostname", Element::string },
230  { "boot-file-name", Element::string },
231  { "4o6-interface", Element::string },
232  { "4o6-interface-id", Element::string },
233  { "4o6-subnet", Element::string },
234  { "user-context", Element::map },
235  { "comment", Element::string },
236  { "calculate-tee-times", Element::boolean },
237  { "t1-percent", Element::real },
238  { "t2-percent", Element::real },
239  { "ddns-send-updates", Element::boolean },
240  { "ddns-override-no-update", Element::boolean },
241  { "ddns-override-client-update", Element::boolean },
242  { "ddns-replace-client-name", Element::string },
243  { "ddns-generated-prefix", Element::string },
244  { "ddns-qualifying-suffix", Element::string },
245  { "hostname-char-set", Element::string },
246  { "hostname-char-replacement", Element::string },
247  { "store-extended-info", Element::boolean },
248  { "metadata", Element::map },
249  { "cache-threshold", Element::real },
250  { "cache-max-age", Element::integer },
251  { "ddns-update-on-renew", Element::boolean },
252  { "ddns-use-conflict-resolution", Element::boolean }
253 };
254 
262 const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
263  { "id", Element::integer, "0" }, // 0 means autogenerate
264  { "interface", Element::string, "" },
265  { "client-class", Element::string, "" },
266  { "4o6-interface", Element::string, "" },
267  { "4o6-interface-id", Element::string, "" },
268  { "4o6-subnet", Element::string, "" },
269 };
270 
277 const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
278  { "id", Element::integer, "0" }, // 0 means autogenerate
279  { "4o6-interface", Element::string, "" },
280  { "4o6-interface-id", Element::string, "" },
281  { "4o6-subnet", Element::string, "" },
282 };
283 
293 const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
294  "rebind-timer",
295  "relay",
296  "renew-timer",
297  "valid-lifetime",
298  "min-valid-lifetime",
299  "max-valid-lifetime",
300  "calculate-tee-times",
301  "t1-percent",
302  "t2-percent",
303  "store-extended-info",
304  "cache-threshold",
305  "cache-max-age"
306 };
307 
313 const SimpleKeywords SimpleParser4::POOL4_PARAMETERS = {
314  { "pool", Element::string },
315  { "option-data", Element::list },
316  { "client-class", Element::string },
317  { "require-client-classes", Element::list },
318  { "user-context", Element::map },
319  { "comment", Element::string },
320  { "metadata", Element::map }
321 };
322 
328 const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = {
329  { "name", Element::string },
330  { "subnet4", Element::list },
331  { "interface", Element::string },
332  { "renew-timer", Element::integer },
333  { "rebind-timer", Element::integer },
334  { "option-data", Element::list },
335  { "match-client-id", Element::boolean },
336  { "authoritative", Element::boolean },
337  { "next-server", Element::string },
338  { "server-hostname", Element::string },
339  { "boot-file-name", Element::string },
340  { "relay", Element::map },
341  { "reservation-mode", Element::string },
342  { "reservations-global", Element::boolean },
343  { "reservations-in-subnet", Element::boolean },
344  { "reservations-out-of-pool", Element::boolean },
345  { "client-class", Element::string },
346  { "require-client-classes", Element::list },
347  { "valid-lifetime", Element::integer },
348  { "min-valid-lifetime", Element::integer },
349  { "max-valid-lifetime", Element::integer },
350  { "user-context", Element::map },
351  { "comment", Element::string },
352  { "calculate-tee-times", Element::boolean },
353  { "t1-percent", Element::real },
354  { "t2-percent", Element::real },
355  { "ddns-send-updates", Element::boolean },
356  { "ddns-override-no-update", Element::boolean },
357  { "ddns-override-client-update", Element::boolean },
358  { "ddns-replace-client-name", Element::string },
359  { "ddns-generated-prefix", Element::string },
360  { "ddns-qualifying-suffix", Element::string },
361  { "hostname-char-set", Element::string },
362  { "hostname-char-replacement", Element::string },
363  { "store-extended-info", Element::boolean },
364  { "metadata", Element::map },
365  { "cache-threshold", Element::real },
366  { "cache-max-age", Element::integer },
367  { "ddns-update-on-renew", Element::boolean },
368  { "ddns-use-conflict-resolution", Element::boolean }
369 };
370 
372 const SimpleDefaults SimpleParser4::SHARED_NETWORK4_DEFAULTS = {
373  { "client-class", Element::string, "" },
374  { "interface", Element::string, "" }
375 };
376 
378 const SimpleDefaults SimpleParser4::IFACE4_DEFAULTS = {
379  { "re-detect", Element::boolean, "true" }
380 };
381 
383 const SimpleDefaults SimpleParser4::DHCP_QUEUE_CONTROL4_DEFAULTS = {
384  { "enable-queue", Element::boolean, "false"},
385  { "queue-type", Element::string, "kea-ring4"},
386  { "capacity", Element::integer, "64"}
387 };
388 
390 const SimpleDefaults SimpleParser4::DHCP_MULTI_THREADING4_DEFAULTS = {
391  { "enable-multi-threading", Element::boolean, "false" },
392  { "thread-pool-size", Element::integer, "0" },
393  { "packet-queue-size", Element::integer, "64" }
394 };
395 
397 const SimpleDefaults SimpleParser4::SANITY_CHECKS4_DEFAULTS = {
398  { "lease-checks", Element::string, "warn" }
399 };
400 
402 
406 
407 size_t SimpleParser4::setAllDefaults(ElementPtr global) {
408  size_t cnt = 0;
409 
410  // Set global defaults first.
411  cnt = setDefaults(global, GLOBAL4_DEFAULTS);
412 
413  // Now set option definition defaults for each specified option definition
414  ConstElementPtr option_defs = global->get("option-def");
415  if (option_defs) {
416  BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
417  cnt += SimpleParser::setDefaults(option_def, OPTION4_DEF_DEFAULTS);
418  }
419  }
420 
421  // Set the defaults for option data
422  ConstElementPtr options = global->get("option-data");
423  if (options) {
424  cnt += setListDefaults(options, OPTION4_DEFAULTS);
425  }
426 
427  // Now set the defaults for defined subnets
428  ConstElementPtr subnets = global->get("subnet4");
429  if (subnets) {
430  cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
431  }
432 
433  // Set the defaults for interfaces config
434  ConstElementPtr ifaces_cfg = global->get("interfaces-config");
435  if (ifaces_cfg) {
436  ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(ifaces_cfg);
437  cnt += setDefaults(mutable_cfg, IFACE4_DEFAULTS);
438  }
439 
440  // Set defaults for shared networks
441  ConstElementPtr shared = global->get("shared-networks");
442  if (shared) {
443  BOOST_FOREACH(ElementPtr net, shared->listValue()) {
444 
445  cnt += setDefaults(net, SHARED_NETWORK4_DEFAULTS);
446 
447  ConstElementPtr subs = net->get("subnet4");
448  if (subs) {
449  cnt += setListDefaults(subs, SHARED_SUBNET4_DEFAULTS);
450  }
451  }
452  }
453 
454  // Set the defaults for dhcp-queue-control. If the element isn't
455  // there we'll add it.
456  ConstElementPtr queue_control = global->get("dhcp-queue-control");
457  ElementPtr mutable_cfg;
458  if (queue_control) {
459  mutable_cfg = boost::const_pointer_cast<Element>(queue_control);
460  } else {
461  mutable_cfg = Element::createMap();
462  global->set("dhcp-queue-control", mutable_cfg);
463  }
464 
465  cnt += setDefaults(mutable_cfg, DHCP_QUEUE_CONTROL4_DEFAULTS);
466 
467  // Set the defaults for multi-threading. If the element isn't there
468  // we'll add it.
469  ConstElementPtr multi_threading = global->get("multi-threading");
470  if (multi_threading) {
471  mutable_cfg = boost::const_pointer_cast<Element>(multi_threading);
472  } else {
473  mutable_cfg = Element::createMap();
474  global->set("multi-threading", mutable_cfg);
475  }
476 
477  cnt += setDefaults(mutable_cfg, DHCP_MULTI_THREADING4_DEFAULTS);
478 
479  // Set the defaults for sanity-checks. If the element isn't
480  // there we'll add it.
481  ConstElementPtr sanity_checks = global->get("sanity-checks");
482  if (sanity_checks) {
483  mutable_cfg = boost::const_pointer_cast<Element>(sanity_checks);
484  } else {
485  mutable_cfg = Element::createMap();
486  global->set("sanity-checks", mutable_cfg);
487  }
488 
489  cnt += setDefaults(mutable_cfg, SANITY_CHECKS4_DEFAULTS);
490 
491  return (cnt);
492 }
493 
494 size_t SimpleParser4::deriveParameters(ElementPtr global) {
495  size_t cnt = 0;
496 
497  // Now derive global parameters into subnets.
498  ConstElementPtr subnets = global->get("subnet4");
499  if (subnets) {
500  BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
501  cnt += SimpleParser::deriveParams(global, single_subnet,
502  INHERIT_TO_SUBNET4);
503  }
504  }
505 
506  // Deriving parameters for shared networks is a bit more involved.
507  // First, the shared-network level derives from global, and then
508  // subnets within derive from it.
509  ConstElementPtr shared = global->get("shared-networks");
510  if (shared) {
511  BOOST_FOREACH(ElementPtr net, shared->listValue()) {
512  // First try to inherit the parameters from shared network,
513  // if defined there.
514  // Then try to inherit them from global.
515  cnt += SimpleParser::deriveParams(global, net,
516  INHERIT_TO_SUBNET4);
517 
518  // Now we need to go thrugh all the subnets in this net.
519  subnets = net->get("subnet4");
520  if (subnets) {
521  BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
522  cnt += SimpleParser::deriveParams(net, single_subnet,
523  INHERIT_TO_SUBNET4);
524  }
525  }
526  }
527  }
528 
529  return (cnt);
530 }
531 
532 } // namespace dhcp
533 } // namespace isc
std::map< std::string, isc::data::Element::types > SimpleKeywords
This specifies all accepted keywords with their types.
std::vector< SimpleDefault > SimpleDefaults
This specifies all default values in a given scope (e.g. a subnet).
boost::shared_ptr< Element > ElementPtr
Definition: data.h:24
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:286
static size_t deriveParams(isc::data::ConstElementPtr parent, isc::data::ElementPtr child, const ParamsList &params)
Derives (inherits) parameters from parent scope to a child.
static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults &default_values)
Sets the default values.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
Defines the logger used by the top-level component of kea-lfc.
std::vector< std::string > ParamsList
This defines a list of all parameters that are derived (or inherited) between contexts.
The Element class represents a piece of data, used by the command channel and configuration parts...
Definition: data.h:70