Commit 741fe7bc authored by Marcin Siodelski's avatar Marcin Siodelski

[master] Merge branch 'trac2315'

Conflicts:
	src/bin/dhcp4/config_parser.cc
	src/bin/dhcp6/config_parser.cc
parents 856d60a9 b7892222
......@@ -1117,8 +1117,8 @@ private:
subnet_->addPool4(*it);
}
const Subnet::OptionContainer& options = subnet_->getOptions();
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
Subnet::OptionContainerPtr options = subnet_->getOptionDescriptors("dhcp4");
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Add subnet specific options.
BOOST_FOREACH(Subnet::OptionDescriptor desc, options_) {
......@@ -1127,7 +1127,7 @@ private:
LOG_WARN(dhcp4_logger, DHCP4_CONFIG_OPTION_DUPLICATE)
.arg(desc.option->getType()).arg(addr.toText());
}
subnet_->addOption(desc.option);
subnet_->addOption(desc.option, false, "dhcp4");
}
// Check all global options and add them to the subnet object if
......@@ -1137,6 +1137,8 @@ private:
BOOST_FOREACH(Subnet::OptionDescriptor desc, option_defaults) {
// Get all options specified locally in the subnet and having
// code equal to global option's code.
Subnet::OptionContainerPtr options = subnet_->getOptionDescriptors("dhcp4");
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
Subnet::OptionContainerTypeRange range = idx.equal_range(desc.option->getType());
// @todo: In the future we will be searching for options using either
// an option code or namespace. Currently we have only the option
......@@ -1147,7 +1149,7 @@ private:
// want to issue a warning about dropping the configuration of
// a global option if one already exsists.
if (std::distance(range.first, range.second) == 0) {
subnet_->addOption(desc.option);
subnet_->addOption(desc.option, false, "dhcp4");
}
}
}
......
......@@ -471,11 +471,11 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(2, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -542,11 +542,11 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.24"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(2, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -609,11 +609,11 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
Subnet4Ptr subnet1 = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.100"));
ASSERT_TRUE(subnet1);
const Subnet::OptionContainer& options1 = subnet1->getOptions();
ASSERT_EQ(1, options1.size());
Subnet::OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp4");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx1 = options1.get<1>();
const Subnet::OptionContainerTypeIndex& idx1 = options1->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -633,10 +633,10 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
// Test another subnet in the same way.
Subnet4Ptr subnet2 = CfgMgr::instance().getSubnet4(IOAddress("192.0.3.102"));
ASSERT_TRUE(subnet2);
const Subnet::OptionContainer& options2 = subnet2->getOptions();
ASSERT_EQ(1, options2.size());
Subnet::OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp4");
ASSERT_EQ(1, options2->size());
const Subnet::OptionContainerTypeIndex& idx2 = options2.get<1>();
const Subnet::OptionContainerTypeIndex& idx2 = options2->get<1>();
std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
Subnet::OptionContainerTypeIndex::const_iterator> range2 =
idx2.equal_range(23);
......@@ -718,11 +718,11 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(1, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp4");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -761,11 +761,13 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(1, options.size());
Subnet::OptionContainerPtr options =
subnet->getOptionDescriptors("dhcp4");
ASSERT_TRUE(options);
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......
......@@ -1151,9 +1151,8 @@ private:
subnet_->addPool6(*it);
}
// Get the options search index.
const Subnet::OptionContainer& options = subnet_->getOptions();
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
Subnet::OptionContainerPtr options = subnet_->getOptionDescriptors("dhcp6");
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Add subnet specific options.
BOOST_FOREACH(Subnet::OptionDescriptor desc, options_) {
......@@ -1162,7 +1161,7 @@ private:
LOG_WARN(dhcp6_logger, DHCP6_CONFIG_OPTION_DUPLICATE)
.arg(desc.option->getType()).arg(addr.toText());
}
subnet_->addOption(desc.option);
subnet_->addOption(desc.option, false, "dhcp6");
}
// Check all global options and add them to the subnet object if
......@@ -1172,6 +1171,8 @@ private:
BOOST_FOREACH(Subnet::OptionDescriptor desc, option_defaults) {
// Get all options specified locally in the subnet and having
// code equal to global option's code.
Subnet::OptionContainerPtr options = subnet_->getOptionDescriptors("dhcp6");
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
Subnet::OptionContainerTypeRange range = idx.equal_range(desc.option->getType());
// @todo: In the future we will be searching for options using either
// an option code or namespace. Currently we have only the option
......@@ -1182,7 +1183,7 @@ private:
// want to issue a warning about dropping the configuration of
// a global option if one already exsists.
if (std::distance(range.first, range.second) == 0) {
subnet_->addOption(desc.option);
subnet_->addOption(desc.option, false, "dhcp6");
}
}
}
......
// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -340,8 +340,8 @@ void 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();
// Get the list of options configured for a subnet.
const Subnet::OptionContainer& options = subnet->getOptions();
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Try to match requested options with those configured for a subnet.
// If match is found, append configured option to the answer message.
BOOST_FOREACH(uint16_t opt, requested_opts) {
......
......@@ -463,11 +463,11 @@ TEST_F(Dhcp6ParserTest, optionDataDefaults) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(2, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -541,11 +541,11 @@ TEST_F(Dhcp6ParserTest, optionDataInSingleSubnet) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(2, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
ASSERT_EQ(2, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -609,11 +609,11 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
Subnet6Ptr subnet1 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
ASSERT_TRUE(subnet1);
const Subnet::OptionContainer& options1 = subnet1->getOptions();
ASSERT_EQ(1, options1.size());
Subnet::OptionContainerPtr options1 = subnet1->getOptionDescriptors("dhcp6");
ASSERT_EQ(1, options1->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx1 = options1.get<1>();
const Subnet::OptionContainerTypeIndex& idx1 = options1->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -633,10 +633,10 @@ TEST_F(Dhcp6ParserTest, optionDataInMultipleSubnets) {
// Test another subnet in the same way.
Subnet6Ptr subnet2 = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:2::4"));
ASSERT_TRUE(subnet2);
const Subnet::OptionContainer& options2 = subnet2->getOptions();
ASSERT_EQ(1, options2.size());
Subnet::OptionContainerPtr options2 = subnet2->getOptionDescriptors("dhcp6");
ASSERT_EQ(1, options2->size());
const Subnet::OptionContainerTypeIndex& idx2 = options2.get<1>();
const Subnet::OptionContainerTypeIndex& idx2 = options2->get<1>();
std::pair<Subnet::OptionContainerTypeIndex::const_iterator,
Subnet::OptionContainerTypeIndex::const_iterator> range2 =
idx2.equal_range(101);
......@@ -727,11 +727,11 @@ TEST_F(Dhcp6ParserTest, optionDataLowerCase) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(1, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......@@ -769,11 +769,11 @@ TEST_F(Dhcp6ParserTest, stdOptionData) {
Subnet6Ptr subnet = CfgMgr::instance().getSubnet6(IOAddress("2001:db8:1::5"));
ASSERT_TRUE(subnet);
const Subnet::OptionContainer& options = subnet->getOptions();
ASSERT_EQ(1, options.size());
Subnet::OptionContainerPtr options = subnet->getOptionDescriptors("dhcp6");
ASSERT_EQ(1, options->size());
// Get the search index. Index #1 is to search using option code.
const Subnet::OptionContainerTypeIndex& idx = options.get<1>();
const Subnet::OptionContainerTypeIndex& idx = options->get<1>();
// Get the options for specified index. Expecting one option to be
// returned but in theory we may have multiple options with the same
......
......@@ -74,6 +74,34 @@ LibDHCP::getOptionDef(const Option::Universe u, const uint16_t code) {
return (OptionDefinitionPtr());
}
bool
LibDHCP::isStandardOption(const Option::Universe u, const uint16_t code) {
if (u == Option::V6) {
if (code < 79 &&
code != 10 &&
code != 35) {
return (true);
}
} else if (u == Option::V4) {
if (!(code == 84 ||
code == 96 ||
(code > 101 && code < 112) ||
code == 115 ||
code == 126 ||
code == 127 ||
(code > 146 && code < 150) ||
(code > 177 && code < 208) ||
(code > 213 && code < 220) ||
(code > 221 && code < 224))) {
return (true);
}
}
return (false);
}
OptionPtr
LibDHCP::optionFactory(Option::Universe u,
uint16_t type,
......
......@@ -55,6 +55,21 @@ public:
static OptionDefinitionPtr getOptionDef(const Option::Universe u,
const uint16_t code);
/// @brief Check if the specified option is a standard option.
///
/// @param u universe (V4 or V6)
/// @param code option code.
///
/// @return true if the specified option is a standard option.
/// @todo We arleady create option definitions for the subset if
/// standard options. We are aiming that this function checks
/// the presence of the standard option definition and if it finds
/// it, then the true value is returned. However, at this point
/// this is not doable because some of the definitions (for less
/// important options) are not created yet.
static bool isStandardOption(const Option::Universe u,
const uint16_t code);
/// @brief Factory function to create instance of option.
///
/// Factory method creates instance of specified option. The option
......
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -42,6 +42,14 @@ public:
isc::Exception(file, line, what) { };
};
/// @brief Exception to be thrown when the particular option definition
/// duplicates existing option definition.
class DuplicateOptionDefinition : public Exception {
public:
DuplicateOptionDefinition(const char* file, size_t line, const char* what) :
isc::Exception(file, line, what) { };
};
/// @brief Forward declaration to OptionDefinition.
class OptionDefinition;
......@@ -492,6 +500,9 @@ typedef boost::multi_index_container<
>
> OptionDefContainer;
/// Pointer to an option definition container.
typedef boost::shared_ptr<OptionDefContainer> OptionDefContainerPtr;
/// Type of the index #1 - option type.
typedef OptionDefContainer::nth_index<1>::type OptionDefContainerTypeIndex;
/// Pair of iterators to represent the range of options definitions
......
......@@ -453,6 +453,66 @@ TEST_F(LibDhcpTest, unpackOptions4) {
EXPECT_TRUE(x == options.end()); // option 2 not found
}
TEST_F(LibDhcpTest, isStandardOption4) {
// Get all option codes that are not occupied by standard options.
const uint16_t unassigned_codes[] = { 84, 96, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 115, 126, 127, 147, 148, 149,
178, 179, 180, 181, 182, 183, 184, 185, 186,
187, 188, 189, 190, 191, 192, 193, 194, 195,
196, 197, 198, 199, 200, 201, 202, 203, 204,
205, 206, 207, 214, 215, 216, 217, 218, 219,
222, 223 };
const size_t unassigned_num = sizeof(unassigned_codes) / sizeof(unassigned_codes[0]);
// Try all possible option codes.
for (size_t i = 0; i < 256; ++i) {
// Some ranges of option codes are unassigned and thus the isStandardOption
// should return false for them.
bool check_unassigned = false;
// Check the array of unassigned options to find out whether option code
// is assigned to standard option or unassigned.
for (size_t j = 0; j < unassigned_num; ++j) {
// If option code is found within the array of unassigned options
// we the isStandardOption function should return false.
if (unassigned_codes[j] == i) {
check_unassigned = true;
EXPECT_FALSE(LibDHCP::isStandardOption(Option::V4,
unassigned_codes[j]))
<< "Test failed for option code " << unassigned_codes[j];
break;
}
}
// If the option code belongs to the standard option then the
// isStandardOption should return true.
if (!check_unassigned) {
EXPECT_TRUE(LibDHCP::isStandardOption(Option::V4, i))
<< "Test failed for the option code " << i;
}
}
}
TEST_F(LibDhcpTest, isStandardOption6) {
// All option codes in the range from 0 to 78 (except 10 and 35)
// identify the standard options.
for (uint16_t code = 0; code < 79; ++code) {
if (code != 10 && code != 35) {
EXPECT_TRUE(LibDHCP::isStandardOption(Option::V6, code))
<< "Test failed for option code " << code;
}
}
// Check the option codes 10 and 35. They are unassigned.
EXPECT_FALSE(LibDHCP::isStandardOption(Option::V6, 10));
EXPECT_FALSE(LibDHCP::isStandardOption(Option::V6, 35));
// Check a range of option codes above 78. Those are option codes
// identifying non-standard options.
for (uint16_t code = 79; code < 512; ++code) {
EXPECT_FALSE(LibDHCP::isStandardOption(Option::V6, code))
<< "Test failed for option code " << code;
}
}
TEST_F(LibDhcpTest, stdOptionDefs4) {
// Create a buffer that holds dummy option data.
......
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -13,6 +13,7 @@
// PERFORMANCE OF THIS SOFTWARE.
#include <asiolink/io_address.h>
#include <dhcp/libdhcp++.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/dhcpsrv_log.h>
......@@ -28,6 +29,84 @@ CfgMgr::instance() {
return (cfg_mgr);
}
void
CfgMgr::addOptionDef(const OptionDefinitionPtr& def,
const std::string& option_space) {
// @todo we need better validation of the provided option space name here.
// This will be implemented when #2313 is merged.
if (option_space.empty()) {
isc_throw(BadValue, "option space name must not be empty");
} else if (!def) {
// Option definition must point to a valid object.
isc_throw(MalformedOptionDefinition, "option definition must not be NULL");
} else if (getOptionDef(option_space, def->getCode())) {
// Option definition must not be overriden.
isc_throw(DuplicateOptionDefinition, "option definition already added"
<< " to option space " << option_space);
} else if ((option_space == "dhcp4" &&
LibDHCP::isStandardOption(Option::V4, def->getCode())) ||
(option_space == "dhcp6" &&
LibDHCP::isStandardOption(Option::V6, def->getCode()))) {
// We must not override standard (assigned) option. The standard options
// belong to dhcp4 or dhcp6 option space.
isc_throw(BadValue, "unable to override definition of option '"
<< def->getCode() << "' in standard option space '"
<< option_space << "'.");
}
// Get existing option definitions for the option space.
OptionDefContainerPtr defs = getOptionDefs(option_space);
// getOptionDefs always returns a valid pointer to
// the container. Let's make an assert to make sure.
assert(defs);
// Actually add the new definition.
defs->push_back(def);
option_def_spaces_[option_space] = defs;
}
OptionDefContainerPtr
CfgMgr::getOptionDefs(const std::string& option_space) const {
// @todo Validate the option space once the #2313 is implemented.
// Get all option definitions for the particular option space.
const OptionDefsMap::const_iterator& defs =
option_def_spaces_.find(option_space);
// If there are no option definitions for the particular option space
// then return empty container.
if (defs == option_def_spaces_.end()) {
return (OptionDefContainerPtr(new OptionDefContainer()));
}
// If option definitions found, return them.
return (defs->second);
}
OptionDefinitionPtr
CfgMgr::getOptionDef(const std::string& option_space,
const uint16_t option_code) const {
// @todo Validate the option space once the #2313 is implemented.
// Get a reference to option definitions for a particular option space.
OptionDefContainerPtr defs = getOptionDefs(option_space);
// If there are no matching option definitions then return the empty pointer.
if (!defs || defs->empty()) {
return (OptionDefinitionPtr());
}
// If there are some option definitions for a particular option space
// use an option code to get the one we want.
const OptionDefContainerTypeIndex& idx = defs->get<1>();
const OptionDefContainerTypeRange& range = idx.equal_range(option_code);
// If there is no definition that matches option code, return empty pointer.
if (std::distance(range.first, range.second) == 0) {
return (OptionDefinitionPtr());
}
// If there is more than one definition matching an option code, return
// the first one. This should not happen because we check for duplicates
// when addOptionDef is called.
return (*range.first);
}
Subnet6Ptr
CfgMgr::getSubnet6(const isc::asiolink::IOAddress& hint) {
......@@ -119,6 +198,10 @@ void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) {
subnets4_.push_back(subnet);
}
void CfgMgr::deleteOptionDefs() {
option_def_spaces_.clear();
}
void CfgMgr::deleteSubnets4() {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CFGMGR_DELETE_SUBNET4);
subnets4_.clear();
......
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
......@@ -17,6 +17,7 @@
#include <asiolink/io_address.h>
#include <dhcp/option.h>
#include <dhcp/option_definition.h>
#include <dhcpsrv/pool.h>
#include <dhcpsrv/subnet.h>
#include <util/buffer.h>
......@@ -77,6 +78,41 @@ public:
/// accessing it.
static CfgMgr& instance();
/// @brief Add new option definition.
///
/// @param def option definition to be added.
/// @param option_space name of the option space to add definition to.
///
/// @throw isc::dhcp::DuplicateOptionDefinition when the particular
/// option definition already exists.
/// @throw isc::dhcp::MalformedOptionDefinition when the pointer to
/// an option definition is NULL.
/// @throw isc::BadValue when the option space name is empty or
/// when trying to override the standard option (in dhcp4 or dhcp6
/// option space).
void addOptionDef(const OptionDefinitionPtr& def,
const std::string& option_space);
/// @brief Return option definitions for particular option space.
///
/// @param option_space option space.
///
/// @return pointer to the collection of option definitions for
/// the particular option space. The option collection is empty
/// if no option exists for the option space specified.
OptionDefContainerPtr
getOptionDefs(const std::string& option_space) const;
/// @brief Return option definition for a particular option space and code.
///
/// @param option_space option space.
/// @param option_code option code.
///
/// @return an option definition or NULL pointer if option definition
/// has not been found.
OptionDefinitionPtr getOptionDef(const std::string& option_space,
const uint16_t option_code) const;
/// @brief get IPv6 subnet by address
///
/// Finds a matching subnet, based on an address. This can be used
......@@ -86,6 +122,8 @@ public:
/// (for directly connected clients)
///
/// @param hint an address that belongs to a searched subnet
///
/// @return a subnet object
Subnet6Ptr getSubnet6(const isc::asiolink::IOAddress& hint);
/// @brief get IPv6 subnet by interface-id
......@@ -93,12 +131,19 @@ public:
/// Another possibility to find a subnet is based on interface-id.