From: Razvan Becheriu Date: Thu, 15 Oct 2020 09:52:51 +0000 (+0300) Subject: [#1405] implemented separate boolean flags for reservation modes X-Git-Tag: Kea-1.9.2~132 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4bb89f01a769d342c5488954392a8e88d66adde7;p=thirdparty%2Fkea.git [#1405] implemented separate boolean flags for reservation modes --- diff --git a/doc/examples/kea4/all-keys.json b/doc/examples/kea4/all-keys.json index 8d4cb5fb51..ebba0c0010 100644 --- a/doc/examples/kea4/all-keys.json +++ b/doc/examples/kea4/all-keys.json @@ -695,16 +695,18 @@ // Enumeration specifying server's mode of operation when it // fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // List of client classes which must be evaluated when this shared // network is selected for client assignments. @@ -867,16 +869,18 @@ // Enumeration specifying server's mode of operation when it // fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // Subnet level compute T1 and T2 timers. "calculate-tee-times": true, @@ -1004,16 +1008,18 @@ }, // Fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // Global compute T1 and T2 timers. "calculate-tee-times": true, diff --git a/doc/examples/kea6/all-keys.json b/doc/examples/kea6/all-keys.json index 46695e9823..9f89b9e3d3 100644 --- a/doc/examples/kea6/all-keys.json +++ b/doc/examples/kea6/all-keys.json @@ -653,16 +653,18 @@ // Enumeration specifying server's mode of operation when it // fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // List of client classes which must be evaluated when this shared // network is selected for client assignments. @@ -848,16 +850,18 @@ // Enumeration specifying server's mode of operation when it // fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // Subnet level compute T1 and T2 timers. "calculate-tee-times": true, @@ -982,16 +986,18 @@ }, // Fetches host reservations. - // It is deprecated by the "reservation-modes" map. + // It is deprecated by the "reservations-out-of-pool", + // reservations-in-subnet and reservations-global parameters. // "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 - }, + // 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. + "reservations-out-of-pool": true, // Data directory. "data-directory": "/tmp", diff --git a/doc/sphinx/arm/dhcp4-srv.rst b/doc/sphinx/arm/dhcp4-srv.rst index 17c5e09962..4c972c1fcb 100644 --- a/doc/sphinx/arm/dhcp4-srv.rst +++ b/doc/sphinx/arm/dhcp4-srv.rst @@ -4623,8 +4623,8 @@ 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. +``reservations-out-of-pool``, ``reservations-in-subnet`` and +``reservations-global`` flags. The flags can be activated independently and can produce various combinations, some of them being unsuported by the deprecated ``reservation-mode``. @@ -4636,11 +4636,10 @@ The correspondence of old values are: "Dhcp4": { - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": false - } + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, + ... } ``global``: @@ -4649,11 +4648,10 @@ The correspondence of old values are: "Dhcp4": { - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - } + "reservations-global": true, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, + ... } ``out-of-pool``: @@ -4662,11 +4660,10 @@ The correspondence of old values are: "Dhcp4": { - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": true - } + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": true, + ... } ``all``: @@ -4675,11 +4672,10 @@ The correspondence of old values are: "Dhcp4": { - "reservation-modes": { - "global": false, - "in-subnet": true, - "out-of-pool": true - } + "reservations-global": false, + "reservations-in-subnet": true, + "reservations-out-of-pool": true, + ... } To activate both ``global`` and ``all``, the following combination can be used: @@ -4688,11 +4684,10 @@ To activate both ``global`` and ``all``, the following combination can be used: "Dhcp4": { - "reservation-modes": { - "global": true, - "in-subnet": true, - "out-of-pool": true - } + "reservations-global": true, + "reservations-in-subnet": true, + "reservations-out-of-pool": true, + ... } The parameter can be specified at global, subnet, and shared-network @@ -4706,11 +4701,9 @@ An example configuration that disables reservation looks as follows: "subnet4": [ { "subnet": "192.0.2.0/24", - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": false - }, + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, ... } ] @@ -4723,12 +4716,9 @@ An example configuration using global reservations is shown below: "Dhcp4": { - - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + "reservations-global": true, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, "reservations": [ { "hw-address": "01:bb:cc:dd:ee:ff", @@ -4853,15 +4843,15 @@ following can be used: "valid-lifetime": 600, "subnet4": [ { "subnet": "10.0.0.0/24", - # It is deprecated by the "reservation-modes" map. + # It is deprecated by the "reservations-out-of-pool", + # reservations-in-subnet and reservations-global parameters. # "reservation-mode": "global", - # Reservation modes specifying server's mode of operation when it - # fetches host reservations. - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + # 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. + "reservations-out-of-pool": false, "pools": [ { "pool": "10.0.0.10-10.0.0.100" } ] } ] } @@ -4964,15 +4954,15 @@ following example: "hw-address": "aa:bb:cc:dd:ee:fe", "client-classes": [ "reserved_class" ] }], - # It is deprecated by the "reservation-modes" map. + # It is deprecated by the "reservations-out-of-pool", + # reservations-in-subnet and reservations-global parameters. # "reservation-mode": "global", - # Reservation modes specifying server's mode of operation when it - # fetches host reservations. - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + # 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. + "reservations-out-of-pool": false, "shared-networks": [{ "subnet4": [ { @@ -5005,8 +4995,8 @@ will be assigned an address from the subnet 192.0.3.0/24. Clients having a reservation for the ``reserved_class`` will be assigned an address from the subnet 192.0.2.0/24. The subnets must belong to the same shared network. In addition, the reservation for the client class must be specified at the -global scope (global reservation) and the ``reservation-modes`` must -set ``global`` to true. +global scope (global reservation) and the ``reservations-global`` must be +set to true. In the example above the ``client-class`` could also be specified at the subnet level rather than pool level yielding the same effect. @@ -6737,7 +6727,11 @@ used by all servers connecting to the configuration database. +-----------------------------+----------------------------+-------------+-------------+-------------+ | reservation-mode | yes | yes | yes | n/a | +-----------------------------+----------------------------+-------------+-------------+-------------+ - | reservation-modes | yes | yes | yes | n/a | + | reservations-out-of-pool | yes | yes | yes | n/a | + +-----------------------------+----------------------------+-------------+-------------+-------------+ + | reservations-in-subnet | yes | yes | yes | n/a | + +-----------------------------+----------------------------+-------------+-------------+-------------+ + | reservations-global | yes | yes | yes | n/a | +-----------------------------+----------------------------+-------------+-------------+-------------+ | t1-percent | yes | yes | yes | n/a | +-----------------------------+----------------------------+-------------+-------------+-------------+ diff --git a/doc/sphinx/arm/dhcp6-srv.rst b/doc/sphinx/arm/dhcp6-srv.rst index f537060378..41d5f6cd92 100644 --- a/doc/sphinx/arm/dhcp6-srv.rst +++ b/doc/sphinx/arm/dhcp6-srv.rst @@ -4068,8 +4068,8 @@ 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. +``reservations-out-of-pool``, ``reservations-in-subnet`` and +``reservations-global`` flags. The flags can be activated independently and can produce various combinations, some of them being unsuported by the deprecated ``reservation-mode``. @@ -4081,11 +4081,10 @@ The correspondence of old values are: "Dhcp6": { - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": false - } + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, + ... } ``global``: @@ -4094,11 +4093,10 @@ The correspondence of old values are: "Dhcp6": { - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - } + "reservations-global": true, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, + ... } ``out-of-pool``: @@ -4107,11 +4105,10 @@ The correspondence of old values are: "Dhcp6": { - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": true - } + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": true, + ... } ``all``: @@ -4120,11 +4117,10 @@ The correspondence of old values are: "Dhcp6": { - "reservation-modes": { - "global": false, - "in-subnet": true, - "out-of-pool": true - } + "reservations-global": false, + "reservations-in-subnet": true, + "reservations-out-of-pool": true, + ... } To activate both ``global`` and ``all``, the following combination can be used: @@ -4133,11 +4129,10 @@ To activate both ``global`` and ``all``, the following combination can be used: "Dhcp6": { - "reservation-modes": { - "global": true, - "in-subnet": true, - "out-of-pool": true - } + "reservations-global": true, + "reservations-in-subnet": true, + "reservations-out-of-pool": true, + ... } The parameter can be specified at global, subnet, and shared-network @@ -4151,11 +4146,9 @@ An example configuration that disables reservation looks as follows: "subnet6": [ { "subnet": "2001:db8:1::/64", - "reservation-modes": { - "global": false, - "in-subnet": false, - "out-of-pool": false - }, + "reservations-global": false, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, ... } ] @@ -4168,12 +4161,9 @@ An example configuration using global reservations is shown below: "Dhcp6": { - - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + "reservations-global": true, + "reservations-in-subnet": false, + "reservations-out-of-pool": false, "reservations": [ { "duid": "00:03:00:01:11:22:33:44:55:66", @@ -4294,15 +4284,15 @@ following can be used: "valid-lifetime": 600, "subnet4": [ { "subnet": "2001:db8:1::/64", - # It is deprecated by the "reservation-modes" map. + # It is deprecated by the "reservations-out-of-pool", + # reservations-in-subnet and reservations-global parameters. # "reservation-mode": "global", - # Reservation modes specifying server's mode of operation when it - # fetches host reservations. - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + # 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. + "reservations-out-of-pool": false, "pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ] } ] } @@ -4405,15 +4395,15 @@ following example: "hw-address": "aa:bb:cc:dd:ee:fe", "client-classes": [ "reserved_class" ] }], - # It is deprecated by the "reservation-modes" map. + # It is deprecated by the "reservations-out-of-pool", + # reservations-in-subnet and reservations-global parameters. # "reservation-mode": "global", - # Reservation modes specifying server's mode of operation when it - # fetches host reservations. - "reservation-modes": { - "global": true, - "in-subnet": false, - "out-of-pool": false - }, + # 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. + "reservations-out-of-pool": false, "shared-networks": [{ "subnet6": [ { @@ -4446,8 +4436,8 @@ will be assigned an address from the subnet 2001:db8:2::/64. Clients having a reservation for the ``reserved_class`` will be assigned an address from the subnet 2001:db8:1::/64. The subnets must belong to the same shared network. In addition, the reservation for the client class must be specified at the -global scope (global reservation) and the ``reservation-modes`` must -set ``global`` to true. +global scope (global reservation) and the ``reservations-global`` must be +set to true. In the example above the ``client-class`` could also be specified at the subnet level rather than pool level yielding the same effect. @@ -6739,7 +6729,11 @@ the global DHCPv6 options (``option-data``) are modified using +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ | reservation-mode | yes | yes | yes | n/a | n/a | +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ - | reservation-modes | yes | yes | yes | n/a | n/a | + | reservations-out-of-pool | yes | yes | yes | n/a | n/a | + +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ + | reservations-in-subnet | yes | yes | yes | n/a | n/a | + +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ + | reservations-global | yes | yes | yes | n/a | n/a | +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ | t1-percent | yes | yes | yes | n/a | n/a | +-----------------------------+----------------------------+-----------+-----------+-----------+------------+ diff --git a/doc/sphinx/arm/hooks.rst b/doc/sphinx/arm/hooks.rst index 453c590f46..e4421df6a5 100644 --- a/doc/sphinx/arm/hooks.rst +++ b/doc/sphinx/arm/hooks.rst @@ -2655,15 +2655,15 @@ An example response could look as follows: "ip-address": "0.0.0.0" }, "renew-timer": 60, - # It is deprecated by the "reservation-modes" map. + # It is deprecated by the "reservations-out-of-pool", + # reservations-in-subnet and reservations-global parameters. # "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 - }, + # 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. + "reservations-out-of-pool": true, "subnet4": [ { "subnet": "192.0.2.0/24", diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll index 9a5c6c14c1..3083980b5f 100644 --- a/src/bin/dhcp4/dhcp4_lexer.ll +++ b/src/bin/dhcp4/dhcp4_lexer.ll @@ -136,8 +136,6 @@ 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_); } @@ -950,14 +948,36 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } -\"reservation-modes\" { +\"reservations-out-of-pool\" { 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_); + return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_); default: - return isc::dhcp::Dhcp4Parser::make_STRING("reservation-modes", driver.loc_); + return isc::dhcp::Dhcp4Parser::make_STRING("reservations-out-of-pool", driver.loc_); + } +} + +\"reservations-in-subnet\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::DHCP4: + case isc::dhcp::Parser4Context::SUBNET4: + case isc::dhcp::Parser4Context::SHARED_NETWORK: + return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("reservations-in-subnet", driver.loc_); + } +} + +\"reservations-global\" { + switch(driver.ctx_) { + case isc::dhcp::Parser4Context::DHCP4: + case isc::dhcp::Parser4Context::SUBNET4: + case isc::dhcp::Parser4Context::SHARED_NETWORK: + return isc::dhcp::Dhcp4Parser::make_RESERVATIONS_GLOBAL(driver.loc_); + default: + return isc::dhcp::Dhcp4Parser::make_STRING("reservations-global", driver.loc_); } } @@ -993,7 +1013,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] \"out-of-pool\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::RESERVATION_MODE: - case isc::dhcp::Parser4Context::RESERVATION_MODES: return isc::dhcp::Dhcp4Parser::make_OUT_OF_POOL(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("out-of-pool", driver.loc_); @@ -1003,7 +1022,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] \"global\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::RESERVATION_MODE: - case isc::dhcp::Parser4Context::RESERVATION_MODES: return isc::dhcp::Dhcp4Parser::make_GLOBAL(driver.loc_); default: return isc::dhcp::Dhcp4Parser::make_STRING("global", driver.loc_); @@ -1019,15 +1037,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } -\"in-subnet\" { - switch(driver.ctx_) { - case isc::dhcp::Parser4Context::RESERVATION_MODES: - return isc::dhcp::Dhcp4Parser::make_IN_SUBNET(driver.loc_); - default: - return isc::dhcp::Dhcp4Parser::make_STRING("in-subnet", driver.loc_); - } -} - \"code\" { switch(driver.ctx_) { case isc::dhcp::Parser4Context::OPTION_DEF: diff --git a/src/bin/dhcp4/dhcp4_parser.yy b/src/bin/dhcp4/dhcp4_parser.yy index cd6f897dc5..8b9624bfad 100644 --- a/src/bin/dhcp4/dhcp4_parser.yy +++ b/src/bin/dhcp4/dhcp4_parser.yy @@ -152,10 +152,11 @@ using namespace std; INTERFACE "interface" ID "id" RESERVATION_MODE "reservation-mode" - RESERVATION_MODES "reservation-modes" + RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool" + RESERVATIONS_IN_SUBNET "reservations-in-subnet" + RESERVATIONS_GLOBAL "reservations-global" DISABLED "disabled" OUT_OF_POOL "out-of-pool" - IN_SUBNET "in-subnet" GLOBAL "global" ALL "all" @@ -255,7 +256,6 @@ using namespace std; SUB_OPTION_DATA SUB_HOOKS_LIBRARY SUB_DHCP_DDNS - SUB_RESERVATION_MODES SUB_CONFIG_CONTROL ; @@ -294,7 +294,6 @@ 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 ; @@ -487,7 +486,9 @@ global_param: valid_lifetime | config_control | server_tag | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | calculate_tee_times | t1_percent | t2_percent @@ -1082,8 +1083,8 @@ host_reservation_identifiers: HOST_RESERVATION_IDENTIFIERS { }; host_reservation_identifiers_list: host_reservation_identifier - | host_reservation_identifiers_list COMMA host_reservation_identifier - ; + | host_reservation_identifiers_list COMMA host_reservation_identifier + ; host_reservation_identifier: duid_id | hw_address_id @@ -1092,22 +1093,22 @@ host_reservation_identifier: duid_id | flex_id ; -duid_id : DUID { +duid_id: DUID { ElementPtr duid(new StringElement("duid", ctx.loc2pos(@1))); ctx.stack_.back()->add(duid); }; -hw_address_id : HW_ADDRESS { +hw_address_id: HW_ADDRESS { ElementPtr hwaddr(new StringElement("hw-address", ctx.loc2pos(@1))); ctx.stack_.back()->add(hwaddr); }; -circuit_id : CIRCUIT_ID { +circuit_id: CIRCUIT_ID { ElementPtr circuit(new StringElement("circuit-id", ctx.loc2pos(@1))); ctx.stack_.back()->add(circuit); }; -client_id : CLIENT_ID { +client_id: CLIENT_ID { ElementPtr client(new StringElement("client-id", ctx.loc2pos(@1))); ctx.stack_.back()->add(client); }; @@ -1178,8 +1179,8 @@ hooks_libraries_list: %empty ; not_empty_hooks_libraries_list: hooks_library - | not_empty_hooks_libraries_list COMMA hooks_library - ; + | not_empty_hooks_libraries_list COMMA hooks_library + ; hooks_library: LCURLY_BRACKET { ElementPtr m(new MapElement(ctx.loc2pos(@1))); @@ -1373,7 +1374,9 @@ subnet4_param: valid_lifetime | require_client_classes | reservations | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | relay | match_client_id | authoritative @@ -1469,51 +1472,22 @@ require_client_classes: REQUIRE_CLIENT_CLASSES { ctx.leave(); }; -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 reservation_modes 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: GLOBAL COLON BOOLEAN { - ctx.unique("global", ctx.loc2pos(@1)); +reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN { + ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1)); ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("global", b); + ctx.stack_.back()->set("reservations-out-of-pool", b); }; -hr_in_subnet: IN_SUBNET COLON BOOLEAN { - ctx.unique("in-subnet", ctx.loc2pos(@1)); +reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN { + ctx.unique("reservations-in-subnet", ctx.loc2pos(@1)); ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("in-subnet", b); + ctx.stack_.back()->set("reservations-in-subnet", b); }; -hr_out_of_pool: OUT_OF_POOL COLON BOOLEAN { - ctx.unique("out-of-pool", ctx.loc2pos(@1)); +reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN { + ctx.unique("reservations-global", ctx.loc2pos(@1)); ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); - ctx.stack_.back()->set("out-of-pool", b); + ctx.stack_.back()->set("reservations-global", b); }; reservation_mode: RESERVATION_MODE { @@ -1584,7 +1558,9 @@ shared_network_param: name | boot_file_name | relay | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | client_class | require_client_classes | valid_lifetime @@ -1811,8 +1787,8 @@ option_data_params: %empty // Those parameters can either be a single parameter or // a list of parameters separated by comma. not_empty_option_data_params: option_data_param - | not_empty_option_data_params COMMA option_data_param - ; + | not_empty_option_data_params COMMA option_data_param + ; // Each single option-data parameter can be one of the following // expressions. @@ -2017,8 +1993,8 @@ reservation_params: %empty ; not_empty_reservation_params: reservation_param - | not_empty_reservation_params COMMA reservation_param - ; + | not_empty_reservation_params COMMA reservation_param + ; /// @todo probably need to add mac-address as well here reservation_param: duid @@ -2201,8 +2177,8 @@ client_class_params: %empty ; not_empty_client_class_params: client_class_param - | not_empty_client_class_params COMMA client_class_param - ; + | not_empty_client_class_params COMMA client_class_param + ; client_class_param: client_class_name | client_class_test diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index 519804b811..c11a96953e 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -370,10 +370,24 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set, ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode"); if (reservation_mode) { // log warning for deprecated option - reservation_mode = mutable_cfg->get("reservation-modes"); + bool found = false; + reservation_mode = mutable_cfg->get("reservations-out-of-pool"); if (reservation_mode) { + found = true; + } + reservation_mode = mutable_cfg->get("reservations-in-subnet"); + if (reservation_mode) { + found = true; + } + reservation_mode = mutable_cfg->get("reservations-global"); + if (reservation_mode) { + found = true; + } + if (found) { isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'" - " and 'reservation-modes' parameters"); + " and one of 'reservations-out-of-pool'" + " , 'reservations-in-subnet' or" + " 'reservations-global' parameters"); } } @@ -639,7 +653,9 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set, (config_pair.first == "boot-file-name") || (config_pair.first == "server-tag") || (config_pair.first == "reservation-mode") || - (config_pair.first == "reservation-modes") || + (config_pair.first == "reservations-out-of-pool") || + (config_pair.first == "reservations-in-subnet") || + (config_pair.first == "reservations-global") || (config_pair.first == "calculate-tee-times") || (config_pair.first == "t1-percent") || (config_pair.first == "t2-percent") || diff --git a/src/bin/dhcp4/tests/config_parser_unittest.cc b/src/bin/dhcp4/tests/config_parser_unittest.cc index bc28c06114..84f064e329 100644 --- a/src/bin/dhcp4/tests/config_parser_unittest.cc +++ b/src/bin/dhcp4/tests/config_parser_unittest.cc @@ -5386,32 +5386,27 @@ TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) { "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.1.0/24\" } ]," " \"subnet\": \"192.0.1.0/24\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true" " }," " {" " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ]," " \"subnet\": \"192.0.2.0/24\", " - " \"reservation-modes\": {" - " \"out-of-pool\": true" + " \"reservations-out-of-pool\": true" " }" " }," " {" " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ]," " \"subnet\": \"192.0.3.0/24\", " - " \"reservation-modes\": {" - " \"in-subnet\": false," - " \"out-of-pool\": false," - " \"global\": false" + " \"reservations-out-of-pool\": false," + " \"reservations-in-subnet\": false," + " \"reservations-global\": false" " }" " }," " {" " \"pools\": [ { \"pool\": \"192.0.4.0/24\" } ]," " \"subnet\": \"192.0.4.0/24\", " - " \"reservation-modes\": {" - " \"global\": true" + " \"reservations-global\": true" " }" " }," " {" @@ -5421,11 +5416,9 @@ TEST_F(Dhcp4ParserTest, hostReservationModesPerSubnet) { " {" " \"pools\": [ { \"pool\": \"192.0.6.0/24\" } ]," " \"subnet\": \"192.0.6.0/24\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true," - " \"global\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true," + " \"reservations-global\": true" " } ]," "\"valid-lifetime\": 4000 }"; @@ -5553,16 +5546,12 @@ TEST_F(Dhcp4ParserTest, hostReservationModesGlobal) { "{ " "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"reservation-modes\": {" - " \"out-of-pool\": true" - " }," + "\"reservations-out-of-pool\": true," "\"subnet4\": [ { " " \"pools\": [ { \"pool\": \"192.0.2.0/24\" } ]," " \"subnet\": \"192.0.2.0/24\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true" " }," " {" " \"pools\": [ { \"pool\": \"192.0.3.0/24\" } ]," @@ -6461,9 +6450,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { " \"relay\": {\n" " \"ip-address\": \"5.6.7.8\"\n" " },\n" - " \"reservation-modes\": {" - " \"out-of-pool\": true" - " },\n" + " \"reservations-out-of-pool\": true," " \"renew-timer\": 10,\n" " \"rebind-timer\": 20,\n" " \"valid-lifetime\": 40,\n" @@ -6489,9 +6476,7 @@ TEST_F(Dhcp4ParserTest, sharedNetworksDerive) { " \"relay\": {\n" " \"ip-address\": \"55.66.77.88\"\n" " },\n" - " \"reservation-modes\": {" - " \"global\": false" - " }" + " \"reservations-global\": false" " }\n" " ]\n" " },\n" diff --git a/src/bin/dhcp4/tests/host_unittest.cc b/src/bin/dhcp4/tests/host_unittest.cc index ddef3d2023..42273631f3 100644 --- a/src/bin/dhcp4/tests/host_unittest.cc +++ b/src/bin/dhcp4/tests/host_unittest.cc @@ -67,7 +67,7 @@ const char* CONFIGS[] = { "\"valid-lifetime\": 600,\n" "\"subnet4\": [ { \n" " \"subnet\": \"10.0.0.0/24\", \n" - " \"reservation-modes\": { \"global\": true }," + " \"reservations-global\": true,\n" " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]\n" "} ]\n" "}\n" @@ -102,7 +102,7 @@ const char* CONFIGS[] = { " \"id\": 20," " \"pools\": [ { \"pool\": \"192.0.2.10-192.0.2.63\" } ],\n" " \"interface\": \"eth1\",\n" - " \"reservation-modes\": { \"global\": true }," + " \"reservations-global\": true,\n" " \"reservations\": [ \n" " {\n" " \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n" @@ -129,7 +129,7 @@ const char* CONFIGS[] = { " \"id\": 10," " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],\n" " \"interface\": \"eth0\",\n" - " \"reservation-modes\": { \"out-of-pool\": true }," + " \"reservations-out-of-pool\": true,\n" " \"reservations\": [ \n" " {\n" " \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n" @@ -157,7 +157,8 @@ const char* CONFIGS[] = { " \"id\": 10," " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],\n" " \"interface\": \"eth0\",\n" - " \"reservation-modes\": { \"in-subnet\": true, \"out-of-pool\": true }," + " \"reservations-out-of-pool\": true,\n" + " \"reservations-in-subnet\": true,\n" " \"reservations\": [ \n" " {\n" " \"hw-address\": \"aa:bb:cc:dd:ee:ff\",\n" @@ -183,7 +184,7 @@ const char* CONFIGS[] = { " \"test\": \"not member('reserved_class')\"" "}" "],\n" - "\"reservation-modes\": { \"global\": true }," + "\"reservations-global\": true,\n" "\"valid-lifetime\": 600,\n" "\"reservations\": [ \n" "{\n" @@ -234,7 +235,7 @@ const char* CONFIGS[] = { " \"test\": \"not member('reserved_class')\"" "}" "],\n" - "\"reservation-modes\": { \"global\": true }," + "\"reservations-global\": true,\n" "\"valid-lifetime\": 600,\n" "\"reservations\": [ \n" "{\n" diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index 6064436c6c..8a2ec54a9d 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -138,8 +138,6 @@ 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_); } @@ -430,7 +428,7 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] return isc::dhcp::Dhcp6Parser::make_STRING(tmp, driver.loc_); } -\"Dhcp6\" { +\"Dhcp6\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::CONFIG: return isc::dhcp::Dhcp6Parser::make_DHCP6(driver.loc_); @@ -1260,14 +1258,36 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } -\"reservation-modes\" { +\"reservations-out-of-pool\" { 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_); + return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_OUT_OF_POOL(driver.loc_); default: - return isc::dhcp::Dhcp6Parser::make_STRING("reservation-modes", driver.loc_); + return isc::dhcp::Dhcp6Parser::make_STRING("reservations-out-of-pool", driver.loc_); + } +} + +\"reservations-in-subnet\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: + case isc::dhcp::Parser6Context::SHARED_NETWORK: + return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_IN_SUBNET(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("reservations-in-subnet", driver.loc_); + } +} + +\"reservations-global\" { + switch(driver.ctx_) { + case isc::dhcp::Parser6Context::DHCP6: + case isc::dhcp::Parser6Context::SUBNET6: + case isc::dhcp::Parser6Context::SHARED_NETWORK: + return isc::dhcp::Dhcp6Parser::make_RESERVATIONS_GLOBAL(driver.loc_); + default: + return isc::dhcp::Dhcp6Parser::make_STRING("reservations-global", driver.loc_); } } @@ -1303,7 +1323,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] \"out-of-pool\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::RESERVATION_MODE: - case isc::dhcp::Parser6Context::RESERVATION_MODES: return isc::dhcp::Dhcp6Parser::make_OUT_OF_POOL(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("out-of-pool", driver.loc_); @@ -1313,7 +1332,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] \"global\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::RESERVATION_MODE: - case isc::dhcp::Parser6Context::RESERVATION_MODES: return isc::dhcp::Dhcp6Parser::make_GLOBAL(driver.loc_); default: return isc::dhcp::Dhcp6Parser::make_STRING("global", driver.loc_); @@ -1329,15 +1347,6 @@ ControlCharacterFill [^"\\]|\\["\\/bfnrtu] } } -\"in-subnet\" { - switch(driver.ctx_) { - case isc::dhcp::Parser6Context::RESERVATION_MODES: - return isc::dhcp::Dhcp6Parser::make_IN_SUBNET(driver.loc_); - default: - return isc::dhcp::Dhcp6Parser::make_STRING("in-subnet", driver.loc_); - } -} - \"code\" { switch(driver.ctx_) { case isc::dhcp::Parser6Context::OPTION_DEF: diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index b2abdc25c3..b99ce9a4d9 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -145,10 +145,11 @@ using namespace std; ID "id" RAPID_COMMIT "rapid-commit" RESERVATION_MODE "reservation-mode" - RESERVATION_MODES "reservation-modes" + RESERVATIONS_OUT_OF_POOL "reservations-out-of-pool" + RESERVATIONS_IN_SUBNET "reservations-in-subnet" + RESERVATIONS_GLOBAL "reservations-global" DISABLED "disabled" OUT_OF_POOL "out-of-pool" - IN_SUBNET "in-subnet" GLOBAL "global" ALL "all" @@ -263,7 +264,6 @@ using namespace std; SUB_OPTION_DATA SUB_HOOKS_LIBRARY SUB_DHCP_DDNS - SUB_RESERVATION_MODES SUB_CONFIG_CONTROL ; @@ -302,7 +302,6 @@ 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 ; @@ -496,7 +495,9 @@ global_param: data_directory | config_control | server_tag | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | calculate_tee_times | t1_percent | t2_percent @@ -1099,8 +1100,8 @@ host_reservation_identifiers: HOST_RESERVATION_IDENTIFIERS { }; host_reservation_identifiers_list: host_reservation_identifier - | host_reservation_identifiers_list COMMA host_reservation_identifier - ; + | host_reservation_identifiers_list COMMA host_reservation_identifier + ; host_reservation_identifier: duid_id | hw_address_id @@ -1191,8 +1192,8 @@ hooks_libraries_list: %empty ; not_empty_hooks_libraries_list: hooks_library - | not_empty_hooks_libraries_list COMMA hooks_library - ; + | not_empty_hooks_libraries_list COMMA hooks_library + ; hooks_library: LCURLY_BRACKET { ElementPtr m(new MapElement(ctx.loc2pos(@1))); @@ -1392,7 +1393,9 @@ subnet6_param: preferred_lifetime | require_client_classes | reservations | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | relay | user_context | comment @@ -1462,6 +1465,24 @@ require_client_classes: REQUIRE_CLIENT_CLASSES { ctx.leave(); }; +reservations_out_of_pool: RESERVATIONS_OUT_OF_POOL COLON BOOLEAN { + ctx.unique("reservations-out-of-pool", ctx.loc2pos(@1)); + ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("reservations-out-of-pool", b); +}; + +reservations_in_subnet: RESERVATIONS_IN_SUBNET COLON BOOLEAN { + ctx.unique("reservations-in-subnet", ctx.loc2pos(@1)); + ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("reservations-in-subnet", b); +}; + +reservations_global: RESERVATIONS_GLOBAL COLON BOOLEAN { + ctx.unique("reservations-global", ctx.loc2pos(@1)); + ElementPtr b(new BoolElement($3, ctx.loc2pos(@3))); + ctx.stack_.back()->set("reservations-global", b); +}; + reservation_mode: RESERVATION_MODE { ctx.unique("reservation-mode", ctx.loc2pos(@1)); ctx.enter(ctx.RESERVATION_MODE); @@ -1476,53 +1497,6 @@ 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 reservation_modes 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: 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: 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: 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))); @@ -1550,8 +1524,8 @@ shared_networks: SHARED_NETWORKS { // This allows 0 or more shared network definitions. shared_networks_content: %empty - | shared_networks_list - ; + | shared_networks_list + ; // This allows 1 or more shared network definitions. shared_networks_list: shared_network @@ -1579,7 +1553,9 @@ shared_network_param: name | option_data_list | relay | reservation_mode - | reservation_modes + | reservations_out_of_pool + | reservations_in_subnet + | reservations_global | client_class | require_client_classes | preferred_lifetime @@ -1810,8 +1786,8 @@ option_data_params: %empty // Those parameters can either be a single parameter or // a list of parameters separated by comma. not_empty_option_data_params: option_data_param - | not_empty_option_data_params COMMA option_data_param - ; + | not_empty_option_data_params COMMA option_data_param + ; // Each single option-data parameter can be one of the following // expressions. @@ -2117,8 +2093,8 @@ reservation_params: %empty ; not_empty_reservation_params: reservation_param - | not_empty_reservation_params COMMA reservation_param - ; + | not_empty_reservation_params COMMA reservation_param + ; /// @todo probably need to add mac-address as well here reservation_param: duid @@ -2263,8 +2239,8 @@ client_class_params: %empty ; not_empty_client_class_params: client_class_param - | not_empty_client_class_params COMMA client_class_param - ; + | not_empty_client_class_params COMMA client_class_param + ; client_class_param: client_class_name | client_class_test diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index a0293e2333..641a8b6145 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -471,10 +471,24 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode"); if (reservation_mode) { // log warning for deprecated option - reservation_mode = mutable_cfg->get("reservation-modes"); + bool found = false; + reservation_mode = mutable_cfg->get("reservations-out-of-pool"); if (reservation_mode) { + found = true; + } + reservation_mode = mutable_cfg->get("reservations-in-subnet"); + if (reservation_mode) { + found = true; + } + reservation_mode = mutable_cfg->get("reservations-global"); + if (reservation_mode) { + found = true; + } + if (found) { isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'" - " and 'reservation-modes' parameters"); + " and one of 'reservations-out-of-pool'" + " , 'reservations-in-subnet' or" + " 'reservations-global' parameters"); } } @@ -771,7 +785,9 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set, (config_pair.first == "dhcp4o6-port") || (config_pair.first == "server-tag") || (config_pair.first == "reservation-mode") || - (config_pair.first == "reservation-modes") || + (config_pair.first == "reservations-out-of-pool") || + (config_pair.first == "reservations-in-subnet") || + (config_pair.first == "reservations-global") || (config_pair.first == "calculate-tee-times") || (config_pair.first == "t1-percent") || (config_pair.first == "t2-percent") || diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 23ae8b5436..958c9fc037 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -5759,33 +5759,26 @@ TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) { "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," " \"subnet\": \"2001:db8:1::/48\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true" " }," " {" " \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ]," " \"subnet\": \"2001:db8:2::/48\", " - " \"reservation-modes\": {" - " \"out-of-pool\": true" + " \"reservations-out-of-pool\": true" " }" " }," " {" " \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ]," " \"subnet\": \"2001:db8:3::/48\", " - " \"reservation-modes\": {" - " \"in-subnet\": false," - " \"out-of-pool\": false," - " \"global\": false" - " }" + " \"reservations-out-of-pool\": false," + " \"reservations-in-subnet\": false," + " \"reservations-global\": false" " }," " {" " \"pools\": [ { \"pool\": \"2001:db8:4::/64\" } ]," " \"subnet\": \"2001:db8:4::/48\", " - " \"reservation-modes\": {" - " \"global\": true" - " }" + " \"reservations-global\": true" " }," " {" " \"pools\": [ { \"pool\": \"2001:db8:5::/64\" } ]," @@ -5794,11 +5787,9 @@ TEST_F(Dhcp6ParserTest, hostReservationModesPerSubnet) { " {" " \"pools\": [ { \"pool\": \"2001:db8:6::/64\" } ]," " \"subnet\": \"2001:db8:6::/48\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true," - " \"global\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true," + " \"reservations-global\": true" " } ]," "\"valid-lifetime\": 4000 }"; @@ -5924,16 +5915,12 @@ TEST_F(Dhcp6ParserTest, hostReservationModesGlobal) { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"reservation-modes\": {" - " \"out-of-pool\": true" - " }," + "\"reservations-out-of-pool\": true," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," " \"subnet\": \"2001:db8:1::/48\", " - " \"reservation-modes\": {" - " \"in-subnet\": true," - " \"out-of-pool\": true" - " }" + " \"reservations-out-of-pool\": true," + " \"reservations-in-subnet\": true" " }," " {" " \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ]," @@ -6891,9 +6878,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) { " \"ip-address\": \"1111::1\"\n" " },\n" " \"rapid-commit\": true,\n" - " \"reservation-modes\": {" - " \"global\": false" - " },\n" + " \"reservations-global\": false," " \"subnet6\": [\n" " { \n" " \"subnet\": \"2001:db1::/48\",\n" @@ -6915,9 +6900,7 @@ TEST_F(Dhcp6ParserTest, sharedNetworksDerive) { " \"max-valid-lifetime\": 500, \n" " \"interface-id\": \"twotwo\",\n" " \"rapid-commit\": true,\n" - " \"reservation-modes\": {" - " \"out-of-pool\": true" - " }" + " \"reservations-out-of-pool\": true" " }\n" " ]\n" " },\n" diff --git a/src/bin/dhcp6/tests/host_unittest.cc b/src/bin/dhcp6/tests/host_unittest.cc index c17525620d..4dd97beb40 100644 --- a/src/bin/dhcp6/tests/host_unittest.cc +++ b/src/bin/dhcp6/tests/host_unittest.cc @@ -353,7 +353,7 @@ const char* CONFIGS[] = { " \"subnet\": \"2001:db8:1::/48\", \n" " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], \n" " \"interface\" : \"eth0\", \n" - " \"reservation-modes\": { \"global\": true } \n" + " \"reservations-global\": true\n" " }," " { \n" " \"subnet\": \"2001:db8:2::/48\", \n" @@ -394,7 +394,7 @@ const char* CONFIGS[] = { " { \n" " \"subnet\": \"2001:db8:1::/48\", \n" " \"interface\" : \"eth0\", \n" - " \"reservation-modes\": { \"global\": true }," + " \"reservations-global\": true,\n" " \"pd-pools\": [ \n" " { \n" " \"prefix\": \"3000::\", \n" @@ -435,7 +435,7 @@ const char* CONFIGS[] = { " \"test\": \"not member('reserved_class')\"" "}" "],\n" - "\"reservation-modes\": { \"global\": true }," + "\"reservations-global\": true,\n" "\"valid-lifetime\": 4000,\n" "\"reservations\": [ \n" "{\n" @@ -487,7 +487,7 @@ const char* CONFIGS[] = { " \"test\": \"not member('reserved_class')\"" "}" "],\n" - "\"reservation-modes\": { \"global\": true }," + "\"reservations-global\": true,\n" "\"valid-lifetime\": 4000,\n" "\"reservations\": [ \n" "{\n" diff --git a/src/bin/keactrl/kea-dhcp4.conf.pre b/src/bin/keactrl/kea-dhcp4.conf.pre index 8bc8816761..b96a2f7d38 100644 --- a/src/bin/keactrl/kea-dhcp4.conf.pre +++ b/src/bin/keactrl/kea-dhcp4.conf.pre @@ -360,7 +360,8 @@ // specific options. // // When using reservations, it is useful to configure - // reservation-modes (subnet specific parameter) and + // reservations-out-of-pool, reservations-in-subnet, + // reservations-global (subnet specific parameters) and // host-reservation-identifiers (global parameter). { "client-id": "01:12:23:34:45:56:67", diff --git a/src/lib/cc/simple_parser.cc b/src/lib/cc/simple_parser.cc index bb3c822f24..de2d308189 100644 --- a/src/lib/cc/simple_parser.cc +++ b/src/lib/cc/simple_parser.cc @@ -224,26 +224,6 @@ size_t SimpleParser::setDefaults(ElementPtr scope, x.reset(new DoubleElement(dbl_value, pos)); break; } - case Element::map: { - auto data = Element::fromJSON(def_value.value_); - if (data->getType() != Element::map) { - isc_throw(BadValue, - "Internal error. Incorrect map value type for " - << def_value.name_ << " : " << def_value.value_); - } - x = data; - break; - } - case Element::list: { - auto data = Element::fromJSON(def_value.value_); - if (data->getType() != Element::list) { - isc_throw(BadValue, - "Internal error. Incorrect list value type for " - << def_value.name_ << " : " << def_value.value_); - } - x = data; - break; - } default: // No default values for null, list or map isc_throw(DhcpConfigError, diff --git a/src/lib/dhcpsrv/network.cc b/src/lib/dhcpsrv/network.cc index 01aceb5d17..b7ba2ba0cd 100644 --- a/src/lib/dhcpsrv/network.cc +++ b/src/lib/dhcpsrv/network.cc @@ -216,24 +216,21 @@ Network::toElement() const { if (hrmode & Network::HR_OUT_OF_POOL) { hr_out_of_pool = true; } - ElementPtr reservation_modes = Element::createMap(); if (hrmode == Network::HR_DISABLED) { - reservation_modes->set("global", Element::create(false)); - reservation_modes->set("in-subnet", Element::create(false)); - reservation_modes->set("out-of-pool", Element::create(false)); + 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) { - reservation_modes->set("global", Element::create(true)); + map->set("reservations-global", Element::create(true)); } if (hr_in_subnet) { - reservation_modes->set("in-subnet", Element::create(true)); + map->set("reservations-in-subnet", Element::create(true)); } if (hr_out_of_pool) { - reservation_modes->set("out-of-pool", Element::create(true)); + map->set("reservations-out-of-pool", Element::create(true)); } } - - map->set("reservation-modes", reservation_modes); } // Set options diff --git a/src/lib/dhcpsrv/network.h b/src/lib/dhcpsrv/network.h index 3990522add..857bab6c91 100644 --- a/src/lib/dhcpsrv/network.h +++ b/src/lib/dhcpsrv/network.h @@ -155,33 +155,30 @@ public: /// @brief Specifies allowed host reservation mode. /// - typedef enum : uint8_t { - - /// None - host reservation is disabled. No reservation types - /// are allowed. - 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. - /// 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 = 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. - HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL - } HRModeFlag; + /// None - host reservation is disabled. No reservation types + /// are allowed. + const uint8_t 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. + /// When HR_IN_SUBNET is set, this is always enabled as well. + const uint8_t 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. + const uint8_t HR_IN_SUBNET = 1 << 1; + + /// Only global reservations are allowed. This mode + /// instructs AllocEngine to only look at global reservations. + const uint8_t 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. + const uint8_t HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL; /// @brief Bitset used to store @ref HRModeFlag flags. typedef uint8_t HRMode; @@ -450,7 +447,7 @@ public: uint8_t flags = 0; util::Optional hr_mode_global; hr_mode_global = getGlobalProperty(hr_mode_global, - "reservation-modes.global"); + "reservations-global"); if (!hr_mode_global.unspecified()) { if (hr_mode_global.get()) { flags |= Network::HR_GLOBAL; @@ -459,7 +456,7 @@ public: } util::Optional hr_mode_in_subnet; hr_mode_in_subnet = getGlobalProperty(hr_mode_in_subnet, - "reservation-modes.in-subnet"); + "reservations-in-subnet"); if (!hr_mode_in_subnet.unspecified()) { if (hr_mode_in_subnet.get()) { flags |= Network::HR_IN_SUBNET; @@ -468,7 +465,7 @@ public: } util::Optional hr_mode_out_of_pool; hr_mode_out_of_pool = getGlobalProperty(hr_mode_out_of_pool, - "reservation-modes.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; @@ -849,39 +846,14 @@ protected: template ReturnType getGlobalProperty(ReturnType property, const std::string& global_name) const { - std::string member_name; - std::string search_name = global_name; - auto found = global_name.find('.'); - if (found != std::string::npos) { - if (std::count(global_name.begin(), global_name.end(), '.') > 1) { - isc_throw(BadValue, "more than one level of indirection found in: " - << global_name); - } - member_name = global_name.substr(found + 1, global_name.length() - found - 1); - search_name = global_name.substr(0, found); - } - if (!search_name.empty() && fetch_globals_fn_) { + if (!global_name.empty() && fetch_globals_fn_) { data::ConstElementPtr globals = fetch_globals_fn_(); if (globals && (globals->getType() == data::Element::map)) { - data::ConstElementPtr global_param = globals->get(search_name); + data::ConstElementPtr global_param = globals->get(global_name); if (global_param) { - if (!member_name.empty()) { - if (global_param->getType() != data::Element::map) { - isc_throw(BadValue, "the parameter: " << global_name - << " must be a map"); - } - auto member_element = global_param->get(member_name); - if (member_element) { - // If there is a global parameter with the specified - // member, convert the member to the optional value - // of the given type and return. - return (data::ElementValue()(member_element)); - } - } else { - // If there is a global parameter, convert it to the - // optional value of the given type and return. - return (data::ElementValue()(global_param)); - } + // If there is a global parameter, convert it to the + // optional value of the given type and return. + return (data::ElementValue()(global_param)); } } } diff --git a/src/lib/dhcpsrv/parsers/base_network_parser.cc b/src/lib/dhcpsrv/parsers/base_network_parser.cc index 316cd2bbe2..eb4b0e7020 100644 --- a/src/lib/dhcpsrv/parsers/base_network_parser.cc +++ b/src/lib/dhcpsrv/parsers/base_network_parser.cc @@ -202,9 +202,21 @@ void BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network_data, NetworkPtr& network) { if (network_data->contains("reservation-mode")) { - if (network_data->contains("reservation-modes")) { + bool found = false; + if (network_data->contains("reservations-out-of-pool")) { + found = true + } + if (network_data->contains("reservations-in-subnet")) { + found = true + } + if (network_data->contains("reservations-global")) { + found = true + } + if (found) isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'" - " and 'reservation-modes' parameters"); + " and one of 'reservations-out-of-pool'" + " , 'reservations-in-subnet' or" + " 'reservations-global' parameters"); } try { std::string hr_mode = getString(network_data, "reservation-mode"); @@ -221,19 +233,28 @@ void BaseNetworkParser::parseHostReservationModes(const data::ConstElementPtr& network_data, NetworkPtr& network) { if (network_data->contains("reservation-modes")) { - if (network_data->contains("reservation-mode")) { + bool found = false; + if (network_data->contains("reservations-out-of-pool")) { + found = true + } + if (network_data->contains("reservations-in-subnet")) { + found = true + } + if (network_data->contains("reservations-global")) { + found = true + } + if (found) isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'" - " and 'reservation-modes' parameters"); + " and one of 'reservations-out-of-pool'" + " , 'reservations-in-subnet' or" + " 'reservations-global' parameters"); } try { - auto reservation_modes = network_data->get("reservation-modes"); HostReservationModesParser parser; - Network::HRMode flags = parser.parse(reservation_modes); + Network::HRMode flags = parser.parse(network_data); network->setHostReservationMode(flags); } catch (const BadValue& ex) { - isc_throw(DhcpConfigError, "invalid reservation-modes parameter: " - << ex.what() << " (" << getPosition("reservation-modes", - network_data) << ")"); + isc_throw(DhcpConfigError, "invalid parameter: " << ex.what()); } } } diff --git a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc index 6044e3059f..2ce25deaef 100644 --- a/src/lib/dhcpsrv/parsers/dhcp_parsers.cc +++ b/src/lib/dhcpsrv/parsers/dhcp_parsers.cc @@ -859,7 +859,7 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params, } } - // reservation-modes + // reservation modes parseHostReservationModes(params, network); // Let's set host reservation mode. If not specified, the default value of @@ -1334,7 +1334,7 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params, subnet6->setIface(iface); } - // reservation-modes + // reservation modes parseHostReservationModes(params, network); // Let's set host reservation mode. If not specified, the default value of diff --git a/src/lib/dhcpsrv/parsers/reservation_modes_parser.cc b/src/lib/dhcpsrv/parsers/reservation_modes_parser.cc index cf14ff407f..36c3aa532d 100644 --- a/src/lib/dhcpsrv/parsers/reservation_modes_parser.cc +++ b/src/lib/dhcpsrv/parsers/reservation_modes_parser.cc @@ -20,16 +20,16 @@ namespace isc { namespace dhcp { Network::HRMode -HostReservationModesParser::parse(const ConstElementPtr& control_elem) { - if (control_elem->getType() != Element::map) { - isc_throw(DhcpConfigError, "reservation-modes must be a map"); +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; try { - elem = control_elem->get("global"); + elem = config_elem->get("reservations-global"); if (elem) { bool value = elem->boolValue(); if (value) { @@ -37,7 +37,7 @@ HostReservationModesParser::parse(const ConstElementPtr& control_elem) { } } - elem = control_elem->get("in-subnet"); + elem = config_elem->get("reservations-in-subnet"); if (elem) { bool value = elem->boolValue(); if (value) { @@ -45,7 +45,7 @@ HostReservationModesParser::parse(const ConstElementPtr& control_elem) { } } - elem = control_elem->get("out-of-pool"); + elem = config_elem->get("reservations-out-of-pool"); if (elem) { bool value = elem->boolValue(); if (value) { diff --git a/src/lib/dhcpsrv/parsers/shared_network_parser.cc b/src/lib/dhcpsrv/parsers/shared_network_parser.cc index 0bc95ba69a..3248ede01f 100644 --- a/src/lib/dhcpsrv/parsers/shared_network_parser.cc +++ b/src/lib/dhcpsrv/parsers/shared_network_parser.cc @@ -185,7 +185,7 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) { } } - // reservation-modes + // reservation modes parseHostReservationModes(shared_network_data, network); // reservation-mode @@ -354,7 +354,7 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) { } } - // reservation-modes + // reservation modes parseHostReservationModes(shared_network_data, network); // reservation-mode diff --git a/src/lib/dhcpsrv/parsers/simple_parser4.cc b/src/lib/dhcpsrv/parsers/simple_parser4.cc index 7207824f97..dfd3345c3c 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser4.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser4.cc @@ -71,7 +71,9 @@ const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = { { "config-control", Element::map }, { "server-tag", Element::string }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "calculate-tee-times", Element::boolean }, { "t1-percent", Element::real }, { "t2-percent", Element::real }, @@ -111,7 +113,9 @@ const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = { { "server-hostname", Element::string, "" }, { "boot-file-name", Element::string, "" }, { "server-tag", Element::string, "" }, - { "reservation-modes", Element::map, "{\"in-subnet\": true, \"out-of-pool\": true}" }, + { "reservations-out-of-pool", Element::boolean, "true" }, + { "reservations-in-subnet", Element::boolean, "true" }, + { "reservations-global", Element::boolean, "false" }, { "calculate-tee-times", Element::boolean, "false" }, { "t1-percent", Element::real, ".50" }, { "t2-percent", Element::real, ".875" }, @@ -208,7 +212,9 @@ const SimpleKeywords SimpleParser4::SUBNET4_PARAMETERS = { { "require-client-classes", Element::list }, { "reservations", Element::list }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map, }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "relay", Element::map }, { "match-client-id", Element::boolean }, { "authoritative", Element::boolean }, @@ -326,7 +332,9 @@ const SimpleKeywords SimpleParser4::SHARED_NETWORK4_PARAMETERS = { { "boot-file-name", Element::string }, { "relay", Element::map }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "client-class", Element::string }, { "require-client-classes", Element::list }, { "valid-lifetime", Element::integer }, diff --git a/src/lib/dhcpsrv/parsers/simple_parser6.cc b/src/lib/dhcpsrv/parsers/simple_parser6.cc index 4ae14d22e0..7a75b1bc19 100644 --- a/src/lib/dhcpsrv/parsers/simple_parser6.cc +++ b/src/lib/dhcpsrv/parsers/simple_parser6.cc @@ -72,7 +72,9 @@ const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = { { "config-control", Element::map }, { "server-tag", Element::string }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "calculate-tee-times", Element::boolean }, { "t1-percent", Element::real }, { "t2-percent", Element::real }, @@ -107,7 +109,9 @@ const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = { { "decline-probation-period", Element::integer, "86400" }, // 24h { "dhcp4o6-port", Element::integer, "0" }, { "server-tag", Element::string, "" }, - { "reservation-modes", Element::map, "{\"in-subnet\": true, \"out-of-pool\": true}" }, + { "reservations-out-of-pool", Element::boolean, "true" }, + { "reservations-in-subnet", Element::boolean, "true" }, + { "reservations-global", Element::boolean, "false" }, { "calculate-tee-times", Element::boolean, "true" }, { "t1-percent", Element::real, ".50" }, { "t2-percent", Element::real, ".80" }, @@ -210,7 +214,9 @@ const SimpleKeywords SimpleParser6::SUBNET6_PARAMETERS = { { "require-client-classes", Element::list }, { "reservations", Element::list }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "relay", Element::map }, { "user-context", Element::map }, { "comment", Element::string }, @@ -335,7 +341,9 @@ const SimpleKeywords SimpleParser6::SHARED_NETWORK6_PARAMETERS = { { "option-data", Element::list }, { "relay", Element::map }, { "reservation-mode", Element::string }, - { "reservation-modes", Element::map }, + { "reservations-out-of-pool", Element::boolean }, + { "reservations-in-subnet", Element::boolean }, + { "reservations-global", Element::boolean }, { "client-class", Element::string }, { "require-client-classes", Element::list }, { "preferred-lifetime", Element::integer }, diff --git a/src/lib/dhcpsrv/srv_config.cc b/src/lib/dhcpsrv/srv_config.cc index 814909bce5..d0c2646a7c 100644 --- a/src/lib/dhcpsrv/srv_config.cc +++ b/src/lib/dhcpsrv/srv_config.cc @@ -375,28 +375,8 @@ SrvConfig::applyDefaultsConfiguredGlobals(const SimpleDefaults& defaults) { x.reset(new DoubleElement(dbl_value, pos)); break; } - case Element::map: { - auto data = Element::fromJSON(def_value.value_); - if (data->getType() != Element::map) { - isc_throw(BadValue, - "Internal error. Incorrect map value type for " - << def_value.name_ << " : " << def_value.value_); - } - x = data; - break; - } - case Element::list: { - auto data = Element::fromJSON(def_value.value_); - if (data->getType() != Element::list) { - isc_throw(BadValue, - "Internal error. Incorrect list value type for " - << def_value.name_ << " : " << def_value.value_); - } - x = data; - break; - } default: - // No default values for null + // No default values for null, list or map isc_throw(BadValue, "Internal error. Incorrect default value type for " << def_value.name_); diff --git a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc index 944160f91a..4eb5b55884 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc @@ -1115,7 +1115,8 @@ TEST(CfgSubnets4Test, unparseSubnet) { " \"4o6-interface-id\": \"\",\n" " \"4o6-subnet\": \"\",\n" " \"authoritative\": false,\n" - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"option-data\": [ ],\n" " \"pools\": [ ]\n," " \"require-client-classes\": [ \"foo\", \"bar\" ],\n" @@ -1282,7 +1283,8 @@ TEST(CfgSubnets4Test, teeTimePercentValidation) { " \"boot-file-name\": \"\", \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"4o6-interface\": \"\", \n" " \"4o6-interface-id\": \"\", \n" " \"4o6-subnet\": \"\" \n" @@ -1349,7 +1351,8 @@ TEST(CfgSubnets4Test, validLifetimeValidation) { " \"boot-file-name\": \"\", \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"4o6-interface\": \"\", \n" " \"4o6-interface-id\": \"\", \n" " \"4o6-subnet\": \"\" \n" @@ -1591,7 +1594,8 @@ TEST(CfgSubnets4Test, hostnameSanitizierValidation) { " \"boot-file-name\": \"\", \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"4o6-interface\": \"\", \n" " \"4o6-interface-id\": \"\", \n" " \"4o6-subnet\": \"\" \n" @@ -1669,7 +1673,8 @@ TEST(CfgSubnets4Test, cacheParamValidation) { " \"boot-file-name\": \"\", \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"4o6-interface\": \"\", \n" " \"4o6-interface-id\": \"\", \n" " \"4o6-subnet\": \"\" \n" diff --git a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc index add98d9e85..e1c98d4c7b 100644 --- a/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc @@ -710,7 +710,8 @@ TEST(CfgSubnets6Test, unparseSubnet) { " \"min-valid-lifetime\": 100,\n" " \"max-valid-lifetime\": 300,\n" " \"rapid-commit\": false,\n" - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true},\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"pools\": [ ],\n" " \"pd-pools\": [ ],\n" " \"option-data\": [ ],\n" @@ -1079,7 +1080,8 @@ TEST(CfgSubnets6Test, teeTimePercentValidation) { " \"valid-lifetime\": 300, \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true\n" " }"; @@ -1142,7 +1144,8 @@ TEST(CfgSubnets6Test, preferredLifetimeValidation) { " \"valid-lifetime\": 300, \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true\n" " }"; @@ -1377,7 +1380,8 @@ TEST(CfgSubnets6Test, hostnameSanitizierValidation) { " \"valid-lifetime\": 300, \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true\n" " }"; data::ElementPtr elems; @@ -1447,7 +1451,8 @@ TEST(CfgSubnets6Test, cacheParamValidation) { " \"valid-lifetime\": 300, \n" " \"client-class\": \"\", \n" " \"require-client-classes\": [] \n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}\n" + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true\n" " }"; data::ElementPtr elems; diff --git a/src/lib/dhcpsrv/tests/network_unittest.cc b/src/lib/dhcpsrv/tests/network_unittest.cc index c94f30f3d7..7c88e21145 100644 --- a/src/lib/dhcpsrv/tests/network_unittest.cc +++ b/src/lib/dhcpsrv/tests/network_unittest.cc @@ -185,11 +185,9 @@ TEST_F(NetworkTest, inheritanceSupport4) { globals_->set("cache-max-age", Element::create(20)); globals_->set("ddns-update-on-renew", Element::create(true)); globals_->set("ddns-use-conflict-resolution", Element::create(true)); - auto reservation_modes = Element::createMap(); - reservation_modes->set("global", Element::create(false)); - reservation_modes->set("in-subnet", Element::create(false)); - reservation_modes->set("out-of-pool", Element::create(false)); - globals_->set("reservation-modes", reservation_modes); + 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. @@ -223,7 +221,7 @@ TEST_F(NetworkTest, inheritanceSupport4) { Network::HR_DISABLED); } { - SCOPED_TRACE("reservation-modes"); + SCOPED_TRACE("reservations-global"); testNetworkInheritance(&Network::getHostReservationMode, &Network::setHostReservationMode, Network::HR_OUT_OF_POOL, diff --git a/src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc b/src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc index d72a556f94..d176ef558f 100644 --- a/src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc @@ -58,117 +58,117 @@ TEST_F(HostReservationModesParserTest, validContent) { { "reservation modes disabled", "{ \n" - " \"global\": false, \n" - " \"in-subnet\": false, \n" - " \"out-of-pool\": false \n" + " \"reservations-global\": false, \n" + " \"reservations-in-subnet\": false, \n" + " \"reservations-out-of-pool\": false \n" "} \n", Network::HR_DISABLED }, { "reservation modes global enabled", "{ \n" - " \"global\": true, \n" - " \"in-subnet\": false, \n" - " \"out-of-pool\": false \n" + " \"reservations-global\": true, \n" + " \"reservations-in-subnet\": false, \n" + " \"reservations-out-of-pool\": false \n" "} \n", Network::HR_GLOBAL }, { "reservation modes in-subnet enabled", "{ \n" - " \"global\": false, \n" - " \"in-subnet\": true, \n" - " \"out-of-pool\": false \n" + " \"reservations-global\": false, \n" + " \"reservations-in-subnet\": true, \n" + " \"reservations-out-of-pool\": false \n" "} \n", Network::HR_IN_SUBNET }, { "reservation modes global and in-subnet enabled", "{ \n" - " \"global\": true, \n" - " \"in-subnet\": true, \n" - " \"out-of-pool\": false \n" + " \"reservations-global\": true, \n" + " \"reservations-in-subnet\": true, \n" + " \"reservations-out-of-pool\": false \n" "} \n", Network::HR_GLOBAL|Network::HR_IN_SUBNET }, { "reservation modes out-of-pool enabled", "{ \n" - " \"global\": false, \n" - " \"in-subnet\": false, \n" - " \"out-of-pool\": true \n" + " \"reservations-global\": false, \n" + " \"reservations-in-subnet\": false, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_OUT_OF_POOL }, { "reservation modes global and out-of-pool enabled", "{ \n" - " \"global\": true, \n" - " \"in-subnet\": false, \n" - " \"out-of-pool\": true \n" + " \"reservations-global\": true, \n" + " \"reservations-in-subnet\": false, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_GLOBAL|Network::HR_OUT_OF_POOL }, { "reservation modes in-subnet and out-of-pool enabled", "{ \n" - " \"global\": false, \n" - " \"in-subnet\": true, \n" - " \"out-of-pool\": true \n" + " \"reservations-global\": false, \n" + " \"reservations-in-subnet\": true, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_IN_SUBNET|Network::HR_OUT_OF_POOL }, { "reservation modes global, in-subnet and out-of-pool enabled", "{ \n" - " \"global\": true, \n" - " \"in-subnet\": true, \n" - " \"out-of-pool\": true \n" + " \"reservations-global\": true, \n" + " \"reservations-in-subnet\": true, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_GLOBAL|Network::HR_IN_SUBNET|Network::HR_OUT_OF_POOL }, { "only global", "{ \n" - " \"global\": true \n" + " \"reservations-global\": true \n" "} \n", Network::HR_GLOBAL }, { "only in-subnet", "{ \n" - " \"in-subnet\": true \n" + " \"reservations-in-subnet\": true \n" "} \n", Network::HR_IN_SUBNET }, { "only out-of-pool", "{ \n" - " \"out-of-pool\": true \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_OUT_OF_POOL }, { "only global and in-subnet", "{ \n" - " \"global\": true, \n" - " \"in-subnet\": true \n" + " \"reservations-global\": true, \n" + " \"reservations-in-subnet\": true \n" "} \n", Network::HR_GLOBAL|Network::HR_IN_SUBNET }, { "only global and out-of-pool", "{ \n" - " \"global\": true, \n" - " \"out-of-pool\": true \n" + " \"reservations-global\": true, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_GLOBAL|Network::HR_OUT_OF_POOL }, { "only in-subnet and out-of-pool", "{ \n" - " \"in-subnet\": true, \n" - " \"out-of-pool\": true \n" + " \"reservations-in-subnet\": true, \n" + " \"reservations-out-of-pool\": true \n" "} \n", Network::HR_IN_SUBNET|Network::HR_OUT_OF_POOL }, @@ -210,19 +210,19 @@ TEST_F(HostReservationModesParserTest, invalidContent) { { "global not boolean", "{ \n" - " \"global\": \"always\" \n" + " \"reservations-global\": \"always\" \n" "} \n" }, { "in-subnet not boolean", "{ \n" - " \"in-subnet\": \"always\" \n" + " \"reservations-in-subnet\": \"always\" \n" "} \n" }, { "out-of-pool not boolean", "{ \n" - " \"out-of-pool\": \"always\" \n" + " \"reservations-out-of-pool\": \"always\" \n" "} \n" } }; diff --git a/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc index 3ef856ea5b..ad01f34fe2 100644 --- a/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_parser_unittest.cc @@ -128,7 +128,7 @@ public: " \"rebind-timer\": 199," " \"relay\": { \"ip-addresses\": [ \"10.1.1.1\" ] }," " \"renew-timer\": 99," - " \"reservation-modes\": {\"out-of-pool\": true}," + " \"reservations-out-of-pool\": true," " \"server-hostname\": \"example.org\"," " \"require-client-classes\": [ \"runner\" ]," " \"user-context\": { \"comment\": \"example\" }," @@ -173,7 +173,8 @@ public: " \"boot-file-name\": \"\"," " \"client-class\": \"\"," " \"require-client-classes\": []\n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true," + " \"reservations-out-of-pool\": true," " \"4o6-interface\": \"\"," " \"4o6-interface-id\": \"\"," " \"4o6-subnet\": \"\"," @@ -198,7 +199,8 @@ public: " \"boot-file-name\": \"\"," " \"client-class\": \"\"," " \"require-client-classes\": []\n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true," + " \"reservations-out-of-pool\": true," " \"4o6-interface\": \"\"," " \"4o6-interface-id\": \"\"," " \"4o6-subnet\": \"\"," @@ -547,7 +549,7 @@ public: " \"relay\": { \"ip-addresses\": [ \"2001:db8:1::1\" ] }," " \"renew-timer\": 99," " \"require-client-classes\": [ \"runner\" ]," - " \"reservation-modes\": {\"out-of-pool\": true}," + " \"reservations-out-of-pool\": true," " \"user-context\": { }," " \"valid-lifetime\": 399," " \"min-valid-lifetime\": 299," @@ -589,7 +591,8 @@ public: " \"max-valid-lifetime\": 500," " \"client-class\": \"\"," " \"require-client-classes\": []\n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true," + " \"reservations-out-of-pool\": true," " \"rapid-commit\": false," " \"hostname-char-set\": \"\"" " }," @@ -604,7 +607,8 @@ public: " \"valid-lifetime\": 40," " \"client-class\": \"\"," " \"require-client-classes\": []\n," - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true," + " \"reservations-out-of-pool\": true," " \"rapid-commit\": false" " }" " ]" diff --git a/src/lib/dhcpsrv/tests/shared_network_unittest.cc b/src/lib/dhcpsrv/tests/shared_network_unittest.cc index 985edafd17..4b1e8cd3d6 100644 --- a/src/lib/dhcpsrv/tests/shared_network_unittest.cc +++ b/src/lib/dhcpsrv/tests/shared_network_unittest.cc @@ -640,7 +640,8 @@ TEST(SharedNetwork4Test, unparse) { " },\n" " \"renew-timer\": 100,\n" " \"require-client-classes\": [ \"foo\" ],\n" - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"subnet4\": [\n" " {\n" " \"4o6-interface\": \"\",\n" @@ -1331,7 +1332,8 @@ TEST(SharedNetwork6Test, unparse) { " },\n" " \"renew-timer\": 100,\n" " \"require-client-classes\": [ \"foo\" ],\n" - " \"reservation-modes\": {\"in-subnet\": true, \"out-of-pool\": true}," + " \"reservations-in-subnet\": true,\n" + " \"reservations-out-of-pool\": true,\n" " \"subnet6\": [\n" " {\n" " \"id\": 1,\n"