///
/// @param addr is IPv4 address of the subnet.
/// @param len is the prefix length
- void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
+ void initSubnet(isc::data::ConstElementPtr params,
+ isc::asiolink::IOAddress addr, uint8_t len) {
// The renew-timer and rebind-timer are optional. If not set, the
// option 58 and 59 will not be sent to a client. In this case the
// client will use default values based on the valid-lifetime.
// particular subnet. If not, the global value should be present.
// If there is no global value, exception is thrown.
Triplet<uint32_t> valid = getParam("valid-lifetime");
+
// Subnet ID is optional. If it is not supplied the value of 0 is used,
- // which means autogenerate.
- SubnetID subnet_id =
- static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
+ // which means autogenerate. The value was inserted earlier by calling
+ // SimpleParser4::setAllDefaults.
+ SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
stringstream s;
s << addr << "/" << static_cast<int>(len) << " with params: ";
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 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
{ "next-server", Element::string, "0.0.0.0" }
};
+/// @brief This table defines default values for each IPv4 subnet.
+const SimpleDefaults SimpleParser4::SUBNET4_DEFAULTS = {
+ { "id", Element::integer, "0" } // 0 means autogenerate
+};
+
/// @brief List of parameters that can be inherited from the global to subnet4 scope.
///
/// Some parameters may be defined on both global (directly in Dhcp4) and
}
}
- // Finally, set the defaults for option data
+ // Set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
- BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
- cnt += SimpleParser::setDefaults(single_option, OPTION4_DEFAULTS);
- }
+ cnt += setListDefaults(options, OPTION4_DEFAULTS);
+ }
+
+ // Now set the defaults for defined subnets
+ ConstElementPtr subnets = global->get("subnet4");
+ if (subnets) {
+ cnt += setListDefaults(subnets, SUBNET4_DEFAULTS);
}
+
return (cnt);
}
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 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
static const isc::data::SimpleDefaults OPTION4_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
+ static const isc::data::SimpleDefaults SUBNET4_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
};
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
+
+ /// @brief Checks if specified map has a string parameter with expected value
+ ///
+ /// @param map map to be checked
+ /// @param param_name name of the parameter to be checked
+ /// @param exp_value expected value of the parameter.
+ void checkStringValue(const ConstElementPtr& map, const std::string& param_name,
+ std::string exp_value) {
+
+ // First check if the passed element is a map.
+ ASSERT_EQ(Element::map, map->getType());
+
+ // Now try to get the element being checked
+ ConstElementPtr elem = map->get(param_name);
+ ASSERT_TRUE(elem);
+
+ // Now check if it's indeed integer
+ ASSERT_EQ(Element::string, elem->getType());
+
+ // Finally, check if its value meets expectation.
+ EXPECT_EQ(exp_value, elem->stringValue());
+ }
+
+ /// @brief Checks if specified map has a boolean parameter with expected value
+ ///
+ /// @param map map to be checked
+ /// @param param_name name of the parameter to be checked
+ /// @param exp_value expected value of the parameter.
+ void checkBoolValue(const ConstElementPtr& map, const std::string& param_name,
+ bool exp_value) {
+
+ // First check if the passed element is a map.
+ ASSERT_EQ(Element::map, map->getType());
+
+ // Now try to get the element being checked
+ ConstElementPtr elem = map->get(param_name);
+ ASSERT_TRUE(elem);
+
+ // Now check if it's indeed integer
+ ASSERT_EQ(Element::boolean, elem->getType());
+
+ // Finally, check if its value meets expectation.
+ EXPECT_EQ(exp_value, elem->boolValue());
+ }
};
// This test checks if global defaults are properly set for DHCPv4.
TEST_F(SimpleParser4Test, inheritGlobalToSubnet4) {
ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
" \"rebind-timer\": 2,"
- " \"preferred-lifetime\": 3,"
" \"valid-lifetime\": 4,"
" \"subnet4\": [ { \"renew-timer\": 100 } ] "
"}");
checkIntegerValue(subnet, "valid-lifetime", 4);
}
+// This test checks if the parameters in "subnet4" are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser4Test, subnetDefaults4) {
+ ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
+ " \"rebind-timer\": 2,"
+ " \"valid-lifetime\": 4,"
+ " \"subnet4\": [ { } ] "
+ "}");
+
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr subnets = global->find("subnet4");
+ ASSERT_TRUE(subnets);
+ ConstElementPtr subnet = subnets->get(0);
+ ASSERT_TRUE(subnet);
+
+ // we should have "id" parameter with the default value of 0 added for us.
+ checkIntegerValue(subnet, "id", 0);
+}
+
+// This test checks if the parameters in option-data are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser4Test, optionDataDefaults4) {
+ ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
+ " \"rebind-timer\": 2,"
+ " \"valid-lifetime\": 4,"
+ " \"option-data\": [ { } ] "
+ "}");
+
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr options = global->find("option-data");
+ ASSERT_TRUE(options);
+ ConstElementPtr option = options->get(0);
+ ASSERT_TRUE(option);
+
+ // we should have appropriate default value set. See
+ // SimpleParser4::OPTION4_DEFAULTS for a list of default values.
+ checkStringValue(option, "space", "dhcp4");
+ checkStringValue(option, "encapsulate", "");
+ checkBoolValue(option, "csv-format", true);
+}
+
+// This test checks if the parameters in option-data are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser4Test, optionDefDefaults4) {
+ ElementPtr global = parseJSON("{ "
+ " \"option-def\": [ { } ] "
+ "}");
+
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr defs = global->find("option-def");
+ ASSERT_TRUE(defs);
+ ASSERT_EQ(1, defs->size());
+ ConstElementPtr def = defs->get(0);
+ ASSERT_TRUE(def);
+
+ // we should have appropriate default value set. See
+ // SimpleParser4::OPTION4_DEFAULTS for a list of default values.
+ checkStringValue(def, "record-types", "");
+ checkStringValue(def, "space", "dhcp4");
+ checkStringValue(def, "encapsulate", "");
+ checkBoolValue(def, "array", false);
+}
};
};
///
/// @param addr is IPv6 prefix of the subnet.
/// @param len is the prefix length
- void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) {
+ void initSubnet(isc::data::ConstElementPtr params,
+ isc::asiolink::IOAddress addr, uint8_t len) {
// Get all 'time' parameters using inheritance.
// If the subnet-specific value is defined then use it, else
// use the global value. The global value must always be
Triplet<uint32_t> t2 = getParam("rebind-timer");
Triplet<uint32_t> pref = getParam("preferred-lifetime");
Triplet<uint32_t> valid = getParam("valid-lifetime");
+
// Subnet ID is optional. If it is not supplied the value of 0 is used,
- // which means autogenerate.
- SubnetID subnet_id =
- static_cast<SubnetID>(uint32_values_->getOptionalParam("id", 0));
+ // which means autogenerate. The value was inserted earlier by calling
+ // SimpleParser6::setAllDefaults.
+ SubnetID subnet_id = static_cast<SubnetID>(getInteger(params, "id"));
// Get interface-id option content. For now we support string
// representation only
}
// Gather boolean parameters values.
- bool rapid_commit = boolean_values_->getOptionalParam("rapid-commit", false);
+ bool rapid_commit = getBoolean(params, "rapid-commit");
std::ostringstream output;
output << addr << "/" << static_cast<int>(len)
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 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
{ "dhcp4o6-port", Element::integer, "0" }
};
+/// @brief This table defines default values for each IPv6 subnet.
+const SimpleDefaults SimpleParser6::SUBNET6_DEFAULTS = {
+ { "id", Element::integer, "0" }, // 0 means autogenerate
+ { "rapid-commit", Element::boolean, "false" } // rapid-commit disabled by default
+};
+
/// @brief List of parameters that can be inherited from the global to subnet6 scope.
///
/// Some parameters may be defined on both global (directly in Dhcp6) and
}
}
- // Finally, set the defaults for option data
+ // Set the defaults for option data
ConstElementPtr options = global->get("option-data");
if (options) {
BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
}
}
+ // Now set the defaults for defined subnets
+ // Now set the defaults for defined subnets
+ ConstElementPtr subnets = global->get("subnet6");
+ if (subnets) {
+ cnt += setListDefaults(subnets, SUBNET6_DEFAULTS);
+ }
+
return (cnt);
}
-// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2017 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
static const isc::data::SimpleDefaults OPTION6_DEF_DEFAULTS;
static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
+ static const isc::data::SimpleDefaults SUBNET6_DEFAULTS;
static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
};
// Finally, check if its value meets expectation.
EXPECT_EQ(exp_value, elem->intValue());
}
+
+ /// @brief Checks if specified map has a string parameter with expected value
+ ///
+ /// @param map map to be checked
+ /// @param param_name name of the parameter to be checked
+ /// @param exp_value expected value of the parameter.
+ void checkStringValue(const ConstElementPtr& map, const std::string& param_name,
+ std::string exp_value) {
+
+ // First check if the passed element is a map.
+ ASSERT_EQ(Element::map, map->getType());
+
+ // Now try to get the element being checked
+ ConstElementPtr elem = map->get(param_name);
+ ASSERT_TRUE(elem);
+
+ // Now check if it's indeed integer
+ ASSERT_EQ(Element::string, elem->getType());
+
+ // Finally, check if its value meets expectation.
+ EXPECT_EQ(exp_value, elem->stringValue());
+ }
+
+ /// @brief Checks if specified map has a boolean parameter with expected value
+ ///
+ /// @param map map to be checked
+ /// @param param_name name of the parameter to be checked
+ /// @param exp_value expected value of the parameter.
+ void checkBoolValue(const ConstElementPtr& map, const std::string& param_name,
+ bool exp_value) {
+
+ // First check if the passed element is a map.
+ ASSERT_EQ(Element::map, map->getType());
+
+ // Now try to get the element being checked
+ ConstElementPtr elem = map->get(param_name);
+ ASSERT_TRUE(elem);
+
+ // Now check if it's indeed integer
+ ASSERT_EQ(Element::boolean, elem->getType());
+
+ // Finally, check if its value meets expectation.
+ EXPECT_EQ(exp_value, elem->boolValue());
+ }
+
};
// This test checks if global defaults are properly set for DHCPv6.
checkIntegerValue(subnet, "valid-lifetime", 4);
}
-};
+// This test checks if the parameters in "subnet6" are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser6Test, subnetDefaults6) {
+ ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
+ " \"rebind-timer\": 2,"
+ " \"preferred-lifetime\": 3,"
+ " \"valid-lifetime\": 4,"
+ " \"subnet6\": [ { } ] "
+ "}");
+
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr subnets = global->find("subnet6");
+ ASSERT_TRUE(subnets);
+ ConstElementPtr subnet = subnets->get(0);
+ ASSERT_TRUE(subnet);
+
+ // we should have "id" parameter with the default value of 0 added for us.
+ checkIntegerValue(subnet, "id", 0);
+}
+
+// This test checks if the parameters in option-data are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser6Test, optionDataDefaults4) {
+ ElementPtr global = parseJSON("{ \"renew-timer\": 1,"
+ " \"rebind-timer\": 2,"
+ " \"preferred-lifetime\": 3,"
+ " \"valid-lifetime\": 4,"
+ " \"option-data\": [ { } ] "
+ "}");
+
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr options = global->find("option-data");
+ ASSERT_TRUE(options);
+ ConstElementPtr option = options->get(0);
+ ASSERT_TRUE(option);
+
+ // we should have appropriate default value set. See
+ // SimpleParser4::OPTION4_DEFAULTS for a list of default values.
+ checkStringValue(option, "space", "dhcp6");
+ checkStringValue(option, "encapsulate", "");
+ checkBoolValue(option, "csv-format", true);
+}
+
+// This test checks if the parameters in option-data are assigned default values
+// if not explicitly specified.
+TEST_F(SimpleParser6Test, optionDefDefaults6) {
+ ElementPtr global = parseJSON("{ "
+ " \"option-def\": [ { } ] "
+ "}");
+ size_t num = 0;
+ EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(global));
+ EXPECT_LE(1, num); // at least 1 parameter has to be modified
+
+ ConstElementPtr defs = global->find("option-def");
+ ASSERT_TRUE(defs);
+ ASSERT_EQ(1, defs->size());
+ ConstElementPtr def = defs->get(0);
+ ASSERT_TRUE(def);
+
+ // we should have appropriate default value set. See
+ // SimpleParser4::OPTION4_DEFAULTS for a list of default values.
+ checkStringValue(def, "record-types", "");
+ checkStringValue(def, "space", "dhcp6");
+ checkStringValue(def, "encapsulate", "");
+ checkBoolValue(def, "array", false);
+}
+
+
+};
// Create a subnet.
try {
- createSubnet();
+ createSubnet(subnet);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError,
"subnet configuration failed (" << subnet->getPosition()
}
void
-SubnetConfigParser::createSubnet() {
+SubnetConfigParser::createSubnet(ConstElementPtr params) {
std::string subnet_txt;
try {
- subnet_txt = string_values_->getParam("subnet");
+ subnet_txt = getString(params, "subnet");
} catch (const DhcpConfigError &) {
// rethrow with precise error
isc_throw(DhcpConfigError,
uint8_t len = boost::lexical_cast<unsigned int>(subnet_txt.substr(pos + 1));
// Call the subclass's method to instantiate the subnet
- initSubnet(addr, len);
+ initSubnet(params, addr, len);
// Add pools to it.
for (PoolStorage::iterator it = pools_->begin(); it != pools_->end();
// iface not mandatory so swallow the exception
}
-
// Let's set host reservation mode. If not specified, the default value of
// all will be used.
std::string hr_mode;
/// @brief Instantiates the subnet based on a given IP prefix and prefix
/// length.
///
+ /// @param params configuration parameters for that subnet
/// @param addr is the IP prefix of the subnet.
/// @param len is the prefix length
- virtual void initSubnet(isc::asiolink::IOAddress addr, uint8_t len) = 0;
+ virtual void initSubnet(isc::data::ConstElementPtr params,
+ isc::asiolink::IOAddress addr, uint8_t len) = 0;
/// @brief Returns value for a given parameter (after using inheritance)
///
/// @brief Create a new subnet using a data from child parsers.
///
+ /// @param data Element map that describes the subnet
/// @throw isc::dhcp::DhcpConfigError if subnet configuration parsing
/// failed.
- void createSubnet();
+ void createSubnet(isc::data::ConstElementPtr data);
protected: