49 #include <boost/algorithm/string.hpp> 50 #include <boost/foreach.hpp> 51 #include <boost/lexical_cast.hpp> 52 #include <boost/scoped_ptr.hpp> 53 #include <boost/shared_ptr.hpp> 58 #include <netinet/in.h> 79 void dirExists(
const string& dir_path) {
81 if (stat(dir_path.c_str(), &statbuf) < 0) {
83 <<
"': " << strerror(errno));
85 if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
111 std::string option_str = source_elem->stringValue();
115 code = boost::lexical_cast<int64_t>(option_str);
119 << option_str <<
"', the option code must be a" 120 " non-negative value");
122 }
else if (code > std::numeric_limits<uint16_t>::max()) {
124 << option_str <<
"', the option code must not be" 125 " greater than '" << std::numeric_limits<uint16_t>::max()
129 }
catch (
const boost::bad_lexical_cast &) {
137 code = def->getCode();
140 " specified option name '" << option_str <<
"'" 141 " while parsing the list of enabled" 142 " relay-supplied-options");
145 cfg->getCfgRSOO()->enable(code);
147 }
catch (
const std::exception& ex) {
183 if (global->contains(
"data-directory")) {
184 CfgMgr::instance().setDataDir(getString(global,
"data-directory"),
189 uint32_t probation_period =
190 getUint32(global,
"decline-probation-period");
191 cfg->setDeclinePeriod(probation_period);
194 uint16_t dhcp4o6_port = getUint16(global,
"dhcp4o6-port");
195 cfg->setDhcp4o6Port(dhcp4o6_port);
200 cfg->setContext(user_context);
204 std::string server_tag = getString(global,
"server-tag");
205 cfg->setServerTag(server_tag);
221 bool ip_reservations_unique = getBoolean(global,
"ip-reservations-unique");
222 cfg->setIPReservationsUnique(ip_reservations_unique);
234 if (!dest || !from) {
246 for (
auto net = networks->begin(); net != networks->end(); ++net) {
257 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
275 cfg->sanityChecksLifetime(
"preferred-lifetime");
276 cfg->sanityChecksLifetime(
"valid-lifetime");
281 sharedNetworksSanityChecks(*networks, global->get(
"shared-networks"));
303 std::set<string> names;
306 for (
auto net = networks.begin(); net != networks.end(); ++net) {
311 string iface = (*net)->getIface();
316 bool rapid_commit =
false;
319 for (
auto subnet = subnets->begin(); subnet != subnets->end(); ++subnet) {
323 if (subnet == subnets->begin()) {
325 rapid_commit = (*subnet)->getRapidCommit();
329 if (rapid_commit != (*subnet)->getRapidCommit()) {
331 "must have the same rapid-commit value. Subnet " 332 << (*subnet)->toText()
333 <<
" has specified rapid-commit " 334 << ( (*subnet)->getRapidCommit() ?
"true" :
"false")
335 <<
", but earlier subnet in the same shared-network" 336 <<
" or the shared-network itself used rapid-commit " 337 << (rapid_commit ?
"true" :
"false"));
342 iface = (*subnet)->getIface();
346 if ((*subnet)->getIface().empty()) {
350 if ((*subnet)->getIface() != iface) {
352 <<
" has specified interface " << (*subnet)->getIface()
353 <<
", but earlier subnet in the same shared-network" 354 <<
" or the shared-network itself used " << iface);
359 txt += (*subnet)->toText() +
" ";
364 if ((*net)->getName().empty()) {
366 << txt <<
" is missing mandatory 'name' parameter");
370 if (names.find((*net)->getName()) != names.end()) {
372 "name " << (*net)->getName() <<
" defined twice.");
374 names.insert((*net)->getName());
395 CfgMgr::instance().getStagingCfg()->getControlSocketInfo();
399 CfgMgr::instance().getCurrentCfg()->getControlSocketInfo();
404 bool sock_changed = (sock_cfg && current_sock_cfg &&
405 !sock_cfg->equals(*current_sock_cfg));
412 if (!sock_cfg || !current_sock_cfg || sock_changed) {
431 string(
"Can't parse NULL config"));
440 Subnet::resetSubnetID();
444 IfaceMgr::instance().closeSockets();
445 TimerMgr::instance()->unregisterTimers();
451 LibDHCP::revertRuntimeOptionDefs();
457 HostDataSourceFactory::printRegistered();
463 bool rollback =
false;
465 string parameter_name;
470 srv_config = CfgMgr::instance().getStagingCfg();
475 mutable_cfg = boost::const_pointer_cast<
Element>(config_set);
481 srv_config->moveDdnsParams(mutable_cfg);
485 BaseNetworkParser::moveReservationMode(mutable_cfg);
488 SimpleParser6::setAllDefaults(mutable_cfg);
491 SimpleParser6::deriveParameters(mutable_cfg);
500 Dhcp6ConfigParser global_parser;
503 global_parser.parseEarly(srv_config, mutable_cfg);
507 if (data_directory) {
508 parameter_name =
"data-directory";
509 dirExists(data_directory->stringValue());
515 parameter_name =
"option-def";
518 parser.
parse(cfg_option_def, option_defs);
523 parameter_name =
"option-data";
526 parser.
parse(cfg_option, option_datas);
531 parameter_name =
"mac-sources";
534 parser.
parse(mac_source, mac_sources);
538 if (control_socket) {
539 parameter_name =
"control-socket";
541 parser.
parse(*srv_config, control_socket);
545 if (multi_threading) {
546 parameter_name =
"multi-threading";
548 parser.
parse(*srv_config, multi_threading);
552 ConstElementPtr queue_control = mutable_cfg->get(
"dhcp-queue-control");
554 parameter_name =
"dhcp-queue-control";
556 srv_config->setDHCPQueueControl(parser.
parse(queue_control));
560 ConstElementPtr reservations_lookup_first = mutable_cfg->get(
"reservations-lookup-first");
561 if (reservations_lookup_first) {
562 parameter_name =
"reservations-lookup-first";
563 if (MultiThreadingMgr::instance().getMode()) {
566 srv_config->setReservationsLookupFirst(reservations_lookup_first->boolValue());
570 mutable_cfg->get(
"host-reservation-identifiers");
571 if (hr_identifiers) {
572 parameter_name =
"host-reservation-identifiers";
574 parser.
parse(hr_identifiers);
579 parameter_name =
"server-id";
581 const CfgDUIDPtr& cfg = srv_config->getCfgDUID();
582 parser.
parse(cfg, server_id);
587 parameter_name =
"interfaces-config";
590 parser.
parse(cfg_iface, ifaces_config);
595 parameter_name =
"sanity-checks";
597 parser.
parse(*srv_config, sanity_checks);
601 mutable_cfg->get(
"expired-leases-processing");
602 if (expiration_cfg) {
603 parameter_name =
"expired-leases-processing";
605 parser.
parse(expiration_cfg);
612 if (hooks_libraries) {
613 parameter_name =
"hooks-libraries";
615 HooksConfig& libraries = srv_config->getHooksConfig();
616 hooks_parser.
parse(libraries, hooks_libraries);
626 parameter_name =
"dhcp-ddns";
628 D2ClientConfigParser::setAllDefaults(dhcp_ddns);
630 d2_client_cfg = parser.
parse(dhcp_ddns);
634 if (client_classes) {
635 parameter_name =
"client-classes";
638 parser.
parse(client_classes, AF_INET6);
639 srv_config->setClientClassDictionary(dictionary);
644 if (lease_database) {
645 parameter_name =
"lease-database";
647 std::string access_string;
648 parser.
parse(access_string, lease_database);
650 cfg_db_access->setLeaseDbAccessString(access_string);
654 if (hosts_database) {
655 parameter_name =
"hosts-database";
657 std::string access_string;
658 parser.
parse(access_string, hosts_database);
660 cfg_db_access->setHostDbAccessString(access_string);
664 if (hosts_databases) {
665 parameter_name =
"hosts-databases";
667 for (
auto it : hosts_databases->listValue()) {
669 std::string access_string;
670 parser.
parse(access_string, it);
671 cfg_db_access->setHostDbAccessString(access_string);
677 if (shared_networks) {
678 parameter_name =
"shared-networks";
686 parser.
parse(cfg, shared_networks);
690 global_parser.copySubnets6(srv_config->getCfgSubnets6(), cfg);
695 parameter_name =
"subnet6";
698 subnets_parser.
parse(srv_config, subnet6);
703 parameter_name =
"reservations";
706 parser.
parse(SUBNET_ID_GLOBAL, reservations, hosts);
707 for (
auto h = hosts.begin(); h != hosts.end(); ++h) {
708 srv_config->getCfgHosts()->add(*h);
713 if (config_control) {
714 parameter_name =
"config-control";
717 CfgMgr::instance().getStagingCfg()->setConfigControlInfo(config_ctl_info);
720 ConstElementPtr rsoo_list = mutable_cfg->get(
"relay-supplied-options");
722 parameter_name =
"relay-supplied-options";
723 RSOOListConfigParser parser;
724 parser.parse(srv_config, rsoo_list);
729 for (
auto kv : compatibility->mapValue()) {
730 if (kv.first ==
"lenient-option-parsing") {
731 CfgMgr::instance().getStagingCfg()->setLenientOptionParsing(
732 kv.second->boolValue());
739 const std::map<std::string, ConstElementPtr>& values_map =
740 mutable_cfg->mapValue();
742 BOOST_FOREACH(config_pair, values_map) {
744 parameter_name = config_pair.first;
747 if ((config_pair.first ==
"data-directory") ||
748 (config_pair.first ==
"option-def") ||
749 (config_pair.first ==
"option-data") ||
750 (config_pair.first ==
"mac-sources") ||
751 (config_pair.first ==
"control-socket") ||
752 (config_pair.first ==
"multi-threading") ||
753 (config_pair.first ==
"dhcp-queue-control") ||
754 (config_pair.first ==
"host-reservation-identifiers") ||
755 (config_pair.first ==
"server-id") ||
756 (config_pair.first ==
"interfaces-config") ||
757 (config_pair.first ==
"sanity-checks") ||
758 (config_pair.first ==
"expired-leases-processing") ||
759 (config_pair.first ==
"hooks-libraries") ||
760 (config_pair.first ==
"dhcp-ddns") ||
761 (config_pair.first ==
"client-classes") ||
762 (config_pair.first ==
"lease-database") ||
763 (config_pair.first ==
"hosts-database") ||
764 (config_pair.first ==
"hosts-databases") ||
765 (config_pair.first ==
"subnet6") ||
766 (config_pair.first ==
"shared-networks") ||
767 (config_pair.first ==
"reservations") ||
768 (config_pair.first ==
"config-control") ||
769 (config_pair.first ==
"relay-supplied-options") ||
770 (config_pair.first ==
"loggers") ||
771 (config_pair.first ==
"compatibility")) {
785 if ( (config_pair.first ==
"renew-timer") ||
786 (config_pair.first ==
"rebind-timer") ||
787 (config_pair.first ==
"preferred-lifetime") ||
788 (config_pair.first ==
"min-preferred-lifetime") ||
789 (config_pair.first ==
"max-preferred-lifetime") ||
790 (config_pair.first ==
"valid-lifetime") ||
791 (config_pair.first ==
"min-valid-lifetime") ||
792 (config_pair.first ==
"max-valid-lifetime") ||
793 (config_pair.first ==
"decline-probation-period") ||
794 (config_pair.first ==
"dhcp4o6-port") ||
795 (config_pair.first ==
"server-tag") ||
796 (config_pair.first ==
"reservation-mode") ||
797 (config_pair.first ==
"reservations-global") ||
798 (config_pair.first ==
"reservations-in-subnet") ||
799 (config_pair.first ==
"reservations-out-of-pool") ||
800 (config_pair.first ==
"calculate-tee-times") ||
801 (config_pair.first ==
"t1-percent") ||
802 (config_pair.first ==
"t2-percent") ||
803 (config_pair.first ==
"cache-threshold") ||
804 (config_pair.first ==
"cache-max-age") ||
805 (config_pair.first ==
"hostname-char-set") ||
806 (config_pair.first ==
"hostname-char-replacement") ||
807 (config_pair.first ==
"ddns-send-updates") ||
808 (config_pair.first ==
"ddns-override-no-update") ||
809 (config_pair.first ==
"ddns-override-client-update") ||
810 (config_pair.first ==
"ddns-replace-client-name") ||
811 (config_pair.first ==
"ddns-generated-prefix") ||
812 (config_pair.first ==
"ddns-qualifying-suffix") ||
813 (config_pair.first ==
"ddns-update-on-renew") ||
814 (config_pair.first ==
"ddns-use-conflict-resolution") ||
815 (config_pair.first ==
"store-extended-info") ||
816 (config_pair.first ==
"statistic-default-sample-count") ||
817 (config_pair.first ==
"statistic-default-sample-age") ||
818 (config_pair.first ==
"early-global-reservations-lookup") ||
819 (config_pair.first ==
"ip-reservations-unique") ||
820 (config_pair.first ==
"reservations-lookup-first") ||
821 (config_pair.first ==
"parked-packet-limit") ||
822 (config_pair.first ==
"allocator") ||
823 (config_pair.first ==
"pd-allocator") ) {
824 CfgMgr::instance().getStagingCfg()->addConfiguredGlobal(config_pair.first,
830 if (config_pair.first ==
"user-context") {
836 "unsupported global configuration parameter: " << config_pair.first
837 <<
" (" << config_pair.second->getPosition() <<
")");
841 parameter_name =
"<post parsing>";
844 global_parser.parse(srv_config, mutable_cfg);
849 global_parser.sanityChecks(srv_config, mutable_cfg);
852 if (!d2_client_cfg) {
855 d2_client_cfg->validateContents();
856 srv_config->setD2ClientConfig(d2_client_cfg);
859 .arg(parameter_name).arg(ex.
what());
868 " processing error");
878 "Configuration seems sane. Control-socket, hook-libraries, and D2 " 879 "configuration were sanity checked, but not applied.");
898 cfg = CfgMgr::instance().getStagingCfg()->getD2ClientConfig();
899 CfgMgr::instance().setD2ClientConfig(cfg);
904 HooksManager::prepareUnloadLibraries();
905 static_cast<void>(HooksManager::unloadLibraries());
907 CfgMgr::instance().getStagingCfg()->getHooksConfig();
932 CBControlDHCPv6::FetchMode::FETCH_ALL);
934 std::ostringstream err;
935 err <<
"during update from config backend database: " << ex.
what();
943 std::ostringstream err;
944 err <<
"during update from config backend database: " 945 <<
"undefined configuration parsing error";
958 LibDHCP::revertRuntimeOptionDefs();
963 .arg(CfgMgr::instance().getStagingCfg()->
964 getConfigSummary(SrvConfig::CFGSEL_ALL6));
void parse(isc::data::ConstElementPtr expiration_config)
Parses parameters in the JSON map, pertaining to the processing of the expired leases.
Parser for the configuration of DHCP packet queue controls.
std::pair< std::string, isc::data::ConstElementPtr > ConfigPair
Combination of parameter name and configuration contents.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
boost::shared_ptr< CfgSharedNetworks6 > CfgSharedNetworks6Ptr
Pointer to the configuration of IPv6 shared networks.
void parse(const CfgOptionPtr &cfg, isc::data::ConstElementPtr option_data_list)
Parses a list of options, instantiates them and stores in cfg.
D2ClientConfigPtr parse(isc::data::ConstElementPtr d2_client_cfg)
Parses a given dhcp-ddns element into D2ClientConfig.
Parser for hooks library list.
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
this class parses a list of DHCP6 subnets
void parse(const CfgDUIDPtr &cfg, isc::data::ConstElementPtr duid_configuration)
Parses DUID configuration.
Parse Database Parameters.
isc::data::ConstElementPtr configureDhcp6Server(Dhcpv6Srv &server, isc::data::ConstElementPtr config_set, bool check_only)
Configures DHCPv6 server.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
ConstElementPtr createAnswer(const int status_code, const std::string &text, const ConstElementPtr &arg)
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
const isc::log::MessageID DHCP6_CONFIG_START
CBControlDHCPv6Ptr getCBControl() const
Returns an object which controls access to the configuration backends.
Parser for a list of host identifiers for DHCPv6.
Parser for the configuration parameters pertaining to the processing of expired leases.
boost::shared_ptr< SrvConfig > SrvConfigPtr
Non-const pointer to the SrvConfig.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
boost::shared_ptr< Element > ElementPtr
boost::shared_ptr< CfgIface > CfgIfacePtr
A pointer to the CfgIface .
std::vector< HostPtr > HostCollection
Collection of the Host objects.
Wrapper class that holds hooks libraries configuration.
data::ElementPtr parse(const isc::data::ConstElementPtr &control_elem)
Parses content of the "dhcp-queue-control".
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
Parser for D2ClientConfig.
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure.
Parser for the configuration of interfaces.
Class of option definition space container.
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 parse(isc::data::ConstElementPtr ids_list)
Parses a list of host identifiers.
parser for MAC/hardware acquisition sources
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
Parser for server DUID configuration.
Parsers for client class definitions.
Implements parser for config control information, "config-control".
Wrapper class that holds MAC/hardware address sources.
boost::shared_ptr< CfgDbAccess > CfgDbAccessPtr
A pointer to the CfgDbAccess.
const int DBG_DHCP6_COMMAND
Debug level used to log receiving commands.
To be removed. Please use ConfigError instead.
Acts as a storage vault for D2 client configuration.
void closeCommandSocket()
Shuts down any open control sockets.
boost::shared_ptr< ClientClassDictionary > ClientClassDictionaryPtr
Defines a pointer to a ClientClassDictionary.
Parser for a list of shared networks.
const isc::log::MessageID DHCP6_PARSER_COMMIT_FAIL
boost::shared_ptr< const Element > ConstElementPtr
void verifyLibraries(const isc::data::Element::Position &position) const
Verifies that libraries stored in libraries_ are valid.
Parser for option data values within a subnet.
boost::shared_ptr< CfgSubnets6 > CfgSubnets6Ptr
Non-const pointer.
Parser for a list of option definitions.
void loadLibraries() const
Commits hooks libraries configuration.
isc::data::ConstElementPtr redactConfig(isc::data::ConstElementPtr const &config)
Redact a configuration.
void parse(CfgMACSource &mac_sources, isc::data::ConstElementPtr value)
parses parameters value
void parse(const CfgIfacePtr &config, const isc::data::ConstElementPtr &values)
Parses content of the "interfaces-config".
Simple parser for sanity-checks structure.
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.
void discardPackets()
Discards parked packets Clears the packet parking lots of all packets.
void configureCommandChannel()
Initialize the command channel based on the staging configuration.
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.
size_t parse(SrvConfigPtr cfg, data::ConstElementPtr subnets_list)
parses contents of the list
ConfigControlInfoPtr parse(const data::ConstElementPtr &config_control)
Parses a configuration control Element.
const isc::log::MessageID DHCP6_CONFIG_COMPLETE
This is a base class for exceptions thrown from the DNS library module.
void openCommandSocket(const isc::data::ConstElementPtr &socket_info)
Opens control socket with parameters specified in socket_info.
Defines the logger used by the top-level component of kea-lfc.
void parse(SrvConfig &srv_cfg, isc::data::ConstElementPtr value)
"Parses" control-socket structure
Logging initialization functions.
ClientClassDictionaryPtr parse(isc::data::ConstElementPtr class_def_list, uint16_t family, bool check_dependencies=true)
Parse configuration entries.
This file contains several functions and constants that are used for handling commands and responses ...
#define DHCP6_OPTION_SPACE
void parse(CfgSharedNetworksTypePtr &cfg, const data::ConstElementPtr &shared_networks_list_data)
Parses a list of shared networks.
The Element class represents a piece of data, used by the command channel and configuration parts...
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
Parser for a list of host reservations for a subnet.
void parse(SrvConfig &srv_cfg, const isc::data::ConstElementPtr &value)
parses JSON structure
void parse(CfgOptionDefPtr cfg, isc::data::ConstElementPtr def_list)
Parses a list of option definitions, create them and store in cfg.
Parser for the control-socket structure.
boost::shared_ptr< CfgDUID > CfgDUIDPtr
Pointer to the Non-const object.
const isc::log::MessageID DHCP6_PARSER_COMMIT_EXCEPTION
boost::shared_ptr< D2ClientConfig > D2ClientConfigPtr
Defines a pointer for D2ClientConfig instances.
boost::shared_ptr< ConfigControlInfo > ConfigControlInfoPtr
Defines a pointer to a ConfigControlInfo.
const isc::log::MessageID DHCP6_PARSER_FAIL
Simple parser for multi-threading structure.
void parse(std::string &access_string, isc::data::ConstElementPtr database_config)
Parse configuration value.
void parse(HooksConfig &libraries, isc::data::ConstElementPtr value)
Parses parameters value.
Parser for a list of client class definitions.
isc::log::Logger dhcp6_logger(DHCP6_APP_LOGGER_NAME)
Base logger for DHCPv6 server.
static CommandMgr & instance()
CommandMgr is a singleton class.
const isc::log::MessageID DHCP6_RESERVATIONS_LOOKUP_FIRST_ENABLED
const isc::log::MessageID DHCP6_PARSER_EXCEPTION