"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// Global compute T1 and T2 timers.
"calculate-tee-times": true,
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
// Data directory.
"data-directory": "/tmp",
"Dhcp4": {
"reservations-global": false,
- "reservations-in-subnet": false,
+ "reservations-in-subnet": true,
"reservations-out-of-pool": true,
...
}
"reservations-global": false,
"reservations-in-subnet": true,
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
...
}
"reservations-global": true,
"reservations-in-subnet": true,
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
...
}
"Dhcp6": {
"reservations-global": false,
- "reservations-in-subnet": false,
+ "reservations-in-subnet": true,
"reservations-out-of-pool": true,
...
}
"reservations-global": false,
"reservations-in-subnet": true,
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
...
}
"reservations-global": true,
"reservations-in-subnet": true,
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
...
}
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
# Specify if server should lookup out-of-pool reservations.
- "reservations-out-of-pool": true,
+ "reservations-out-of-pool": false,
"subnet4": [
{
"subnet": "192.0.2.0/24",
bool found = false;
ConstElementPtr reservations_out_of_pool = mutable_cfg->get("reservations-out-of-pool");
- if (reservations_out_of_pool) {
- found = true;
- }
ConstElementPtr reservations_in_subnet = mutable_cfg->get("reservations-in-subnet");
- if (reservations_in_subnet) {
- found = true;
- }
ConstElementPtr reservations_global = mutable_cfg->get("reservations-global");
- if (reservations_global) {
+ if (reservations_out_of_pool || reservations_in_subnet || reservations_global) {
found = true;
}
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
// reset all other reservation flags to overwrite default values.
if (found) {
+ bool force_true = false;
if (!reservations_out_of_pool) {
mutable_cfg->set("reservations-out-of-pool", Element::create(false));
+ } else {
+ force_true = reservations_out_of_pool->boolValue();
}
if (!reservations_in_subnet) {
- mutable_cfg->set("reservations-in-subnet", Element::create(false));
+ if (force_true) {
+ mutable_cfg->set("reservations-in-subnet", Element::create(true));
+ } else {
+ mutable_cfg->set("reservations-in-subnet", Element::create(false));
+ }
+ } else if (force_true && !reservations_in_subnet->boolValue()) {
+ isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
+ " when enabled 'reservations-out-of-pool'");
}
if (!reservations_global) {
mutable_cfg->set("reservations-global", Element::create(false));
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ],"
" \"subnet\": \"192.0.1.0/24\", "
- " \"reservations-out-of-pool\": true,"
" \"reservations-in-subnet\": true"
" },"
" {"
" {"
" \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ],"
" \"subnet\": \"192.0.6.0/24\", "
- " \"reservations-out-of-pool\": true,"
+ " \"reservations-out-of-pool\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-global\": true"
" } ],"
"\"subnet4\": [ { "
" \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ],"
" \"subnet\": \"192.0.2.0/24\", "
- " \"reservations-out-of-pool\": true,"
" \"reservations-in-subnet\": true"
" },"
" {"
" \"id\": 10,"
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],\n"
" \"interface\": \"eth0\",\n"
- " \"reservations-out-of-pool\": true,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations\": [ \n"
" {\n"
bool found = false;
ConstElementPtr reservations_out_of_pool = mutable_cfg->get("reservations-out-of-pool");
- if (reservations_out_of_pool) {
- found = true;
- }
ConstElementPtr reservations_in_subnet = mutable_cfg->get("reservations-in-subnet");
- if (reservations_in_subnet) {
- found = true;
- }
ConstElementPtr reservations_global = mutable_cfg->get("reservations-global");
- if (reservations_global) {
+ if (reservations_out_of_pool || reservations_in_subnet || reservations_global) {
found = true;
}
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
// reset all other reservation flags to overwrite default values.
if (found) {
+ bool force_true = false;
if (!reservations_out_of_pool) {
mutable_cfg->set("reservations-out-of-pool", Element::create(false));
+ } else {
+ force_true = reservations_out_of_pool->boolValue();
}
if (!reservations_in_subnet) {
- mutable_cfg->set("reservations-in-subnet", Element::create(false));
+ if (force_true) {
+ mutable_cfg->set("reservations-in-subnet", Element::create(true));
+ } else {
+ mutable_cfg->set("reservations-in-subnet", Element::create(false));
+ }
+ } else if (force_true && !reservations_in_subnet->boolValue()) {
+ isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
+ " when enabled 'reservations-out-of-pool'");
}
if (!reservations_global) {
mutable_cfg->set("reservations-global", Element::create(false));
/// - 2001:db8:3::/64 (reservations disabled)
/// - 2001:db8:4::/64 (global reservations)
/// - 2001:db8:5::/64 (reservations not specified)
- /// - 2001:db8:5::/64 (global + all enabled)
+ /// - 2001:db8:6::/64 (global + all enabled)
const char* hr_config =
"{"
"\"preferred-lifetime\": 3000,"
"\"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
" \"subnet\": \"2001:db8:1::/48\", "
- " \"reservations-out-of-pool\": true,"
" \"reservations-in-subnet\": true"
" },"
" {"
" {"
" \"pools\": [ { \"pool\": \"2001:db8:6::/64\" } ],"
" \"subnet\": \"2001:db8:6::/48\", "
- " \"reservations-out-of-pool\": true,"
+ " \"reservations-out-of-pool\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-global\": true"
" } ],"
"\"subnet6\": [ { "
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
" \"subnet\": \"2001:db8:1::/48\", "
- " \"reservations-out-of-pool\": true,"
" \"reservations-in-subnet\": true"
" },"
" {"
const uint8_t Network::HR_OUT_OF_POOL = 1 << 0;
const uint8_t Network::HR_IN_SUBNET = 1 << 1;
const uint8_t Network::HR_GLOBAL = 1 << 2;
-const uint8_t Network::HR_ALL = Network::HR_IN_SUBNET | Network::HR_OUT_OF_POOL;
+const uint8_t Network::HR_ALL = Network::HR_IN_SUBNET;
void
Network::RelayInfo::addAddress(const asiolink::IOAddress& addr) {
}
if (hr_out_of_pool) {
map->set("reservations-out-of-pool", Element::create(true));
+ map->set("reservations-in-subnet", Element::create(true));
}
}
}
IOAddressList addresses_;
};
-
/// @brief Specifies allowed host reservation mode.
///
/// None - host reservation is disabled. No reservation types
/// are allowed.
- static const uint8_t HR_DISABLED;
-
- /// Only out-of-pool reservations is allowed. This mode
- /// allows AllocEngine to skip reservation checks when
- /// dealing with with addresses that are in pool.
- /// When HR_IN_SUBNET is set, this is always enabled as well.
- static const uint8_t HR_OUT_OF_POOL;
-
- /// The in-pool reservations is allowed. This mode actually
- /// behaves as if out-of-pool reservations are active as well.
- static const uint8_t HR_IN_SUBNET;
-
- /// Only global reservations are allowed. This mode
- /// instructs AllocEngine to only look at global reservations.
- static const uint8_t HR_GLOBAL;
-
- /// Both out-of-pool and in-pool reservations are allowed. This is the
- /// most flexible mode, where sysadmin have biggest liberty. However,
- /// there is a non-trivial performance penalty for it, as the
- /// AllocEngine code has to check whether there are reservations, even
- /// when dealing with reservations from within the dynamic pools.
- static const uint8_t HR_ALL;
+ static const uint8_t HR_DISABLED; // value: 0
+
+ /// Only out-of-pool reservations is allowed. This mode allows AllocEngine
+ /// to skip reservation checks for dynamically allocated addressed.
+ /// When this is set, HR_IN_SUBNET is always enabled as well as there can
+ /// can be no reservations that are out-of-pool but not in-subnet.
+ static const uint8_t HR_OUT_OF_POOL; // value: 1 << 0
+
+ /// The in-subnet mode which also allows in-pool reservations.
+ /// This is equivalent to HR_ALL flag.
+ static const uint8_t HR_IN_SUBNET; // value: 1 << 1
+
+ /// Only global reservations are allowed. This mode instructs AllocEngine
+ /// to only look at global reservations.
+ static const uint8_t HR_GLOBAL; // value: 1 << 2
+
+ /// Both out-of-pool and in-pool reservations are allowed. This is the most
+ /// flexible mode, where sysadmin have biggest liberty. However, there is a
+ /// non-trivial performance penalty for it, as the AllocEngine code has to
+ /// check whether there are reservations, even when dealing with
+ /// reservations from within the dynamic pools. This is required so that the
+ /// dynamically allocated addresses don't match any of the reservations.
+ /// This is the default mode.
+ static const uint8_t HR_ALL; // value: HR_IN_SUBNET
/// @brief Bitset used to store @ref HRModeFlag flags.
typedef uint8_t HRMode;
///
/// Host reservations may be any of the combinations of in-subnet (they
/// reserve an address that is in the subnet either in-pool or out-of-pool),
- /// out-of-pool (they reserve an address that is not in the dynamic pool) or
- /// global (they are defined at global level). HR may also be completely
+ /// out-of-pool (they reserve an address that is in-subnet but not in-pool)
+ /// or global (they are defined at global level). HR may also be completely
/// disabled for performance reasons.
///
/// @param inheritance inheritance mode to be used.
"reservations-out-of-pool");
if (!hr_mode_out_of_pool.unspecified()) {
if (hr_mode_out_of_pool.get()) {
- flags |= Network::HR_OUT_OF_POOL;
+ flags |= Network::HR_IN_SUBNET | Network::HR_OUT_OF_POOL;
}
found = true;
}
NetworkPtr& network) {
if (network_data->contains("reservation-mode")) {
bool found = false;
- if (network_data->contains("reservations-out-of-pool")) {
- found = true;
- }
- if (network_data->contains("reservations-in-subnet")) {
- found = true;
- }
- if (network_data->contains("reservations-global")) {
+ if (network_data->contains("reservations-out-of-pool") ||
+ network_data->contains("reservations-in-subnet") ||
+ network_data->contains("reservations-global")) {
found = true;
}
if (found) {
BaseNetworkParser::parseHostReservationModes(const data::ConstElementPtr& network_data,
NetworkPtr& network) {
bool found = false;
- if (network_data->contains("reservations-out-of-pool")) {
- found = true;
- }
- if (network_data->contains("reservations-in-subnet")) {
- found = true;
- }
- if (network_data->contains("reservations-global")) {
+ if (network_data->contains("reservations-out-of-pool") ||
+ network_data->contains("reservations-in-subnet") ||
+ network_data->contains("reservations-global")) {
found = true;
}
if (network_data->contains("reservation-mode")) {
if (elem) {
bool value = elem->boolValue();
if (value) {
- flags |= Network::HR_OUT_OF_POOL;
+ flags |= Network::HR_IN_SUBNET | Network::HR_OUT_OF_POOL;
}
}
} catch (const Exception& ex) {
{ "server-hostname", Element::string, "" },
{ "boot-file-name", Element::string, "" },
{ "server-tag", Element::string, "" },
- { "reservations-out-of-pool", Element::boolean, "true" },
+ { "reservations-out-of-pool", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-global", Element::boolean, "false" },
{ "calculate-tee-times", Element::boolean, "false" },
{ "decline-probation-period", Element::integer, "86400" }, // 24h
{ "dhcp4o6-port", Element::integer, "0" },
{ "server-tag", Element::string, "" },
- { "reservations-out-of-pool", Element::boolean, "true" },
+ { "reservations-out-of-pool", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-global", Element::boolean, "false" },
{ "calculate-tee-times", Element::boolean, "true" },
" \"4o6-subnet\": \"\",\n"
" \"authoritative\": false,\n"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"option-data\": [ ],\n"
" \"pools\": [ ]\n,"
" \"require-client-classes\": [ \"foo\", \"bar\" ],\n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
" \"max-valid-lifetime\": 300,\n"
" \"rapid-commit\": false,\n"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"pools\": [ ],\n"
" \"pd-pools\": [ ],\n"
" \"option-data\": [ ],\n"
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
- " \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true\n"
+ " \"reservations-in-subnet\": true\n"
" }";
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
- " \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true\n"
+ " \"reservations-in-subnet\": true\n"
" }";
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
- " \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true\n"
+ " \"reservations-in-subnet\": true\n"
" }";
data::ElementPtr elems;
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
- " \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true\n"
+ " \"reservations-in-subnet\": true\n"
" }";
data::ElementPtr elems;
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-in-subnet\": true,"
- " \"reservations-out-of-pool\": true,"
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"4o6-subnet\": \"\","
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-in-subnet\": true,"
- " \"reservations-out-of-pool\": true,"
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"4o6-subnet\": \"\","
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-in-subnet\": true,"
- " \"reservations-out-of-pool\": true,"
" \"rapid-commit\": false,"
" \"hostname-char-set\": \"\""
" },"
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-in-subnet\": true,"
- " \"reservations-out-of-pool\": true,"
" \"rapid-commit\": false"
" }"
" ]"
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
-
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
" \"renew-timer\": 100,\n"
" \"require-client-classes\": [ \"foo\" ],\n"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
" \"renew-timer\": 100,\n"
" \"require-client-classes\": [ \"foo\" ],\n"
" \"reservations-in-subnet\": true,\n"
- " \"reservations-out-of-pool\": true,\n"
" \"subnet6\": [\n"
" {\n"
" \"id\": 1,\n"