Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
650a6c1b
Commit
650a6c1b
authored
Oct 11, 2012
by
Tomek Mrugalski
🛰
Browse files
[2270] Configuration parser for DHCPv4
parent
0375b659
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/Makefile.am
View file @
650a6c1b
...
...
@@ -44,6 +44,7 @@ pkglibexec_PROGRAMS = b10-dhcp4
b10_dhcp4_SOURCES
=
main.cc
b10_dhcp4_SOURCES
+=
ctrl_dhcp4_srv.cc ctrl_dhcp4_srv.h
b10_dhcp4_SOURCES
+=
config_parser.cc config_parser.h
b10_dhcp4_SOURCES
+=
dhcp4_log.cc dhcp4_log.h
b10_dhcp4_SOURCES
+=
dhcp4_srv.cc dhcp4_srv.h
...
...
@@ -57,6 +58,7 @@ b10_dhcp4_CXXFLAGS = -Wno-unused-parameter
endif
b10_dhcp4_LDADD
=
$(top_builddir)
/src/lib/dhcp/libb10-dhcp++.la
b10_dhcp4_LDADD
+=
$(top_builddir)
/src/lib/dhcp/libb10-dhcpsrv.la
b10_dhcp4_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libb10-exceptions.la
b10_dhcp4_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libb10-asiolink.la
b10_dhcp4_LDADD
+=
$(top_builddir)
/src/lib/log/libb10-log.la
...
...
src/bin/dhcp4/config_parser.cc
0 → 100644
View file @
650a6c1b
This diff is collapsed.
Click to expand it.
src/bin/dhcp4/config_parser.h
0 → 100644
View file @
650a6c1b
// 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
<string>
#include
<exceptions/exceptions.h>
#include
<cc/data.h>
#ifndef DHCP4_CONFIG_PARSER_H
#define DHCP4_CONFIG_PARSER_H
namespace
isc
{
namespace
dhcp
{
class
Dhcpv4Srv
;
/// An exception that is thrown if an error occurs while configuring an
/// \c Dhcpv4Srv object.
class
Dhcp4ConfigError
:
public
isc
::
Exception
{
public:
/// @brief constructor
///
/// @param file name of the file, where exception occurred
/// @param line line of the file, where exception occurred
/// @param what text description of the issue that caused exception
Dhcp4ConfigError
(
const
char
*
file
,
size_t
line
,
const
char
*
what
)
:
isc
::
Exception
(
file
,
line
,
what
)
{}
};
class
DhcpConfigParser
{
///
/// \name Constructors and Destructor
///
/// Note: The copy constructor and the assignment operator are
/// intentionally defined as private to make it explicit that this is a
/// pure base class.
//@{
private:
DhcpConfigParser
(
const
DhcpConfigParser
&
source
);
DhcpConfigParser
&
operator
=
(
const
DhcpConfigParser
&
source
);
protected:
/// \brief The default constructor.
///
/// This is intentionally defined as \c protected as this base class should
/// never be instantiated (except as part of a derived class).
DhcpConfigParser
()
{}
public:
/// The destructor.
virtual
~
DhcpConfigParser
()
{}
//@}
/// \brief Prepare configuration value.
///
/// This method parses the "value part" of the configuration identifier
/// that corresponds to this derived class and prepares a new value to
/// apply to the server.
///
/// This method must validate the given value both in terms of syntax
/// and semantics of the configuration, so that the server will be
/// validly configured at the time of \c commit(). Note: the given
/// configuration value is normally syntactically validated, but the
/// \c build() implementation must also expect invalid input. If it
/// detects an error it may throw an exception of a derived class
/// of \c isc::Exception.
///
/// Preparing a configuration value will often require resource
/// allocation. If it fails, it may throw a corresponding standard
/// exception.
///
/// This method is not expected to be called more than once in the
/// life of the object. Although multiple calls are not prohibited
/// by the interface, the behavior is undefined.
///
/// \param config_value The configuration value for the identifier
/// corresponding to the derived class.
virtual
void
build
(
isc
::
data
::
ConstElementPtr
config_value
)
=
0
;
/// \brief Apply the prepared configuration value to the server.
///
/// This method is expected to be exception free, and, as a consequence,
/// it should normally not involve resource allocation.
/// Typically it would simply perform exception free assignment or swap
/// operation on the value prepared in \c build().
/// In some cases, however, it may be very difficult to meet this
/// condition in a realistic way, while the failure case should really
/// be very rare. In such a case it may throw, and, if the parser is
/// called via \c configureDhcp4Server(), the caller will convert the
/// exception as a fatal error.
///
/// This method is expected to be called after \c build(), and only once.
/// The result is undefined otherwise.
virtual
void
commit
()
=
0
;
};
/// @brief a pointer to configuration parser
typedef
boost
::
shared_ptr
<
DhcpConfigParser
>
ParserPtr
;
/// @brief a collection of parsers
///
/// This container is used to store pointer to parsers for a given scope.
typedef
std
::
vector
<
ParserPtr
>
ParserCollection
;
/// \brief Configure an \c Dhcpv4Srv object with a set of configuration values.
///
/// This function parses configuration information stored in \c config_set
/// and configures the \c server by applying the configuration to it.
/// It provides the strong exception guarantee as long as the underlying
/// derived class implementations of \c DhcpConfigParser meet the assumption,
/// that is, it ensures that either configuration is fully applied or the
/// state of the server is intact.
///
/// If a syntax or semantics level error happens during the configuration
/// (such as malformed configuration or invalid configuration parameter),
/// this function throws an exception of class \c Dhcp4ConfigError.
/// If the given configuration requires resource allocation and it fails,
/// a corresponding standard exception will be thrown.
/// Other exceptions may also be thrown, depending on the implementation of
/// the underlying derived class of \c Dhcp4ConfigError.
/// In any case the strong guarantee is provided as described above except
/// in the very rare cases where the \c commit() method of a parser throws
/// an exception. If that happens this function converts the exception
/// into a \c FatalError exception and rethrows it. This exception is
/// expected to be caught at the highest level of the application to terminate
/// the program gracefully.
///
/// \param server The \c Dhcpv4Srv object to be configured.
/// \param config_set A JSON style configuration to apply to \c server.
isc
::
data
::
ConstElementPtr
configureDhcp4Server
(
Dhcpv4Srv
&
server
,
isc
::
data
::
ConstElementPtr
config_set
);
};
// end of isc::dhcp namespace
};
// end of isc namespace
#endif // DHCP4_CONFIG_PARSER_H
src/bin/dhcp4/ctrl_dhcp4_srv.cc
View file @
650a6c1b
...
...
@@ -25,6 +25,7 @@
#include
<dhcp4/ctrl_dhcp4_srv.h>
#include
<dhcp4/dhcp4_log.h>
#include
<dhcp4/spec_config.h>
#include
<dhcp4/config_parser.h>
#include
<dhcp/iface_mgr.h>
#include
<exceptions/exceptions.h>
#include
<util/buffer.h>
...
...
@@ -47,8 +48,14 @@ ConstElementPtr
ControlledDhcpv4Srv
::
dhcp4ConfigHandler
(
ConstElementPtr
new_config
)
{
LOG_DEBUG
(
dhcp4_logger
,
DBG_DHCP4_COMMAND
,
DHCP4_CONFIG_UPDATE
)
.
arg
(
new_config
->
str
());
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
0
,
"Thank you for sending config."
);
if
(
server_
)
{
return
(
configureDhcp4Server
(
*
server_
,
new_config
));
}
// That should never happen as we install config_handler after we instantiate
// the server.
ConstElementPtr
answer
=
isc
::
config
::
createAnswer
(
1
,
"Configuration rejected, server is during startup/shutdown phase."
);
return
(
answer
);
}
...
...
@@ -101,10 +108,22 @@ void ControlledDhcpv4Srv::establishSession() {
.
arg
(
specfile
);
cc_session_
=
new
Session
(
io_service_
.
get_io_service
());
config_session_
=
new
ModuleCCSession
(
specfile
,
*
cc_session_
,
dhcp4ConfigHandler
,
NULL
,
dhcp4CommandHandler
,
false
);
config_session_
->
start
();
// We initially create ModuleCCSession() without configHandler, as
// the session module is too eager to send partial configuration.
// We want to get the full configuration, so we explicitly call
// getFullConfig() and then pass it to our configHandler.
config_session_
->
setConfigHandler
(
dhcp4ConfigHandler
);
try
{
configureDhcp4Server
(
*
this
,
config_session_
->
getFullConfig
());
}
catch
(
const
Dhcp4ConfigError
&
ex
)
{
LOG_ERROR
(
dhcp4_logger
,
DHCP4_CONFIG_LOAD_FAIL
).
arg
(
ex
.
what
());
}
/// 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 dhcpv4Session.
...
...
src/bin/dhcp4/dhcp4.spec
View file @
650a6c1b
...
...
@@ -4,9 +4,85 @@
"module_description": "DHCPv4 server daemon",
"config_data": [
{ "item_name": "interface",
"item_type": "st
ring
",
"item_type": "
li
st",
"item_optional": false,
"item_default": "eth0"
"item_default": [ "all" ],
"list_item_spec":
{
"item_name": "interface_name",
"item_type": "string",
"item_optional": false,
"item_default": "all"
}
} ,
{ "item_name": "renew-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 1000
},
{ "item_name": "rebind-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 2000
},
{ "item_name": "valid-lifetime",
"item_type": "integer",
"item_optional": false,
"item_default": 4000
},
{ "item_name": "subnet4",
"item_type": "list",
"item_optional": false,
"item_default": [],
"list_item_spec":
{
"item_name": "single-subnet4",
"item_type": "map",
"item_optional": false,
"item_default": {},
"map_item_spec": [
{ "item_name": "subnet",
"item_type": "string",
"item_optional": false,
"item_default": ""
},
{ "item_name": "renew-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 1000
},
{ "item_name": "rebind-timer",
"item_type": "integer",
"item_optional": false,
"item_default": 2000
},
{ "item_name": "valid-lifetime",
"item_type": "integer",
"item_optional": false,
"item_default": 7200
},
{ "item_name": "pool",
"item_type": "list",
"item_optional": false,
"item_default": [],
"list_item_spec":
{
"item_name": "type",
"item_type": "string",
"item_optional": false,
"item_default": ""
}
}
]
}
}
],
"commands": [
...
...
src/bin/dhcp4/dhcp4_messages.mes
View file @
650a6c1b
...
...
@@ -26,10 +26,30 @@ to establish a session with the BIND 10 control channel.
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
% DHCP4_CONFIG_LOAD_FAIL failed to load configuration: %1
This critical error message indicates that the initial DHCPv4
configuration has failed. The server will start, but nothing will be
served until the configuration has been corrected.
% DHCP4_CONFIG_UPDATE updated configuration received: %1
A debug message indicating that the IPv4 DHCP server has received an
updated configuration from the BIND 10 configuration system.
% DHCP4_CONFIG_START DHCPv4 server is processing the following configuration: %1
This is a debug message that is issued every time the server receives a
configuration. That happens start up and also when a server configuration
change is committed by the administrator.
% DHCP4_CONFIG_NEW_SUBNET A new subnet has been added to configuration: %1
This is an informational message reporting that the configuration has
been extended to include the specified IPv4 subnet.
% DHCP4_CONFIG_COMPLETE DHCPv4 server has completed configuration: %1
This is an informational message announcing the successful processing of a
new configuration. it is output during server startup, and when an updated
configuration is committed by the administrator. Additional information
may be provided.
% DHCP4_NOT_RUNNING IPv4 DHCP server is not running
A warning message is issued when an attempt is made to shut down the
IPv4 DHCP server but it is not running.
...
...
src/bin/dhcp4/tests/Makefile.am
View file @
650a6c1b
...
...
@@ -49,9 +49,11 @@ TESTS += dhcp4_unittests
dhcp4_unittests_SOURCES
=
../dhcp4_srv.h ../dhcp4_srv.cc ../ctrl_dhcp4_srv.cc
dhcp4_unittests_SOURCES
+=
../dhcp4_log.h ../dhcp4_log.cc
dhcp4_unittests_SOURCES
+=
../config_parser.cc ../config_parser.h
dhcp4_unittests_SOURCES
+=
dhcp4_unittests.cc
dhcp4_unittests_SOURCES
+=
dhcp4_srv_unittest.cc
dhcp4_unittests_SOURCES
+=
ctrl_dhcp4_srv_unittest.cc
dhcp4_unittests_SOURCES
+=
config_parser_unittest.cc
nodist_dhcp4_unittests_SOURCES
=
../dhcp4_messages.h ../dhcp4_messages.cc
if
USE_CLANGPP
...
...
@@ -65,6 +67,7 @@ dhcp4_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS)
dhcp4_unittests_LDADD
=
$(GTEST_LDADD)
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libb10-asiolink.la
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcp/libb10-dhcp++.la
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/dhcp/libb10-dhcpsrv.la
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/exceptions/libb10-exceptions.la
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/log/libb10-log.la
dhcp4_unittests_LDADD
+=
$(top_builddir)
/src/lib/asiolink/libb10-asiolink.la
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
0 → 100644
View file @
650a6c1b
// 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
<iostream>
#include
<fstream>
#include
<sstream>
#include
<arpa/inet.h>
#include
<gtest/gtest.h>
#include
<dhcp4/dhcp4_srv.h>
#include
<dhcp4/config_parser.h>
#include
<config/ccsession.h>
#include
<dhcp/subnet.h>
#include
<dhcp/cfgmgr.h>
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
data
;
using
namespace
isc
::
config
;
namespace
{
class
Dhcp4ParserTest
:
public
::
testing
::
Test
{
public:
Dhcp4ParserTest
()
:
rcode_
(
-
1
)
{
// Open port 0 means to not do anything at all. We don't want to
// deal with sockets here, just check if configuration handling
// is sane.
srv_
=
new
Dhcpv4Srv
(
0
);
}
~
Dhcp4ParserTest
()
{
delete
srv_
;
};
Dhcpv4Srv
*
srv_
;
int
rcode_
;
ConstElementPtr
comment_
;
};
// Goal of this test is a verification if a very simple config update
// with just a bumped version number. That's the simplest possible
// config update.
TEST_F
(
Dhcp4ParserTest
,
version
)
{
ConstElementPtr
x
;
EXPECT_NO_THROW
(
x
=
configureDhcp4Server
(
*
srv_
,
Element
::
fromJSON
(
"{
\"
version
\"
: 0}"
)));
// returned value must be 0 (configuration accepted)
ASSERT_TRUE
(
x
);
comment_
=
parseAnswer
(
rcode_
,
x
);
EXPECT_EQ
(
0
,
rcode_
);
}
/// The goal of this test is to verify that the code accepts only
/// valid commands and malformed or unsupported parameters are rejected.
TEST_F
(
Dhcp4ParserTest
,
bogus_command
)
{
ConstElementPtr
x
;
EXPECT_NO_THROW
(
x
=
configureDhcp4Server
(
*
srv_
,
Element
::
fromJSON
(
"{
\"
bogus
\"
: 5}"
)));
// returned value must be 1 (configuration parse error)
ASSERT_TRUE
(
x
);
comment_
=
parseAnswer
(
rcode_
,
x
);
EXPECT_EQ
(
1
,
rcode_
);
}
/// The goal of this test is to verify if wrongly defined subnet will
/// be rejected. Properly defined subnet must include at least one
/// pool definition.
TEST_F
(
Dhcp4ParserTest
,
empty_subnet
)
{
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
Element
::
fromJSON
(
"{
\"
interface
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet4
\"
: [ ], "
"
\"
valid-lifetime
\"
: 4000 }"
)));
// returned value should be 0 (success)
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
0
,
rcode_
);
}
/// The goal of this test is to verify if defined subnet uses global
/// parameter timer definitions.
TEST_F
(
Dhcp4ParserTest
,
subnet_global_defaults
)
{
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.2.1 - 192.0.2.100
\"
],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ],"
"
\"
valid-lifetime
\"
: 4000 }"
;
cout
<<
config
<<
endl
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
// check if returned status is OK
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
0
,
rcode_
);
// Now check if the configuration was indeed handled and we have
// expected pool configured.
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.200"
));
ASSERT_TRUE
(
subnet
);
EXPECT_EQ
(
1000
,
subnet
->
getT1
());
EXPECT_EQ
(
2000
,
subnet
->
getT2
());
EXPECT_EQ
(
4000
,
subnet
->
getValid
());
}
// This test checks if it is possible to override global values
// on a per subnet basis.
TEST_F
(
Dhcp4ParserTest
,
subnet_local
)
{
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.2.1 - 192.0.2.100
\"
],"
"
\"
renew-timer
\"
: 1, "
"
\"
rebind-timer
\"
: 2, "
"
\"
valid-lifetime
\"
: 4,"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ],"
"
\"
valid-lifetime
\"
: 4000 }"
;
cout
<<
config
<<
endl
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
// returned value should be 0 (configuration success)
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
0
,
rcode_
);
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.200"
));
ASSERT_TRUE
(
subnet
);
EXPECT_EQ
(
1
,
subnet
->
getT1
());
EXPECT_EQ
(
2
,
subnet
->
getT2
());
EXPECT_EQ
(
4
,
subnet
->
getValid
());
}
// Test verifies that a subnet with pool values that do not belong to that
// pool are rejected.
TEST_F
(
Dhcp4ParserTest
,
pool_out_of_subnet
)
{
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.4.0/28
\"
],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ],"
"
\"
valid-lifetime
\"
: 4000 }"
;
cout
<<
config
<<
endl
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
// returned value must be 2 (values error)
// as the pool does not belong to that subnet
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
2
,
rcode_
);
}
// Goal of this test is to verify if pools can be defined
// using prefix/length notation. There is no separate test for min-max
// notation as it was tested in several previous tests.
TEST_F
(
Dhcp4ParserTest
,
pool_prefix_len
)
{
ConstElementPtr
x
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.2.128/28
\"
],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
} ],"
"
\"
valid-lifetime
\"
: 4000 }"
;
cout
<<
config
<<
endl
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
x
=
configureDhcp4Server
(
*
srv_
,
json
));
// returned value must be 1 (configuration parse error)
ASSERT_TRUE
(
x
);
comment_
=
parseAnswer
(
rcode_
,
x
);
EXPECT_EQ
(
0
,
rcode_
);
Subnet4Ptr
subnet
=
CfgMgr
::
instance
().
getSubnet4
(
IOAddress
(
"192.0.2.200"
));
ASSERT_TRUE
(
subnet
);
EXPECT_EQ
(
1000
,
subnet
->
getT1
());
EXPECT_EQ
(
2000
,
subnet
->
getT2
());
EXPECT_EQ
(
4000
,
subnet
->
getValid
());
}
};
src/lib/dhcp/cfgmgr.cc
View file @
650a6c1b
...
...
@@ -101,6 +101,14 @@ void CfgMgr::addSubnet4(const Subnet4Ptr& subnet) {
subnets4_
.
push_back
(
subnet
);
}
void
CfgMgr
::
deleteSubnets4
()
{
subnets4_
.
clear
();
}
void
CfgMgr
::
deleteSubnets6
()
{
subnets6_
.
clear
();
}
CfgMgr
::
CfgMgr
()
{
}
...
...
src/lib/dhcp/cfgmgr.h
View file @
650a6c1b
...
...
@@ -99,9 +99,9 @@ public:
/// needed is a dynamic server reconfiguration - a use case that is not
/// planned to be supported any time soon.
/// @brief removes all subnets
/// @brief removes all
IPv6
subnets
///
/// This method removes all existing subnets. It is used during
/// This method removes all existing
IPv6
subnets. It is used during
/// reconfiguration - old configuration is wiped and new definitions
/// are used to recreate subnets.
///
...
...
@@ -109,9 +109,7 @@ public:
/// between old and new configuration is tricky. For example: is
/// 2000::/64 and 2000::/48 the same subnet or is it something
/// completely new?
<