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