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 // Sanity check use of SFLQ allocator.
290 cfg->sanityChecksSflqAllocator();
291 }
292
299 void
300 sharedNetworksSanityChecks(const SharedNetwork6Collection& networks,
301 ConstElementPtr json) {
302
304 if (!json) {
305 // No json? That means that the shared-networks was never specified
306 // in the config.
307 return;
308 }
309
310 // Used for names uniqueness checks.
311 std::set<string> names;
312
313 // Let's go through all the networks one by one
314 for (auto const& net : networks) {
315 string txt;
316
317 // Let's check if all subnets have either the same interface
318 // or don't have the interface specified at all.
319 string iface = net->getIface();
320
321 const Subnet6SimpleCollection* subnets = net->getAllSubnets();
322 if (subnets) {
323
324 bool rapid_commit = false;
325
326 // Rapid commit must either be enabled or disabled in all subnets
327 // in the shared network.
328 if (subnets->size()) {
329 // If this is the first subnet, remember the value.
330 rapid_commit = (*subnets->begin())->getRapidCommit();
331 }
332
333 // For each subnet, add it to a list of regular subnets.
334 for (auto const& subnet : *subnets) {
335 // Ok, this is the second or following subnets. The value
336 // must match what was set in the first subnet.
337 if (rapid_commit != subnet->getRapidCommit()) {
338 isc_throw(DhcpConfigError, "All subnets in a shared network "
339 "must have the same rapid-commit value. Subnet "
340 << subnet->toText()
341 << " has specified rapid-commit "
342 << (subnet->getRapidCommit() ? "true" : "false")
343 << ", but earlier subnet in the same shared-network"
344 << " or the shared-network itself used rapid-commit "
345 << (rapid_commit ? "true" : "false"));
346 }
347
348 if (iface.empty()) {
349 iface = subnet->getIface();
350 continue;
351 }
352
353 if (subnet->getIface().empty()) {
354 continue;
355 }
356
357 if (subnet->getIface() != iface) {
358 isc_throw(DhcpConfigError, "Subnet " << subnet->toText()
359 << " has specified interface " << subnet->getIface()
360 << ", but earlier subnet in the same shared-network"
361 << " or the shared-network itself used " << iface);
362 }
363
364 // Let's collect the subnets in case we later find out the
365 // subnet doesn't have a mandatory name.
366 txt += subnet->toText() + " ";
367 }
368 }
369
370 // Next, let's check name of the shared network.
371 if (net->getName().empty()) {
372 isc_throw(DhcpConfigError, "Shared-network with subnets "
373 << txt << " is missing mandatory 'name' parameter");
374 }
375
376 // Is it unique?
377 if (names.find(net->getName()) != names.end()) {
378 isc_throw(DhcpConfigError, "A shared-network with "
379 "name " << net->getName() << " defined twice.");
380 }
381 names.insert(net->getName());
382
383 }
384 }
385};
386
387} // anonymous namespace
388
389namespace isc {
390namespace dhcp {
391
400 // Get new UNIX socket configuration.
401 ConstElementPtr unix_config =
402 CfgMgr::instance().getStagingCfg()->getUnixControlSocketInfo();
403
404 // Get current UNIX socket configuration.
405 ConstElementPtr current_unix_config =
406 CfgMgr::instance().getCurrentCfg()->getUnixControlSocketInfo();
407
408 // Determine if the socket configuration has changed. It has if
409 // both old and new configuration is specified but respective
410 // data elements aren't equal.
411 bool sock_changed = (unix_config && current_unix_config &&
412 !unix_config->equals(*current_unix_config));
413
414 // If the previous or new socket configuration doesn't exist or
415 // the new configuration differs from the old configuration we
416 // close the existing socket and open a new socket as appropriate.
417 // Note that closing an existing socket means the client will not
418 // receive the configuration result.
419 if (!unix_config || !current_unix_config || sock_changed) {
420 if (unix_config) {
421 // This will create a control socket and install the external
422 // socket in IfaceMgr. That socket will be monitored when
423 // Dhcp6Srv::receivePacket() calls IfaceMgr::receive6() and
424 // callback in CommandMgr will be called, if necessary.
426 } else if (current_unix_config) {
428 }
429 }
430
431 // Get new HTTP/HTTPS socket configuration.
432 ConstElementPtr http_config =
433 CfgMgr::instance().getStagingCfg()->getHttpControlSocketInfo();
434
435 // Get current HTTP/HTTPS socket configuration.
436 ConstElementPtr current_http_config =
437 CfgMgr::instance().getCurrentCfg()->getHttpControlSocketInfo();
438
439 if (http_config) {
441 } else if (current_http_config) {
443 }
444}
445
452 // Revert any runtime option definitions configured so far and not committed.
454 // Let's set empty container in case a user hasn't specified any configuration
455 // for option definitions. This is equivalent to committing empty container.
457
459
460 // Answer will hold the result.
461 ConstElementPtr answer;
462
463 // Global parameter name in case of an error.
464 string parameter_name;
465 ElementPtr mutable_cfg;
466 SrvConfigPtr srv_config;
467 try {
468 // Get the staging configuration.
469 srv_config = CfgMgr::instance().getStagingCfg();
470
471 // This is a way to convert ConstElementPtr to ElementPtr.
472 // We need a config that can be edited, because we will insert
473 // default values and will insert derived values as well.
474 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
475
476 // Set all default values if not specified by the user.
478
479 // And now derive (inherit) global parameters to subnets, if not specified.
481
482 // In principle we could have the following code structured as a series
483 // of long if else if clauses. That would give a marginal performance
484 // boost, but would make the code less readable. We had serious issues
485 // with the parser code debugability, so I decided to keep it as a
486 // series of independent ifs.
487
488 // This parser is used in several places.
489 Dhcp6ConfigParser global_parser;
490
491 // Apply global options in the staging config, e.g. ip-reservations-unique
492 global_parser.parseEarly(srv_config, mutable_cfg);
493
494 // We need definitions first
495 ConstElementPtr option_defs = mutable_cfg->get("option-def");
496 if (option_defs) {
497 parameter_name = "option-def";
498 OptionDefListParser parser(AF_INET6);
499 CfgOptionDefPtr cfg_option_def = srv_config->getCfgOptionDef();
500 parser.parse(cfg_option_def, option_defs);
501 }
502
503 ConstElementPtr option_datas = mutable_cfg->get("option-data");
504 if (option_datas) {
505 parameter_name = "option-data";
506 OptionDataListParser parser(AF_INET6);
507 CfgOptionPtr cfg_option = srv_config->getCfgOption();
508 parser.parse(cfg_option, option_datas);
509 }
510
511 ConstElementPtr mac_sources = mutable_cfg->get("mac-sources");
512 if (mac_sources) {
513 parameter_name = "mac-sources";
515 CfgMACSource& mac_source = srv_config->getMACSources();
516 parser.parse(mac_source, mac_sources);
517 }
518
519 ConstElementPtr control_socket = mutable_cfg->get("control-socket");
520 if (control_socket) {
521 mutable_cfg->remove("control-socket");
523 l->add(UserContext::toElement(control_socket));
524 mutable_cfg->set("control-sockets", l);
525 }
526
527 ConstElementPtr control_sockets = mutable_cfg->get("control-sockets");
528 if (control_sockets) {
529 parameter_name = "control-sockets";
531 parser.parse(*srv_config, control_sockets);
532 }
533
534 ConstElementPtr multi_threading = mutable_cfg->get("multi-threading");
535 if (multi_threading) {
536 parameter_name = "multi-threading";
538 parser.parse(*srv_config, multi_threading);
539 }
540
541 bool multi_threading_enabled = true;
542 uint32_t thread_count = 0;
543 uint32_t queue_size = 0;
544 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
545 multi_threading_enabled, thread_count, queue_size);
546
548 ConstElementPtr queue_control = mutable_cfg->get("dhcp-queue-control");
549 if (queue_control) {
550 parameter_name = "dhcp-queue-control";
552 srv_config->setDHCPQueueControl(parser.parse(queue_control, multi_threading_enabled));
553 }
554
556 ConstElementPtr reservations_lookup_first = mutable_cfg->get("reservations-lookup-first");
557 if (reservations_lookup_first) {
558 parameter_name = "reservations-lookup-first";
559 if (multi_threading_enabled) {
561 }
562 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
563 }
564
565 ConstElementPtr hr_identifiers =
566 mutable_cfg->get("host-reservation-identifiers");
567 if (hr_identifiers) {
568 parameter_name = "host-reservation-identifiers";
569 HostReservationIdsParser6 parser(srv_config->getCfgHostOperations6());
570 parser.parse(hr_identifiers);
571 }
572
573 ConstElementPtr server_id = mutable_cfg->get("server-id");
574 if (server_id) {
575 parameter_name = "server-id";
576 DUIDConfigParser parser;
577 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
578 parser.parse(cfg, server_id);
579 }
580
581 ConstElementPtr sanity_checks = mutable_cfg->get("sanity-checks");
582 if (sanity_checks) {
583 parameter_name = "sanity-checks";
584 SanityChecksParser parser;
585 parser.parse(*srv_config, sanity_checks);
586 }
587
588 ConstElementPtr expiration_cfg =
589 mutable_cfg->get("expired-leases-processing");
590 if (expiration_cfg) {
591 parameter_name = "expired-leases-processing";
593 parser.parse(expiration_cfg, CfgMgr::instance().getStagingCfg()->getCfgExpiration());
594 }
595
596 // The hooks-libraries configuration must be parsed after parsing
597 // multi-threading configuration so that libraries are checked
598 // for multi-threading compatibility.
599 ConstElementPtr hooks_libraries = mutable_cfg->get("hooks-libraries");
600 if (hooks_libraries) {
601 parameter_name = "hooks-libraries";
602 HooksLibrariesParser hooks_parser;
603 HooksConfig& libraries = srv_config->getHooksConfig();
604 hooks_parser.parse(libraries, hooks_libraries);
605 libraries.verifyLibraries(hooks_libraries->getPosition(),
606 multi_threading_enabled);
607 }
608
609 // D2 client configuration.
610 D2ClientConfigPtr d2_client_cfg;
611
612 // Legacy DhcpConfigParser stuff below.
613 ConstElementPtr dhcp_ddns = mutable_cfg->get("dhcp-ddns");
614 if (dhcp_ddns) {
615 parameter_name = "dhcp-ddns";
616 // Apply defaults
619 d2_client_cfg = parser.parse(dhcp_ddns);
620 }
621
622 ConstElementPtr client_classes = mutable_cfg->get("client-classes");
623 if (client_classes) {
624 parameter_name = "client-classes";
626 ClientClassDictionaryPtr dictionary =
627 parser.parse(client_classes, AF_INET6);
628 srv_config->setClientClassDictionary(dictionary);
629 }
630
631 // Please move at the end when migration will be finished.
632 ConstElementPtr lease_database = mutable_cfg->get("lease-database");
633 if (lease_database) {
634 parameter_name = "lease-database";
635 db::DbAccessParser parser;
636 std::string access_string;
637 parser.parse(access_string, lease_database);
638 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
639 cfg_db_access->setLeaseDbAccessString(access_string);
640 }
641
642 ConstElementPtr hosts_database = mutable_cfg->get("hosts-database");
643 if (hosts_database) {
644 parameter_name = "hosts-database";
645 db::DbAccessParser parser;
646 std::string access_string;
647 parser.parse(access_string, hosts_database);
648 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
649 cfg_db_access->setHostDbAccessString(access_string);
650 }
651
652 ConstElementPtr hosts_databases = mutable_cfg->get("hosts-databases");
653 if (hosts_databases) {
654 parameter_name = "hosts-databases";
655 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
656 for (auto const& it : hosts_databases->listValue()) {
657 db::DbAccessParser parser;
658 std::string access_string;
659 parser.parse(access_string, it);
660 cfg_db_access->setHostDbAccessString(access_string);
661 }
662 }
663
664 // Keep relative orders of shared networks and subnets.
665 ConstElementPtr shared_networks = mutable_cfg->get("shared-networks");
666 if (shared_networks) {
667 parameter_name = "shared-networks";
674 CfgSharedNetworks6Ptr cfg = srv_config->getCfgSharedNetworks6();
675 parser.parse(cfg, shared_networks);
676
677 // We also need to put the subnets it contains into normal
678 // subnets list.
679 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
680 }
681
682 ConstElementPtr subnet6 = mutable_cfg->get("subnet6");
683 if (subnet6) {
684 parameter_name = "subnet6";
685 Subnets6ListConfigParser subnets_parser;
686 // parse() returns number of subnets parsed. We may log it one day.
687 subnets_parser.parse(srv_config, subnet6);
688 }
689
690 ConstElementPtr reservations = mutable_cfg->get("reservations");
691 if (reservations) {
692 parameter_name = "reservations";
693 HostCollection hosts;
695 parser.parse(SUBNET_ID_GLOBAL, reservations, hosts);
696 for (auto const& h : hosts) {
697 srv_config->getCfgHosts()->add(h);
698 }
699 }
700
701 ConstElementPtr config_control = mutable_cfg->get("config-control");
702 if (config_control) {
703 parameter_name = "config-control";
704 ConfigControlParser parser;
705 ConfigControlInfoPtr config_ctl_info = parser.parse(config_control);
706 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
707 }
708
709 ConstElementPtr rsoo_list = mutable_cfg->get("relay-supplied-options");
710 if (rsoo_list) {
711 parameter_name = "relay-supplied-options";
712 RSOOListConfigParser parser;
713 parser.parse(srv_config, rsoo_list);
714 }
715
716 ConstElementPtr compatibility = mutable_cfg->get("compatibility");
717 if (compatibility) {
718 CompatibilityParser parser;
719 parser.parse(compatibility, *CfgMgr::instance().getStagingCfg());
720 }
721
722 // Make parsers grouping.
723 const std::map<std::string, ConstElementPtr>& values_map =
724 mutable_cfg->mapValue();
725
726 for (auto const& config_pair : values_map) {
727 parameter_name = config_pair.first;
728
729 // These are converted to SimpleParser and are handled already above.
730 if ((config_pair.first == "data-directory") ||
731 (config_pair.first == "option-def") ||
732 (config_pair.first == "option-data") ||
733 (config_pair.first == "mac-sources") ||
734 (config_pair.first == "control-socket") ||
735 (config_pair.first == "control-sockets") ||
736 (config_pair.first == "multi-threading") ||
737 (config_pair.first == "dhcp-queue-control") ||
738 (config_pair.first == "host-reservation-identifiers") ||
739 (config_pair.first == "server-id") ||
740 (config_pair.first == "interfaces-config") ||
741 (config_pair.first == "sanity-checks") ||
742 (config_pair.first == "expired-leases-processing") ||
743 (config_pair.first == "hooks-libraries") ||
744 (config_pair.first == "dhcp-ddns") ||
745 (config_pair.first == "client-classes") ||
746 (config_pair.first == "lease-database") ||
747 (config_pair.first == "hosts-database") ||
748 (config_pair.first == "hosts-databases") ||
749 (config_pair.first == "subnet6") ||
750 (config_pair.first == "shared-networks") ||
751 (config_pair.first == "reservations") ||
752 (config_pair.first == "config-control") ||
753 (config_pair.first == "relay-supplied-options") ||
754 (config_pair.first == "loggers") ||
755 (config_pair.first == "compatibility")) {
756 continue;
757 }
758
759 // As of Kea 1.6.0 we have two ways of inheriting the global parameters.
760 // The old method is used in JSON configuration parsers when the global
761 // parameters are derived into the subnets and shared networks and are
762 // being treated as explicitly specified. The new way used by the config
763 // backend is the dynamic inheritance whereby each subnet and shared
764 // network uses a callback function to return global parameter if it
765 // is not specified at lower level. This callback uses configured globals.
766 // We deliberately include both default and explicitly specified globals
767 // so as the callback can access the appropriate global values regardless
768 // whether they are set to a default or other value.
769 if ( (config_pair.first == "renew-timer") ||
770 (config_pair.first == "rebind-timer") ||
771 (config_pair.first == "preferred-lifetime") ||
772 (config_pair.first == "min-preferred-lifetime") ||
773 (config_pair.first == "max-preferred-lifetime") ||
774 (config_pair.first == "valid-lifetime") ||
775 (config_pair.first == "min-valid-lifetime") ||
776 (config_pair.first == "max-valid-lifetime") ||
777 (config_pair.first == "decline-probation-period") ||
778 (config_pair.first == "dhcp4o6-port") ||
779 (config_pair.first == "server-tag") ||
780 (config_pair.first == "reservations-global") ||
781 (config_pair.first == "reservations-in-subnet") ||
782 (config_pair.first == "reservations-out-of-pool") ||
783 (config_pair.first == "calculate-tee-times") ||
784 (config_pair.first == "t1-percent") ||
785 (config_pair.first == "t2-percent") ||
786 (config_pair.first == "cache-threshold") ||
787 (config_pair.first == "cache-max-age") ||
788 (config_pair.first == "adaptive-lease-time-threshold") ||
789 (config_pair.first == "hostname-char-set") ||
790 (config_pair.first == "hostname-char-replacement") ||
791 (config_pair.first == "ddns-send-updates") ||
792 (config_pair.first == "ddns-override-no-update") ||
793 (config_pair.first == "ddns-override-client-update") ||
794 (config_pair.first == "ddns-replace-client-name") ||
795 (config_pair.first == "ddns-generated-prefix") ||
796 (config_pair.first == "ddns-qualifying-suffix") ||
797 (config_pair.first == "ddns-update-on-renew") ||
798 (config_pair.first == "ddns-use-conflict-resolution") ||
799 (config_pair.first == "ddns-conflict-resolution-mode") ||
800 (config_pair.first == "ddns-ttl-percent") ||
801 (config_pair.first == "store-extended-info") ||
802 (config_pair.first == "statistic-default-sample-count") ||
803 (config_pair.first == "statistic-default-sample-age") ||
804 (config_pair.first == "early-global-reservations-lookup") ||
805 (config_pair.first == "ip-reservations-unique") ||
806 (config_pair.first == "reservations-lookup-first") ||
807 (config_pair.first == "allow-address-registration") ||
808 (config_pair.first == "parked-packet-limit") ||
809 (config_pair.first == "allocator") ||
810 (config_pair.first == "ddns-ttl") ||
811 (config_pair.first == "ddns-ttl-min") ||
812 (config_pair.first == "ddns-ttl-max") ||
813 (config_pair.first == "pd-allocator") ) {
814 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
815 config_pair.second);
816 continue;
817 }
818
819 // Nothing to configure for the user-context.
820 if (config_pair.first == "user-context") {
821 continue;
822 }
823
824 // If we got here, no code handled this parameter, so we bail out.
826 "unsupported global configuration parameter: " << config_pair.first
827 << " (" << config_pair.second->getPosition() << ")");
828 }
829
830 // Reset parameter name.
831 parameter_name = "<post parsing>";
832
833 // Apply global options in the staging config.
834 global_parser.parse(srv_config, mutable_cfg);
835
836 // This method conducts final sanity checks and tweaks. In particular,
837 // it checks that there is no conflict between plain subnets and those
838 // defined as part of shared networks.
839 global_parser.sanityChecks(srv_config, mutable_cfg);
840
841 // Validate D2 client configuration.
842 if (!d2_client_cfg) {
843 d2_client_cfg.reset(new D2ClientConfig());
844 }
845 d2_client_cfg->validateContents();
846 srv_config->setD2ClientConfig(d2_client_cfg);
847 } catch (const isc::Exception& ex) {
849 .arg(parameter_name).arg(ex.what());
851 } catch (...) {
852 // For things like bad_cast in boost::lexical_cast
853 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
854 answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration "
855 "processing error");
856 }
857
858 if (!answer) {
859 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration seems sane. "
860 "Control-socket, hook-libraries, and D2 configuration "
861 "were sanity checked, but not applied.");
862 }
863
864 return (answer);
865}
866
869 bool check_only, bool extra_checks) {
870 if (!config_set) {
872 "Can't parse NULL config");
873 return (answer);
874 }
875
877 .arg(server.redactConfig(config_set)->str());
878
879 // Resource managers usually check for @ref MultiThreadingMgr::isTestMode
880 // value and do not open UNIX or TCP/UDP sockets, lock files, nor do they open
881 // or rotate files, as any of these actions could interfere with a running
882 // process on the same machine.
883 std::unique_ptr<MtTestMode> mt_test_mode;
884 if (check_only) {
885 mt_test_mode.reset(new MtTestMode());
886 }
887
888 auto answer = processDhcp6Config(config_set);
889
890 int status_code = CONTROL_RESULT_SUCCESS;
891 isc::config::parseAnswer(status_code, answer);
892
893 SrvConfigPtr srv_config;
894
895 if (status_code == CONTROL_RESULT_SUCCESS) {
896 if (check_only) {
897 if (extra_checks) {
898 std::ostringstream err;
899 // Configure DHCP packet queueing
900 try {
902 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
903 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET6, qc)) {
905 .arg(IfaceMgr::instance().getPacketQueue6()->getInfoStr());
906 }
907
908 } catch (const std::exception& ex) {
909 err << "Error setting packet queue controls after server reconfiguration: "
910 << ex.what();
912 status_code = CONTROL_RESULT_ERROR;
913 }
914 }
915 } else {
916
917 // Usually unit tests create managers before calling configureDhcp6Server and
918 // do not call ControlledDhcpv6Srv::processConfig.
919 // Runtime code path creates the managers after calling configureDhcp6Server
920 // and they need to be reset just after successful configuration parsing.
921 if (!IfaceMgr::instance().isTestMode()) {
922 // Destroy lease manager before hooks unload.
924
925 // Destroy host manager before hooks unload.
927 }
928
929 // disable multi-threading (it will be applied by new configuration)
930 // this must be done in order to properly handle MT to ST transition
931 // when 'multi-threading' structure is missing from new config and
932 // to properly drop any task items stored in the thread pool which
933 // might reference some handles to loaded hooks, preventing them
934 // from being unloaded.
935 MultiThreadingMgr::instance().apply(false, 0, 0);
936
937 // Close DHCP sockets and remove any existing timers.
939 TimerMgr::instance()->unregisterTimers();
940 server.discardPackets();
941 server.getCBControl()->reset();
942 }
943 }
944
945 // Parsing stage is complete. The current configuration has not been altered.
946 // From this stage on, every error might have irreversible consequences and the
947 // configuration might not be restored to a working state.
948 if (status_code == CONTROL_RESULT_SUCCESS) {
949 string parameter_name;
950 ElementPtr mutable_cfg;
951 try {
952 // Get the staging configuration.
953 srv_config = CfgMgr::instance().getStagingCfg();
954
955 // This is a way to convert ConstElementPtr to ElementPtr.
956 // We need a config that can be edited, because we will insert
957 // default values and will insert derived values as well.
958 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
959
960 ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
961 if (ifaces_config) {
962 parameter_name = "interfaces-config";
963 IfacesConfigParser parser(AF_INET6, check_only);
964 CfgIfacePtr cfg_iface = srv_config->getCfgIface();
965 cfg_iface->reset();
966 parser.parse(cfg_iface, ifaces_config);
967 }
968 } catch (const isc::Exception& ex) {
970 .arg(parameter_name).arg(ex.what());
971 if (!check_only || extra_checks) {
972 status_code = CONTROL_RESULT_FATAL_ERROR;
973 } else {
974 status_code = CONTROL_RESULT_ERROR;
975 }
976 answer = isc::config::createAnswer(status_code, ex.what());
977 } catch (...) {
978 // For things like bad_cast in boost::lexical_cast
979 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
980 if (!check_only || extra_checks) {
981 status_code = CONTROL_RESULT_FATAL_ERROR;
982 } else {
983 status_code = CONTROL_RESULT_ERROR;
984 }
985 answer = isc::config::createAnswer(status_code, "undefined configuration"
986 " processing error");
987 }
988 }
989
990 // So far so good, there was no parsing error so let's commit the
991 // configuration. This will add created subnets and option values into
992 // the server's configuration.
993 // This operation should be exception safe but let's make sure.
994 if (status_code == CONTROL_RESULT_SUCCESS && !check_only) {
995 try {
996
997 // Setup the command channel.
999 } catch (const isc::Exception& ex) {
1001 status_code = CONTROL_RESULT_FATAL_ERROR;
1002 answer = isc::config::createAnswer(status_code, ex.what());
1003 } catch (...) {
1004 // For things like bad_cast in boost::lexical_cast
1006 status_code = CONTROL_RESULT_FATAL_ERROR;
1007 answer = isc::config::createAnswer(status_code, "undefined configuration"
1008 " parsing error");
1009 }
1010 }
1011
1012 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1013 try {
1014 // No need to commit interface names as this is handled by the
1015 // CfgMgr::commit() function.
1016
1017 // Apply the staged D2ClientConfig, used to be done by parser commit
1019 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
1021 } catch (const isc::Exception& ex) {
1023 status_code = CONTROL_RESULT_FATAL_ERROR;
1024 answer = isc::config::createAnswer(status_code, ex.what());
1025 } catch (...) {
1026 // For things like bad_cast in boost::lexical_cast
1028 status_code = CONTROL_RESULT_FATAL_ERROR;
1029 answer = isc::config::createAnswer(status_code, "undefined configuration"
1030 " parsing error");
1031 }
1032 }
1033
1034 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1035 try {
1036 // This occurs last as if it succeeds, there is no easy way to
1037 // revert it. As a result, the failure to commit a subsequent
1038 // change causes problems when trying to roll back.
1040 static_cast<void>(HooksManager::unloadLibraries());
1042 const HooksConfig& libraries =
1043 CfgMgr::instance().getStagingCfg()->getHooksConfig();
1044 bool multi_threading_enabled = true;
1045 uint32_t thread_count = 0;
1046 uint32_t queue_size = 0;
1047 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
1048 multi_threading_enabled, thread_count, queue_size);
1049 libraries.loadLibraries(multi_threading_enabled);
1050 } catch (const isc::Exception& ex) {
1052 status_code = CONTROL_RESULT_FATAL_ERROR;
1053 answer = isc::config::createAnswer(status_code, ex.what());
1054 } catch (...) {
1055 // For things like bad_cast in boost::lexical_cast
1057 status_code = CONTROL_RESULT_FATAL_ERROR;
1058 answer = isc::config::createAnswer(status_code, "undefined configuration"
1059 " parsing error");
1060 }
1061
1062 if (extra_checks && status_code == CONTROL_RESULT_SUCCESS) {
1063 // Re-open lease and host database with new parameters.
1064 try {
1065 // Get the staging configuration.
1066 srv_config = CfgMgr::instance().getStagingCfg();
1067
1068 // Create managers like @ref ControlledDhcpv6Srv::processConfig
1069 // does. No need to change "persist" value here because
1070 // @ref MultiThreadingMgr::isTestMode is used instead.
1071 // This will also make log messages consistent with the checked
1072 // config values.
1073 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
1074 string params = "universe=6";
1075 if (cfg_db->getExtendedInfoTablesEnabled()) {
1076 params += " extended-info-tables=true";
1077 }
1078 cfg_db->setAppendedParameters(params);
1079 cfg_db->createManagers();
1080 } catch (const std::exception& ex) {
1081 status_code = CONTROL_RESULT_FATAL_ERROR;
1082 answer = isc::config::createAnswer(status_code, ex.what());
1083 }
1084 }
1085 }
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 // Log the list of known backends.
1098
1099 // Moved from the commit block to add the config backend indication.
1100 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1101 try {
1102 // If there are config backends, fetch and merge into staging config
1103 server.getCBControl()->databaseConfigFetch(srv_config,
1104 CBControlDHCPv6::FetchMode::FETCH_ALL);
1105 } catch (const isc::Exception& ex) {
1106 std::ostringstream err;
1107 err << "during update from config backend database: " << ex.what();
1109 status_code = CONTROL_RESULT_FATAL_ERROR;
1110 answer = isc::config::createAnswer(status_code, err.str());
1111 } catch (...) {
1112 // For things like bad_cast in boost::lexical_cast
1113 std::ostringstream err;
1114 err << "during update from config backend database: "
1115 << "undefined configuration parsing error";
1117 status_code = CONTROL_RESULT_FATAL_ERROR;
1118 answer = isc::config::createAnswer(status_code, err.str());
1119 }
1120 }
1121
1122 // Rollback changes as the configuration parsing failed.
1123 if (check_only || status_code != CONTROL_RESULT_SUCCESS) {
1124 // Revert to original configuration of runtime option definitions
1125 // in the libdhcp++.
1127
1128 if (status_code == CONTROL_RESULT_SUCCESS && extra_checks) {
1129 auto notify_libraries = ControlledDhcpv6Srv::finishConfigHookLibraries(config_set);
1130 if (notify_libraries) {
1131 return (notify_libraries);
1132 }
1133
1135 try {
1136 // Handle events registered by hooks using external IOService objects.
1138 } catch (const std::exception& ex) {
1139 std::ostringstream err;
1140 err << "Error initializing hooks: "
1141 << ex.what();
1143 }
1144 }
1145
1146 return (answer);
1147 }
1148
1150 .arg(CfgMgr::instance().getStagingCfg()->
1151 getConfigSummary(SrvConfig::CFGSEL_ALL6));
1152
1153 // Also calculate SHA256 hash of the config that was just set and
1154 // append it to the response.
1156 string hash = BaseCommandMgr::getHash(config);
1157 ElementPtr hash_map = Element::createMap();
1158 hash_map->set("hash", Element::create(hash));
1159
1160 // Everything was fine. Configuration is successful.
1161 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration successful.", hash_map);
1162 return (answer);
1163}
1164
1165} // namespace dhcp
1166} // 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.