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);
}
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;
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);
}
// 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 =
#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>
} 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);
}
<< "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 "
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.
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);
}
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());
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.
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.
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>();
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.
classify_);
ASSERT_TRUE(subnet);
OptionContainerPtr options =
- subnet->getOptionDescriptors("dhcp4");
+ subnet->getCfgOption()->getAll("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
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());
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);
}
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);
}
// 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() {
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) {
// 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);
}
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;
#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>
} 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);
}
<< "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 "
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.
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);
}
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());
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.
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>();
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.
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.
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);
}
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);
}
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());
#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 {
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
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.
// 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);
}
}
// 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-") {
- return (0);
- }
-
- // text after "vendor-", supposedly numbers only
- 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));
-}
-
isc::dhcp::Triplet<uint32_t>
SubnetConfigParser::getParam(const std::string& name) {
uint32_t value = 0;
t1_(t1), t2_(t2), valid_(valid_lifetime),
last_allocated_ia_(lastAddrInPrefix(prefix, len)),
last_allocated_ta_(lastAddrInPrefix(prefix, len)),
- last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay)
+ last_allocated_pd_(lastAddrInPrefix(prefix, len)), relay_(relay),
+ cfg_option_(new CfgOption())
+
{
if ((prefix.isV6() && len > 128) ||
(prefix.isV4() && len > 32)) {
return ((first <= addr) && (addr <= last));
}
-void
-Subnet::addOption(const OptionPtr& option, bool persistent,
- const std::string& option_space) {
- // Check that the option space name is valid.
- if (!OptionSpace::validateName(option_space)) {
- isc_throw(isc::BadValue, "invalid option space name: '"
- << option_space << "'");
- }
- validateOption(option);
-
- // Actually add new option descriptor.
- option_spaces_.addItem(OptionDescriptor(option, persistent), option_space);
-}
-
void
Subnet::setRelayInfo(const isc::dhcp::Subnet::RelayInfo& relay) {
relay_ = relay;
white_list_.insert(class_name);
}
-void
-Subnet::delOptions() {
- option_spaces_.clearItems();
-}
-
-OptionContainerPtr
-Subnet::getOptionDescriptors(const std::string& option_space) const {
- return (option_spaces_.getItems(option_space));
-}
-
-OptionDescriptor
-Subnet::getOptionDescriptor(const std::string& option_space,
- const uint16_t option_code) {
- OptionContainerPtr options = getOptionDescriptors(option_space);
- if (!options || options->empty()) {
- return (OptionDescriptor(false));
- }
- const OptionContainerTypeIndex& idx = options->get<1>();
- const OptionContainerTypeRange& range = idx.equal_range(option_code);
- if (std::distance(range.first, range.second) == 0) {
- return (OptionDescriptor(false));
- }
-
- return (*range.first);
-}
-
-void Subnet::addVendorOption(const OptionPtr& option, bool persistent,
- uint32_t vendor_id){
-
- validateOption(option);
-
- vendor_option_spaces_.addItem(OptionDescriptor(option, persistent), vendor_id);
-}
-
-OptionContainerPtr
-Subnet::getVendorOptionDescriptors(uint32_t vendor_id) const {
- return (vendor_option_spaces_.getItems(vendor_id));
-}
-
-OptionDescriptor
-Subnet::getVendorOptionDescriptor(uint32_t vendor_id, uint16_t option_code) {
- OptionContainerPtr options = getVendorOptionDescriptors(vendor_id);
- if (!options || options->empty()) {
- return (OptionDescriptor(false));
- }
- const OptionContainerTypeIndex& idx = options->get<1>();
- const OptionContainerTypeRange& range = idx.equal_range(option_code);
- if (std::distance(range.first, range.second) == 0) {
- return (OptionDescriptor(false));
- }
-
- return (*range.first);
-}
-
-void Subnet::delVendorOptions() {
- vendor_option_spaces_.clearItems();
-}
-
isc::asiolink::IOAddress Subnet::getLastAllocated(Lease::Type type) const {
// check if the type is valid (and throw if it isn't)
checkType(type);
return (iface_);
}
-void
-Subnet4::validateOption(const OptionPtr& option) const {
- if (!option) {
- isc_throw(isc::BadValue,
- "option configured for subnet must not be NULL");
- } else if (option->getUniverse() != Option::V4) {
- isc_throw(isc::BadValue,
- "expected V4 option to be added to the subnet");
- }
-}
-
bool
Subnet::inPool(Lease::Type type, const isc::asiolink::IOAddress& addr) const {
}
}
-void
-Subnet6::validateOption(const OptionPtr& option) const {
- if (!option) {
- isc_throw(isc::BadValue,
- "option configured for subnet must not be NULL");
- } else if (option->getUniverse() != Option::V6) {
- isc_throw(isc::BadValue,
- "expected V6 option to be added to the subnet");
- }
-}
-
} // end of isc::dhcp namespace
} // end of isc namespace
/// @brief checks if specified address is in range
bool inRange(const isc::asiolink::IOAddress& addr) const;
- /// @brief Add new option instance to the collection.
- ///
- /// @param option option instance.
- /// @param persistent if true, send an option regardless if client
- /// requested it or not.
- /// @param option_space name of the option space to add an option to.
- ///
- /// @throw isc::BadValue if invalid option provided.
- void addOption(const OptionPtr& option, bool persistent,
- const std::string& option_space);
-
-
- /// @brief Adds new vendor option instance to the collection.
- ///
- /// @param option option instance.
- /// @param persistent if true, send an option regardless if client
- /// requested it or not.
- /// @param vendor_id enterprise id of the vendor space to add an option to.
- void addVendorOption(const OptionPtr& option, bool persistent,
- uint32_t vendor_id);
-
- /// @brief Delete all options configured for the subnet.
- void delOptions();
-
- /// @brief Deletes all vendor options configured for the subnet.
- void delVendorOptions();
-
/// @brief checks if the specified address is in pools
///
/// Note the difference between inSubnet() and inPool(). For a given
return (t2_);
}
- /// @brief Return a collection of option descriptors.
- ///
- /// @param option_space name of the option space.
- ///
- /// @return pointer to collection of options configured for a subnet.
- OptionContainerPtr
- getOptionDescriptors(const std::string& option_space) const;
-
- /// @brief Return a collection of vendor option descriptors.
- ///
- /// @param vendor_id enterprise id of the option space.
- ///
- /// @return pointer to collection of options configured for a subnet.
- OptionContainerPtr
- getVendorOptionDescriptors(uint32_t vendor_id) const;
-
- /// @brief Return single option descriptor.
- ///
- /// @param option_space name of the option space.
- /// @param option_code code of the option to be returned.
- ///
- /// @return option descriptor found for the specified option space
- /// and option code.
- OptionDescriptor
- getOptionDescriptor(const std::string& option_space,
- const uint16_t option_code);
-
- /// @brief Return single vendor option descriptor.
- ///
- /// @param vendor_id enterprise id of the option space.
- /// @param option_code code of the option to be returned.
- ///
- /// @return option descriptor found for the specified option space
- /// and option code.
- OptionDescriptor
- getVendorOptionDescriptor(uint32_t vendor_id, uint16_t option_code);
+ /// @brief Returns pointer to the option data configuration for this subnet.
+ CfgOptionPtr getCfgOption() {
+ return (cfg_option_);
+ }
/// @brief returns the last address that was tried from this pool
///
/// @throw BadValue if invalid value is used
virtual void checkType(Lease::Type type) const = 0;
- /// @brief Check if option is valid and can be added to a subnet.
- ///
- /// @param option option to be validated.
- virtual void validateOption(const OptionPtr& option) const = 0;
-
/// @brief subnet-id
///
/// Subnet-id is a unique value that can be used to find or identify
private:
- /// A collection of option spaces grouping option descriptors.
- typedef OptionSpaceContainer<OptionContainer,
- OptionDescriptor, std::string> OptionSpaceCollection;
-
- /// A collection of vendor space option descriptors.
- typedef OptionSpaceContainer<OptionContainer,
- OptionDescriptor, uint32_t> VendorOptionSpaceCollection;
-
- /// Regular options are kept here
- OptionSpaceCollection option_spaces_;
-
- /// Vendor options are kept here
- VendorOptionSpaceCollection vendor_option_spaces_;
+ /// @brief Pointer to the option data configuration for this subnet.
+ CfgOptionPtr cfg_option_;
};
/// @brief A generic pointer to either Subnet4 or Subnet6 object
protected:
- /// @brief Check if option is valid and can be added to a subnet.
- ///
- /// @param option option to be validated.
- ///
- /// @throw isc::BadValue if provided option is invalid.
- virtual void validateOption(const OptionPtr& option) const;
-
/// @brief Returns default address for pool selection
/// @return ANY IPv4 address
virtual isc::asiolink::IOAddress default_pool() const {
protected:
- /// @brief Check if option is valid and can be added to a subnet.
- ///
- /// @param option option to be validated.
- ///
- /// @throw isc::BadValue if provided option is invalid.
- virtual void validateOption(const OptionPtr& option) const;
-
/// @brief Returns default address for pool selection
/// @return ANY IPv6 address
virtual isc::asiolink::IOAddress default_pool() const {
EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET));
}
-// Checks whether option space can be detected as vendor-id
-TEST_F(DhcpParserTest, vendorOptionSpace) {
- EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId(""));
- EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId("dhcp4"));
- EXPECT_EQ(0, SubnetConfigParser::optionSpaceToVendorId("vendor-"));
- EXPECT_EQ(1, SubnetConfigParser::optionSpaceToVendorId("vendor-1"));
- EXPECT_EQ(4491, SubnetConfigParser::optionSpaceToVendorId("vendor-4491"));
- EXPECT_EQ(12345678, SubnetConfigParser::optionSpaceToVendorId("vendor-12345678"));
-}
-
/// @brief Test Implementation of abstract OptionDataParser class. Allows
/// testing basic option parsing.
class UtestOptionDataParser : public OptionDataParser {
// Some dummy option code.
uint16_t code = 100;
- // Create option with invalid universe (V6 instead of V4).
- // Attempt to add this option should result in exception.
- OptionPtr option1(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- EXPECT_THROW(subnet->addOption(option1, false, "dhcp4"),
- isc::BadValue);
// Create NULL pointer option. Attempt to add NULL option
// should result in exception.
OptionPtr option2;
ASSERT_FALSE(option2);
- EXPECT_THROW(subnet->addOption(option2, false, "dhcp4"),
+ EXPECT_THROW(subnet->getCfgOption()->add(option2, false, "dhcp4"),
isc::BadValue);
}
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp6 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addOption(option, false, "isc"));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "isc"));
}
// Get options from the Subnet and check if all 10 are there.
- OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+ OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
++expected_code;
}
- options = subnet->getOptionDescriptors("isc");
+ options = subnet->getCfgOption()->getAll("isc");
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
}
// Try to get options from a non-existing option space.
- options = subnet->getOptionDescriptors("abcd");
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
-
- // Delete options from all spaces.
- subnet->delOptions();
-
- // Make sure that all options have been removed.
- options = subnet->getOptionDescriptors("dhcp6");
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
-
- options = subnet->getOptionDescriptors("isc");
+ options = subnet->getCfgOption()->getAll("abcd");
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}
// In the inner loop we create options with unique codes (100-109).
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
}
}
// Sanity check that all options are there.
- OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+ OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
ASSERT_EQ(20, options->size());
// Use container index #1 to get the options by their codes.
idx.equal_range(non_existing_code);
// Empty set is expected.
EXPECT_EQ(0, distance(range.first, range.second));
-
- subnet->delOptions();
-
- options = subnet->getOptionDescriptors("dhcp6");
- EXPECT_EQ(0, options->size());
-}
-
-TEST(Subnet6Test, addInvalidOption) {
- // Create as subnet to add options to it.
- Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
-
- // Some dummy option code.
- uint16_t code = 100;
- // Create option with invalid universe (V4 instead of V6).
- // Attempt to add this option should result in exception.
- OptionPtr option1(new Option(Option::V4, code, OptionBuffer(10, 0xFF)));
- EXPECT_THROW(subnet->addOption(option1, false, "dhcp6"), isc::BadValue);
-
- // Create NULL pointer option. Attempt to add NULL option
- // should result in exception.
- OptionPtr option2;
- ASSERT_FALSE(option2);
- EXPECT_THROW(subnet->addOption(option2, false, "dhcp6"), isc::BadValue);
}
TEST(Subnet6Test, addPersistentOption) {
// and options with these codes will be flagged non-persistent.
// Options with other codes will be flagged persistent.
bool persistent = (code % 3) ? true : false;
- ASSERT_NO_THROW(subnet->addOption(option, persistent, "dhcp6"));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, persistent, "dhcp6"));
}
// Get added options from the subnet.
- OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
+ OptionContainerPtr options = subnet->getCfgOption()->getAll("dhcp6");
// options->get<2> returns reference to container index #2. This
// index is used to access options by the 'persistent' flag.
idx.equal_range(false);
// 7 out of 10 options have been flagged persistent.
ASSERT_EQ(3, distance(range_non_persistent.first, range_non_persistent.second));
-
- subnet->delOptions();
-
- options = subnet->getOptionDescriptors("dhcp6");
- EXPECT_EQ(0, options->size());
}
-TEST(Subnet6Test, getOptionDescriptor) {
+TEST(Subnet6Test, getOptions) {
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8::"), 56, 1, 2, 3, 4));
// Add 10 options to a "dhcp6" option space in the subnet.
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addOption(option, false, "dhcp6"));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "dhcp6"));
}
// Check that we can get each added option descriptor using
for (uint16_t code = 100; code < 110; ++code) {
std::ostringstream stream;
// First, try the invalid option space name.
- OptionDescriptor desc = subnet->getOptionDescriptor("isc", code);
+ OptionDescriptor desc = subnet->getCfgOption()->get("isc", code);
// Returned descriptor should contain NULL option ptr.
EXPECT_FALSE(desc.option);
// Now, try the valid option space.
- desc = subnet->getOptionDescriptor("dhcp6", code);
+ desc = subnet->getCfgOption()->get("dhcp6", code);
// Test that the option code matches the expected code.
ASSERT_TRUE(desc.option);
EXPECT_EQ(code, desc.option->getType());
}
-TEST(Subnet6Test, addVendorOptions) {
-
- uint32_t vendor_id1 = 12345678;
- uint32_t vendor_id2 = 87654321;
- uint32_t vendor_id_bogus = 1111111;
+TEST(Subnet6Test, addVendorOption) {
// Create as subnet to add options to it.
Subnet6Ptr subnet(new Subnet6(IOAddress("2001:db8:1::"), 56, 1, 2, 3, 4));
// Differentiate options by their codes (100-109)
for (uint16_t code = 100; code < 110; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addVendorOption(option, false, vendor_id1));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-12345678"));
}
// Add 7 options to another option space. The option codes partially overlap
// with option codes that we have added to dhcp6 option space.
for (uint16_t code = 105; code < 112; ++code) {
OptionPtr option(new Option(Option::V6, code, OptionBuffer(10, 0xFF)));
- ASSERT_NO_THROW(subnet->addVendorOption(option, false, vendor_id2));
+ ASSERT_NO_THROW(subnet->getCfgOption()->add(option, false, "vendor-87654321"));
}
// Get options from the Subnet and check if all 10 are there.
- OptionContainerPtr options = subnet->getVendorOptionDescriptors(vendor_id1);
+ OptionContainerPtr options = subnet->getCfgOption()->getAll(12345678);
ASSERT_TRUE(options);
ASSERT_EQ(10, options->size());
++expected_code;
}
- options = subnet->getVendorOptionDescriptors(vendor_id2);
+ options = subnet->getCfgOption()->getAll(87654321);
ASSERT_TRUE(options);
ASSERT_EQ(7, options->size());
}
// Try to get options from a non-existing option space.
- options = subnet->getVendorOptionDescriptors(vendor_id_bogus);
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
-
- // Delete options from all spaces.
- subnet->delVendorOptions();
-
- // Make sure that all options have been removed.
- options = subnet->getVendorOptionDescriptors(vendor_id1);
- ASSERT_TRUE(options);
- EXPECT_TRUE(options->empty());
-
- options = subnet->getVendorOptionDescriptors(vendor_id2);
+ options = subnet->getCfgOption()->getAll(1111111);
ASSERT_TRUE(options);
EXPECT_TRUE(options->empty());
}