Kea 3.1.8
dhcp6/json_config_parser.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2026 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
11#include <cc/data.h>
13#include <config/command_mgr.h>
19#include <dhcp6/dhcp6_log.h>
20#include <dhcp6/dhcp6_srv.h>
22#include <dhcp/libdhcp++.h>
23#include <dhcp/iface_mgr.h>
27#include <dhcpsrv/cfg_option.h>
28#include <dhcpsrv/cfgmgr.h>
29#include <dhcpsrv/db_type.h>
45#include <dhcpsrv/host_mgr.h>
46#include <dhcpsrv/pool.h>
47#include <dhcpsrv/subnet.h>
48#include <dhcpsrv/timer_mgr.h>
49#include <hooks/hooks_manager.h>
50#include <hooks/hooks_parser.h>
51#include <log/logger_support.h>
53#include <util/encode/encode.h>
55#include <util/triplet.h>
56#include <boost/algorithm/string.hpp>
57#include <boost/lexical_cast.hpp>
58#include <boost/scoped_ptr.hpp>
59#include <boost/shared_ptr.hpp>
60
61#include <iostream>
62#include <limits>
63#include <map>
64#include <netinet/in.h>
65#include <vector>
66
67#include <stdint.h>
68
69using namespace isc::asiolink;
70using namespace isc::config;
71using namespace isc::data;
72using namespace isc::db;
73using namespace isc::dhcp;
74using namespace isc::hooks;
75using namespace isc::process;
76using namespace isc::util;
77using namespace isc;
78using namespace std;
79
80//
81// Register database backends
82//
83namespace {
84
93class RSOOListConfigParser : public isc::data::SimpleParser {
94public:
95
103 void parse(const SrvConfigPtr& cfg, const isc::data::ConstElementPtr& value) {
104 try {
105 for (auto const& source_elem : value->listValue()) {
106 std::string option_str = source_elem->stringValue();
107 // This option can be either code (integer) or name. Let's try code first
108 int64_t code = 0;
109 try {
110 code = boost::lexical_cast<int64_t>(option_str);
111 // Protect against the negative value and too high value.
112 if (code < 0) {
113 isc_throw(BadValue, "invalid option code value specified '"
114 << option_str << "', the option code must be a"
115 " non-negative value");
116
117 } else if (code > std::numeric_limits<uint16_t>::max()) {
118 isc_throw(BadValue, "invalid option code value specified '"
119 << option_str << "', the option code must not be"
120 " greater than '" << std::numeric_limits<uint16_t>::max()
121 << "'");
122 }
123
124 } catch (const boost::bad_lexical_cast &) {
125 // Oh well, it's not a number
126 }
127
128 if (!code) {
130 option_str);
131 if (def) {
132 code = def->getCode();
133 } else {
134 isc_throw(BadValue, "unable to find option code for the "
135 " specified option name '" << option_str << "'"
136 " while parsing the list of enabled"
137 " relay-supplied-options");
138 }
139 }
140 cfg->getCfgRSOO()->enable(code);
141 }
142 } catch (const std::exception& ex) {
143 // Rethrow exception with the appended position of the parsed
144 // element.
145 isc_throw(DhcpConfigError, ex.what() << " (" << value->getPosition() << ")");
146 }
147 }
148};
149
158class Dhcp6ConfigParser : public isc::data::SimpleParser {
159public:
160
175 void parse(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
176
177 // Set the data directory for server id file.
178 if (global->contains("data-directory")) {
179 auto dd = getString(global, "data-directory");
180 if (dd != CfgMgr::instance().getDataDir()) {
181 isc_throw(DhcpConfigError,
182 "'data-directory' of '" << dd << "' is invalid,"
183 << " supported path is '"
184 << CfgMgr::instance().getDataDir() << "'");
185 }
186
188 }
189
190 // Set the probation period for decline handling.
191 uint32_t probation_period =
192 getUint32(global, "decline-probation-period");
193 cfg->setDeclinePeriod(probation_period);
194
195 // Set the DHCPv4-over-DHCPv6 interserver port.
196 uint16_t dhcp4o6_port = getUint16(global, "dhcp4o6-port");
197 cfg->setDhcp4o6Port(dhcp4o6_port);
198
199 // Set the global user context.
200 ConstElementPtr user_context = global->get("user-context");
201 if (user_context) {
202 cfg->setContext(user_context);
203 }
204
205 // Set the server's logical name
206 std::string server_tag = getString(global, "server-tag");
207 cfg->setServerTag(server_tag);
208 }
209
221 void parseEarly(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
222 // Set ip-reservations-unique flag.
223 bool ip_reservations_unique = getBoolean(global, "ip-reservations-unique");
224 cfg->setIPReservationsUnique(ip_reservations_unique);
225 }
226
233 void
234 copySubnets6(const CfgSubnets6Ptr& dest, const CfgSharedNetworks6Ptr& from) {
235
236 if (!dest || !from) {
237 isc_throw(BadValue, "Unable to copy subnets: at least one pointer is null");
238 }
239
240 const SharedNetwork6Collection* networks = from->getAll();
241 if (!networks) {
242 // Nothing to copy. Technically, it should return a pointer to empty
243 // container, but let's handle null pointer as well.
244 return;
245 }
246
247 // Let's go through all the networks one by one
248 for (auto const& net : *networks) {
249
250 // For each network go through all the subnets in it.
251 const Subnet6SimpleCollection* subnets = net->getAllSubnets();
252 if (!subnets) {
253 // Shared network without subnets it weird, but we decided to
254 // accept such configurations.
255 continue;
256 }
257
258 // For each subnet, add it to a list of regular subnets.
259 for (auto const& subnet : *subnets) {
260 dest->add(subnet);
261 }
262 }
263 }
264
273 void
274 sanityChecks(const SrvConfigPtr& cfg, const ConstElementPtr& global) {
275
277 cfg->sanityChecksLifetime("preferred-lifetime");
278 cfg->sanityChecksLifetime("valid-lifetime");
279
281 cfg->sanityChecksDdnsTtlParameters();
282
284 const SharedNetwork6Collection* networks = cfg->getCfgSharedNetworks6()->getAll();
285 if (networks) {
286 sharedNetworksSanityChecks(*networks, global->get("shared-networks"));
287 }
288 }
289
296 void
297 sharedNetworksSanityChecks(const SharedNetwork6Collection& networks,
298 ConstElementPtr json) {
299
301 if (!json) {
302 // No json? That means that the shared-networks was never specified
303 // in the config.
304 return;
305 }
306
307 // Used for names uniqueness checks.
308 std::set<string> names;
309
310 // Let's go through all the networks one by one
311 for (auto const& net : networks) {
312 string txt;
313
314 // Let's check if all subnets have either the same interface
315 // or don't have the interface specified at all.
316 string iface = net->getIface();
317
318 const Subnet6SimpleCollection* subnets = net->getAllSubnets();
319 if (subnets) {
320
321 bool rapid_commit = false;
322
323 // Rapid commit must either be enabled or disabled in all subnets
324 // in the shared network.
325 if (subnets->size()) {
326 // If this is the first subnet, remember the value.
327 rapid_commit = (*subnets->begin())->getRapidCommit();
328 }
329
330 // For each subnet, add it to a list of regular subnets.
331 for (auto const& subnet : *subnets) {
332 // Ok, this is the second or following subnets. The value
333 // must match what was set in the first subnet.
334 if (rapid_commit != subnet->getRapidCommit()) {
335 isc_throw(DhcpConfigError, "All subnets in a shared network "
336 "must have the same rapid-commit value. Subnet "
337 << subnet->toText()
338 << " has specified rapid-commit "
339 << (subnet->getRapidCommit() ? "true" : "false")
340 << ", but earlier subnet in the same shared-network"
341 << " or the shared-network itself used rapid-commit "
342 << (rapid_commit ? "true" : "false"));
343 }
344
345 if (iface.empty()) {
346 iface = subnet->getIface();
347 continue;
348 }
349
350 if (subnet->getIface().empty()) {
351 continue;
352 }
353
354 if (subnet->getIface() != iface) {
355 isc_throw(DhcpConfigError, "Subnet " << subnet->toText()
356 << " has specified interface " << subnet->getIface()
357 << ", but earlier subnet in the same shared-network"
358 << " or the shared-network itself used " << iface);
359 }
360
361 // Let's collect the subnets in case we later find out the
362 // subnet doesn't have a mandatory name.
363 txt += subnet->toText() + " ";
364 }
365 }
366
367 // Next, let's check name of the shared network.
368 if (net->getName().empty()) {
369 isc_throw(DhcpConfigError, "Shared-network with subnets "
370 << txt << " is missing mandatory 'name' parameter");
371 }
372
373 // Is it unique?
374 if (names.find(net->getName()) != names.end()) {
375 isc_throw(DhcpConfigError, "A shared-network with "
376 "name " << net->getName() << " defined twice.");
377 }
378 names.insert(net->getName());
379
380 }
381 }
382};
383
384} // anonymous namespace
385
386namespace isc {
387namespace dhcp {
388
397 // Get new UNIX socket configuration.
398 ConstElementPtr unix_config =
399 CfgMgr::instance().getStagingCfg()->getUnixControlSocketInfo();
400
401 // Get current UNIX socket configuration.
402 ConstElementPtr current_unix_config =
403 CfgMgr::instance().getCurrentCfg()->getUnixControlSocketInfo();
404
405 // Determine if the socket configuration has changed. It has if
406 // both old and new configuration is specified but respective
407 // data elements aren't equal.
408 bool sock_changed = (unix_config && current_unix_config &&
409 !unix_config->equals(*current_unix_config));
410
411 // If the previous or new socket configuration doesn't exist or
412 // the new configuration differs from the old configuration we
413 // close the existing socket and open a new socket as appropriate.
414 // Note that closing an existing socket means the client will not
415 // receive the configuration result.
416 if (!unix_config || !current_unix_config || sock_changed) {
417 if (unix_config) {
418 // This will create a control socket and install the external
419 // socket in IfaceMgr. That socket will be monitored when
420 // Dhcp6Srv::receivePacket() calls IfaceMgr::receive6() and
421 // callback in CommandMgr will be called, if necessary.
423 } else if (current_unix_config) {
425 }
426 }
427
428 // Get new HTTP/HTTPS socket configuration.
429 ConstElementPtr http_config =
430 CfgMgr::instance().getStagingCfg()->getHttpControlSocketInfo();
431
432 // Get current HTTP/HTTPS socket configuration.
433 ConstElementPtr current_http_config =
434 CfgMgr::instance().getCurrentCfg()->getHttpControlSocketInfo();
435
436 if (http_config) {
438 } else if (current_http_config) {
440 }
441}
442
449 // Revert any runtime option definitions configured so far and not committed.
451 // Let's set empty container in case a user hasn't specified any configuration
452 // for option definitions. This is equivalent to committing empty container.
454
456
457 // Answer will hold the result.
458 ConstElementPtr answer;
459
460 // Global parameter name in case of an error.
461 string parameter_name;
462 ElementPtr mutable_cfg;
463 SrvConfigPtr srv_config;
464 try {
465 // Get the staging configuration.
466 srv_config = CfgMgr::instance().getStagingCfg();
467
468 // This is a way to convert ConstElementPtr to ElementPtr.
469 // We need a config that can be edited, because we will insert
470 // default values and will insert derived values as well.
471 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
472
473 // Set all default values if not specified by the user.
475
476 // And now derive (inherit) global parameters to subnets, if not specified.
478
479 // In principle we could have the following code structured as a series
480 // of long if else if clauses. That would give a marginal performance
481 // boost, but would make the code less readable. We had serious issues
482 // with the parser code debugability, so I decided to keep it as a
483 // series of independent ifs.
484
485 // This parser is used in several places.
486 Dhcp6ConfigParser global_parser;
487
488 // Apply global options in the staging config, e.g. ip-reservations-unique
489 global_parser.parseEarly(srv_config, mutable_cfg);
490
491 // We need definitions first
492 ConstElementPtr option_defs = mutable_cfg->get("option-def");
493 if (option_defs) {
494 parameter_name = "option-def";
495 OptionDefListParser parser(AF_INET6);
496 CfgOptionDefPtr cfg_option_def = srv_config->getCfgOptionDef();
497 parser.parse(cfg_option_def, option_defs);
498 }
499
500 ConstElementPtr option_datas = mutable_cfg->get("option-data");
501 if (option_datas) {
502 parameter_name = "option-data";
503 OptionDataListParser parser(AF_INET6);
504 CfgOptionPtr cfg_option = srv_config->getCfgOption();
505 parser.parse(cfg_option, option_datas);
506 }
507
508 ConstElementPtr mac_sources = mutable_cfg->get("mac-sources");
509 if (mac_sources) {
510 parameter_name = "mac-sources";
512 CfgMACSource& mac_source = srv_config->getMACSources();
513 parser.parse(mac_source, mac_sources);
514 }
515
516 ConstElementPtr control_socket = mutable_cfg->get("control-socket");
517 if (control_socket) {
518 mutable_cfg->remove("control-socket");
520 l->add(UserContext::toElement(control_socket));
521 mutable_cfg->set("control-sockets", l);
522 }
523
524 ConstElementPtr control_sockets = mutable_cfg->get("control-sockets");
525 if (control_sockets) {
526 parameter_name = "control-sockets";
528 parser.parse(*srv_config, control_sockets);
529 }
530
531 ConstElementPtr multi_threading = mutable_cfg->get("multi-threading");
532 if (multi_threading) {
533 parameter_name = "multi-threading";
535 parser.parse(*srv_config, multi_threading);
536 }
537
538 bool multi_threading_enabled = true;
539 uint32_t thread_count = 0;
540 uint32_t queue_size = 0;
541 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
542 multi_threading_enabled, thread_count, queue_size);
543
545 ConstElementPtr queue_control = mutable_cfg->get("dhcp-queue-control");
546 if (queue_control) {
547 parameter_name = "dhcp-queue-control";
549 srv_config->setDHCPQueueControl(parser.parse(queue_control, multi_threading_enabled));
550 }
551
553 ConstElementPtr reservations_lookup_first = mutable_cfg->get("reservations-lookup-first");
554 if (reservations_lookup_first) {
555 parameter_name = "reservations-lookup-first";
556 if (multi_threading_enabled) {
558 }
559 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
560 }
561
562 ConstElementPtr hr_identifiers =
563 mutable_cfg->get("host-reservation-identifiers");
564 if (hr_identifiers) {
565 parameter_name = "host-reservation-identifiers";
566 HostReservationIdsParser6 parser(srv_config->getCfgHostOperations6());
567 parser.parse(hr_identifiers);
568 }
569
570 ConstElementPtr server_id = mutable_cfg->get("server-id");
571 if (server_id) {
572 parameter_name = "server-id";
573 DUIDConfigParser parser;
574 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
575 parser.parse(cfg, server_id);
576 }
577
578 ConstElementPtr sanity_checks = mutable_cfg->get("sanity-checks");
579 if (sanity_checks) {
580 parameter_name = "sanity-checks";
581 SanityChecksParser parser;
582 parser.parse(*srv_config, sanity_checks);
583 }
584
585 ConstElementPtr expiration_cfg =
586 mutable_cfg->get("expired-leases-processing");
587 if (expiration_cfg) {
588 parameter_name = "expired-leases-processing";
590 parser.parse(expiration_cfg, CfgMgr::instance().getStagingCfg()->getCfgExpiration());
591 }
592
593 // The hooks-libraries configuration must be parsed after parsing
594 // multi-threading configuration so that libraries are checked
595 // for multi-threading compatibility.
596 ConstElementPtr hooks_libraries = mutable_cfg->get("hooks-libraries");
597 if (hooks_libraries) {
598 parameter_name = "hooks-libraries";
599 HooksLibrariesParser hooks_parser;
600 HooksConfig& libraries = srv_config->getHooksConfig();
601 hooks_parser.parse(libraries, hooks_libraries);
602 libraries.verifyLibraries(hooks_libraries->getPosition(),
603 multi_threading_enabled);
604 }
605
606 // D2 client configuration.
607 D2ClientConfigPtr d2_client_cfg;
608
609 // Legacy DhcpConfigParser stuff below.
610 ConstElementPtr dhcp_ddns = mutable_cfg->get("dhcp-ddns");
611 if (dhcp_ddns) {
612 parameter_name = "dhcp-ddns";
613 // Apply defaults
616 d2_client_cfg = parser.parse(dhcp_ddns);
617 }
618
619 ConstElementPtr client_classes = mutable_cfg->get("client-classes");
620 if (client_classes) {
621 parameter_name = "client-classes";
623 ClientClassDictionaryPtr dictionary =
624 parser.parse(client_classes, AF_INET6);
625 srv_config->setClientClassDictionary(dictionary);
626 }
627
628 // Please move at the end when migration will be finished.
629 ConstElementPtr lease_database = mutable_cfg->get("lease-database");
630 if (lease_database) {
631 parameter_name = "lease-database";
632 db::DbAccessParser parser;
633 std::string access_string;
634 parser.parse(access_string, lease_database);
635 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
636 cfg_db_access->setLeaseDbAccessString(access_string);
637 }
638
639 ConstElementPtr hosts_database = mutable_cfg->get("hosts-database");
640 if (hosts_database) {
641 parameter_name = "hosts-database";
642 db::DbAccessParser parser;
643 std::string access_string;
644 parser.parse(access_string, hosts_database);
645 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
646 cfg_db_access->setHostDbAccessString(access_string);
647 }
648
649 ConstElementPtr hosts_databases = mutable_cfg->get("hosts-databases");
650 if (hosts_databases) {
651 parameter_name = "hosts-databases";
652 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
653 for (auto const& it : hosts_databases->listValue()) {
654 db::DbAccessParser parser;
655 std::string access_string;
656 parser.parse(access_string, it);
657 cfg_db_access->setHostDbAccessString(access_string);
658 }
659 }
660
661 // Keep relative orders of shared networks and subnets.
662 ConstElementPtr shared_networks = mutable_cfg->get("shared-networks");
663 if (shared_networks) {
664 parameter_name = "shared-networks";
671 CfgSharedNetworks6Ptr cfg = srv_config->getCfgSharedNetworks6();
672 parser.parse(cfg, shared_networks);
673
674 // We also need to put the subnets it contains into normal
675 // subnets list.
676 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
677 }
678
679 ConstElementPtr subnet6 = mutable_cfg->get("subnet6");
680 if (subnet6) {
681 parameter_name = "subnet6";
682 Subnets6ListConfigParser subnets_parser;
683 // parse() returns number of subnets parsed. We may log it one day.
684 subnets_parser.parse(srv_config, subnet6);
685 }
686
687 ConstElementPtr reservations = mutable_cfg->get("reservations");
688 if (reservations) {
689 parameter_name = "reservations";
690 HostCollection hosts;
692 parser.parse(SUBNET_ID_GLOBAL, reservations, hosts);
693 for (auto const& h : hosts) {
694 srv_config->getCfgHosts()->add(h);
695 }
696 }
697
698 ConstElementPtr config_control = mutable_cfg->get("config-control");
699 if (config_control) {
700 parameter_name = "config-control";
701 ConfigControlParser parser;
702 ConfigControlInfoPtr config_ctl_info = parser.parse(config_control);
703 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
704 }
705
706 ConstElementPtr rsoo_list = mutable_cfg->get("relay-supplied-options");
707 if (rsoo_list) {
708 parameter_name = "relay-supplied-options";
709 RSOOListConfigParser parser;
710 parser.parse(srv_config, rsoo_list);
711 }
712
713 ConstElementPtr compatibility = mutable_cfg->get("compatibility");
714 if (compatibility) {
715 CompatibilityParser parser;
716 parser.parse(compatibility, *CfgMgr::instance().getStagingCfg());
717 }
718
719 // Make parsers grouping.
720 const std::map<std::string, ConstElementPtr>& values_map =
721 mutable_cfg->mapValue();
722
723 for (auto const& config_pair : values_map) {
724 parameter_name = config_pair.first;
725
726 // These are converted to SimpleParser and are handled already above.
727 if ((config_pair.first == "data-directory") ||
728 (config_pair.first == "option-def") ||
729 (config_pair.first == "option-data") ||
730 (config_pair.first == "mac-sources") ||
731 (config_pair.first == "control-socket") ||
732 (config_pair.first == "control-sockets") ||
733 (config_pair.first == "multi-threading") ||
734 (config_pair.first == "dhcp-queue-control") ||
735 (config_pair.first == "host-reservation-identifiers") ||
736 (config_pair.first == "server-id") ||
737 (config_pair.first == "interfaces-config") ||
738 (config_pair.first == "sanity-checks") ||
739 (config_pair.first == "expired-leases-processing") ||
740 (config_pair.first == "hooks-libraries") ||
741 (config_pair.first == "dhcp-ddns") ||
742 (config_pair.first == "client-classes") ||
743 (config_pair.first == "lease-database") ||
744 (config_pair.first == "hosts-database") ||
745 (config_pair.first == "hosts-databases") ||
746 (config_pair.first == "subnet6") ||
747 (config_pair.first == "shared-networks") ||
748 (config_pair.first == "reservations") ||
749 (config_pair.first == "config-control") ||
750 (config_pair.first == "relay-supplied-options") ||
751 (config_pair.first == "loggers") ||
752 (config_pair.first == "compatibility")) {
753 continue;
754 }
755
756 // As of Kea 1.6.0 we have two ways of inheriting the global parameters.
757 // The old method is used in JSON configuration parsers when the global
758 // parameters are derived into the subnets and shared networks and are
759 // being treated as explicitly specified. The new way used by the config
760 // backend is the dynamic inheritance whereby each subnet and shared
761 // network uses a callback function to return global parameter if it
762 // is not specified at lower level. This callback uses configured globals.
763 // We deliberately include both default and explicitly specified globals
764 // so as the callback can access the appropriate global values regardless
765 // whether they are set to a default or other value.
766 if ( (config_pair.first == "renew-timer") ||
767 (config_pair.first == "rebind-timer") ||
768 (config_pair.first == "preferred-lifetime") ||
769 (config_pair.first == "min-preferred-lifetime") ||
770 (config_pair.first == "max-preferred-lifetime") ||
771 (config_pair.first == "valid-lifetime") ||
772 (config_pair.first == "min-valid-lifetime") ||
773 (config_pair.first == "max-valid-lifetime") ||
774 (config_pair.first == "decline-probation-period") ||
775 (config_pair.first == "dhcp4o6-port") ||
776 (config_pair.first == "server-tag") ||
777 (config_pair.first == "reservations-global") ||
778 (config_pair.first == "reservations-in-subnet") ||
779 (config_pair.first == "reservations-out-of-pool") ||
780 (config_pair.first == "calculate-tee-times") ||
781 (config_pair.first == "t1-percent") ||
782 (config_pair.first == "t2-percent") ||
783 (config_pair.first == "cache-threshold") ||
784 (config_pair.first == "cache-max-age") ||
785 (config_pair.first == "adaptive-lease-time-threshold") ||
786 (config_pair.first == "hostname-char-set") ||
787 (config_pair.first == "hostname-char-replacement") ||
788 (config_pair.first == "ddns-send-updates") ||
789 (config_pair.first == "ddns-override-no-update") ||
790 (config_pair.first == "ddns-override-client-update") ||
791 (config_pair.first == "ddns-replace-client-name") ||
792 (config_pair.first == "ddns-generated-prefix") ||
793 (config_pair.first == "ddns-qualifying-suffix") ||
794 (config_pair.first == "ddns-update-on-renew") ||
795 (config_pair.first == "ddns-use-conflict-resolution") ||
796 (config_pair.first == "ddns-conflict-resolution-mode") ||
797 (config_pair.first == "ddns-ttl-percent") ||
798 (config_pair.first == "store-extended-info") ||
799 (config_pair.first == "statistic-default-sample-count") ||
800 (config_pair.first == "statistic-default-sample-age") ||
801 (config_pair.first == "early-global-reservations-lookup") ||
802 (config_pair.first == "ip-reservations-unique") ||
803 (config_pair.first == "reservations-lookup-first") ||
804 (config_pair.first == "allow-address-registration") ||
805 (config_pair.first == "parked-packet-limit") ||
806 (config_pair.first == "allocator") ||
807 (config_pair.first == "ddns-ttl") ||
808 (config_pair.first == "ddns-ttl-min") ||
809 (config_pair.first == "ddns-ttl-max") ||
810 (config_pair.first == "pd-allocator") ) {
811 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
812 config_pair.second);
813 continue;
814 }
815
816 // Nothing to configure for the user-context.
817 if (config_pair.first == "user-context") {
818 continue;
819 }
820
821 // If we got here, no code handled this parameter, so we bail out.
823 "unsupported global configuration parameter: " << config_pair.first
824 << " (" << config_pair.second->getPosition() << ")");
825 }
826
827 // Reset parameter name.
828 parameter_name = "<post parsing>";
829
830 // Apply global options in the staging config.
831 global_parser.parse(srv_config, mutable_cfg);
832
833 // This method conducts final sanity checks and tweaks. In particular,
834 // it checks that there is no conflict between plain subnets and those
835 // defined as part of shared networks.
836 global_parser.sanityChecks(srv_config, mutable_cfg);
837
838 // Validate D2 client configuration.
839 if (!d2_client_cfg) {
840 d2_client_cfg.reset(new D2ClientConfig());
841 }
842 d2_client_cfg->validateContents();
843 srv_config->setD2ClientConfig(d2_client_cfg);
844 } catch (const isc::Exception& ex) {
846 .arg(parameter_name).arg(ex.what());
848 } catch (...) {
849 // For things like bad_cast in boost::lexical_cast
850 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
851 answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration "
852 "processing error");
853 }
854
855 if (!answer) {
856 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration seems sane. "
857 "Control-socket, hook-libraries, and D2 configuration "
858 "were sanity checked, but not applied.");
859 }
860
861 return (answer);
862}
863
866 bool check_only, bool extra_checks) {
867 if (!config_set) {
869 "Can't parse NULL config");
870 return (answer);
871 }
872
874 .arg(server.redactConfig(config_set)->str());
875
876 // Resource managers usually check for @ref MultiThreadingMgr::isTestMode
877 // value and do not open UNIX or TCP/UDP sockets, lock files, nor do they open
878 // or rotate files, as any of these actions could interfere with a running
879 // process on the same machine.
880 std::unique_ptr<MtTestMode> mt_test_mode;
881 if (check_only) {
882 mt_test_mode.reset(new MtTestMode());
883 }
884
885 auto answer = processDhcp6Config(config_set);
886
887 int status_code = CONTROL_RESULT_SUCCESS;
888 isc::config::parseAnswer(status_code, answer);
889
890 SrvConfigPtr srv_config;
891
892 if (status_code == CONTROL_RESULT_SUCCESS) {
893 if (check_only) {
894 if (extra_checks) {
895 std::ostringstream err;
896 // Configure DHCP packet queueing
897 try {
899 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
900 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET6, qc)) {
902 .arg(IfaceMgr::instance().getPacketQueue6()->getInfoStr());
903 }
904
905 } catch (const std::exception& ex) {
906 err << "Error setting packet queue controls after server reconfiguration: "
907 << ex.what();
909 status_code = CONTROL_RESULT_ERROR;
910 }
911 }
912 } else {
913
914 // Usually unit tests create managers before calling configureDhcp6Server and
915 // do not call ControlledDhcpv6Srv::processConfig.
916 // Runtime code path creates the managers after calling configureDhcp6Server
917 // and they need to be reset just after successful configuration parsing.
918 if (!IfaceMgr::instance().isTestMode()) {
919 // Destroy lease manager before hooks unload.
921
922 // Destroy host manager before hooks unload.
924 }
925
926 // disable multi-threading (it will be applied by new configuration)
927 // this must be done in order to properly handle MT to ST transition
928 // when 'multi-threading' structure is missing from new config and
929 // to properly drop any task items stored in the thread pool which
930 // might reference some handles to loaded hooks, preventing them
931 // from being unloaded.
932 MultiThreadingMgr::instance().apply(false, 0, 0);
933
934 // Close DHCP sockets and remove any existing timers.
936 TimerMgr::instance()->unregisterTimers();
937 server.discardPackets();
938 server.getCBControl()->reset();
939 }
940 }
941
942 // Parsing stage is complete. The current configuration has not been altered.
943 // From this stage on, every error might have irreversible consequences and the
944 // configuration might not be restored to a working state.
945 if (status_code == CONTROL_RESULT_SUCCESS) {
946 string parameter_name;
947 ElementPtr mutable_cfg;
948 try {
949 // Get the staging configuration.
950 srv_config = CfgMgr::instance().getStagingCfg();
951
952 // This is a way to convert ConstElementPtr to ElementPtr.
953 // We need a config that can be edited, because we will insert
954 // default values and will insert derived values as well.
955 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
956
957 ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
958 if (ifaces_config) {
959 parameter_name = "interfaces-config";
960 IfacesConfigParser parser(AF_INET6, check_only);
961 CfgIfacePtr cfg_iface = srv_config->getCfgIface();
962 cfg_iface->reset();
963 parser.parse(cfg_iface, ifaces_config);
964 }
965 } catch (const isc::Exception& ex) {
967 .arg(parameter_name).arg(ex.what());
968 if (!check_only || extra_checks) {
969 status_code = CONTROL_RESULT_FATAL_ERROR;
970 } else {
971 status_code = CONTROL_RESULT_ERROR;
972 }
973 answer = isc::config::createAnswer(status_code, ex.what());
974 } catch (...) {
975 // For things like bad_cast in boost::lexical_cast
976 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
977 if (!check_only || extra_checks) {
978 status_code = CONTROL_RESULT_FATAL_ERROR;
979 } else {
980 status_code = CONTROL_RESULT_ERROR;
981 }
982 answer = isc::config::createAnswer(status_code, "undefined configuration"
983 " processing error");
984 }
985 }
986
987 // So far so good, there was no parsing error so let's commit the
988 // configuration. This will add created subnets and option values into
989 // the server's configuration.
990 // This operation should be exception safe but let's make sure.
991 if (status_code == CONTROL_RESULT_SUCCESS && !check_only) {
992 try {
993
994 // Setup the command channel.
996 } catch (const isc::Exception& ex) {
998 status_code = CONTROL_RESULT_FATAL_ERROR;
999 answer = isc::config::createAnswer(status_code, ex.what());
1000 } catch (...) {
1001 // For things like bad_cast in boost::lexical_cast
1003 status_code = CONTROL_RESULT_FATAL_ERROR;
1004 answer = isc::config::createAnswer(status_code, "undefined configuration"
1005 " parsing error");
1006 }
1007 }
1008
1009 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1010 try {
1011 // No need to commit interface names as this is handled by the
1012 // CfgMgr::commit() function.
1013
1014 // Apply the staged D2ClientConfig, used to be done by parser commit
1016 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
1018 } catch (const isc::Exception& ex) {
1020 status_code = CONTROL_RESULT_FATAL_ERROR;
1021 answer = isc::config::createAnswer(status_code, ex.what());
1022 } catch (...) {
1023 // For things like bad_cast in boost::lexical_cast
1025 status_code = CONTROL_RESULT_FATAL_ERROR;
1026 answer = isc::config::createAnswer(status_code, "undefined configuration"
1027 " parsing error");
1028 }
1029 }
1030
1031 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1032 try {
1033 // This occurs last as if it succeeds, there is no easy way to
1034 // revert it. As a result, the failure to commit a subsequent
1035 // change causes problems when trying to roll back.
1037 static_cast<void>(HooksManager::unloadLibraries());
1039 const HooksConfig& libraries =
1040 CfgMgr::instance().getStagingCfg()->getHooksConfig();
1041 bool multi_threading_enabled = true;
1042 uint32_t thread_count = 0;
1043 uint32_t queue_size = 0;
1044 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
1045 multi_threading_enabled, thread_count, queue_size);
1046 libraries.loadLibraries(multi_threading_enabled);
1047 } catch (const isc::Exception& ex) {
1049 status_code = CONTROL_RESULT_FATAL_ERROR;
1050 answer = isc::config::createAnswer(status_code, ex.what());
1051 } catch (...) {
1052 // For things like bad_cast in boost::lexical_cast
1054 status_code = CONTROL_RESULT_FATAL_ERROR;
1055 answer = isc::config::createAnswer(status_code, "undefined configuration"
1056 " parsing error");
1057 }
1058
1059 if (extra_checks && status_code == CONTROL_RESULT_SUCCESS) {
1060 // Re-open lease and host database with new parameters.
1061 try {
1062 // Get the staging configuration.
1063 srv_config = CfgMgr::instance().getStagingCfg();
1064
1065 // Create managers like @ref ControlledDhcpv6Srv::processConfig
1066 // does. No need to change "persist" value here because
1067 // @ref MultiThreadingMgr::isTestMode is used instead.
1068 // This will also make log messages consistent with the checked
1069 // config values.
1070 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
1071 string params = "universe=6";
1072 if (cfg_db->getExtendedInfoTablesEnabled()) {
1073 params += " extended-info-tables=true";
1074 }
1075 cfg_db->setAppendedParameters(params);
1076 cfg_db->createManagers();
1077 } catch (const std::exception& ex) {
1078 status_code = CONTROL_RESULT_FATAL_ERROR;
1079 answer = isc::config::createAnswer(status_code, ex.what());
1080 }
1081 }
1082 }
1083
1084 // Log the list of known backends.
1086
1087 // Log the list of known backends.
1089
1090 // Log the list of known backends.
1092
1093 // Log the list of known backends.
1095
1096 // Moved from the commit block to add the config backend indication.
1097 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1098 try {
1099 // If there are config backends, fetch and merge into staging config
1100 server.getCBControl()->databaseConfigFetch(srv_config,
1101 CBControlDHCPv6::FetchMode::FETCH_ALL);
1102 } catch (const isc::Exception& ex) {
1103 std::ostringstream err;
1104 err << "during update from config backend database: " << ex.what();
1106 status_code = CONTROL_RESULT_FATAL_ERROR;
1107 answer = isc::config::createAnswer(status_code, err.str());
1108 } catch (...) {
1109 // For things like bad_cast in boost::lexical_cast
1110 std::ostringstream err;
1111 err << "during update from config backend database: "
1112 << "undefined configuration parsing error";
1114 status_code = CONTROL_RESULT_FATAL_ERROR;
1115 answer = isc::config::createAnswer(status_code, err.str());
1116 }
1117 }
1118
1119 // Rollback changes as the configuration parsing failed.
1120 if (check_only || status_code != CONTROL_RESULT_SUCCESS) {
1121 // Revert to original configuration of runtime option definitions
1122 // in the libdhcp++.
1124
1125 if (status_code == CONTROL_RESULT_SUCCESS && extra_checks) {
1126 auto notify_libraries = ControlledDhcpv6Srv::finishConfigHookLibraries(config_set);
1127 if (notify_libraries) {
1128 return (notify_libraries);
1129 }
1130
1132 try {
1133 // Handle events registered by hooks using external IOService objects.
1135 } catch (const std::exception& ex) {
1136 std::ostringstream err;
1137 err << "Error initializing hooks: "
1138 << ex.what();
1140 }
1141 }
1142
1143 return (answer);
1144 }
1145
1147 .arg(CfgMgr::instance().getStagingCfg()->
1148 getConfigSummary(SrvConfig::CFGSEL_ALL6));
1149
1150 // Also calculate SHA256 hash of the config that was just set and
1151 // append it to the response.
1153 string hash = BaseCommandMgr::getHash(config);
1154 ElementPtr hash_map = Element::createMap();
1155 hash_map->set("hash", Element::create(hash));
1156
1157 // Everything was fine. Configuration is successful.
1158 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration successful.", hash_map);
1159 return (answer);
1160}
1161
1162} // namespace dhcp
1163} // namespace isc
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.
void logRegistered()
Logs out all registered backends.
static std::string getHash(const isc::data::ConstElementPtr &config)
returns a hash of a given Element structure
void closeCommandSockets()
Close http control sockets.
static HttpCommandMgr & instance()
HttpCommandMgr is a singleton class.
void openCommandSockets(const isc::data::ConstElementPtr config)
Open http control sockets using configuration.
static UnixCommandMgr & instance()
UnixCommandMgr is a singleton class.
void openCommandSockets(const isc::data::ConstElementPtr config)
Opens unix control socket with parameters specified in socket_info (required parameters: socket-type:...
void closeCommandSockets()
Shuts down any open unix control sockets.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:299
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:354
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:349
Parse Database Parameters.
void parse(std::string &access_string, isc::data::ConstElementPtr database_config)
Parse configuration value.
Wrapper class that holds MAC/hardware address sources.
void setD2ClientConfig(D2ClientConfigPtr &new_config)
Updates the DHCP-DDNS client configuration to the given value.
Definition cfgmgr.cc:45
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition cfgmgr.cc:121
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
static void extract(data::ConstElementPtr value, bool &enabled, uint32_t &thread_count, uint32_t &queue_size)
Extract multi-threading parameters from a given configuration.
Parser for a list of client class definitions.
ClientClassDictionaryPtr parse(isc::data::ConstElementPtr class_def_list, uint16_t family, bool check_dependencies=true)
Parse configuration entries.
void parse(isc::data::ConstElementPtr cfg, isc::dhcp::SrvConfig &srv_cfg)
Parse compatibility flags.
static ConfigBackendDHCPv6Mgr & instance()
Returns a sole instance of the ConfigBackendDHCPv6Mgr.
Parser for the control-sockets structure.
void parse(SrvConfig &srv_cfg, isc::data::ConstElementPtr value)
"Parses" control-sockets structure
static isc::data::ConstElementPtr finishConfigHookLibraries(isc::data::ConstElementPtr config)
Configuration checker for hook libraries.
Parser for D2ClientConfig.
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg)
Parses a given dhcp-ddns element into D2ClientConfig.
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.
Parser for the configuration of DHCP packet queue controls.
data::ElementPtr parse(const isc::data::ConstElementPtr &control_elem, bool multi_threading_enabled)
Parses content of the "dhcp-queue-control".
Parser for server DUID configuration.
void parse(const CfgDUIDPtr &cfg, isc::data::ConstElementPtr duid_configuration)
Parses DUID configuration.
To be removed. Please use ConfigError instead.
DHCPv6 server service.
Definition dhcp6_srv.h:66
CBControlDHCPv6Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
Definition dhcp6_srv.h:124
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
Parser for the configuration parameters pertaining to the processing of expired leases.
void parse(isc::data::ConstElementPtr expiration_config, isc::dhcp::CfgExpirationPtr expiration)
Parses parameters in the JSON map, pertaining to the processing of the expired leases.
static void logRegistered()
Logs out all registered backends.
static void create()
Creates new instance of the HostMgr.
Definition host_mgr.cc:52
Parser for a list of host identifiers for DHCPv6.
void parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
Parser for a list of host reservations for a subnet.
void parse(const SubnetID &subnet_id, isc::data::ConstElementPtr hr_list, HostCollection &hosts_list)
Parses a list of host reservation entries for a subnet.
void detectIfaces(bool update_only=false)
Detects network interfaces.
static IfaceMgr & instance()
IfaceMgr is a singleton class.
Definition iface_mgr.cc:49
void closeSockets()
Closes all open sockets.
Definition iface_mgr.cc:287
Parser for the configuration of interfaces.
void parse(const CfgIfacePtr &config, const isc::data::ConstElementPtr &values)
Parses content of the "interfaces-config".
static void destroy()
Destroy lease manager.
static void logRegistered()
Logs out all registered backends.
static void logRegistered()
Logs out all registered backends.
static void setRuntimeOptionDefs(const OptionDefSpaceContainer &defs)
Copies option definitions created at runtime.
Definition libdhcp++.cc:224
static OptionDefinitionPtr getOptionDef(const std::string &space, const uint16_t code)
Return the first option definition matching a particular option code.
Definition libdhcp++.cc:132
static void revertRuntimeOptionDefs()
Reverts uncommitted changes to runtime option definitions.
Definition libdhcp++.cc:243
parser for MAC/hardware acquisition sources
void parse(CfgMACSource &mac_sources, isc::data::ConstElementPtr value)
parses parameters value
Simple parser for multi-threading structure.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure.
Parser for option data values within a subnet.
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list, bool encapsulate=true)
Parses a list of options, instantiates them and stores in cfg.
Parser for a list of option definitions.
void parse(CfgOptionDefPtr cfg, isc::data::ConstElementPtr def_list)
Parses a list of option definitions, create them and store in cfg.
Class of option definition space container.
Simple parser for sanity-checks structure.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure
void parse(CfgSharedNetworksTypePtr &cfg, const data::ConstElementPtr &shared_networks_list_data)
Parses a list of shared networks.
static size_t deriveParameters(isc::data::ElementPtr global)
Derives (inherits) all parameters from global to more specific scopes.
static size_t setAllDefaults(isc::data::ElementPtr global)
Sets all defaults for DHCPv6 configuration.
static const uint32_t CFGSEL_ALL6
IPv6 related config.
Definition srv_config.h:76
this class parses a list of DHCP6 subnets
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list, bool encapsulate_options=true)
parses contents of the list
static const TimerMgrPtr & instance()
Returns pointer to the sole instance of the TimerMgr.
Definition timer_mgr.cc:446
Wrapper class that holds hooks libraries configuration.
void verifyLibraries(const isc::data::Element::Position &position, bool multi_threading_enabled) const
Verifies that libraries stored in libraries_ are valid.
void loadLibraries(bool multi_threading_enabled) const
Commits hooks libraries configuration.
Parser for hooks library list.
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
static bool unloadLibraries()
Unload libraries.
static void prepareUnloadLibraries()
Prepare the unloading of libraries.
Implements parser for config control information, "config-control".
ConfigControlInfoPtr parse(const data::ConstElementPtr &config_control)
Parses a configuration control Element.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
Definition daemon.cc:297
RAII wrapper for MT test mode.
static MultiThreadingMgr & instance()
Returns a single instance of Multi Threading Manager.
void apply(bool enabled, uint32_t thread_count, uint32_t queue_size)
Apply the multi-threading related settings.
Parsers for client class definitions.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Logging initialization functions.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#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
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
ConstElementPtr parseAnswer(int &rcode, const ConstElementPtr &msg)
Parses a standard config/command level answer and returns arguments or text status code.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
Creates a standard config/command level answer message.
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_FATAL_ERROR
Status code indicating that the command was unsuccessful and the configuration could not be reverted ...
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
void configureCommandChannel()
Initialize the command channel based on the staging configuration.
boost::shared_ptr< CfgDUID > CfgDUIDPtr
Pointer to the Non-const object.
Definition cfg_duid.h:161
const isc::log::MessageID DHCP6_PARSER_FAIL
const isc::log::MessageID DHCP6_PARSER_EXCEPTION
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition cfg_option.h:973
boost::multi_index_container< SharedNetwork6Ptr, boost::multi_index::indexed_by< boost::multi_index::random_access< boost::multi_index::tag< SharedNetworkRandomAccessIndexTag > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< SharedNetworkIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t, &data::BaseStampedElement::getId > >, boost::multi_index::ordered_unique< boost::multi_index::tag< SharedNetworkNameIndexTag >, boost::multi_index::const_mem_fun< SharedNetwork6, std::string, &SharedNetwork6::getName > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< SharedNetworkModificationTimeIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > > > > SharedNetwork6Collection
Multi index container holding shared networks.
const isc::log::MessageID DHCP6_DATA_DIRECTORY_DEPRECATED
isc::data::ConstElementPtr configureDhcp6Server(Dhcpv6Srv &server, isc::data::ConstElementPtr config_set, bool check_only, bool extra_checks)
Configure DHCPv6 server (Dhcpv6Srv) with a set of configuration values.
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
isc::data::ConstElementPtr processDhcp6Config(isc::data::ConstElementPtr config_set)
Process a DHCPv6 configuration and return an answer stating if the configuration is valid,...
const int DBG_DHCP6_COMMAND
Debug level used to log receiving commands.
Definition dhcp6_log.h:28
const isc::log::MessageID DHCP6_CONFIG_COMPLETE
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
Definition cfg_iface.h:501
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Definition host.h:846
const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
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 > > > > Subnet6SimpleCollection
A simple collection of Subnet6 objects.
Definition subnet.h:890
const isc::log::MessageID DHCP6_PARSER_COMMIT_EXCEPTION
const isc::log::MessageID DHCP6_CONFIG_START
SharedNetworksListParser< SharedNetwork6Parser > SharedNetworks6ListParser
Type of the shared networks list parser for IPv6.
const isc::log::MessageID DHCP6_PARSER_COMMIT_FAIL
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
Definition dhcp6_log.h:88
const isc::log::MessageID DHCP6_CONFIG_PACKET_QUEUE
boost::shared_ptr< ConfigControlInfo > ConfigControlInfoPtr
Defines a pointer to a ConfigControlInfo.
Defines the logger used by the top-level component of kea-lfc.
#define DHCP6_OPTION_SPACE
static data::ElementPtr toElement(data::ConstElementPtr map)
Copy an Element map.