Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
ISC Open Source Projects
Kea
Commits
45b03507
Commit
45b03507
authored
Jan 11, 2013
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2314] Create option definition with encapsulated option space name.
parent
656b5d1c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
189 additions
and
17 deletions
+189
-17
src/bin/dhcp4/config_parser.cc
src/bin/dhcp4/config_parser.cc
+30
-3
src/bin/dhcp4/dhcp4.spec
src/bin/dhcp4/dhcp4.spec
+7
-1
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp4/tests/config_parser_unittest.cc
+152
-13
No files found.
src/bin/dhcp4/config_parser.cc
View file @
45b03507
...
...
@@ -1008,7 +1008,8 @@ public:
std
::
string
entry
(
param
.
first
);
ParserPtr
parser
;
if
(
entry
==
"name"
||
entry
==
"type"
||
entry
==
"record-types"
||
entry
==
"space"
)
{
entry
==
"record-types"
||
entry
==
"space"
||
entry
==
"encapsulate"
)
{
StringParserPtr
str_parser
(
dynamic_cast
<
StringParser
*>
(
StringParser
::
factory
(
entry
)));
if
(
str_parser
)
{
...
...
@@ -1092,9 +1093,35 @@ private:
uint32_t
code
=
getParam
<
uint32_t
>
(
"code"
,
uint32_values_
);
std
::
string
type
=
getParam
<
std
::
string
>
(
"type"
,
string_values_
);
bool
array_type
=
getParam
<
bool
>
(
"array"
,
boolean_values_
);
std
::
string
encapsulates
=
getParam
<
std
::
string
>
(
"encapsulate"
,
string_values_
);
// Create option definition.
OptionDefinitionPtr
def
;
// We need to check if user has set encapsulated option space
// name. If so, different constructor will be used.
if
(
!
encapsulates
.
empty
())
{
// Arrays can't be used together with sub-options.
if
(
array_type
)
{
isc_throw
(
DhcpConfigError
,
"option '"
<<
space
<<
"."
<<
"name"
<<
"', comprising an array of data"
<<
" fields may not encapsulate any option space"
);
}
else
if
(
encapsulates
==
space
)
{
isc_throw
(
DhcpConfigError
,
"option must not encapsulate"
<<
" an option space it belongs to: '"
<<
space
<<
"."
<<
name
<<
"' is set to"
<<
" encapsulate '"
<<
space
<<
"'"
);
OptionDefinitionPtr
def
(
new
OptionDefinition
(
name
,
code
,
type
,
array_type
));
}
else
{
def
.
reset
(
new
OptionDefinition
(
name
,
code
,
type
,
encapsulates
.
c_str
()));
}
}
else
{
def
.
reset
(
new
OptionDefinition
(
name
,
code
,
type
,
array_type
));
}
// The record-types field may carry a list of comma separated names
// of data types that form a record.
std
::
string
record_types
=
getParam
<
std
::
string
>
(
"record-types"
,
...
...
src/bin/dhcp4/dhcp4.spec
View file @
45b03507
...
...
@@ -73,13 +73,19 @@
{ "item_name": "record_types",
"item_type": "string",
"item_optional": false,
"item_default": ""
,
"item_default": ""
},
{ "item_name": "space",
"item_type": "string",
"item_optional": false,
"item_default": ""
},
{ "item_name": "encapsulate",
"item_type": "string",
"item_optional": false,
"item_default": ""
} ]
}
},
...
...
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
45b03507
...
...
@@ -461,7 +461,8 @@ TEST_F(Dhcp4ParserTest, optionDefIpv4Address) {
"
\"
type
\"
:
\"
ipv4-address
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -474,6 +475,7 @@ TEST_F(Dhcp4ParserTest, optionDefIpv4Address) {
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
// The option definition should now be available in the CfgMgr.
def
=
CfgMgr
::
instance
().
getOptionDef
(
"isc"
,
100
);
...
...
@@ -484,6 +486,7 @@ TEST_F(Dhcp4ParserTest, optionDefIpv4Address) {
EXPECT_EQ
(
100
,
def
->
getCode
());
EXPECT_FALSE
(
def
->
getArrayType
());
EXPECT_EQ
(
OPT_IPV4_ADDRESS_TYPE
,
def
->
getType
());
EXPECT_TRUE
(
def
->
getEncapsulatedSpace
().
empty
());
}
// The goal of this test is to check whether an option definiiton
...
...
@@ -499,7 +502,8 @@ TEST_F(Dhcp4ParserTest, optionDefRecord) {
"
\"
type
\"
:
\"
record
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"
uint16, ipv4-address, ipv6-address, string
\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -523,6 +527,7 @@ TEST_F(Dhcp4ParserTest, optionDefRecord) {
EXPECT_EQ
(
100
,
def
->
getCode
());
EXPECT_EQ
(
OPT_RECORD_TYPE
,
def
->
getType
());
EXPECT_FALSE
(
def
->
getArrayType
());
EXPECT_TRUE
(
def
->
getEncapsulatedSpace
().
empty
());
// The option comprises the record of data fields. Verify that all
// fields are present and they are of the expected types.
...
...
@@ -546,7 +551,8 @@ TEST_F(Dhcp4ParserTest, optionDefMultiple) {
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" },"
" {"
"
\"
name
\"
:
\"
foo-2
\"
,"
...
...
@@ -554,7 +560,8 @@ TEST_F(Dhcp4ParserTest, optionDefMultiple) {
"
\"
type
\"
:
\"
ipv4-address
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -578,6 +585,7 @@ TEST_F(Dhcp4ParserTest, optionDefMultiple) {
EXPECT_EQ
(
100
,
def1
->
getCode
());
EXPECT_EQ
(
OPT_UINT32_TYPE
,
def1
->
getType
());
EXPECT_FALSE
(
def1
->
getArrayType
());
EXPECT_TRUE
(
def1
->
getEncapsulatedSpace
().
empty
());
// Check the second option definition we have created.
OptionDefinitionPtr
def2
=
CfgMgr
::
instance
().
getOptionDef
(
"isc"
,
101
);
...
...
@@ -588,6 +596,7 @@ TEST_F(Dhcp4ParserTest, optionDefMultiple) {
EXPECT_EQ
(
101
,
def2
->
getCode
());
EXPECT_EQ
(
OPT_IPV4_ADDRESS_TYPE
,
def2
->
getType
());
EXPECT_FALSE
(
def2
->
getArrayType
());
EXPECT_TRUE
(
def2
->
getEncapsulatedSpace
().
empty
());
}
// The goal of this test is to verify that the duplicated option
...
...
@@ -604,7 +613,8 @@ TEST_F(Dhcp4ParserTest, optionDefDuplicate) {
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" },"
" {"
"
\"
name
\"
:
\"
foo-2
\"
,"
...
...
@@ -612,7 +622,8 @@ TEST_F(Dhcp4ParserTest, optionDefDuplicate) {
"
\"
type
\"
:
\"
ipv4-address
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -640,7 +651,8 @@ TEST_F(Dhcp4ParserTest, optionDefArray) {
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: True,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -664,6 +676,48 @@ TEST_F(Dhcp4ParserTest, optionDefArray) {
EXPECT_EQ
(
100
,
def
->
getCode
());
EXPECT_EQ
(
OPT_UINT32_TYPE
,
def
->
getType
());
EXPECT_TRUE
(
def
->
getArrayType
());
EXPECT_TRUE
(
def
->
getEncapsulatedSpace
().
empty
());
}
// The purpose of this test to verify that encapsulated option
// space name may be specified.
TEST_F
(
Dhcp4ParserTest
,
optionDefEncapsulate
)
{
// Configuration string. Included the encapsulated
// option space name.
std
::
string
config
=
"{
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
code
\"
: 100,"
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"
sub-opts-space
\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
// Make sure that the particular option definition does not exist.
OptionDefinitionPtr
def
=
CfgMgr
::
instance
().
getOptionDef
(
"isc"
,
100
);
ASSERT_FALSE
(
def
);
// Use the configuration string to create new option definition.
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
// The option definition should now be available in the CfgMgr.
def
=
CfgMgr
::
instance
().
getOptionDef
(
"isc"
,
100
);
ASSERT_TRUE
(
def
);
// Check the option data.
EXPECT_EQ
(
"foo"
,
def
->
getName
());
EXPECT_EQ
(
100
,
def
->
getCode
());
EXPECT_EQ
(
OPT_UINT32_TYPE
,
def
->
getType
());
EXPECT_FALSE
(
def
->
getArrayType
());
EXPECT_EQ
(
"sub-opts-space"
,
def
->
getEncapsulatedSpace
());
}
/// The purpose of this test is to verify that the option definition
...
...
@@ -678,7 +732,8 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidName) {
"
\"
type
\"
:
\"
string
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -703,7 +758,8 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidType) {
"
\"
type
\"
:
\"
sting
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -728,7 +784,8 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidRecordType) {
"
\"
type
\"
:
\"
record
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"
uint32,uint8,sting
\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -741,6 +798,85 @@ TEST_F(Dhcp4ParserTest, optionDefInvalidRecordType) {
checkResult
(
status
,
1
);
}
/// The goal of this test is to verify that the invalid encapsulated
/// option space name is not accepted.
TEST_F
(
Dhcp4ParserTest
,
optionDefInvalidEncapsulatedSpace
)
{
// Configuration string. The encapsulated option space
// name is invalid (% character is not allowed).
std
::
string
config
=
"{
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
code
\"
: 100,"
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"
invalid%space%name
\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
// Use the configuration string to create new option definition.
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
// Expecting parsing error (error code 1).
checkResult
(
status
,
1
);
}
/// The goal of this test is to verify that the encapsulated
/// option space name can't be specified for the option that
/// comprises an array of data fields.
TEST_F
(
Dhcp4ParserTest
,
optionDefEncapsulatedSpaceAndArray
)
{
// Configuration string. The encapsulated option space
// name is set to non-empty value and the array flag
// is set.
std
::
string
config
=
"{
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
code
\"
: 100,"
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: True,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"
valid-space-name
\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
// Use the configuration string to create new option definition.
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
// Expecting parsing error (error code 1).
checkResult
(
status
,
1
);
}
/// The goal of this test is to verify that the option may not
/// encapsulate option space it belongs to.
TEST_F
(
Dhcp4ParserTest
,
optionDefEncapsulateOwnSpace
)
{
// Configuration string. Option is set to encapsulate
// option space it belongs to.
std
::
string
config
=
"{
\"
option-def
\"
: [ {"
"
\"
name
\"
:
\"
foo
\"
,"
"
\"
code
\"
: 100,"
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"
isc
\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
// Use the configuration string to create new option definition.
ConstElementPtr
status
;
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
// Expecting parsing error (error code 1).
checkResult
(
status
,
1
);
}
/// The purpose of this test is to verify that it is not allowed
/// to override the standard option (that belongs to dhcp4 option
...
...
@@ -759,7 +895,8 @@ TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
"
\"
type
\"
:
\"
string
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
dhcp4
\"
"
"
\"
space
\"
:
\"
dhcp4
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -794,7 +931,8 @@ TEST_F(Dhcp4ParserTest, optionStandardDefOverride) {
"
\"
type
\"
:
\"
string
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
dhcp4
\"
"
"
\"
space
\"
:
\"
dhcp4
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ]"
"}"
;
json
=
Element
::
fromJSON
(
config
);
...
...
@@ -907,7 +1045,8 @@ TEST_F(Dhcp4ParserTest, optionDataTwoSpaces) {
"
\"
type
\"
:
\"
uint32
\"
,"
"
\"
array
\"
: False,"
"
\"
record-types
\"
:
\"\"
,"
"
\"
space
\"
:
\"
isc
\"
"
"
\"
space
\"
:
\"
isc
\"
,"
"
\"
encapsulate
\"
:
\"\"
"
" } ],"
"
\"
subnet4
\"
: [ { "
"
\"
pool
\"
: [
\"
192.0.2.1 - 192.0.2.100
\"
],"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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