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
3a1cec32
Commit
3a1cec32
authored
Oct 04, 2019
by
Francis Dupont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[219-allow-an-option-value-to-be-set-from-an-expression] Added new tests and an example
parent
85ff0365
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
100 additions
and
8 deletions
+100
-8
doc/sphinx/arm/hooks.rst
doc/sphinx/arm/hooks.rst
+10
-3
src/hooks/dhcp/flex_option/flex_option.dox
src/hooks/dhcp/flex_option/flex_option.dox
+1
-1
src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc
src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc
+48
-1
src/hooks/dhcp/flex_option/tests/flex_option_unittests.cc
src/hooks/dhcp/flex_option/tests/flex_option_unittests.cc
+41
-3
No files found.
doc/sphinx/arm/hooks.rst
View file @
3a1cec32
...
...
@@ -1216,14 +1216,15 @@ take a string value representing an expression.
::
"Dhcp
6
": {
"Dhcp
4
": {
"hook_libraries": [
{ "library": "/usr/local/lib/libdhcp_flex_option.so",
"parameters": {
"options": [
{
"code": 100,
"add": "concat(relay6[0].option[37].hex, 'abc')"
"code": 67,
"add":
"ifelse(option[host-name].exists,concat(option[host-name].text,'.boot'),'')"
}
]
}
...
...
@@ -1232,8 +1233,14 @@ take a string value representing an expression.
]
}
If (and only if) the query includes a host-name option (code 12),
a boot-file-name option (code 67) is added to the response with the host
name followed by .boot for content.
The flexible option library supports both DHCPv4 and DHCPv6.
.. _host-cmds:
host_cmds: Host Commands
...
...
src/hooks/dhcp/flex_option/flex_option.dox
View file @
3a1cec32
...
...
@@ -63,7 +63,7 @@ To configure it for kea-dhcp6, the commands are simply as shown below:
{ "library": "/usr/local/lib/libdhcp_flex_option.so",
"parameters": {
"options": [
{
{
"code": 100,
"add": "concat(relay6[0].option[37].hex, 'abc')"
}
...
...
src/hooks/dhcp/flex_option/libloadtests/callout_unittests.cc
View file @
3a1cec32
...
...
@@ -17,6 +17,8 @@
#include <hooks/hooks_manager.h>
#include <hooks/callout_manager.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <dhcpsrv/cfgmgr.h>
#include <gtest/gtest.h>
#include <errno.h>
...
...
@@ -114,7 +116,7 @@ TEST_F(CalloutTest, pkt4Send) {
EXPECT_NO_THROW
(
HooksManager
::
callCallouts
(
testHooks
.
hook_index_pkt4_send_
,
*
handle
));
EXPECT_EQ
(
0
,
handle
->
getStatus
());
// Check the result.
OptionPtr
opt
=
response
->
getOption
(
DHO_HOST_NAME
);
ASSERT_TRUE
(
opt
);
...
...
@@ -124,4 +126,49 @@ TEST_F(CalloutTest, pkt4Send) {
EXPECT_EQ
(
0
,
memcmp
(
&
buffer
[
0
],
"abc"
,
3
));
}
// Simple test which exercises the pkt6_send callout.
TEST_F
(
CalloutTest
,
pkt6Send
)
{
// Move to DHCPv6.
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
// Prepare load() parameters.
ElementPtr
params
=
Element
::
createMap
();
ElementPtr
options
=
Element
::
createList
();
params
->
set
(
"options"
,
options
);
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
ElementPtr
code
=
Element
::
create
(
D6O_BOOTFILE_URL
);
option
->
set
(
"code"
,
code
);
ElementPtr
supersede
=
Element
::
create
(
string
(
"'abc'"
));
option
->
set
(
"supersede"
,
supersede
);
// Load the library.
addLib
(
FLEX_OPTION_LIB_SO
,
params
);
loadLibs
();
// Prepare packets.
Pkt6Ptr
query
(
new
Pkt6
(
DHCPV6_SOLICIT
,
12345
));
Pkt6Ptr
response
(
new
Pkt6
(
DHCPV6_ADVERTISE
,
12345
));
EXPECT_FALSE
(
response
->
getOption
(
D6O_BOOTFILE_URL
));
// Get and setup the callout handle.
EXPECT_TRUE
(
HooksManager
::
calloutsPresent
(
testHooks
.
hook_index_pkt6_send_
));
CalloutHandlePtr
handle
=
HooksManager
::
createCalloutHandle
();
handle
->
setArgument
(
"query6"
,
query
);
handle
->
setArgument
(
"response6"
,
response
);
// Execute the callout.
EXPECT_NO_THROW
(
HooksManager
::
callCallouts
(
testHooks
.
hook_index_pkt6_send_
,
*
handle
));
EXPECT_EQ
(
0
,
handle
->
getStatus
());
// Check the result.
OptionPtr
opt
=
response
->
getOption
(
D6O_BOOTFILE_URL
);
ASSERT_TRUE
(
opt
);
EXPECT_EQ
(
D6O_BOOTFILE_URL
,
opt
->
getType
());
const
OptionBuffer
&
buffer
=
opt
->
getData
();
ASSERT_EQ
(
3
,
buffer
.
size
());
EXPECT_EQ
(
0
,
memcmp
(
&
buffer
[
0
],
"abc"
,
3
));
}
}
// end of anonymous namespace
src/hooks/dhcp/flex_option/tests/flex_option_unittests.cc
View file @
3a1cec32
...
...
@@ -778,6 +778,8 @@ TEST_F(FlexOptionTest, processAdd) {
// Verify that ADD action does not add an already existing option.
TEST_F
(
FlexOptionTest
,
processAddExisting
)
{
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
...
...
@@ -852,6 +854,8 @@ TEST_F(FlexOptionTest, processSupersede) {
// Verify that SUPERSEDE action supersedes an already existing option.
TEST_F
(
FlexOptionTest
,
processSupersedeExisting
)
{
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
...
...
@@ -916,6 +920,8 @@ TEST_F(FlexOptionTest, processSupersedeEmpty) {
// Verify that REMOVE action removes an already existing option.
TEST_F
(
FlexOptionTest
,
processRemove
)
{
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
...
...
@@ -961,6 +967,8 @@ TEST_F(FlexOptionTest, processRemoveNoOption) {
// Verify that REMOVE action does nothing when the expression evaluates to false.
TEST_F
(
FlexOptionTest
,
processRemoveFalse
)
{
CfgMgr
::
instance
().
setFamily
(
AF_INET6
);
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
...
...
@@ -971,16 +979,46 @@ TEST_F(FlexOptionTest, processRemoveFalse) {
EXPECT_NO_THROW
(
impl_
->
testConfigure
(
options
));
EXPECT_TRUE
(
impl_
->
getErrMsg
().
empty
());
Pkt
4
Ptr
query
(
new
Pkt
4
(
DHCP
DISCOVER
,
12345
));
Pkt
4
Ptr
response
(
new
Pkt
4
(
DHCP
OFFER
,
12345
));
Pkt
6
Ptr
query
(
new
Pkt
6
(
DHCP
V6_SOLICIT
,
12345
));
Pkt
6
Ptr
response
(
new
Pkt
6
(
DHCP
V6_ADVERTISE
,
12345
));
OptionStringPtr
str
(
new
OptionString
(
Option
::
V6
,
D6O_BOOTFILE_URL
,
"http"
));
response
->
addOption
(
str
);
string
response_txt
=
response
->
toText
();
EXPECT_NO_THROW
(
impl_
->
process
<
Pkt
4
Ptr
>
(
Option
::
V6
,
query
,
response
));
EXPECT_NO_THROW
(
impl_
->
process
<
Pkt
6
Ptr
>
(
Option
::
V6
,
query
,
response
));
EXPECT_EQ
(
response_txt
,
response
->
toText
());
EXPECT_TRUE
(
response
->
getOption
(
D6O_BOOTFILE_URL
));
}
// A more complex check...
TEST_F
(
FlexOptionTest
,
processFullTest
)
{
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
options
->
add
(
option
);
ElementPtr
code
=
Element
::
create
(
DHO_BOOT_FILE_NAME
);
option
->
set
(
"code"
,
code
);
string
expr
=
"ifelse(option[host-name].exists,"
;
expr
+=
"concat(option[host-name].text,'.boot'),'')"
;
ElementPtr
add
=
Element
::
create
(
expr
);
option
->
set
(
"add"
,
add
);
EXPECT_NO_THROW
(
impl_
->
testConfigure
(
options
));
EXPECT_TRUE
(
impl_
->
getErrMsg
().
empty
());
Pkt4Ptr
query
(
new
Pkt4
(
DHCPDISCOVER
,
12345
));
Pkt4Ptr
response
(
new
Pkt4
(
DHCPOFFER
,
12345
));
OptionStringPtr
str
(
new
OptionString
(
Option
::
V4
,
DHO_HOST_NAME
,
"foo"
));
query
->
addOption
(
str
);
EXPECT_FALSE
(
response
->
getOption
(
DHO_BOOT_FILE_NAME
));
EXPECT_NO_THROW
(
impl_
->
process
<
Pkt4Ptr
>
(
Option
::
V4
,
query
,
response
));
OptionPtr
opt
=
response
->
getOption
(
DHO_BOOT_FILE_NAME
);
ASSERT_TRUE
(
opt
);
EXPECT_EQ
(
DHO_BOOT_FILE_NAME
,
opt
->
getType
());
const
OptionBuffer
&
buffer
=
opt
->
getData
();
ASSERT_EQ
(
8
,
buffer
.
size
());
EXPECT_EQ
(
0
,
memcmp
(
&
buffer
[
0
],
"foo.boot"
,
8
));
}
}
// end of anonymous namespace
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