Commit 777dbdb2 authored by Marcin Siodelski's avatar Marcin Siodelski
Browse files

[master] Merge branch 'trac3409'

Conflicts:
	src/lib/dhcpsrv/d2_client_cfg.cc
	src/lib/dhcpsrv/dhcp_parsers.cc
parents 1b72b3e3 d5965863
......@@ -1466,6 +1466,7 @@ AC_CONFIG_FILES([compatcheck/Makefile
src/lib/dhcp_ddns/tests/Makefile
src/lib/dhcp/Makefile
src/lib/dhcpsrv/Makefile
src/lib/dhcpsrv/testutils/Makefile
src/lib/dhcpsrv/tests/Makefile
src/lib/dhcpsrv/tests/test_libraries.h
src/lib/dhcp/tests/Makefile
......
......@@ -167,9 +167,13 @@ public:
:SubnetConfigParser("", globalContext(), IOAddress("0.0.0.0")) {
}
/// @brief Adds the created subnet to a server's configuration.
/// @throw throws Unexpected if dynamic cast fails.
void commit() {
/// @brief Parses a single IPv4 subnet configuration and adds to the
/// Configuration Manager.
///
/// @param subnet A new subnet being configured.
void build(ConstElementPtr subnet) {
SubnetConfigParser::build(subnet);
if (subnet_) {
Subnet4Ptr sub4ptr = boost::dynamic_pointer_cast<Subnet4>(subnet_);
if (!sub4ptr) {
......@@ -183,10 +187,24 @@ public:
sub4ptr->setRelayInfo(*relay_info_);
}
isc::dhcp::CfgMgr::instance().addSubnet4(sub4ptr);
// Adding a subnet to the Configuration Manager may fail if the
// subnet id is invalid (duplicate). Thus, we catch exceptions
// here to append a position in the configuration string.
try {
isc::dhcp::CfgMgr::instance().addSubnet4(sub4ptr);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, ex.what() << " ("
<< subnet->getPosition() << ")");
}
}
}
/// @brief Commits subnet configuration.
///
/// This function is currently no-op because subnet should already
/// be added into the Config Manager in the build().
void commit() { }
protected:
/// @brief Creates parsers for entries in subnet definition.
......@@ -218,8 +236,7 @@ protected:
global_context_,
Dhcp4OptionDataParser::factory);
} else {
isc_throw(NotImplemented,
"parser error: Subnet4 parameter not supported: " << config_id);
isc_throw(NotImplemented, "unsupported parameter: " << config_id);
}
return (parser);
......@@ -294,6 +311,10 @@ protected:
}
} catch (const DhcpConfigError&) {
// Don't care. next_server is optional. We can live without it
} catch (...) {
isc_throw(DhcpConfigError, "invalid parameter next-server ("
<< globalContext()->string_values_->getPosition("next-server")
<< ")");
}
// Try subnet specific value if it's available
......@@ -304,8 +325,13 @@ protected:
}
} catch (const DhcpConfigError&) {
// Don't care. next_server is optional. We can live without it
} catch (...) {
isc_throw(DhcpConfigError, "invalid parameter next-server ("
<< string_values_->getPosition("next-server")
<< ")");
}
// Try setting up client class (if specified)
try {
string client_class = string_values_->getParam("client-class");
......@@ -338,6 +364,12 @@ public:
///
/// @param subnets_list pointer to a list of IPv4 subnets
void build(ConstElementPtr subnets_list) {
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
CfgMgr::instance().deleteSubnets4();
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
ParserPtr parser(new Subnet4ConfigParser("subnet"));
parser->build(subnet);
......@@ -350,12 +382,6 @@ public:
/// Iterates over all Subnet4 parsers. Each parser contains definitions of
/// a single subnet and its parameters and commits each subnet separately.
void commit() {
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
CfgMgr::instance().deleteSubnets4();
BOOST_FOREACH(ParserPtr subnet, subnets_) {
subnet->commit();
}
......@@ -388,7 +414,8 @@ namespace dhcp {
/// @return parser for specified global DHCPv4 parameter
/// @throw NotImplemented if trying to create a parser for unknown
/// config element
DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id,
ConstElementPtr element) {
DhcpConfigParser* parser = NULL;
if ((config_id.compare("valid-lifetime") == 0) ||
(config_id.compare("renew-timer") == 0) ||
......@@ -405,8 +432,7 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
globalContext(),
Dhcp4OptionDataParser::factory);
} else if (config_id.compare("option-def") == 0) {
parser = new OptionDefListParser(config_id,
globalContext()->option_defs_);
parser = new OptionDefListParser(config_id, globalContext());
} else if ((config_id.compare("version") == 0) ||
(config_id.compare("next-server") == 0)) {
parser = new StringParser(config_id,
......@@ -420,9 +446,9 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id) {
} else if (config_id.compare("dhcp-ddns") == 0) {
parser = new D2ClientConfigParser(config_id);
} else {
isc_throw(NotImplemented,
"Parser error: Global configuration parameter not supported: "
<< config_id);
isc_throw(DhcpConfigError,
"unsupported global configuration parameter: "
<< config_id << " (" << element->getPosition() << ")");
}
return (parser);
......@@ -500,7 +526,8 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
const std::map<std::string, ConstElementPtr>& values_map =
config_set->mapValue();
BOOST_FOREACH(config_pair, values_map) {
ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first));
ParserPtr parser(createGlobalDhcp4ConfigParser(config_pair.first,
config_pair.second));
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_DETAIL, DHCP4_PARSER_CREATED)
.arg(config_pair.first);
if (config_pair.first == "subnet4") {
......@@ -534,6 +561,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
std::map<std::string, ConstElementPtr>::const_iterator option_config =
values_map.find("option-data");
if (option_config != values_map.end()) {
config_pair.first = "option-data";
option_parser->build(option_config->second);
option_parser->commit();
}
......@@ -542,6 +570,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
std::map<std::string, ConstElementPtr>::const_iterator subnet_config =
values_map.find("subnet4");
if (subnet_config != values_map.end()) {
config_pair.first = "subnet4";
subnet_parser->build(subnet_config->second);
}
......
......@@ -106,6 +106,7 @@ dhcp4_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
dhcp4_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
endif
noinst_PROGRAMS = $(TESTS)
......@@ -27,6 +27,7 @@
#include <dhcp/classify.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/testutils/config_result_check.h>
#include <hooks/hooks_manager.h>
#include "marker_file.h"
......@@ -286,9 +287,8 @@ public:
std::string config = createConfigWithOption(param_value, parameter);
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(1, rcode_);
checkResult(x, 1);
EXPECT_TRUE(errorContainsPosition(x, "<string>"));
}
/// @brief Test invalid option paramater value.
......@@ -304,9 +304,8 @@ public:
std::string config = createConfigWithOption(params);
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(1, rcode_);
checkResult(x, 1);
EXPECT_TRUE(errorContainsPosition(x, "<string>"));
}
/// @brief Test option against given code and data.
......@@ -580,9 +579,7 @@ TEST_F(Dhcp4ParserTest, multipleSubnets) {
do {
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......@@ -635,9 +632,7 @@ TEST_F(Dhcp4ParserTest, multipleSubnetsExplicitIDs) {
int cnt = 0; // Number of reconfigurations
do {
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......@@ -686,9 +681,8 @@ TEST_F(Dhcp4ParserTest, multipleSubnetsOverlapingIDs) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
EXPECT_NE(rcode_, 0);
checkResult(x, 1);
EXPECT_TRUE(errorContainsPosition(x, "<string>"));
}
// Goal of this test is to verify that a previously configured subnet can be
......@@ -769,9 +763,7 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
ElementPtr json = Element::fromJSON(config4);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......@@ -780,9 +772,7 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
// Do the reconfiguration (the last subnet is removed)
json = Element::fromJSON(config_first3);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......@@ -799,16 +789,12 @@ TEST_F(Dhcp4ParserTest, reconfigureRemoveSubnet) {
/// @todo: Uncomment subnet removal test as part of #3281.
json = Element::fromJSON(config4);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
// Do reconfiguration
json = Element::fromJSON(config_second_removed);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......@@ -932,12 +918,15 @@ TEST_F(Dhcp4ParserTest, nextServerNegative) {
// check if returned status is always a failure
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json1));
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json2));
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json3));
checkResult(status, 0);
EXPECT_FALSE(errorContainsPosition(status, "<string>"));
}
// Checks if the next-server defined as global value is overridden by subnet
......@@ -1065,6 +1054,7 @@ TEST_F(Dhcp4ParserTest, poolOutOfSubnet) {
// returned value must be 1 (values error)
// as the pool does not belong to that subnet
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
// Goal of this test is to verify if pools can be defined
......@@ -1284,6 +1274,7 @@ TEST_F(Dhcp4ParserTest, optionDefDuplicate) {
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status);
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
// The goal of this test is to verify that the option definition
......@@ -1392,6 +1383,7 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidName) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The purpose of this test is to verify that the option definition
......@@ -1418,6 +1410,7 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidType) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The purpose of this test is to verify that the option definition
......@@ -1444,6 +1437,7 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidRecordType) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The goal of this test is to verify that the invalid encapsulated
......@@ -1470,6 +1464,7 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidEncapsulatedSpace) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The goal of this test is to verify that the encapsulated
......@@ -1498,6 +1493,7 @@ TEST_F(Dhcp4ParserTest, optionDefEncapsulatedSpaceAndArray) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The goal of this test is to verify that the option may not
......@@ -1524,6 +1520,7 @@ TEST_F(Dhcp4ParserTest, optionDefEncapsulateOwnSpace) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
/// The purpose of this test is to verify that it is not allowed
......@@ -1588,6 +1585,7 @@ TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
ASSERT_TRUE(status);
// Expecting parsing error (error code 1).
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
/// @todo The option 65 is a standard DHCPv4 option. However, at this point
/// there is no definition for this option in libdhcp++, so it should be
......@@ -1655,9 +1653,7 @@ TEST_F(Dhcp4ParserTest, optionDataDefaults) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.200"),
classify_);
......@@ -1960,9 +1956,7 @@ TEST_F(Dhcp4ParserTest, optionDataInSingleSubnet) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.24"),
classify_);
......@@ -2113,9 +2107,7 @@ TEST_F(Dhcp4ParserTest, optionDataInMultipleSubnets) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
Subnet4Ptr subnet1 = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.100"),
classify_);
......@@ -2218,9 +2210,7 @@ TEST_F(Dhcp4ParserTest, optionDataLowerCase) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
classify_);
......@@ -2263,9 +2253,7 @@ TEST_F(Dhcp4ParserTest, stdOptionData) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
Subnet4Ptr subnet = CfgMgr::instance().getSubnet4(IOAddress("192.0.2.5"),
classify_);
......@@ -2343,6 +2331,7 @@ TEST_F(Dhcp4ParserTest, DISABLED_Uint32Parser) {
// returned value must be rejected (1 configuration error)
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
// CASE 4: -1 (UINT_MIN -1 ) should not work
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_,
......@@ -2351,6 +2340,7 @@ TEST_F(Dhcp4ParserTest, DISABLED_Uint32Parser) {
// returned value must be rejected (1 configuration error)
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
}
// The goal of this test is to verify that the standard option can
......@@ -2941,6 +2931,7 @@ TEST_F(Dhcp4ParserTest, invalidD2ClientConfig) {
// check if returned status is failed.
checkResult(status, 1);
EXPECT_TRUE(errorContainsPosition(status, "<string>"));
// Verify that the D2 configuraiton can be fetched and is set to disabled.
D2ClientConfigPtr d2_client_config = CfgMgr::instance().getD2ClientConfig();
......@@ -3014,9 +3005,7 @@ TEST_F(Dhcp4ParserTest, classifySubnets) {
ElementPtr json = Element::fromJSON(config);
EXPECT_NO_THROW(x = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(x);
comment_ = parseAnswer(rcode_, x);
ASSERT_EQ(0, rcode_);
checkResult(x, 0);
const Subnet4Collection* subnets = CfgMgr::instance().getSubnets4();
ASSERT_TRUE(subnets);
......
......@@ -231,30 +231,33 @@ public:
uint32_values_));
parser = code_parser;
} else {
isc_throw(DhcpConfigError, "invalid parameter: " << entry);
isc_throw(DhcpConfigError, "unsupported parameter: " << entry
<< " (" << param.second->getPosition() << ")");
}
parser->build(param.second);
parser->commit();
}
// Try to obtain the pool parameters. It will throw an exception if any
// of the required parameters are not present or invalid.
std::string addr_str;
uint32_t prefix_len;
uint32_t delegated_len;
try {
// We should now have all of the pool elements we need to create
// the pool. Fetch them and pass them into the Pool6 constructor.
// The constructor is expected to enforce any value validation.
const std::string addr_str = string_values_->getParam("prefix");
IOAddress addr(addr_str);
uint32_t prefix_len = uint32_values_->getParam("prefix-len");
uint32_t delegated_len = uint32_values_->getParam("delegated-len");
addr_str = string_values_->getParam("prefix");
prefix_len = uint32_values_->getParam("prefix-len");
delegated_len = uint32_values_->getParam("delegated-len");
// Attempt to construct the local pool.
pool_.reset(new Pool6(Lease::TYPE_PD, addr, prefix_len,
delegated_len));
pool_.reset(new Pool6(Lease::TYPE_PD, IOAddress(addr_str),
prefix_len, delegated_len));
} catch (const std::exception& ex) {
isc_throw(isc::dhcp::DhcpConfigError,
"PdPoolParser failed to build pool: " << ex.what());
// Some parameters don't exist or are invalid. Since we are not
// aware whether they don't exist or are invalid, let's append
// the position of the pool map element.
isc_throw(isc::dhcp::DhcpConfigError, ex.what()
<< " (" << pd_pool_->getPosition() << ")");
}
}
......@@ -319,7 +322,7 @@ public:
// Make sure we have a configuration elements to parse.
if (!pd_pool_list) {
isc_throw(DhcpConfigError,
"PdPoolListParser: list of pool definitions is empty");
"PdPoolListParser: list of pool definitions is NULL");
}
// Loop through the list of pd pools.
......@@ -371,15 +374,19 @@ public:
:SubnetConfigParser("", globalContext(), IOAddress("::")) {
}
/// @brief Adds the created subnet to a server's configuration.
/// @throw throws Unexpected if dynamic cast fails.
void commit() {
/// @brief Parses a single IPv4 subnet configuration and adds to the
/// Configuration Manager.
///
/// @param subnet A new subnet being configured.
void build(ConstElementPtr subnet) {
SubnetConfigParser::build(subnet);
if (subnet_) {
Subnet6Ptr sub6ptr = boost::dynamic_pointer_cast<Subnet6>(subnet_);
if (!sub6ptr) {
// If we hit this, it is a programming error.
isc_throw(Unexpected,
"Invalid cast in Subnet4ConfigParser::commit");
"Invalid cast in Subnet6ConfigParser::commit");
}
// Set relay infomation if it was provided
......@@ -387,10 +394,25 @@ public:
sub6ptr->setRelayInfo(*relay_info_);
}
isc::dhcp::CfgMgr::instance().addSubnet6(sub6ptr);
// Adding a subnet to the Configuration Manager may fail if the
// subnet id is invalid (duplicate). Thus, we catch exceptions
// here to append a position in the configuration string.
try {
isc::dhcp::CfgMgr::instance().addSubnet6(sub6ptr);
} catch (const std::exception& ex) {
isc_throw(DhcpConfigError, ex.what() << " ("
<< subnet->getPosition() << ")");
}
}
}
/// @brief Commits subnet configuration.
///
/// This function is currently no-op because subnet should already
/// be added into the Config Manager in the build().
void commit() { }
protected:
/// @brief creates parsers for entries in subnet definition
......@@ -425,8 +447,7 @@ protected:
global_context_,
Dhcp6OptionDataParser::factory);
} else {
isc_throw(NotImplemented,
"parser error: Subnet6 parameter not supported: " << config_id);
isc_throw(NotImplemented, "unsupported parameter: " << config_id);
}
return (parser);
......@@ -569,6 +590,12 @@ public:
///
/// @param subnets_list pointer to a list of IPv6 subnets
void build(ConstElementPtr subnets_list) {
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
isc::dhcp::CfgMgr::instance().deleteSubnets6();
BOOST_FOREACH(ConstElementPtr subnet, subnets_list->listValue()) {
ParserPtr parser(new Subnet6ConfigParser("subnet"));
parser->build(subnet);
......@@ -582,12 +609,6 @@ public:
/// Iterates over all Subnet6 parsers. Each parser contains definitions of
/// a single subnet and its parameters and commits each subnet separately.
void commit() {
// @todo: Implement more subtle reconfiguration than toss
// the old one and replace with the new one.
// remove old subnets
isc::dhcp::CfgMgr::instance().deleteSubnets6();
BOOST_FOREACH(ParserPtr subnet, subnets_) {
subnet->commit();
}
......@@ -619,7 +640,8 @@ namespace dhcp {
/// @return parser for specified global DHCPv6 parameter
/// @throw NotImplemented if trying to create a parser for unknown config
/// element
DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
ConstElementPtr element) {
DhcpConfigParser* parser = NULL;
if ((config_id.compare("preferred-lifetime") == 0) ||
(config_id.compare("valid-lifetime") == 0) ||
......@@ -637,8 +659,7 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
globalContext(),
Dhcp6OptionDataParser::factory);
} else if (config_id.compare("option-def") == 0) {
parser = new OptionDefListParser(config_id,
globalContext()->option_defs_);
parser = new OptionDefListParser(config_id, globalContext());
} else if (config_id.compare("version") == 0) {
parser = new StringParser(config_id,
globalContext()->string_values_);
......@@ -649,9 +670,9 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
} else if (config_id.compare("dhcp-ddns") == 0) {
parser = new D2ClientConfigParser(config_id);
} else {
isc_throw(NotImplemented,
"Parser error: Global configuration parameter not supported: "
<< config_id);
isc_throw(DhcpConfigError,
"unsupported global configuration parameter: "