Commit d330a583 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[master] Merge branch 'master' of ssh://git.kea.isc.org/git/kea

Conflicts:
	ChangeLog
parents cc2e6681 ce6e519c
832. [bug] jiri 833. [bug] jiri
Compilation fix for PostgreSQL on i686. Thanks to Jiri Popelka Compilation fix for PostgreSQL on i686. Thanks to Jiri Popelka
from RedHat for providing a patch! from RedHat for providing a patch!
(Trac #3532, git 96a06654f2177444dcea3a0e9f6fa06947855497) (Trac #3532, git 96a06654f2177444dcea3a0e9f6fa06947855497)
832. [func] marcin
DHCP servers check if the interfaces specified in the configuration,
to be used to receive DHCP messsages, are present in the system.
If the interface doesn't exist, an error is reported. In addition,
the SO_REUSEPORT flag is set for IPv6 sockets as multiple multicast
sockets can be bound to the DHCPv6 server port.
(Trac #3512, git 5cbbab2d01c6e1bf6d563ba64d80bc6bc857f73d)
831. [bug] marcin 831. [bug] marcin
Kea deamons report configuration summary when the configuration is Kea deamons report configuration summary when the configuration is
completed successfully. completed successfully.
......
...@@ -177,7 +177,8 @@ void ControlledDhcpv4Srv::init(const std::string& config_file) { ...@@ -177,7 +177,8 @@ void ControlledDhcpv4Srv::init(const std::string& config_file) {
// Configuration may disable or enable interfaces so we have to // Configuration may disable or enable interfaces so we have to
// reopen sockets according to new configuration. // reopen sockets according to new configuration.
openActiveSockets(getPort(), useBroadcast()); CfgMgr::instance().getConfiguration()->cfg_iface_
.openSockets(getPort(), useBroadcast());
} catch (const std::exception& ex) { } catch (const std::exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what()); LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what());
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <dhcp4/dhcp4_log.h> #include <dhcp4/dhcp4_log.h>
#include <hooks/hooks_manager.h> #include <hooks/hooks_manager.h>
#include <dhcp4/json_config_parser.h> #include <dhcp4/json_config_parser.h>
#include <dhcpsrv/cfgmgr.h>
using namespace isc::data; using namespace isc::data;
using namespace isc::hooks; using namespace isc::hooks;
...@@ -117,7 +118,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) { ...@@ -117,7 +118,7 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
err << "Server object not initialized, can't process config."; err << "Server object not initialized, can't process config.";
return (isc::config::createAnswer(1, err.str())); return (isc::config::createAnswer(1, err.str()));
} }
ConstElementPtr answer = configureDhcp4Server(*srv, config); ConstElementPtr answer = configureDhcp4Server(*srv, config);
...@@ -148,7 +149,9 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) { ...@@ -148,7 +149,9 @@ ControlledDhcpv4Srv::processConfig(isc::data::ConstElementPtr config) {
// safe and we really don't want to emit exceptions to whoever called this // safe and we really don't want to emit exceptions to whoever called this
// method. Instead, catch an exception and create appropriate answer. // method. Instead, catch an exception and create appropriate answer.
try { try {
srv->openActiveSockets(srv->getPort(), getInstance()->useBroadcast()); CfgMgr::instance().getConfiguration()->cfg_iface_
.openSockets(srv->getPort(), getInstance()->useBroadcast());
} catch (std::exception& ex) { } catch (std::exception& ex) {
err << "failed to open sockets after server reconfiguration: " err << "failed to open sockets after server reconfiguration: "
<< ex.what(); << ex.what();
......
...@@ -50,10 +50,11 @@ new configuration. It is output during server startup, and when an updated ...@@ -50,10 +50,11 @@ new configuration. It is output during server startup, and when an updated
configuration is committed by the administrator. Additional information configuration is committed by the administrator. Additional information
may be provided. may be provided.
% DHCP4_CONFIG_LOAD_FAIL failed to load configuration: %1 % DHCP4_CONFIG_LOAD_FAIL configuration error using file: %1, reason: %2
This critical error message indicates that the initial DHCPv4 This error message indicates that the DHCPv4 configuration has failed.
configuration has failed. The server will start, but nothing will be If this is an initial configuration (during server's startup) the server
served until the configuration has been corrected. will fail to start. If this is a dynamic reconfiguration attempt the
server will continue to use an old configuration.
% DHCP4_CONFIG_NEW_SUBNET a new subnet has been added to configuration: %1 % DHCP4_CONFIG_NEW_SUBNET a new subnet has been added to configuration: %1
This is an informational message reporting that the configuration has This is an informational message reporting that the configuration has
......
...@@ -1795,55 +1795,6 @@ Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) { ...@@ -1795,55 +1795,6 @@ Dhcpv4Srv::sanityCheck(const Pkt4Ptr& pkt, RequirementLevel serverid) {
} }
} }
void
Dhcpv4Srv::openActiveSockets(const uint16_t port,
const bool use_bcast) {
IfaceMgr::instance().closeSockets();
// Get the reference to the collection of interfaces. This reference should
// be valid as long as the program is run because IfaceMgr is a singleton.
// Therefore we can safely iterate over instances of all interfaces and
// modify their flags. Here we modify flags which indicate whether socket
// should be open for a particular interface or not.
const IfaceMgr::IfaceCollection& ifaces = IfaceMgr::instance().getIfaces();
for (IfaceMgr::IfaceCollection::const_iterator iface = ifaces.begin();
iface != ifaces.end(); ++iface) {
Iface* iface_ptr = IfaceMgr::instance().getIface(iface->getName());
if (iface_ptr == NULL) {
isc_throw(isc::Unexpected, "Interface Manager returned NULL"
<< " instance of the interface when DHCPv4 server was"
<< " trying to reopen sockets after reconfiguration");
}
// Ignore loopback interfaces.
if (iface_ptr->flag_loopback_) {
iface_ptr->inactive4_ = true;
} else if (CfgMgr::instance().isActiveIface(iface->getName())) {
iface_ptr->inactive4_ = false;
LOG_INFO(dhcp4_logger, DHCP4_ACTIVATE_INTERFACE)
.arg(iface->getFullName());
} else {
// For deactivating interface, it should be sufficient to log it
// on the debug level because it is more useful to know what
// interface is activated which is logged on the info level.
LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC,
DHCP4_DEACTIVATE_INTERFACE).arg(iface->getName());
iface_ptr->inactive4_ = true;
}
}
// Let's reopen active sockets. openSockets4 will check internally whether
// sockets are marked active or inactive.
/// @todo Optimization: we should not reopen all sockets but rather select
/// those that have been affected by the new configuration.
isc::dhcp::IfaceMgrErrorMsgCallback error_handler =
boost::bind(&Dhcpv4Srv::ifaceMgrSocket4ErrorHandler, _1);
if (!IfaceMgr::instance().openSockets4(port, use_bcast, error_handler)) {
LOG_WARN(dhcp4_logger, DHCP4_NO_SOCKETS_OPEN);
}
}
size_t size_t
Dhcpv4Srv::unpackOptions(const OptionBuffer& buf, Dhcpv4Srv::unpackOptions(const OptionBuffer& buf,
const std::string& option_space, const std::string& option_space,
......
...@@ -128,11 +128,6 @@ public: ...@@ -128,11 +128,6 @@ public:
/// ///
/// @name Public accessors returning values required to (re)open sockets. /// @name Public accessors returning values required to (re)open sockets.
/// ///
/// These accessors must be public because sockets are reopened from the
/// static configuration callback handler. This callback handler invokes
/// @c ControlledDhcpv4Srv::openActiveSockets which requires parameters
/// which has to be retrieved from the @c ControlledDhcpv4Srv object.
/// They are retrieved using these public functions
//@{ //@{
/// ///
/// @brief Get UDP port on which server should listen. /// @brief Get UDP port on which server should listen.
...@@ -154,17 +149,6 @@ public: ...@@ -154,17 +149,6 @@ public:
} }
//@} //@}
/// @brief Open sockets which are marked as active in @c CfgMgr.
///
/// This function reopens sockets according to the current settings in the
/// Configuration Manager. It holds the list of the interfaces which server
/// should listen on. This function will open sockets on these interfaces
/// only. This function is not exception safe.
///
/// @param port UDP port on which server should listen.
/// @param use_bcast should broadcast flags be set on the sockets.
static void openActiveSockets(const uint16_t port, const bool use_bcast);
/// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled. /// @brief Starts DHCP_DDNS client IO if DDNS updates are enabled.
/// ///
/// If updates are enabled, it Instructs the D2ClientMgr singleton to /// If updates are enabled, it Instructs the D2ClientMgr singleton to
......
...@@ -594,8 +594,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -594,8 +594,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
} catch (const isc::Exception& ex) { } catch (const isc::Exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL) LOG_ERROR(dhcp4_logger, DHCP4_PARSER_FAIL)
.arg(config_pair.first).arg(ex.what()); .arg(config_pair.first).arg(ex.what());
answer = isc::config::createAnswer(1, answer = isc::config::createAnswer(1, ex.what());
string("Configuration parsing failed: ") + ex.what());
// An error occured, so make sure that we restore original data. // An error occured, so make sure that we restore original data.
rollback = true; rollback = true;
...@@ -603,8 +602,8 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -603,8 +602,8 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
} catch (...) { } catch (...) {
// For things like bad_cast in boost::lexical_cast // For things like bad_cast in boost::lexical_cast
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_EXCEPTION).arg(config_pair.first); LOG_ERROR(dhcp4_logger, DHCP4_PARSER_EXCEPTION).arg(config_pair.first);
answer = isc::config::createAnswer(1, answer = isc::config::createAnswer(1, "undefined configuration"
string("Configuration parsing failed")); " processing error");
// An error occured, so make sure that we restore original data. // An error occured, so make sure that we restore original data.
rollback = true; rollback = true;
...@@ -636,14 +635,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -636,14 +635,13 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
} }
catch (const isc::Exception& ex) { catch (const isc::Exception& ex) {
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what()); LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_FAIL).arg(ex.what());
answer = isc::config::createAnswer(2, answer = isc::config::createAnswer(2, ex.what());
string("Configuration commit failed: ") + ex.what());
rollback = true; rollback = true;
} catch (...) { } catch (...) {
// For things like bad_cast in boost::lexical_cast // For things like bad_cast in boost::lexical_cast
LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION); LOG_ERROR(dhcp4_logger, DHCP4_PARSER_COMMIT_EXCEPTION);
answer = isc::config::createAnswer(2, answer = isc::config::createAnswer(2, "undefined configuration"
string("Configuration commit failed")); " parsing error");
rollback = true; rollback = true;
} }
} }
...@@ -659,7 +657,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) { ...@@ -659,7 +657,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
getConfigSummary(Configuration::CFGSEL_ALL4)); getConfigSummary(Configuration::CFGSEL_ALL4));
// Everything was fine. Configuration is successful. // Everything was fine. Configuration is successful.
answer = isc::config::createAnswer(0, "Configuration committed."); answer = isc::config::createAnswer(0, "Configuration successful.");
return (answer); return (answer);
} }
......
...@@ -56,12 +56,8 @@ void configure(const std::string& file_name) { ...@@ -56,12 +56,8 @@ void configure(const std::string& file_name) {
// Read contents of the file and parse it as JSON // Read contents of the file and parse it as JSON
json = isc::data::Element::fromJSONFile(file_name, true); json = isc::data::Element::fromJSONFile(file_name, true);
if (!json) { if (!json) {
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL) isc_throw(isc::BadValue, "no configuration found");
.arg("Config file " + file_name + " missing or empty.");
isc_throw(isc::BadValue, "Unable to process JSON configuration"
" file: " << file_name);
} }
// Let's configure logging before applying the configuration, // Let's configure logging before applying the configuration,
...@@ -75,46 +71,37 @@ void configure(const std::string& file_name) { ...@@ -75,46 +71,37 @@ void configure(const std::string& file_name) {
// Get Dhcp4 component from the config // Get Dhcp4 component from the config
dhcp4 = json->get("Dhcp4"); dhcp4 = json->get("Dhcp4");
if (!dhcp4) { if (!dhcp4) {
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL) isc_throw(isc::BadValue, "no mandatory 'Dhcp4' entry in"
.arg("Config file " + file_name + " does not include 'Dhcp4'" " the configuration");
" entry.");
isc_throw(isc::BadValue, "Unable to process JSON configuration"
" file: " << file_name);
} }
// Use parsed JSON structures to configure the server // Use parsed JSON structures to configure the server
result = ControlledDhcpv4Srv::processCommand("config-reload", dhcp4); result = ControlledDhcpv4Srv::processCommand("config-reload", dhcp4);
if (!result) {
// Undetermined status of the configuration. This should never
// happen, but as the configureDhcp4Server returns a pointer, it is
// theoretically possible that it will return NULL.
isc_throw(isc::BadValue, "undefined result of "
"processCommand(\"config-reload\", dhcp4)");
}
} catch (const std::exception& ex) { // Now check is the returned result is successful (rcode=0) or not
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(ex.what()); // (see @ref isc::config::parseAnswer).
isc_throw(isc::BadValue, "Unable to process JSON configuration file: " int rcode;
<< file_name); isc::data::ConstElementPtr comment =
} isc::config::parseAnswer(rcode, result);
if (rcode != 0) {
string reason = comment ? comment->stringValue() :
"no details available";
isc_throw(isc::BadValue, reason);
}
if (!result) { } catch (const std::exception& ex) {
// Undetermined status of the configuration. This should never happen,
// but as the configureDhcp4Server returns a pointer, it is
// theoretically possible that it will return NULL.
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL) LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL)
.arg("Configuration failed: Undefined result of processCommand(" .arg(file_name).arg(ex.what());
"config-reload, " + file_name + ")"); isc_throw(isc::BadValue, "configuration error using file '"
isc_throw(isc::BadValue, "Configuration failed: Undefined result of " << file_name << "': " << ex.what());
"processCommand('config-reload', " << file_name << ")");
}
// Now check is the returned result is successful (rcode=0) or not
isc::data::ConstElementPtr comment; /// see @ref isc::config::parseAnswer
int rcode;
comment = isc::config::parseAnswer(rcode, result);
if (rcode != 0) {
string reason = "";
if (comment) {
reason = comment->stringValue();
}
LOG_ERROR(dhcp4_logger, DHCP4_CONFIG_LOAD_FAIL).arg(reason);
isc_throw(isc::BadValue, "Failed to apply configuration: " << reason);
} }
} }
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <dhcp/option_int.h> #include <dhcp/option_int.h>
#include <dhcp/docsis3_option_defs.h> #include <dhcp/docsis3_option_defs.h>
#include <dhcp/classify.h> #include <dhcp/classify.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcpsrv/subnet.h> #include <dhcpsrv/subnet.h>
#include <dhcpsrv/cfgmgr.h> #include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/testutils/config_result_check.h> #include <dhcpsrv/testutils/config_result_check.h>
...@@ -77,7 +78,6 @@ public: ...@@ -77,7 +78,6 @@ public:
// deal with sockets here, just check if configuration handling // deal with sockets here, just check if configuration handling
// is sane. // is sane.
srv_.reset(new Dhcpv4Srv(0)); srv_.reset(new Dhcpv4Srv(0));
CfgMgr::instance().deleteActiveIfaces();
// Create fresh context. // Create fresh context.
globalContext()->copyContext(ParserContext(Option::V4)); globalContext()->copyContext(ParserContext(Option::V4));
} }
...@@ -2895,6 +2895,8 @@ TEST_F(Dhcp4ParserTest, LibrariesSpecified) { ...@@ -2895,6 +2895,8 @@ TEST_F(Dhcp4ParserTest, LibrariesSpecified) {
// This test verifies that it is possible to select subset of interfaces // This test verifies that it is possible to select subset of interfaces
// on which server should listen. // on which server should listen.
TEST_F(Dhcp4ParserTest, selectedInterfaces) { TEST_F(Dhcp4ParserTest, selectedInterfaces) {
IfaceMgrTestConfig test_config(true);
ConstElementPtr x; ConstElementPtr x;
string config = "{ \"interfaces\": [ \"eth0\", \"eth1\" ]," string config = "{ \"interfaces\": [ \"eth0\", \"eth1\" ],"
"\"rebind-timer\": 2000, " "\"rebind-timer\": 2000, "
...@@ -2907,24 +2909,26 @@ TEST_F(Dhcp4ParserTest, selectedInterfaces) { ...@@ -2907,24 +2909,26 @@ TEST_F(Dhcp4ParserTest, selectedInterfaces) {
// Make sure the config manager is clean and there is no hanging // Make sure the config manager is clean and there is no hanging
// interface configuration. // interface configuration.
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth0")); EXPECT_FALSE(test_config.socketOpen("eth0", AF_INET));
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth1")); EXPECT_FALSE(test_config.socketOpen("eth1", AF_INET));
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth2"));
// Apply configuration. // Apply configuration.
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json)); EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status); ASSERT_TRUE(status);
checkResult(status, 0); checkResult(status, 0);
CfgMgr::instance().getConfiguration()->cfg_iface_.openSockets(10000);
// eth0 and eth1 were explicitly selected. eth2 was not. // eth0 and eth1 were explicitly selected. eth2 was not.
EXPECT_TRUE(CfgMgr::instance().isActiveIface("eth0")); EXPECT_TRUE(test_config.socketOpen("eth0", AF_INET));
EXPECT_TRUE(CfgMgr::instance().isActiveIface("eth1")); EXPECT_TRUE(test_config.socketOpen("eth1", AF_INET));
EXPECT_FALSE(CfgMgr::instance().isActiveIface("eth2"));
} }
// This test verifies that it is possible to configure the server in such a way // This test verifies that it is possible to configure the server in such a way
// that it listens on all interfaces. // that it listens on all interfaces.
TEST_F(Dhcp4ParserTest, allInterfaces) { TEST_F(Dhcp4ParserTest, allInterfaces) {
IfaceMgrTestConfig test_config(true);
ConstElementPtr x; ConstElementPtr x;
// This configuration specifies two interfaces on which server should listen // This configuration specifies two interfaces on which server should listen
// but it also includes asterisk. The asterisk switches server into the // but it also includes asterisk. The asterisk switches server into the
...@@ -2940,19 +2944,19 @@ TEST_F(Dhcp4ParserTest, allInterfaces) { ...@@ -2940,19 +2944,19 @@ TEST_F(Dhcp4ParserTest, allInterfaces) {
ConstElementPtr status; ConstElementPtr status;
// Make sure there is no old configuration. // Make sure there is no old configuration.
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth0")); ASSERT_FALSE(test_config.socketOpen("eth0", AF_INET));
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth1")); ASSERT_FALSE(test_config.socketOpen("eth1", AF_INET));
ASSERT_FALSE(CfgMgr::instance().isActiveIface("eth2"));
// Apply configuration. // Apply configuration.
EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json)); EXPECT_NO_THROW(status = configureDhcp4Server(*srv_, json));
ASSERT_TRUE(status); ASSERT_TRUE(status);
checkResult(status, 0); checkResult(status, 0);
CfgMgr::instance().getConfiguration()->cfg_iface_.openSockets(10000);
// All interfaces should be now active. // All interfaces should be now active.
EXPECT_TRUE(CfgMgr::instance().isActiveIface("eth0")); ASSERT_TRUE(test_config.socketOpen("eth0", AF_INET));
EXPECT_TRUE(CfgMgr::instance().isActiveIface("eth1")); ASSERT_TRUE(test_config.socketOpen("eth1", AF_INET));
EXPECT_TRUE(CfgMgr::instance().isActiveIface("eth2"));
} }
// This test checks the ability of the server to parse a configuration // This test checks the ability of the server to parse a configuration
......
...@@ -420,26 +420,6 @@ TEST_F(Dhcpv4SrvTest, basic) { ...@@ -420,26 +420,6 @@ TEST_F(Dhcpv4SrvTest, basic) {
ASSERT_NO_THROW(naked_srv.reset(new NakedDhcpv4Srv(0))); ASSERT_NO_THROW(naked_srv.reset(new NakedDhcpv4Srv(0)));
} }
// This test verifies that exception is not thrown when an error occurs during
// opening sockets. This test forces an error by adding a fictious interface
// to the IfaceMgr. An attempt to open socket on this interface must always
// fail. The DHCPv4 installs the error handler function to prevent exceptions
// being thrown from the openSockets4 function.
// @todo The server tests for socket should be extended but currently the
// ability to unit test the sockets code is somewhat limited.
TEST_F(Dhcpv4SrvTest, openActiveSockets) {
ASSERT_NO_THROW(CfgMgr::instance().activateAllIfaces());
Iface iface("bogusiface", 255);
iface.flag_loopback_ = false;
iface.flag_up_ = true;
iface.flag_running_ = true;
iface.inactive4_ = false;
iface.addAddress(IOAddress("192.0.0.0"));
IfaceMgr::instance().addInterface(iface);
ASSERT_NO_THROW(Dhcpv4Srv::openActiveSockets(DHCP4_SERVER_PORT, false));
}
// Verifies that DISCOVER message can be processed correctly, // Verifies that DISCOVER message can be processed correctly,
// that the OFFER message generated in response is valid and // that the OFFER message generated in response is valid and
// contains necessary options. // contains necessary options.
...@@ -2970,7 +2950,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) { ...@@ -2970,7 +2950,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
NakedDhcpv4Srv srv(0); NakedDhcpv4Srv srv(0);
ConstElementPtr x; ConstElementPtr x;
string config = "{ \"interfaces\": [ \"all\" ]," string config = "{ \"interfaces\": [ \"*\" ],"
"\"rebind-timer\": 2000, " "\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, " "\"renew-timer\": 1000, "
" \"option-data\": [ {" " \"option-data\": [ {"
...@@ -3055,7 +3035,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) { ...@@ -3055,7 +3035,7 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsORO) {
// src/lib/dhcp/docsis3_option_defs.h. // src/lib/dhcp/docsis3_option_defs.h.
TEST_F(Dhcpv4SrvTest, vendorOptionsDocsisDefinitions) { TEST_F(Dhcpv4SrvTest, vendorOptionsDocsisDefinitions) {
ConstElementPtr x; ConstElementPtr x;
string config_prefix = "{ \"interfaces\": [ \"all\" ]," string config_prefix = "{ \"interfaces\": [ \"*\" ],"
"\"rebind-timer\": 2000, " "\"rebind-timer\": 2000, "
"\"renew-timer\": 1000, " "\"renew-timer\": 1000, "
" \"option-data\": [ {" " \"option-data\": [ {"
......
...@@ -45,7 +45,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest() ...@@ -45,7 +45,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"), IOAddress("192.0.2.110"))); pool_ = Pool4Ptr(new Pool4(IOAddress("192.0.2.100"), IOAddress("192.0.2.110")));
subnet_->addPool(pool_); subnet_->addPool(pool_);
CfgMgr::instance().deleteActiveIfaces(); CfgMgr::instance().getConfiguration()->cfg_iface_.reset();
CfgMgr::instance().deleteSubnets4(); CfgMgr::instance().deleteSubnets4();
CfgMgr::instance().addSubnet4(subnet_); CfgMgr::instance().addSubnet4(subnet_);
...@@ -58,6 +58,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest() ...@@ -58,6 +58,7 @@ Dhcpv4SrvTest::Dhcpv4SrvTest()
Dhcpv4SrvTest::~Dhcpv4SrvTest() { Dhcpv4SrvTest::~Dhcpv4SrvTest() {
// Make sure that we revert to default value // Make sure that we revert to default value
CfgMgr::instance().getConfiguration()->cfg_iface_.reset();
CfgMgr::instance().echoClientId(true); CfgMgr::instance().echoClientId(true);
} }
......
...@@ -49,7 +49,7 @@ namespace { ...@@ -49,7 +49,7 @@ namespace {
/// - Quotes Servers option present: 192.0.2.202, 192.0.2.203. /// - Quotes Servers option present: 192.0.2.202, 192.0.2.203.
const char* DORA_CONFIGS[] = { const char* DORA_CONFIGS[] = {
// Configuration 0 // Configuration 0
"{ \"interfaces\": [ \"all\" ]," "{ \"interfaces\": [ \"*\" ],"
"\"valid-lifetime\": 600," "\"valid-lifetime\": 600,"
"\"subnet4\": [ { " "\"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\", " " \"subnet\": \"10.0.0.0/24\", "
...@@ -86,7 +86,7 @@ const char* DORA_CONFIGS[] = { ...@@ -86,7 +86,7 @@ const char* DORA_CONFIGS[] = {
"}", "}",
// Configuration 1 // Configuration 1
"{ \"interfaces\": [ \"all\" ]," "{ \"interfaces\": [ \"*\" ],"
"\"valid-lifetime\": 600," "\"valid-lifetime\": 600,"
"\"subnet4\": [ { " "\"subnet4\": [ { "
" \"subnet\": \"192.0.2.0/24\", " " \"subnet\": \"192.0.2.0/24\", "
......
...@@ -48,7 +48,7 @@ namespace { ...@@ -48,7 +48,7 @@ namespace {
/// - Quotes Servers option present: 192.0.2.202, 192.0.2.203. /// - Quotes Servers option present: 192.0.2.202, 192.0.2.203.
const char* INFORM_CONFIGS[] = { const char* INFORM_CONFIGS[] = {
// Configuration 0 // Configuration 0
"{ \"interfaces\": [ \"all\" ]," "{ \"interfaces\": [ \"*\" ],"
"\"valid-lifetime\": 600," "\"valid-lifetime\": 600,"
"\"subnet4\": [ { " "\"subnet4\": [ { "
" \"subnet\": \"10.0.0.0/24\", " " \"subnet\": \"10.0.0.0/24\", "
...@@ -85,7 +85,7 @@ const char* INFORM_CONFIGS[] = { ...@@ -85,7 +85,7 @@ const char* INFORM_CONFIGS[] = {
"}", "}",