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
ISC Open Source Projects
Kea
Commits
042c0b6f
Commit
042c0b6f
authored
Sep 20, 2017
by
Francis Dupont
Browse files
[5073a] On the right track (still a lot of code and new tests to do)
parent
74b6b67b
Changes
10
Hide whitespace changes
Inline
Side-by-side
doc/examples/kea4/advanced.json
View file @
042c0b6f
...
...
@@ -36,6 +36,15 @@
"re-detect"
:
true
},
//
Option
43
last
resort
definition
can
make
legal
messages
to
be
//
rejected
because
they
use
not
compatible
"raw"
value.
//
The
option
definition
can
be
applied
to
avoid
this
problem.
"option-def"
:
[
{
"name"
:
"vendor-encapsulated-options"
,
"code"
:
43
,
"type"
:
"binary"
}
],
//
We
need
to
specify
the
the
database
used
to
store
leases.
As
of
//
September
2016
,
four
database
backends
are
supported:
MySQL
,
//
PostgreSQL
,
Cassandra
,
and
the
in-memory
database
,
Memfile.
...
...
doc/examples/kea4/classify.json
View file @
042c0b6f
...
...
@@ -55,12 +55,18 @@
//
In
this
particular
class
,
we
want
to
set
specific
values
//
of
certain
DHCPv
4
fields.
If
the
incoming
packet
matches
the
//
test
,
those
fields
will
be
set
in
outgoing
responses.
//
The
option
43
is
defined
to
encapsulate
suboption
inf
the
aastra
space.
{
"name"
:
"VoIP"
,
"test"
:
"substring(option[60].hex,0,6) == 'Aastra'"
,
"next-server"
:
"192.0.2.254"
,
"server-hostname"
:
"hal9000"
,
"boot-file-name"
:
"/dev/null"
"boot-file-name"
:
"/dev/null"
,
"option-def"
:
[
{
"name"
:
"vendor-encapsulated-options"
,
"code"
:
43
,
"type"
:
"empty"
,
"encapsulate"
:
"aastra"
}
]
}
],
...
...
src/lib/dhcp/libdhcp++.cc
View file @
042c0b6f
// Copyright (C) 2011-201
6
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2011-201
7
Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
...
...
@@ -60,6 +60,9 @@ StagedValue<OptionDefSpaceContainer> LibDHCP::runtime_option_defs_;
// Null container.
const
OptionDefContainerPtr
null_option_def_container_
(
new
OptionDefContainer
());
// Option 43 definition.
OptionDefinitionPtr
LibDHCP
::
last_resort_option43_def
;
// Those two vendor classes are used for cable modems:
/// DOCSIS3.0 compatible cable modem
...
...
@@ -257,6 +260,13 @@ LibDHCP::commitRuntimeOptionDefs() {
runtime_option_defs_
.
commit
();
}
bool
LibDHCP
::
deferOption
(
const
std
::
string
&
space
,
const
uint16_t
code
)
{
return
((
space
==
DHCP4_OPTION_SPACE
)
&&
((
code
==
DHO_VENDOR_ENCAPSULATED_OPTIONS
)
||
((
code
>=
224
)
&&
(
code
<=
254
))));
}
OptionPtr
LibDHCP
::
optionFactory
(
Option
::
Universe
u
,
uint16_t
type
,
...
...
@@ -501,6 +511,11 @@ size_t LibDHCP::unpackOptions4(const OptionBuffer& buf,
num_defs
=
distance
(
range
.
first
,
range
.
second
);
}
// Check if option unpacking must be deferred
if
(
deferOption
(
option_space
,
opt_type
))
{
num_defs
=
0
;
}
OptionPtr
opt
;
if
(
num_defs
>
1
)
{
// Multiple options of the same code are not supported right now!
...
...
@@ -814,6 +829,11 @@ void
LibDHCP
::
initStdOptionDefs4
()
{
initOptionSpace
(
v4option_defs_
,
STANDARD_V4_OPTION_DEFINITIONS
,
STANDARD_V4_OPTION_DEFINITIONS_SIZE
);
last_resort_option43_def
.
reset
(
new
OptionDefinition
(
LAST_RESORT_OPTION43_DEFINITION
.
name
,
LAST_RESORT_OPTION43_DEFINITION
.
code
,
LAST_RESORT_OPTION43_DEFINITION
.
type
,
LAST_RESORT_OPTION43_DEFINITION
.
array
));
}
void
...
...
src/lib/dhcp/libdhcp++.h
View file @
042c0b6f
...
...
@@ -112,6 +112,19 @@ public:
static
OptionDefContainerPtr
getRuntimeOptionDefs
(
const
std
::
string
&
space
);
/// @brief Checks if an option unpacking has to be deferred.
///
/// DHCPv4 option 43 and 224-254 unpacking is done after classification.
///
/// @space Option space name.
/// @param code Option code.
///
/// @return True if option processing should be deferred.
static
bool
deferOption
(
const
std
::
string
&
space
,
const
uint16_t
code
);
/// @brief Last resort definition for DHCPv4 option 43
static
OptionDefinitionPtr
last_resort_option43_def
;
/// @brief Factory function to create instance of option.
///
/// Factory method creates instance of specified option. The option
...
...
src/lib/dhcp/std_option_defs.h
View file @
042c0b6f
...
...
@@ -124,8 +124,7 @@ const OptionDefParams STANDARD_V4_OPTION_DEFINITIONS[] = {
{
"nis-domain"
,
DHO_NIS_DOMAIN
,
OPT_STRING_TYPE
,
false
,
NO_RECORD_DEF
,
""
},
{
"nis-servers"
,
DHO_NIS_SERVERS
,
OPT_IPV4_ADDRESS_TYPE
,
true
,
NO_RECORD_DEF
,
""
},
{
"ntp-servers"
,
DHO_NTP_SERVERS
,
OPT_IPV4_ADDRESS_TYPE
,
true
,
NO_RECORD_DEF
,
""
},
{
"vendor-encapsulated-options"
,
DHO_VENDOR_ENCAPSULATED_OPTIONS
,
OPT_EMPTY_TYPE
,
false
,
NO_RECORD_DEF
,
"vendor-encapsulated-options-space"
},
/// vendor-encapsulated-options (43) is deferred
{
"netbios-name-servers"
,
DHO_NETBIOS_NAME_SERVERS
,
OPT_IPV4_ADDRESS_TYPE
,
true
,
NO_RECORD_DEF
,
""
},
{
"netbios-dd-server"
,
DHO_NETBIOS_DD_SERVER
,
...
...
@@ -217,6 +216,12 @@ const OptionDefParams STANDARD_V4_OPTION_DEFINITIONS[] = {
const
int
STANDARD_V4_OPTION_DEFINITIONS_SIZE
=
sizeof
(
STANDARD_V4_OPTION_DEFINITIONS
)
/
sizeof
(
STANDARD_V4_OPTION_DEFINITIONS
[
0
]);
/// Last resort definition for option 43
const
OptionDefParams
LAST_RESORT_OPTION43_DEFINITION
=
{
"vendor-encapsulated-options"
,
DHO_VENDOR_ENCAPSULATED_OPTIONS
,
OPT_EMPTY_TYPE
,
false
,
NO_RECORD_DEF
,
"vendor-encapsulated-options-space"
};
/// Start Definition of DHCPv6 options
// client-fqdn
...
...
src/lib/dhcp/tests/libdhcp++_unittest.cc
View file @
042c0b6f
...
...
@@ -862,6 +862,7 @@ TEST_F(LibDhcpTest, unpackOptions4) {
ASSERT_EQ
(
1
,
addresses
.
size
());
EXPECT_EQ
(
"10.0.0.10"
,
addresses
[
0
].
toText
());
#if 0
// Vendor Specific Information option
x = options.find(43);
ASSERT_FALSE(x == options.end());
...
...
@@ -876,6 +877,7 @@ TEST_F(LibDhcpTest, unpackOptions4) {
ASSERT_TRUE(eso);
EXPECT_EQ(0xdc, eso->getType());
EXPECT_EQ(2, eso->len());
#endif
// Checking DHCP Relay Agent Information Option.
x
=
options
.
find
(
DHO_DHCP_AGENT_OPTIONS
);
...
...
@@ -1174,6 +1176,7 @@ TEST_F(LibDhcpTest, stdOptionDefs4) {
LibDhcpTest
::
testStdOptionDefs4
(
DHO_NTP_SERVERS
,
begin
,
end
,
typeid
(
Option4AddrLst
));
#if 0
// The following option requires well formed buffer to be created from.
// Not just a dummy one. This buffer includes some suboptions.
OptionBuffer vendor_opts_buf = createVendorOption();
...
...
@@ -1182,6 +1185,7 @@ TEST_F(LibDhcpTest, stdOptionDefs4) {
vendor_opts_buf.end(),
typeid(OptionCustom),
"vendor-encapsulated-options-space");
#endif
LibDhcpTest
::
testStdOptionDefs4
(
DHO_NETBIOS_NAME_SERVERS
,
begin
,
end
,
typeid
(
Option4AddrLst
));
...
...
src/lib/dhcpsrv/client_class_def.cc
View file @
042c0b6f
...
...
@@ -45,6 +45,10 @@ ClientClassDef::ClientClassDef(const ClientClassDef& rhs)
*
match_expr_
=
*
(
rhs
.
match_expr_
);
}
if
(
rhs
.
cfg_option_def_
)
{
rhs
.
cfg_option_def_
->
copyTo
(
*
cfg_option_def_
);
}
if
(
rhs
.
cfg_option_
)
{
rhs
.
cfg_option_
->
copyTo
(
*
cfg_option_
);
}
...
...
@@ -87,6 +91,16 @@ ClientClassDef::setTest(const std::string& test) {
test_
=
test
;
}
const
CfgOptionDefPtr
&
ClientClassDef
::
getCfgOptionDef
()
const
{
return
(
cfg_option_def_
);
}
void
ClientClassDef
::
setCfgOptionDef
(
const
CfgOptionDefPtr
&
cfg_option_def
)
{
cfg_option_def_
=
cfg_option_def
;
}
const
CfgOptionPtr
&
ClientClassDef
::
getCfgOption
()
const
{
return
(
cfg_option_
);
...
...
@@ -106,6 +120,9 @@ ClientClassDef::equals(const ClientClassDef& other) const {
((
!
cfg_option_
&&
!
other
.
cfg_option_
)
||
(
cfg_option_
&&
other
.
cfg_option_
&&
(
*
cfg_option_
==
*
other
.
cfg_option_
)))
&&
((
!
cfg_option_def_
&&
!
other
.
cfg_option_def_
)
||
(
cfg_option_def_
&&
other
.
cfg_option_def_
&&
(
*
cfg_option_def_
==
*
other
.
cfg_option_def_
)))
&&
(
next_server_
==
other
.
next_server_
)
&&
(
sname_
==
other
.
sname_
)
&&
(
filename_
==
other
.
filename_
));
...
...
@@ -121,6 +138,10 @@ ClientClassDef:: toElement() const {
if
(
!
test_
.
empty
())
{
result
->
set
(
"test"
,
Element
::
create
(
test_
));
}
// Set option-def
if
(
cfg_option_def_
)
{
result
->
set
(
"option-def"
,
cfg_option_def_
->
toElement
());
}
// Set option-data
result
->
set
(
"option-data"
,
cfg_option_
->
toElement
());
if
(
family
!=
AF_INET
)
{
...
...
@@ -163,11 +184,13 @@ ClientClassDictionary::addClass(const std::string& name,
const
ExpressionPtr
&
match_expr
,
const
std
::
string
&
test
,
const
CfgOptionPtr
&
cfg_option
,
CfgOptionDefPtr
cfg_option_def
,
asiolink
::
IOAddress
next_server
,
const
std
::
string
&
sname
,
const
std
::
string
&
filename
)
{
ClientClassDefPtr
cclass
(
new
ClientClassDef
(
name
,
match_expr
,
cfg_option
));
cclass
->
setTest
(
test
);
cclass
->
setCfgOptionDef
(
cfg_option_def
);
cclass
->
setNextServer
(
next_server
);
cclass
->
setSname
(
sname
);
cclass
->
setFilename
(
filename
);
...
...
src/lib/dhcpsrv/client_class_def.h
View file @
042c0b6f
...
...
@@ -9,6 +9,7 @@
#include
<cc/cfg_to_element.h>
#include
<dhcpsrv/cfg_option.h>
#include
<dhcpsrv/cfg_option_def.h>
#include
<eval/token.h>
#include
<exceptions/exceptions.h>
...
...
@@ -79,6 +80,14 @@ public:
/// @param test the original expression to assign the class
void
setTest
(
const
std
::
string
&
test
);
/// @brief Fetches the class's option definitions
const
CfgOptionDefPtr
&
getCfgOptionDef
()
const
;
/// @brief Sets the class's option definition collection
///
/// @param cfg_option_def the option definitions to assign the class
void
setCfgOptionDef
(
const
CfgOptionDefPtr
&
cfg_option_def
);
/// @brief Fetches the class's option collection
const
CfgOptionPtr
&
getCfgOption
()
const
;
...
...
@@ -171,6 +180,9 @@ private:
/// this class.
std
::
string
test_
;
/// @brief The option definition configuration for this class
CfgOptionDefPtr
cfg_option_def_
;
/// @brief The option data configuration for this class
CfgOptionPtr
cfg_option_
;
...
...
@@ -223,6 +235,7 @@ public:
/// @param match_expr Expression the class will use to determine membership
/// @param test Original version of match_expr
/// @param options Collection of options members should be given
/// @param defs Option definitions (optional)
/// @param next_server next-server value for this class (optional)
/// @param sname server-name value for this class (optional)
/// @param filename boot-file-name value for this class (optional)
...
...
@@ -232,6 +245,7 @@ public:
/// others.
void
addClass
(
const
std
::
string
&
name
,
const
ExpressionPtr
&
match_expr
,
const
std
::
string
&
test
,
const
CfgOptionPtr
&
options
,
CfgOptionDefPtr
defs
=
0
,
asiolink
::
IOAddress
next_server
=
asiolink
::
IOAddress
(
"0.0.0.0"
),
const
std
::
string
&
sname
=
std
::
string
(),
const
std
::
string
&
filename
=
std
::
string
());
...
...
src/lib/dhcpsrv/parsers/client_class_def_parser.cc
View file @
042c0b6f
...
...
@@ -5,6 +5,7 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include
<config.h>
#include
<dhcp/libdhcp++.h>
#include
<dhcpsrv/cfgmgr.h>
#include
<dhcpsrv/client_class_def.h>
#include
<dhcpsrv/parsers/dhcp_parsers.h>
...
...
@@ -81,6 +82,33 @@ ClientClassDefParser::parse(ClientClassDictionaryPtr& class_dictionary,
test
=
test_cfg
->
stringValue
();
}
// Parse option def
CfgOptionDefPtr
defs
(
new
CfgOptionDef
());
ConstElementPtr
option_defs
=
class_def_cfg
->
get
(
"option-def"
);
if
(
option_defs
)
{
OptionDefParser
parser
;
BOOST_FOREACH
(
ConstElementPtr
option_def
,
option_defs
->
listValue
())
{
OptionDefinitionTuple
def
;
def
=
parser
.
parse
(
option_def
);
// Verify if the defition is for an option which are
// in a deferred processing list.
if
(
!
LibDHCP
::
deferOption
(
def
.
second
,
def
.
first
->
getCode
()))
{
isc_throw
(
DhcpConfigError
,
"Not allowed option definition for code '"
<<
def
.
first
->
getCode
()
<<
"' in space '"
<<
def
.
second
<<
"' at ("
<<
option_def
->
getPosition
()
<<
")"
);
}
try
{
defs
->
add
(
def
.
first
,
def
.
second
);
}
catch
(
const
std
::
exception
&
ex
)
{
isc_throw
(
DhcpConfigError
,
ex
.
what
()
<<
" ("
<<
option_def
->
getPosition
()
<<
")"
);
}
}
}
// Parse option data
CfgOptionPtr
options
(
new
CfgOption
());
ConstElementPtr
option_data
=
class_def_cfg
->
get
(
"option-data"
);
...
...
@@ -145,7 +173,7 @@ ClientClassDefParser::parse(ClientClassDictionaryPtr& class_dictionary,
// Add the client class definition
try
{
class_dictionary
->
addClass
(
name
,
match_expr
,
test
,
options
,
next_server
,
sname
,
filename
);
defs
,
next_server
,
sname
,
filename
);
}
catch
(
const
std
::
exception
&
ex
)
{
isc_throw
(
DhcpConfigError
,
"Can't add class: "
<<
ex
.
what
()
<<
" ("
<<
class_def_cfg
->
getPosition
()
<<
")"
);
...
...
src/lib/dhcpsrv/parsers/client_class_def_parser.h
View file @
042c0b6f
...
...
@@ -17,8 +17,8 @@
///
/// These parsers are used to parse lists of client class definitions
/// into a ClientClassDictionary of ClientClassDef instances. Each
/// ClientClassDef consists of (at least) a name, an expression,
and
/// option-data.
The latter two are currently optional
.
/// ClientClassDef consists of (at least) a name, an expression,
option-def
///
and
option-data.
Currently only a not empty name is required
.
///
/// There parsers defined are:
///
...
...
@@ -36,6 +36,11 @@
/// -# "test" - a string containing the logical expression used to determine
/// membership in the class. This is passed into the eval parser.
///
/// -# "option-def" - a list which defines the options which processing
/// is deferred. This element is optional and parsed using the @ref
/// isc::dhcp::OptionDefParser. A check is done to verify definitions
/// are only for deferred processing option (DHCPv4 43 and 224-254).
///
/// -# "option-data" - a list which defines the options that should be
/// assigned to remembers of the class. This element is optional and parsed
/// using the @ref isc::dhcp::OptionDataListParser.
...
...
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