Commit 199af97d authored by Mukund Sivaraman's avatar Mukund Sivaraman
Browse files

Merge branch 'master' into trac2164

parents d8e429d6 76f73392
......@@ -35,3 +35,4 @@ TAGS
/coverage-cpp-html
/dns++.pc
/report.info
/logger_lockfile
459. [func] tomek
b10-dhcp6: DHCPv6 server component is now integrated into
BIND10 framework. It can be started from BIND10 (using bindctl)
and can receive commands. The only supported command for now
is 'Dhcp6 shutdown'.
b10-dhcp4: Command line-switch '-s' to disable msgq was added.
b10-dhcp6: Command line-switch '-s' to disable msgq was added.
(Trac #1708, git e0d7c52a71414f4de1361b09d3c70431c96daa3f)
458. [build]* jinmei
BIND 10 now relies on Boost offset_ptr, which caused some new
portability issues. Such issues are detected at ./configure time.
......
......@@ -72,11 +72,13 @@
* DHCPv6 server component does not support relayed traffic yet, as
* support for relay decapsulation is not implemented yet.
*
* DHCPv6 server component does not listen to BIND10 message queue.
*
* DHCPv6 server component does not use BIND10 logging yet.
*
* DHCPv6 server component is not integrated with boss yet.
* @section dhcpv6Session BIND10 message queue integration
*
* DHCPv4 server component is now integrated with BIND10 message queue.
* It follows the same principle as DHCPv4. See \ref dhcpv4Session for
* details.
*
* @page libdhcp libdhcp++
*
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20120712. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="idp98160"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>BIND 10 Messages Manual</title><link rel="stylesheet" href="./bind10-guide.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.75.2"><meta name="description" content="BIND 10 is a Domain Name System (DNS) suite managed by Internet Systems Consortium (ISC). It includes DNS libraries and modular components for controlling authoritative and recursive DNS servers. This is the messages manual for BIND 10 version 20120712. The most up-to-date version of this document, along with other documents for BIND 10, can be found at ."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="BIND 10 Messages Manual"><div class="titlepage"><div><div><h1 class="title"><a name="idp74800"></a>BIND 10 Messages Manual</h1></div><div><p class="releaseinfo">This is the messages manual for BIND 10 version
20120712.</p></div><div><p class="copyright">Copyright © 2011-2012 Internet Systems Consortium, Inc.</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a Domain Name System (DNS) suite managed by
Internet Systems Consortium (ISC). It includes DNS libraries
and modular components for controlling authoritative and
......
......@@ -26,8 +26,9 @@ b10-cfgmgr: b10-cfgmgr.py
install-data-local:
$(mkinstalldirs) $(DESTDIR)/@localstatedir@/@PACKAGE@
# TODO: permissions handled later
install-data-hook:
-chmod 2770 $(DESTDIR)/@localstatedir@/@PACKAGE@
CLEANDIRS = __pycache__
......
......@@ -12,8 +12,8 @@
"item_type": "map",
"item_optional": true,
"item_default": {
"origin": "",
"class": "IN",
"origin": "",
"class": "IN",
"update_acl": []
},
"map_item_spec": [
......@@ -33,11 +33,12 @@
"item_name": "update_acl",
"item_type": "list",
"item_optional": false,
"item_default": [],
"item_default": [],
"list_item_spec": {
"item_name": "acl_element",
"item_type": "any",
"item_optional": true
"item_optional": true,
"item_default": {"action": "REJECT"}
}
}
]
......
......@@ -86,7 +86,7 @@ void ControlledDhcpv4Srv::establishSession() {
string specfile;
if (getenv("B10_FROM_BUILD")) {
specfile = string(getenv("B10_FROM_BUILD")) +
"/src/bin/auth/dhcp4.spec";
"/src/bin/dhcp4/dhcp4.spec";
} else {
specfile = string(DHCP4_SPECFILE_LOCATION);
}
......
......@@ -37,16 +37,21 @@ const std::string HARDCODED_SERVER_ID = "192.0.2.1";
Dhcpv4Srv::Dhcpv4Srv(uint16_t port) {
cout << "Initialization: opening sockets on port " << port << endl;
// first call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
IfaceMgr::instance();
try {
// first call to instance() will create IfaceMgr (it's a singleton)
// it may throw something if things go wrong
IfaceMgr::instance();
/// @todo: instantiate LeaseMgr here once it is imlpemented.
IfaceMgr::instance().printIfaces();
/// @todo: instantiate LeaseMgr here once it is imlpemented.
IfaceMgr::instance().openSockets4(port);
IfaceMgr::instance().openSockets4(port);
setServerID();
setServerID();
} catch (const std::exception &e) {
cerr << "Error during DHCPv4 server startup: " << e.what() << endl;
shutdown_ = true;
return;
}
shutdown_ = false;
}
......
......@@ -14,18 +14,14 @@
#include <config.h>
#include <iostream>
#include <exceptions/exceptions.h>
#include <log/dummylog.h>
#include <log/logger_support.h>
#include <dhcp4/ctrl_dhcp4_srv.h>
#include <dhcp4/dhcp4_srv.h>
#include <dhcp/dhcp4.h>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace isc::dhcp;
/// This file contains entry point (main() function) for standard DHCPv4 server
/// component for BIND10 framework. It parses command-line arguments and
/// instantiates ControlledDhcpv4Srv class that is responsible for establishing
......@@ -44,7 +40,9 @@ usage() {
cerr << "Usage: b10-dhcp4 [-v]"
<< endl;
cerr << "\t-v: verbose output" << endl;
cerr << "\t-p number: specify non-standard port number 1-65535 (useful for testing only)" << endl;
cerr << "\t-s: stand-alone mode (don't connect to BIND10)" << endl;
cerr << "\t-p number: specify non-standard port number 1-65535 "
<< "(useful for testing only)" << endl;
exit(EXIT_FAILURE);
}
} // end of anonymous namespace
......@@ -55,16 +53,26 @@ main(int argc, char* argv[]) {
bool verbose_mode = false; // should server be verbose?
int port_number = DHCP4_SERVER_PORT; // The default. any other values are
// useful for testing only.
bool stand_alone = false; // should be connect to BIND10 msgq?
while ((ch = getopt(argc, argv, "vp:")) != -1) {
while ((ch = getopt(argc, argv, "vsp:")) != -1) {
switch (ch) {
case 'v':
verbose_mode = true;
isc::log::denabled = true;
break;
case 's':
stand_alone = true;
break;
case 'p':
port_number = strtol(optarg, NULL, 10);
if (port_number == 0) {
try {
port_number = boost::lexical_cast<int>(optarg);
} catch (const boost::bad_lexical_cast &) {
cerr << "Failed to parse port number: [" << optarg
<< "], 1-65535 allowed." << endl;
usage();
}
if (port_number <= 0 || port_number > 65535) {
cerr << "Failed to parse port number: [" << optarg
<< "], 1-65535 allowed." << endl;
usage();
......@@ -82,7 +90,8 @@ main(int argc, char* argv[]) {
isc::log::MAX_DEBUG_LEVEL, NULL);
cout << "b10-dhcp4: My pid=" << getpid() << ", binding to port "
<< port_number << ", verbose " << (verbose_mode?"yes":"no") << endl;
<< port_number << ", verbose " << (verbose_mode?"yes":"no")
<< ", stand-alone=" << (stand_alone?"yes":"no") << endl;
if (argc - optind > 0) {
usage();
......@@ -94,11 +103,23 @@ main(int argc, char* argv[]) {
cout << "[b10-dhcp4] Initiating DHCPv4 server operation." << endl;
ControlledDhcpv4Srv* server = new ControlledDhcpv4Srv(port_number);
server->run();
delete server;
server = NULL;
/// @todo: pass verbose to the actul server once logging is implemented
ControlledDhcpv4Srv server(port_number);
if (!stand_alone) {
try {
server.establishSession();
} catch (const std::exception& ex) {
cerr << "Failed to establish BIND10 session. "
"Running in stand-alone mode:" << ex.what() << endl;
// Let's continue. It is useful to have the ability to run
// DHCP server in stand-alone mode, e.g. for testing
}
} else {
cout << "Skipping connection to the BIND10 msgq." << endl;
}
server.run();
} catch (const std::exception& ex) {
cerr << "[b10-dhcp4] Server failed: " << ex.what() << endl;
ret = EXIT_FAILURE;
......
// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012 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
......@@ -64,7 +64,7 @@ TEST_F(CtrlDhcpv4SrvTest, commands) {
ConstElementPtr comment = parseAnswer(rcode, result);
EXPECT_EQ(1, rcode); // expect failure (no such command as blah)
// case 1: send shutdown command without any parameters
// case 2: send shutdown command without any parameters
result = ControlledDhcpv4Srv::execDhcpv4ServerCommand("shutdown", params);
comment = parseAnswer(rcode, result);
EXPECT_EQ(0, rcode); // expect success
......@@ -73,7 +73,7 @@ TEST_F(CtrlDhcpv4SrvTest, commands) {
ConstElementPtr x(new isc::data::IntElement(pid));
params->set("pid", x);
// case 2: send shutdown command with 1 parameter: pid
// case 3: send shutdown command with 1 parameter: pid
result = ControlledDhcpv4Srv::execDhcpv4ServerCommand("shutdown", params);
comment = parseAnswer(rcode, result);
EXPECT_EQ(0, rcode); // expect success
......
......@@ -34,7 +34,7 @@ class TestDhcpv4Daemon(unittest.TestCase):
def tearDown(self):
pass
def runDhcp4(self, params, wait=1):
def runCommand(self, params, wait=1):
"""
This method runs dhcp4 and returns a touple: (returncode, stdout, stderr)
"""
......@@ -127,14 +127,14 @@ class TestDhcpv4Daemon(unittest.TestCase):
print("Note: Purpose of some of the tests is to check if DHCPv4 server can be started,")
print(" not that is can bind sockets correctly. Please ignore binding errors.")
(returncode, output, error) = self.runDhcp4(["../b10-dhcp4", "-v"])
(returncode, output, error) = self.runCommand(["../b10-dhcp4", "-v"])
self.assertEqual( str(output).count("[b10-dhcp4] Initiating DHCPv4 server operation."), 1)
def test_portnumber_0(self):
print("Check that specifying port number 0 is not allowed.")
(returncode, output, error) = self.runDhcp4(['../b10-dhcp4', '-p', '0'])
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-p', '0'])
# When invalid port number is specified, return code must not be success
self.assertTrue(returncode != 0)
......@@ -145,7 +145,7 @@ class TestDhcpv4Daemon(unittest.TestCase):
def test_portnumber_missing(self):
print("Check that -p option requires a parameter.")
(returncode, output, error) = self.runDhcp4(['../b10-dhcp4', '-p'])
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-p'])
# When invalid port number is specified, return code must not be success
self.assertTrue(returncode != 0)
......@@ -153,10 +153,32 @@ class TestDhcpv4Daemon(unittest.TestCase):
# Check that there is an error message about invalid port number printed on stderr
self.assertEqual( str(error).count("option requires an argument"), 1)
def test_portnumber_invalid1(self):
print("Check that -p option is check against bogus port number (999999).")
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-p','999999'])
# When invalid port number is specified, return code must not be success
self.assertTrue(returncode != 0)
# Check that there is an error message about invalid port number printed on stderr
self.assertEqual( str(error).count("Failed to parse port number"), 1)
def test_portnumber_invalid2(self):
print("Check that -p option is check against bogus port number (123garbage).")
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-p','123garbage'])
# When invalid port number is specified, return code must not be success
self.assertTrue(returncode != 0)
# Check that there is an error message about invalid port number printed on stderr
self.assertEqual( str(error).count("Failed to parse port number"), 1)
def test_portnumber_nonroot(self):
print("Check that specifying unprivileged port number will work.")
(returncode, output, error) = self.runDhcp4(['../b10-dhcp4', '-p', '10057'])
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-s', '-p', '10057'])
# When invalid port number is specified, return code must not be success
# TODO: Temporarily commented out as socket binding on systems that do not have
......@@ -166,5 +188,18 @@ class TestDhcpv4Daemon(unittest.TestCase):
# Check that there is an error message about invalid port number printed on stderr
self.assertEqual( str(output).count("opening sockets on port 10057"), 1)
def test_skip_msgq(self):
print("Check that connection to BIND10 msgq can be disabled.")
(returncode, output, error) = self.runCommand(['../b10-dhcp4', '-s', '-p', '10057'])
# When invalid port number is specified, return code must not be success
# TODO: Temporarily commented out as socket binding on systems that do not have
# interface detection implemented currently fails.
# self.assertTrue(returncode == 0)
# Check that there is an error message about invalid port number printed on stderr
self.assertEqual( str(output).count("Skipping connection to the BIND10 msgq."), 1)
if __name__ == '__main__':
unittest.main()
......@@ -33,6 +33,7 @@ BUILT_SOURCES = spec_config.h
pkglibexec_PROGRAMS = b10-dhcp6
b10_dhcp6_SOURCES = main.cc dhcp6_srv.cc dhcp6_srv.h
b10_dhcp6_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
if USE_CLANGPP
# Disable unused parameter warning caused by some of the
......@@ -44,6 +45,8 @@ b10_dhcp6_LDADD = $(top_builddir)/src/lib/exceptions/libb10-exceptions.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/log/libb10-log.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la
b10_dhcp6_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la
b10_dhcp6dir = $(pkgdatadir)
b10_dhcp6_DATA = dhcp6.spec
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <config.h>
#include <cassert>
#include <iostream>
#include <cc/session.h>
#include <cc/data.h>
#include <exceptions/exceptions.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <util/buffer.h>
#include <dhcp6/spec_config.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp/iface_mgr.h>
#include <asiolink/asiolink.h>
using namespace std;
using namespace isc::util;
using namespace isc::dhcp;
using namespace isc::util;
using namespace isc::data;
using namespace isc::cc;
using namespace isc::config;
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
ControlledDhcpv6Srv* ControlledDhcpv6Srv::server_ = NULL;
ConstElementPtr
ControlledDhcpv6Srv::dhcp6ConfigHandler(ConstElementPtr new_config) {
cout << "b10-dhcp6: Received new config:" << new_config->str() << endl;
ConstElementPtr answer = isc::config::createAnswer(0,
"Thank you for sending config.");
return (answer);
}
ConstElementPtr
ControlledDhcpv6Srv::dhcp6CommandHandler(const string& command, ConstElementPtr args) {
cout << "b10-dhcp6: Received new command: [" << command << "], args="
<< args->str() << endl;
if (command == "shutdown") {
if (ControlledDhcpv6Srv::server_) {
ControlledDhcpv6Srv::server_->shutdown();
} else {
cout << "Server not initialized yet or already shut down." << endl;
ConstElementPtr answer = isc::config::createAnswer(1,
"Shutdown failure.");
return (answer);
}
ConstElementPtr answer = isc::config::createAnswer(0,
"Shutting down.");
return (answer);
}
ConstElementPtr answer = isc::config::createAnswer(1,
"Unrecognized command.");
return (answer);
}
void ControlledDhcpv6Srv::sessionReader(void) {
// Process one asio event. If there are more events, iface_mgr will call
// this callback more than once.
if (server_) {
server_->io_service_.run_one();
}
}
void ControlledDhcpv6Srv::establishSession() {
string specfile;
if (getenv("B10_FROM_BUILD")) {
specfile = string(getenv("B10_FROM_BUILD")) +
"/src/bin/dhcp6/dhcp6.spec";
} else {
specfile = string(DHCP6_SPECFILE_LOCATION);
}
/// @todo: Check if session is not established already. Throw, if it is.
cout << "b10-dhcp6: my specfile is " << specfile << endl;
cc_session_ = new Session(io_service_.get_io_service());
config_session_ = new ModuleCCSession(specfile, *cc_session_,
dhcp6ConfigHandler,
dhcp6CommandHandler, false);
config_session_->start();
/// Integrate the asynchronous I/O model of BIND 10 configuration
/// control with the "select" model of the DHCP server. This is
/// fully explained in \ref dhcpv6Session.
int ctrl_socket = cc_session_->getSocketDesc();
cout << "b10-dhcp6: Control session started, socket="
<< ctrl_socket << endl;
IfaceMgr::instance().set_session_socket(ctrl_socket, sessionReader);
}
void ControlledDhcpv6Srv::disconnectSession() {
if (config_session_) {
delete config_session_;
config_session_ = NULL;
}
if (cc_session_) {
cc_session_->disconnect();
delete cc_session_;
cc_session_ = NULL;
}
// deregister session socket
IfaceMgr::instance().set_session_socket(IfaceMgr::INVALID_SOCKET, NULL);
}
ControlledDhcpv6Srv::ControlledDhcpv6Srv(uint16_t port /*= DHCP6_SERVER_PORT*/)
:Dhcpv6Srv(port), cc_session_(NULL), config_session_(NULL) {
server_ = this; // remember this instance for use in callback
}
void ControlledDhcpv6Srv::shutdown() {
io_service_.stop(); // Stop ASIO transmissions
Dhcpv6Srv::shutdown(); // Initiate DHCPv6 shutdown procedure.
}
ControlledDhcpv6Srv::~ControlledDhcpv6Srv() {
disconnectSession();
server_ = NULL; // forget this instance. There should be no callback anymore
// at this stage anyway.
}
isc::data::ConstElementPtr
ControlledDhcpv6Srv::execDhcpv6ServerCommand(const std::string& command_id,
isc::data::ConstElementPtr args) {
try {
return (dhcp6CommandHandler(command_id, args));
} catch (const Exception& ex) {
ConstElementPtr answer = isc::config::createAnswer(1, ex.what());
return (answer);
}
}
};
};
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef CTRL_DHCPV6_SRV_H
#define CTRL_DHCPV6_SRV_H
#include <dhcp6/dhcp6_srv.h>
#include <asiolink/asiolink.h>
#include <cc/session.h>
#include <config/ccsession.h>
#include <cc/data.h>
namespace isc {
namespace dhcp {
/// @brief Controlled version of the DHCPv6 server
///
/// This is a class that is responsible for establishing connection
/// with msqg (receving commands and configuration). This is an extended
/// version of Dhcpv6Srv class that is purely a DHCPv6 server, without
/// external control. ControlledDhcpv6Srv should be used in typical BIND10
/// (i.e. featuring msgq) environment, while Dhcpv6Srv should be used in
/// embedded environments.
///
/// For detailed explanation or relations between main(), ControlledDhcpv6Srv,
/// Dhcpv6Srv and other classes, see \ref dhcpv6Session.
class ControlledDhcpv6Srv : public isc::dhcp::Dhcpv6Srv {
public:
/// @brief Constructor
///
/// @param port UDP port to be opened for DHCP traffic
ControlledDhcpv6Srv(uint16_t port = DHCP6_SERVER_PORT);
/// @brief Destructor.
~ControlledDhcpv6Srv();
/// @brief Establishes msgq session.
///
/// Creates session that will be used to receive commands and updated
/// configuration from boss (or indirectly from user via bindctl).
void establishSession();
/// @brief Terminates existing msgq session.
///
/// This method terminates existing session with msgq. After calling
/// it, no further messages over msgq (commands or configuration updates)
/// may be received.
///
/// It is ok to call this method when session is disconnected already.
void disconnectSession();
/// @brief Initiates shutdown procedure for the whole DHCPv6 server.
void shutdown();
/// @brief Session callback, processes received commands.
///
/// @param command_id text represenation of the command (e.g. "shutdown")
/// @param args optional parameters
///
/// @return status of the command
static isc::data::ConstElementPtr
execDhcpv6ServerCommand(const std::string& command,
isc::data::ConstElementPtr args);
protected:
/// @brief Static pointer to the sole instance of the DHCP server.
///
/// This is required for config and command handlers to gain access to
/// the server
static ControlledDhcpv6Srv* server_;
/// @brief A callback for handling incoming configuration updates.
///
/// As pointer to this method is used a callback in ASIO used in
/// ModuleCCSession, it has to be static.
///
/// @param new_config textual representation of the new configuration
///
/// @return status of the config update
static isc::data::ConstElementPtr
dhcp6ConfigHandler(isc::data::ConstElementPtr new_config);
/// @brief A callback for handling incoming commands.
///
/// @param command textual representation of the command
/// @param args parameters of the command
///
/// @return status of the processed command
static isc::data::ConstElementPtr
dhcp6CommandHandler(const std::string& command, isc::data::ConstElementPtr args);
/// @brief Callback that will be called from iface_mgr when command/config arrives.
///