summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/examples/kea4/all-keys-netconf.json41
-rw-r--r--doc/examples/kea4/all-keys.json41
-rw-r--r--doc/examples/kea4/global-reservations.json11
-rw-r--r--doc/examples/kea4/reservations.json12
-rw-r--r--doc/examples/kea4/shared-network.json31
-rw-r--r--doc/examples/kea6/all-keys-netconf.json39
-rw-r--r--doc/examples/kea6/all-keys.json39
-rw-r--r--doc/examples/kea6/global-reservations.json13
-rw-r--r--doc/examples/kea6/reservations.json11
-rw-r--r--doc/examples/kea6/shared-network.json31
-rw-r--r--doc/sphinx/arm/dhcp4-srv.rst100
-rw-r--r--doc/sphinx/arm/dhcp6-srv.rst101
-rw-r--r--src/bin/dhcp4/dhcp4_lexer.ll13
-rw-r--r--src/bin/dhcp4/dhcp4_parser.yy53
-rw-r--r--src/bin/dhcp4/parser_context.h6
-rw-r--r--src/bin/dhcp6/dhcp6_lexer.ll13
-rw-r--r--src/bin/dhcp6/dhcp6_parser.yy56
-rw-r--r--src/bin/dhcp6/parser_context.h6
-rw-r--r--src/lib/dhcpsrv/alloc_engine.cc26
-rw-r--r--src/lib/dhcpsrv/network.h14
20 files changed, 600 insertions, 57 deletions
diff --git a/doc/examples/kea4/all-keys-netconf.json b/doc/examples/kea4/all-keys-netconf.json
index 5cc9bff32d..9ab0f99951 100644
--- a/doc/examples/kea4/all-keys-netconf.json
+++ b/doc/examples/kea4/all-keys-netconf.json
@@ -563,7 +563,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
@@ -685,9 +694,18 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
- // Subnet-level compute T1 and T2 timers.
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+ // Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
// T1 = valid lifetime * .5.
@@ -772,8 +790,7 @@
// Configuration control (currently not used, i.e. this syntax
// is already defined but corresponding feature is not implemented).
- "config-control":
- {
+ "config-control": {
// Only configuration databases entry is defined.
"config-databases": [
{
@@ -793,8 +810,7 @@
"server-tag": "my DHCPv4 server",
// DHCP queue control parameters.
- "dhcp-queue-control":
- {
+ "dhcp-queue-control": {
// Enable queue is mandatory.
"enable-queue": true,
@@ -803,7 +819,16 @@
},
// Fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Global compute T1 and T2 timers.
"calculate-tee-times": true,
diff --git a/doc/examples/kea4/all-keys.json b/doc/examples/kea4/all-keys.json
index a8aedd94b4..3a75c3259c 100644
--- a/doc/examples/kea4/all-keys.json
+++ b/doc/examples/kea4/all-keys.json
@@ -695,7 +695,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
@@ -858,9 +867,18 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
- // Subnet-level compute T1 and T2 timers.
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+ // Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
// T1 = valid lifetime * .5.
@@ -954,8 +972,7 @@
// Configuration control (currently not used, i.e. this syntax
// is already defined but corresponding feature is not implemented).
- "config-control":
- {
+ "config-control": {
// Only configuration databases entry is defined.
"config-databases": [
{
@@ -975,8 +992,7 @@
"server-tag": "my DHCPv4 server",
// DHCP queue control parameters.
- "dhcp-queue-control":
- {
+ "dhcp-queue-control": {
// Enable queue is mandatory.
"enable-queue": true,
@@ -988,7 +1004,16 @@
},
// Fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Global compute T1 and T2 timers.
"calculate-tee-times": true,
diff --git a/doc/examples/kea4/global-reservations.json b/doc/examples/kea4/global-reservations.json
index 155b56aeea..d5bb5ef9f8 100644
--- a/doc/examples/kea4/global-reservations.json
+++ b/doc/examples/kea4/global-reservations.json
@@ -51,7 +51,16 @@
// This directive tells Kea that reservations are global. Note that this
// can also be specified at shared network and/or subnet level.
- "reservation-mode": "global",
+// It is deprecated by the "reservation-modes" map.
+// "reservation-mode": "global",
+
+// Since Kea 1.9.1, a more flexible option of configuring the way Kea uses host
+// reservations is available through the 'reservation-modes' map.
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
// Define several global host reservations.
"reservations": [
diff --git a/doc/examples/kea4/reservations.json b/doc/examples/kea4/reservations.json
index 61b18bd8b4..4f1864f805 100644
--- a/doc/examples/kea4/reservations.json
+++ b/doc/examples/kea4/reservations.json
@@ -66,7 +66,17 @@
// out of the dynamic pool and change reservation-mode to "out-of-pool".
// Kea will then be able to skip querying for host reservations when
// assigning leases from dynamic pool.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
"reservations": [
// This is a reservation for a specific hardware/MAC address. It's a very
diff --git a/doc/examples/kea4/shared-network.json b/doc/examples/kea4/shared-network.json
index 397869fd6e..08c3bf2bfa 100644
--- a/doc/examples/kea4/shared-network.json
+++ b/doc/examples/kea4/shared-network.json
@@ -64,7 +64,16 @@
// Timer values can be overridden here.
"renew-timer": 100,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// This starts a list of subnets allowed in this shared network.
// In our example, there are two subnets.
@@ -86,7 +95,15 @@
"ip-address": "0.0.0.0"
},
"renew-timer": 10,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
"subnet": "10.0.0.0/8",
"valid-lifetime": 30
},
@@ -100,7 +117,15 @@
"pools": [ ],
"rebind-timer": 20,
"renew-timer": 10,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
"subnet": "192.0.2.0/24",
"valid-lifetime": 30
}
diff --git a/doc/examples/kea6/all-keys-netconf.json b/doc/examples/kea6/all-keys-netconf.json
index eb16357c2e..7585399fb6 100644
--- a/doc/examples/kea6/all-keys-netconf.json
+++ b/doc/examples/kea6/all-keys-netconf.json
@@ -528,7 +528,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
@@ -676,7 +685,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
@@ -763,8 +781,7 @@
// Configuration control (currently not used, i.e. this syntax
// is already defined but corresponding feature is not implemented).
- "config-control":
- {
+ "config-control": {
// Only configuration databases entry is defined.
"config-databases": [
{
@@ -784,8 +801,7 @@
"server-tag": "my DHCPv6 server",
// DHCP queue control parameters.
- "dhcp-queue-control":
- {
+ "dhcp-queue-control": {
// Enable queue is mandatory.
"enable-queue": true,
@@ -794,7 +810,16 @@
},
// Fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Data directory.
"data-directory": "/tmp",
diff --git a/doc/examples/kea6/all-keys.json b/doc/examples/kea6/all-keys.json
index ab84a84351..9482db7521 100644
--- a/doc/examples/kea6/all-keys.json
+++ b/doc/examples/kea6/all-keys.json
@@ -653,7 +653,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// List of client classes which must be evaluated when this shared
// network is selected for client assignments.
@@ -839,7 +848,16 @@
// Enumeration specifying server's mode of operation when it
// fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Subnet level compute T1 and T2 timers.
"calculate-tee-times": true,
@@ -932,8 +950,7 @@
// Configuration control (currently not used, i.e. this syntax
// is already defined but corresponding feature is not implemented).
- "config-control":
- {
+ "config-control": {
// Only configuration databases entry is defined.
"config-databases": [
{
@@ -953,8 +970,7 @@
"server-tag": "my DHCPv6 server",
// DHCP queue control parameters.
- "dhcp-queue-control":
- {
+ "dhcp-queue-control": {
// Enable queue is mandatory.
"enable-queue": true,
@@ -966,7 +982,16 @@
},
// Fetches host reservations.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// Data directory.
"data-directory": "/tmp",
diff --git a/doc/examples/kea6/global-reservations.json b/doc/examples/kea6/global-reservations.json
index b5674178c1..53e253a8d9 100644
--- a/doc/examples/kea6/global-reservations.json
+++ b/doc/examples/kea6/global-reservations.json
@@ -36,11 +36,20 @@
// costly database lookup to do so. It is therefore useful from a performance
// perspective to use only the reservation types that are actually used in a
// given network.
- "host-reservation-identifiers": [ "duid", "hw-address", "flex-id" ],
+ "host-reservation-identifiers": [ "duid", "hw-address", "flex-id" ],
// This directive tells Kea that reservations are global. Note that this
// can also be specified at shared network and/or subnet level.
- "reservation-mode": "global",
+// It is deprecated by the "reservation-modes" map.
+// "reservation-mode": "global",
+
+// Since Kea 1.9.1, a more flexible option of configuring the way Kea uses host
+// reservations is available through the 'reservation-modes' map.
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
// Define several global host reservations.
"reservations": [
diff --git a/doc/examples/kea6/reservations.json b/doc/examples/kea6/reservations.json
index dad59d4f1e..5005b5100e 100644
--- a/doc/examples/kea6/reservations.json
+++ b/doc/examples/kea6/reservations.json
@@ -48,7 +48,16 @@
// out of the dynamic pool and change reservation-mode to "out-of-pool".
// Kea will then be able to skip querying for host reservations when
// assigning leases from dynamic pool.
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
"pools": [ { "pool": "2001:db8:1::/120" } ],
diff --git a/doc/examples/kea6/shared-network.json b/doc/examples/kea6/shared-network.json
index a8a537e36f..49f1c998ea 100644
--- a/doc/examples/kea6/shared-network.json
+++ b/doc/examples/kea6/shared-network.json
@@ -69,7 +69,16 @@
"ip-address": "2001:db8::1"
},
"renew-timer": 100,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
// List of subnets belonging to this particular shared-network
// start here.
@@ -85,7 +94,15 @@
"ip-address": "2001:db8:1::123"
},
"renew-timer": 10,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
"subnet": "2001:db8:1::/64",
"pools": [ { "pool": "2001:db8:1:abcd::/64" } ],
"valid-lifetime": 40
@@ -101,7 +118,15 @@
"ip-address": "3000::1"
},
"renew-timer": 10,
- "reservation-mode": "all",
+ // It is deprecated by the "reservation-modes" map.
+ // "reservation-mode": "all",
+ // Reservation modes specifying server's mode of operation when it
+ // fetches host reservations.
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
"subnet": "3000::/16",
"valid-lifetime": 40
}
diff --git a/doc/sphinx/arm/dhcp4-srv.rst b/doc/sphinx/arm/dhcp4-srv.rst
index 1fde30bc7e..fde29ba960 100644
--- a/doc/sphinx/arm/dhcp4-srv.rst
+++ b/doc/sphinx/arm/dhcp4-srv.rst
@@ -4621,6 +4621,106 @@ An example configuration using global reservations is shown below:
]
}
+Since Kea 1.9.1, the ``reservation-mode`` is deprecated by the
+``reservation-modes`` map.
+The map contains ``global``, ``in-subnet`` and ``out-of-pool`` boolean flags.
+The flags can be activated independently and can produce various combinations,
+some of them being unsuported by the deprecated ``reservation-mode``.
+
+The correspondence of old values are:
+
+``disabled``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+
+``global``:
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+
+``out-of-pool``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": True
+ },
+
+``all``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+To activate both ``global`` and ``all``, the following combination can be used:
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+The parameter can be specified at global, subnet, and shared-network
+levels.
+
+An example configuration that disables reservation looks as follows:
+
+::
+
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "subnet": "192.0.2.0/24",
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+ ...
+ }
+ ]
+ }
+
+An example configuration using global reservations is shown below:
+
+::
+
+ "Dhcp4": {
+
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+ "reservations": [
+ {
+ "hw-address": "01:bb:cc:dd:ee:ff",
+ "hostname": "host-one"
+ },
+ {
+ "hw-address": "02:bb:cc:dd:ee:ff",
+ "hostname": "host-two"
+ }
+ ],
+
+ "subnet4": [
+ {
+ "subnet": "192.0.2.0/24",
+ ...
+ }
+ ]
+ }
+
For more details regarding global reservations, see :ref:`global-reservations4`.
Another aspect of host reservations is the different types of
diff --git a/doc/sphinx/arm/dhcp6-srv.rst b/doc/sphinx/arm/dhcp6-srv.rst
index 9fa897fdaa..a9500e47b9 100644
--- a/doc/sphinx/arm/dhcp6-srv.rst
+++ b/doc/sphinx/arm/dhcp6-srv.rst
@@ -4067,6 +4067,107 @@ An example configuration using global reservations is shown below:
]
}
+Since Kea 1.9.1, the ``reservation-mode`` is deprecated by the
+``reservation-modes`` map.
+The map contains ``global``, ``in-subnet`` and ``out-of-pool`` boolean flags.
+The flags can be activated independently and can produce various combinations,
+some of them being unsuported by the deprecated ``reservation-mode``.
+
+The correspondence of old values are:
+
+``disabled``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+
+``global``:
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+
+``out-of-pool``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": True
+ },
+
+``all``:
+
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+To activate both ``global`` and ``all``, the following combination can be used:
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": True,
+ "out-of-pool": True
+ },
+
+The parameter can be specified at global, subnet, and shared-network
+levels.
+
+An example configuration that disables reservation looks as follows:
+
+::
+
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "subnet": "2001:db8:1::/64",
+ "reservation-modes": {
+ "global": False,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+ ...
+ }
+ ]
+ }
+
+
+An example configuration using global reservations is shown below:
+
+::
+
+ "Dhcp6": {
+
+
+ "reservation-modes": {
+ "global": True,
+ "in-subnet": False,
+ "out-of-pool": False
+ },
+ "reservations": [
+ {
+ "duid": "00:03:00:01:11:22:33:44:55:66",
+ "hostname": "host-one"
+ },
+ {
+ "duid": "00:03:00:01:99:88:77:66:55:44",
+ "hostname": "host-two"
+ }
+ ],
+
+ "subnet6": [
+ {
+ "subnet": "2001:db8:1::/64",
+ ...
+ }
+ ]
+ }
+
For more details regarding global reservations, see :ref:`global-reservations6`.
Another aspect of host reservations is the different types of
diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll
index e1b1f1ba32..26917e509b 100644
--- a/src/bin/dhcp4/dhcp4_lexer.ll
+++ b/src/bin/dhcp4/dhcp4_lexer.ll
@@ -136,6 +136,8 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
return isc::dhcp::Dhcp4Parser::make_SUB_HOOKS_LIBRARY(driver.loc_);
case Parser4Context::PARSER_DHCP_DDNS:
return isc::dhcp::Dhcp4Parser::make_SUB_DHCP_DDNS(driver.loc_);
+ case Parser4Context::PARSER_RESERVATION_MODES:
+ return isc::dhcp::Dhcp4Parser::make_SUB_RESERVATION_MODES(driver.loc_);
case Parser4Context::PARSER_CONFIG_CONTROL:
return isc::dhcp::Dhcp4Parser::make_SUB_CONFIG_CONTROL(driver.loc_);
}
@@ -959,6 +961,17 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
}
}
+\"reservation-modes\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser4Context::DHCP4:
+ case isc::dhcp::Parser4Context::SUBNET4:
+ case isc::dhcp::Parser4Context::SHARED_NETWORK:
+ return isc::dhcp::Dhcp4Parser::make_RESERVATION_MODES(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp4Parser::make_STRING("reservation-modes", driver.loc_);
+ }
+}
+
\"disabled\" {
switch(driver.ctx_) {
case isc::dhcp::Parser4Context::RESERVATION_MODE:
diff --git a/src/bin/dhcp4/dhcp4_parser.yy b/src/bin/dhcp4/dhcp4_parser.yy
index 9e27bf6005..ccd9605b89 100644
--- a/src/bin/dhcp4/dhcp4_parser.yy
+++ b/src/bin/dhcp4/dhcp4_parser.yy
@@ -152,10 +152,14 @@ using namespace std;
INTERFACE "interface"
ID "id"
RESERVATION_MODE "reservation-mode"
+ RESERVATION_MODES "reservation-modes"
DISABLED "disabled"
OUT_OF_POOL "out-of-pool"
GLOBAL "global"
ALL "all"
+ HR_GLOBAL "global"
+ HR_IN_SUBNET "in-subnet"
+ HR_OUT_OF_POOL "out-of-pool"
HOST_RESERVATION_IDENTIFIERS "host-reservation-identifiers"
@@ -253,6 +257,7 @@ using namespace std;
SUB_OPTION_DATA
SUB_HOOKS_LIBRARY
SUB_DHCP_DDNS
+ SUB_RESERVATION_MODES
SUB_CONFIG_CONTROL
;
@@ -291,6 +296,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json
| SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
| SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library
| SUB_DHCP_DDNS { ctx.ctx_ = ctx.DHCP_DDNS; } sub_dhcp_ddns
+ | SUB_RESERVATION_MODES { ctx.ctx_ = ctx.RESERVATION_MODES; } sub_reservation_modes
| SUB_CONFIG_CONTROL { ctx.ctx_ = ctx.CONFIG_CONTROL; } sub_config_control
;
@@ -1477,6 +1483,53 @@ hr_mode: DISABLED { $$ = ElementPtr(new StringElement("disabled", ctx.loc2pos(@1
| ALL { $$ = ElementPtr(new StringElement("all", ctx.loc2pos(@1))); }
;
+reservation_modes: RESERVATION_MODES {
+ ctx.unique("reservation-modes", ctx.loc2pos(@1));
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("reservation-modes", m);
+ ctx.stack_.push_back(m);
+ ctx.enter(ctx.RESERVATION_MODES);
+} COLON LCURLY_BRACKET reservation_modes_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+sub_reservation_modes: LCURLY_BRACKET {
+ // Parse the reservation-modes map
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.push_back(m);
+} reservation_modes_params RCURLY_BRACKET {
+ // No config_control params are required
+ // parsing completed
+};
+
+reservation_modes_params: reservation_modes_param
+ | reservation_modes_params COMMA reservation_modes_param
+ ;
+
+reservation_modes_param: hr_global
+ | hr_in_subnet
+ | hr_out_of_pool
+ ;
+
+hr_global: HR_GLOBAL COLON BOOLEAN {
+ ctx.unique("global", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("global", b);
+};
+
+hr_in_subnet: HR_IN_SUBNET COLON BOOLEAN {
+ ctx.unique("in-subnet", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("in-subnet", b);
+};
+
+hr_out_of_pool: HR_OUT_OF_POOL COLON BOOLEAN {
+ ctx.unique("out-of-pool", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("out-of-pool", b);
+};
+
id: ID COLON INTEGER {
ctx.unique("id", ctx.loc2pos(@1));
ElementPtr id(new IntElement($3, ctx.loc2pos(@3)));
diff --git a/src/bin/dhcp4/parser_context.h b/src/bin/dhcp4/parser_context.h
index e87f4732e7..0bf2e7b40a 100644
--- a/src/bin/dhcp4/parser_context.h
+++ b/src/bin/dhcp4/parser_context.h
@@ -87,6 +87,9 @@ public:
/// This will parse the input as dhcp-ddns.
PARSER_DHCP_DDNS,
+ /// This will parse the input as reservation-modes.
+ PARSER_RESERVATION_MODES,
+
/// This will parse the input as config-control.
PARSER_CONFIG_CONTROL,
} ParserType;
@@ -314,6 +317,9 @@ public:
/// Used while parsing Dhcp4/config-control
CONFIG_CONTROL,
+ /// Used while parsing Dhcp4/reservation-modes
+ RESERVATION_MODES,
+
/// Used while parsing config-control/config-databases
CONFIG_DATABASE
diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll
index 99b61cb0b3..a464814cfa 100644
--- a/src/bin/dhcp6/dhcp6_lexer.ll
+++ b/src/bin/dhcp6/dhcp6_lexer.ll
@@ -138,6 +138,8 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
return isc::dhcp::Dhcp6Parser::make_SUB_HOOKS_LIBRARY(driver.loc_);
case Parser6Context::PARSER_DHCP_DDNS:
return isc::dhcp::Dhcp6Parser::make_SUB_DHCP_DDNS(driver.loc_);
+ case Parser6Context::PARSER_RESERVATION_MODES:
+ return isc::dhcp::Dhcp6Parser::make_SUB_RESERVATION_MODES(driver.loc_);
case Parser6Context::PARSER_CONFIG_CONTROL:
return isc::dhcp::Dhcp6Parser::make_SUB_CONFIG_CONTROL(driver.loc_);
}
@@ -1269,6 +1271,17 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu]
}
}
+\"reservation-modes\" {
+ switch(driver.ctx_) {
+ case isc::dhcp::Parser6Context::DHCP6:
+ case isc::dhcp::Parser6Context::SUBNET6:
+ case isc::dhcp::Parser6Context::SHARED_NETWORK:
+ return isc::dhcp::Dhcp6Parser::make_RESERVATION_MODES(driver.loc_);
+ default:
+ return isc::dhcp::Dhcp6Parser::make_STRING("reservation-modes", driver.loc_);
+ }
+}
+
\"disabled\" {
switch(driver.ctx_) {
case isc::dhcp::Parser6Context::RESERVATION_MODE:
diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy
index e0fe398404..e4a457d7ac 100644
--- a/src/bin/dhcp6/dhcp6_parser.yy
+++ b/src/bin/dhcp6/dhcp6_parser.yy
@@ -126,6 +126,8 @@ using namespace std;
ENCAPSULATE "encapsulate"
ARRAY "array"
+ SHARED_NETWORKS "shared-networks"
+
POOLS "pools"
POOL "pool"
PD_POOLS "pd-pools"
@@ -143,11 +145,14 @@ using namespace std;
ID "id"
RAPID_COMMIT "rapid-commit"
RESERVATION_MODE "reservation-mode"
+ RESERVATION_MODES "reservation-modes"
DISABLED "disabled"
OUT_OF_POOL "out-of-pool"
GLOBAL "global"
ALL "all"
- SHARED_NETWORKS "shared-networks"
+ HR_GLOBAL "global"
+ HR_IN_SUBNET "in-subnet"
+ HR_OUT_OF_POOL "out-of-pool"
MAC_SOURCES "mac-sources"
RELAY_SUPPLIED_OPTIONS "relay-supplied-options"
@@ -260,6 +265,7 @@ using namespace std;
SUB_OPTION_DATA
SUB_HOOKS_LIBRARY
SUB_DHCP_DDNS
+ SUB_RESERVATION_MODES
SUB_CONFIG_CONTROL
;
@@ -298,6 +304,7 @@ start: TOPLEVEL_JSON { ctx.ctx_ = ctx.NO_KEYWORD; } sub_json
| SUB_OPTION_DATA { ctx.ctx_ = ctx.OPTION_DATA; } sub_option_data
| SUB_HOOKS_LIBRARY { ctx.ctx_ = ctx.HOOKS_LIBRARIES; } sub_hooks_library
| SUB_DHCP_DDNS { ctx.ctx_ = ctx.DHCP_DDNS; } sub_dhcp_ddns
+ | SUB_RESERVATION_MODES { ctx.ctx_ = ctx.RESERVATION_MODES; } sub_reservation_modes
| SUB_CONFIG_CONTROL { ctx.ctx_ = ctx.CONFIG_CONTROL; } sub_config_control
;
@@ -1469,6 +1476,53 @@ hr_mode: DISABLED { $$ = ElementPtr(new StringElement("disabled", ctx.loc2pos(@1
| ALL { $$ = ElementPtr(new StringElement("all", ctx.loc2pos(@1))); }
;
+reservation_modes: RESERVATION_MODES {
+ ctx.unique("reservation-modes", ctx.loc2pos(@1));
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.back()->set("reservation-modes", m);
+ ctx.stack_.push_back(m);
+ ctx.enter(ctx.RESERVATION_MODES);
+} COLON LCURLY_BRACKET reservation_modes_params RCURLY_BRACKET {
+ ctx.stack_.pop_back();
+ ctx.leave();
+};
+
+sub_reservation_modes: LCURLY_BRACKET {
+ // Parse the reservation-modes map
+ ElementPtr m(new MapElement(ctx.loc2pos(@1)));
+ ctx.stack_.push_back(m);
+} reservation_modes_params RCURLY_BRACKET {
+ // No config_control params are required
+ // parsing completed
+};
+
+reservation_modes_params: reservation_modes_param
+ | reservation_modes_params COMMA reservation_modes_param
+ ;
+
+reservation_modes_param: hr_global
+ | hr_in_subnet
+ | hr_out_of_pool
+ ;
+
+hr_global: HR_GLOBAL COLON BOOLEAN {
+ ctx.unique("global", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("global", b);
+};
+
+hr_in_subnet: HR_IN_SUBNET COLON BOOLEAN {
+ ctx.unique("in-subnet", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("in-subnet", b);
+};
+
+hr_out_of_pool: HR_OUT_OF_POOL COLON BOOLEAN {
+ ctx.unique("out-of-pool", ctx.loc2pos(@1));
+ ElementPtr b(new BoolElement($3, ctx.loc2pos(@3)));
+ ctx.stack_.back()->set("out-of-pool", b);
+};
+
id: ID COLON INTEGER {
ctx.unique("id", ctx.loc2pos(@1));
ElementPtr id(new IntElement($3, ctx.loc2pos(@3)));
diff --git a/src/bin/dhcp6/parser_context.h b/src/bin/dhcp6/parser_context.h
index e95b12949e..cdc2da5329 100644
--- a/src/bin/dhcp6/parser_context.h
+++ b/src/bin/dhcp6/parser_context.h
@@ -90,6 +90,9 @@ public:
/// This will parse the input as dhcp-ddns. (D2 client config)
PARSER_DHCP_DDNS,
+ /// This will parse the input as reservation-modes.
+ PARSER_RESERVATION_MODES,
+
/// This will parse the input as config-control.
PARSER_CONFIG_CONTROL,
} ParserType;
@@ -320,6 +323,9 @@ public:
/// Used while parsing Dhcp6/config-control
CONFIG_CONTROL,
+ /// Used while parsing Dhcp6/reservation-modes
+ RESERVATION_MODES,
+
/// Used while parsing config-control/config-databases
CONFIG_DATABASE
diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc
index c01100a92b..6ea19bb024 100644
--- a/src/lib/dhcpsrv/alloc_engine.cc
+++ b/src/lib/dhcpsrv/alloc_engine.cc
@@ -2950,8 +2950,8 @@ namespace {
bool
addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx) {
if (ctx.subnet_ &&
- ((ctx.subnet_->getHostReservationMode() == Network::HR_ALL) ||
- ((ctx.subnet_->getHostReservationMode() == Network::HR_OUT_OF_POOL) &&
+ ((ctx.subnet_->getHostReservationMode() & Network::HR_IN_SUBNET) ||
+ ((ctx.subnet_->getHostReservationMode() & Network::HR_OUT_OF_POOL) &&
(!ctx.subnet_->inPool(Lease::TYPE_V4, address))))) {
// The global parameter ip-reservations-unique controls whether it is allowed
// to specify multiple reservations for the same IP address or delegated prefix
@@ -2974,12 +2974,11 @@ addressReserved(const IOAddress& address, const AllocEngine::ClientContext4& ctx
}
for (auto host : hosts) {
- for (auto id = ctx.host_identifiers_.cbegin(); id != ctx.host_identifiers_.cend();
- ++id) {
+ for (auto id : ctx.host_identifiers_) {
// If we find the matching host we know that this address is reserved
// for us and we can return immediatelly.
- if (id->first == host->getIdentifierType() &&
- id->second == host->getIdentifier()) {
+ if (id.first == host->getIdentifierType() &&
+ id.second == host->getIdentifier()) {
return (false);
}
}
@@ -3015,19 +3014,26 @@ hasAddressReservation(AllocEngine::ClientContext4& ctx) {
Subnet4Ptr subnet = ctx.subnet_;
while (subnet) {
- if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
+ if (subnet->getHostReservationMode() & Network::HR_GLOBAL) {
auto host = ctx.hosts_.find(SUBNET_ID_GLOBAL);
- return (host != ctx.hosts_.end() &&
+ bool found = (host != ctx.hosts_.end() &&
!(host->second->getIPv4Reservation().isV4Zero()));
// if we want global + other modes we would need to
// return only if true, else continue
+ if (subnet->getHostReservationMode() == Network::HR_GLOBAL) {
+ return (found);
+ } else {
+ if (found) {
+ return (found);
+ }
+ }
}
auto host = ctx.hosts_.find(subnet->getID());
if ((host != ctx.hosts_.end()) &&
!(host->second->getIPv4Reservation().isV4Zero()) &&
- ((subnet->getHostReservationMode() == Network::HR_ALL) ||
- ((subnet->getHostReservationMode() == Network::HR_OUT_OF_POOL) &&
+ ((subnet->getHostReservationMode() & Network::HR_IN_SUBNET) ||
+ ((subnet->getHostReservationMode() & Network::HR_OUT_OF_POOL) &&
(!subnet->inPool(Lease::TYPE_V4, host->second->getIPv4Reservation()))))) {
ctx.subnet_ = subnet;
return (true);
diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h
index 325b61e688..89a6951fe3 100644
--- a/src/lib/dhcpsrv/network.h
+++ b/src/lib/dhcpsrv/network.h
@@ -159,24 +159,28 @@ public:
/// None - host reservation is disabled. No reservation types
/// are allowed.
- HR_DISABLED,
+ HR_DISABLED = 0,
/// Only out-of-pool reservations is allowed. This mode
/// allows AllocEngine to skip reservation checks when
/// dealing with with addresses that are in pool.
- HR_OUT_OF_POOL,
+ /// When HR_IN_SUBNET is set, this is always enabled as well.
+ HR_OUT_OF_POOL = 1 << 0,
+
+ /// The in-pool reservations is allowed. This mode actually
+ /// behaves as if out-of-pool reservations are active as well.
+ HR_IN_SUBNET = 1 << 1,
/// Only global reservations are allowed. This mode
/// instructs AllocEngine to only look at global reservations.
- HR_GLOBAL,
+ HR_GLOBAL = 1 << 2,
/// Both out-of-pool and in-pool reservations are allowed. This is the
/// most flexible mode, where sysadmin have biggest liberty. However,
/// there is a non-trivial performance penalty for it, as the
/// AllocEngine code has to check whether there are reservations, even
/// when dealing with reservations from within the dynamic pools.
- /// @todo - should ALL include global?
- HR_ALL
+ HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL
} HRMode;
/// @brief Inheritance "mode" used when fetching an optional @c Network