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
4f81789e
Commit
4f81789e
authored
Nov 22, 2016
by
Tomek Mrugalski
🛰
Browse files
[master] Merge branch 'trac5023' (contexts in v6 pools)
# Conflicts: # src/lib/dhcpsrv/pool.h
parents
0a9d5bc9
0dc31ffa
Changes
8
Hide whitespace changes
Inline
Side-by-side
doc/guide/dhcp4-srv.xml
View file @
4f81789e
...
...
@@ -3713,6 +3713,51 @@ src/lib/dhcpsrv/cfg_host_operations.cc -->
</itemizedlist>
</section>
<section>
<title>
User context in IPv4 pools
</title>
<para>
Kea allows loading hook libraries that sometimes could benefit from
additional parameters. If such a parameter is specific to the whole
library, it is typically defined as a parameter for the hook library.
However, sometimes there is a need to specify parameters that are
different for each pool.
</para>
<para>
Let's consider an imaginary case of devices that have color LED
lights. Depending on their location, they should glow red, blue or
green. It would be easy to write a hook library that would send
specific values as maybe vendor option. However, the server has to
have some way to specify that value for each pool. This need is
addressed by user contexts. In essence, any user data can specified
in the user context as long as it is a valid JSON map. For example,
the forementioned case of LED devices could be configured in the
following way:
<screen>
"Dhcp4": {
"subnet4": [
{
"subnet": "192.0.2.0/24",
"pools": [ { "pool": "192.0.2.10 - 192.0.2.20" } ],
<userinput>
"user-context": { "colour": "red" }
</userinput>
},
...
],
...
}
</screen>
</para>
<para>
It should be noted that Kea will not use that information, but will
simply store and make it available to hook libraries. It is up to the
hook library to extract that information and make use of it.
</para>
<para>
Currently only pools allow definition of user contexts, but this
concept is expected to be enhanced to other structures in the future.
For more background information, see
<xref
linkend=
"user-context"
/>
</para>
</section>
<section
id=
"dhcp4-limit"
>
<title>
DHCPv4 Server Limitations
</title>
<para>
These are the current limitations of the DHCPv4 server
...
...
doc/guide/dhcp6-srv.xml
View file @
4f81789e
...
...
@@ -4077,6 +4077,66 @@ If not specified, the default value is:
<xref
linkend=
"command-shutdown"
/>
, respectively.
</para>
</section>
<section>
<title>
User context in IPv6 pools
</title>
<para>
Kea allows loading hook libraries that sometimes could benefit from
additional parameters. If such a parameter is specific to the whole
library, it is typically defined as a parameter for the hook library.
However, sometimes there is a need to specify parameters that are
different for each pool.
</para>
<para>
Let's consider a lightweight 4over6 deployment as an example. It is an
IPv6 transition technology that allows mapping IPv6 prefix into full
or parts of IPv4 addresses. In DHCP context, these are certain
parameters that are supposed to be delivered to clients in form of
additional options. Values of those options are correlated to
delegated prefixes, so it is reasonable to keep those parameters
together with the PD pool. On the other hand, lightweight 4over6 is
not a commonly used feature, so it is not a part of the base Kea
code. The solution to this problem is to use user context. For each PD
pool that is expected to be used for lightweight 4over6, user context
with extra parameters is defined. Those extra parameters will be used
by hook library that would be loaded only when dynamic calculation of
the lightweight 4over6 option is actually needed. An example
configuration looks as follows:
<screen>
"Dhcp4": {
"subnet6": [ {
"pd-pools": [
{
"prefix": "2001:db8::",
"prefix-len": 56,
"delegated-len": 64,
<userinput>
"user-context": {
"lw4over6-sharing-ratio": 64,
"lw4over6-v4-pool": "192.0.2.0/24",
"lw4over6-sysports-exclude": true,
"lw4over6-bind-prefix-len": 56
}
</userinput>
} ],
"subnet": "2001:db8::/32"
} ],
...
}
</screen>
</para>
<para>
It should be noted that Kea will not use any information in the user
context, but will simply store and make it available to the hook
libraries. It is up to the hook library to extract that information
and make use of it.
</para>
<para>
Currently only address and prefix pools allow definition of user
contexts, but this concept is expected to be enhanced to other
structures in the future. For more background information, see
<xref
linkend=
"user-context"
/>
</para>
</section>
<section
id=
"dhcp6-std"
>
<title>
Supported DHCPv6 Standards
</title>
<para>
The following standards are currently
...
...
doc/guide/hooks.xml
View file @
4f81789e
...
...
@@ -545,4 +545,23 @@ link address: 3001::1, hop count: 1, identified by remote-id:
</section>
</section>
</section>
<section
id=
"user-context"
>
<title>
User contexts
</title>
<para>
Hook libraries can have their own configuration parameters. That is
convenient if the parameter applies to the whole library. However,
sometimes it is very useful if certain configuration entities are extended
with additional configuration data. This is where the concept of user
contexts comes in. A sysadmin can define an arbitrary set of data and
attach it to Kea structures, as long as the data is specified as JSON map.
In particular, it is possible to define fields that are integers, strings,
boolean, lists and maps. It is possible to define nested structures of
arbitrary complexity. Kea does not use that data on its own, simply stores
and makes it available for the hook libraries.
</para>
<para>
As of Kea 1.2, the only structures that allow user contexts are address
and prefix pools, but it is expected to extend other structures with the
user context capability.
</para>
</section>
</chapter>
<!-- hooks-libraries -->
src/bin/dhcp4/tests/config_parser_unittest.cc
View file @
4f81789e
...
...
@@ -50,6 +50,64 @@ using namespace isc::hooks;
using
namespace
std
;
namespace
{
const
char
*
PARSER_CONFIGS
[]
=
{
// CONFIGURATION 0: one subnet with one pool, no user contexts
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet4
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
192.0.2.0/28
\"
}"
" ],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
"
" } ]"
"}"
,
// Configuration 1: one pool with empty user context
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet4
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
192.0.2.0/28
\"
,"
"
\"
user-context
\"
: {"
" }"
" }"
" ],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
"
" } ]"
"}"
,
// Configuration 2: one pool with user context containing lw4over6 parameters
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet4
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
192.0.2.0/28
\"
,"
"
\"
user-context
\"
: {"
"
\"
integer-param
\"
: 42,"
"
\"
string-param
\"
:
\"
Sagittarius
\"
,"
"
\"
bool-param
\"
: true"
" }"
" }"
" ],"
"
\"
subnet
\"
:
\"
192.0.2.0/24
\"
"
" } ]"
"}"
};
/// @brief Prepends the given name with the DHCP4 source directory
///
...
...
@@ -501,6 +559,37 @@ public:
return
(
ReturnType
());
}
/// @brief This utility method attempts to configure using specified
/// config and then returns requested pool from requested subnet
///
/// @param config configuration to be applied
/// @param subnet_index index of the subnet to be returned (0 - the first subnet)
/// @param pool_index index of the pool within a subnet (0 - the first pool)
/// @param pool [out] Pool pointer will be stored here (if found)
void
getPool
(
const
std
::
string
&
config
,
size_t
subnet_index
,
size_t
pool_index
,
PoolPtr
&
pool
)
{
ConstElementPtr
status
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp4Server
(
*
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
ConstCfgSubnets4Ptr
subnets4
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getCfgSubnets4
();
ASSERT_TRUE
(
subnets4
);
const
Subnet4Collection
*
subnets
=
subnets4
->
getAll
();
ASSERT_TRUE
(
subnets
);
ASSERT_GE
(
subnets
->
size
(),
subnet_index
+
1
);
const
PoolCollection
pools
=
subnets
->
at
(
subnet_index
)
->
getPools
(
Lease
::
TYPE_V4
);
ASSERT_GE
(
pools
.
size
(),
pool_index
+
1
);
pool
=
pools
.
at
(
pool_index
);
EXPECT_TRUE
(
pool
);
}
boost
::
scoped_ptr
<
Dhcpv4Srv
>
srv_
;
///< DHCP4 server under test
int
rcode_
;
///< Return code from element parsing
ConstElementPtr
comment_
;
///< Reason for parse fail
...
...
@@ -4277,5 +4366,61 @@ TEST_F(Dhcp4ParserTest, invalidClientClassDictionary) {
checkResult
(
status
,
1
);
}
// Test verifies that regular configuration does not provide any user context
// in the address pool.
TEST_F
(
Dhcp4ParserTest
,
poolUserContextMissing
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
0
]),
0
,
0
,
pool
);
ASSERT_TRUE
(
pool
);
EXPECT_FALSE
(
pool
->
getContext
());
}
// Test verifies that it's possible to specify empty user context in the
// address pool.
TEST_F
(
Dhcp4ParserTest
,
poolUserContextEmpty
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
1
]),
0
,
0
,
pool
);
ASSERT_TRUE
(
pool
);
ConstElementPtr
ctx
=
pool
->
getContext
();
ASSERT_TRUE
(
ctx
);
// The context should be of type map and not contain any parameters.
EXPECT_EQ
(
Element
::
map
,
ctx
->
getType
());
EXPECT_EQ
(
0
,
ctx
->
size
());
}
// Test verifies that it's possible to specify parameters in the user context
// in the address pool.
TEST_F
(
Dhcp4ParserTest
,
poolUserContextData
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
2
]),
0
,
0
,
pool
);
ASSERT_TRUE
(
pool
);
ConstElementPtr
ctx
=
pool
->
getContext
();
ASSERT_TRUE
(
ctx
);
// The context should be of type map and contain 4 parameters.
EXPECT_EQ
(
Element
::
map
,
ctx
->
getType
());
EXPECT_EQ
(
3
,
ctx
->
size
());
ConstElementPtr
int_param
=
ctx
->
get
(
"integer-param"
);
ConstElementPtr
str_param
=
ctx
->
get
(
"string-param"
);
ConstElementPtr
bool_param
=
ctx
->
get
(
"bool-param"
);
ASSERT_TRUE
(
int_param
);
ASSERT_EQ
(
Element
::
integer
,
int_param
->
getType
());
int64_t
int_value
;
EXPECT_NO_THROW
(
int_param
->
getValue
(
int_value
));
EXPECT_EQ
(
42L
,
int_value
);
ASSERT_TRUE
(
str_param
);
ASSERT_EQ
(
Element
::
string
,
str_param
->
getType
());
EXPECT_EQ
(
"Sagittarius"
,
str_param
->
stringValue
());
ASSERT_TRUE
(
bool_param
);
bool
bool_value
;
ASSERT_EQ
(
Element
::
boolean
,
bool_param
->
getType
());
EXPECT_NO_THROW
(
bool_param
->
getValue
(
bool_value
));
EXPECT_EQ
(
true
,
bool_value
);
}
}
src/bin/dhcp6/json_config_parser.cc
View file @
4f81789e
...
...
@@ -188,7 +188,9 @@ public:
options_
,
AF_INET6
));
parser
=
option_parser
;
}
else
if
(
entry
==
"user-context"
)
{
user_context_
=
param
.
second
;
continue
;
// no parser to remember, simply store the value
}
else
{
isc_throw
(
DhcpConfigError
,
"unsupported parameter: "
<<
entry
<<
" ("
<<
param
.
second
->
getPosition
()
<<
")"
);
...
...
@@ -222,6 +224,10 @@ public:
isc_throw
(
isc
::
dhcp
::
DhcpConfigError
,
ex
.
what
()
<<
" ("
<<
pd_pool_
->
getPosition
()
<<
")"
);
}
if
(
user_context_
)
{
pool_
->
setUserContext
(
user_context_
);
}
}
// @brief Commits the constructed local pool to the pool storage.
...
...
@@ -248,6 +254,8 @@ protected:
/// A storage for pool specific option values.
CfgOptionPtr
options_
;
isc
::
data
::
ConstElementPtr
user_context_
;
};
/// @brief Parser for a list of prefix delegation pools.
...
...
src/bin/dhcp6/tests/config_parser_unittest.cc
View file @
4f81789e
...
...
@@ -55,6 +55,135 @@ using namespace std;
namespace
{
const
char
*
PARSER_CONFIGS
[]
=
{
// CONFIGURATION 0: one subnet with one pool, no user contexts
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
2001:db8::/64
\"
}"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
,
// Configuration 1: one pool with empty user context
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
2001:db8::/64
\"
,"
"
\"
user-context
\"
: {"
" }"
" }"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
,
// Configuration 2: one pool with user context containing lw4over6 parameters
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pools
\"
: [ "
" {
\"
pool
\"
:
\"
2001:db8::/64
\"
,"
"
\"
user-context
\"
: {"
"
\"
lw4over6-sharing-ratio
\"
: 64,"
"
\"
lw4over6-v4-pool
\"
:
\"
192.0.2.0/24
\"
,"
"
\"
lw4over6-sysports-exclude
\"
: true,"
"
\"
lw4over6-bind-prefix-len
\"
: 56"
" }"
" }"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
,
// Configuration 3: pd-pool without any user-context
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pd-pools
\"
: [ "
" {
\"
prefix
\"
:
\"
2001:db8::
\"
,"
"
\"
prefix-len
\"
: 56,"
"
\"
delegated-len
\"
: 64 }"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
,
// Configuration 4: pd-pool with empty user-context
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pd-pools
\"
: [ "
" {
\"
prefix
\"
:
\"
2001:db8::
\"
,"
"
\"
prefix-len
\"
: 56,"
"
\"
delegated-len
\"
: 64,"
"
\"
user-context
\"
: { }"
" }"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
,
// Configuration 5: pd-pool with user-context with lw4over6 parameters
"{"
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
" },"
"
\"
valid-lifetime
\"
: 4000,"
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000,"
"
\"
renew-timer
\"
: 1000,"
"
\"
subnet6
\"
: [ {"
"
\"
pd-pools
\"
: [ "
" {
\"
prefix
\"
:
\"
2001:db8::
\"
,"
"
\"
prefix-len
\"
: 56,"
"
\"
delegated-len
\"
: 64,"
"
\"
user-context
\"
: {"
"
\"
lw4over6-sharing-ratio
\"
: 64,"
"
\"
lw4over6-v4-pool
\"
:
\"
192.0.2.0/24
\"
,"
"
\"
lw4over6-sysports-exclude
\"
: true,"
"
\"
lw4over6-bind-prefix-len
\"
: 56"
" }"
" }"
" ],"
"
\"
subnet
\"
:
\"
2001:db8::/32
\"
"
" } ]"
"}"
};
std
::
string
specfile
(
const
std
::
string
&
name
)
{
return
(
std
::
string
(
DHCP6_SRC_DIR
)
+
"/"
+
name
);
}
...
...
@@ -562,6 +691,37 @@ public:
CfgMgr
::
instance
().
clear
();
}
/// @brief This utility method attempts to configure using specified
/// config and then returns requested pool from requested subnet
///
/// @param config configuration to be applied
/// @param subnet_index index of the subnet to be returned (0 - the first subnet)
/// @param pool_index index of the pool within a subnet (0 - the first pool)
/// @param type Pool type (TYPE_NA or TYPE_PD)
/// @param pool [out] Pool pointer will be stored here (if found)
void
getPool
(
const
std
::
string
&
config
,
size_t
subnet_index
,
size_t
pool_index
,
Lease
::
Type
type
,
PoolPtr
&
pool
)
{
ConstElementPtr
status
;
ElementPtr
json
=
Element
::
fromJSON
(
config
);
EXPECT_NO_THROW
(
status
=
configureDhcp6Server
(
srv_
,
json
));
ASSERT_TRUE
(
status
);
checkResult
(
status
,
0
);
ConstCfgSubnets6Ptr
subnets6
=
CfgMgr
::
instance
().
getStagingCfg
()
->
getCfgSubnets6
();
ASSERT_TRUE
(
subnets6
);
const
Subnet6Collection
*
subnets
=
subnets6
->
getAll
();
ASSERT_TRUE
(
subnets
);
ASSERT_GE
(
subnets
->
size
(),
subnet_index
+
1
);
const
PoolCollection
pools
=
subnets
->
at
(
subnet_index
)
->
getPools
(
type
);
ASSERT_GE
(
pools
.
size
(),
pool_index
+
1
);
pool
=
pools
.
at
(
pool_index
);
EXPECT_TRUE
(
pool
);
}
int
rcode_
;
///< Return code (see @ref isc::config::parseAnswer)
Dhcpv6Srv
srv_
;
///< Instance of the Dhcp6Srv used during tests
ConstElementPtr
comment_
;
///< Comment (see @ref isc::config::parseAnswer)
...
...
@@ -4581,4 +4741,129 @@ TEST_F(Dhcp6ParserTest, invalidClientClassDictionary) {
checkResult
(
status
,
1
);
}
// Test verifies that regular configuration does not provide any user context
// in the address pool.
TEST_F
(
Dhcp6ParserTest
,
poolUserContextMissing
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
0
]),
0
,
0
,
Lease
::
TYPE_NA
,
pool
);
ASSERT_TRUE
(
pool
);
EXPECT_FALSE
(
pool
->
getContext
());
}
// Test verifies that it's possible to specify empty user context in the
// address pool.
TEST_F
(
Dhcp6ParserTest
,
poolUserContextEmpty
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
1
]),
0
,
0
,
Lease
::
TYPE_NA
,
pool
);
ASSERT_TRUE
(
pool
);
ConstElementPtr
ctx
=
pool
->
getContext
();
ASSERT_TRUE
(
ctx
);
// The context should be of type map and not contain any parameters.
EXPECT_EQ
(
Element
::
map
,
ctx
->
getType
());
EXPECT_EQ
(
0
,
ctx
->
size
());
}
// Test verifies that it's possible to specify parameters in the user context
// in the address pool.
TEST_F
(
Dhcp6ParserTest
,
poolUserContextlw4over6
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
2
]),
0
,
0
,
Lease
::
TYPE_NA
,
pool
);
ASSERT_TRUE
(
pool
);
ConstElementPtr
ctx
=
pool
->
getContext
();
ASSERT_TRUE
(
ctx
);
// The context should be of type map and contain 4 parameters.
EXPECT_EQ
(
Element
::
map
,
ctx
->
getType
());
EXPECT_EQ
(
4
,
ctx
->
size
());
ConstElementPtr
ratio
=
ctx
->
get
(
"lw4over6-sharing-ratio"
);
ConstElementPtr
v4pool
=
ctx
->
get
(
"lw4over6-v4-pool"
);
ConstElementPtr
exclude
=
ctx
->
get
(
"lw4over6-sysports-exclude"
);
ConstElementPtr
v6len
=
ctx
->
get
(
"lw4over6-bind-prefix-len"
);
ASSERT_TRUE
(
ratio
);
ASSERT_EQ
(
Element
::
integer
,
ratio
->
getType
());
int64_t
int_value
;
EXPECT_NO_THROW
(
ratio
->
getValue
(
int_value
));
EXPECT_EQ
(
64L
,
int_value
);
ASSERT_TRUE
(
v4pool
);
ASSERT_EQ
(
Element
::
string
,
v4pool
->
getType
());
EXPECT_EQ
(
"192.0.2.0/24"
,
v4pool
->
stringValue
());
ASSERT_TRUE
(
exclude
);
bool
bool_value
;
ASSERT_EQ
(
Element
::
boolean
,
exclude
->
getType
());
EXPECT_NO_THROW
(
exclude
->
getValue
(
bool_value
));
EXPECT_EQ
(
true
,
bool_value
);
ASSERT_TRUE
(
v6len
);
ASSERT_EQ
(
Element
::
integer
,
v6len
->
getType
());
EXPECT_NO_THROW
(
v6len
->
getValue
(
int_value
));
EXPECT_EQ
(
56L
,
int_value
);
}
// Test verifies that regular configuration does not provide any user context
// in the address pool.
TEST_F
(
Dhcp6ParserTest
,
pdPoolUserContextMissing
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
3
]),
0
,
0
,
Lease
::
TYPE_PD
,
pool
);
ASSERT_TRUE
(
pool
);
EXPECT_FALSE
(
pool
->
getContext
());
}
// Test verifies that it's possible to specify empty user context in the
// address pool.
TEST_F
(
Dhcp6ParserTest
,
pdPoolUserContextEmpty
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
4
]),
0
,
0
,
Lease
::
TYPE_PD
,
pool
);
ASSERT_TRUE
(
pool
);
ConstElementPtr
ctx
=
pool
->
getContext
();
ASSERT_TRUE
(
ctx
);
// The context should be of type map and not contain any parameters.
EXPECT_EQ
(
Element
::
map
,
ctx
->
getType
());
EXPECT_EQ
(
0
,
ctx
->
size
());
}
// Test verifies that it's possible to specify parameters in the user context
// in the address pool.
TEST_F
(
Dhcp6ParserTest
,
pdPoolUserContextlw4over6
)
{
PoolPtr
pool
;
getPool
(
string
(
PARSER_CONFIGS
[
5
]),
0
,
0
,
Lease
::
TYPE_PD
,
pool
);