Kea 3.2.0
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
461
462 // Answer will hold the result.
463 ConstElementPtr answer;
464
465 // Global parameter name in case of an error.
466 string parameter_name;
467 ElementPtr mutable_cfg;
468 SrvConfigPtr srv_config;
469 try {
470 // Get the staging configuration.
471 srv_config = CfgMgr::instance().getStagingCfg();
472
473 // This is a way to convert ConstElementPtr to ElementPtr.
474 // We need a config that can be edited, because we will insert
475 // default values and will insert derived values as well.
476 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
477
478 // Set all default values if not specified by the user.
480
481 // And now derive (inherit) global parameters to subnets, if not specified.
483
484 // In principle we could have the following code structured as a series
485 // of long if else if clauses. That would give a marginal performance
486 // boost, but would make the code less readable. We had serious issues
487 // with the parser code debugability, so I decided to keep it as a
488 // series of independent ifs.
489
490 // This parser is used in several places.
491 Dhcp6ConfigParser global_parser;
492
493 // Apply global options in the staging config, e.g. ip-reservations-unique
494 global_parser.parseEarly(srv_config, mutable_cfg);
495
496 // We need definitions first
497 ConstElementPtr option_defs = mutable_cfg->get("option-def");
498 if (option_defs) {
499 parameter_name = "option-def";
500 OptionDefListParser parser(AF_INET6);
501 CfgOptionDefPtr cfg_option_def = srv_config->getCfgOptionDef();
502 parser.parse(cfg_option_def, option_defs);
503 }
504
505 ConstElementPtr option_datas = mutable_cfg->get("option-data");
506 if (option_datas) {
507 parameter_name = "option-data";
508 OptionDataListParser parser(AF_INET6);
509 CfgOptionPtr cfg_option = srv_config->getCfgOption();
510 parser.parse(cfg_option, option_datas);
511 }
512
513 ConstElementPtr mac_sources = mutable_cfg->get("mac-sources");
514 if (mac_sources) {
515 parameter_name = "mac-sources";
517 CfgMACSource& mac_source = srv_config->getMACSources();
518 parser.parse(mac_source, mac_sources);
519 }
520
521 ConstElementPtr control_socket = mutable_cfg->get("control-socket");
522 if (control_socket) {
523 mutable_cfg->remove("control-socket");
525 l->add(UserContext::toElement(control_socket));
526 mutable_cfg->set("control-sockets", l);
527 }
528
529 ConstElementPtr control_sockets = mutable_cfg->get("control-sockets");
530 if (control_sockets) {
531 parameter_name = "control-sockets";
533 parser.parse(*srv_config, control_sockets);
534 }
535
536 ConstElementPtr multi_threading = mutable_cfg->get("multi-threading");
537 if (multi_threading) {
538 parameter_name = "multi-threading";
540 parser.parse(*srv_config, multi_threading);
541 }
542
543 bool multi_threading_enabled = true;
544 uint32_t thread_count = 0;
545 uint32_t queue_size = 0;
546 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
547 multi_threading_enabled, thread_count, queue_size);
548
550 ConstElementPtr queue_control = mutable_cfg->get("dhcp-queue-control");
551 if (queue_control) {
552 parameter_name = "dhcp-queue-control";
554 srv_config->setDHCPQueueControl(parser.parse(queue_control, multi_threading_enabled));
555 }
556
558 ConstElementPtr reservations_lookup_first = mutable_cfg->get("reservations-lookup-first");
559 if (reservations_lookup_first) {
560 parameter_name = "reservations-lookup-first";
561 if (multi_threading_enabled) {
563 }
564 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
565 }
566
567 ConstElementPtr hr_identifiers =
568 mutable_cfg->get("host-reservation-identifiers");
569 if (hr_identifiers) {
570 parameter_name = "host-reservation-identifiers";
571 HostReservationIdsParser6 parser(srv_config->getCfgHostOperations6());
572 parser.parse(hr_identifiers);
573 }
574
575 ConstElementPtr server_id = mutable_cfg->get("server-id");
576 if (server_id) {
577 parameter_name = "server-id";
578 DUIDConfigParser parser;
579 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
580 parser.parse(cfg, server_id);
581 }
582
583 ConstElementPtr sanity_checks = mutable_cfg->get("sanity-checks");
584 if (sanity_checks) {
585 parameter_name = "sanity-checks";
586 SanityChecksParser parser;
587 parser.parse(*srv_config, sanity_checks);
588 }
589
590 ConstElementPtr expiration_cfg =
591 mutable_cfg->get("expired-leases-processing");
592 if (expiration_cfg) {
593 parameter_name = "expired-leases-processing";
595 parser.parse(expiration_cfg, CfgMgr::instance().getStagingCfg()->getCfgExpiration());
596 }
597
598 // The hooks-libraries configuration must be parsed after parsing
599 // multi-threading configuration so that libraries are checked
600 // for multi-threading compatibility.
601 ConstElementPtr hooks_libraries = mutable_cfg->get("hooks-libraries");
602 if (hooks_libraries) {
603 parameter_name = "hooks-libraries";
604 HooksLibrariesParser hooks_parser;
605 HooksConfig& libraries = srv_config->getHooksConfig();
606 hooks_parser.parse(libraries, hooks_libraries);
607 libraries.verifyLibraries(hooks_libraries->getPosition(),
608 multi_threading_enabled);
609 }
610
611 // D2 client configuration.
612 D2ClientConfigPtr d2_client_cfg;
613
614 // Legacy DhcpConfigParser stuff below.
615 ConstElementPtr dhcp_ddns = mutable_cfg->get("dhcp-ddns");
616 if (dhcp_ddns) {
617 parameter_name = "dhcp-ddns";
618 // Apply defaults
621 d2_client_cfg = parser.parse(dhcp_ddns);
622 }
623
624 ConstElementPtr client_classes = mutable_cfg->get("client-classes");
625 if (client_classes) {
626 parameter_name = "client-classes";
628 ClientClassDictionaryPtr dictionary =
629 parser.parse(client_classes, AF_INET6);
630 srv_config->setClientClassDictionary(dictionary);
631 }
632
633 // Please move at the end when migration will be finished.
634 ConstElementPtr lease_database = mutable_cfg->get("lease-database");
635 if (lease_database) {
636 parameter_name = "lease-database";
637 db::DbAccessParser parser;
638 std::string access_string;
639 parser.parse(access_string, lease_database);
640 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
641 cfg_db_access->setLeaseDbAccessString(access_string);
642 }
643
644 ConstElementPtr hosts_database = mutable_cfg->get("hosts-database");
645 if (hosts_database) {
646 parameter_name = "hosts-database";
647 db::DbAccessParser parser;
648 std::string access_string;
649 parser.parse(access_string, hosts_database);
650 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
651 cfg_db_access->setHostDbAccessString(access_string);
652 }
653
654 ConstElementPtr hosts_databases = mutable_cfg->get("hosts-databases");
655 if (hosts_databases) {
656 parameter_name = "hosts-databases";
657 CfgDbAccessPtr cfg_db_access = srv_config->getCfgDbAccess();
658 for (auto const& it : hosts_databases->listValue()) {
659 db::DbAccessParser parser;
660 std::string access_string;
661 parser.parse(access_string, it);
662 cfg_db_access->setHostDbAccessString(access_string);
663 }
664 }
665
666 // Keep relative orders of shared networks and subnets.
667 ConstElementPtr shared_networks = mutable_cfg->get("shared-networks");
668 if (shared_networks) {
669 parameter_name = "shared-networks";
676 CfgSharedNetworks6Ptr cfg = srv_config->getCfgSharedNetworks6();
677 parser.parse(cfg, shared_networks);
678
679 // We also need to put the subnets it contains into normal
680 // subnets list.
681 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
682 }
683
684 ConstElementPtr subnet6 = mutable_cfg->get("subnet6");
685 if (subnet6) {
686 parameter_name = "subnet6";
687 Subnets6ListConfigParser subnets_parser;
688 // parse() returns number of subnets parsed. We may log it one day.
689 subnets_parser.parse(srv_config, subnet6);
690 }
691
692 ConstElementPtr reservations = mutable_cfg->get("reservations");
693 if (reservations) {
694 parameter_name = "reservations";
695 HostCollection hosts;
697 parser.parse(SUBNET_ID_GLOBAL, reservations, hosts);
698 for (auto const& h : hosts) {
699 srv_config->getCfgHosts()->add(h);
700 }
701 }
702
703 ConstElementPtr config_control = mutable_cfg->get("config-control");
704 if (config_control) {
705 parameter_name = "config-control";
706 ConfigControlParser parser;
707 ConfigControlInfoPtr config_ctl_info = parser.parse(config_control);
708 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
709 }
710
711 ConstElementPtr rsoo_list = mutable_cfg->get("relay-supplied-options");
712 if (rsoo_list) {
713 parameter_name = "relay-supplied-options";
714 RSOOListConfigParser parser;
715 parser.parse(srv_config, rsoo_list);
716 }
717
718 ConstElementPtr compatibility = mutable_cfg->get("compatibility");
719 if (compatibility) {
720 CompatibilityParser parser;
721 parser.parse(compatibility, *CfgMgr::instance().getStagingCfg());
722 }
723
724 // Make parsers grouping.
725 const std::map<std::string, ConstElementPtr>& values_map =
726 mutable_cfg->mapValue();
727
728 for (auto const& config_pair : values_map) {
729 parameter_name = config_pair.first;
730
731 // These are converted to SimpleParser and are handled already above.
732 if ((config_pair.first == "data-directory") ||
733 (config_pair.first == "option-def") ||
734 (config_pair.first == "option-data") ||
735 (config_pair.first == "mac-sources") ||
736 (config_pair.first == "control-socket") ||
737 (config_pair.first == "control-sockets") ||
738 (config_pair.first == "multi-threading") ||
739 (config_pair.first == "dhcp-queue-control") ||
740 (config_pair.first == "host-reservation-identifiers") ||
741 (config_pair.first == "server-id") ||
742 (config_pair.first == "interfaces-config") ||
743 (config_pair.first == "sanity-checks") ||
744 (config_pair.first == "expired-leases-processing") ||
745 (config_pair.first == "hooks-libraries") ||
746 (config_pair.first == "dhcp-ddns") ||
747 (config_pair.first == "client-classes") ||
748 (config_pair.first == "lease-database") ||
749 (config_pair.first == "hosts-database") ||
750 (config_pair.first == "hosts-databases") ||
751 (config_pair.first == "subnet6") ||
752 (config_pair.first == "shared-networks") ||
753 (config_pair.first == "reservations") ||
754 (config_pair.first == "config-control") ||
755 (config_pair.first == "relay-supplied-options") ||
756 (config_pair.first == "loggers") ||
757 (config_pair.first == "compatibility")) {
758 continue;
759 }
760
761 // As of Kea 1.6.0 we have two ways of inheriting the global parameters.
762 // The old method is used in JSON configuration parsers when the global
763 // parameters are derived into the subnets and shared networks and are
764 // being treated as explicitly specified. The new way used by the config
765 // backend is the dynamic inheritance whereby each subnet and shared
766 // network uses a callback function to return global parameter if it
767 // is not specified at lower level. This callback uses configured globals.
768 // We deliberately include both default and explicitly specified globals
769 // so as the callback can access the appropriate global values regardless
770 // whether they are set to a default or other value.
771 if ( (config_pair.first == "renew-timer") ||
772 (config_pair.first == "rebind-timer") ||
773 (config_pair.first == "preferred-lifetime") ||
774 (config_pair.first == "min-preferred-lifetime") ||
775 (config_pair.first == "max-preferred-lifetime") ||
776 (config_pair.first == "valid-lifetime") ||
777 (config_pair.first == "min-valid-lifetime") ||
778 (config_pair.first == "max-valid-lifetime") ||
779 (config_pair.first == "decline-probation-period") ||
780 (config_pair.first == "dhcp4o6-port") ||
781 (config_pair.first == "server-tag") ||
782 (config_pair.first == "reservations-global") ||
783 (config_pair.first == "reservations-in-subnet") ||
784 (config_pair.first == "reservations-out-of-pool") ||
785 (config_pair.first == "calculate-tee-times") ||
786 (config_pair.first == "t1-percent") ||
787 (config_pair.first == "t2-percent") ||
788 (config_pair.first == "cache-threshold") ||
789 (config_pair.first == "cache-max-age") ||
790 (config_pair.first == "adaptive-lease-time-threshold") ||
791 (config_pair.first == "hostname-char-set") ||
792 (config_pair.first == "hostname-char-replacement") ||
793 (config_pair.first == "ddns-send-updates") ||
794 (config_pair.first == "ddns-override-no-update") ||
795 (config_pair.first == "ddns-override-client-update") ||
796 (config_pair.first == "ddns-replace-client-name") ||
797 (config_pair.first == "ddns-generated-prefix") ||
798 (config_pair.first == "ddns-qualifying-suffix") ||
799 (config_pair.first == "ddns-update-on-renew") ||
800 (config_pair.first == "ddns-use-conflict-resolution") ||
801 (config_pair.first == "ddns-conflict-resolution-mode") ||
802 (config_pair.first == "ddns-ttl-percent") ||
803 (config_pair.first == "store-extended-info") ||
804 (config_pair.first == "statistic-default-sample-count") ||
805 (config_pair.first == "statistic-default-sample-age") ||
806 (config_pair.first == "early-global-reservations-lookup") ||
807 (config_pair.first == "ip-reservations-unique") ||
808 (config_pair.first == "reservations-lookup-first") ||
809 (config_pair.first == "allow-address-registration") ||
810 (config_pair.first == "parked-packet-limit") ||
811 (config_pair.first == "allocator") ||
812 (config_pair.first == "ddns-ttl") ||
813 (config_pair.first == "ddns-ttl-min") ||
814 (config_pair.first == "ddns-ttl-max") ||
815 (config_pair.first == "pd-allocator") ) {
816 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
817 config_pair.second);
818 continue;
819 }
820
821 // Nothing to configure for the user-context.
822 if (config_pair.first == "user-context") {
823 continue;
824 }
825
826 // If we got here, no code handled this parameter, so we bail out.
828 "unsupported global configuration parameter: " << config_pair.first
829 << " (" << config_pair.second->getPosition() << ")");
830 }
831
832 // Reset parameter name.
833 parameter_name = "<post parsing>";
834
835 // Apply global options in the staging config.
836 global_parser.parse(srv_config, mutable_cfg);
837
838 // This method conducts final sanity checks and tweaks. In particular,
839 // it checks that there is no conflict between plain subnets and those
840 // defined as part of shared networks.
841 global_parser.sanityChecks(srv_config, mutable_cfg);
842
843 // Validate D2 client configuration.
844 if (!d2_client_cfg) {
845 d2_client_cfg.reset(new D2ClientConfig());
846 }
847 d2_client_cfg->validateContents();
848 srv_config->setD2ClientConfig(d2_client_cfg);
849 } catch (const isc::Exception& ex) {
851 .arg(parameter_name).arg(ex.what());
853 } catch (...) {
854 // For things like bad_cast in boost::lexical_cast
855 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
856 answer = isc::config::createAnswer(CONTROL_RESULT_ERROR, "undefined configuration "
857 "processing error");
858 }
859
860 if (!answer) {
861 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration seems sane. "
862 "Control-socket, hook-libraries, and D2 configuration "
863 "were sanity checked, but not applied.");
864 }
865
866 return (answer);
867}
868
871 bool check_only, bool extra_checks) {
872 if (!config_set) {
874 "Can't parse NULL config");
875 return (answer);
876 }
877
879 .arg(server.redactConfig(config_set)->str());
880
881 // Resource managers usually check for @ref MultiThreadingMgr::isTestMode
882 // value and do not open UNIX or TCP/UDP sockets, lock files, nor do they open
883 // or rotate files, as any of these actions could interfere with a running
884 // process on the same machine.
885 std::unique_ptr<MtTestMode> mt_test_mode;
886 if (check_only) {
887 mt_test_mode.reset(new MtTestMode());
888 }
889
890 auto answer = processDhcp6Config(config_set);
891
892 int status_code = CONTROL_RESULT_SUCCESS;
893 isc::config::parseAnswer(status_code, answer);
894
895 SrvConfigPtr srv_config;
896
897 if (status_code == CONTROL_RESULT_SUCCESS) {
898 if (check_only) {
899 if (extra_checks) {
900 std::ostringstream err;
901 // Configure DHCP packet queueing
902 try {
904 qc = CfgMgr::instance().getStagingCfg()->getDHCPQueueControl();
905 if (IfaceMgr::instance().configureDHCPPacketQueue(AF_INET6, qc)) {
907 .arg(IfaceMgr::instance().getPacketQueue6()->getInfoStr());
908 }
909
910 } catch (const std::exception& ex) {
911 err << "Error setting packet queue controls after server reconfiguration: "
912 << ex.what();
914 status_code = CONTROL_RESULT_ERROR;
915 }
916 }
917 } else {
918
919 // Usually unit tests create managers before calling configureDhcp6Server and
920 // do not call ControlledDhcpv6Srv::processConfig.
921 // Runtime code path creates the managers after calling configureDhcp6Server
922 // and they need to be reset just after successful configuration parsing.
923 if (!IfaceMgr::instance().isTestMode()) {
924 // Destroy lease manager before hooks unload.
926
927 // Destroy host manager before hooks unload.
929 }
930
931 // disable multi-threading (it will be applied by new configuration)
932 // this must be done in order to properly handle MT to ST transition
933 // when 'multi-threading' structure is missing from new config and
934 // to properly drop any task items stored in the thread pool which
935 // might reference some handles to loaded hooks, preventing them
936 // from being unloaded.
937 MultiThreadingMgr::instance().apply(false, 0, 0);
938
939 // Close DHCP sockets and remove any existing timers.
941 TimerMgr::instance()->unregisterTimers();
942 server.discardPackets();
943 server.getCBControl()->reset();
944 }
945 }
946
947 // Parsing stage is complete. The current configuration has not been altered.
948 // From this stage on, every error might have irreversible consequences and the
949 // configuration might not be restored to a working state.
950 if (status_code == CONTROL_RESULT_SUCCESS) {
951 string parameter_name;
952 ElementPtr mutable_cfg;
953 try {
954 // Get the staging configuration.
955 srv_config = CfgMgr::instance().getStagingCfg();
956
957 // This is a way to convert ConstElementPtr to ElementPtr.
958 // We need a config that can be edited, because we will insert
959 // default values and will insert derived values as well.
960 mutable_cfg = boost::const_pointer_cast<Element>(config_set);
961
962 ConstElementPtr ifaces_config = mutable_cfg->get("interfaces-config");
963 if (ifaces_config) {
964 parameter_name = "interfaces-config";
965 IfacesConfigParser parser(AF_INET6, check_only);
966 CfgIfacePtr cfg_iface = srv_config->getCfgIface();
967 cfg_iface->reset();
968 parser.parse(cfg_iface, ifaces_config);
969 }
970 } catch (const isc::Exception& ex) {
972 .arg(parameter_name).arg(ex.what());
973 if (!check_only || extra_checks) {
974 status_code = CONTROL_RESULT_FATAL_ERROR;
975 } else {
976 status_code = CONTROL_RESULT_ERROR;
977 }
978 answer = isc::config::createAnswer(status_code, ex.what());
979 } catch (...) {
980 // For things like bad_cast in boost::lexical_cast
981 LOG_ERROR(dhcp6_logger, DHCP6_PARSER_EXCEPTION).arg(parameter_name);
982 if (!check_only || extra_checks) {
983 status_code = CONTROL_RESULT_FATAL_ERROR;
984 } else {
985 status_code = CONTROL_RESULT_ERROR;
986 }
987 answer = isc::config::createAnswer(status_code, "undefined configuration"
988 " processing error");
989 }
990 }
991
992 // So far so good, there was no parsing error so let's commit the
993 // configuration. This will add created subnets and option values into
994 // the server's configuration.
995 // This operation should be exception safe but let's make sure.
996 if (status_code == CONTROL_RESULT_SUCCESS && !check_only) {
997 try {
998
999 // Setup the command channel.
1001 } catch (const isc::Exception& ex) {
1003 status_code = CONTROL_RESULT_FATAL_ERROR;
1004 answer = isc::config::createAnswer(status_code, ex.what());
1005 } catch (...) {
1006 // For things like bad_cast in boost::lexical_cast
1008 status_code = CONTROL_RESULT_FATAL_ERROR;
1009 answer = isc::config::createAnswer(status_code, "undefined configuration"
1010 " parsing error");
1011 }
1012 }
1013
1014 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1015 try {
1016 // No need to commit interface names as this is handled by the
1017 // CfgMgr::commit() function.
1018
1019 // Apply the staged D2ClientConfig, used to be done by parser commit
1021 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
1023 } catch (const isc::Exception& ex) {
1025 status_code = CONTROL_RESULT_FATAL_ERROR;
1026 answer = isc::config::createAnswer(status_code, ex.what());
1027 } catch (...) {
1028 // For things like bad_cast in boost::lexical_cast
1030 status_code = CONTROL_RESULT_FATAL_ERROR;
1031 answer = isc::config::createAnswer(status_code, "undefined configuration"
1032 " parsing error");
1033 }
1034 }
1035
1036 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1037 try {
1038 // This occurs last as if it succeeds, there is no easy way to
1039 // revert it. As a result, the failure to commit a subsequent
1040 // change causes problems when trying to roll back.
1042 static_cast<void>(HooksManager::unloadLibraries());
1044 const HooksConfig& libraries =
1045 CfgMgr::instance().getStagingCfg()->getHooksConfig();
1046 bool multi_threading_enabled = true;
1047 uint32_t thread_count = 0;
1048 uint32_t queue_size = 0;
1049 CfgMultiThreading::extract(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading(),
1050 multi_threading_enabled, thread_count, queue_size);
1051 libraries.loadLibraries(multi_threading_enabled);
1052 } catch (const isc::Exception& ex) {
1054 status_code = CONTROL_RESULT_FATAL_ERROR;
1055 answer = isc::config::createAnswer(status_code, ex.what());
1056 } catch (...) {
1057 // For things like bad_cast in boost::lexical_cast
1059 status_code = CONTROL_RESULT_FATAL_ERROR;
1060 answer = isc::config::createAnswer(status_code, "undefined configuration"
1061 " parsing error");
1062 }
1063
1064 if (extra_checks && status_code == CONTROL_RESULT_SUCCESS) {
1065 // Re-open lease and host database with new parameters.
1066 try {
1067 // Get the staging configuration.
1068 srv_config = CfgMgr::instance().getStagingCfg();
1069
1070 // Create managers like @ref ControlledDhcpv6Srv::processConfig
1071 // does. No need to change "persist" value here because
1072 // @ref MultiThreadingMgr::isTestMode is used instead.
1073 // This will also make log messages consistent with the checked
1074 // config values.
1075 CfgDbAccessPtr cfg_db = CfgMgr::instance().getStagingCfg()->getCfgDbAccess();
1076 string params = "universe=6";
1077 if (cfg_db->getExtendedInfoTablesEnabled()) {
1078 params += " extended-info-tables=true";
1079 }
1080 cfg_db->setAppendedParameters(params);
1081 cfg_db->createManagers();
1082 } catch (const std::exception& ex) {
1083 status_code = CONTROL_RESULT_FATAL_ERROR;
1084 answer = isc::config::createAnswer(status_code, ex.what());
1085 }
1086 }
1087 }
1088
1089 // Log the list of known backends.
1091
1092 // Log the list of known backends.
1094
1095 // Log the list of known backends.
1097
1098 // Log the list of known backends.
1100
1101 // Moved from the commit block to add the config backend indication.
1102 if (status_code == CONTROL_RESULT_SUCCESS && (!check_only || extra_checks)) {
1103 try {
1104 // If there are config backends, fetch and merge into staging config
1105 server.getCBControl()->databaseConfigFetch(srv_config,
1106 CBControlDHCPv6::FetchMode::FETCH_ALL);
1107 } catch (const isc::Exception& ex) {
1108 std::ostringstream err;
1109 err << "during update from config backend database: " << ex.what();
1111 status_code = CONTROL_RESULT_FATAL_ERROR;
1112 answer = isc::config::createAnswer(status_code, err.str());
1113 } catch (...) {
1114 // For things like bad_cast in boost::lexical_cast
1115 std::ostringstream err;
1116 err << "during update from config backend database: "
1117 << "undefined configuration parsing error";
1119 status_code = CONTROL_RESULT_FATAL_ERROR;
1120 answer = isc::config::createAnswer(status_code, err.str());
1121 }
1122 }
1123
1124 // Rollback changes as the configuration parsing failed.
1125 if (check_only || status_code != CONTROL_RESULT_SUCCESS) {
1126 // Revert to original configuration of runtime option definitions
1127 // in the libdhcp++.
1129
1130 if (status_code == CONTROL_RESULT_SUCCESS && extra_checks) {
1131 auto notify_libraries = ControlledDhcpv6Srv::finishConfigHookLibraries(config_set);
1132 if (notify_libraries) {
1133 return (notify_libraries);
1134 }
1135
1137 try {
1138 // Handle events registered by hooks using external IOService objects.
1140 } catch (const std::exception& ex) {
1141 std::ostringstream err;
1142 err << "Error initializing hooks: "
1143 << ex.what();
1145 }
1146 }
1147
1148 return (answer);
1149 }
1150
1152 .arg(CfgMgr::instance().getStagingCfg()->
1153 getConfigSummary(SrvConfig::CFGSEL_ALL6));
1154
1155 // Also calculate SHA256 hash of the config that was just set and
1156 // append it to the response.
1158 string hash = BaseCommandMgr::getHash(config);
1159 ElementPtr hash_map = Element::createMap();
1160 hash_map->set("hash", Element::create(hash));
1161
1162 // Everything was fine. Configuration is successful.
1163 answer = isc::config::createAnswer(CONTROL_RESULT_SUCCESS, "Configuration successful.", hash_map);
1164 return (answer);
1165}
1166
1167} // namespace dhcp
1168} // 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:52
void closeSockets()
Closes all open sockets.
Definition iface_mgr.cc:313
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.
RAII class creating a critical section for the receiver thread.
Definition iface_mgr.h:1867
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:522
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:887
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.