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