// resolution as described in RFC 4703 should be employed for the
// given update request. The default value for this flag is true.
// It may be specified at the global, shared-network, and subnet levels.
- "ddns-use-conflict-resolution": true,
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
+ // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
+ // update request to indicate the mode used for resolving conflicts
+ // while performing DDNS updates. The acceptable values are:
+ // check-with-dhcid (this includes adding a DHCID record and checking
+ // that record via conflict detection as per RFC 4703,
+ // no-check-with-dhcid (this will ignore conflict detection but add
+ // a DHCID record when creating/updating an entry),
+ // check-exists-with-dhcid (this will check if there is an existing
+ // DHCID record but does not verify the value of the record matches
+ // the update. This will also update the DHCID record for the entry),
+ // no-check-without-dhcid (this ignores conflict detection and will
+ // not add a DHCID record when creating/updating a DDNS entry).
+ // The default value is "check-with-dhcid". It may be
+ // specified at the global, shared-network and subnet levels.
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// When greater than 0.0, it is the percent of the lease's lifetime
// to use for the DNS TTL.
// serve-retry-continue
"on-fail": "stop-retry-exit",
+ // Flag which indicates if the DB recovery should be attempted
+ // at server startup and on reconfiguration events.
+ "retry-on-startup": false,
+
// Connection connect timeout in seconds.
"connect-timeout": 100,
"ddns-update-on-renew": true,
// Shared-network level value. See description at the global level.
- "ddns-use-conflict-resolution": true,
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
+ // Shared-network level value. See description at the global level.
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// Shared-network level value. See description at the global level.
"ddns-ttl-percent": 0.65,
// Subnet-level value. See description at the global level.
"ddns-update-on-renew": true,
+ // Shared-network level value. See description at the global level.
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
// Subnet-level value. See description at the global level.
- "ddns-use-conflict-resolution": true,
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// Subnet-level value. See description at the global level.
"ddns-ttl-percent": 0.55,
// Global server hostname set in the 'sname' field.
"server-hostname": "",
+ // Stash agent options (aka RAI) to make direct queries to come
+ // through a relay.
+ "stash-agent-options": false,
+
// List of IPv4 subnets which don't belong to any shared network.
"subnet4": [],
// resolution as described in RFC 4703 should be employed for the
// given update request. The default value for this flag is true.
// It may be specified at the global, shared-network, and subnet levels.
- "ddns-use-conflict-resolution": true,
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
+ // Enumeration, which is passed to kea-dhcp-ddns with each DDNS
+ // update request to indicate the mode used for resolving conflicts
+ // while performing DDNS updates. The acceptable values are:
+ // check-with-dhcid (this includes adding a DHCID record and checking
+ // that record via conflict detection as per RFC 4703,
+ // no-check-with-dhcid (this will ignore conflict detection but add
+ // a DHCID record when creating/updating an entry),
+ // check-exists-with-dhcid (this will check if there is an existing
+ // DHCID record but does not verify the value of the record matches
+ // the update. This will also update the DHCID record for the entry),
+ // no-check-without-dhcid (this ignores conflict detection and will
+ // not add a DHCID record when creating/updating a DDNS entry).
+ // The default value is "check-with-dhcid". It may be
+ // specified at the global, shared-network and subnet levels.
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// When greater than 0.0, it is the percent of the lease's lifetime
// to use for the DNS TTL.
// serve-retry-continue
"on-fail": "stop-retry-exit",
+ // Flag which indicates if the DB recovery should be attempted
+ // at server startup and on reconfiguration events.
+ "retry-on-startup": false,
+
// Connection connect timeout in seconds.
"connect-timeout": 100,
"ddns-update-on-renew": true,
// Shared-network level value. See description at the global level.
- "ddns-use-conflict-resolution": true,
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
+ // Shared-network level value. See description at the global level.
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// Shared-network level value. See description at the global level.
"ddns-ttl-percent": 0.65,
"ddns-update-on-renew": true,
// Subnet-level value. See description at the global level.
- "ddns-use-conflict-resolution": true,
+ // This field has been replaced by ddns-conflict-resolution-mode.
+ // Parsing is maintained only for backwards compatibility.
+ // "ddns-use-conflict-resolution": true,
+
+ // Subnet-level value. See description at the global level.
+ "ddns-conflict-resolution-mode": "check-with-dhcid",
// Subnet-level value. See description at the global level.
"ddns-ttl-percent": 0.55,
{
"id": 1,
"subnet": "10.0.0.0/24",
- # It is replaced by the "reservations-global",
- # "reservations-in-subnet", and "reservations-out-of-pool"
- # parameters.
- # "reservation-mode": "global",
# Specify if the server should look up global reservations.
"reservations-global": true,
# Specify if the server should look up in-subnet reservations.
+-----------------------------+----------------------------+--------------+-------------+-------------+-------------+
| require-client-classes | no | n/a | yes | yes | yes |
+-----------------------------+----------------------------+--------------+-------------+-------------+-------------+
- | reservation-mode | yes | n/a | yes | yes | n/a |
- +-----------------------------+----------------------------+--------------+-------------+-------------+-------------+
| reservations-global | yes | n/a | yes | yes | n/a |
+-----------------------------+----------------------------+--------------+-------------+-------------+-------------+
| reservations-in-subnet | yes | n/a | yes | yes | n/a |
"valid-lifetime": 600,
"subnet4": [ {
"subnet": "2001:db8:1::/64",
- # It is replaced by the "reservations-global",
- # "reservations-in-subnet", and "reservations-out-of-pool"
- # parameters.
- # "reservation-mode": "global",
# Specify if the server should look up global reservations.
"reservations-global": true,
# Specify if the server should look up in-subnet reservations.
+-----------------------------+----------------------------+-----------+-----------+-----------+-----------+------------+
| require-client-classes | n/a | n/a | yes | yes | yes | yes |
+-----------------------------+----------------------------+-----------+-----------+-----------+-----------+------------+
- | reservation-mode | yes | n/a | yes | yes | n/a | n/a |
- +-----------------------------+----------------------------+-----------+-----------+-----------+-----------+------------+
| reservations-global | yes | n/a | yes | yes | n/a | n/a |
+-----------------------------+----------------------------+-----------+-----------+-----------+-----------+------------+
| reservations-in-subnet | yes | n/a | yes | yes | n/a | n/a |
return;
}
ConstElementPtr addresses = relay->get("ip-addresses");
- if (!addresses) {
- ConstElementPtr address = relay->get("ip-address");
- if (!address) {
- subnet->remove("relay");
- return;
- }
- ElementPtr addr = Element::create(address->stringValue());
- ElementPtr addrs = Element::createList();
- addrs->add(addr);
- ElementPtr updated = Element::createMap();
- updated->set("ip-addresses", addrs);
- subnet->set("relay", updated);
- } else if (addresses->size() == 0) {
+ if (!addresses || addresses->size() == 0) {
subnet->remove("relay");
}
}
/// so the caller can decide if the second pass is needed.
/// -2- For a subnet without an ID, assigned the next unused ID.
///
-/// For relays an old syntax ip-address is translated into a new syntax
-/// ip-addresses. Note as all canonization adaptor it is optional, i.e.,
-/// code should work without it.
+/// Note as all canonization adaptor it is optional, i.e., code should work
+/// without it.
class AdaptorSubnet {
public:
/// @brief Destructor.
/// @brief Update relay.
///
- /// Force the use of ip-addresses when it finds an ip-address entry.
/// Can be used for shared networks too.
///
/// @param subnet The subnet.
EXPECT_FALSE(json->get("relay"));
}
-// Verifies how updateRelay handles a subnet entry with relay which
-// has addresses: no change.
-TEST(AdaptorSubnetTest, updateRelayAddresses) {
- string config = "{\n"
- " \"subnet\": \"192.0.2.0/24\",\n"
- " \"relay\": {\n"
- " \"ip-addresses\": [ \"192.168.1.1\" ]\n"
- " }\n"
- "}";
- ElementPtr json;
- ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
- ConstElementPtr copied = copy(json);
- ASSERT_NO_THROW_LOG(AdaptorSubnet::updateRelay(json));
- EXPECT_TRUE(copied->equals(*json));
-}
-
-// Verifies how updateRelay handles a subnet entry with relay which
-// has only address: the address is moved to a new list.
-TEST(AdaptorSubnetTest, updateRelayAddress) {
- string config = "{\n"
- " \"subnet\": \"192.0.2.0/24\",\n"
- " \"relay\": {\n"
- " \"ip-address\": \"192.168.1.1\"\n"
- " }\n"
- "}";
- ElementPtr json;
- ASSERT_NO_THROW_LOG(json = Element::fromJSON(config));
- ConstElementPtr copied = copy(json);
- ASSERT_NO_THROW_LOG(AdaptorSubnet::updateRelay(json));
- EXPECT_FALSE(copied->equals(*json));
- ConstElementPtr relay = json->get("relay");
- ASSERT_TRUE(relay);
- string expected = "{ \"ip-addresses\": [ \"192.168.1.1\" ] }";
- EXPECT_EQ(expected, relay->str());
-}
-
-// It does not make sense to have both ip-address and ip-addresses...
-
} // anonymous namespace
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, "ddns-ttl-percent");
checkAndGetLeaf(result, data_node, "ddns-update-on-renew");
checkAndGetLeaf(result, data_node, "ddns-use-conflict-resolution");
+ checkAndGetLeaf(result, data_node, "ddns-conflict-resolution-mode");
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, "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, config, "next-server");
checkAndGetLeaf(result, config, "offer-lifetime");
checkAndGetLeaf(result, config, "server-hostname");
+ checkAndGetLeaf(result, config, "stash-agent-options");
checkAndGet(result, config, "compatibility",
[&](DataNode const& node) -> ElementPtr const {
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, "ddns-conflict-resolution-mode", LeafBaseType::Enum);
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, "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);
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(elem, xpath, "next-server", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "offer-lifetime", LeafBaseType::Uint32);
checkAndSetLeaf(elem, xpath, "server-hostname", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "stash-agent-options", LeafBaseType::Bool);
ConstElementPtr compatibility(elem->get("compatibility"));
if (compatibility) {
/// <user-context>,
/// <comment>,
/// "sanity-checks": { <sanity checks> },
-/// "reservation-mode": <host reservation mode>,
/// "reservations": [ <list of host reservations> ],
/// <config-control>,
/// "server-tag": <server tag>,
/// +--rw authoritative? boolean
/// +--rw user-context? user-context
/// +--rw sanity-checks
-/// +--rw reservation-mode? host-reservation-mode
/// +--rw host* [identifier-type identifier]
/// +--rw config-control
/// +--rw server-tag? string
/// +--rw ddns-send-updates? boolean
/// +--rw ddns-update-on-renew? boolean
/// +--rw ddns-use-conflict-resolution? boolean
+/// +--rw ddns-conflict-resolution-mode? conflict-resolution-mode
/// +--rw ip-reservations-unique? boolean
/// +--rw early-global-reservations-lookup? boolean
/// +--rw reservations-lookup-first? boolean
/// <user-context>,
/// <comment>
/// "sanity-checks": { <sanity checks> },
-/// "reservation-mode": <host reservation mode>,
/// "reservations": [ <list of host reservations> ],
/// <config-control>,
/// "server-tag": <server tag>,
/// +--rw dhcp-ddns
/// +--rw user-context? user-context
/// +--rw sanity-checks
-/// +--rw reservation-mode? host-reservation-mode
/// +--rw host* [identifier-type identifier]
/// +--rw config-control
/// +--rw server-tag? string
/// +--rw ddns-send-updates? boolean
/// +--rw ddns-update-on-renew? boolean
/// +--rw ddns-use-conflict-resolution? boolean
+/// +--rw ddns-conflict-resolution-mode? conflict-resolution-mode
/// +--rw ip-reservations-unique? boolean
/// +--rw early-global-reservations-lookup? boolean
/// +--rw reservations-lookup-first? boolean
checkAndGetLeaf(result, data_node, "max-row-errors");
checkAndGetLeaf(result, data_node, "name");
checkAndGetLeaf(result, data_node, "on-fail");
+ checkAndGetLeaf(result, data_node, "retry-on-startup");
checkAndGetLeaf(result, data_node, "password");
checkAndGetLeaf(result, data_node, "persist");
checkAndGetLeaf(result, data_node, "port");
checkAndSetLeaf(elem, xpath, "max-row-errors", LeafBaseType::Uint32);
checkAndSetLeaf(elem, xpath, "name", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "on-fail", LeafBaseType::String);
+ checkAndSetLeaf(elem, xpath, "retry-on-startup", LeafBaseType::Bool);
checkAndSetLeaf(elem, xpath, "password", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "persist", LeafBaseType::Bool);
checkAndSetLeaf(elem, xpath, "port", LeafBaseType::Uint16);
/// +--rw reconnect-wait-time? uint32
/// +--rw max-row-errors? uint32
/// +--rw on-fail? string
+/// +--rw retry-on-startup? boolean
/// +--rw user-context? user-context
/// @endcode
///
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, "ddns-conflict-resolution-mode");
checkAndGetLeaf(result, data_node, "hostname-char-replacement");
checkAndGetLeaf(result, data_node, "hostname-char-set");
checkAndGetLeaf(result, data_node, "interface");
checkAndGetLeaf(result, data_node, "rebind-timer");
checkAndGetLeaf(result, data_node, "renew-timer");
checkAndGetLeaf(result, data_node, "require-client-classes");
- checkAndGetLeaf(result, data_node, "reservation-mode");
checkAndGetLeaf(result, data_node, "reservations-global");
checkAndGetLeaf(result, data_node, "reservations-in-subnet");
checkAndGetLeaf(result, data_node, "reservations-out-of-pool");
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, "ddns-conflict-resolution-mode", LeafBaseType::Enum);
checkAndSetLeaf(elem, xpath, "hostname-char-replacement", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "hostname-char-set", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "interface", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "min-valid-lifetime", 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-out-of-pool", LeafBaseType::Bool);
ConstElementPtr relay = elem->get("relay");
if (relay) {
- ConstElementPtr address = relay->get("ip-address");
ConstElementPtr addresses = relay->get("ip-addresses");
- if (address) {
- setItem(xpath + "/relay/ip-addresses", address, LeafBaseType::String);
- } else if (addresses && !addresses->empty()) {
+ if (addresses && !addresses->empty()) {
for (ElementPtr const& addr : addresses->listValue()) {
setItem(xpath + "/relay/ip-addresses", addr, LeafBaseType::String);
}
/// "interface": "<interface>",
/// "client-class": "<guard class name>",
/// "require-client-classes": [ <list of required class names> ],
-/// "reservation-mode": <host reservation mode>,
/// "relay": <relay ip address(es)>,
/// "match-client-id": <match client id flag>,
/// "next-server": "<next server>",
/// "rapid-commit": <rapid commit flag>,
/// "client-class": "<guard class name>",
/// "require-client-classes": [ <list of required class names> ],
-/// "reservation-mode": <host reservation mode>,
/// "relay": <relay ip address(es)>,
/// "user-context": { <json map> },
/// "comment": "<comment>"
/// +--rw renew-timer? uint32
/// +--rw rebind-timer? uint32
/// +--rw option-data* [code space]
-/// +--rw reservation-mode? host-reservation-mode
/// +--rw client-class? string
/// +--rw require-client-classes* string
/// +--rw valid-lifetime? uint32
/// +--rw ddns-send-updates? boolean
/// +--rw ddns-update-on-renew? boolean
/// +--rw ddns-use-conflict-resolution? boolean
+/// +--rw ddns-conflict-resolution-mode? conflict-resolution-mode
/// +--rw store-extended-info? boolean
/// +--rw hostname-char-replacement? string
/// +--rw hostname-char-set? string
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, "ddns-conflict-resolution-mode");
checkAndGetLeaf(result, data_node, "hostname-char-replacement");
checkAndGetLeaf(result, data_node, "hostname-char-set");
checkAndGetLeaf(result, data_node, "interface");
checkAndGetLeaf(result, data_node, "rebind-timer");
checkAndGetLeaf(result, data_node, "renew-timer");
checkAndGetLeaf(result, data_node, "require-client-classes");
- checkAndGetLeaf(result, data_node, "reservation-mode");
checkAndGetLeaf(result, data_node, "reservations-global");
checkAndGetLeaf(result, data_node, "reservations-in-subnet");
checkAndGetLeaf(result, data_node, "reservations-out-of-pool");
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, "ddns-conflict-resolution-mode", LeafBaseType::Enum);
checkAndSetLeaf(elem, xpath, "hostname-char-replacement", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "hostname-char-set", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "interface", LeafBaseType::String);
checkAndSetLeaf(elem, xpath, "min-valid-lifetime", 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-out-of-pool", LeafBaseType::Bool);
}
ConstElementPtr relay = elem->get("relay");
if (relay) {
- ConstElementPtr address = relay->get("ip-address");
ConstElementPtr addresses = relay->get("ip-addresses");
- if (address) {
- setItem(xpath + "/relay/ip-addresses", address, LeafBaseType::String);
- } else if (addresses && !addresses->empty()) {
+ if (addresses && !addresses->empty()) {
for (ElementPtr const& addr : addresses->listValue()) {
setItem(xpath + "/relay/ip-addresses", addr, LeafBaseType::String);
}
/// "client-class": "<guard class name>",
/// "require-client-classes": [ <list of required class names> ],
/// "reservations": [ <list of host reservations> ],
-/// "reservation-mode": <host reservation mode>,
/// "relay": <relay ip address(es)>,
/// "match-client-id": <match client id flag>,
/// "next-server": "<next server>",
/// "client-class": "<guard class name>",
/// "require-client-classes": [ <list of required class names> ],
/// "reservations": [ <list of host reservations> ],
-/// "reservation-mode": <host reservation mode>,
/// "relay": <relay ip address(es)>,
/// "user-context": { <json map> },
/// "comment": "<comment>"
/// +--rw client-class? string
/// +--rw require-client-classes* string
/// +--rw host* [identifier-type identifier]
-/// +--rw reservation-mode? host-reservation-mode
/// +--rw relay
/// +--rw cache-max-age? uint32
/// +--rw cache-threshold? decimal64
/// +--rw ddns-send-updates? boolean
/// +--rw ddns-update-on-renew? boolean
/// +--rw ddns-use-conflict-resolution? boolean
+/// +--rw ddns-conflict-resolution-mode? conflict-resolution-mode
/// +--rw hostname-char-replacement? string
/// +--rw hostname-char-set? string
/// +--rw reservations-global? boolean
{ "ietf-dhcpv6-options", "2018-09-04" },
{ "ietf-dhcpv6-server", "2018-09-04" },
{ "kea-types", "2019-08-12" },
- { "kea-dhcp-types", "2023-06-28" },
- { "kea-dhcp4-server", "2024-01-31" },
- { "kea-dhcp6-server", "2024-01-31" },
+ { "kea-dhcp-types", "2024-05-29" },
+ { "kea-dhcp4-server", "2024-05-29" },
+ { "kea-dhcp6-server", "2024-05-29" },
{ "kea-ctrl-agent", "2019-08-12" },
{ "kea-dhcp-ddns", "2022-07-27" }
}; // YANG_REVISIONS
yangmodules_list += ietf-yang-types@2013-07-15.yang
yangmodules_list += kea-ctrl-agent@2019-08-12.yang
yangmodules_list += kea-dhcp-ddns@2022-07-27.yang
-yangmodules_list += kea-dhcp-types@2023-06-28.yang
-yangmodules_list += kea-dhcp4-server@2024-01-31.yang
-yangmodules_list += kea-dhcp6-server@2024-01-31.yang
+yangmodules_list += kea-dhcp-types@2024-05-29.yang
+yangmodules_list += kea-dhcp4-server@2024-05-29.yang
+yangmodules_list += kea-dhcp6-server@2024-05-29.yang
yangmodules_list += kea-types@2019-08-12.yang
yangmodules_list += keatest-module@2022-11-30.yang
+++ /dev/null
-1d8a9d22cdd4751a0b67d1018ca2d6495d68a2dd3beaad3d791999784e53ec1a
--- /dev/null
+ed30e29cccb5c67db520704003a88e9a574e46f3579d3a20e651deefcbec33c7
+++ /dev/null
-a1b6cad9bbf1174cf985163df390b89fa20c9f9dd52732c194dfcc9d8ab82d8d
--- /dev/null
+2340982f95cf932980e9de6b32aebf52ee8852302dcce1aaf6647db03f0f0809
+++ /dev/null
-5e06c05278ba1591d5860c3069900fb4e3ce21117742453257afad6c34a2f703
--- /dev/null
+953e6ab578308b714a9dbc20e5e2b3bb2b97c21194ec38911402cccb85836833
description "This file defines some commonly used Kea DHCP types and
groupings.";
+ revision 2024-05-29 {
+ description "Removed qualifying-suffix, override-no-update,
+ override-client-update, replace-client-name, generated-prefix,
+ hostname-char-set and hostname-char-replacement from dhcp-ddns,
+ removed reservation-mode and added retry-on-startup and
+ ddns-conflict-resolution-mode.";
+ }
+
revision 2023-06-28 {
description "Added pool ID.";
}
/*
* Typedef
*/
- typedef host-reservation-mode {
+ typedef conflict-resolution-mode {
type enumeration {
- enum "disabled" {
- description "Host reservation support is disabled.";
+ enum "check-with-dhcid" {
+ description "Existing DNS entries may be overwritten by matching client if
+ they have a DHCID record and it matches the client's DHCID.";
}
- enum "out-of-pool" {
- description "Allows only out of pool host reservations.";
+ enum "no-check-with-dhcid" {
+ description "Existing DNS entries may be overwritten by any client, whether
+ or not those entries include a DHCID record.";
}
- enum "all" {
- description "Allows both in pool and out of pool host reservations.";
+ enum "check-exists-with-dhcid" {
+ description "Existing DNS entries may be overwritten only if they have a
+ DHCID record.";
}
- enum "global" {
- description "Allows only global host reservations.";
+ enum "no-check-without-dhcid" {
+ description "Existing DNS entries may be overwritten by any client.";
}
}
- description "Host reservation mode.";
+ description "Conflict Resolution mode.";
}
typedef lease-state {
}
leaf on-fail {
type string;
- description
- "action to take when connection recovery fails";
+ description "action to take when connection recovery fails";
+ }
+ leaf retry-on-startup {
+ type boolean;
+ description "try connection recovery on startup.";
}
uses kea:user-context {
refine user-context {
type boolean;
description "Enable DHCP-DDNS updates.";
}
- leaf qualifying-suffix {
- type string;
- description "DHCP-DDNS qualifying suffix.";
- }
leaf server-ip {
type inet:ip-address;
description "DHCP-DDNS server IP address.";
}
description "Packet format to use for DHCP-DDNS.";
}
- leaf override-no-update {
- type boolean;
- description "Ignore client request and send update.";
- }
- leaf override-client-update {
- type boolean;
- description "Ignore client delegation.";
- }
- leaf replace-client-name {
- type enumeration {
- enum "when-present" {
- description "When the client sent a name.";
- }
- enum "never" {
- description "Never replace or generate a name.";
- }
- enum "always" {
- description "Always replace or generate a name.";
- }
- enum "when-not-present" {
- description "When the client did not send a name.";
- }
- }
- description "Replace the name provided by the client.";
- }
- leaf generated-prefix {
- type string;
- description "DHCP-DDNS generated prefix.";
- }
- uses hostname-char-set;
- uses hostname-char-replacement;
uses kea:user-context {
refine user-context {
description "DHCP-DDNS user context. Arbitrary JSON data can
}
}
- grouping reservation-mode {
- description "Reservation mode grouping.";
- leaf reservation-mode {
- type host-reservation-mode;
- description "Reservation mode entry.";
- }
- }
-
grouping interfaces-re-detect {
description "Interfaces re-detect grouping.";
leaf re-detect {
}
}
+ grouping ddns-conflict-resolution-mode {
+ description "Conflict resolution mode grouping.";
+ leaf ddns-conflict-resolution-mode {
+ type conflict-resolution-mode;
+ description "Conflict resolution mode entry.";
+ }
+ }
+
grouping ip-reservations-unique {
leaf ip-reservations-unique {
type boolean;
}
import kea-dhcp-types {
prefix dhcp;
- revision-date 2023-06-28;
+ revision-date 2024-05-29;
}
organization "Internet Systems Consortium";
description "This model defines a YANG data model that can be
used to configure and manage a Kea DHCPv4 server.";
+ revision 2024-05-29 {
+ description "Removed reservation-mode and added stash-agent-options.";
+ }
+
revision 2024-01-31 {
description "Added data to the set of keys for option-data to facilitate
configuring options with same code and space, but different
description "Subnet host reservations list.";
}
}
- uses dhcp:reservation-mode;
container relay {
description "Optional information about relay agent.";
uses relay;
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:hostname-char-replacement;
uses dhcp:hostname-char-set;
uses dhcp:reservations-global;
uses relay;
}
uses authoritative;
- uses dhcp:reservation-mode;
uses dhcp:network-client-class;
uses dhcp:network-require-client-classes;
uses dhcp:valid-lifetime;
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:hostname-char-replacement;
uses dhcp:hostname-char-set;
uses dhcp:reservations-global;
}
}
uses dhcp:sanity-checks;
- uses dhcp:reservation-mode;
uses reservations {
refine host {
description "Global host reservations list.";
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:ip-reservations-unique;
uses dhcp:early-global-reservations-lookup;
uses dhcp:reservations-lookup-first;
uses dhcp:statistic-default-sample-age;
uses dhcp:statistic-default-sample-count;
uses dhcp:store-extended-info;
+
+ leaf stash-agent-options {
+ type boolean;
+ description "Stash agent options (aka RAI) to make direct queries to come
+ through a relay.";
+ }
}
/*
}
import kea-dhcp-types {
prefix dhcp;
- revision-date 2023-06-28;
+ revision-date 2024-05-29;
}
organization "Internet Systems Consortium";
description "This model defines a YANG data model that can be
used to configure and manage a Kea DHCPv6 server.";
+ revision 2024-05-29 {
+ description "Removed reservation-mode.";
+ }
+
revision 2024-01-31 {
description "Added data to the set of keys for option-data to facilitate
configuring options with same code and space, but different
description "Subnet host reservations list.";
}
}
- uses dhcp:reservation-mode;
container relay {
description "Optional information about relay agent.";
uses relay;
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:hostname-char-replacement;
uses dhcp:hostname-char-set;
uses dhcp:reservations-global;
description "Optional information about relay agent.";
uses relay;
}
- uses dhcp:reservation-mode;
uses dhcp:network-client-class;
uses dhcp:require-client-classes;
uses preferred-lifetime;
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:hostname-char-replacement;
uses dhcp:hostname-char-set;
uses dhcp:reservations-global;
}
}
uses dhcp:sanity-checks;
- uses dhcp:reservation-mode;
uses reservations {
refine host {
description "Global host reservations list.";
uses dhcp:ddns-ttl-percent;
uses dhcp:ddns-update-on-renew;
uses dhcp:ddns-use-conflict-resolution;
+ uses dhcp:ddns-conflict-resolution-mode;
uses dhcp:ip-reservations-unique;
uses dhcp:early-global-reservations-lookup;
uses dhcp:reservations-lookup-first;