// 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.
// 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
// 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.
// 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.
},
// 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.
// 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.
// 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.
// 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
// 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.
// 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.
},
// 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.
// 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.
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
]
}
-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:
"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" } ]
} ]
"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": [
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
"Dhcp6": {
"subnet6": [
- {
+ {
"subnet": "2001:db8:1::/64",
"reservation-mode": "disabled",
...
- }
+ }
]
}
]
}
-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:
::
- "Dhcp4": {
+ "Dhcp6": {
"reservations-global": true,
"reservations-out-of-pool": true,
"Dhcp6": {
"subnet6": [
- {
+ {
"subnet": "2001:db8:1::/64",
"reservations-global": false,
"reservations-in-subnet": false,
"reservations-out-of-pool": false,
...
- }
+ }
]
}
"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" } ]
} ]
"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": [
"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": [
{
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
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
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
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
# 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)
"\"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\","
"\"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\","
"\"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\","
// 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
/// - 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"
"],\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"
" \"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"
"]\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"
" \"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"
"]\n"
"}\n"
,
- // Configuration 3 global and all
+ // Configuration 3 global and in-subnet
"{ \"interfaces-config\": {\n"
" \"interfaces\": [ \"*\" ]\n"
"},\n"
" \"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"
"}"
"],\n"
"\"reservations-global\": true,\n"
+ "\"reservations-in-subnet\": false,\n"
+ "\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 600,\n"
"\"reservations\": [ \n"
"{\n"
"}"
"],\n"
"\"reservations-global\": true,\n"
+ "\"reservations-in-subnet\": false,\n"
+ "\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 600,\n"
"\"reservations\": [ \n"
"{\n"
"}",
// 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"
" \"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"
};
// 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);
// 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);
// 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);
// 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);
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);
} // namespace dhcp
} // namespace isc
-
/// - 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:
"{ "
"\"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"
"\"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"
" }] \n"
" },"
" { \n"
+ " \"id\": 2, \n"
" \"subnet\": \"2001:db8:2::/48\", \n"
" \"interface\" : \"eth1\", \n"
" \"pd-pools\": [ \n"
"}"
"],\n"
"\"reservations-global\": true,\n"
+ "\"reservations-in-subnet\": false,\n"
+ "\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 4000,\n"
"\"reservations\": [ \n"
"{\n"
"}"
"],\n"
"\"reservations-global\": true,\n"
+ "\"reservations-in-subnet\": false,\n"
+ "\"reservations-out-of-pool\": false,\n"
"\"valid-lifetime\": 4000,\n"
"\"reservations\": [ \n"
"{\n"
}
{
- 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");
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");
}
{
- 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");
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");
// 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",
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
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
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 \
/// @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.
/// @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;
/// @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
/// @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.
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)) {
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 {
}
}
- // 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
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.
///
/// @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_(),
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.
- ///
- /// See @ref getHostReservationMode for details.
+ /// @brief Sets whether global reservations should be fetched.
///
- /// @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() {
} 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);
}
/// 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.
/// @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_;
/// @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.
+++ /dev/null
-// 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
+++ /dev/null
-// 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
{ "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 },
{ "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" },
{ "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 },
{ "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 },
{ "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 },
{ "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" },
{ "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 },
{ "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 },
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
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());
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.
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.
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.
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.
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.
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.
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.
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.
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));
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));
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));
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));
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));
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));
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));
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));
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"));
" \"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"
" \"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"
" \"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"
" \"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"
" \"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"
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);
" \"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"
" \"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"
" }";
" \"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"
" }";
" \"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;
" \"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;
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());
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());
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());
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());
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) {
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));
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.
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("reservation-in-subnet");
+ testNetworkInheritance<TestNetwork>(&Network::getReservationsInSubnet,
+ &Network::setReservationsInSubnet,
+ true, false);
}
{
- SCOPED_TRACE("reservations-global");
- testNetworkInheritance<TestNetwork>(&Network::getHostReservationMode,
- &Network::setHostReservationMode,
- Network::HR_OUT_OF_POOL,
- Network::HR_DISABLED);
+ SCOPED_TRACE("reservation-out-of-pool");
+ testNetworkInheritance<TestNetwork>(&Network::getReservationsOutOfPool,
+ &Network::setReservationsOutOfPool,
+ true, false);
}
{
SCOPED_TRACE("calculate-tee-times");
+++ /dev/null
-// 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
" \"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\" ],"
" \"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\": \"\","
" \"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\": \"\","
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());
" \"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,"
" \"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\": \"\""
" },"
" \"valid-lifetime\": 40,"
" \"client-class\": \"\","
" \"require-client-classes\": []\n,"
+ " \"reservations-global\": false,"
" \"reservations-in-subnet\": true,"
+ " \"reservations-out-of-pool\": false,"
" \"rapid-commit\": false"
" }"
" ]"
#include <gtest/gtest.h>
#include <cstdint>
#include <vector>
+
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
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());
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,
" },\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"
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());
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,
" },\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"
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());
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());
# This line concludes database upgrade to version 9.4.
-# Update reservation_mode value after separating flags.
-
-# 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 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 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;
+# 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 dhcp6_subnet SET reservation_mode = 4 WHERE reservation_mode = 2;
-UPDATE dhcp6_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 dhcp6_subnet SET reservation_mode = 2 WHERE reservation_mode = 3;
-UPDATE dhcp6_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 dhcp6_subnet SET reservation_mode = 3 WHERE reservation_mode = 1;
-UPDATE dhcp6_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;
+
+# 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
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.
-
-# 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 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 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 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;
+# 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 dhcp4_subnet
+ SET reservations_global = FALSE,
+ reservations_in_subnet = TRUE,
+ reservations_out_of_pool = TRUE
+ WHERE reservation_mode = 1;
+
+UPDATE dhcp4_subnet
+ SET reservations_global = TRUE,
+ reservations_in_subnet = FALSE,
+ reservations_out_of_pool = FALSE
+ WHERE reservation_mode = 2;
+
+UPDATE dhcp4_subnet
+ SET reservations_global = FALSE,
+ reservations_in_subnet = TRUE,
+ reservations_out_of_pool = FALSE
+ WHERE reservation_mode = 3;
+
+UPDATE dhcp4_shared_network
+ SET reservations_global = FALSE,
+ reservations_in_subnet = FALSE,
+ reservations_out_of_pool = FALSE
+ WHERE reservation_mode = 0;
+
+UPDATE dhcp4_shared_network
+ SET reservations_global = FALSE,
+ reservations_in_subnet = TRUE,
+ reservations_out_of_pool = TRUE
+ 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;