mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-09-04 07:55:18 +00:00
[#1405] added parser class
This commit is contained in:
@@ -4853,7 +4853,15 @@ following can be used:
|
|||||||
"valid-lifetime": 600,
|
"valid-lifetime": 600,
|
||||||
"subnet4": [ {
|
"subnet4": [ {
|
||||||
"subnet": "10.0.0.0/24",
|
"subnet": "10.0.0.0/24",
|
||||||
"reservation-mode": "global",
|
# It is deprecated by the "reservation-modes" map.
|
||||||
|
# "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
|
||||||
|
},
|
||||||
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ]
|
"pools": [ { "pool": "10.0.0.10-10.0.0.100" } ]
|
||||||
} ]
|
} ]
|
||||||
}
|
}
|
||||||
@@ -4956,7 +4964,15 @@ following example:
|
|||||||
"hw-address": "aa:bb:cc:dd:ee:fe",
|
"hw-address": "aa:bb:cc:dd:ee:fe",
|
||||||
"client-classes": [ "reserved_class" ]
|
"client-classes": [ "reserved_class" ]
|
||||||
}],
|
}],
|
||||||
"reservation-mode": "global",
|
# It is deprecated by the "reservation-modes" map.
|
||||||
|
# "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
|
||||||
|
},
|
||||||
"shared-networks": [{
|
"shared-networks": [{
|
||||||
"subnet4": [
|
"subnet4": [
|
||||||
{
|
{
|
||||||
|
@@ -4294,7 +4294,15 @@ following can be used:
|
|||||||
"valid-lifetime": 600,
|
"valid-lifetime": 600,
|
||||||
"subnet4": [ {
|
"subnet4": [ {
|
||||||
"subnet": "2001:db8:1::/64",
|
"subnet": "2001:db8:1::/64",
|
||||||
"reservation-mode": "global",
|
# It is deprecated by the "reservation-modes" map.
|
||||||
|
# "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
|
||||||
|
},
|
||||||
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ]
|
"pools": [ { "pool": "2001:db8:1::-2001:db8:1::100" } ]
|
||||||
} ]
|
} ]
|
||||||
}
|
}
|
||||||
@@ -4397,7 +4405,15 @@ following example:
|
|||||||
"hw-address": "aa:bb:cc:dd:ee:fe",
|
"hw-address": "aa:bb:cc:dd:ee:fe",
|
||||||
"client-classes": [ "reserved_class" ]
|
"client-classes": [ "reserved_class" ]
|
||||||
}],
|
}],
|
||||||
"reservation-mode": "global",
|
# It is deprecated by the "reservation-modes" map.
|
||||||
|
# "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
|
||||||
|
},
|
||||||
"shared-networks": [{
|
"shared-networks": [{
|
||||||
"subnet6": [
|
"subnet6": [
|
||||||
{
|
{
|
||||||
|
@@ -2655,7 +2655,15 @@ An example response could look as follows:
|
|||||||
"ip-address": "0.0.0.0"
|
"ip-address": "0.0.0.0"
|
||||||
},
|
},
|
||||||
"renew-timer": 60,
|
"renew-timer": 60,
|
||||||
"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
|
||||||
|
},
|
||||||
"subnet4": [
|
"subnet4": [
|
||||||
{
|
{
|
||||||
"subnet": "192.0.2.0/24",
|
"subnet": "192.0.2.0/24",
|
||||||
|
@@ -564,6 +564,15 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||||
|
if (reservation_mode) {
|
||||||
|
reservation_mode = mutable_cfg->get("reservation-modes");
|
||||||
|
if (reservation_mode) {
|
||||||
|
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||||
|
" and 'reservation-modes' parameters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
||||||
if (config_control) {
|
if (config_control) {
|
||||||
parameter_name = "config-control";
|
parameter_name = "config-control";
|
||||||
@@ -628,6 +637,7 @@ configureDhcp4Server(Dhcpv4Srv& server, isc::data::ConstElementPtr config_set,
|
|||||||
(config_pair.first == "boot-file-name") ||
|
(config_pair.first == "boot-file-name") ||
|
||||||
(config_pair.first == "server-tag") ||
|
(config_pair.first == "server-tag") ||
|
||||||
(config_pair.first == "reservation-mode") ||
|
(config_pair.first == "reservation-mode") ||
|
||||||
|
(config_pair.first == "reservation-modes") ||
|
||||||
(config_pair.first == "calculate-tee-times") ||
|
(config_pair.first == "calculate-tee-times") ||
|
||||||
(config_pair.first == "t1-percent") ||
|
(config_pair.first == "t1-percent") ||
|
||||||
(config_pair.first == "t2-percent") ||
|
(config_pair.first == "t2-percent") ||
|
||||||
|
@@ -184,6 +184,8 @@ Parser4Context::contextName()
|
|||||||
return ("subnet4");
|
return ("subnet4");
|
||||||
case RESERVATION_MODE:
|
case RESERVATION_MODE:
|
||||||
return ("reservation-mode");
|
return ("reservation-mode");
|
||||||
|
case RESERVATION_MODES:
|
||||||
|
return ("reservation-modes");
|
||||||
case OPTION_DEF:
|
case OPTION_DEF:
|
||||||
return ("option-def");
|
return ("option-def");
|
||||||
case OPTION_DATA:
|
case OPTION_DATA:
|
||||||
|
@@ -84,7 +84,7 @@ public:
|
|||||||
/// This will parse the input as hooks-library.
|
/// This will parse the input as hooks-library.
|
||||||
PARSER_HOOKS_LIBRARY,
|
PARSER_HOOKS_LIBRARY,
|
||||||
|
|
||||||
/// This will parse the input as dhcp-ddns.
|
/// This will parse the input as dhcp-ddns. (D2 client config)
|
||||||
PARSER_DHCP_DDNS,
|
PARSER_DHCP_DDNS,
|
||||||
|
|
||||||
/// This will parse the input as reservation-modes.
|
/// This will parse the input as reservation-modes.
|
||||||
@@ -195,7 +195,7 @@ public:
|
|||||||
/// Check if a required parameter is present in the map at the top
|
/// Check if a required parameter is present in the map at the top
|
||||||
/// of the stack and raise an error when it is not.
|
/// of the stack and raise an error when it is not.
|
||||||
///
|
///
|
||||||
/// @param name name of the parameter to check
|
/// @param name name of the parameter expected to be present
|
||||||
/// @param open_loc location of the opening curly bracket
|
/// @param open_loc location of the opening curly bracket
|
||||||
/// @param close_loc location of the closing curly bracket
|
/// @param close_loc location of the closing curly bracket
|
||||||
/// @throw Dhcp4ParseError
|
/// @throw Dhcp4ParseError
|
||||||
|
@@ -688,6 +688,15 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConstElementPtr reservation_mode = mutable_cfg->get("reservation-mode");
|
||||||
|
if (reservation_mode) {
|
||||||
|
reservation_mode = mutable_cfg->get("reservation-modes");
|
||||||
|
if (reservation_mode) {
|
||||||
|
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||||
|
" and 'reservation-modes' parameters");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
ConstElementPtr config_control = mutable_cfg->get("config-control");
|
||||||
if (config_control) {
|
if (config_control) {
|
||||||
parameter_name = "config-control";
|
parameter_name = "config-control";
|
||||||
@@ -761,6 +770,7 @@ configureDhcp6Server(Dhcpv6Srv& server, isc::data::ConstElementPtr config_set,
|
|||||||
(config_pair.first == "dhcp4o6-port") ||
|
(config_pair.first == "dhcp4o6-port") ||
|
||||||
(config_pair.first == "server-tag") ||
|
(config_pair.first == "server-tag") ||
|
||||||
(config_pair.first == "reservation-mode") ||
|
(config_pair.first == "reservation-mode") ||
|
||||||
|
(config_pair.first == "reservation-modes") ||
|
||||||
(config_pair.first == "calculate-tee-times") ||
|
(config_pair.first == "calculate-tee-times") ||
|
||||||
(config_pair.first == "t1-percent") ||
|
(config_pair.first == "t1-percent") ||
|
||||||
(config_pair.first == "t2-percent") ||
|
(config_pair.first == "t2-percent") ||
|
||||||
|
@@ -181,6 +181,8 @@ Parser6Context::contextName()
|
|||||||
return ("subnet6");
|
return ("subnet6");
|
||||||
case RESERVATION_MODE:
|
case RESERVATION_MODE:
|
||||||
return ("reservation-mode");
|
return ("reservation-mode");
|
||||||
|
case RESERVATION_MODES:
|
||||||
|
return ("reservation-modes");
|
||||||
case OPTION_DEF:
|
case OPTION_DEF:
|
||||||
return ("option-def");
|
return ("option-def");
|
||||||
case OPTION_DATA:
|
case OPTION_DATA:
|
||||||
|
@@ -360,7 +360,7 @@
|
|||||||
// specific options.
|
// specific options.
|
||||||
//
|
//
|
||||||
// When using reservations, it is useful to configure
|
// When using reservations, it is useful to configure
|
||||||
// reservation-mode (subnet specific parameter) and
|
// reservation-modes (subnet specific parameter) and
|
||||||
// host-reservation-identifiers (global parameter).
|
// host-reservation-identifiers (global parameter).
|
||||||
{
|
{
|
||||||
"client-id": "01:12:23:34:45:56:67",
|
"client-id": "01:12:23:34:45:56:67",
|
||||||
|
@@ -45,6 +45,8 @@ EXTRA_DIST += parsers/ifaces_config_parser.h
|
|||||||
EXTRA_DIST += parsers/multi_threading_config_parser.cc
|
EXTRA_DIST += parsers/multi_threading_config_parser.cc
|
||||||
EXTRA_DIST += parsers/multi_threading_config_parser.h
|
EXTRA_DIST += parsers/multi_threading_config_parser.h
|
||||||
EXTRA_DIST += parsers/option_data_parser.h
|
EXTRA_DIST += parsers/option_data_parser.h
|
||||||
|
EXTRA_DIST += parsers/reservation_modes_parser.cc
|
||||||
|
EXTRA_DIST += parsers/reservation_modes_parser.h
|
||||||
EXTRA_DIST += parsers/sanity_checks_parser.cc
|
EXTRA_DIST += parsers/sanity_checks_parser.cc
|
||||||
EXTRA_DIST += parsers/sanity_checks_parser.h
|
EXTRA_DIST += parsers/sanity_checks_parser.h
|
||||||
EXTRA_DIST += parsers/simple_parser4.cc
|
EXTRA_DIST += parsers/simple_parser4.cc
|
||||||
@@ -178,6 +180,8 @@ libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.cc
|
|||||||
libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.h
|
libkea_dhcpsrv_la_SOURCES += parsers/option_data_parser.h
|
||||||
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.cc
|
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.cc
|
||||||
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.h
|
libkea_dhcpsrv_la_SOURCES += parsers/dhcp_queue_control_parser.h
|
||||||
|
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.cc
|
||||||
|
libkea_dhcpsrv_la_SOURCES += parsers/reservation_modes_parser.h
|
||||||
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.cc
|
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.cc
|
||||||
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.h
|
libkea_dhcpsrv_la_SOURCES += parsers/sanity_checks_parser.h
|
||||||
libkea_dhcpsrv_la_SOURCES += parsers/shared_network_parser.cc
|
libkea_dhcpsrv_la_SOURCES += parsers/shared_network_parser.cc
|
||||||
@@ -408,6 +412,7 @@ libkea_dhcpsrv_parsers_include_HEADERS = \
|
|||||||
parsers/multi_threading_config_parser.h \
|
parsers/multi_threading_config_parser.h \
|
||||||
parsers/option_data_parser.h \
|
parsers/option_data_parser.h \
|
||||||
parsers/dhcp_queue_control_parser.h \
|
parsers/dhcp_queue_control_parser.h \
|
||||||
|
parsers/reservation_modes_parser.h \
|
||||||
parsers/sanity_checks_parser.h \
|
parsers/sanity_checks_parser.h \
|
||||||
parsers/shared_network_parser.h \
|
parsers/shared_network_parser.h \
|
||||||
parsers/shared_networks_list_parser.h \
|
parsers/shared_networks_list_parser.h \
|
||||||
|
@@ -155,7 +155,7 @@ public:
|
|||||||
|
|
||||||
/// @brief Specifies allowed host reservation mode.
|
/// @brief Specifies allowed host reservation mode.
|
||||||
///
|
///
|
||||||
typedef enum {
|
typedef enum : uint8_t {
|
||||||
|
|
||||||
/// None - host reservation is disabled. No reservation types
|
/// None - host reservation is disabled. No reservation types
|
||||||
/// are allowed.
|
/// are allowed.
|
||||||
@@ -181,7 +181,10 @@ public:
|
|||||||
/// AllocEngine code has to check whether there are reservations, even
|
/// AllocEngine code has to check whether there are reservations, even
|
||||||
/// when dealing with reservations from within the dynamic pools.
|
/// when dealing with reservations from within the dynamic pools.
|
||||||
HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL
|
HR_ALL = HR_IN_SUBNET | HR_OUT_OF_POOL
|
||||||
} HRMode;
|
} HRModeFlag;
|
||||||
|
|
||||||
|
/// @brief Bitset used to store @ref HRModeFlag flags.
|
||||||
|
typedef uint8_t HRMode;
|
||||||
|
|
||||||
/// @brief Inheritance "mode" used when fetching an optional @c Network
|
/// @brief Inheritance "mode" used when fetching an optional @c Network
|
||||||
/// parameter.
|
/// parameter.
|
||||||
@@ -811,17 +814,42 @@ protected:
|
|||||||
template<typename ReturnType>
|
template<typename ReturnType>
|
||||||
ReturnType getGlobalProperty(ReturnType property,
|
ReturnType getGlobalProperty(ReturnType property,
|
||||||
const std::string& global_name) const {
|
const std::string& global_name) const {
|
||||||
if (!global_name.empty() && fetch_globals_fn_) {
|
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_) {
|
||||||
data::ConstElementPtr globals = fetch_globals_fn_();
|
data::ConstElementPtr globals = fetch_globals_fn_();
|
||||||
if (globals && (globals->getType() == data::Element::map)) {
|
if (globals && (globals->getType() == data::Element::map)) {
|
||||||
data::ConstElementPtr global_param = globals->get(global_name);
|
data::ConstElementPtr global_param = globals->get(search_name);
|
||||||
if (global_param) {
|
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<typename ReturnType::ValueType>()(member_element));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
// If there is a global parameter, convert it to the
|
// If there is a global parameter, convert it to the
|
||||||
// optional value of the given type and return.
|
// optional value of the given type and return.
|
||||||
return (data::ElementValue<typename ReturnType::ValueType>()(global_param));
|
return (data::ElementValue<typename ReturnType::ValueType>()(global_param));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return (property);
|
return (property);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#include <dhcpsrv/triplet.h>
|
#include <dhcpsrv/triplet.h>
|
||||||
#include <dhcpsrv/parsers/base_network_parser.h>
|
#include <dhcpsrv/parsers/base_network_parser.h>
|
||||||
|
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||||
#include <util/optional.h>
|
#include <util/optional.h>
|
||||||
#include <util/strutil.h>
|
#include <util/strutil.h>
|
||||||
|
|
||||||
@@ -201,6 +202,10 @@ void
|
|||||||
BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network_data,
|
BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||||
NetworkPtr& network) {
|
NetworkPtr& network) {
|
||||||
if (network_data->contains("reservation-mode")) {
|
if (network_data->contains("reservation-mode")) {
|
||||||
|
if (network_data->contains("reservation-modes")) {
|
||||||
|
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||||
|
" and 'reservation-modes' parameters");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
std::string hr_mode = getString(network_data, "reservation-mode");
|
std::string hr_mode = getString(network_data, "reservation-mode");
|
||||||
network->setHostReservationMode(Network::hrModeFromString(hr_mode));
|
network->setHostReservationMode(Network::hrModeFromString(hr_mode));
|
||||||
@@ -212,6 +217,27 @@ BaseNetworkParser::parseHostReservationMode(const data::ConstElementPtr& network
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BaseNetworkParser::parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||||
|
NetworkPtr& network) {
|
||||||
|
if (network_data->contains("reservation-modes")) {
|
||||||
|
if (network_data->contains("reservation-mode")) {
|
||||||
|
isc_throw(DhcpConfigError, "invalid use of both 'reservation-mode'"
|
||||||
|
" and 'reservation-modes' parameters");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
auto reservation_modes = network_data->get("reservation-modes");
|
||||||
|
HostReservationModesParser parser;
|
||||||
|
Network::HRMode flags = parser.parse(reservation_modes);
|
||||||
|
network->setHostReservationMode(flags);
|
||||||
|
} catch (const BadValue& ex) {
|
||||||
|
isc_throw(DhcpConfigError, "invalid reservation-modes parameter: "
|
||||||
|
<< ex.what() << " (" << getPosition("reservation-modes",
|
||||||
|
network_data) << ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
|
BaseNetworkParser::parseDdnsParams(const data::ConstElementPtr& network_data,
|
||||||
NetworkPtr& network) {
|
NetworkPtr& network) {
|
||||||
|
@@ -80,6 +80,9 @@ protected:
|
|||||||
|
|
||||||
/// @brief Parses host reservation mode.
|
/// @brief Parses host reservation mode.
|
||||||
///
|
///
|
||||||
|
/// @note Configuring 'reservation-mode' is deprecated. The new map
|
||||||
|
/// 'reservation-modes' should be used.
|
||||||
|
///
|
||||||
/// @param network_data Data element holding shared network
|
/// @param network_data Data element holding shared network
|
||||||
/// configuration to be parsed.
|
/// configuration to be parsed.
|
||||||
/// @param [out] network Pointer to a network in which parsed data is
|
/// @param [out] network Pointer to a network in which parsed data is
|
||||||
@@ -87,6 +90,15 @@ protected:
|
|||||||
void parseHostReservationMode(const data::ConstElementPtr& network_data,
|
void parseHostReservationMode(const data::ConstElementPtr& network_data,
|
||||||
NetworkPtr& network);
|
NetworkPtr& network);
|
||||||
|
|
||||||
|
/// @brief Parses host reservation modes.
|
||||||
|
///
|
||||||
|
/// @param network_data Data element holding shared network
|
||||||
|
/// configuration to be parsed.
|
||||||
|
/// @param [out] network Pointer to a network in which parsed data is
|
||||||
|
/// to be stored.
|
||||||
|
void parseHostReservationModes(const data::ConstElementPtr& network_data,
|
||||||
|
NetworkPtr& network);
|
||||||
|
|
||||||
/// @brief Parses parameters pertaining to DDNS behavior.
|
/// @brief Parses parameters pertaining to DDNS behavior.
|
||||||
///
|
///
|
||||||
/// The parsed parameters are:
|
/// The parsed parameters are:
|
||||||
|
@@ -859,7 +859,11 @@ Subnet4ConfigParser::initSubnet(data::ConstElementPtr params,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's set host reservation mode.
|
// reservation-modes
|
||||||
|
parseHostReservationModes(params, network);
|
||||||
|
|
||||||
|
// Let's set host reservation mode. If not specified, the default value of
|
||||||
|
// all will be used.
|
||||||
parseHostReservationMode(params, network);
|
parseHostReservationMode(params, network);
|
||||||
|
|
||||||
// Try setting up client class.
|
// Try setting up client class.
|
||||||
@@ -1330,6 +1334,9 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
|
|||||||
subnet6->setIface(iface);
|
subnet6->setIface(iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reservation-modes
|
||||||
|
parseHostReservationModes(params, network);
|
||||||
|
|
||||||
// Let's set host reservation mode. If not specified, the default value of
|
// Let's set host reservation mode. If not specified, the default value of
|
||||||
// all will be used.
|
// all will be used.
|
||||||
parseHostReservationMode(params, network);
|
parseHostReservationMode(params, network);
|
||||||
|
59
src/lib/dhcpsrv/parsers/reservation_modes_parser.cc
Normal file
59
src/lib/dhcpsrv/parsers/reservation_modes_parser.cc
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#include <cc/data.h>
|
||||||
|
#include <dhcpsrv/cfgmgr.h>
|
||||||
|
#include <dhcpsrv/dhcpsrv_log.h>
|
||||||
|
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
using namespace isc::data;
|
||||||
|
using namespace isc::util;
|
||||||
|
|
||||||
|
namespace isc {
|
||||||
|
namespace dhcp {
|
||||||
|
|
||||||
|
Network::HRMode
|
||||||
|
HostReservationModesParser::parse(const ConstElementPtr& control_elem) {
|
||||||
|
if (control_elem->getType() != Element::map) {
|
||||||
|
isc_throw(DhcpConfigError, "reservation-modes must be a map");
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstElementPtr elem;
|
||||||
|
uint8_t flags = 0;
|
||||||
|
|
||||||
|
elem = control_elem->get("global");
|
||||||
|
if (elem) {
|
||||||
|
bool value = elem->boolValue();
|
||||||
|
if (value) {
|
||||||
|
flags |= Network::HR_GLOBAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elem = control_elem->get("in-subnet");
|
||||||
|
if (elem) {
|
||||||
|
bool value = elem->boolValue();
|
||||||
|
if (value) {
|
||||||
|
flags |= Network::HR_IN_SUBNET;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
elem = control_elem->get("out-of-pool");
|
||||||
|
if (elem) {
|
||||||
|
bool value = elem->boolValue();
|
||||||
|
if (value) {
|
||||||
|
flags |= Network::HR_OUT_OF_POOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (static_cast<Network::HRMode>(flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end of namespace isc::dhcp
|
||||||
|
} // end of namespace isc
|
46
src/lib/dhcpsrv/parsers/reservation_modes_parser.h
Normal file
46
src/lib/dhcpsrv/parsers/reservation_modes_parser.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#ifndef RESERVATION_MODES_PARSER_H
|
||||||
|
#define RESERVATION_MODES_PARSER_H
|
||||||
|
|
||||||
|
#include <cc/data.h>
|
||||||
|
#include <cc/simple_parser.h>
|
||||||
|
#include <dhcpsrv/network.h>
|
||||||
|
#include <dhcpsrv/parsers/dhcp_parsers.h>
|
||||||
|
|
||||||
|
namespace isc {
|
||||||
|
namespace dhcp {
|
||||||
|
|
||||||
|
/// @brief Parser for the configuration of DHCP packet queue controls
|
||||||
|
///
|
||||||
|
/// This parser parses the "reservation-modes" parameter which holds the
|
||||||
|
/// the configurable parameters that tailor host reservation modes.
|
||||||
|
///
|
||||||
|
/// This parser is used in both DHCPv4 and DHCPv6, and also inside subnet and
|
||||||
|
/// shared networks.
|
||||||
|
class HostReservationModesParser : public isc::data::SimpleParser {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @brief Constructor
|
||||||
|
///
|
||||||
|
HostReservationModesParser(){};
|
||||||
|
|
||||||
|
/// @brief Parses content of the "reservation-modes".
|
||||||
|
///
|
||||||
|
/// @param control_elem MapElement containing the host reservation modes
|
||||||
|
/// values to parse
|
||||||
|
///
|
||||||
|
/// @return Host reservation modes flags.
|
||||||
|
///
|
||||||
|
/// @throw DhcpConfigError if any of the values are invalid.
|
||||||
|
Network::HRMode parse(const isc::data::ConstElementPtr& control_elem);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
} // end of namespace isc
|
||||||
|
|
||||||
|
#endif // RESERVATION_MODES_PARSER_H
|
@@ -185,6 +185,9 @@ SharedNetwork4Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reservation-modes
|
||||||
|
parseHostReservationModes(shared_network_data, network);
|
||||||
|
|
||||||
// reservation-mode
|
// reservation-mode
|
||||||
parseHostReservationMode(shared_network_data, network);
|
parseHostReservationMode(shared_network_data, network);
|
||||||
|
|
||||||
@@ -351,6 +354,9 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reservation-modes
|
||||||
|
parseHostReservationModes(shared_network_data, network);
|
||||||
|
|
||||||
// reservation-mode
|
// reservation-mode
|
||||||
parseHostReservationMode(shared_network_data, network);
|
parseHostReservationMode(shared_network_data, network);
|
||||||
|
|
||||||
|
@@ -87,6 +87,7 @@ libdhcpsrv_unittests_SOURCES += csv_lease_file6_unittest.cc
|
|||||||
libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
|
libdhcpsrv_unittests_SOURCES += d2_client_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
|
libdhcpsrv_unittests_SOURCES += d2_udp_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += dhcp_queue_control_parser_unittest.cc
|
libdhcpsrv_unittests_SOURCES += dhcp_queue_control_parser_unittest.cc
|
||||||
|
libdhcpsrv_unittests_SOURCES += reservation_modes_parser_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += dhcp4o6_ipc_unittest.cc
|
libdhcpsrv_unittests_SOURCES += dhcp4o6_ipc_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += duid_config_parser_unittest.cc
|
libdhcpsrv_unittests_SOURCES += duid_config_parser_unittest.cc
|
||||||
libdhcpsrv_unittests_SOURCES += expiration_config_parser_unittest.cc
|
libdhcpsrv_unittests_SOURCES += expiration_config_parser_unittest.cc
|
||||||
|
@@ -48,7 +48,7 @@ DHCPQueueControlParserTest::TearDown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verifies that DHCPQueueControlParser handles
|
// Verifies that DHCPQueueControlParser handles
|
||||||
// expected valid dhcp-queue-control contet
|
// expected valid dhcp-queue-control content
|
||||||
TEST_F(DHCPQueueControlParserTest, validContent) {
|
TEST_F(DHCPQueueControlParserTest, validContent) {
|
||||||
struct Scenario {
|
struct Scenario {
|
||||||
std::string description_;
|
std::string description_;
|
||||||
@@ -153,9 +153,8 @@ TEST_F(DHCPQueueControlParserTest, invalidContent) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Iterate over the valid scenarios and verify they succeed.
|
// Iterate over the invalid scenarios and verify they throw exception.
|
||||||
ConstElementPtr config_elems;
|
ConstElementPtr config_elems;
|
||||||
ConstElementPtr queue_control;
|
|
||||||
for (auto scenario : scenarios) {
|
for (auto scenario : scenarios) {
|
||||||
SCOPED_TRACE(scenario.description_);
|
SCOPED_TRACE(scenario.description_);
|
||||||
{
|
{
|
||||||
|
165
src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc
Normal file
165
src/lib/dhcpsrv/tests/reservation_modes_parser_unittest.cc
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
// Copyright (C) 2018-2020 Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <cc/data.h>
|
||||||
|
#include <dhcpsrv/cfgmgr.h>
|
||||||
|
#include <dhcpsrv/parsers/reservation_modes_parser.h>
|
||||||
|
#include <testutils/test_to_element.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
using namespace isc::data;
|
||||||
|
using namespace isc::dhcp;
|
||||||
|
using namespace isc::test;
|
||||||
|
using namespace isc::util;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
/// @brief Test fixture class for @c HostReservationModesParser
|
||||||
|
class HostReservationModesParserTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
|
||||||
|
/// @brief Setup for each test.
|
||||||
|
///
|
||||||
|
/// Clears the configuration in the @c CfgMgr.
|
||||||
|
virtual void SetUp();
|
||||||
|
|
||||||
|
/// @brief Cleans up after each test.
|
||||||
|
///
|
||||||
|
/// Clears the configuration in the @c CfgMgr.
|
||||||
|
virtual void TearDown();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
HostReservationModesParserTest::SetUp() {
|
||||||
|
CfgMgr::instance().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
HostReservationModesParserTest::TearDown() {
|
||||||
|
CfgMgr::instance().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that HostReservationModesParser handles
|
||||||
|
// expected valid reservation-modes content
|
||||||
|
TEST_F(HostReservationModesParserTest, validContent) {
|
||||||
|
struct Scenario {
|
||||||
|
std::string description_;
|
||||||
|
std::string json_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
"queue disabled",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": false \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"queue disabled, arbitrary content allowed",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": false, \n"
|
||||||
|
" \"foo\": \"bogus\", \n"
|
||||||
|
" \"random-int\" : 1234 \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"queue enabled, with queue-type",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": true, \n"
|
||||||
|
" \"queue-type\": \"some-type\" \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"queue enabled with queue-type and arbitrary content",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": true, \n"
|
||||||
|
" \"queue-type\": \"some-type\", \n"
|
||||||
|
" \"foo\": \"bogus\", \n"
|
||||||
|
" \"random-int\" : 1234 \n"
|
||||||
|
"} \n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterate over the valid scenarios and verify they succeed.
|
||||||
|
ConstElementPtr config_elems;
|
||||||
|
Network::HRMode reservation_modes;
|
||||||
|
for (auto scenario : scenarios) {
|
||||||
|
SCOPED_TRACE(scenario.description_);
|
||||||
|
{
|
||||||
|
// Construct the config JSON
|
||||||
|
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
|
||||||
|
<< "invalid JSON, test is broken";
|
||||||
|
|
||||||
|
// Parsing config into a reservation modes parser should succeed.
|
||||||
|
HostReservationModesParser parser;
|
||||||
|
try {
|
||||||
|
reservation_modes = parser.parse(config_elems);
|
||||||
|
} catch (const std::exception& ex) {
|
||||||
|
ADD_FAILURE() << "parser threw an exception: " << ex.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the resultant reservation-modes.
|
||||||
|
ASSERT_TRUE(reservation_modes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifies that HostReservationModesParser correctly catches
|
||||||
|
// invalid reservation-modes content
|
||||||
|
TEST_F(HostReservationModesParserTest, invalidContent) {
|
||||||
|
struct Scenario {
|
||||||
|
std::string description_;
|
||||||
|
std::string json_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Scenario> scenarios = {
|
||||||
|
{
|
||||||
|
"enable-queue missing",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-type\": \"some-type\" \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"enable-queue not boolean",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": \"always\" \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"queue enabled, type missing",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": true \n"
|
||||||
|
"} \n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"queue enabled, type not a string",
|
||||||
|
"{ \n"
|
||||||
|
" \"enable-queue\": true, \n"
|
||||||
|
" \"queue-type\": 7777 \n"
|
||||||
|
"} \n"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Iterate over the invalid scenarios and verify they throw exception.
|
||||||
|
ConstElementPtr config_elems;
|
||||||
|
for (auto scenario : scenarios) {
|
||||||
|
SCOPED_TRACE(scenario.description_);
|
||||||
|
{
|
||||||
|
// Construct the config JSON
|
||||||
|
ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
|
||||||
|
<< "invalid JSON, test is broken";
|
||||||
|
|
||||||
|
// Parsing config into a reservation modes parser should succeed.
|
||||||
|
HostReservationModesParser parser;
|
||||||
|
EXPECT_THROW(parser.parse(config_elems), DhcpConfigError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // anonymous namespace
|
Reference in New Issue
Block a user