Commit 08c3a4ae authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[3589] Moved subnet-specific option configuration to CfgOption class.

parent 7853fe17
......@@ -599,8 +599,7 @@ Dhcpv4Srv::appendRequestedOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
for (std::vector<uint8_t>::const_iterator opt = requested_opts.begin();
opt != requested_opts.end(); ++opt) {
if (!msg->getOption(*opt)) {
OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", *opt);
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp4", *opt);
if (desc.option && !msg->getOption(*opt)) {
msg->addOption(desc.option);
}
......@@ -650,8 +649,8 @@ Dhcpv4Srv::appendRequestedVendorOptions(const Pkt4Ptr& question, Pkt4Ptr& answer
for (std::vector<uint8_t>::const_iterator code = requested_opts.begin();
code != requested_opts.end(); ++code) {
if (!vendor_rsp->getOption(*code)) {
OptionDescriptor desc = subnet->getVendorOptionDescriptor(vendor_id,
*code);
OptionDescriptor desc = subnet->getCfgOption()->get(vendor_id,
*code);
if (desc.option) {
vendor_rsp->addOption(desc.option);
added = true;
......@@ -689,8 +688,8 @@ Dhcpv4Srv::appendBasicOptions(const Pkt4Ptr& question, Pkt4Ptr& msg) {
OptionPtr opt = msg->getOption(required_options[i]);
if (!opt) {
// Check whether option has been configured.
OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", required_options[i]);
OptionDescriptor desc = subnet->getCfgOption()->
get("dhcp4", required_options[i]);
if (desc.option) {
msg->addOption(desc.option);
}
......@@ -1949,8 +1948,8 @@ bool Dhcpv4Srv::classSpecificProcessing(const Pkt4Ptr& query, const Pkt4Ptr& rsp
// Now try to set up file field in DHCPv4 packet. We will just copy
// content of the boot-file option, which contains the same information.
OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", DHO_BOOT_FILE_NAME);
OptionDescriptor desc = subnet->getCfgOption()->
get("dhcp4", DHO_BOOT_FILE_NAME);
if (desc.option) {
boost::shared_ptr<OptionString> boot =
......
......@@ -16,6 +16,7 @@
#include <dhcp4/dhcp4_log.h>
#include <dhcp/libdhcp++.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcp4/json_config_parser.h>
#include <dhcpsrv/dbaccess_parser.h>
......@@ -97,7 +98,7 @@ protected:
} else {
// Check if this is a vendor-option. If it is, get vendor-specific
// definition.
uint32_t vendor_id = SubnetConfigParser::optionSpaceToVendorId(option_space);
uint32_t vendor_id = CfgOption::optionSpaceToVendorId(option_space);
if (vendor_id) {
def = LibDHCP::getVendorOptionDef(Option::V4, vendor_id, option_code);
}
......
......@@ -244,7 +244,7 @@ public:
<< "does not exist in Config Manager";
}
OptionContainerPtr options =
subnet->getOptionDescriptors("dhcp4");
subnet->getCfgOption()->getAll("dhcp4");
if (expected_options_count != options->size()) {
ADD_FAILURE() << "The number of options in the subnet '"
<< subnet_address.toText() << "' is different "
......@@ -1797,7 +1797,7 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -1884,16 +1884,16 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
classify_);
ASSERT_TRUE(subnet);
// Try to get the option from the space dhcp4.
OptionDescriptor desc1 = subnet->getOptionDescriptor("dhcp4", 56);
OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp4", 56);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(56, desc1.option->getType());
// Try to get the option from the space isc.
OptionDescriptor desc2 = subnet->getOptionDescriptor("isc", 56);
OptionDescriptor desc2 = subnet->getCfgOption()->get("isc", 56);
ASSERT_TRUE(desc2.option);
EXPECT_EQ(56, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc3 = subnet->getOptionDescriptor("non-existing", 56);
OptionDescriptor desc3 = subnet->getCfgOption()->get("non-existing", 56);
ASSERT_FALSE(desc3.option);
}
......@@ -2039,12 +2039,12 @@ TEST_F(Dhcp4ParserTest, optionDataEncapsulate) {
ASSERT_TRUE(subnet);
// We should have one option available.
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the option.
OptionDescriptor desc = subnet->getOptionDescriptor("dhcp4", 222);
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp4", 222);
EXPECT_TRUE(desc.option);
EXPECT_EQ(222, desc.option->getType());
......@@ -2104,7 +2104,7 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.24"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2255,7 +2255,7 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
Subnet4Ptr subnet1 = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.100"),
classify_);
ASSERT_TRUE(subnet1);
OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp4");
OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2280,7 +2280,7 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
Subnet4Ptr subnet2 = CfgMgr::instance().getSubnet4(IOAddress("192.0.3.102"),
classify_);
ASSERT_TRUE(subnet2);
OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp4");
OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(1, options2->size());
const OptionContainerTypeIndex& idx2 = options2->get<1>();
......@@ -2358,7 +2358,7 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2402,7 +2402,7 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options =
subnet->getOptionDescriptors("dhcp4");
subnet->getCfgOption()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
......@@ -2611,13 +2611,13 @@ TEST_F(Dhcp4ParserTest, stdOptionDataEncapsulate) {
ASSERT_TRUE(subnet);
// We should have one option available.
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the option.
OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
subnet->getCfgOption()->get("dhcp4", DHO_VENDOR_ENCAPSULATED_OPTIONS);
EXPECT_TRUE(desc.option);
EXPECT_EQ(DHO_VENDOR_ENCAPSULATED_OPTIONS, desc.option->getType());
......@@ -2695,17 +2695,17 @@ TEST_F(Dhcp4ParserTest, vendorOptionsHex) {
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(VENDOR_ID_CABLE_LABS, 100);
OptionDescriptor desc1 = subnet->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the option from the vendor space 1234
OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 100);
OptionDescriptor desc2 = subnet->getCfgOption()->get(1234, 100);
ASSERT_TRUE(desc2.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 100);
OptionDescriptor desc3 = subnet->getCfgOption()->get(5678, 100);
ASSERT_FALSE(desc3.option);
}
......@@ -2756,13 +2756,13 @@ TEST_F(Dhcp4ParserTest, vendorOptionsCsv) {
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(VENDOR_ID_CABLE_LABS, 100);
OptionDescriptor desc1 = subnet->getCfgOption()->get(VENDOR_ID_CABLE_LABS, 100);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(5678, 100);
OptionDescriptor desc2 = subnet->getCfgOption()->get(5678, 100);
ASSERT_FALSE(desc2.option);
}
......
......@@ -52,7 +52,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
// Add Router option.
Option4AddrLstPtr opt_routers(new Option4AddrLst(DHO_ROUTERS));
opt_routers->setAddress(IOAddress("192.0.2.2"));
subnet_->addOption(opt_routers, false, "dhcp4");
subnet_->getCfgOption()->add(opt_routers, false, "dhcp4");
}
Dhcpv4SrvTest::~Dhcpv4SrvTest() {
......@@ -86,24 +86,24 @@ void Dhcpv4SrvTest::configureRequestedOptions() {
option_dns_servers(new Option4AddrLst(DHO_DOMAIN_NAME_SERVERS));
option_dns_servers->addAddress(IOAddress("192.0.2.1"));
option_dns_servers->addAddress(IOAddress("192.0.2.100"));
ASSERT_NO_THROW(subnet_->addOption(option_dns_servers, false, "dhcp4"));
ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_dns_servers, false, "dhcp4"));
// domain-name
OptionDefinition def("domain-name", DHO_DOMAIN_NAME, OPT_FQDN_TYPE);
OptionCustomPtr option_domain_name(new OptionCustom(def, Option::V4));
option_domain_name->writeFqdn("example.com");
subnet_->addOption(option_domain_name, false, "dhcp4");
subnet_->getCfgOption()->add(option_domain_name, false, "dhcp4");
// log-servers
Option4AddrLstPtr option_log_servers(new Option4AddrLst(DHO_LOG_SERVERS));
option_log_servers->addAddress(IOAddress("192.0.2.2"));
option_log_servers->addAddress(IOAddress("192.0.2.10"));
ASSERT_NO_THROW(subnet_->addOption(option_log_servers, false, "dhcp4"));
ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_log_servers, false, "dhcp4"));
// cookie-servers
Option4AddrLstPtr option_cookie_servers(new Option4AddrLst(DHO_COOKIE_SERVERS));
option_cookie_servers->addAddress(IOAddress("192.0.2.1"));
ASSERT_NO_THROW(subnet_->addOption(option_cookie_servers, false, "dhcp4"));
ASSERT_NO_THROW(subnet_->getCfgOption()->add(option_cookie_servers, false, "dhcp4"));
}
void Dhcpv4SrvTest::messageCheck(const Pkt4Ptr& q, const Pkt4Ptr& a) {
......
......@@ -731,7 +731,7 @@ Dhcpv6Srv::appendRequestedOptions(const Pkt6Ptr& question, Pkt6Ptr& answer) {
// Get the list of options that client requested.
const std::vector<uint16_t>& requested_opts = option_oro->getValues();
BOOST_FOREACH(uint16_t opt, requested_opts) {
OptionDescriptor desc = subnet->getOptionDescriptor("dhcp6", opt);
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", opt);
if (desc.option) {
answer->addOption(desc.option);
}
......@@ -777,7 +777,7 @@ Dhcpv6Srv::appendRequestedVendorOptions(const Pkt6Ptr& question, Pkt6Ptr& answer
bool added = false;
const std::vector<uint16_t>& requested_opts = oro->getValues();
BOOST_FOREACH(uint16_t opt, requested_opts) {
OptionDescriptor desc = subnet->getVendorOptionDescriptor(vendor_id, opt);
OptionDescriptor desc = subnet->getCfgOption()->get(vendor_id, opt);
if (desc.option) {
vendor_rsp->addOption(desc.option);
added = true;
......
......@@ -19,6 +19,7 @@
#include <dhcp6/json_config_parser.h>
#include <dhcp6/dhcp6_log.h>
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/cfg_option.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dbaccess_parser.h>
#include <dhcpsrv/dhcp_config_parser.h>
......@@ -112,7 +113,7 @@ protected:
} else {
// Check if this is a vendor-option. If it is, get vendor-specific
// definition.
uint32_t vendor_id = SubnetConfigParser::optionSpaceToVendorId(option_space);
uint32_t vendor_id = CfgOption::optionSpaceToVendorId(option_space);
if (vendor_id) {
def = LibDHCP::getVendorOptionDef(Option::V6, vendor_id, option_code);
}
......
......@@ -256,7 +256,7 @@ public:
<< "does not exist in Config Manager";
}
OptionContainerPtr options =
subnet->getOptionDescriptors("dhcp6");
subnet->getCfgOption()->getAll("dhcp6");
if (expected_options_count != options->size()) {
ADD_FAILURE() << "The number of options in the subnet '"
<< subnet_address.toText() << "' is different "
......@@ -2030,7 +2030,7 @@ TEST_F(Dhcp6ParserTest, optionDataDefaults) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2126,16 +2126,16 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
classify_);
ASSERT_TRUE(subnet);
// Try to get the option from the space dhcp6.
OptionDescriptor desc1 = subnet->getOptionDescriptor("dhcp6", 38);
OptionDescriptor desc1 = subnet->getCfgOption()->get("dhcp6", 38);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(38, desc1.option->getType());
// Try to get the option from the space isc.
OptionDescriptor desc2 = subnet->getOptionDescriptor("isc", 38);
OptionDescriptor desc2 = subnet->getCfgOption()->get("isc", 38);
ASSERT_TRUE(desc2.option);
EXPECT_EQ(38, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc3 = subnet->getOptionDescriptor("non-existing", 38);
OptionDescriptor desc3 = subnet->getCfgOption()->get("non-existing", 38);
ASSERT_FALSE(desc3.option);
}
......@@ -2283,12 +2283,12 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
ASSERT_TRUE(subnet);
// We should have one option available.
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the option.
OptionDescriptor desc = subnet->getOptionDescriptor("dhcp6", 100);
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", 100);
EXPECT_TRUE(desc.option);
EXPECT_EQ(100, desc.option->getType());
......@@ -2344,7 +2344,7 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
Subnet6Ptr subnet1 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
ASSERT_TRUE(subnet1);
OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp6");
OptionContainerPtr options1 = subnet1->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2370,7 +2370,7 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
Subnet6Ptr subnet2 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:2::4"),
classify_);
ASSERT_TRUE(subnet2);
OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp6");
OptionContainerPtr options2 = subnet2->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options2->size());
const OptionContainerTypeIndex& idx2 = options2->get<1>();
......@@ -2541,7 +2541,7 @@ TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2584,7 +2584,7 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"),
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
......@@ -2664,17 +2664,17 @@ TEST_F(Dhcp6ParserTest, vendorOptionsHex) {
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 100);
OptionDescriptor desc1 = subnet->getCfgOption()->get(4491, 100);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the option from the vendor space 1234
OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(1234, 100);
OptionDescriptor desc2 = subnet->getCfgOption()->get(1234, 100);
ASSERT_TRUE(desc2.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc3 = subnet->getVendorOptionDescriptor(5678, 38);
OptionDescriptor desc3 = subnet->getCfgOption()->get(5678, 38);
ASSERT_FALSE(desc3.option);
}
......@@ -2726,13 +2726,13 @@ TEST_F(Dhcp6ParserTest, vendorOptionsCsv) {
ASSERT_TRUE(subnet);
// Try to get the option from the vendor space 4491
OptionDescriptor desc1 = subnet->getVendorOptionDescriptor(4491, 100);
OptionDescriptor desc1 = subnet->getCfgOption()->get(4491, 100);
ASSERT_TRUE(desc1.option);
EXPECT_EQ(100, desc1.option->getType());
// Try to get the non-existing option from the non-existing
// option space and expect that option is not returned.
OptionDescriptor desc2 = subnet->getVendorOptionDescriptor(5678, 100);
OptionDescriptor desc2 = subnet->getCfgOption()->get(5678, 100);
ASSERT_FALSE(desc2.option);
}
......@@ -2865,13 +2865,12 @@ TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
ASSERT_TRUE(subnet);
// We should have one option available.
OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the option.
OptionDescriptor desc =
subnet->getOptionDescriptor("dhcp6", D6O_VENDOR_OPTS);
OptionDescriptor desc = subnet->getCfgOption()->get("dhcp6", D6O_VENDOR_OPTS);
EXPECT_TRUE(desc.option);
EXPECT_EQ(D6O_VENDOR_OPTS, desc.option->getType());
......
......@@ -18,49 +18,6 @@
#include <limits>
#include <string>
namespace {
uint32_t
optionSpaceToVendorId(const std::string& option_space) {
if (option_space.size() < 8) {
// 8 is a minimal length of "vendor-X" format
return (0);
}
if (option_space.substr(0,7) != "vendor-") {
return (0);
}
// text after "vendor-", supposedly numbers only
std::string x = option_space.substr(7);
int64_t check;
try {
check = boost::lexical_cast<int64_t>(x);
} catch (const boost::bad_lexical_cast &) {
/// @todo: Should we throw here?
// isc_throw(BadValue, "Failed to parse vendor-X value (" << x
// << ") as unsigned 32-bit integer.");
return (0);
}
if (check > std::numeric_limits<uint32_t>::max()) {
/// @todo: Should we throw here?
//isc_throw(BadValue, "Value " << x << "is too large"
// << " for unsigned 32-bit integer.");
return (0);
}
if (check < 0) {
/// @todo: Should we throw here?
// isc_throw(BadValue, "Value " << x << "is negative."
// << " Only 0 or larger are allowed for unsigned 32-bit integer.");
return (0);
}
// value is small enough to fit
return (static_cast<uint32_t>(check));
}
}
namespace isc {
namespace dhcp {
......@@ -160,5 +117,45 @@ CfgOption::getAll(const uint32_t vendor_id) const {
return (vendor_options_.getItems(vendor_id));
}
uint32_t
CfgOption::optionSpaceToVendorId(const std::string& option_space) {
if (option_space.size() < 8) {
// 8 is a minimal length of "vendor-X" format
return (0);
}
if (option_space.substr(0,7) != "vendor-") {
return (0);
}
// text after "vendor-", supposedly numbers only
std::string x = option_space.substr(7);
int64_t check;
try {
check = boost::lexical_cast<int64_t>(x);
} catch (const boost::bad_lexical_cast &) {
/// @todo: Should we throw here?
// isc_throw(BadValue, "Failed to parse vendor-X value (" << x
// << ") as unsigned 32-bit integer.");
return (0);
}
if (check > std::numeric_limits<uint32_t>::max()) {
/// @todo: Should we throw here?
//isc_throw(BadValue, "Value " << x << "is too large"
// << " for unsigned 32-bit integer.");
return (0);
}
if (check < 0) {
/// @todo: Should we throw here?
// isc_throw(BadValue, "Value " << x << "is negative."
// << " Only 0 or larger are allowed for unsigned 32-bit integer.");
return (0);
}
// value is small enough to fit
return (static_cast<uint32_t>(check));
}
} // end of namespace isc::dhcp
} // end of namespace isc
......@@ -317,6 +317,19 @@ public:
return (*range.first);
}
/// @brief Converts option space name to vendor id.
///
/// If the option space name is specified in the following format:
/// "vendor-X" where X is an uint32_t number, it is assumed to be
/// a vendor space and the uint32_t number is returned by this function.
///
/// @todo remove this function once when the conversion is dealt by the
/// appropriate functions returning options by option space names.
///
/// @param option_space Option space name.
/// @return vendor id.
static uint32_t optionSpaceToVendorId(const std::string& option_space);
private:
/// @brief Merges data from two option containers.
......
......@@ -1163,23 +1163,15 @@ SubnetConfigParser::createSubnet() {
// option code has been already added. If so, we want
// to issue a warning.
OptionDescriptor existing_desc =
subnet_->getOptionDescriptor("option_space",
desc.option->getType());
subnet_->getCfgOption()->get("option_space", desc.option->getType());
if (existing_desc.option) {
duplicate_option_warning(desc.option->getType(), addr);
}
// Add sub-options (if any).
appendSubOptions(option_space, desc.option);
// Check if the option space defines a vendor-option
uint32_t vendor_id = optionSpaceToVendorId(option_space);
if (vendor_id) {
// This is a vendor option
subnet_->addVendorOption(desc.option, false, vendor_id);
} else {
// This is a normal option
subnet_->addOption(desc.option, false, option_space);
}
subnet_->getCfgOption()->add(desc.option, false, option_space);
}
}
......@@ -1202,65 +1194,18 @@ SubnetConfigParser::createSubnet() {
// subnet scope take precedence over globally configured
// values we don't add option from the global storage
// if there is one already.
OptionDescriptor existing_desc =
subnet_->getOptionDescriptor(option_space,
desc.option->getType());
OptionDescriptor existing_desc = subnet_->getCfgOption()->
get(option_space, desc.option->getType());
if (!existing_desc.option) {
// Add sub-options (if any).
appendSubOptions(option_space, desc.option);
uint32_t vendor_id = optionSpaceToVendorId(option_space);
if (vendor_id) {
// This is a vendor option
subnet_->addVendorOption(desc.option, false, vendor_id);
} else {
// This is a normal option
subnet_->addOption(desc.option, false, option_space);
}
subnet_->getCfgOption()->add(desc.option, false, option_space);
}
}
}
}
uint32_t
SubnetConfigParser::optionSpaceToVendorId(const std::string& option_space) {
if (option_space.size() < 8) {
// 8 is a minimal length of "vendor-X" format
return (0);
}
if (option_space.substr(0,7) != "vendor-") {