Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
450
Issues
450
List
Boards
Labels
Service Desk
Milestones
Merge Requests
75
Merge Requests
75
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
Kea
Commits
650a6c1b
Commit
650a6c1b
authored
Oct 11, 2012
by
Tomek Mrugalski
🛰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2270] Configuration parser for DHCPv4
parent
0375b659
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
1319 additions
and
11 deletions
+1319
-11
src/bin/dhcp4/Makefile.am
src/bin/dhcp4/Makefile.am
+2
-0
src/bin/dhcp4/config_parser.cc
src/bin/dhcp4/config_parser.cc
+790
-0
src/bin/dhcp4/config_parser.h
src/bin/dhcp4/config_parser.h
+147
-0
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/ctrl_dhcp4_srv.cc
+22
-3
src/bin/dhcp4/dhcp4.spec
src/bin/dhcp4/dhcp4.spec
+78
-2
src/bin/dhcp4/dhcp4_messages.mes
src/bin/dhcp4/dhcp4_messages.mes
+20
-0
src/bin/dhcp4/tests/Makefile.am
src/bin/dhcp4/tests/Makefile.am
+3
-0
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp4/tests/config_parser_unittest.cc
+236
-0
src/lib/dhcp/cfgmgr.cc
src/lib/dhcp/cfgmgr.cc
+8
-0
src/lib/dhcp/cfgmgr.h
src/lib/dhcp/cfgmgr.h
+13
-6
No files found.
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": "
string
",
"item_type": "
list
",
"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?
void
deleteSubnets6
()
{
subnets6_
.
clear
();
}
void
deleteSubnets6
();