Kea  1.9.9-git
simple_parser4.cc
Go to the documentation of this file.
1 // Copyright (C) 2016-2021 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  { "ip-reservations-unique", Element::boolean },
96  { "ddns-update-on-renew", Element::boolean },
97  { "ddns-use-conflict-resolution", Element::boolean },
98  { "compatibility", Element::map },
99 };
100 
106 const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
107  { "valid-lifetime", Element::integer, "7200" },
108  { "decline-probation-period", Element::integer, "86400" }, // 24h
109  { "dhcp4o6-port", Element::integer, "0" },
110  { "echo-client-id", Element::boolean, "true" },
111  { "match-client-id", Element::boolean, "true" },
112  { "authoritative", Element::boolean, "false" },
113  { "next-server", Element::string, "0.0.0.0" },
114  { "server-hostname", Element::string, "" },
115  { "boot-file-name", Element::string, "" },
116  { "server-tag", Element::string, "" },
117  { "reservations-global", Element::boolean, "false" },
118  { "reservations-in-subnet", Element::boolean, "true" },
119  { "reservations-out-of-pool", Element::boolean, "false" },
120  { "calculate-tee-times", Element::boolean, "false" },
121  { "t1-percent", Element::real, ".50" },
122  { "t2-percent", Element::real, ".875" },
123  { "ddns-send-updates", Element::boolean, "true" },
124  { "ddns-override-no-update", Element::boolean, "false" },
125  { "ddns-override-client-update", Element::boolean, "false" },
126  { "ddns-replace-client-name", Element::string, "never" },
127  { "ddns-generated-prefix", Element::string, "myhost" },
128  { "ddns-qualifying-suffix", Element::string, "" },
129  { "hostname-char-set", Element::string, "[^A-Za-z0-9.-]" },
130  { "hostname-char-replacement", Element::string, "" },
131  { "store-extended-info", Element::boolean, "false" },
132  { "statistic-default-sample-count", Element::integer, "20" },
133  { "statistic-default-sample-age", Element::integer, "0" },
134  { "ip-reservations-unique", Element::boolean, "true" },
135  { "ddns-update-on-renew", Element::boolean, "false" },
136  { "ddns-use-conflict-resolution", Element::boolean, "true" }
137 };
138 
144 const SimpleKeywords SimpleParser4::OPTION4_DEF_PARAMETERS = {
145  { "name", Element::string },
146  { "code", Element::integer },
147  { "type", Element::string },
148  { "record-types", Element::string },
149  { "space", Element::string },
150  { "encapsulate", Element::string },
151  { "array", Element::boolean, },
152  { "user-context", Element::map },
153  { "comment", Element::string },
154  { "metadata", Element::map }
155 };
156 
161 const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
162  { "record-types", Element::string, ""},
163  { "space", Element::string, "dhcp4"}, // DHCP4_OPTION_SPACE
164  { "array", Element::boolean, "false"},
165  { "encapsulate", Element::string, "" }
166 };
167 
173 const SimpleKeywords SimpleParser4::OPTION4_PARAMETERS = {
174  { "name", Element::string },
175  { "data", Element::string },
176  { "code", Element::integer },
177  { "space", Element::string },
178  { "csv-format", Element::boolean },
179  { "always-send", Element::boolean },
180  { "user-context", Element::map },
181  { "comment", Element::string },
182  { "metadata", Element::map }
183 };
184 
190 const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = {
191  { "space", Element::string, "dhcp4"}, // DHCP4_OPTION_SPACE
192  { "csv-format", Element::boolean, "true"},
193  { "always-send", Element::boolean, "false"}
194 };
195 
201 const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
202  { "valid-lifetime", Element::integer },
203  { "min-valid-lifetime", Element::integer },
204  { "max-valid-lifetime", Element::integer },
205  { "renew-timer", Element::integer },
206  { "rebind-timer", Element::integer },
207  { "option-data", Element::list },
208  { "pools", Element::list },
209  { "subnet", Element::string },
210  { "interface", Element::string },
211  { "id", Element::integer },
212  { "client-class", Element::string },
213  { "require-client-classes", Element::list },
214  { "reservations", Element::list },
215  { "reservation-mode", Element::string },
216  { "reservations-global", Element::boolean },
217  { "reservations-in-subnet", Element::boolean },
218  { "reservations-out-of-pool", Element::boolean },
219  { "relay", Element::map },
220  { "match-client-id", Element::boolean },
221  { "authoritative", Element::boolean },
222  { "next-server", Element::string },
223  { "server-hostname", Element::string },
224  { "boot-file-name", Element::string },
225  { "4o6-interface", Element::string },
226  { "4o6-interface-id", Element::string },
227  { "4o6-subnet", Element::string },
228  { "user-context", Element::map },
229  { "comment", Element::string },
230  { "calculate-tee-times", Element::boolean },
231  { "t1-percent", Element::real },
232  { "t2-percent", Element::real },
233  { "ddns-send-updates", Element::boolean },
234  { "ddns-override-no-update", Element::boolean },
235  { "ddns-override-client-update", Element::boolean },
236  { "ddns-replace-client-name", Element::string },
237  { "ddns-generated-prefix", Element::string },
238  { "ddns-qualifying-suffix", Element::string },
239  { "hostname-char-set", Element::string },
240  { "hostname-char-replacement", Element::string },
241  { "store-extended-info", Element::boolean },
242  { "metadata", Element::map },
243  { "cache-threshold", Element::real },
244  { "cache-max-age", Element::integer },
245  { "ddns-update-on-renew", Element::boolean },
246  { "ddns-use-conflict-resolution", Element::boolean }
247 };
248 
256 const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
257  { "id", Element::integer, "0" }, // 0 means autogenerate
258  { "interface", Element::string, "" },
259  { "client-class", Element::string, "" },
260  { "4o6-interface", Element::string, "" },
261  { "4o6-interface-id", Element::string, "" },
262  { "4o6-subnet", Element::string, "" },
263 };
264 
271 const SimpleDefaults SimpleParser4::SHARED_SUBNET4_DEFAULTS = {
272  { "id", Element::integer, "0" }, // 0 means autogenerate
273  { "4o6-interface", Element::string, "" },
274  { "4o6-interface-id", Element::string, "" },
275  { "4o6-subnet", Element::string, "" },
276 };
277 
287 const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
288  "rebind-timer",
289  "relay",
290  "renew-timer",
291  "valid-lifetime",
292  "min-valid-lifetime",
293  "max-valid-lifetime",
294  "calculate-tee-times",
295  "t1-percent",
296  "t2-percent",
297  "store-extended-info",
298  "cache-threshold",
299  "cache-max-age"
300 };
301 
307 const SimpleKeywords SimpleParser4::POOL4_PARAMETERS = {
308  { "pool", Element::string },
309  { "option-data", Element::list },
310  { "client-class", Element::string },
311  { "require-client-classes", Element::list },
312  { "user-context", Element::map },
313  { "comment", Element::string },
314  { "metadata", Element::map }
315 };
316 
322 const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = {
323  { "name", Element::string },
324  { "subnet4", Element::list },
325  { "interface", Element::string },
326  { "renew-timer", Element::integer },
327  { "rebind-timer", Element::integer },
328  { "option-data", Element::list },
329  { "match-client-id", Element::boolean },
330  { "authoritative", Element::boolean },
331  { "next-server", Element::string },
332  { "server-hostname", Element::string },
333  { "boot-file-name", Element::string },
334  { "relay", Element::map },
335  { "reservation-mode", Element::string },
336  { "reservations-global", Element::boolean },
337  { "reservations-in-subnet", Element::boolean },
338  { "reservations-out-of-pool", Element::boolean },
339  { "client-class", Element::string },
340  { "require-client-classes", Element::list },
341  { "valid-lifetime", Element::integer },
342  { "min-valid-lifetime", Element::integer },
343  { "max-valid-lifetime", Element::integer },
344  { "user-context", Element::map },
345  { "comment", Element::string },
346  { "calculate-tee-times", Element::boolean },
347  { "t1-percent", Element::real },
348  { "t2-percent", Element::real },
349  { "ddns-send-updates", Element::boolean },
350  { "ddns-override-no-update", Element::boolean },
351  { "ddns-override-client-update", Element::boolean },
352  { "ddns-replace-client-name", Element::string },
353  { "ddns-generated-prefix", Element::string },
354  { "ddns-qualifying-suffix", Element::string },
355  { "hostname-char-set", Element::string },
356  { "hostname-char-replacement", Element::string },
357  { "store-extended-info", Element::boolean },
358  { "metadata", Element::map },
359  { "cache-threshold", Element::real },
360  { "cache-max-age", Element::integer },
361  { "ddns-update-on-renew", Element::boolean },
362  { "ddns-use-conflict-resolution", Element::boolean }
363 };
364 
366 const SimpleDefaults SimpleParser4::SHARED_NETWORK4_DEFAULTS = {
367  { "client-class", Element::string, "" },
368  { "interface", Element::string, "" }
369 };
370 
372 const SimpleDefaults SimpleParser4::IFACE4_DEFAULTS = {
373  { "re-detect", Element::boolean, "true" }
374 };
375 
377 const SimpleDefaults SimpleParser4::DHCP_QUEUE_CONTROL4_DEFAULTS = {
378  { "enable-queue", Element::boolean, "false"},
379  { "queue-type", Element::string, "kea-ring4"},
380  { "capacity", Element::integer, "64"}
381 };
382 
384 const SimpleDefaults SimpleParser4::DHCP_MULTI_THREADING4_DEFAULTS = {
385  { "enable-multi-threading", Element::boolean, "false" },
386  { "thread-pool-size", Element::integer, "0" },
387  { "packet-queue-size", Element::integer, "64" }
388 };
389 
391 const SimpleDefaults SimpleParser4::SANITY_CHECKS4_DEFAULTS = {
392  { "lease-checks", Element::string, "warn" }
393 };
394 
396 
400 
401 size_t SimpleParser4::setAllDefaults(ElementPtr global) {
402  size_t cnt = 0;
403 
404  // Set global defaults first.
405  cnt = setDefaults(global, GLOBAL4_DEFAULTS);
406 
407  // Now set option definition defaults for each specified option definition
408  ConstElementPtr option_defs = global->get("option-def");
409  if (option_defs) {
410  BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
411  cnt += SimpleParser::setDefaults(option_def, OPTION4_DEF_DEFAULTS);
412  }
413  }
414 
415  // Set the defaults for option data
416  ConstElementPtr options = global->get("option-data");
417  if (options) {
418  cnt += setListDefaults(options, OPTION4_DEFAULTS);
419  }
420 
421  // Now set the defaults for defined subnets
422  ConstElementPtr subnets = global->get("subnet4");
423  if (subnets) {
424  cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
425  }
426 
427  // Set the defaults for interfaces config
428  ConstElementPtr ifaces_cfg = global->get("interfaces-config");
429  if (ifaces_cfg) {
430  ElementPtr mutable_cfg = boost::const_pointer_cast<Element>(ifaces_cfg);
431  cnt += setDefaults(mutable_cfg, IFACE4_DEFAULTS);
432  }
433 
434  // Set defaults for shared networks
435  ConstElementPtr shared = global->get("shared-networks");
436  if (shared) {
437  BOOST_FOREACH(ElementPtr net, shared->listValue()) {
438 
439  cnt += setDefaults(net, SHARED_NETWORK4_DEFAULTS);
440 
441  ConstElementPtr subs = net->get("subnet4");
442  if (subs) {
443  cnt += setListDefaults(subs, SHARED_SUBNET4_DEFAULTS);
444  }
445  }
446  }
447 
448  // Set the defaults for dhcp-queue-control. If the element isn't
449  // there we'll add it.
450  ConstElementPtr queue_control = global->get("dhcp-queue-control");
451  ElementPtr mutable_cfg;
452  if (queue_control) {
453  mutable_cfg = boost::const_pointer_cast<Element>(queue_control);
454  } else {
455  mutable_cfg = Element::createMap();
456  global->set("dhcp-queue-control", mutable_cfg);
457  }
458 
459  cnt += setDefaults(mutable_cfg, DHCP_QUEUE_CONTROL4_DEFAULTS);
460 
461  // Set the defaults for multi-threading. If the element isn't there
462  // we'll add it.
463  ConstElementPtr multi_threading = global->get("multi-threading");
464  if (multi_threading) {
465  mutable_cfg = boost::const_pointer_cast<Element>(multi_threading);
466  } else {
467  mutable_cfg = Element::createMap();
468  global->set("multi-threading", mutable_cfg);
469  }
470 
471  cnt += setDefaults(mutable_cfg, DHCP_MULTI_THREADING4_DEFAULTS);
472 
473  // Set the defaults for sanity-checks. If the element isn't
474  // there we'll add it.
475  ConstElementPtr sanity_checks = global->get("sanity-checks");
476  if (sanity_checks) {
477  mutable_cfg = boost::const_pointer_cast<Element>(sanity_checks);
478  } else {
479  mutable_cfg = Element::createMap();
480  global->set("sanity-checks", mutable_cfg);
481  }
482 
483  cnt += setDefaults(mutable_cfg, SANITY_CHECKS4_DEFAULTS);
484 
485  return (cnt);
486 }
487 
488 size_t SimpleParser4::deriveParameters(ElementPtr global) {
489  size_t cnt = 0;
490 
491  // Now derive global parameters into subnets.
492  ConstElementPtr subnets = global->get("subnet4");
493  if (subnets) {
494  BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
495  cnt += SimpleParser::deriveParams(global, single_subnet,
496  INHERIT_TO_SUBNET4);
497  }
498  }
499 
500  // Deriving parameters for shared networks is a bit more involved.
501  // First, the shared-network level derives from global, and then
502  // subnets within derive from it.
503  ConstElementPtr shared = global->get("shared-networks");
504  if (shared) {
505  BOOST_FOREACH(ElementPtr net, shared->listValue()) {
506  // First try to inherit the parameters from shared network,
507  // if defined there.
508  // Then try to inherit them from global.
509  cnt += SimpleParser::deriveParams(global, net,
510  INHERIT_TO_SUBNET4);
511 
512  // Now we need to go thrugh all the subnets in this net.
513  subnets = net->get("subnet4");
514  if (subnets) {
515  BOOST_FOREACH(ElementPtr single_subnet, subnets->listValue()) {
516  cnt += SimpleParser::deriveParams(net, single_subnet,
517  INHERIT_TO_SUBNET4);
518  }
519  }
520  }
521  }
522 
523  return (cnt);
524 }
525 
526 } // namespace dhcp
527 } // 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:20
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:267
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:23
Defines the logger used by the top-level component of kea-dhcp-ddns.
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:66