2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-29 13:07:50 +00:00

[#1405] merged first pass

This commit is contained in:
Razvan Becheriu 2020-11-11 11:06:18 +02:00
parent 051aededa4
commit 8d05ba02b2
32 changed files with 611 additions and 818 deletions

View File

@ -695,8 +695,9 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and "reservations-out-of-pool"
// parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -705,7 +706,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved addresses
// are out-of-pool.
"reservations-out-of-pool": false,
// List of client classes which must be evaluated when this shared
@ -869,8 +871,9 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and
// "reservations-out-of-pool" parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -879,7 +882,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved
// addresses are out-of-pool.
"reservations-out-of-pool": false,
// Subnet level compute T1 and T2 timers.
@ -1008,8 +1012,8 @@
},
// Fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and "reservations-out-of-pool" parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -1018,7 +1022,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved addresses
// are out-of-pool.
"reservations-out-of-pool": false,
// Global compute T1 and T2 timers.

View File

@ -653,8 +653,9 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and "reservations-out-of-pool"
// parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -663,7 +664,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved addresses
// are out-of-pool.
"reservations-out-of-pool": false,
// List of client classes which must be evaluated when this shared
@ -850,8 +852,9 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and
// "reservations-out-of-pool" parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -860,7 +863,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved
// addresses are out-of-pool.
"reservations-out-of-pool": false,
// Subnet level compute T1 and T2 timers.
@ -986,8 +990,8 @@
},
// Fetches host reservations.
// It is deprecated by the "reservations-out-of-pool",
// "reservations-in-subnet" and "reservations-global" parameters.
// It is replaced by the "reservations-global",
// "reservations-in-subnet" and "reservations-out-of-pool" parameters.
// "reservation-mode": "all",
// Specify if server should lookup global reservations.
@ -996,7 +1000,8 @@
// Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
// Specify if server should lookup out-of-pool reservations.
// Specify if server can assume that all reserved addresses
// are out-of-pool.
"reservations-out-of-pool": false,
// Data directory.

View File

@ -4106,6 +4106,15 @@ another.
that must be given due consideration when using them, please see
:ref:`reservation4-conflict` for more details.
.. note::
Beginning with Kea 1.9.1 reservation mode was replaced by three
boolean flags ``"reservations-global"``, ``"reservations-in-subnet"``
and ``"reservations-out-of-pool"`` which allow to configure host
reservations both global and in a subnet. In such case a subnet
host reservation has the preference on a global reservation
when both exist for the same client.
.. _reservation4-conflict:
Conflicts in DHCPv4 Reservations
@ -4622,11 +4631,26 @@ An example configuration using global reservations is shown below:
]
}
Since Kea 1.9.1, the ``reservation-mode`` is deprecated by the
``reservations-out-of-pool``, ``reservations-in-subnet`` and
``reservations-global`` flags.
Since Kea 1.9.1, the ``reservation-mode`` is replaced by the
``reservations-global``, ``reservations-in-subnet`` and
``reservations-out-of-pool`` flags.
The flags can be activated independently and can produce various combinations,
some of them being unsupported by the deprecated ``reservation-mode``.
some of them being unsuported by the deprecated ``reservation-mode``.
The meaning of these flags are:
- ``reservations-global``: fetch global reservations.
- ``reservations-in-subnet``: fetch subnet reservations. For a shared network
this includes all subnets member of the shared network.
- ``reservations-out-of-pool``: the makes sense only when the
``reservations-in-subnet`` flag is true. When ``reservations-out-of-pool``
is true the server may assume that all host reservations of the subnet are
for addresses that do not belong to the dynamic pool as described in the
``out-of-pool`` reservation mode.
The ``reservation-mode`` will be deprecated in a future Kea version.
The correspondence of old values are:
@ -4881,14 +4905,16 @@ following can be used:
"valid-lifetime": 600,
"subnet4": [ {
"subnet": "10.0.0.0/24",
# It is deprecated by the "reservations-out-of-pool",
# "reservations-in-subnet" and "reservations-global" parameters.
# It is replaced by the "reservations-global"
# "reservations-in-subnet" and "reservations-out-of-pool"
# parameters.
# "reservation-mode": "global",
# Specify if server should lookup global reservations.
"reservations-global": true,
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": false,
# Specify if server should lookup out-of-pool reservations.
# Specify if server can assume that all reserved addresses
# are out-of-pool.
"reservations-out-of-pool": false,
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ]
} ]
@ -4992,14 +5018,14 @@ following example:
"hw-address": "aa:bb:cc:dd:ee:fe",
"client-classes": [ "reserved_class" ]
}],
# It is deprecated by the "reservations-out-of-pool",
# "reservations-in-subnet" and "reservations-global" parameters.
# "reservation-mode": "global",
# It is replaced by the "reservations-global"
# "reservations-in-subnet" and "reservations-out-of-pool" parameters.
# Specify if server should lookup global reservations.
"reservations-global": true,
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": false,
# Specify if server should lookup out-of-pool reservations.
# Specify if server can assume that all reserved addresses
# are out-of-pool.
"reservations-out-of-pool": false,
"shared-networks": [{
"subnet4": [

View File

@ -3606,6 +3606,15 @@ another.
that must be given due consideration. Please see
:ref:`reservation6-conflict` for more details.
.. note::
Beginning with Kea 1.9.1 reservation mode was replaced by three
boolean flags ``"reservations-global"``, ``"reservations-in-subnet"``
and ``"reservations-out-of-pool"`` which allow to configure host
reservations both global and in a subnet. In such case a subnet
host reservation has the preference on a global reservation
when both exist for the same client.
.. _reservation6-conflict:
Conflicts in DHCPv6 Reservations
@ -4031,11 +4040,11 @@ An example configuration that disables reservations looks as follows:
"Dhcp6": {
"subnet6": [
{
{
"subnet": "2001:db8:1::/64",
"reservation-mode": "disabled",
...
}
}
]
}
@ -4067,11 +4076,26 @@ An example configuration using global reservations is shown below:
]
}
Since Kea 1.9.1, the ``reservation-mode`` is deprecated by the
``reservations-out-of-pool``, ``reservations-in-subnet`` and
``reservations-global`` flags.
Since Kea 1.9.1, the ``reservation-mode`` is replaced by the
``reservations-global``, ``reservations-in-subnet`` and
``reservations-out-of-pool`` flags.
The flags can be activated independently and can produce various combinations,
some of them being unsupported by the deprecated ``reservation-mode``.
some of them being unsuported by the deprecated ``reservation-mode``.
The meaning of these flags are:
- ``reservations-global``: fetch global reservations.
- ``reservations-in-subnet``: fetch subnet reservations. For a shared network
this includes all subnets member of the shared network.
- ``reservations-out-of-pool``: the makes sense only when the
``reservations-in-subnet`` flag is true. When ``reservations-out-of-pool``
is true the server may assume that all host reservations of the subnet are
for addresses or prefixes that do not belong to the dynamic pool as described
in the ``out-of-pool`` reservation mode.
The ``reservation-mode`` will be deprecated in a future Kea version.
The correspondence of old values are:
@ -4166,7 +4190,7 @@ For this reason, the ``in-subnet`` can be omitted when ``out-of-pool`` is set.
::
"Dhcp4": {
"Dhcp6": {
"reservations-global": true,
"reservations-out-of-pool": true,
@ -4182,13 +4206,13 @@ An example configuration that disables reservations looks as follows:
"Dhcp6": {
"subnet6": [
{
{
"subnet": "2001:db8:1::/64",
"reservations-global": false,
"reservations-in-subnet": false,
"reservations-out-of-pool": false,
...
}
}
]
}
@ -4322,14 +4346,16 @@ following can be used:
"valid-lifetime": 600,
"subnet4": [ {
"subnet": "2001:db8:1::/64",
# It is deprecated by the "reservations-out-of-pool",
# "reservations-in-subnet" and "reservations-global" parameters.
# It is replaced by the "reservations-global"
# "reservations-in-subnet" and "reservations-out-of-pool"
# parameters.
# "reservation-mode": "global",
# Specify if server should lookup global reservations.
"reservations-global": true,
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": false,
# Specify if server should lookup out-of-pool reservations.
# Specify if server can assume that all reserved addresses
# are out-of-pool.
"reservations-out-of-pool": false,
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ]
} ]
@ -4433,14 +4459,14 @@ following example:
"hw-address": "aa:bb:cc:dd:ee:fe",
"client-classes": [ "reserved_class" ]
}],
# It is deprecated by the "reservations-out-of-pool",
# "reservations-in-subnet" and "reservations-global" parameters.
# "reservation-mode": "global",
# It is replaced by the "reservations-global"
# "reservations-in-subnet" and "reservations-out-of-pool" parameters.
# Specify if server should lookup global reservations.
"reservations-global": true,
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": false,
# Specify if server should lookup out-of-pool reservations.
# Specify if server can assume that all reserved addresses
# are out-of-pool.
"reservations-out-of-pool": false,
"shared-networks": [{
"subnet6": [

View File

@ -2655,14 +2655,15 @@ An example response could look as follows:
"ip-address": "0.0.0.0"
},
"renew-timer": 60,
# It is deprecated by the "reservations-out-of-pool",
# "reservations-in-subnet" and "reservations-global" parameters.
# It is replaced by the "reservations-global"
# "reservations-in-subnet" and "reservations-out-of-pool" parameters.
# "reservation-mode": "all",
# Specify if server should lookup global reservations.
"reservations-global": false,
# Specify if server should lookup in-subnet reservations.
"reservations-in-subnet": true,
# Specify if server should lookup out-of-pool reservations.
# Specify if server can assume that all reserved addresses
# are out-of-pool.
"reservations-out-of-pool": false,
"subnet4": [
{

View File

@ -513,7 +513,7 @@ EOF
run_statement "dhcp4_option_def_server" "$qry"
# table: dhcp4_shared_network
qry="select id, name, client_class, interface, match_client_id, modification_ts, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, user_context, valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent, boot_file_name, next_server, server_hostname from dhcp4_shared_network"
qry="select id, name, client_class, interface, match_client_id, modification_ts, rebind_timer, relay, renew_timer, require_client_classes, user_context, valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent, boot_file_name, next_server, server_hostname from dhcp4_shared_network"
run_statement "dhcp4_shared_network" "$qry"
# table: dhcp4_shared_network_server
@ -521,7 +521,7 @@ EOF
run_statement "dhcp4_shared_network_server" "$qry"
# table: dhcp4_subnet
qry="select subnet_prefix, 4o6_interface, 4o6_interface_id, 4o6_subnet, boot_file_name, client_class, interface, match_client_id, modification_ts, next_server, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, server_hostname, shared_network_name, subnet_id, user_context, valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent from dhcp4_subnet"
qry="select subnet_prefix, 4o6_interface, 4o6_interface_id, 4o6_subnet, boot_file_name, client_class, interface, match_client_id, modification_ts, next_server, rebind_timer, relay, renew_timer, require_client_classes, server_hostname, shared_network_name, subnet_id, user_context, valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent from dhcp4_subnet"
run_statement "dhcp4_subnet" "$qry"
# table: dhcp4_pool
@ -569,7 +569,7 @@ EOF
run_statement "dhcp6_option_def_server" "$qry"
# table: dhcp6_shared_network
qry="select id, name, client_class, interface, modification_ts, preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, user_context, valid_lifetime, calculate_tee_times, t1_percent, t2_percent, interface_id from dhcp6_shared_network"
qry="select id, name, client_class, interface, modification_ts, preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, user_context, valid_lifetime, calculate_tee_times, t1_percent, t2_percent, interface_id from dhcp6_shared_network"
run_statement "dhcp6_shared_network" "$qry"
# table: dhcp6_shared_network_server
@ -577,7 +577,7 @@ EOF
run_statement "dhcp6_shared_network" "$qry"
# table: dhcp6_subnet
qry="select subnet_prefix, client_class, interface, modification_ts, preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, shared_network_name, subnet_id, user_context, valid_lifetime, calculate_tee_times, t1_percent, t2_percent, interface_id from dhcp6_subnet"
qry="select subnet_prefix, client_class, interface, modification_ts, preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, shared_network_name, subnet_id, user_context, valid_lifetime, calculate_tee_times, t1_percent, t2_percent, interface_id from dhcp6_subnet"
run_statement "dhcp6_subnet" "$qry"
# table: dhcp6_subnet_server
@ -700,19 +700,19 @@ EOF
# New lifetime bounds.
# table: dhcp4_shared_network
qry="select id, name, client_class, interface, match_client_id, modification_ts, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent, boot_file_name, next_server, server_hostname from dhcp4_shared_network"
qry="select id, name, client_class, interface, match_client_id, modification_ts, rebind_timer, relay, renew_timer, require_client_classes, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent, boot_file_name, next_server, server_hostname from dhcp4_shared_network"
run_statement "dhcp4_shared_network" "$qry"
# table: dhcp4_subnet
qry="select subnet_prefix, 4o6_interface, 4o6_interface_id, 4o6_subnet, boot_file_name, client_class, interface, match_client_id, modification_ts, next_server, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, server_hostname, shared_network_name, subnet_id, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent from dhcp4_subnet"
qry="select subnet_prefix, 4o6_interface, 4o6_interface_id, 4o6_subnet, boot_file_name, client_class, interface, match_client_id, modification_ts, next_server, rebind_timer, relay, renew_timer, require_client_classes, server_hostname, shared_network_name, subnet_id, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, authoritative, calculate_tee_times, t1_percent, t2_percent from dhcp4_subnet"
run_statement "dhcp4_subnet" "$qry"
# table: dhcp6_shared_network
qry="select id, name, client_class, interface, modification_ts, preferred_lifetime, min_preferred_lifetime, max_preferred_lifetime,rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, calculate_tee_times, t1_percent, t2_percent from dhcp6_shared_network"
qry="select id, name, client_class, interface, modification_ts, preferred_lifetime, min_preferred_lifetime, max_preferred_lifetime,rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, calculate_tee_times, t1_percent, t2_percent from dhcp6_shared_network"
run_statement "dhcp6_shared_network" "$qry"
# table: dhcp6_subnet
qry="select subnet_prefix, client_class, interface, modification_ts, preferred_lifetime, min_preferred_lifetime, max_preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, reservation_mode, shared_network_name, subnet_id, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, calculate_tee_times, t1_percent, t2_percent from dhcp6_subnet"
qry="select subnet_prefix, client_class, interface, modification_ts, preferred_lifetime, min_preferred_lifetime, max_preferred_lifetime, rapid_commit, rebind_timer, relay, renew_timer, require_client_classes, shared_network_name, subnet_id, user_context, valid_lifetime, min_valid_lifetime, max_valid_lifetime, calculate_tee_times, t1_percent, t2_percent from dhcp6_subnet"
run_statement "dhcp6_subnet" "$qry"
# table: dhcp4_pool (should include three new columns)

View File

@ -459,7 +459,9 @@ const char* DORA_CONFIGS[] = {
"\"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\","
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
" \"reservation-mode\": \"all\","
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": false,"
" \"reservations\": [ "
" {"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
@ -477,7 +479,9 @@ const char* DORA_CONFIGS[] = {
"\"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\","
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
" \"reservation-mode\": \"disabled\","
" \"reservations-global\": false,"
" \"reservations-in-subnet\": false,"
" \"reservations-out-of-pool\": false,"
" \"reservations\": [ "
" {"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
@ -495,7 +499,9 @@ const char* DORA_CONFIGS[] = {
"\"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\","
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
" \"reservation-mode\": \"out-of-pool\","
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": true,"
" \"reservations\": [ "
" {"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
@ -1803,8 +1809,8 @@ TEST_F(DORATest, reservationModeDisabled) {
// Set explicit HW address so as it matches the reservation in the
// configuration used below.
client.setHWAddress("aa:bb:cc:dd:ee:ff");
// Configure DHCP server. In this configuration the reservation mode is
// set to disabled. Thus, the server should ignore the reservation for
// Configure DHCP server. In this configuration the reservation flags are
// set to false. Thus, the server should ignore the reservation for
// this client.
configure(DORA_CONFIGS[13], *client.getServer());
// Client requests the 10.0.0.50 address and the server should assign it

View File

@ -34,7 +34,7 @@ namespace {
/// - 1 subnet: 10.0.0.0/24
const char* CONFIGS[] = {
// Configuration 0
// 1 subnet, mode HR_GLOBAL,
// 1 subnet, global only,
// global reservations for different identifier types
"{ \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -66,14 +66,17 @@ const char* CONFIGS[] = {
"],\n"
"\"valid-lifetime\": 600,\n"
"\"subnet4\": [ { \n"
" \"subnet\": \"10.0.0.0/24\", \n"
" \"subnet\": \"10.0.0.0/24\",\n"
" \"reservations-global\": true,\n"
" \"reservations-in-subnet\": false,\n"
" \"reservations-out-of-pool\": false,\n"
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]\n"
"} ]\n"
"}\n"
,
// Configuration 1 global vs in-pool
// 2 subnets, one mode default (aka HR_ALL), one mode HR_GLOBAL
// Configuration 1 global vs in-subnet
// 2 subnets, one default reservations flags (aka in-subnet),
// one reservations flags global only
// Host reservations for the same client, one global, one in each subnet
"{ \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
@ -103,6 +106,8 @@ const char* CONFIGS[] = {
" \"pools\": [ { \"pool\": \"192.0.2.10-192.0.2.63\" } ],\n"
" \"interface\": \"eth1\",\n"
" \"reservations-global\": true,\n"
" \"reservations-in-subnet\": false,\n"
" \"reservations-out-of-pool\": false,\n"
" \"reservations\": [ \n"
" {\n"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
@ -112,7 +117,7 @@ const char* CONFIGS[] = {
"]\n"
"}\n"
,
// Configuration 2 global and out-of-pool
// Configuration 2 global and in-subnet with out-of-pool
"{ \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
"},\n"
@ -129,6 +134,8 @@ const char* CONFIGS[] = {
" \"id\": 10,"
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],\n"
" \"interface\": \"eth0\",\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": true,\n"
" \"reservations\": [ \n"
" {\n"
@ -140,7 +147,7 @@ const char* CONFIGS[] = {
"]\n"
"}\n"
,
// Configuration 3 global and all
// Configuration 3 global and in-subnet
"{ \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
"},\n"
@ -157,7 +164,9 @@ const char* CONFIGS[] = {
" \"id\": 10,"
" \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],\n"
" \"interface\": \"eth0\",\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"reservations\": [ \n"
" {\n"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
@ -184,6 +193,8 @@ const char* CONFIGS[] = {
"}"
"],\n"
"\"reservations-global\": true,\n"
"\"reservations-in-subnet\": false,\n"
"\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 600,\n"
"\"reservations\": [ \n"
"{\n"
@ -235,6 +246,8 @@ const char* CONFIGS[] = {
"}"
"],\n"
"\"reservations-global\": true,\n"
"\"reservations-in-subnet\": false,\n"
"\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 600,\n"
"\"reservations\": [ \n"
"{\n"
@ -340,7 +353,7 @@ const char* CONFIGS[] = {
"}",
// Configuration 8 both global and in-subnet
// 2 subnets, one reservations flags default (aka in-subnet),
// 2 subnets, one default reservations flags (aka in-subnet),
// one reservations flags global and in-subnet.
// Host reservations for the same client, one global, one in each subnet
"{ \"interfaces-config\": {\n"
@ -372,6 +385,7 @@ const char* CONFIGS[] = {
" \"interface\": \"eth1\",\n"
" \"reservations-global\": true,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"reservations\": [ \n"
" {\n"
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n"
@ -556,7 +570,8 @@ public:
};
// Verifies that a client, which fails to match to a global
// reservation, still gets a dynamic address when subnet mode is HR_GLOBAL
// reservation, still gets a dynamic address when subnet reservations
// flags are global only.
TEST_F(HostTest, globalHardwareNoMatch) {
Dhcp4Client client(Dhcp4Client::SELECTING);
@ -566,7 +581,7 @@ TEST_F(HostTest, globalHardwareNoMatch) {
// Verifies that a client, that matches to a global hostname
// reservation, gets both the hostname and a dynamic address,
// when the subnet mode is HR_GLOBAL
// when the subnet reservations flags are global only.
TEST_F(HostTest, globalHardwareDynamicAddress) {
Dhcp4Client client(Dhcp4Client::SELECTING);
@ -576,7 +591,7 @@ TEST_F(HostTest, globalHardwareDynamicAddress) {
// Verifies that a client matched to a global address reservation
// gets both the hostname and the reserved address
// when the subnet mode is HR_GLOBAL
// when the subnet reservations flags are global only.
TEST_F(HostTest, globalHardwareFixedAddress) {
Dhcp4Client client(Dhcp4Client::SELECTING);
@ -632,22 +647,22 @@ TEST_F(HostTest, globalClientID) {
// Verifies that even when a matching global reservation exists,
// client will get a subnet scoped reservation, when subnet
// reservation mode is default
// reservations flags are default
TEST_F(HostTest, defaultOverGlobal) {
Dhcp4Client client(Dhcp4Client::SELECTING);
// Hardware address matches all reservations
client.setHWAddress("aa:bb:cc:dd:ee:ff");
// Subnet 10 usses default HR mode(i.e. "in-pool"), so its
// Subnet 10 uses default reservations flags (i.e. in-subnet), so its
// reservation should be used, rather than global.
runDoraTest(CONFIGS[1], client, "subnet-10-host", "10.0.0.10");
}
// Verifies that when there are matching reservations at
// both the global and subnet levels, client will be matched
// to the global reservation, when subnet reservation mode
// is HR_GLOBAL.
// to the global reservation, when subnet reservations flags
// are global only.
TEST_F(HostTest, globalOverSubnet) {
Dhcp4Client client(Dhcp4Client::SELECTING);
@ -658,44 +673,44 @@ TEST_F(HostTest, globalOverSubnet) {
client.setIfaceName("eth1");
client.setIfaceIndex(ETH1_INDEX);
// Subnet 20 usses global HR mode, so the global
// Subnet 20 uses global only reservations flags, so the global
// reservation should be used, rather than the subnet one.
runDoraTest(CONFIGS[1], client, "global-host", "192.0.2.10");
}
// Verifies that when there are matching reservations at
// both the global and subnet levels, client will be matched
// to the subnet reservation, when subnet reservation mode
// is HR_OUT_OF_POOL
// to the subnet reservation, when subnet reservations flags
// are in-subnet and out-of-pool.
TEST_F(HostTest, outOfPoolOverGlobal) {
Dhcp4Client client(Dhcp4Client::SELECTING);
// Hardware address matches all reservations
client.setHWAddress("aa:bb:cc:dd:ee:ff");
// Subnet 10 uses "out-of-pool" HR mode, so its
// reservation should be used, rather than global.
// Subnet 10 uses in-subnet and out-of-pool reservations flags,
// so its reservation should be used, rather than global.
runDoraTest(CONFIGS[2], client, "subnet-10-host", "10.0.0.105");
}
// Verifies that when there are matching reservations at
// both the global and subnet levels, client will be matched
// to the subnet reservation, when subnet reservation mode
// is HR_ALL
// to the subnet reservation, when subnet reservations flags
// are in-subnet only.
TEST_F(HostTest, allOverGlobal) {
Dhcp4Client client(Dhcp4Client::SELECTING);
// Hardware address matches all reservations
client.setHWAddress("aa:bb:cc:dd:ee:ff");
// Subnet 10 uses default HR mode(i.e. "all"), so its
// Subnet 10 uses default reservations flags (i.e. in-subnet), so its
// reservation should be used, rather than global.
runDoraTest(CONFIGS[3], client, "subnet-10-host", "10.0.0.105");
}
// Verifies that when there are matching reservations at
// both the global and subnet levels, client will be matched
// to the subnet reservation, when subnet reservation true flags
// to the subnet reservation, when subnet reservations flags
// are global and in-subnet, i.e. the subnet has the preference.
TEST_F(HostTest, subnetOverGlobal) {
Dhcp4Client client(Dhcp4Client::SELECTING);

View File

@ -4289,4 +4289,3 @@ Dhcpv6Srv::checkDynamicSubnetChange(const Pkt6Ptr& question, Pkt6Ptr& answer,
} // namespace dhcp
} // namespace isc

View File

@ -57,6 +57,7 @@ namespace {
/// - Similar to Configuration 6, but one of the addresses reserved to client
/// with the DUID 04:03:02:01.
///
/// Descriptions of next configurations are in the comment with the number.
const char* CONFIGS[] = {
// Configuration 0:
"{ "
@ -350,12 +351,16 @@ const char* CONFIGS[] = {
"\"mac-sources\": [ \"ipv6-link-local\" ], \n"
"\"subnet6\": [ \n"
" { \n"
" \"id\": 1, \n"
" \"subnet\": \"2001:db8:1::/48\", \n"
" \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], \n"
" \"interface\" : \"eth0\", \n"
" \"reservations-global\": true\n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": false \n"
" },"
" { \n"
" \"id\": 2, \n"
" \"subnet\": \"2001:db8:2::/48\", \n"
" \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ], \n"
" \"interface\" : \"eth1\", \n"
@ -392,9 +397,12 @@ const char* CONFIGS[] = {
"\"mac-sources\": [ \"ipv6-link-local\" ], \n"
"\"subnet6\": [ \n"
" { \n"
" \"id\": 1, \n"
" \"subnet\": \"2001:db8:1::/48\", \n"
" \"interface\" : \"eth0\", \n"
" \"reservations-global\": true,\n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": false, \n"
" \"pd-pools\": [ \n"
" { \n"
" \"prefix\": \"3000::\", \n"
@ -403,6 +411,7 @@ const char* CONFIGS[] = {
" }] \n"
" },"
" { \n"
" \"id\": 2, \n"
" \"subnet\": \"2001:db8:2::/48\", \n"
" \"interface\" : \"eth1\", \n"
" \"pd-pools\": [ \n"
@ -436,6 +445,8 @@ const char* CONFIGS[] = {
"}"
"],\n"
"\"reservations-global\": true,\n"
"\"reservations-in-subnet\": false,\n"
"\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 4000,\n"
"\"reservations\": [ \n"
"{\n"
@ -488,6 +499,8 @@ const char* CONFIGS[] = {
"}"
"],\n"
"\"reservations-global\": true,\n"
"\"reservations-in-subnet\": false,\n"
"\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 4000,\n"
"\"reservations\": [ \n"
"{\n"
@ -2383,7 +2396,7 @@ TEST_F(HostTest, globalReservationsNA) {
}
{
SCOPED_TRACE("Default subnet mode excludes Global HR");
SCOPED_TRACE("Default subnet reservations flags excludes global reservations");
client.clearConfig();
client.setInterface("eth1");
client.setDUID("01:02:03:04");
@ -2408,7 +2421,8 @@ TEST_F(HostTest, globalReservationsNA) {
Subnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()->
getCfgSubnets6()->getSubnet(2);
ASSERT_TRUE(subnet);
subnet->setHostReservationMode(Network::HR_IN_SUBNET|Network::HR_GLOBAL);
subnet->setReservationsGlobal(true);
subnet->setReservationsInSubnet(true);
client.clearConfig();
client.setInterface("eth1");
client.setDUID("01:02:03:05");
@ -2445,7 +2459,7 @@ TEST_F(HostTest, globalReservationsPD) {
}
{
SCOPED_TRACE("Default subnet mode excludes Global HR");
SCOPED_TRACE("Default subnet reservations flags excludes global reservations");
client.clearConfig();
client.setInterface("eth1");
client.setDUID("01:02:03:04");
@ -2470,7 +2484,8 @@ TEST_F(HostTest, globalReservationsPD) {
Subnet6Ptr subnet = CfgMgr::instance().getCurrentCfg()->
getCfgSubnets6()->getSubnet(2);
ASSERT_TRUE(subnet);
subnet->setHostReservationMode(Network::HR_IN_SUBNET|Network::HR_GLOBAL);
subnet->setReservationsGlobal(true);
subnet->setReservationsInSubnet(true);
client.clearConfig();
client.setInterface("eth1");
client.setDUID("01:02:03:05");

View File

@ -360,9 +360,9 @@
// specific options.
//
// When using reservations, it is useful to configure
// reservations-out-of-pool, reservations-in-subnet,
// reservations-global (subnet specific parameters) and
// host-reservation-identifiers (global parameter).
// reservations-global, reservations-in-subnet,
// reservations-out-of-pool (subnet specific parameters)
// and host-reservation-identifiers (global parameter).
{
"client-id": "01:12:23:34:45:56:67",
"ip-address": "192.0.2.204",

View File

@ -45,8 +45,6 @@ EXTRA_DIST += parsers/ifaces_config_parser.h
EXTRA_DIST += parsers/multi_threading_config_parser.cc
EXTRA_DIST += parsers/multi_threading_config_parser.h
EXTRA_DIST += parsers/option_data_parser.h
EXTRA_DIST += parsers/reservation_modes_parser.cc
EXTRA_DIST += parsers/reservation_modes_parser.h
EXTRA_DIST += parsers/sanity_checks_parser.cc
EXTRA_DIST += parsers/sanity_checks_parser.h
EXTRA_DIST += parsers/simple_parser4.cc
@ -180,8 +178,6 @@ libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.cc
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.h
libkea_dhcpsrv_la_SOURCES += parsers/shared_network_parser.cc
@ -412,7 +408,6 @@ libkea_dhcpsrv_parsers_include_HEADERS = \
parsers/multi_threading_config_parser.h \
parsers/option_data_parser.h \
parsers/dhcp_queue_control_parser.h \
parsers/reservation_modes_parser.h \
parsers/sanity_checks_parser.h \
parsers/shared_network_parser.h \
parsers/shared_networks_list_parser.h \

View File

@ -651,12 +651,15 @@ public:
/// @brief Returns host from the most preferred subnet.
///
/// If there is no such host and global reservations are enabled
/// returns the global host.
///
/// @return Pointer to the host object.
ConstHostPtr currentHost() const;
/// @brief Returns global host reservation if there is one
///
/// If the current subnet's reservation mode is global and
/// If the current subnet's reservations-global is true and
/// there is a global host (i.e. reservation belonging to
/// the global subnet), return it. Otherwise return an
/// empty pointer.
@ -666,8 +669,8 @@ public:
/// @brief Determines if a global reservation exists
///
/// @return true if there current subnet's reservation mode is
/// global and there is global host containing the given
/// @return true if there current subnet's reservations-global
/// is true and there is global host containing the given
/// lease reservation, false otherwise
bool hasGlobalReservation(const IPv6Resrv& resv) const;
@ -1024,14 +1027,13 @@ private:
/// @brief Creates new leases based on reservations.
///
/// This method allcoates new leases, based on host reservations.
/// Existing leases are specified in the existing_leases parameter.
/// It first calls @c allocateGlobalReservedLeases6 to accomodate
/// subnets using global reservations. If that method allocates
/// addresses, we return, otherwise we continue and check for non-global
/// reservations. A new lease is not created, if there is a lease for
/// specified address on existing_leases list or there is a lease used by
/// someone else.
/// This method allocates new leases, based on host reservations.
/// Existing leases are specified in the existing_leases
/// parameter. It first checks for non-global reservations. A
/// new lease is not created, if there is a lease for specified
/// address on existing_leases list or there is a lease used by
/// someone else. It last calls @c allocateGlobalReservedLeases6
/// to accomodate subnets using global reservations.
///
/// @param ctx client context that contains all details (subnet, client-id, etc.)
/// @param existing_leases leases that are already associated with the client
@ -1407,12 +1409,15 @@ public:
/// @brief Returns host for currently selected subnet.
///
/// If there is no such host and global reservations are enabled
/// returns the global host.
///
/// @return Pointer to the host object.
ConstHostPtr currentHost() const;
/// @brief Returns global host reservation if there is one
///
/// If the current subnet's reservation mode is global and
/// If the current subnet's reservations-global is true and
/// there is a global host (i.e. reservation belonging to
/// the global subnet), return it. Otherwise return an
/// empty pointer.

View File

@ -19,15 +19,6 @@ using namespace isc::util;
namespace isc {
namespace dhcp {
const uint8_t Network::HR_DISABLED = 0;
const uint8_t Network::HR_OUT_OF_POOL_FLAG = 1 << 0;
const uint8_t Network::HR_IN_SUBNET_FLAG = 1 << 1;
const uint8_t Network::HR_GLOBAL_FLAG = 1 << 2;
const uint8_t Network::HR_OUT_OF_POOL = HR_OUT_OF_POOL_FLAG | HR_IN_SUBNET_FLAG;
const uint8_t Network::HR_IN_SUBNET = HR_IN_SUBNET_FLAG;
const uint8_t Network::HR_GLOBAL = HR_GLOBAL_FLAG;
const uint8_t Network::HR_ALL = Network::HR_IN_SUBNET;
void
Network::RelayInfo::addAddress(const asiolink::IOAddress& addr) {
if (containsAddress(addr)) {
@ -108,24 +99,6 @@ Network::getRequiredClasses() const {
return (required_classes_);
}
Network::HRMode
Network::hrModeFromString(const std::string& hr_mode_name) {
if ( (hr_mode_name.compare("disabled") == 0) ||
(hr_mode_name.compare("off") == 0) ) {
return (Network::HR_DISABLED);
} else if (hr_mode_name.compare("out-of-pool") == 0) {
return (Network::HR_OUT_OF_POOL);
} else if (hr_mode_name.compare("global") == 0) {
return (Network::HR_GLOBAL);
} else if (hr_mode_name.compare("all") == 0) {
return (Network::HR_ALL);
} else {
// Should never happen...
isc_throw(BadValue, "Can't convert '" << hr_mode_name
<< "' into any valid reservation-mode values");
}
}
Optional<IOAddress>
Network::getGlobalProperty(Optional<IOAddress> property,
const std::string& global_name) const {
@ -210,36 +183,22 @@ Network::toElement() const {
}
}
// Set reservation mode
Optional<Network::HRMode> hrmode = host_reservation_mode_;
if (!hrmode.unspecified()) {
bool hr_global = false;
bool hr_in_subnet = false;
bool hr_out_of_pool = false;
if (hrmode & Network::HR_GLOBAL) {
hr_global = true;
}
if (hrmode & Network::HR_IN_SUBNET_FLAG) {
hr_in_subnet = true;
}
if (hrmode & Network::HR_OUT_OF_POOL_FLAG) {
hr_out_of_pool = true;
}
if (hrmode == Network::HR_DISABLED) {
map->set("reservations-global", Element::create(false));
map->set("reservations-in-subnet", Element::create(false));
map->set("reservations-out-of-pool", Element::create(false));
} else {
if (hr_global) {
map->set("reservations-global", Element::create(true));
}
if (hr_in_subnet) {
map->set("reservations-in-subnet", Element::create(true));
}
if (hr_out_of_pool) {
map->set("reservations-out-of-pool", Element::create(true));
}
}
// Set reservations-global
if (!reservations_global_.unspecified()) {
map->set("reservations-global",
Element::create(reservations_global_.get()));
}
// Set reservations-in-subnet
if (!reservations_in_subnet_.unspecified()) {
map->set("reservations-in-subnet",
Element::create(reservations_in_subnet_.get()));
}
// Set reservations-out-of-pool
if (!reservations_out_of_pool_.unspecified()) {
map->set("reservations-out-of-pool",
Element::create(reservations_out_of_pool_.get()));
}
// Set options

View File

@ -152,48 +152,6 @@ public:
IOAddressList addresses_;
};
/// @brief Specifies allowed host reservation mode.
///
/// None - host reservation is disabled. No reservation types
/// are allowed.
static const uint8_t HR_DISABLED; // value: 0
/// The out-of-pool reservations flag.
static const uint8_t HR_OUT_OF_POOL_FLAG; // value: 1 << 0
/// The in-subnet flag.
static const uint8_t HR_IN_SUBNET_FLAG; // value: 1 << 1
/// The global flag.
static const uint8_t HR_GLOBAL_FLAG; // value: 1 << 2
/// Only out-of-pool reservations is allowed. This mode allows AllocEngine
/// to skip reservation checks for dynamically allocated addressed.
/// When this is set, both HR_OUT_OF_POOL_FLAG and HR_IN_SUBNET_FLAG are
/// enabled 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: HR_OUT_OF_POOL_FLAG | HR_IN_SUBNET_FLAG
/// 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: HR_IN_SUBNET_FLAG
/// Only global reservations are allowed. This mode instructs AllocEngine
/// to only look at global reservations.
static const uint8_t HR_GLOBAL; // value: HR_GLOBAL_FLAG
/// 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;
/// @brief Inheritance "mode" used when fetching an optional @c Network
/// parameter.
///
@ -218,7 +176,8 @@ public:
/// @brief Constructor.
Network()
: iface_name_(), client_class_(), t1_(), t2_(), valid_(),
host_reservation_mode_(HR_ALL, true), cfg_option_(new CfgOption()),
reservations_global_(false, true), reservations_in_subnet_(true, true),
reservations_out_of_pool_(false, true), cfg_option_(new CfgOption()),
calculate_tee_times_(), t1_percent_(), t2_percent_(),
ddns_send_updates_(), ddns_override_no_update_(), ddns_override_client_update_(),
ddns_replace_client_name_mode_(), ddns_generated_prefix_(), ddns_qualifying_suffix_(),
@ -412,105 +371,59 @@ public:
t2_ = t2;
}
/// @brief Specifies what type of Host Reservations are supported.
///
/// 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 in-subnet but not in-pool)
/// or global (they are defined at global level). HR may also be completely
/// disabled for performance reasons.
/// @brief Returns whether global reservations should be fetched.
///
/// @param inheritance inheritance mode to be used.
/// @return Host reservation mode enabled.
util::Optional<HRMode>
getHostReservationMode(const Inheritance& inheritance = Inheritance::ALL) const {
// Inheritance for host reservations is a little different than for other
// parameters. The reservation at the global level is given as a string.
// Thus we call getProperty here without a global name to check if the
// host reservation mode is specified on network level only.
const util::Optional<HRMode>& hr_mode = getProperty<Network>(&Network::getHostReservationMode,
host_reservation_mode_,
inheritance);
// If HR mode is not specified at network level we need this special
// case code to handle conversion of the globally configured HR
// mode to an enum.
if (hr_mode.unspecified() && (inheritance != Inheritance::NONE) &&
(inheritance != Inheritance::PARENT_NETWORK)) {
// Get global reservation mode.
util::Optional<std::string> hr_mode_name;
hr_mode_name = getGlobalProperty(hr_mode_name, "reservation-mode");
if (!hr_mode_name.unspecified()) {
try {
// If the HR mode is globally configured, let's convert it from
// a string to enum.
return (hrModeFromString(hr_mode_name.get()));
} catch (...) {
// This should not really happen because the configuration
// parser should have already verified the globally configured
// reservation mode. However, we want to be 100% sure that this
// method doesn't throw. Let's just return unspecified.
return (hr_mode);
}
} else {
// Get global reservation modes and merge the values.
bool found = false;
uint8_t flags = 0;
util::Optional<bool> hr_mode_global;
hr_mode_global = getGlobalProperty(hr_mode_global,
"reservations-global");
if (!hr_mode_global.unspecified()) {
if (hr_mode_global.get()) {
flags |= Network::HR_GLOBAL;
}
found = true;
}
util::Optional<bool> hr_mode_in_subnet;
hr_mode_in_subnet = getGlobalProperty(hr_mode_in_subnet,
"reservations-in-subnet");
if (!hr_mode_in_subnet.unspecified()) {
if (hr_mode_in_subnet.get()) {
flags |= Network::HR_IN_SUBNET;
}
found = true;
}
util::Optional<bool> hr_mode_out_of_pool;
hr_mode_out_of_pool = getGlobalProperty(hr_mode_out_of_pool,
"reservations-out-of-pool");
if (!hr_mode_out_of_pool.unspecified()) {
if (hr_mode_out_of_pool.get()) {
flags |= Network::HR_OUT_OF_POOL;
}
found = true;
}
if (found) {
return (static_cast<Network::HRMode>(flags));
}
}
}
return (hr_mode);
util::Optional<bool>
getReservationsGlobal(const Inheritance& inheritance = Inheritance::ALL) const {
return (getProperty<Network>(&Network::getReservationsGlobal,
reservations_global_,
inheritance,
"reservations-global"));
}
/// @brief Sets host reservation mode.
/// @brief Sets whether global reservations should be fetched.
///
/// See @ref getHostReservationMode for details.
///
/// @param mode mode to be set
void setHostReservationMode(const util::Optional<HRMode>& mode) {
host_reservation_mode_ = mode;
/// @param reservations_global new value of enabled/disabled.
void setReservationsGlobal(const util::Optional<bool>& reservations_global) {
reservations_global_ = reservations_global;
}
/// @brief Attempts to convert text representation to HRMode enum.
/// @brief Returns whether subnet reservations should be fetched.
///
/// Allowed values are "disabled", "off" (alias for disabled),
/// "out-of-pool" and "all". See @c Network::HRMode for their exact meaning.
/// @param inheritance inheritance mode to be used.
util::Optional<bool>
getReservationsInSubnet(const Inheritance& inheritance = Inheritance::ALL) const {
return (getProperty<Network>(&Network::getReservationsInSubnet,
reservations_in_subnet_,
inheritance,
"reservations-in-subnet"));
}
/// @brief Sets whether subnet reservations should be fetched.
///
/// @param hr_mode_name Host Reservation mode in the textual form.
/// @param reservations_in_subnet new value of enabled/disabled.
void setReservationsInSubnet(const util::Optional<bool>& reservations_in_subnet) {
reservations_in_subnet_ = reservations_in_subnet;
}
/// @brief Returns whether only out-of-pool reservations are allowed.
///
/// @throw BadValue if the text cannot be converted.
/// @param inheritance inheritance mode to be used.
util::Optional<bool>
getReservationsOutOfPool(const Inheritance& inheritance = Inheritance::ALL) const {
return (getProperty<Network>(&Network::getReservationsOutOfPool,
reservations_out_of_pool_,
inheritance,
"reservations-out-of-pool"));
}
/// @brief Sets whether only out-of-pool reservations are allowed.
///
/// @return one of allowed HRMode values
static HRMode hrModeFromString(const std::string& hr_mode_name);
/// @param reservations_out_of_pool new value of enabled/disabled.
void setReservationsOutOfPool(const util::Optional<bool>& reservations_out_of_pool) {
reservations_out_of_pool_ = reservations_out_of_pool;
}
/// @brief Returns pointer to the option data configuration for this network.
CfgOptionPtr getCfgOption() {
@ -651,7 +564,7 @@ public:
} catch (...) {
// This should not really happen because the configuration
// parser should have already verified the globally configured
// reservation mode. However, we want to be 100% sure that this
// mode. However, we want to be 100% sure that this
// method doesn't throw. Let's just return unspecified.
return (mode);
}
@ -840,8 +753,8 @@ protected:
/// name. Typically, this method is invoked by @c getProperty when
/// network specific value of the parameter is not found. In some cases
/// it may be called by other methods. One such example is the
/// @c getHostReservationMode which needs to call @c getGlobalProperty
/// explicitly to convert the global host reservation mode value from
/// @c getDdnsReplaceClientNameMode which needs to call @c getGlobalProperty
/// explicitly to convert the global replace client name mode value from
/// a string to an enum.
///
/// @tparam ReturnType Type of the returned value, e.g.
@ -1062,10 +975,18 @@ protected:
/// @brief a Triplet (min/default/max) holding allowed valid lifetime values
Triplet<uint32_t> valid_;
/// @brief Specifies host reservation mode
/// @brief Enables global reservations.
util::Optional<bool> reservations_global_;
/// @brief Enables subnet reservations.
util::Optional<bool> reservations_in_subnet_;
/// @brief Enables out-of-pool reservations optimization.
///
/// See @ref HRMode type for details.
util::Optional<HRMode> host_reservation_mode_;
/// When true only out-of-pool reservations are allowed. This allows
/// AllocEngine to skip reservation checks when dealing with addresses
/// that are in pool.
util::Optional<bool> reservations_out_of_pool_;
/// @brief Pointer to the option data configuration for this subnet.
CfgOptionPtr cfg_option_;
@ -1117,7 +1038,7 @@ protected:
/// @brief Value in seconds to use as cache maximal age.
util::Optional<uint32_t> cache_max_age_;
/// @brief Should Kea perform updates when leases are extended
/// @brief Should Kea perform updates when leases are extended
util::Optional<bool> ddns_update_on_renew_;
/// @brief Used to to tell kea-dhcp-ddns whether or not to use conflict resolution.

View File

@ -1,68 +0,0 @@
// Copyright (C) 2015-2020 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 <cc/data.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/parsers/reservation_modes_parser.h>
#include <string>
#include <sys/types.h>
using namespace isc::data;
using namespace isc::util;
namespace isc {
namespace dhcp {
Network::HRMode
HostReservationModesParser::parse(const ConstElementPtr& config_elem) {
if (config_elem->getType() != Element::map) {
isc_throw(DhcpConfigError, "configuration must be a map");
}
ConstElementPtr elem;
uint8_t flags = 0;
bool force_true = false;
try {
elem = config_elem->get("reservations-out-of-pool");
if (elem) {
bool value = elem->boolValue();
if (value) {
flags |= Network::HR_OUT_OF_POOL;
force_true = true;
}
}
elem = config_elem->get("reservations-in-subnet");
if (elem) {
bool value = elem->boolValue();
if (value) {
flags |= Network::HR_IN_SUBNET;
} else if (force_true) {
isc_throw(DhcpConfigError, "invalid use of disabled 'reservations-in-subnet'"
" when enabled 'reservations-out-of-pool'");
}
}
elem = config_elem->get("reservations-global");
if (elem) {
bool value = elem->boolValue();
if (value) {
flags |= Network::HR_GLOBAL;
}
}
} catch (const Exception& ex) {
isc_throw(DhcpConfigError, "error parsing element: " << ex.what());
}
return (static_cast<Network::HRMode>(flags));
}
} // end of namespace isc::dhcp
} // end of namespace isc

View File

@ -1,42 +0,0 @@
// Copyright (C) 2018 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/.
#ifndef RESERVATION_MODES_PARSER_H
#define RESERVATION_MODES_PARSER_H
#include <cc/data.h>
#include <cc/simple_parser.h>
#include <dhcpsrv/network.h>
#include <dhcpsrv/parsers/dhcp_parsers.h>
namespace isc {
namespace dhcp {
/// @brief Parser for the configuration of DHCP packet queue controls
///
/// This parser parses the "reservation-modes" parameter which holds the
/// the configurable parameters that tailor host reservation modes.
///
/// This parser is used in both DHCPv4 and DHCPv6, and also inside subnet and
/// shared networks.
class HostReservationModesParser : public isc::data::SimpleParser {
public:
/// @brief Parses content of the "reservation-modes".
///
/// @param control_elem MapElement containing the host reservation modes
/// values to parse
///
/// @return Host reservation modes flags.
///
/// @throw DhcpConfigError if any of the values are invalid.
Network::HRMode parse(const isc::data::ConstElementPtr& control_elem);
};
}
} // end of namespace isc
#endif // RESERVATION_MODES_PARSER_H

View File

@ -71,9 +71,9 @@ const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
{ "config-control", Element::map },
{ "server-tag", Element::string },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "calculate-tee-times", Element::boolean },
{ "t1-percent", Element::real },
{ "t2-percent", Element::real },
@ -113,9 +113,9 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
{ "server-hostname", Element::string, "" },
{ "boot-file-name", Element::string, "" },
{ "server-tag", Element::string, "" },
{ "reservations-out-of-pool", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-global", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-out-of-pool", Element::boolean, "false" },
{ "calculate-tee-times", Element::boolean, "false" },
{ "t1-percent", Element::real, ".50" },
{ "t2-percent", Element::real, ".875" },
@ -212,9 +212,9 @@ const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = {
{ "require-client-classes", Element::list },
{ "reservations", Element::list },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "relay", Element::map },
{ "match-client-id", Element::boolean },
{ "authoritative", Element::boolean },
@ -332,9 +332,9 @@ const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = {
{ "boot-file-name", Element::string },
{ "relay", Element::map },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "client-class", Element::string },
{ "require-client-classes", Element::list },
{ "valid-lifetime", Element::integer },

View File

@ -72,9 +72,9 @@ const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = {
{ "config-control", Element::map },
{ "server-tag", Element::string },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "calculate-tee-times", Element::boolean },
{ "t1-percent", Element::real },
{ "t2-percent", Element::real },
@ -109,9 +109,9 @@ const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = {
{ "decline-probation-period", Element::integer, "86400" }, // 24h
{ "dhcp4o6-port", Element::integer, "0" },
{ "server-tag", Element::string, "" },
{ "reservations-out-of-pool", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-global", Element::boolean, "false" },
{ "reservations-in-subnet", Element::boolean, "true" },
{ "reservations-out-of-pool", Element::boolean, "false" },
{ "calculate-tee-times", Element::boolean, "true" },
{ "t1-percent", Element::real, ".50" },
{ "t2-percent", Element::real, ".80" },
@ -214,9 +214,9 @@ const SimpleKeywords SimpleParser6::SUBNET6_PARAMETERS = {
{ "require-client-classes", Element::list },
{ "reservations", Element::list },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "relay", Element::map },
{ "user-context", Element::map },
{ "comment", Element::string },
@ -341,9 +341,9 @@ const SimpleKeywords SimpleParser6::SHARED_NETWORK6_PARAMETERS = {
{ "option-data", Element::list },
{ "relay", Element::map },
{ "reservation-mode", Element::string },
{ "reservations-out-of-pool", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-global", Element::boolean },
{ "reservations-in-subnet", Element::boolean },
{ "reservations-out-of-pool", Element::boolean },
{ "client-class", Element::string },
{ "require-client-classes", Element::list },
{ "preferred-lifetime", Element::integer },

View File

@ -87,7 +87,6 @@ libdhcpsrv_unittests_SOURCES += csv_lease_file6_unittest.cc
libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
libdhcpsrv_unittests_SOURCES += dhcp_queue_control_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += reservation_modes_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += dhcp4o6_ipc_unittest.cc
libdhcpsrv_unittests_SOURCES += duid_config_parser_unittest.cc
libdhcpsrv_unittests_SOURCES += expiration_config_parser_unittest.cc

View File

@ -2899,13 +2899,13 @@ TEST_F(AllocEngine4Test, findReservation) {
EXPECT_TRUE(ctx.currentHost());
EXPECT_EQ(ctx.currentHost()->getIPv4Reservation(), host->getIPv4Reservation());
// It shouldn't be returned when HR_DISABLED mode is enabled.
subnet_->setHostReservationMode(Network::HR_DISABLED);
// It shouldn't be returned when reservations-in-subnet is disabled.
subnet_->setReservationsInSubnet(false);
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_FALSE(ctx.currentHost());
// Check the out of the pool reservation mode.
subnet_->setHostReservationMode(Network::HR_OUT_OF_POOL);
subnet_->setReservationsOutOfPool(true);
ASSERT_NO_THROW(engine.findReservation(ctx));
EXPECT_TRUE(ctx.currentHost());
EXPECT_EQ(ctx.currentHost()->getIPv4Reservation(), host->getIPv4Reservation());
@ -3092,7 +3092,7 @@ TEST_F(AllocEngine4Test, globalReservationReservedAddressDiscover) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3140,7 +3140,7 @@ TEST_F(AllocEngine4Test, globalReservationReservedAddressRequest) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3192,7 +3192,7 @@ TEST_F(AllocEngine4Test, globalReservationDynamicDiscover) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3241,7 +3241,7 @@ TEST_F(AllocEngine4Test, globalReservationDynamicRequest) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3293,7 +3293,8 @@ TEST_F(AllocEngine4Test, mixedReservationReservedAddressDiscover) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3342,7 +3343,8 @@ TEST_F(AllocEngine4Test, mixedReservationReservedAddressRequest) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3398,7 +3400,8 @@ TEST_F(AllocEngine4Test, bothReservationReservedAddressDiscover) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.
@ -3451,7 +3454,8 @@ TEST_F(AllocEngine4Test, bothReservationReservedAddressRequest) {
AllocEngine engine(AllocEngine::ALLOC_ITERATIVE, 0, false);
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Query allocation engine for the lease to be assigned to this
// client without specifying the address to be assigned.

View File

@ -3407,7 +3407,7 @@ TEST_F(AllocEngine6Test, hostDynamicAddress) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_ALL);
subnet_->setReservationsInSubnet(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3498,7 +3498,7 @@ TEST_F(AllocEngine6Test, globalHostDynamicAddress) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3585,7 +3585,7 @@ TEST_F(AllocEngine6Test, globalHostReservedAddress) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3649,7 +3649,7 @@ TEST_F(AllocEngine6Test, globalHostReservedPrefix) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL);
subnet_->setReservationsGlobal(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3717,7 +3717,8 @@ TEST_F(AllocEngine6Test, mixedHostReservedAddress) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3781,7 +3782,8 @@ TEST_F(AllocEngine6Test, mixedHostReservedPrefix) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3858,7 +3860,8 @@ TEST_F(AllocEngine6Test, bothHostReservedAddress) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));
@ -3931,7 +3934,8 @@ TEST_F(AllocEngine6Test, bothHostReservedPrefix) {
CfgMgr::instance().getStagingCfg()->getCfgHosts()->add(host);
CfgMgr::instance().commit();
subnet_->setHostReservationMode(Network::HR_GLOBAL|Network::HR_IN_SUBNET);
subnet_->setReservationsGlobal(true);
subnet_->setReservationsInSubnet(true);
// Create context which will be used to try to allocate leases
Pkt6Ptr query(new Pkt6(DHCPV6_REQUEST, 1234));

View File

@ -1037,7 +1037,9 @@ TEST(CfgSubnets4Test, unparseSubnet) {
subnet3->setCalculateTeeTimes(true);
subnet3->setT1Percent(0.50);
subnet3->setT2Percent(0.65);
subnet3->setHostReservationMode(Network::HR_ALL);
subnet3->setReservationsGlobal(false);
subnet3->setReservationsInSubnet(true);
subnet3->setReservationsOutOfPool(false);
subnet3->setAuthoritative(false);
subnet3->setMatchClientId(true);
subnet3->setSiaddr(IOAddress("192.0.2.2"));
@ -1115,7 +1117,9 @@ TEST(CfgSubnets4Test, unparseSubnet) {
" \"4o6-interface-id\": \"\",\n"
" \"4o6-subnet\": \"\",\n"
" \"authoritative\": false,\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"option-data\": [ ],\n"
" \"pools\": [ ]\n,"
" \"require-client-classes\": [ \"foo\", \"bar\" ],\n"
@ -1282,7 +1286,9 @@ TEST(CfgSubnets4Test, teeTimePercentValidation) {
" \"boot-file-name\": \"\", \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false, \n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
@ -1349,7 +1355,9 @@ TEST(CfgSubnets4Test, validLifetimeValidation) {
" \"boot-file-name\": \"\", \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false, \n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
@ -1591,7 +1599,9 @@ TEST(CfgSubnets4Test, hostnameSanitizierValidation) {
" \"boot-file-name\": \"\", \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false, \n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"
@ -1669,7 +1679,9 @@ TEST(CfgSubnets4Test, cacheParamValidation) {
" \"boot-file-name\": \"\", \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true,\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false, \n"
" \"4o6-interface\": \"\", \n"
" \"4o6-interface-id\": \"\", \n"
" \"4o6-subnet\": \"\" \n"

View File

@ -637,7 +637,9 @@ TEST(CfgSubnets6Test, unparseSubnet) {
subnet3->setIface("eth1");
subnet3->requireClientClass("foo");
subnet3->requireClientClass("bar");
subnet3->setHostReservationMode(Network::HR_ALL);
subnet3->setReservationsGlobal(false);
subnet3->setReservationsInSubnet(true);
subnet3->setReservationsOutOfPool(false);
subnet3->setRapidCommit(false);
subnet3->setCalculateTeeTimes(true);
subnet3->setT1Percent(0.50);
@ -710,7 +712,9 @@ TEST(CfgSubnets6Test, unparseSubnet) {
" \"min-valid-lifetime\": 100,\n"
" \"max-valid-lifetime\": 300,\n"
" \"rapid-commit\": false,\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"pools\": [ ],\n"
" \"pd-pools\": [ ],\n"
" \"option-data\": [ ],\n"
@ -1079,7 +1083,9 @@ TEST(CfgSubnets6Test, teeTimePercentValidation) {
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
" }";
@ -1142,7 +1148,9 @@ TEST(CfgSubnets6Test, preferredLifetimeValidation) {
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
" }";
@ -1377,7 +1385,9 @@ TEST(CfgSubnets6Test, hostnameSanitizierValidation) {
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
" }";
data::ElementPtr elems;
@ -1447,7 +1457,9 @@ TEST(CfgSubnets6Test, cacheParamValidation) {
" \"valid-lifetime\": 300, \n"
" \"client-class\": \"\", \n"
" \"require-client-classes\": [] \n,"
" \"reservations-in-subnet\": true\n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
" }";
data::ElementPtr elems;

View File

@ -2728,8 +2728,14 @@ TEST_F(ParseConfigTest, defaultSubnet4) {
EXPECT_TRUE(subnet->getT2().unspecified());
EXPECT_EQ(0, subnet->getT2().get());
EXPECT_TRUE(subnet->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode().get());
EXPECT_TRUE(subnet->getReservationsGlobal().unspecified());
EXPECT_FALSE(subnet->getReservationsGlobal().get());
EXPECT_TRUE(subnet->getReservationsInSubnet().unspecified());
EXPECT_TRUE(subnet->getReservationsInSubnet().get());
EXPECT_TRUE(subnet->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(subnet->getReservationsOutOfPool().get());
EXPECT_TRUE(subnet->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(subnet->getCalculateTeeTimes().get());
@ -2832,8 +2838,14 @@ TEST_F(ParseConfigTest, defaultSubnet6) {
EXPECT_TRUE(subnet->getT2().unspecified());
EXPECT_EQ(0, subnet->getT2().get());
EXPECT_TRUE(subnet->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, subnet->getHostReservationMode().get());
EXPECT_TRUE(subnet->getReservationsGlobal().unspecified());
EXPECT_FALSE(subnet->getReservationsGlobal().get());
EXPECT_TRUE(subnet->getReservationsInSubnet().unspecified());
EXPECT_TRUE(subnet->getReservationsInSubnet().get());
EXPECT_TRUE(subnet->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(subnet->getReservationsOutOfPool().get());
EXPECT_TRUE(subnet->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(subnet->getCalculateTeeTimes().get());
@ -2918,8 +2930,14 @@ TEST_F(ParseConfigTest, defaultSharedNetwork4) {
EXPECT_TRUE(network->getT2().unspecified());
EXPECT_EQ(0, network->getT2().get());
EXPECT_TRUE(network->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, network->getHostReservationMode().get());
EXPECT_TRUE(network->getReservationsGlobal().unspecified());
EXPECT_FALSE(network->getReservationsGlobal().get());
EXPECT_TRUE(network->getReservationsInSubnet().unspecified());
EXPECT_TRUE(network->getReservationsInSubnet().get());
EXPECT_TRUE(network->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(network->getReservationsOutOfPool().get());
EXPECT_TRUE(network->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(network->getCalculateTeeTimes().get());
@ -2999,8 +3017,14 @@ TEST_F(ParseConfigTest, defaultSharedNetwork6) {
EXPECT_TRUE(network->getT2().unspecified());
EXPECT_EQ(0, network->getT2().get());
EXPECT_TRUE(network->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, network->getHostReservationMode().get());
EXPECT_TRUE(network->getReservationsGlobal().unspecified());
EXPECT_FALSE(network->getReservationsGlobal().get());
EXPECT_TRUE(network->getReservationsInSubnet().unspecified());
EXPECT_TRUE(network->getReservationsInSubnet().get());
EXPECT_TRUE(network->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(network->getReservationsOutOfPool().get());
EXPECT_TRUE(network->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(network->getCalculateTeeTimes().get());

View File

@ -145,17 +145,6 @@ public:
ElementPtr globals_;
};
// This test verifies conversions of host reservation mode names to
// appropriate enum values.
TEST_F(NetworkTest, hrModeFromString) {
EXPECT_EQ(Network::HR_DISABLED, Network::hrModeFromString("off"));
EXPECT_EQ(Network::HR_DISABLED, Network::hrModeFromString("disabled"));
EXPECT_EQ(Network::HR_OUT_OF_POOL, Network::hrModeFromString("out-of-pool"));
EXPECT_EQ(Network::HR_GLOBAL, Network::hrModeFromString("global"));
EXPECT_EQ(Network::HR_ALL, Network::hrModeFromString("all"));
EXPECT_THROW(Network::hrModeFromString("bogus"), isc::BadValue);
}
// This test verifies that the inheritance is supported for certain
// network parameters.
TEST_F(NetworkTest, inheritanceSupport4) {
@ -163,7 +152,9 @@ TEST_F(NetworkTest, inheritanceSupport4) {
globals_->set("valid-lifetime", Element::create(80));
globals_->set("renew-timer", Element::create(80));
globals_->set("rebind-timer", Element::create(80));
globals_->set("reservation-mode", Element::create("disabled"));
globals_->set("reservations-global", Element::create(false));
globals_->set("reservations-in-subnet", Element::create(false));
globals_->set("reservations-out-of-pool", Element::create(false));
globals_->set("calculate-tee-times", Element::create(false));
globals_->set("t1-percent", Element::create(0.75));
globals_->set("t2-percent", Element::create(0.6));
@ -185,9 +176,6 @@ TEST_F(NetworkTest, inheritanceSupport4) {
globals_->set("cache-max-age", Element::create(20));
globals_->set("ddns-update-on-renew", Element::create(true));
globals_->set("ddns-use-conflict-resolution", Element::create(true));
globals_->set("reservations-out-of-pool", Element::create(false));
globals_->set("reservations-in-subnet", Element::create(false));
globals_->set("reservations-global", Element::create(false));
// For each parameter for which inheritance is supported run
// the test that checks if the values are inherited properly.
@ -214,18 +202,22 @@ TEST_F(NetworkTest, inheritanceSupport4) {
60, 80);
}
{
SCOPED_TRACE("reservation-mode");
testNetworkInheritance<TestNetwork>(&Network::getHostReservationMode,
&Network::setHostReservationMode,
Network::HR_OUT_OF_POOL,
Network::HR_DISABLED);
SCOPED_TRACE("reservation-global");
testNetworkInheritance<TestNetwork>(&Network::getReservationsGlobal,
&Network::setReservationsGlobal,
true, false);
}
{
SCOPED_TRACE("reservations-global");
testNetworkInheritance<TestNetwork>(&Network::getHostReservationMode,
&Network::setHostReservationMode,
Network::HR_OUT_OF_POOL,
Network::HR_DISABLED);
SCOPED_TRACE("reservation-in-subnet");
testNetworkInheritance<TestNetwork>(&Network::getReservationsInSubnet,
&Network::setReservationsInSubnet,
true, false);
}
{
SCOPED_TRACE("reservation-out-of-pool");
testNetworkInheritance<TestNetwork>(&Network::getReservationsOutOfPool,
&Network::setReservationsOutOfPool,
true, false);
}
{
SCOPED_TRACE("calculate-tee-times");

View File

@ -1,272 +0,0 @@
// Copyright (C) 2018-2020 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 <cc/data.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/parsers/reservation_modes_parser.h>
#include <testutils/test_to_element.h>
#include <gtest/gtest.h>
using namespace isc::data;
using namespace isc::dhcp;
using namespace isc::test;
using namespace isc::util;
namespace {
/// @brief Test fixture class for @c HostReservationModesParser
class HostReservationModesParserTest : public ::testing::Test {
protected:
/// @brief Setup for each test.
///
/// Clears the configuration in the @c CfgMgr.
virtual void SetUp();
/// @brief Cleans up after each test.
///
/// Clears the configuration in the @c CfgMgr.
virtual void TearDown();
};
void
HostReservationModesParserTest::SetUp() {
CfgMgr::instance().clear();
}
void
HostReservationModesParserTest::TearDown() {
CfgMgr::instance().clear();
}
// Verifies that HostReservationModesParser handles
// expected valid reservation-modes content
TEST_F(HostReservationModesParserTest, validContent) {
struct Scenario {
std::string description_;
std::string json_;
uint8_t expected_result_;
};
std::vector<Scenario> scenarios = {
{
"reservation modes disabled specifying all parameters",
"{ \n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_DISABLED)
},
{
"reservation modes disabled specifying only global",
"{ \n"
" \"reservations-global\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_DISABLED)
},
{
"reservation modes disabled specifying only in-subnet",
"{ \n"
" \"reservations-in-subnet\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_DISABLED)
},
{
"reservation modes disabled specifying only out-of-pool",
"{ \n"
" \"reservations-out-of-pool\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_DISABLED)
},
{
"reservation modes global enabled specifying all parameters",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_GLOBAL)
},
{
"reservation modes global enabled specifying only global",
"{ \n"
" \"reservations-global\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_GLOBAL)
},
{
"reservation modes in-subnet enabled specifying all parameters",
"{ \n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_IN_SUBNET)
},
{
"reservation modes in-subnet enabled specifying only in-subnet",
"{ \n"
" \"reservations-in-subnet\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_IN_SUBNET)
},
{
"reservation modes global and in-subnet enabled specifying all parameters",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": false \n"
"} \n",
static_cast<uint8_t>(Network::HR_GLOBAL|Network::HR_IN_SUBNET)
},
{
"reservation modes global and in-subnet enabled specifying global and in-subnet",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_GLOBAL|Network::HR_IN_SUBNET)
},
{
"reservation modes out-of-pool enabled specifying all parameters",
"{ \n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_OUT_OF_POOL)
},
{
"reservation modes out-of-pool enabled specifying in-subnet and out-of-pool",
"{ \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_OUT_OF_POOL)
},
{
"reservation modes out-of-pool enabled specifying only out-of-pool",
"{ \n"
" \"reservations-out-of-pool\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_OUT_OF_POOL)
},
{
"reservation modes global and out-of-pool enabled specifying all parameters",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": true, \n"
" \"reservations-out-of-pool\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_OUT_OF_POOL|Network::HR_GLOBAL)
},
{
"reservation modes global and out-of-pool enabled specifying global and out-of-pool",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-out-of-pool\": true \n"
"} \n",
static_cast<uint8_t>(Network::HR_OUT_OF_POOL|Network::HR_GLOBAL)
}
};
// Iterate over the valid scenarios and verify they succeed.
ConstElementPtr config_elems;
Network::HRMode reservation_modes;
for (auto scenario : scenarios) {
SCOPED_TRACE(scenario.description_);
{
// Construct the config JSON
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
<< "invalid JSON, test is broken";
// Parsing config into a reservation modes parser should succeed.
HostReservationModesParser parser;
try {
reservation_modes = parser.parse(config_elems);
} catch (const std::exception& ex) {
ADD_FAILURE() << "parser threw an exception: " << ex.what();
}
// Verify the resultant reservation-modes.
ASSERT_EQ(scenario.expected_result_, reservation_modes);
}
}
}
// Verifies that HostReservationModesParser correctly catches
// invalid reservation-modes content
TEST_F(HostReservationModesParserTest, invalidContent) {
struct Scenario {
std::string description_;
std::string json_;
};
std::vector<Scenario> scenarios = {
{
"global not boolean",
"{ \n"
" \"reservations-global\": \"always\" \n"
"} \n"
},
{
"in-subnet not boolean",
"{ \n"
" \"reservations-in-subnet\": \"always\" \n"
"} \n"
},
{
"out-of-pool not boolean",
"{ \n"
" \"reservations-out-of-pool\": \"always\" \n"
"} \n"
},
{
"reservation modes out-of-pool enabled specifying all parameters",
"{ \n"
" \"reservations-global\": false, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": true \n"
"} \n"
},
{
"reservation modes out-of-pool enabled specifying all parameters",
"{ \n"
" \"reservations-global\": true, \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": true \n"
"} \n"
},
{
"reservation modes out-of-pool enabled specifying in-subnet and out-of-pool",
"{ \n"
" \"reservations-in-subnet\": false, \n"
" \"reservations-out-of-pool\": true \n"
"} \n"
},
};
// Iterate over the invalid scenarios and verify they throw exception.
ConstElementPtr config_elems;
for (auto scenario : scenarios) {
SCOPED_TRACE(scenario.description_);
{
// Construct the config JSON
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
<< "invalid JSON, test is broken";
// Parsing config into a reservation modes parser should succeed.
HostReservationModesParser parser;
EXPECT_THROW(parser.parse(config_elems), DhcpConfigError);
}
}
}
}; // anonymous namespace

View File

@ -128,6 +128,8 @@ public:
" \"rebind-timer\": 199,"
" \"relay\": { \"ip-addresses\": [ \"10.1.1.1\" ] },"
" \"renew-timer\": 99,"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": true,"
" \"server-hostname\": \"example.org\","
" \"require-client-classes\": [ \"runner\" ],"
@ -173,7 +175,9 @@ public:
" \"boot-file-name\": \"\","
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": false,"
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"4o6-subnet\": \"\","
@ -198,7 +202,9 @@ public:
" \"boot-file-name\": \"\","
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": false,"
" \"4o6-interface\": \"\","
" \"4o6-interface-id\": \"\","
" \"4o6-subnet\": \"\","
@ -259,7 +265,9 @@ TEST_F(SharedNetwork4ParserTest, parse) {
EXPECT_EQ("/dev/null", network->getFilename().get());
EXPECT_EQ("10.0.0.1", network->getSiaddr().get().toText());
EXPECT_EQ("example.org", network->getSname().get());
EXPECT_EQ(Network::HR_OUT_OF_POOL, network->getHostReservationMode());
EXPECT_FALSE(network->getReservationsGlobal());
EXPECT_TRUE(network->getReservationsInSubnet());
EXPECT_TRUE(network->getReservationsOutOfPool());
EXPECT_TRUE(network->getDdnsSendUpdates().get());
EXPECT_TRUE(network->getDdnsOverrideNoUpdate().get());
EXPECT_TRUE(network->getDdnsOverrideClientUpdate().get());
@ -547,6 +555,8 @@ public:
" \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\" ] },"
" \"renew-timer\": 99,"
" \"require-client-classes\": [ \"runner\" ],"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": true,"
" \"user-context\": { },"
" \"valid-lifetime\": 399,"
@ -589,7 +599,9 @@ public:
" \"max-valid-lifetime\": 500,"
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": false,"
" \"rapid-commit\": false,"
" \"hostname-char-set\": \"\""
" },"
@ -604,7 +616,9 @@ public:
" \"valid-lifetime\": 40,"
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
" \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
" \"reservations-out-of-pool\": false,"
" \"rapid-commit\": false"
" }"
" ]"

View File

@ -18,6 +18,7 @@
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
@ -52,8 +53,14 @@ TEST(SharedNetwork4Test, defaults) {
EXPECT_TRUE(network->getT2().unspecified());
EXPECT_EQ(0, network->getT2().get());
EXPECT_TRUE(network->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, network->getHostReservationMode().get());
EXPECT_TRUE(network->getReservationsGlobal().unspecified());
EXPECT_FALSE(network->getReservationsGlobal().get());
EXPECT_TRUE(network->getReservationsInSubnet().unspecified());
EXPECT_TRUE(network->getReservationsInSubnet().get());
EXPECT_TRUE(network->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(network->getReservationsOutOfPool().get());
EXPECT_TRUE(network->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(network->getCalculateTeeTimes().get());
@ -614,7 +621,9 @@ TEST(SharedNetwork4Test, unparse) {
network->addRelayAddress(IOAddress("192.168.2.1"));
network->setAuthoritative(false);
network->setMatchClientId(false);
network->setHostReservationMode(Network::HR_ALL);
network->setReservationsGlobal(false);
network->setReservationsInSubnet(true);
network->setReservationsOutOfPool(false);
// Add several subnets.
Subnet4Ptr subnet1(new Subnet4(IOAddress("10.0.0.0"), 8, 10, 20, 30,
@ -639,7 +648,9 @@ TEST(SharedNetwork4Test, unparse) {
" },\n"
" \"renew-timer\": 100,\n"
" \"require-client-classes\": [ \"foo\" ],\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"subnet4\": [\n"
" {\n"
" \"4o6-interface\": \"\",\n"
@ -753,8 +764,14 @@ TEST(SharedNetwork6Test, defaults) {
EXPECT_TRUE(network->getT2().unspecified());
EXPECT_EQ(0, network->getT2().get());
EXPECT_TRUE(network->getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, network->getHostReservationMode().get());
EXPECT_TRUE(network->getReservationsGlobal().unspecified());
EXPECT_FALSE(network->getReservationsGlobal().get());
EXPECT_TRUE(network->getReservationsInSubnet().unspecified());
EXPECT_TRUE(network->getReservationsInSubnet().get());
EXPECT_TRUE(network->getReservationsOutOfPool().unspecified());
EXPECT_FALSE(network->getReservationsOutOfPool().get());
EXPECT_TRUE(network->getCalculateTeeTimes().unspecified());
EXPECT_FALSE(network->getCalculateTeeTimes().get());
@ -1306,7 +1323,9 @@ TEST(SharedNetwork6Test, unparse) {
network->addRelayAddress(IOAddress("2001:db8:1::8"));
network->setRapidCommit(true);
network->setHostReservationMode(Network::HR_ALL);
network->setReservationsGlobal(false);
network->setReservationsInSubnet(true);
network->setReservationsOutOfPool(false);
// Add several subnets.
Subnet6Ptr subnet1(new Subnet6(IOAddress("2001:db8:1::"), 64, 10, 20, 30,
@ -1330,7 +1349,9 @@ TEST(SharedNetwork6Test, unparse) {
" },\n"
" \"renew-timer\": 100,\n"
" \"require-client-classes\": [ \"foo\" ],\n"
" \"reservations-global\": false,\n"
" \"reservations-in-subnet\": true,\n"
" \"reservations-out-of-pool\": false,\n"
" \"subnet6\": [\n"
" {\n"
" \"id\": 1,\n"

View File

@ -83,8 +83,14 @@ TEST(Subnet4Test, defaults) {
EXPECT_TRUE(subnet.getT2().unspecified());
EXPECT_EQ(0, subnet.getT2().get());
EXPECT_TRUE(subnet.getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, subnet.getHostReservationMode().get());
EXPECT_TRUE(subnet.getReservationsGlobal().unspecified());
EXPECT_FALSE(subnet.getReservationsGlobal().get());
EXPECT_TRUE(subnet.getReservationsInSubnet().unspecified());
EXPECT_TRUE(subnet.getReservationsInSubnet().get());
EXPECT_TRUE(subnet.getReservationsOutOfPool().unspecified());
EXPECT_FALSE(subnet.getReservationsOutOfPool().get());
EXPECT_TRUE(subnet.getCalculateTeeTimes().unspecified());
EXPECT_FALSE(subnet.getCalculateTeeTimes().get());
@ -853,8 +859,14 @@ TEST(SharedNetwork6Test, defaults) {
EXPECT_TRUE(subnet.getT2().unspecified());
EXPECT_EQ(0, subnet.getT2().get());
EXPECT_TRUE(subnet.getHostReservationMode().unspecified());
EXPECT_EQ(Network::HR_ALL, subnet.getHostReservationMode().get());
EXPECT_TRUE(subnet.getReservationsGlobal().unspecified());
EXPECT_FALSE(subnet.getReservationsGlobal().get());
EXPECT_TRUE(subnet.getReservationsInSubnet().unspecified());
EXPECT_TRUE(subnet.getReservationsInSubnet().get());
EXPECT_TRUE(subnet.getReservationsOutOfPool().unspecified());
EXPECT_FALSE(subnet.getReservationsOutOfPool().get());
EXPECT_TRUE(subnet.getCalculateTeeTimes().unspecified());
EXPECT_FALSE(subnet.getCalculateTeeTimes().get());

View File

@ -3027,31 +3027,32 @@ SET version = '9', minor = '4';
# This line concludes database upgrade to version 9.4.
# Update reservation_mode value after separating flags.
# Add new reservations flags.
ALTER TABLE dhcp4_subnet
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
# update old global to new value
UPDATE dhcp4_subnet SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp4_shared_network SET reservation_mode = 4 WHERE reservation_mode = 2;
ALTER TABLE dhcp4_shared_network
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
# update old all to new value
UPDATE dhcp4_subnet SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp4_shared_network SET reservation_mode = 2 WHERE reservation_mode = 3;
ALTER TABLE dhcp6_subnet
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
# update out-of-pool all to new value
UPDATE dhcp4_subnet SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp4_shared_network SET reservation_mode = 3 WHERE reservation_mode = 1;
ALTER TABLE dhcp6_shared_network
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
# update old global to new value
UPDATE dhcp6_subnet SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp6_shared_network SET reservation_mode = 4 WHERE reservation_mode = 2;
# update old all to new value
UPDATE dhcp6_subnet SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp6_shared_network SET reservation_mode = 2 WHERE reservation_mode = 3;
# update out-of-pool all to new value
UPDATE dhcp6_subnet SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp6_shared_network SET reservation_mode = 3 WHERE reservation_mode = 1;
# DROP reservation_mode
ALTER TABLE dhcp4_subnet DROP COLUMN reservation_mode;
ALTER TABLE dhcp4_shared_network DROP COLUMN reservation_mode;
ALTER TABLE dhcp6_subnet DROP COLUMN reservation_mode;
ALTER TABLE dhcp6_shared_network DROP COLUMN reservation_mode;
# Update the schema version number
UPDATE schema_version

View File

@ -18,34 +18,136 @@ fi
mysql "$@" <<EOF
# Add new reservations flags.
ALTER TABLE dhcp4_subnet
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
ALTER TABLE dhcp4_shared_network
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
ALTER TABLE dhcp6_subnet
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
ALTER TABLE dhcp6_shared_network
ADD COLUMN reservations_global BOOL DEFAULT NULL,
ADD COLUMN reservations_in_subnet BOOL DEFAULT NULL,
ADD COLUMN reservations_out_of_pool BOOL DEFAULT NULL;
# Disable audit
SET @disable_audit = 1;
# Update reservation_mode value after separating flags.
# Translate reservation_mode to new flags.
# 0 is DISABLED
# 1 is OUT_OF_POOL
# 2 is GLOBAL
# 3 is ALL
UPDATE dhcp4_subnet
SET reservations_global = FALSE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 0;
# update old global to new value
UPDATE dhcp4_subnet SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp4_shared_network SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp4_subnet
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = TRUE
WHERE reservation_mode = 1;
# update old all to new value
UPDATE dhcp4_subnet SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp4_shared_network SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp4_subnet
SET reservations_global = TRUE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 2;
# update out-of-pool all to new value
UPDATE dhcp4_subnet SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp4_shared_network SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp4_subnet
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 3;
# update old global to new value
UPDATE dhcp6_subnet SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp6_shared_network SET reservation_mode = 4 WHERE reservation_mode = 2;
UPDATE dhcp4_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 0;
# update old all to new value
UPDATE dhcp6_subnet SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp6_shared_network SET reservation_mode = 2 WHERE reservation_mode = 3;
UPDATE dhcp4_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = TRUE
WHERE reservation_mode = 1;
# update out-of-pool all to new value
UPDATE dhcp6_subnet SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp6_shared_network SET reservation_mode = 3 WHERE reservation_mode = 1;
UPDATE dhcp4_shared_network
SET reservations_global = TRUE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 2;
UPDATE dhcp4_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 3;
UPDATE dhcp6_subnet
SET reservations_global = FALSE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 0;
UPDATE dhcp6_subnet
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = TRUE
WHERE reservation_mode = 1;
UPDATE dhcp6_subnet
SET reservations_global = TRUE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 2;
UPDATE dhcp6_subnet
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 3;
UPDATE dhcp6_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 0;
UPDATE dhcp6_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = TRUE
WHERE reservation_mode = 1;
UPDATE dhcp6_shared_network
SET reservations_global = TRUE,
reservations_in_subnet = FALSE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 2;
UPDATE dhcp6_shared_network
SET reservations_global = FALSE,
reservations_in_subnet = TRUE,
reservations_out_of_pool = FALSE
WHERE reservation_mode = 3;
# DROP reservation_mode
ALTER TABLE dhcp4_subnet DROP COLUMN reservation_mode;
ALTER TABLE dhcp4_shared_network DROP COLUMN reservation_mode;
ALTER TABLE dhcp6_subnet DROP COLUMN reservation_mode;
ALTER TABLE dhcp6_shared_network DROP COLUMN reservation_mode;
# Enable audit
SET @disable_audit = 0;