Kea  2.3.9
srv_config.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2023 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>
9 #include <dhcpsrv/cfgmgr.h>
12 #include <dhcpsrv/srv_config.h>
14 #include <dhcpsrv/dhcpsrv_log.h>
15 #include <dhcpsrv/cfg_hosts_util.h>
16 #include <process/logging_info.h>
17 #include <log/logger_manager.h>
19 #include <dhcp/pkt.h> // Needed for HWADDR_SOURCE_*
20 #include <stats/stats_mgr.h>
21 #include <util/strutil.h>
22 
23 #include <boost/make_shared.hpp>
24 
25 #include <list>
26 #include <sstream>
27 
28 using namespace isc::log;
29 using namespace isc::data;
30 using namespace isc::process;
31 
32 namespace isc {
33 namespace dhcp {
34 
35 SrvConfig::SrvConfig()
36  : sequence_(0), cfg_iface_(new CfgIface()),
37  cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
38  cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
39  cfg_shared_networks4_(new CfgSharedNetworks4()),
40  cfg_shared_networks6_(new CfgSharedNetworks6()),
41  cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
42  cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
43  cfg_db_access_(new CfgDbAccess()),
44  cfg_host_operations4_(CfgHostOperations::createConfig4()),
45  cfg_host_operations6_(CfgHostOperations::createConfig6()),
46  class_dictionary_(new ClientClassDictionary()),
47  decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
48  d2_client_config_(new D2ClientConfig()),
49  configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()),
50  lenient_option_parsing_(false), ignore_dhcp_server_identifier_(false),
51  ignore_rai_link_selection_(false), exclude_first_last_24_(false),
52  reservations_lookup_first_(false) {
53 }
54 
55 SrvConfig::SrvConfig(const uint32_t sequence)
56  : sequence_(sequence), cfg_iface_(new CfgIface()),
57  cfg_option_def_(new CfgOptionDef()), cfg_option_(new CfgOption()),
58  cfg_subnets4_(new CfgSubnets4()), cfg_subnets6_(new CfgSubnets6()),
59  cfg_shared_networks4_(new CfgSharedNetworks4()),
60  cfg_shared_networks6_(new CfgSharedNetworks6()),
61  cfg_hosts_(new CfgHosts()), cfg_rsoo_(new CfgRSOO()),
62  cfg_expiration_(new CfgExpiration()), cfg_duid_(new CfgDUID()),
63  cfg_db_access_(new CfgDbAccess()),
64  cfg_host_operations4_(CfgHostOperations::createConfig4()),
65  cfg_host_operations6_(CfgHostOperations::createConfig6()),
66  class_dictionary_(new ClientClassDictionary()),
67  decline_timer_(0), echo_v4_client_id_(true), dhcp4o6_port_(0),
68  d2_client_config_(new D2ClientConfig()),
69  configured_globals_(new CfgGlobals()), cfg_consist_(new CfgConsistency()),
70  lenient_option_parsing_(false), ignore_dhcp_server_identifier_(false),
71  ignore_rai_link_selection_(false), exclude_first_last_24_(false),
72  reservations_lookup_first_(false) {
73 }
74 
75 std::string
76 SrvConfig::getConfigSummary(const uint32_t selection) const {
77  std::ostringstream s;
78  size_t subnets_num;
79  if ((selection & CFGSEL_SUBNET4) == CFGSEL_SUBNET4) {
80  subnets_num = getCfgSubnets4()->getAll()->size();
81  if (subnets_num > 0) {
82  s << "added IPv4 subnets: " << subnets_num;
83  } else {
84  s << "no IPv4 subnets!";
85  }
86  s << "; ";
87  }
88 
89  if ((selection & CFGSEL_SUBNET6) == CFGSEL_SUBNET6) {
90  subnets_num = getCfgSubnets6()->getAll()->size();
91  if (subnets_num > 0) {
92  s << "added IPv6 subnets: " << subnets_num;
93  } else {
94  s << "no IPv6 subnets!";
95  }
96  s << "; ";
97  }
98 
99  if ((selection & CFGSEL_DDNS) == CFGSEL_DDNS) {
100  bool ddns_enabled = getD2ClientConfig()->getEnableUpdates();
101  s << "DDNS: " << (ddns_enabled ? "enabled" : "disabled") << "; ";
102  }
103 
104  if (s.tellp() == static_cast<std::streampos>(0)) {
105  s << "no config details available";
106  }
107 
108  std::string summary = s.str();
109  size_t last_separator_pos = summary.find_last_of(";");
110  if (last_separator_pos == summary.length() - 2) {
111  summary.erase(last_separator_pos);
112  }
113  return (summary);
114 }
115 
116 bool
118  return (getSequence() == other.getSequence());
119 }
120 
121 void
122 SrvConfig::copy(SrvConfig& new_config) const {
123  ConfigBase::copy(new_config);
124 
125  // Replace interface configuration.
126  new_config.cfg_iface_.reset(new CfgIface(*cfg_iface_));
127  // Replace option definitions.
128  cfg_option_def_->copyTo(*new_config.cfg_option_def_);
129  cfg_option_->copyTo(*new_config.cfg_option_);
130  // Replace the client class dictionary
131  new_config.class_dictionary_.reset(new ClientClassDictionary(*class_dictionary_));
132  // Replace the D2 client configuration
133  new_config.setD2ClientConfig(getD2ClientConfig());
134  // Replace configured hooks libraries.
135  new_config.hooks_config_.clear();
136  using namespace isc::hooks;
137  for (HookLibsCollection::const_iterator it = hooks_config_.get().begin();
138  it != hooks_config_.get().end(); ++it) {
139  new_config.hooks_config_.add(it->first, it->second);
140  }
141 }
142 
143 bool
144 SrvConfig::equals(const SrvConfig& other) const {
145 
146  // Checks common elements: logging & config control
147  if (!ConfigBase::equals(other)) {
148  return (false);
149  }
150 
151  // Common information is equal between objects, so check other values.
152  if ((*cfg_iface_ != *other.cfg_iface_) ||
153  (*cfg_option_def_ != *other.cfg_option_def_) ||
154  (*cfg_option_ != *other.cfg_option_) ||
155  (*class_dictionary_ != *other.class_dictionary_) ||
156  (*d2_client_config_ != *other.d2_client_config_)) {
157  return (false);
158  }
159  // Now only configured hooks libraries can differ.
160  // If number of configured hooks libraries are different, then
161  // configurations aren't equal.
162  if (hooks_config_.get().size() != other.hooks_config_.get().size()) {
163  return (false);
164  }
165  // Pass through all configured hooks libraries.
166  return (hooks_config_.equal(other.hooks_config_));
167 }
168 
169 void
171  ConfigBase::merge(other);
172  try {
173  SrvConfig& other_srv_config = dynamic_cast<SrvConfig&>(other);
174  // We merge objects in order of dependency (real or theoretical).
175  // First we merge the common stuff.
176 
177  // Merge globals.
178  mergeGlobals(other_srv_config);
179 
180  // Merge option defs. We need to do this next so we
181  // pass these into subsequent merges so option instances
182  // at each level can be created based on the merged
183  // definitions.
184  cfg_option_def_->merge((*other_srv_config.getCfgOptionDef()));
185 
186  // Merge options.
187  cfg_option_->merge(cfg_option_def_, (*other_srv_config.getCfgOption()));
188 
189  if (!other_srv_config.getClientClassDictionary()->empty()) {
190  // Client classes are complicated because they are ordered and may
191  // depend on each other. Merging two lists of classes with preserving
192  // the order would be very involved and could result in errors. Thus,
193  // we simply replace the current list of classes with a new list.
194  setClientClassDictionary(boost::make_shared
195  <ClientClassDictionary>(*other_srv_config.getClientClassDictionary()));
196  }
197 
198  if (CfgMgr::instance().getFamily() == AF_INET) {
199  merge4(other_srv_config);
200  } else {
201  merge6(other_srv_config);
202  }
203  } catch (const std::bad_cast&) {
204  isc_throw(InvalidOperation, "internal server error: must use derivation"
205  " of the SrvConfig as an argument of the call to"
206  " SrvConfig::merge()");
207  }
208 }
209 
210 void
211 SrvConfig::merge4(SrvConfig& other) {
212  // Merge shared networks.
213  cfg_shared_networks4_->merge(cfg_option_def_, *(other.getCfgSharedNetworks4()));
214 
215  // Merge subnets.
216  cfg_subnets4_->merge(cfg_option_def_, getCfgSharedNetworks4(),
217  *(other.getCfgSubnets4()));
218 
220 }
221 
222 void
223 SrvConfig::merge6(SrvConfig& other) {
224  // Merge shared networks.
225  cfg_shared_networks6_->merge(cfg_option_def_, *(other.getCfgSharedNetworks6()));
226 
227  // Merge subnets.
228  cfg_subnets6_->merge(cfg_option_def_, getCfgSharedNetworks6(),
229  *(other.getCfgSubnets6()));
230 
232 }
233 
234 void
235 SrvConfig::mergeGlobals(SrvConfig& other) {
236  auto config_set = getConfiguredGlobals();
237  // If the deprecated reservation-mode is found in database, overwrite other
238  // reservation flags so there is no conflict when merging to new flags.
239  if (other.getConfiguredGlobal(CfgGlobals::RESERVATION_MODE)) {
243  }
244  // Iterate over the "other" globals, adding/overwriting them into
245  // this config's list of globals.
246  for (auto other_global : other.getConfiguredGlobals()->valuesMap()) {
247  addConfiguredGlobal(other_global.first, other_global.second);
248  }
249 
250  // Merge the reservation-mode to new reservation flags.
252 
253  // A handful of values are stored as members in SrvConfig. So we'll
254  // iterate over the merged globals, setting appropriate members.
255  for (auto merged_global : getConfiguredGlobals()->valuesMap()) {
256  std::string name = merged_global.first;
257  ConstElementPtr element = merged_global.second;
258  try {
259  if (name == "decline-probation-period") {
260  setDeclinePeriod(element->intValue());
261  } else if (name == "echo-client-id") {
262  // echo-client-id is v4 only, but we'll let upstream
263  // worry about that.
264  setEchoClientId(element->boolValue());
265  } else if (name == "dhcp4o6-port") {
266  setDhcp4o6Port(element->intValue());
267  } else if (name == "server-tag") {
268  setServerTag(element->stringValue());
269  } else if (name == "ip-reservations-unique") {
270  setIPReservationsUnique(element->boolValue());
271  } else if (name == "reservations-lookup-first") {
272  setReservationsLookupFirst(element->boolValue());
273  }
274  } catch(const std::exception& ex) {
275  isc_throw (BadValue, "Invalid value:" << element->str()
276  << " explicit global:" << name);
277  }
278  }
279 }
280 
281 void
283  // Removes statistics for v4 and v6 subnets
284  getCfgSubnets4()->removeStatistics();
285 
286  getCfgSubnets6()->removeStatistics();
287 }
288 
289 void
291  // Update default sample limits.
293  ConstElementPtr samples =
294  getConfiguredGlobal("statistic-default-sample-count");
295  uint32_t max_samples = 0;
296  if (samples) {
297  max_samples = samples->intValue();
298  stats_mgr.setMaxSampleCountDefault(max_samples);
299  if (max_samples != 0) {
300  stats_mgr.setMaxSampleCountAll(max_samples);
301  }
302  }
303  ConstElementPtr duration =
304  getConfiguredGlobal("statistic-default-sample-age");
305  if (duration) {
306  int64_t time_duration = duration->intValue();
307  auto max_age = std::chrono::seconds(time_duration);
308  stats_mgr.setMaxSampleAgeDefault(max_age);
309  if (max_samples == 0) {
310  stats_mgr.setMaxSampleAgeAll(max_age);
311  }
312  }
313 
314  // Updating subnet statistics involves updating lease statistics, which
315  // is done by the LeaseMgr. Since servers with subnets, must have a
316  // LeaseMgr, we do not bother updating subnet stats for servers without
317  // a lease manager, such as D2. @todo We should probably examine why
318  // "SrvConfig" is being used by D2.
320  // Updates statistics for v4 and v6 subnets
321  getCfgSubnets4()->updateStatistics();
322 
323  getCfgSubnets6()->updateStatistics();
324  }
325 }
326 
327 void
329  // Code from SimpleParser::setDefaults
330  // This is the position representing a default value. As the values
331  // we're inserting here are not present in whatever the config file
332  // came from, we need to make sure it's clearly labeled as default.
333  const Element::Position pos("<default-value>", 0, 0);
334 
335  // Let's go over all parameters we have defaults for.
336  for (auto def_value : defaults) {
337 
338  // Try if such a parameter is there. If it is, let's
339  // skip it, because user knows best *cough*.
340  ConstElementPtr x = getConfiguredGlobal(def_value.name_);
341  if (x) {
342  // There is such a value already, skip it.
343  continue;
344  }
345 
346  // There isn't such a value defined, let's create the default
347  // value...
348  switch (def_value.type_) {
349  case Element::string: {
350  x.reset(new StringElement(def_value.value_, pos));
351  break;
352  }
353  case Element::integer: {
354  try {
355  int int_value = boost::lexical_cast<int>(def_value.value_);
356  x.reset(new IntElement(int_value, pos));
357  }
358  catch (const std::exception& ex) {
360  "Internal error. Integer value expected for: "
361  << def_value.name_ << ", value is: "
362  << def_value.value_ );
363  }
364 
365  break;
366  }
367  case Element::boolean: {
368  bool bool_value;
369  if (def_value.value_ == std::string("true")) {
370  bool_value = true;
371  } else if (def_value.value_ == std::string("false")) {
372  bool_value = false;
373  } else {
375  "Internal error. Boolean value for "
376  << def_value.name_ << " specified as "
377  << def_value.value_ << ", expected true or false");
378  }
379  x.reset(new BoolElement(bool_value, pos));
380  break;
381  }
382  case Element::real: {
383  double dbl_value = boost::lexical_cast<double>(def_value.value_);
384  x.reset(new DoubleElement(dbl_value, pos));
385  break;
386  }
387  default:
388  // No default values for null, list or map
390  "Internal error. Incorrect default value type for "
391  << def_value.name_);
392  }
393  addConfiguredGlobal(def_value.name_, x);
394  }
395 }
396 
397 void
399  if (config->getType() != Element::map) {
400  isc_throw(BadValue, "extractConfiguredGlobals must be given a map element");
401  }
402 
403  const std::map<std::string, ConstElementPtr>& values = config->mapValue();
404  for (auto value = values.begin(); value != values.end(); ++value) {
405  if (value->second->getType() != Element::list &&
406  value->second->getType() != Element::map) {
407  addConfiguredGlobal(value->first, value->second);
408  }
409  }
410 }
411 
412 void
413 SrvConfig::sanityChecksLifetime(const std::string& name) const {
414  // Initialize as some compilers complain otherwise.
415  uint32_t value = 0;
416  ConstElementPtr has_value = getConfiguredGlobal(name);
417  if (has_value) {
418  value = has_value->intValue();
419  }
420 
421  uint32_t min_value = 0;
422  ConstElementPtr has_min = getConfiguredGlobal("min-" + name);
423  if (has_min) {
424  min_value = has_min->intValue();
425  }
426 
427  uint32_t max_value = 0;
428  ConstElementPtr has_max = getConfiguredGlobal("max-" + name);
429  if (has_max) {
430  max_value = has_max->intValue();
431  }
432 
433  if (!has_value && !has_min && !has_max) {
434  return;
435  }
436  if (has_value) {
437  if (!has_min && !has_max) {
438  // default only.
439  return;
440  } else if (!has_min) {
441  // default and max.
442  min_value = value;
443  } else if (!has_max) {
444  // default and min.
445  max_value = value;
446  }
447  } else if (has_min) {
448  if (!has_max) {
449  // min only.
450  return;
451  } else {
452  // min and max.
453  isc_throw(BadValue, "have min-" << name << " and max-"
454  << name << " but no " << name << " (default)");
455  }
456  } else {
457  // max only.
458  return;
459  }
460 
461  // Check that min <= max.
462  if (min_value > max_value) {
463  if (has_min && has_max) {
464  isc_throw(BadValue, "the value of min-" << name << " ("
465  << min_value << ") is not less than max-" << name << " ("
466  << max_value << ")");
467  } else if (has_min) {
468  // Only min and default so min > default.
469  isc_throw(BadValue, "the value of min-" << name << " ("
470  << min_value << ") is not less than (default) " << name
471  << " (" << value << ")");
472  } else {
473  // Only default and max so default > max.
474  isc_throw(BadValue, "the value of (default) " << name
475  << " (" << value << ") is not less than max-" << name
476  << " (" << max_value << ")");
477  }
478  }
479 
480  // Check that value is between min and max.
481  if ((value < min_value) || (value > max_value)) {
482  isc_throw(BadValue, "the value of (default) " << name << " ("
483  << value << ") is not between min-" << name << " ("
484  << min_value << ") and max-" << name << " ("
485  << max_value << ")");
486  }
487 }
488 
489 void
491  const std::string& name) const {
492  // Three cases:
493  // - the external/source config has the parameter: use it.
494  // - only the target config has the parameter: use this one.
495  // - no config has the parameter.
496  uint32_t value = 0;
497  ConstElementPtr has_value = getConfiguredGlobal(name);
498  bool new_value = true;
499  if (!has_value) {
500  has_value = target_config.getConfiguredGlobal(name);
501  new_value = false;
502  }
503  if (has_value) {
504  value = has_value->intValue();
505  }
506 
507  uint32_t min_value = 0;
508  ConstElementPtr has_min = getConfiguredGlobal("min-" + name);
509  bool new_min = true;
510  if (!has_min) {
511  has_min = target_config.getConfiguredGlobal("min-" + name);
512  new_min = false;
513  }
514  if (has_min) {
515  min_value = has_min->intValue();
516  }
517 
518  uint32_t max_value = 0;
519  ConstElementPtr has_max = getConfiguredGlobal("max-" + name);
520  bool new_max = true;
521  if (!has_max) {
522  has_max = target_config.getConfiguredGlobal("max-" + name);
523  new_max = false;
524  }
525  if (has_max) {
526  max_value = has_max->intValue();
527  }
528 
529  if (!has_value && !has_min && !has_max) {
530  return;
531  }
532  if (has_value) {
533  if (!has_min && !has_max) {
534  // default only.
535  return;
536  } else if (!has_min) {
537  // default and max.
538  min_value = value;
539  } else if (!has_max) {
540  // default and min.
541  max_value = value;
542  }
543  } else if (has_min) {
544  if (!has_max) {
545  // min only.
546  return;
547  } else {
548  // min and max.
549  isc_throw(BadValue, "have min-" << name << " and max-"
550  << name << " but no " << name << " (default)");
551  }
552  } else {
553  // max only.
554  return;
555  }
556 
557  // Check that min <= max.
558  if (min_value > max_value) {
559  if (has_min && has_max) {
560  std::string from_min = (new_min ? "new" : "previous");
561  std::string from_max = (new_max ? "new" : "previous");
562  isc_throw(BadValue, "the value of " << from_min
563  << " min-" << name << " ("
564  << min_value << ") is not less than "
565  << from_max << " max-" << name
566  << " (" << max_value << ")");
567  } else if (has_min) {
568  // Only min and default so min > default.
569  std::string from_min = (new_min ? "new" : "previous");
570  std::string from_value = (new_value ? "new" : "previous");
571  isc_throw(BadValue, "the value of " << from_min
572  << " min-" << name << " ("
573  << min_value << ") is not less than " << from_value
574  << " (default) " << name
575  << " (" << value << ")");
576  } else {
577  // Only default and max so default > max.
578  std::string from_max = (new_max ? "new" : "previous");
579  std::string from_value = (new_value ? "new" : "previous");
580  isc_throw(BadValue, "the value of " << from_value
581  << " (default) " << name
582  << " (" << value << ") is not less than " << from_max
583  << " max-" << name << " (" << max_value << ")");
584  }
585  }
586 
587  // Check that value is between min and max.
588  if ((value < min_value) || (value > max_value)) {
589  std::string from_value = (new_value ? "new" : "previous");
590  std::string from_min = (new_min ? "new" : "previous");
591  std::string from_max = (new_max ? "new" : "previous");
592  isc_throw(BadValue, "the value of " << from_value
593  <<" (default) " << name << " ("
594  << value << ") is not between " << from_min
595  << " min-" << name << " (" << min_value
596  << ") and " << from_max << " max-"
597  << name << " (" << max_value << ")");
598  }
599 }
600 
603  // Top level map
604  ElementPtr result = Element::createMap();
605 
606  // Get family for the configuration manager
607  uint16_t family = CfgMgr::instance().getFamily();
608 
609  // DhcpX global map initialized from configured globals
610  ElementPtr dhcp = configured_globals_->toElement();
611 
612  auto loggers_info = getLoggingInfo();
613  // Was in the Logging global map.
614  if (!loggers_info.empty()) {
615  // Set loggers list
616  ElementPtr loggers = Element::createList();
617  for (LoggingInfoStorage::const_iterator logger =
618  loggers_info.cbegin();
619  logger != loggers_info.cend(); ++logger) {
620  loggers->add(logger->toElement());
621  }
622  dhcp->set("loggers", loggers);
623  }
624 
625  // Set user-context
626  contextToElement(dhcp);
627 
628  // Set data directory if DHCPv6 and specified.
629  if (family == AF_INET6) {
630  const util::Optional<std::string>& datadir =
632  if (!datadir.unspecified()) {
633  dhcp->set("data-directory", Element::create(datadir));
634  }
635  }
636 
637  // Set compatibility flags.
638  ElementPtr compatibility = Element::createMap();
639  if (getLenientOptionParsing()) {
640  compatibility->set("lenient-option-parsing", Element::create(true));
641  }
643  compatibility->set("ignore-dhcp-server-identifier", Element::create(true));
644  }
646  compatibility->set("ignore-rai-link-selection", Element::create(true));
647  }
648  if (getExcludeFirstLast24()) {
649  compatibility->set("exclude-first-last-24", Element::create(true));
650  }
651  if (compatibility->size() > 0) {
652  dhcp->set("compatibility", compatibility);
653  }
654 
655  // Set decline-probation-period
656  dhcp->set("decline-probation-period",
657  Element::create(static_cast<long long>(decline_timer_)));
658  // Set echo-client-id (DHCPv4)
659  if (family == AF_INET) {
660  dhcp->set("echo-client-id", Element::create(echo_v4_client_id_));
661  }
662  // Set dhcp4o6-port
663  dhcp->set("dhcp4o6-port",
664  Element::create(static_cast<int>(dhcp4o6_port_)));
665  // Set dhcp-ddns
666  dhcp->set("dhcp-ddns", d2_client_config_->toElement());
667  // Set interfaces-config
668  dhcp->set("interfaces-config", cfg_iface_->toElement());
669  // Set option-def
670  dhcp->set("option-def", cfg_option_def_->toElement());
671  // Set option-data
672  dhcp->set("option-data", cfg_option_->toElement());
673 
674  // Set subnets and shared networks.
675 
676  // We have two problems to solve:
677  // - a subnet is unparsed once:
678  // * if it is a plain subnet in the global subnet list
679  // * if it is a member of a shared network in the shared network
680  // subnet list
681  // - unparsed subnets must be kept to add host reservations in them.
682  // Of course this can be done only when subnets are unparsed.
683 
684  // The list of all unparsed subnets
685  std::vector<ElementPtr> sn_list;
686 
687  if (family == AF_INET) {
688  // Get plain subnets
689  ElementPtr plain_subnets = Element::createList();
690  const Subnet4Collection* subnets = cfg_subnets4_->getAll();
691  for (Subnet4Collection::const_iterator subnet = subnets->cbegin();
692  subnet != subnets->cend(); ++subnet) {
693  // Skip subnets which are in a shared-network
694  SharedNetwork4Ptr network;
695  (*subnet)->getSharedNetwork(network);
696  if (network) {
697  continue;
698  }
699  ElementPtr subnet_cfg = (*subnet)->toElement();
700  sn_list.push_back(subnet_cfg);
701  plain_subnets->add(subnet_cfg);
702  }
703  dhcp->set("subnet4", plain_subnets);
704 
705  // Get shared networks
706  ElementPtr shared_networks = cfg_shared_networks4_->toElement();
707  dhcp->set("shared-networks", shared_networks);
708 
709  // Get subnets in shared network subnet lists
710  const std::vector<ElementPtr> networks = shared_networks->listValue();
711  for (auto network = networks.cbegin();
712  network != networks.cend(); ++network) {
713  const std::vector<ElementPtr> sh_list =
714  (*network)->get("subnet4")->listValue();
715  for (auto subnet = sh_list.cbegin();
716  subnet != sh_list.cend(); ++subnet) {
717  sn_list.push_back(*subnet);
718  }
719  }
720 
721  } else {
722  // Get plain subnets
723  ElementPtr plain_subnets = Element::createList();
724  const Subnet6Collection* subnets = cfg_subnets6_->getAll();
725  for (Subnet6Collection::const_iterator subnet = subnets->cbegin();
726  subnet != subnets->cend(); ++subnet) {
727  // Skip subnets which are in a shared-network
728  SharedNetwork6Ptr network;
729  (*subnet)->getSharedNetwork(network);
730  if (network) {
731  continue;
732  }
733  ElementPtr subnet_cfg = (*subnet)->toElement();
734  sn_list.push_back(subnet_cfg);
735  plain_subnets->add(subnet_cfg);
736  }
737  dhcp->set("subnet6", plain_subnets);
738 
739  // Get shared networks
740  ElementPtr shared_networks = cfg_shared_networks6_->toElement();
741  dhcp->set("shared-networks", shared_networks);
742 
743  // Get subnets in shared network subnet lists
744  const std::vector<ElementPtr> networks = shared_networks->listValue();
745  for (auto network = networks.cbegin();
746  network != networks.cend(); ++network) {
747  const std::vector<ElementPtr> sh_list =
748  (*network)->get("subnet6")->listValue();
749  for (auto subnet = sh_list.cbegin();
750  subnet != sh_list.cend(); ++subnet) {
751  sn_list.push_back(*subnet);
752  }
753  }
754  }
755 
756  // Host reservations
757  CfgHostsList resv_list;
758  resv_list.internalize(cfg_hosts_->toElement());
759 
760  // Insert global reservations
761  ConstElementPtr global_resvs = resv_list.get(SUBNET_ID_GLOBAL);
762  if (global_resvs->size() > 0) {
763  dhcp->set("reservations", global_resvs);
764  }
765 
766  // Insert subnet reservations
767  for (std::vector<ElementPtr>::const_iterator subnet = sn_list.cbegin();
768  subnet != sn_list.cend(); ++subnet) {
769  ConstElementPtr id = (*subnet)->get("id");
770  if (isNull(id)) {
771  isc_throw(ToElementError, "subnet has no id");
772  }
773  SubnetID subnet_id = id->intValue();
774  ConstElementPtr resvs = resv_list.get(subnet_id);
775  (*subnet)->set("reservations", resvs);
776  }
777 
778  // Set expired-leases-processing
779  ConstElementPtr expired = cfg_expiration_->toElement();
780  dhcp->set("expired-leases-processing", expired);
781  if (family == AF_INET6) {
782  // Set server-id (DHCPv6)
783  dhcp->set("server-id", cfg_duid_->toElement());
784 
785  // Set relay-supplied-options (DHCPv6)
786  dhcp->set("relay-supplied-options", cfg_rsoo_->toElement());
787  }
788  // Set lease-database
789  CfgLeaseDbAccess lease_db(*cfg_db_access_);
790  dhcp->set("lease-database", lease_db.toElement());
791  // Set hosts-databases
792  CfgHostDbAccess host_db(*cfg_db_access_);
793  ConstElementPtr hosts_databases = host_db.toElement();
794  if (hosts_databases->size() > 0) {
795  dhcp->set("hosts-databases", hosts_databases);
796  }
797  // Set host-reservation-identifiers
798  ConstElementPtr host_ids;
799  if (family == AF_INET) {
800  host_ids = cfg_host_operations4_->toElement();
801  } else {
802  host_ids = cfg_host_operations6_->toElement();
803  }
804  dhcp->set("host-reservation-identifiers", host_ids);
805  // Set mac-sources (DHCPv6)
806  if (family == AF_INET6) {
807  dhcp->set("mac-sources", cfg_mac_source_.toElement());
808  }
809  // Set control-socket (skip if null as empty is not legal)
810  if (!isNull(control_socket_)) {
811  dhcp->set("control-socket", UserContext::toElement(control_socket_));
812  }
813  // Set client-classes
814  ConstElementPtr client_classes = class_dictionary_->toElement();
816  if (!client_classes->empty()) {
817  dhcp->set("client-classes", client_classes);
818  }
819  // Set hooks-libraries
820  ConstElementPtr hooks_libs = hooks_config_.toElement();
821  dhcp->set("hooks-libraries", hooks_libs);
822  // Set DhcpX
823  result->set(family == AF_INET ? "Dhcp4" : "Dhcp6", dhcp);
824 
825  ConstElementPtr cfg_consist = cfg_consist_->toElement();
826  dhcp->set("sanity-checks", cfg_consist);
827 
828  // Set config-control (if it exists)
830  if (info) {
831  ConstElementPtr info_elem = info->toElement();
832  dhcp->set("config-control", info_elem);
833  }
834 
835  // Set dhcp-packet-control (if it exists)
836  data::ConstElementPtr dhcp_queue_control = getDHCPQueueControl();
837  if (dhcp_queue_control) {
838  dhcp->set("dhcp-queue-control", dhcp_queue_control);
839  }
840 
841  // Set multi-threading (if it exists)
842  data::ConstElementPtr dhcp_multi_threading = getDHCPMultiThreading();
843  if (dhcp_multi_threading) {
844  dhcp->set("multi-threading", dhcp_multi_threading);
845  }
846 
847  return (result);
848 }
849 
851 SrvConfig::getDdnsParams(const Subnet4Ptr& subnet) const {
852  return (DdnsParamsPtr(new DdnsParams(subnet,
853  getD2ClientConfig()->getEnableUpdates())));
854 }
855 
857 SrvConfig::getDdnsParams(const Subnet6Ptr& subnet) const {
858  return(DdnsParamsPtr(new DdnsParams(subnet,
859  getD2ClientConfig()->getEnableUpdates())));
860 }
861 
862 void
864  if (!srv_elem || (srv_elem->getType() != Element::map)) {
865  isc_throw(BadValue, "moveDdnsParams server config must be given a map element");
866  }
867 
868  if (!srv_elem->contains("dhcp-ddns")) {
869  /* nothing to do */
870  return;
871  }
872 
873  ElementPtr d2_elem = boost::const_pointer_cast<Element>(srv_elem->get("dhcp-ddns"));
874  if (!d2_elem || (d2_elem->getType() != Element::map)) {
875  isc_throw(BadValue, "moveDdnsParams dhcp-ddns is not a map");
876  }
877 
878  struct Param {
879  std::string from_name;
880  std::string to_name;
881  };
882 
883  std::vector<Param> params {
884  { "override-no-update", "ddns-override-no-update" },
885  { "override-client-update", "ddns-override-client-update" },
886  { "replace-client-name", "ddns-replace-client-name" },
887  { "generated-prefix", "ddns-generated-prefix" },
888  { "qualifying-suffix", "ddns-qualifying-suffix" },
889  { "hostname-char-set", "hostname-char-set" },
890  { "hostname-char-replacement", "hostname-char-replacement" }
891  };
892 
893  for (auto param : params) {
894  if (d2_elem->contains(param.from_name)) {
895  if (!srv_elem->contains(param.to_name)) {
896  // No global value for it already, so let's add it.
897  srv_elem->set(param.to_name, d2_elem->get(param.from_name));
899  .arg(param.from_name).arg(param.to_name);
900  } else {
901  // Already a global value, we'll use it and ignore this one.
903  .arg(param.from_name).arg(param.to_name);
904  }
905 
906  // Now remove it from d2_data, so D2ClientCfg won't complain.
907  d2_elem->remove(param.from_name);
908  }
909  }
910 }
911 
912 void
914  if (!getCfgDbAccess()->getIPReservationsUnique() && unique) {
916  }
917  getCfgHosts()->setIPReservationsUnique(unique);
918  getCfgDbAccess()->setIPReservationsUnique(unique);
919 }
920 
921 void
923  Option::lenient_parsing_ = lenient_option_parsing_;
924 }
925 
926 bool
928  if (!subnet_) {
929  return (false);
930  }
931 
932  return (d2_client_enabled_ && subnet_->getDdnsSendUpdates().get());
933 }
934 
935 bool
937  if (!subnet_) {
938  return (false);
939  }
940 
941  return (subnet_->getDdnsOverrideNoUpdate().get());
942 }
943 
945  if (!subnet_) {
946  return (false);
947  }
948 
949  return (subnet_->getDdnsOverrideClientUpdate().get());
950 }
951 
954  if (!subnet_) {
955  return (D2ClientConfig::RCM_NEVER);
956  }
957 
958  return (subnet_->getDdnsReplaceClientNameMode().get());
959 }
960 
961 std::string
963  if (!subnet_) {
964  return ("");
965  }
966 
967  return (subnet_->getDdnsGeneratedPrefix().get());
968 }
969 
970 std::string
972  if (!subnet_) {
973  return ("");
974  }
975 
976  return (subnet_->getDdnsQualifyingSuffix().get());
977 }
978 
979 std::string
981  if (!subnet_) {
982  return ("");
983  }
984 
985  return (subnet_->getHostnameCharSet().get());
986 }
987 
988 std::string
990  if (!subnet_) {
991  return ("");
992  }
993 
994  return (subnet_->getHostnameCharReplacement().get());
995 }
996 
1000  if (subnet_) {
1001  std::string char_set = getHostnameCharSet();
1002  if (!char_set.empty()) {
1003  try {
1004  sanitizer.reset(new util::str::StringSanitizer(char_set,
1005  getHostnameCharReplacement()));
1006  } catch (const std::exception& ex) {
1007  isc_throw(BadValue, "hostname_char_set_: '" << char_set <<
1008  "' is not a valid regular expression");
1009  }
1010  }
1011  }
1012 
1013  return (sanitizer);
1014 }
1015 
1016 bool
1018  if (!subnet_) {
1019  return (false);
1020  }
1021 
1022  return (subnet_->getDdnsUpdateOnRenew().get());
1023 }
1024 
1025 bool
1027  if (!subnet_) {
1028  return (true);
1029  }
1030 
1031  return (subnet_->getDdnsUseConflictResolution().get());
1032 }
1033 
1036  if (!subnet_) {
1037  return (util::Optional<double>());
1038  }
1039 
1040  return (subnet_->getDdnsTtlPercent());
1041 }
1042 
1043 } // namespace dhcp
1044 } // namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
Cannot unparse error.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Definition: data.cc:246
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition: data.cc:301
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition: data.cc:296
Notes: IntElement type is changed to int64_t.
Definition: data.h:615
static void moveReservationMode(isc::data::ElementPtr config)
Moves deprecated reservation-mode parameter to new reservations flags.
Parameters for various consistency checks.
Holds manual configuration of the server identifier (DUID).
Definition: cfg_duid.h:30
Holds access parameters and the configuration of the lease and hosts database connection.
Definition: cfg_db_access.h:25
Holds configuration parameters pertaining to lease expiration and lease affinity.
Class to store configured global parameters.
Definition: cfg_globals.h:25
Represents global configuration for host reservations.
Utility class to represent host reservation configurations internally as a map keyed by subnet IDs,...
isc::data::ConstElementPtr get(SubnetID id) const
Return the host reservations for a subnet ID.
void internalize(isc::data::ConstElementPtr list)
Internalize a list Element.
Represents the host reservations specified in the configuration file.
Definition: cfg_hosts.h:38
Represents selection of interfaces for DHCP server.
Definition: cfg_iface.h:131
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
util::Optional< std::string > getDataDir() const
returns path do the data directory
Definition: cfgmgr.cc:31
uint16_t getFamily() const
Returns address family.
Definition: cfgmgr.h:280
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
Represents option definitions used by the DHCP server.
Represents option data configuration for the DHCP server.
Definition: cfg_option.h:351
Represents configuration of the RSOO options for the DHCP server.
Definition: cfg_rsoo.h:25
Represents configuration of IPv4 shared networks.
Represents configuration of IPv6 shared networks.
Holds subnets configured for the DHCPv4 server.
Definition: cfg_subnets4.h:33
Holds subnets configured for the DHCPv6 server.
Definition: cfg_subnets6.h:34
Maintains a list of ClientClassDef's.
Acts as a storage vault for D2 client configuration.
Definition: d2_client_cfg.h:57
ReplaceClientNameMode
Defines the client name replacement modes.
Definition: d2_client_cfg.h:76
Convenience container for conveying DDNS behavioral parameters It is intended to be created per Packe...
Definition: srv_config.h:48
std::string getHostnameCharReplacement() const
Returns the string to replace invalid characters when scrubbing hostnames.
Definition: srv_config.cc:989
bool getUseConflictResolution() const
Returns whether or not keah-dhcp-ddns should use conflict resolution.
Definition: srv_config.cc:1026
D2ClientConfig::ReplaceClientNameMode getReplaceClientNameMode() const
Returns how Kea should handle the domain-name supplied by the client.
Definition: srv_config.cc:953
std::string getGeneratedPrefix() const
Returns the Prefix Kea should use when generating domain-names.
Definition: srv_config.cc:962
util::Optional< double > getTtlPercent() const
Returns percent of lease lifetime to use for TTL.
Definition: srv_config.cc:1035
isc::util::str::StringSanitizerPtr getHostnameSanitizer() const
Returns a regular expression string sanitizer.
Definition: srv_config.cc:998
std::string getHostnameCharSet() const
Returns the regular expression describing invalid characters for client hostnames.
Definition: srv_config.cc:980
std::string getQualifyingSuffix() const
Returns the suffix Kea should use when to qualify partial domain-names.
Definition: srv_config.cc:971
bool getUpdateOnRenew() const
Returns whether or not DNS should be updated when leases renew.
Definition: srv_config.cc:1017
bool getOverrideNoUpdate() const
Returns whether or not Kea should perform updates, even if client requested no updates.
Definition: srv_config.cc:936
bool getEnableUpdates() const
Returns whether or not DHCP DDNS updating is enabled.
Definition: srv_config.cc:927
bool getOverrideClientUpdate() const
Returns whether or not Kea should perform updates, even if client requested delegation.
Definition: srv_config.cc:944
static bool haveInstance()
Indicates if the lease manager has been instantiated.
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition: option.h:483
Specifies current DHCP configuration.
Definition: srv_config.h:186
ClientClassDictionaryPtr getClientClassDictionary()
Returns pointer to the dictionary of global client class definitions.
Definition: srv_config.h:581
static const uint32_t CFGSEL_SUBNET4
Number of IPv4 subnets.
Definition: srv_config.h:194
static void moveDdnsParams(isc::data::ElementPtr srv_elem)
Moves deprecated parameters from dhcp-ddns element to global element.
Definition: srv_config.cc:863
void setDhcp4o6Port(uint16_t port)
Sets DHCP4o6 IPC port.
Definition: srv_config.h:818
void addConfiguredGlobal(const std::string &name, isc::data::ConstElementPtr value)
Adds a parameter to the collection configured globals.
Definition: srv_config.h:912
CfgGlobalsPtr getConfiguredGlobals()
Returns non-const pointer to configured global parameters.
Definition: srv_config.h:858
void setClientClassDictionary(const ClientClassDictionaryPtr &dictionary)
Sets the client class dictionary.
Definition: srv_config.h:596
virtual void merge(ConfigBase &other)
Merges the configuration specified as a parameter into this configuration.
Definition: srv_config.cc:170
void extractConfiguredGlobals(isc::data::ConstElementPtr config)
Saves scalar elements from the global scope of a configuration.
Definition: srv_config.cc:398
isc::data::ConstElementPtr getConfiguredGlobal(std::string name) const
Returns pointer to a given configured global parameter.
Definition: srv_config.h:877
CfgSharedNetworks6Ptr getCfgSharedNetworks6() const
Returns pointer to non-const object holding configuration of shared networks in DHCPv6.
Definition: srv_config.h:352
bool getIgnoreRAILinkSelection() const
Get ignore RAI Link Selection compatibility flag.
Definition: srv_config.h:1029
void setD2ClientConfig(const D2ClientConfigPtr &d2_client_config)
Sets the D2 client configuration.
Definition: srv_config.h:848
void applyDefaultsConfiguredGlobals(const isc::data::SimpleDefaults &defaults)
Applies defaults to global parameters.
Definition: srv_config.cc:328
void setIPReservationsUnique(const bool unique)
Configures the server to allow or disallow specifying multiple hosts with the same IP address/subnet.
Definition: srv_config.cc:913
void configureLowerLevelLibraries() const
Convenience method to propagate configuration parameters through inversion of control.
Definition: srv_config.cc:922
bool sequenceEquals(const SrvConfig &other)
Compares configuration sequence with other sequence.
Definition: srv_config.cc:117
CfgSubnets4Ptr getCfgSubnets4()
Returns pointer to non-const object holding subnets configuration for DHCPv4.
Definition: srv_config.h:334
CfgSubnets6Ptr getCfgSubnets6()
Returns pointer to non-const object holding subnets configuration for DHCPv6.
Definition: srv_config.h:368
CfgOptionDefPtr getCfgOptionDef()
Return pointer to non-const object representing user-defined option definitions.
Definition: srv_config.h:295
D2ClientConfigPtr getD2ClientConfig()
Returns pointer to the D2 client configuration.
Definition: srv_config.h:834
void setReservationsLookupFirst(const bool first)
Sets whether the server does host reservations lookup before lease lookup.
Definition: srv_config.h:970
const isc::data::ConstElementPtr getDHCPMultiThreading() const
Returns DHCP multi threading information.
Definition: srv_config.h:566
void sanityChecksLifetime(const std::string &name) const
Conducts sanity checks on global lifetime parameters.
Definition: srv_config.cc:413
std::string getConfigSummary(const uint32_t selection) const
Returns summary of the configuration in the textual format.
Definition: srv_config.cc:76
const isc::data::ConstElementPtr getDHCPQueueControl() const
Returns DHCP queue control information.
Definition: srv_config.h:552
bool equals(const SrvConfig &other) const
Compares two objects for equality.
Definition: srv_config.cc:144
uint32_t getSequence() const
Returns configuration sequence number.
Definition: srv_config.h:252
static const uint32_t CFGSEL_DDNS
DDNS enabled/disabled.
Definition: srv_config.h:202
void setDeclinePeriod(const uint32_t decline_timer)
Sets decline probation-period.
Definition: srv_config.h:782
void removeStatistics()
Removes statistics.
Definition: srv_config.cc:282
CfgOptionPtr getCfgOption()
Returns pointer to the non-const object holding options.
Definition: srv_config.h:316
virtual isc::data::ElementPtr toElement() const
Unparse a configuration object.
Definition: srv_config.cc:602
bool getLenientOptionParsing() const
Get lenient option parsing compatibility flag.
Definition: srv_config.h:999
static const uint32_t CFGSEL_SUBNET6
Number of IPv6 subnets.
Definition: srv_config.h:196
bool getExcludeFirstLast24() const
Get exclude .0 and .255 addresses in subnets bigger than /24 flag.
Definition: srv_config.h:1044
void updateStatistics()
Updates statistics.
Definition: srv_config.cc:290
CfgDbAccessPtr getCfgDbAccess()
Returns pointer to the object holding configuration of the lease and host database connection paramet...
Definition: srv_config.h:454
void setEchoClientId(const bool echo)
Sets whether server should send back client-id in DHCPv4.
Definition: srv_config.h:801
void copy(SrvConfig &new_config) const
Copies the current configuration to a new configuration.
Definition: srv_config.cc:122
CfgSharedNetworks4Ptr getCfgSharedNetworks4() const
Returns pointer to non-const object holding configuration of shared networks in DHCPv4;.
Definition: srv_config.h:343
CfgHostsPtr getCfgHosts()
Returns pointer to the non-const objects representing host reservations for different IPv4 and IPv6 s...
Definition: srv_config.h:384
bool getIgnoreServerIdentifier() const
Get ignore DHCP Server Identifier compatibility flag.
Definition: srv_config.h:1014
DdnsParamsPtr getDdnsParams(const Subnet4Ptr &subnet) const
Fetches the DDNS parameters for a given DHCPv4 subnet.
Definition: srv_config.cc:851
SrvConfig()
Default constructor.
Definition: srv_config.cc:35
void clear()
Removes all configured hooks libraries.
Definition: hooks_config.h:59
bool equal(const HooksConfig &other) const
Compares two Hooks Config classes for equality.
Definition: hooks_config.cc:69
const isc::hooks::HookLibsCollection & get() const
Provides access to the configured hooks libraries.
Definition: hooks_config.h:54
isc::data::ElementPtr toElement() const
Unparse a configuration object.
void add(std::string libname, isc::data::ConstElementPtr parameters)
Adds additional hooks libraries.
Definition: hooks_config.h:46
Base class for all configurations.
Definition: config_base.h:33
process::ConstConfigControlInfoPtr getConfigControlInfo() const
Fetches a read-only copy of the configuration control information.
Definition: config_base.h:106
const process::LoggingInfoStorage & getLoggingInfo() const
Returns logging specific configuration.
Definition: config_base.h:43
void setServerTag(const util::Optional< std::string > &server_tag)
Sets the server's logical name.
Definition: config_base.h:127
Statistics Manager class.
static StatsMgr & instance()
Statistics Manager accessor method.
void unspecified(bool unspecified)
Modifies the flag that indicates whether the value is specified or unspecified.
Definition: optional.h:136
Implements a regular expression based string scrubber.
Definition: strutil.h:311
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void setMaxSampleCountDefault(uint32_t max_samples)
Set default count limit.
void setMaxSampleAgeAll(const StatsDuration &duration)
Set duration limit for all collected statistics.
void setMaxSampleCountAll(uint32_t max_samples)
Set count limit for all collected statistics.
void setMaxSampleAgeDefault(const StatsDuration &duration)
Set default duration limit.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
isc::log::Logger logger("asiodns")
Use the ASIO logger.
ElementPtr copy(ConstElementPtr from, int level)
Copy the data up to a nesting level.
Definition: data.cc:1395
void merge(ElementPtr element, ConstElementPtr other)
Merges the data from other into element.
Definition: data.cc:1174
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
bool isNull(ConstElementPtr p)
Checks whether the given ElementPtr is a NULL pointer.
Definition: data.cc:1123
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:26
@ info
Definition: db_log.h:118
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition: dhcpsrv_log.h:56
boost::shared_ptr< Subnet4 > Subnet4Ptr
A pointer to a Subnet4 object.
Definition: subnet.h:498
const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_IGNORED
const isc::log::MessageID DHCPSRV_CFGMGR_DDNS_PARAMETER_MOVED
boost::shared_ptr< Subnet6 > Subnet6Ptr
A pointer to a Subnet6 object.
Definition: subnet.h:665
boost::multi_index_container< Subnet6Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > >> Subnet6Collection
A collection of Subnet6 objects.
Definition: subnet.h:977
boost::shared_ptr< DdnsParams > DdnsParamsPtr
Defines a pointer for DdnsParams instances.
Definition: srv_config.h:181
boost::shared_ptr< SharedNetwork6 > SharedNetwork6Ptr
Pointer to SharedNetwork6 object.
boost::multi_index_container< Subnet4Ptr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetSubnetIdIndexTag >, boost::multi_index::const_mem_fun< Subnet, SubnetID, &Subnet::getID > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SubnetPrefixIndexTag >, boost::multi_index::const_mem_fun< Subnet, std::string, &Subnet::toText > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetServerIdIndexTag >, boost::multi_index::const_mem_fun< Network4, asiolink::IOAddress, &Network4::getServerId > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SubnetModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > >> Subnet4Collection
A collection of Subnet4 objects.
Definition: subnet.h:906
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
const isc::log::MessageID DHCPSRV_CFGMGR_IP_RESERVATIONS_UNIQUE_DUPLICATES_POSSIBLE
boost::shared_ptr< SharedNetwork4 > SharedNetwork4Ptr
Pointer to SharedNetwork4 object.
boost::shared_ptr< const ConfigControlInfo > ConstConfigControlInfoPtr
Defines a pointer to a const ConfigControlInfo.
boost::shared_ptr< StringSanitizer > StringSanitizerPtr
Type representing the pointer to the StringSanitizer.
Definition: strutil.h:359
Defines the logger used by the top-level component of kea-lfc.
Represents the position of the data element within a configuration string.
Definition: data.h:94
void contextToElement(data::ElementPtr map) const
Merge unparse a user_context object.
Definition: user_context.cc:15
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy an Element map.
Definition: user_context.cc:24
virtual isc::data::ElementPtr toElement() const
Unparse.
utility class for unparsing
virtual isc::data::ElementPtr toElement() const
Unparse.