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
339d60a7
Commit
339d60a7
authored
Jul 11, 2013
by
Marcin Siodelski
Browse files
[1555] Implemented configuration parameter to select interfaces for DHCPv6.
parent
ffdc326d
Changes
3
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/config_parser.cc
View file @
339d60a7
...
...
@@ -413,7 +413,7 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id) {
(
config_id
.
compare
(
"rebind-timer"
)
==
0
))
{
parser
=
new
Uint32Parser
(
config_id
,
globalContext
()
->
uint32_values_
);
}
else
if
(
config_id
.
compare
(
"interface"
)
==
0
)
{
}
else
if
(
config_id
.
compare
(
"interface
s
"
)
==
0
)
{
parser
=
new
InterfaceListConfigParser
(
config_id
);
}
else
if
(
config_id
.
compare
(
"subnet6"
)
==
0
)
{
parser
=
new
Subnets6ListConfigParser
(
config_id
);
...
...
@@ -463,6 +463,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
ParserCollection
independent_parsers
;
ParserPtr
subnet_parser
;
ParserPtr
option_parser
;
ParserPtr
iface_parser
;
// The subnet parsers implement data inheritance by directly
// accessing global storage. For this reason the global data
...
...
@@ -495,6 +496,11 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
subnet_parser
=
parser
;
}
else
if
(
config_pair
.
first
==
"option-data"
)
{
option_parser
=
parser
;
}
else
if
(
config_pair
.
first
==
"interfaces"
)
{
// The interface parser is independent from any other parser and
// can be run here before other parsers.
parser
->
build
(
config_pair
.
second
);
iface_parser
=
parser
;
}
else
{
// Those parsers should be started before other
// parsers so we can call build straight away.
...
...
@@ -548,6 +554,10 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
if
(
subnet_parser
)
{
subnet_parser
->
commit
();
}
if
(
iface_parser
)
{
iface_parser
->
commit
();
}
}
catch
(
const
isc
::
Exception
&
ex
)
{
LOG_ERROR
(
dhcp6_logger
,
DHCP6_PARSER_COMMIT_FAIL
).
arg
(
ex
.
what
());
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
339d60a7
...
...
@@ -66,11 +66,12 @@ public:
<<
" while the test assumes that it doesn't, to execute"
<<
" some negative scenarios. Can't continue this test."
;
}
// Reset configuration for each test.
resetConfiguration
();
}
~
Dhcp6ParserTest
()
{
// Reset configuration database after each test.
resetConfiguration
();
};
// Checks if config_result (result of DHCP server configuration) has
...
...
@@ -133,7 +134,7 @@ public:
std
::
string
>&
params
)
{
std
::
ostringstream
stream
;
stream
<<
"{
\"
interface
\"
: [
\"
all
\"
],"
stream
<<
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -173,13 +174,13 @@ public:
///
/// This function resets configuration data base by
/// removing all subnets and option-data. Reset must
/// be performed
after
each test to make sure that
/// be performed
before
each test to make sure that
/// contents of the database do not affect result of
///
subsequent tests
.
///
the test being executed
.
void
resetConfiguration
()
{
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -213,6 +214,12 @@ public:
<<
" after the test. Configuration function returned"
<<
" error code "
<<
rcode_
<<
std
::
endl
;
}
// The default setting is to listen on all interfaces. In order to
// properly test interface configuration we disable listening on
// all interfaces before each test and later check that this setting
// has been overriden by the configuration used in the test.
CfgMgr
::
instance
().
deleteActiveIfaces
();
}
/// @brief Test invalid option parameter value.
...
...
@@ -324,7 +331,7 @@ TEST_F(Dhcp6ParserTest, emptySubnet) {
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
Element
::
fromJSON
(
"{
\"
interface
\"
: [
\"
all
\"
],"
Element
::
fromJSON
(
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -343,7 +350,7 @@ TEST_F(Dhcp6ParserTest, subnetGlobalDefaults) {
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -377,7 +384,7 @@ TEST_F(Dhcp6ParserTest, subnetLocal) {
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -415,7 +422,7 @@ TEST_F(Dhcp6ParserTest, subnetInterface) {
// There should be at least one interface
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -448,7 +455,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceBogus) {
// There should be at least one interface
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -479,7 +486,7 @@ TEST_F(Dhcp6ParserTest, interfaceGlobal) {
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -549,7 +556,7 @@ TEST_F(Dhcp6ParserTest, subnetInterfaceId) {
// parameter.
TEST_F
(
Dhcp6ParserTest
,
interfaceIdGlobal
)
{
const
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
const
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -604,7 +611,7 @@ TEST_F(Dhcp6ParserTest, poolOutOfSubnet) {
ConstElementPtr
status
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -632,7 +639,7 @@ TEST_F(Dhcp6ParserTest, poolPrefixLen) {
ConstElementPtr
x
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -1152,7 +1159,7 @@ TEST_F(Dhcp6ParserTest, optionStandardDefOverride) {
// configuration does not include options configuration.
TEST_F
(
Dhcp6ParserTest
,
optionDataDefaults
)
{
ConstElementPtr
x
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
...
...
@@ -1234,7 +1241,7 @@ TEST_F(Dhcp6ParserTest, optionDataTwoSpaces) {
// The definition is not required for the option that
// belongs to the 'dhcp6' option space as it is the
// standard option.
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
...
...
@@ -1312,7 +1319,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
// at the very end (when all other parameters are configured).
// Starting stage 1. Configure sub-options and their definitions.
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
...
...
@@ -1361,7 +1368,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
// the configuration from the stage 2 is repeated because BIND
// configuration manager sends whole configuration for the lists
// where at least one element is being modified or added.
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
...
...
@@ -1455,7 +1462,7 @@ TEST_F(Dhcp6ParserTest, optionDataEncapsulate) {
// for multiple subnets.
TEST_F
(
Dhcp6ParserTest
,
optionDataInMultipleSubnets
)
{
ConstElementPtr
x
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
@@ -1698,7 +1705,7 @@ TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
// In the first stahe we create definitions of suboptions
// that we will add to the base option.
// Let's create some dummy options: foo and foo2.
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
...
...
@@ -1751,7 +1758,7 @@ TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
// We add our dummy options to this option space and thus
// they should be included as sub-options in the 'vendor-opts'
// option.
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
option-data
\"
: [ {"
...
...
@@ -1850,4 +1857,77 @@ TEST_F(Dhcp6ParserTest, stdOptionDataEncapsulate) {
EXPECT_FALSE
(
desc
.
option
->
getOption
(
112
));
}
// This test verifies that it is possible to select subset of interfaces on
// which server should listen.
TEST_F
(
Dhcp6ParserTest
,
selectedInterfaces
)
{
// Make sure there is no garbage interface configuration in the CfgMgr.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ConstElementPtr
status
;
string
config
=
"{
\"
interfaces
\"
: [
\"
eth0
\"
,
\"
eth1
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000 }"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
// returned value must be 1 (values error)
// as the pool does not belong to that subnet
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
0
,
rcode_
);
// eth0 and eth1 were explicitly selected. eth2 was not.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
}
// This test verifies that it is possible to configure the server to listen on
// all interfaces.
TEST_F
(
Dhcp6ParserTest
,
allInterfaces
)
{
// Make sure there is no garbage interface configuration in the CfgMgr.
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
ASSERT_FALSE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
ConstElementPtr
status
;
// This configuration specifies two interfaces on which server should listen
// bu also includes keyword 'all'. This keyword switches server into the
// mode when it listens on all interfaces regardless of what interface names
// were specified in the "interfaces" parameter.
string
config
=
"{
\"
interfaces
\"
: [
\"
eth0
\"
,
\"
eth1
\"
,
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
valid-lifetime
\"
: 4000 }"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
// returned value must be 1 (values error)
// as the pool does not belong to that subnet
ASSERT_TRUE
(
status
);
comment_
=
parseAnswer
(
rcode_
,
status
);
EXPECT_EQ
(
0
,
rcode_
);
// All interfaces should be now active.
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth0"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth1"
));
EXPECT_TRUE
(
CfgMgr
::
instance
().
isActiveIface
(
"eth2"
));
}
};
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
339d60a7
...
...
@@ -555,7 +555,7 @@ TEST_F(Dhcpv6SrvTest, DUID) {
// and the requested options are actually assigned.
TEST_F
(
Dhcpv6SrvTest
,
advertiseOptions
)
{
ConstElementPtr
x
;
string
config
=
"{
\"
interface
\"
: [
\"
all
\"
],"
string
config
=
"{
\"
interface
s
\"
: [
\"
all
\"
],"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment