]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1405] added parser for the reservation-modes map
authorRazvan Becheriu <razvan@isc.org>
Thu, 8 Oct 2020 19:04:36 +0000 (22:04 +0300)
committerRazvan Becheriu <razvan@isc.org>
Wed, 18 Nov 2020 13:55:22 +0000 (15:55 +0200)
20 files changed:
doc/examples/kea4/all-keys-netconf.json
doc/examples/kea4/all-keys.json
doc/examples/kea4/global-reservations.json
doc/examples/kea4/reservations.json
doc/examples/kea4/shared-network.json
doc/examples/kea6/all-keys-netconf.json
doc/examples/kea6/all-keys.json
doc/examples/kea6/global-reservations.json
doc/examples/kea6/reservations.json
doc/examples/kea6/shared-network.json
doc/sphinx/arm/dhcp4-srv.rst
doc/sphinx/arm/dhcp6-srv.rst
src/bin/dhcp4/dhcp4_lexer.ll
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp4/parser_context.h
src/bin/dhcp6/dhcp6_lexer.ll
src/bin/dhcp6/dhcp6_parser.yy
src/bin/dhcp6/parser_context.h
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/network.h

index 5cc9bff32d131542ed11f9e9e0197adfa66a4ad8..9ab0f99951769fce23fce576bae0c9dc3e75fcfd 100644 (file)
 
                 // 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.
 
                         // 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.
 
         // 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": [
                 {
         "server-tag": "my DHCPv4 server",
 
         // DHCP queue control parameters.
-        "dhcp-queue-control":
-        {
+        "dhcp-queue-control": {
             // Enable queue is mandatory.
             "enable-queue": true,
 
         },
 
         // 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,
index a8aedd94b4a6b549cff57627b2ad55896549af79..3a75c3259c6e386af9e67e0f459ae10661acc60f 100644 (file)
 
                 // 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.
 
                         // 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.
 
         // 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": [
                 {
         "server-tag": "my DHCPv4 server",
 
         // DHCP queue control parameters.
-        "dhcp-queue-control":
-        {
+        "dhcp-queue-control": {
             // Enable queue is mandatory.
             "enable-queue": true,
 
         },
 
         // 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,
index 155b56aeeaefc05e1862d3cef7b77c50e9a8cdaf..d5bb5ef9f8d43ad714b7e0df06120a087f130535 100644 (file)
 
 // 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": [
index 61b18bd8b45c586561bcbb99570437087debba95..4f1864f80538cc1e09266c5a4f74ec56ce55b481 100644 (file)
         // 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
index 397869fd6ea77b63325671c36ddc94dfa418839c..08c3bf2bfa4a99c184cb92f2fdaffd99c926e367 100644 (file)
 
             // 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.
                         "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
                 },
                     "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
                 }
index eb16357c2ee0e844347a1d3805a036c4225cdcde..7585399fb69aab81816dad9a68ccd5cc19362784 100644 (file)
 
                 // 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.
 
                         // 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,
 
         // 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": [
                 {
         "server-tag": "my DHCPv6 server",
 
         // DHCP queue control parameters.
-        "dhcp-queue-control":
-        {
+        "dhcp-queue-control": {
             // Enable queue is mandatory.
             "enable-queue": true,
 
         },
 
         // 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",
index ab84a843517d5bb1f5722955569ccf488fc40cd9..9482db752144d4f89dc733efd31da5596780d25d 100644 (file)
 
                 // 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.
 
                         // 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,
 
         // 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": [
                 {
         "server-tag": "my DHCPv6 server",
 
         // DHCP queue control parameters.
-        "dhcp-queue-control":
-        {
+        "dhcp-queue-control": {
             // Enable queue is mandatory.
             "enable-queue": true,
 
         },
 
         // 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",
index b5674178c16125b60dc89bc486f919aa588a0b48..53e253a8d96dd63bc8f78d9e6db285015f0d7f9e 100644 (file)
 // 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": [
index dad59d4f1e4e2d1057510ab8a3735cb11415767f..5005b5100e4748c3dd230e4c2394b6f094ec95ad 100644 (file)
       // 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" } ],
 
index a8a537e36f2e634f5ac1fa9017697e7ba9762498..49f1c998eabe0e19e46db903736d0d08cca80543 100644 (file)
                 "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.
                         "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
                         "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
                 }
index 1fde30bc7e3c8603e3e7b6a0a29a092a1d165058..fde29ba960235fcae1001cc5991f18d3c37ede7b 100644 (file)
@@ -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
index 9fa897fdaad7b91a2d1e4864f4615398a185c882..a9500e47b9cd5c96153e6d16b102ad99058065fd 100644 (file)
@@ -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
index e1b1f1ba32ae6b5a575df19d8236a39628409de8..26917e509b3b493678cd86d58f8efcffa03d1c36 100644 (file)
@@ -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:
index 9e27bf60058a5c97fcd5445ec060ad31e877aacc..ccd9605b89ee7374584d2d57f5bbbc06b7b559cd 100644 (file)
@@ -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)));
index e87f4732e76a4ad0f762d24e7d86590b9e02e715..0bf2e7b40a99aebc63b9635dfa07d603551f6335 100644 (file)
@@ -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
 
index 99b61cb0b384c89f858db06150be7133f57dd44b..a464814cfa24843afb7b42ab891c3ed67d4e82a7 100644 (file)
@@ -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:
index e0fe3984044fb4e6a8e14d872728d7327f4bf648..e4a457d7ac44c2b7d370df369af9cbf8bd789e52 100644 (file)
@@ -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)));
index e95b12949eaf36e750549acbf6a5c34215b1985b..cdc2da532968df3f9b7cf20ce2bb2f999737e03a 100644 (file)
@@ -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
 
index c01100a92bbfab13fd289e3d48b93e7f9fa6a35a..6ea19bb024aa5ed7b2f413fe4e36554a67c8277b 100644 (file)
@@ -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);
index 325b61e68869db64ababf53b0acde7aa7a964cd5..89a6951fe364bfe0141930ecf99c6af8e48d39e9 100644 (file)
@@ -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