summaryrefslogtreecommitdiffstats
path: root/src/lib/yang/translator_config.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:15:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 12:15:43 +0000
commitf5f56e1a1c4d9e9496fcb9d81131066a964ccd23 (patch)
tree49e44c6f87febed37efb953ab5485aa49f6481a7 /src/lib/yang/translator_config.cc
parentInitial commit. (diff)
downloadisc-kea-f5f56e1a1c4d9e9496fcb9d81131066a964ccd23.tar.xz
isc-kea-f5f56e1a1c4d9e9496fcb9d81131066a964ccd23.zip
Adding upstream version 2.4.1.upstream/2.4.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/yang/translator_config.cc')
-rw-r--r--src/lib/yang/translator_config.cc759
1 files changed, 759 insertions, 0 deletions
diff --git a/src/lib/yang/translator_config.cc b/src/lib/yang/translator_config.cc
new file mode 100644
index 0000000..4c2c6b8
--- /dev/null
+++ b/src/lib/yang/translator_config.cc
@@ -0,0 +1,759 @@
+// Copyright (C) 2018-2023 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+
+#include <yang/adaptor_config.h>
+#include <yang/translator_config.h>
+#include <yang/yang_models.h>
+
+#include <sstream>
+
+using namespace std;
+using namespace isc::data;
+using namespace libyang;
+using namespace sysrepo;
+
+namespace isc {
+namespace yang {
+
+TranslatorConfig::TranslatorConfig(Session session, const string& model)
+ : Translator(session, model),
+ TranslatorControlSocket(session, model),
+ TranslatorDatabase(session, model),
+ TranslatorDatabases(session, model),
+ TranslatorOptionData(session, model),
+ TranslatorOptionDataList(session, model),
+ TranslatorOptionDef(session, model),
+ TranslatorOptionDefList(session, model),
+ TranslatorClass(session, model),
+ TranslatorClasses(session, model),
+ TranslatorPool(session, model),
+ TranslatorPools(session, model),
+ TranslatorPdPool(session, model),
+ TranslatorPdPools(session, model),
+ TranslatorHost(session, model),
+ TranslatorHosts(session, model),
+ TranslatorSubnet(session, model),
+ TranslatorSubnets(session, model),
+ TranslatorSharedNetwork(session, model),
+ TranslatorSharedNetworks(session, model),
+ TranslatorLogger(session, model),
+ TranslatorLoggers(session, model) {
+}
+
+ElementPtr
+TranslatorConfig::getConfig() {
+ try {
+ if (model_ == IETF_DHCPV6_SERVER) {
+ return (getConfigIetf6());
+ } else if (model_ == KEA_DHCP4_SERVER) {
+ return (getConfigKea4());
+ } else if (model_ == KEA_DHCP6_SERVER) {
+ return (getConfigKea6());
+ }
+ } catch (Error const& ex) {
+ isc_throw(NetconfError, "getting config: " << ex.what());
+ }
+ isc_throw(NotImplemented,
+ "getConfig not implemented for the model: " << model_);
+}
+
+ElementPtr
+TranslatorConfig::getConfigIetf6() {
+ ElementPtr result = Element::createMap();
+ ElementPtr dhcp6 = Element::createMap();
+ result->set("Dhcp6", dhcp6);
+ string const xpath("/ietf-dhcpv6-server:server");
+ optional<DataNode> config;
+ try {
+ config = findXPath(xpath);
+ } catch (NetconfError const&) {
+ return result;
+ }
+
+ checkAndGetDiverging(dhcp6, *config, "subnet6", "server-config/network-ranges",
+ [&](DataNode const& data_node) -> ElementPtr const {
+ return getSubnets(data_node);
+ });
+
+ // Skip everything else.
+ return (result);
+}
+
+ElementPtr
+TranslatorConfig::getConfigKea4() {
+ ElementPtr result = Element::createMap();
+ ElementPtr dhcp = getServerKeaDhcp4();
+ result->set("Dhcp4", dhcp);
+ return (result);
+}
+
+ElementPtr
+TranslatorConfig::getConfigKea6() {
+ ElementPtr result = Element::createMap();
+ ElementPtr dhcp = getServerKeaDhcp6();
+ result->set("Dhcp6", dhcp);
+ return (result);
+}
+
+ElementPtr TranslatorConfig::getHook(DataNode const& data_node) {
+ ElementPtr hook_library(Element::createMap());
+ checkAndGetLeaf(hook_library, data_node, "library");
+ checkAndGetAndJsonifyLeaf(hook_library, data_node, "parameters");
+ return hook_library;
+}
+
+ElementPtr
+TranslatorConfig::getHooksKea(DataNode const& data_node) {
+ return getList(data_node, "hook-library", *this, &TranslatorConfig::getHook);
+}
+
+isc::data::ElementPtr
+TranslatorConfig::getExpiredKea(DataNode const& data_node) {
+ ElementPtr result = Element::createMap();
+
+ checkAndGetLeaf(result, data_node, "flush-reclaimed-timer-wait-time");
+ checkAndGetLeaf(result, data_node, "hold-reclaimed-time");
+ checkAndGetLeaf(result, data_node, "max-reclaim-leases");
+ checkAndGetLeaf(result, data_node, "max-reclaim-time");
+ checkAndGetLeaf(result, data_node, "reclaim-timer-wait-time");
+ checkAndGetLeaf(result, data_node, "unwarned-reclaim-cycles");
+
+ return (result->empty() ? ElementPtr() : result);
+}
+
+isc::data::ElementPtr
+TranslatorConfig::getDdnsKea(DataNode const& data_node) {
+ ElementPtr result(Element::createMap());
+
+ checkAndGetLeaf(result, data_node, "enable-updates");
+ checkAndGetLeaf(result, data_node, "generated-prefix");
+ checkAndGetLeaf(result, data_node, "hostname-char-replacement");
+ checkAndGetLeaf(result, data_node, "hostname-char-set");
+ checkAndGetLeaf(result, data_node, "max-queue-size");
+ checkAndGetLeaf(result, data_node, "ncr-format");
+ checkAndGetLeaf(result, data_node, "ncr-protocol");
+ checkAndGetLeaf(result, data_node, "qualifying-suffix");
+ checkAndGetLeaf(result, data_node, "override-client-update");
+ checkAndGetLeaf(result, data_node, "override-no-update");
+ checkAndGetLeaf(result, data_node, "replace-client-name");
+ checkAndGetLeaf(result, data_node, "sender-ip");
+ checkAndGetLeaf(result, data_node, "sender-port");
+ checkAndGetLeaf(result, data_node, "server-ip");
+ checkAndGetLeaf(result, data_node, "server-port");
+
+ checkAndGetAndJsonifyLeaf(result, data_node, "user-context");
+
+ return (result->empty() ? ElementPtr() : result);
+}
+
+ElementPtr
+TranslatorConfig::getConfigControlKea(DataNode const& data_node) {
+ ElementPtr result(Element::createMap());
+ checkAndGetLeaf(result, data_node, "config-fetch-wait-time");
+ ConstElementPtr databases = getDatabases(data_node, "config-database");
+ if (databases && !databases->empty()) {
+ result->set("config-databases", databases);
+ }
+ return (result->empty() ? ElementPtr() : result);
+}
+
+ElementPtr
+TranslatorConfig::getInterfacesKea(DataNode const& config) {
+ ElementPtr result;
+ optional<DataNode> const& interfaces_config_optional(config.findPath("interfaces-config"));
+ if (interfaces_config_optional) {
+ DataNode const interfaces_config(*interfaces_config_optional);
+ result = Element::createMap();
+
+ checkAndGetLeaf(result, interfaces_config, "dhcp-socket-type");
+ checkAndGetLeaf(result, interfaces_config, "interfaces");
+ checkAndGetLeaf(result, interfaces_config, "outbound-interface");
+ checkAndGetLeaf(result, interfaces_config, "re-detect");
+ checkAndGetLeaf(result, interfaces_config, "service-sockets-max-retries");
+ checkAndGetLeaf(result, interfaces_config, "service-sockets-require-all");
+ checkAndGetLeaf(result, interfaces_config, "service-sockets-retry-wait-time");
+
+ checkAndGetAndJsonifyLeaf(result, interfaces_config, "user-context");
+ }
+ return (result->empty() ? ElementPtr() : result);
+}
+
+ElementPtr
+TranslatorConfig::getServerKeaDhcpCommon(DataNode const& data_node) {
+ ElementPtr result = Element::createMap();
+
+ checkAndGetLeaf(result, data_node, "allocator");
+ checkAndGetLeaf(result, data_node, "cache-max-age");
+ checkAndGetLeaf(result, data_node, "cache-threshold");
+ checkAndGetLeaf(result, data_node, "calculate-tee-times");
+ checkAndGetLeaf(result, data_node, "dhcp4o6-port");
+ checkAndGetLeaf(result, data_node, "ddns-generated-prefix");
+ checkAndGetLeaf(result, data_node, "ddns-override-client-update");
+ checkAndGetLeaf(result, data_node, "ddns-override-no-update");
+ checkAndGetLeaf(result, data_node, "ddns-qualifying-suffix");
+ checkAndGetLeaf(result, data_node, "ddns-replace-client-name");
+ checkAndGetLeaf(result, data_node, "ddns-send-updates");
+ checkAndGetLeaf(result, data_node, "ddns-ttl-percent");
+ checkAndGetLeaf(result, data_node, "ddns-update-on-renew");
+ checkAndGetLeaf(result, data_node, "ddns-use-conflict-resolution");
+ checkAndGetLeaf(result, data_node, "decline-probation-period");
+ checkAndGetLeaf(result, data_node, "early-global-reservations-lookup");
+ checkAndGetLeaf(result, data_node, "host-reservation-identifiers");
+ checkAndGetLeaf(result, data_node, "hostname-char-replacement");
+ checkAndGetLeaf(result, data_node, "hostname-char-set");
+ checkAndGetLeaf(result, data_node, "ip-reservations-unique");
+ checkAndGetLeaf(result, data_node, "max-valid-lifetime");
+ checkAndGetLeaf(result, data_node, "min-valid-lifetime");
+ checkAndGetLeaf(result, data_node, "parked-packet-limit");
+ checkAndGetLeaf(result, data_node, "rebind-timer");
+ checkAndGetLeaf(result, data_node, "renew-timer");
+ checkAndGetLeaf(result, data_node, "reservation-mode");
+ checkAndGetLeaf(result, data_node, "reservations-global");
+ checkAndGetLeaf(result, data_node, "reservations-in-subnet");
+ checkAndGetLeaf(result, data_node, "reservations-lookup-first");
+ checkAndGetLeaf(result, data_node, "reservations-out-of-pool");
+ checkAndGetLeaf(result, data_node, "server-tag");
+ checkAndGetLeaf(result, data_node, "statistic-default-sample-age");
+ checkAndGetLeaf(result, data_node, "statistic-default-sample-count");
+ checkAndGetLeaf(result, data_node, "store-extended-info");
+ checkAndGetLeaf(result, data_node, "t1-percent");
+ checkAndGetLeaf(result, data_node, "t2-percent");
+ checkAndGetLeaf(result, data_node, "valid-lifetime");
+
+ checkAndGetAndJsonifyLeaf(result, data_node, "dhcp-queue-control");
+ checkAndGetAndJsonifyLeaf(result, data_node, "user-context");
+
+ ConstElementPtr classes = getClasses(data_node);
+ if (classes && !classes->empty()) {
+ result->set("client-classes", classes);
+ }
+
+ checkAndGet(result, data_node, "compatibility",
+ [&](DataNode const& node) -> ElementPtr const {
+ ElementPtr compatibility(Element::createMap());
+ checkAndGetLeaf(compatibility, node, "ignore-rai-link-selection");
+ checkAndGetLeaf(compatibility, node, "lenient-option-parsing");
+ return compatibility;
+ });
+
+ checkAndGet(result, data_node, "config-control",
+ [&](DataNode const& node) -> ElementPtr const {
+ return getConfigControlKea(node);
+ });
+
+ checkAndGet(result, data_node, "control-socket",
+ [&](DataNode const& node) -> ElementPtr const {
+ return getControlSocket(node);
+ });
+
+ checkAndGet(result, data_node, "dhcp-ddns",
+ [&](DataNode const& node) -> ElementPtr const {
+ return getDdnsKea(node);
+ });
+
+ checkAndGet(result, data_node, "expired-leases-processing",
+ [&](DataNode const& node) -> ElementPtr const {
+ return getExpiredKea(node);
+ });
+
+ ConstElementPtr hooks = getHooksKea(data_node);
+ if (hooks && !hooks->empty()) {
+ result->set("hooks-libraries", hooks);
+ }
+
+ ConstElementPtr const& hosts_databases(getDatabases(data_node, "hosts-database"));
+ if (hosts_databases && !hosts_databases->empty()) {
+ result->set("hosts-databases", hosts_databases);
+ }
+
+ checkAndGet(result, data_node, "lease-database",
+ [&](DataNode const& node) -> ElementPtr const {
+ return getDatabase(node);
+ });
+
+ ConstElementPtr loggers = getLoggers(data_node);
+ if (loggers && !loggers->empty()) {
+ result->set("loggers", loggers);
+ }
+
+ checkAndGet(result, data_node, "multi-threading",
+ [&](DataNode const& node) -> ElementPtr const {
+ ElementPtr multi_threading(Element::createMap());
+ checkAndGetLeaf(multi_threading, node, "enable-multi-threading");
+ checkAndGetLeaf(multi_threading, node, "packet-queue-size");
+ checkAndGetLeaf(multi_threading, node, "thread-pool-size");
+ return multi_threading;
+ });
+
+ ConstElementPtr options = getOptionDataList(data_node);
+ if (options) {
+ result->set("option-data", options);
+ }
+
+ ConstElementPtr defs = getOptionDefList(data_node);
+ if (defs) {
+ result->set("option-def", defs);
+ }
+
+ ConstElementPtr hosts = getHosts(data_node);
+ if (hosts) {
+ result->set("reservations", hosts);
+ }
+
+ ConstElementPtr networks = getSharedNetworks(data_node);
+ if (networks) {
+ result->set("shared-networks", networks);
+ }
+
+ checkAndGet(result, data_node, "sanity-checks",
+ [&](DataNode const& node) -> ElementPtr const {
+ ElementPtr sanity_checks = Element::createMap();
+ checkAndGetLeaf(sanity_checks, node, "extended-info-checks");
+ checkAndGetLeaf(sanity_checks, node, "lease-checks");
+ return sanity_checks;
+ });
+
+ return (result);
+}
+
+ElementPtr
+TranslatorConfig::getServerKeaDhcp4() {
+ string xpath = "/kea-dhcp4-server:config";
+ optional<DataNode> config_optional;
+ try {
+ config_optional = findXPath(xpath);
+ } catch (NetconfError const&) {
+ return ElementPtr();
+ }
+ DataNode const config(*config_optional);
+ ElementPtr result = getServerKeaDhcpCommon(config);
+
+ // Handle DHCPv4 specific global parameters.
+ checkAndGetLeaf(result, config, "authoritative");
+ checkAndGetLeaf(result, config, "boot-file-name");
+ checkAndGetLeaf(result, config, "echo-client-id");
+ checkAndGetLeaf(result, config, "match-client-id");
+ checkAndGetLeaf(result, config, "next-server");
+ checkAndGetLeaf(result, config, "offer-lifetime");
+ checkAndGetLeaf(result, config, "server-hostname");
+
+ checkAndGet(result, config, "compatibility",
+ [&](DataNode const& node) -> ElementPtr const {
+ // If it exists, add to the existing compatibility map created in getServerKeaDhcpCommon.
+ ConstElementPtr const_compatibility(result->get("compatibility"));
+ ElementPtr compatibility;
+ if (const_compatibility) {
+ compatibility = copy(const_compatibility);
+ } else {
+ compatibility = Element::createMap();
+ }
+
+ checkAndGetLeaf(compatibility, node, "exclude-first-last-24");
+ checkAndGetLeaf(compatibility, node, "ignore-dhcp-server-identifier");
+ return compatibility;
+ });
+
+ // Handle interfaces.
+ ElementPtr interfaces_config(getInterfacesKea(config));
+ if (interfaces_config) {
+ result->set("interfaces-config", interfaces_config);
+ }
+
+ // Handle subnets.
+ ConstElementPtr subnets = getSubnets(config);
+ if (subnets) {
+ result->set("subnet4", subnets);
+ }
+
+ return (result);
+}
+
+ElementPtr
+TranslatorConfig::getServerKeaDhcp6() {
+ string xpath = "/kea-dhcp6-server:config";
+ optional<DataNode> config_optional;
+ try {
+ config_optional = findXPath(xpath);
+ } catch (NetconfError const&) {
+ return ElementPtr();
+ }
+ DataNode const config(*config_optional);
+ ElementPtr result = getServerKeaDhcpCommon(config);
+
+ // Handle DHCPv6 specific global parameters.
+ checkAndGetLeaf(result, config, "data-directory");
+ checkAndGetLeaf(result, config, "mac-sources");
+ checkAndGetLeaf(result, config, "max-preferred-lifetime");
+ checkAndGetLeaf(result, config, "min-preferred-lifetime");
+ checkAndGetLeaf(result, config, "pd-allocator");
+ checkAndGetLeaf(result, config, "preferred-lifetime");
+ checkAndGetLeaf(result, config, "relay-supplied-options");
+
+ // Handle interfaces.
+ ElementPtr interfaces_config(getInterfacesKea(config));
+ if (interfaces_config) {
+ result->set("interfaces-config", interfaces_config);
+ }
+
+ // Handle server-id.
+ optional<DataNode> const& server_id_optional(config.findPath("server-id"));
+ if (server_id_optional) {
+ DataNode const server_id(*server_id_optional);
+ ElementPtr server_id_map(Element::createMap());
+ checkAndGetLeaf(server_id_map, server_id, "type");
+ checkAndGetLeaf(server_id_map, server_id, "identifier");
+ checkAndGetLeaf(server_id_map, server_id, "time");
+ checkAndGetLeaf(server_id_map, server_id, "htype");
+ checkAndGetLeaf(server_id_map, server_id, "enterprise-id");
+ checkAndGetLeaf(server_id_map, server_id, "persist");
+ checkAndGetAndJsonifyLeaf(server_id_map, server_id, "user-context");
+ if (!server_id_map->empty()) {
+ result->set("server-id", server_id_map);
+ }
+ }
+
+ // Handle subnets.
+ ConstElementPtr subnets = getSubnets(config);
+ if (subnets) {
+ result->set("subnet6", subnets);
+ }
+
+ return (result);
+}
+
+void
+TranslatorConfig::setConfig(ElementPtr elem) {
+ try {
+ if (model_ == IETF_DHCPV6_SERVER) {
+ if (elem) {
+ AdaptorConfig::preProcess6(elem);
+ setConfigIetf6(elem);
+ } else {
+ delConfigIetf6();
+ }
+ } else if (model_ == KEA_DHCP4_SERVER) {
+ if (elem) {
+ AdaptorConfig::preProcess4(elem);
+ setConfigKea4(elem);
+ } else {
+ delConfigKea();
+ }
+ } else if (model_ == KEA_DHCP6_SERVER) {
+ if (elem) {
+ AdaptorConfig::preProcess6(elem);
+ setConfigKea6(elem);
+ } else {
+ delConfigKea();
+ }
+ } else {
+ isc_throw(NotImplemented,
+ "setConfig not implemented for the model: " << model_);
+ }
+ } catch (Error const& ex) {
+ isc_throw(NetconfError,
+ "setting config '" << elem->str()
+ << "': " << ex.what());
+ }
+}
+
+void
+TranslatorConfig::delConfigIetf6() {
+ deleteItem("/" + model_ + ":server");
+}
+
+void
+TranslatorConfig::setConfigIetf6(ConstElementPtr elem) {
+ string xpath = "/" + model_ + ":server/server-config";
+ ConstElementPtr dhcp6 = elem->get("Dhcp6");
+ if (!dhcp6) {
+ isc_throw(BadValue, "no Dhcp6 entry in " << elem->str());
+ }
+
+ ConstElementPtr ranges = dhcp6->get("subnet6");
+ if (ranges && !ranges->empty()) {
+ setSubnets(xpath + "/network-ranges", ranges);
+ }
+
+ // Skip everything else.
+}
+
+void
+TranslatorConfig::delConfigKea() {
+ deleteItem("/" + model_ + ":config");
+}
+
+void
+TranslatorConfig::setConfigKea4(ConstElementPtr elem) {
+ ConstElementPtr dhcp = elem->get("Dhcp4");
+ if (dhcp) {
+ setServerKeaDhcp4(dhcp);
+ }
+}
+
+void
+TranslatorConfig::setConfigKea6(ConstElementPtr elem) {
+ ConstElementPtr dhcp = elem->get("Dhcp6");
+ if (dhcp) {
+ setServerKeaDhcp6(dhcp);
+ }
+}
+
+void
+TranslatorConfig::setServerKeaDhcpCommon(string const& xpath,
+ ConstElementPtr elem) {
+ checkAndSetLeaf(elem, xpath, "allocator", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "cache-max-age", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "cache-threshold", LeafBaseType::Dec64);
+ checkAndSetLeaf(elem, xpath, "calculate-tee-times", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "ddns-generated-prefix", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "ddns-override-client-update", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "ddns-override-no-update", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "ddns-qualifying-suffix", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "ddns-replace-client-name", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "ddns-send-updates", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "ddns-ttl-percent", LeafBaseType::Dec64);
+ checkAndSetLeaf(elem, xpath, "ddns-update-on-renew", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "ddns-use-conflict-resolution", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "dhcp4o6-port", LeafBaseType::Uint16);
+ checkAndSetLeaf(elem, xpath, "decline-probation-period", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "early-global-reservations-lookup", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "hostname-char-replacement", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "hostname-char-set", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "ip-reservations-unique", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "max-valid-lifetime", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "min-valid-lifetime", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "parked-packet-limit", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "rebind-timer", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "renew-timer", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "reservation-mode", LeafBaseType::Enum);
+ checkAndSetLeaf(elem, xpath, "reservations-global", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "reservations-in-subnet", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "reservations-lookup-first", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "reservations-out-of-pool", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "server-tag", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "statistic-default-sample-age", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "statistic-default-sample-count", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "store-extended-info", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "t1-percent", LeafBaseType::Dec64);
+ checkAndSetLeaf(elem, xpath, "t2-percent", LeafBaseType::Dec64);
+ checkAndSetLeaf(elem, xpath, "valid-lifetime", LeafBaseType::Uint32);
+
+ checkAndSetLeafList(elem, xpath, "host-reservation-identifiers", LeafBaseType::Enum);
+
+ checkAndStringifyAndSetLeaf(elem, xpath, "dhcp-queue-control");
+
+ checkAndSetUserContext(elem, xpath);
+
+ ConstElementPtr classes = elem->get("client-classes");
+ if (classes && !classes->empty()) {
+ setClasses(xpath, classes);
+ }
+
+ ConstElementPtr compatibility(elem->get("compatibility"));
+ if (compatibility) {
+ checkAndSetLeaf(compatibility, xpath + "/compatibility", "ignore-rai-link-selection", LeafBaseType::Bool);
+ checkAndSetLeaf(compatibility, xpath + "/compatibility", "lenient-option-parsing", LeafBaseType::Bool);
+ }
+
+ ConstElementPtr config_ctrl = elem->get("config-control");
+ if (config_ctrl && !config_ctrl->empty()) {
+ checkAndSetLeaf(config_ctrl, xpath + "/config-control", "config-fetch-wait-time", LeafBaseType::Uint32);
+ ConstElementPtr config_databases = config_ctrl->get("config-databases");
+ if (config_databases && !config_databases->empty()) {
+ setDatabases(xpath + "/config-control/config-database", config_databases);
+ }
+ }
+
+ ConstElementPtr socket = elem->get("control-socket");
+ if (socket && !socket->empty()) {
+ setControlSocket(xpath + "/control-socket", socket);
+ }
+
+ ConstElementPtr ddns = elem->get("dhcp-ddns");
+ if (ddns) {
+ string const ddns_xpath(xpath + "/dhcp-ddns");
+ checkAndSetLeaf(ddns, ddns_xpath, "enable-updates", LeafBaseType::Bool);
+ checkAndSetLeaf(ddns, ddns_xpath, "generated-prefix", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "hostname-char-replacement", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "hostname-char-set", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "max-queue-size", LeafBaseType::Uint32);
+ checkAndSetLeaf(ddns, ddns_xpath, "ncr-format", LeafBaseType::Enum);
+ checkAndSetLeaf(ddns, ddns_xpath, "ncr-protocol", LeafBaseType::Enum);
+ checkAndSetLeaf(ddns, ddns_xpath, "override-client-update", LeafBaseType::Bool);
+ checkAndSetLeaf(ddns, ddns_xpath, "override-no-update", LeafBaseType::Bool);
+ checkAndSetLeaf(ddns, ddns_xpath, "qualifying-suffix", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "replace-client-name", LeafBaseType::Enum);
+ checkAndSetLeaf(ddns, ddns_xpath, "sender-ip", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "sender-port", LeafBaseType::Uint16);
+ checkAndSetLeaf(ddns, ddns_xpath, "server-ip", LeafBaseType::String);
+ checkAndSetLeaf(ddns, ddns_xpath, "server-port", LeafBaseType::Uint16);
+ checkAndSetUserContext(ddns, ddns_xpath);
+ }
+
+ ConstElementPtr expired = elem->get("expired-leases-processing");
+ if (expired) {
+ string const expired_xpath(xpath + "/expired-leases-processing");
+ checkAndSetLeaf(expired, expired_xpath, "flush-reclaimed-timer-wait-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(expired, expired_xpath, "hold-reclaimed-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(expired, expired_xpath, "max-reclaim-leases", LeafBaseType::Uint32);
+ checkAndSetLeaf(expired, expired_xpath, "max-reclaim-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(expired, expired_xpath, "reclaim-timer-wait-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(expired, expired_xpath, "unwarned-reclaim-cycles", LeafBaseType::Uint32);
+ }
+
+ ConstElementPtr hook_libs = elem->get("hooks-libraries");
+ if (hook_libs) {
+ for (ElementPtr const& lib : hook_libs->listValue()) {
+ ConstElementPtr name = lib->get("library");
+ if (!name) {
+ continue;
+ }
+ ostringstream hook_lib;
+ hook_lib << xpath << "/hook-library[library='"
+ << name->stringValue() << "']";
+ string const hook_xpath(hook_lib.str());
+ setItem(hook_xpath, ElementPtr(), LeafBaseType::Unknown);
+ checkAndStringifyAndSetLeaf(lib, hook_xpath, "parameters");
+ }
+ }
+
+ ConstElementPtr hosts_databases = elem->get("hosts-databases");
+ if (hosts_databases && !hosts_databases->empty()) {
+ setDatabases(xpath + "/hosts-database", hosts_databases);
+ }
+
+ ConstElementPtr database = elem->get("lease-database");
+ if (database && !database->empty()) {
+ setDatabase(xpath + "/lease-database", database);
+ }
+
+ ConstElementPtr loggers = elem->get("loggers");
+ if (loggers) {
+ setLoggers(xpath, loggers);
+ }
+
+ ConstElementPtr multi_threading(elem->get("multi-threading"));
+ if (multi_threading) {
+ string const mt_xpath(xpath + "/multi-threading");
+ checkAndSetLeaf(multi_threading, mt_xpath, "enable-multi-threading", LeafBaseType::Bool);
+ checkAndSetLeaf(multi_threading, mt_xpath, "packet-queue-size", LeafBaseType::Uint32);
+ checkAndSetLeaf(multi_threading, mt_xpath, "thread-pool-size", LeafBaseType::Uint32);
+ }
+
+ ConstElementPtr options = elem->get("option-data");
+ if (options && !options->empty()) {
+ setOptionDataList(xpath, options);
+ }
+
+ ConstElementPtr defs = elem->get("option-def");
+ if (defs && !defs->empty()) {
+ setOptionDefList(xpath, defs);
+ }
+
+ ConstElementPtr hosts = elem->get("reservations");
+ if (hosts && !hosts->empty()) {
+ setHosts(xpath, hosts);
+ }
+
+ ConstElementPtr sanity = elem->get("sanity-checks");
+ if (sanity) {
+ checkAndSetLeaf(sanity, xpath + "/sanity-checks", "extended-info-checks", LeafBaseType::Enum);
+ checkAndSetLeaf(sanity, xpath + "/sanity-checks", "lease-checks", LeafBaseType::Enum);
+ }
+
+ ConstElementPtr networks = elem->get("shared-networks");
+ if (networks && !networks->empty()) {
+ setSharedNetworks(xpath, networks);
+ }
+}
+
+void
+TranslatorConfig::setServerKeaDhcp4(ConstElementPtr elem) {
+ string xpath = "/kea-dhcp4-server:config";
+
+ setServerKeaDhcpCommon(xpath, elem);
+
+ checkAndSetLeaf(elem, xpath, "authoritative", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "boot-file-name", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "echo-client-id", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "match-client-id", LeafBaseType::Bool);
+ checkAndSetLeaf(elem, xpath, "next-server", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "offer-lifetime", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "server-hostname", LeafBaseType::String);
+
+ ConstElementPtr compatibility(elem->get("compatibility"));
+ if (compatibility) {
+ checkAndSetLeaf(compatibility, xpath + "/compatibility", "exclude-first-last-24", LeafBaseType::Bool);
+ checkAndSetLeaf(compatibility, xpath + "/compatibility", "ignore-dhcp-server-identifier", LeafBaseType::Bool);
+ }
+
+ ConstElementPtr if_config = elem->get("interfaces-config");
+ if (if_config) {
+ string const if_cfg_xpath(xpath + "/interfaces-config");
+ checkAndSetLeaf(if_config, if_cfg_xpath, "dhcp-socket-type", LeafBaseType::Enum);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "outbound-interface", LeafBaseType::Enum);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-max-retries", LeafBaseType::Uint32);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-require-all", LeafBaseType::Bool);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-retry-wait-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "re-detect", LeafBaseType::Bool);
+ checkAndSetLeafList(if_config, if_cfg_xpath, "interfaces", LeafBaseType::String);
+ checkAndSetUserContext(if_config, if_cfg_xpath);
+ }
+
+ ConstElementPtr subnets = elem->get("subnet4");
+ if (subnets) {
+ setSubnets(xpath, subnets);
+ }
+}
+
+void
+TranslatorConfig::setServerKeaDhcp6(ConstElementPtr elem) {
+ string xpath = "/kea-dhcp6-server:config";
+
+ setServerKeaDhcpCommon(xpath, elem);
+
+ checkAndSetLeaf(elem, xpath, "data-directory", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "max-preferred-lifetime", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "min-preferred-lifetime", LeafBaseType::Uint32);
+ checkAndSetLeaf(elem, xpath, "pd-allocator", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "preferred-lifetime", LeafBaseType::Uint32);
+
+ checkAndSetLeafList(elem, xpath, "mac-sources", LeafBaseType::String);
+ checkAndSetLeafList(elem, xpath, "relay-supplied-options", LeafBaseType::String);
+
+ ConstElementPtr if_config = elem->get("interfaces-config");
+ if (if_config) {
+ string const if_cfg_xpath(xpath + "/interfaces-config");
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-max-retries", LeafBaseType::Uint32);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-require-all", LeafBaseType::Bool);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "service-sockets-retry-wait-time", LeafBaseType::Uint32);
+ checkAndSetLeaf(if_config, if_cfg_xpath, "re-detect", LeafBaseType::Bool);
+ checkAndSetLeafList(if_config, if_cfg_xpath, "interfaces", LeafBaseType::String);
+ checkAndSetUserContext(if_config, if_cfg_xpath);
+ }
+
+ ConstElementPtr server_id = elem->get("server-id");
+ if (server_id) {
+ string const srv_id_xpath(xpath + "/server-id");
+ checkAndSetLeaf(server_id, srv_id_xpath, "type", LeafBaseType::Enum);
+ checkAndSetLeaf(server_id, srv_id_xpath, "identifier", LeafBaseType::String);
+ checkAndSetLeaf(server_id, srv_id_xpath, "time", LeafBaseType::Uint32);
+ checkAndSetLeaf(server_id, srv_id_xpath, "htype", LeafBaseType::Uint16);
+ checkAndSetLeaf(server_id, srv_id_xpath, "enterprise-id", LeafBaseType::Uint32);
+ checkAndSetLeaf(server_id, srv_id_xpath, "persist", LeafBaseType::Bool);
+ checkAndSetUserContext(server_id, srv_id_xpath);
+ }
+
+ ConstElementPtr subnets = elem->get("subnet6");
+ if (subnets) {
+ setSubnets(xpath, subnets);
+ }
+}
+
+} // namespace yang
+} // namespace isc