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
Adam Osuchowski
Kea
Commits
894aeb04
Commit
894aeb04
authored
Aug 10, 2017
by
Thomas Markwalder
Browse files
Options
Browse Files
Download
Plain Diff
[master] Added subnet manipulation support
Merge branch 'trac5314'
parents
fde84942
ac93de29
Changes
16
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
663 additions
and
494 deletions
+663
-494
src/bin/dhcp4/tests/get_config_unittest.cc
src/bin/dhcp4/tests/get_config_unittest.cc
+0
-56
src/bin/dhcp6/tests/get_config_unittest.cc
src/bin/dhcp6/tests/get_config_unittest.cc
+0
-126
src/lib/config/hooked_command_mgr.cc
src/lib/config/hooked_command_mgr.cc
+9
-12
src/lib/config/hooked_command_mgr.h
src/lib/config/hooked_command_mgr.h
+0
-10
src/lib/dhcpsrv/cfg_subnets4.cc
src/lib/dhcpsrv/cfg_subnets4.cc
+15
-100
src/lib/dhcpsrv/cfg_subnets4.h
src/lib/dhcpsrv/cfg_subnets4.h
+36
-0
src/lib/dhcpsrv/cfg_subnets6.cc
src/lib/dhcpsrv/cfg_subnets6.cc
+15
-165
src/lib/dhcpsrv/cfg_subnets6.h
src/lib/dhcpsrv/cfg_subnets6.h
+37
-1
src/lib/dhcpsrv/pool.cc
src/lib/dhcpsrv/pool.cc
+107
-0
src/lib/dhcpsrv/pool.h
src/lib/dhcpsrv/pool.h
+15
-0
src/lib/dhcpsrv/subnet.cc
src/lib/dhcpsrv/subnet.cc
+216
-0
src/lib/dhcpsrv/subnet.h
src/lib/dhcpsrv/subnet.h
+108
-11
src/lib/dhcpsrv/tests/alloc_engine_utils.cc
src/lib/dhcpsrv/tests/alloc_engine_utils.cc
+2
-0
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
src/lib/dhcpsrv/tests/cfg_subnets4_unittest.cc
+51
-2
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc
src/lib/dhcpsrv/tests/cfg_subnets6_unittest.cc
+51
-9
src/lib/dhcpsrv/tests/srv_config_unittest.cc
src/lib/dhcpsrv/tests/srv_config_unittest.cc
+1
-2
No files found.
src/bin/dhcp4/tests/get_config_unittest.cc
View file @
894aeb04
This diff is collapsed.
Click to expand it.
src/bin/dhcp6/tests/get_config_unittest.cc
View file @
894aeb04
This diff is collapsed.
Click to expand it.
src/lib/config/hooked_command_mgr.cc
View file @
894aeb04
...
...
@@ -7,6 +7,7 @@
#include <cc/command_interpreter.h>
#include <config/hooked_command_mgr.h>
#include <config/config_log.h>
#include <hooks/callout_handle.h>
#include <hooks/hooks_manager.h>
#include <hooks/server_hooks.h>
#include <boost/pointer_cast.hpp>
...
...
@@ -19,7 +20,7 @@ namespace isc {
namespace
config
{
HookedCommandMgr
::
HookedCommandMgr
()
:
BaseCommandMgr
()
,
callout_handle_
(
HooksManager
::
createCalloutHandle
())
{
:
BaseCommandMgr
()
{
}
bool
...
...
@@ -31,25 +32,25 @@ HookedCommandMgr::delegateCommandToHookLibrary(const std::string& cmd_name,
ConstElementPtr
hook_response
;
if
(
HooksManager
::
commandHandlersPresent
(
cmd_name
))
{
callout_handle
_
=
HooksManager
::
createCalloutHandle
();
CalloutHandlePtr
callout_handle
=
HooksManager
::
createCalloutHandle
();
// Set status to normal.
callout_handle
_
->
setStatus
(
CalloutHandle
::
NEXT_STEP_CONTINUE
);
callout_handle
->
setStatus
(
CalloutHandle
::
NEXT_STEP_CONTINUE
);
// Delete previously set arguments.
callout_handle
_
->
deleteAllArguments
();
callout_handle
->
deleteAllArguments
();
ConstElementPtr
command
=
original_cmd
?
original_cmd
:
createCommand
(
cmd_name
,
params
);
// And pass it to the hook library.
callout_handle
_
->
setArgument
(
"command"
,
command
);
callout_handle
_
->
setArgument
(
"response"
,
hook_response
);
callout_handle
->
setArgument
(
"command"
,
command
);
callout_handle
->
setArgument
(
"response"
,
hook_response
);
HooksManager
::
callCommandHandlers
(
cmd_name
,
*
callout_handle
_
);
HooksManager
::
callCommandHandlers
(
cmd_name
,
*
callout_handle
);
// The callouts should set the response.
callout_handle
_
->
getArgument
(
"response"
,
hook_response
);
callout_handle
->
getArgument
(
"response"
,
hook_response
);
answer
=
boost
::
const_pointer_cast
<
Element
>
(
hook_response
);
...
...
@@ -63,10 +64,6 @@ ConstElementPtr
HookedCommandMgr
::
handleCommand
(
const
std
::
string
&
cmd_name
,
const
ConstElementPtr
&
params
,
const
ConstElementPtr
&
original_cmd
)
{
if
(
!
callout_handle_
)
{
isc_throw
(
Unexpected
,
"callout handle not configured for the Command "
"Manager: this is a programming error"
);
}
// The 'list-commands' is a special case. Hook libraries do not implement
// this command. We determine what commands are supported by the hook
...
...
src/lib/config/hooked_command_mgr.h
View file @
894aeb04
...
...
@@ -9,7 +9,6 @@
#include <cc/data.h>
#include <config/base_command_mgr.h>
#include <hooks/callout_handle.h>
namespace
isc
{
namespace
config
{
...
...
@@ -47,13 +46,6 @@ public:
protected:
/// @brief Returns callout handle to the derived class.
///
/// @return const pointer to the callout handle.
const
isc
::
hooks
::
CalloutHandlePtr
&
getCalloutHandle
()
const
{
return
(
callout_handle_
);
}
/// @brief Handles the command within the hooks libraries.
///
/// This method checks if the hooks libraries are installed which implement
...
...
@@ -91,8 +83,6 @@ protected:
const
isc
::
data
::
ConstElementPtr
&
params
,
const
isc
::
data
::
ConstElementPtr
&
original_cmd
);
/// @brief Pointer to a callout handle used by this class.
isc
::
hooks
::
CalloutHandlePtr
callout_handle_
;
};
}
// end of namespace isc::config
...
...
src/lib/dhcpsrv/cfg_subnets4.cc
View file @
894aeb04
...
...
@@ -34,6 +34,20 @@ CfgSubnets4::add(const Subnet4Ptr& subnet) {
subnets_
.
push_back
(
subnet
);
}
ConstSubnet4Ptr
CfgSubnets4
::
getBySubnetId
(
const
SubnetID
&
subnet_id
)
const
{
const
auto
&
index
=
subnets_
.
get
<
SubnetSubnetIdIndexTag
>
();
auto
subnet_it
=
index
.
find
(
subnet_id
);
return
((
subnet_it
!=
index
.
cend
())
?
(
*
subnet_it
)
:
ConstSubnet4Ptr
());
}
ConstSubnet4Ptr
CfgSubnets4
::
getByPrefix
(
const
std
::
string
&
subnet_text
)
const
{
const
auto
&
index
=
subnets_
.
get
<
SubnetPrefixIndexTag
>
();
auto
subnet_it
=
index
.
find
(
subnet_text
);
return
((
subnet_it
!=
index
.
cend
())
?
(
*
subnet_it
)
:
ConstSubnet4Ptr
());
}
Subnet4Ptr
CfgSubnets4
::
selectSubnet4o6
(
const
SubnetSelector
&
selector
)
const
{
...
...
@@ -297,106 +311,7 @@ CfgSubnets4::toElement() const {
// Iterate subnets
for
(
Subnet4Collection
::
const_iterator
subnet
=
subnets_
.
cbegin
();
subnet
!=
subnets_
.
cend
();
++
subnet
)
{
// Prepare the map
ElementPtr
map
=
Element
::
createMap
();
// Set subnet id
SubnetID
id
=
(
*
subnet
)
->
getID
();
map
->
set
(
"id"
,
Element
::
create
(
static_cast
<
long
long
>
(
id
)));
// Set relay info
const
Subnet
::
RelayInfo
&
relay_info
=
(
*
subnet
)
->
getRelayInfo
();
ElementPtr
relay
=
Element
::
createMap
();
relay
->
set
(
"ip-address"
,
Element
::
create
(
relay_info
.
addr_
.
toText
()));
map
->
set
(
"relay"
,
relay
);
// Set subnet
map
->
set
(
"subnet"
,
Element
::
create
((
*
subnet
)
->
toText
()));
// Set interface
const
std
::
string
&
iface
=
(
*
subnet
)
->
getIface
();
map
->
set
(
"interface"
,
Element
::
create
(
iface
));
// Set renew-timer
map
->
set
(
"renew-timer"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getT1
().
get
())));
// Set rebind-timer
map
->
set
(
"rebind-timer"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getT2
().
get
())));
// Set valid-lifetime
map
->
set
(
"valid-lifetime"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getValid
().
get
())));
// Set pools
const
PoolCollection
&
pools
=
(
*
subnet
)
->
getPools
(
Lease
::
TYPE_V4
);
ElementPtr
pool_list
=
Element
::
createList
();
for
(
PoolCollection
::
const_iterator
pool
=
pools
.
cbegin
();
pool
!=
pools
.
cend
();
++
pool
)
{
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr
pool_map
=
Element
::
createMap
();
// Set pool
const
IOAddress
&
first
=
(
*
pool
)
->
getFirstAddress
();
const
IOAddress
&
last
=
(
*
pool
)
->
getLastAddress
();
std
::
string
range
=
first
.
toText
()
+
"-"
+
last
.
toText
();
// Try to output a prefix (vs a range)
int
prefix_len
=
prefixLengthFromRange
(
first
,
last
);
if
(
prefix_len
>=
0
)
{
std
::
ostringstream
oss
;
oss
<<
first
.
toText
()
<<
"/"
<<
prefix_len
;
range
=
oss
.
str
();
}
pool_map
->
set
(
"pool"
,
Element
::
create
(
range
));
// Set user-context
ConstElementPtr
context
=
(
*
pool
)
->
getContext
();
if
(
!
isNull
(
context
))
{
pool_map
->
set
(
"user-context"
,
context
);
}
// Set pool options
ConstCfgOptionPtr
opts
=
(
*
pool
)
->
getCfgOption
();
pool_map
->
set
(
"option-data"
,
opts
->
toElement
());
// Push on the pool list
pool_list
->
add
(
pool_map
);
}
map
->
set
(
"pools"
,
pool_list
);
// Set host reservation-mode
Subnet
::
HRMode
hrmode
=
(
*
subnet
)
->
getHostReservationMode
();
std
::
string
mode
;
switch
(
hrmode
)
{
case
Subnet
::
HR_DISABLED
:
mode
=
"disabled"
;
break
;
case
Subnet
::
HR_OUT_OF_POOL
:
mode
=
"out-of-pool"
;
break
;
case
Subnet
::
HR_ALL
:
mode
=
"all"
;
break
;
default:
isc_throw
(
ToElementError
,
"invalid host reservation mode: "
<<
hrmode
);
}
map
->
set
(
"reservation-mode"
,
Element
::
create
(
mode
));
// Set match-client-id
map
->
set
(
"match-client-id"
,
Element
::
create
((
*
subnet
)
->
getMatchClientId
()));
// Set next-server
map
->
set
(
"next-server"
,
Element
::
create
((
*
subnet
)
->
getSiaddr
().
toText
()));
// Set DHCP4o6
const
Cfg4o6
&
d4o6
=
(
*
subnet
)
->
get4o6
();
isc
::
data
::
merge
(
map
,
d4o6
.
toElement
());
// Set client-class
const
ClientClasses
&
cclasses
=
(
*
subnet
)
->
getClientClasses
();
if
(
cclasses
.
size
()
>
1
)
{
isc_throw
(
ToElementError
,
"client-class has too many items: "
<<
cclasses
.
size
());
}
else
if
(
!
cclasses
.
empty
())
{
map
->
set
(
"client-class"
,
Element
::
create
(
*
cclasses
.
cbegin
()));
}
// Set options
ConstCfgOptionPtr
opts
=
(
*
subnet
)
->
getCfgOption
();
map
->
set
(
"option-data"
,
opts
->
toElement
());
// Not supported: interface-id
// Not supported: rapid-commit
// Push on the list
result
->
add
(
map
);
result
->
add
((
*
subnet
)
->
toElement
());
}
return
(
result
);
}
...
...
src/lib/dhcpsrv/cfg_subnets4.h
View file @
894aeb04
...
...
@@ -10,8 +10,10 @@
#include <asiolink/io_address.h>
#include <cc/cfg_to_element.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/subnet_selector.h>
#include <boost/shared_ptr.hpp>
#include <string>
namespace
isc
{
namespace
dhcp
{
...
...
@@ -48,6 +50,40 @@ public:
return
(
&
subnets_
);
}
/// @brief Returns const pointer to a subnet identified by the specified
/// subnet identifier.
///
/// The const pointer is returned by this method to prevent a caller from
/// modifying the subnet configuration. Modifications to subnet configuration
/// is dangerous and must be done carefully. The subnets' configruation is
/// held in the multi index container and any modifications to the subnet
/// id or subnet prefix must trigger re-indexing of multi index container.
/// There is no possibility to enforce this when the non-const pointer is
/// returned.
///
/// @param subnet_id Subnet identifier.
///
/// @return Pointer to the @c Subnet4 object or null pointer if such
/// subnet doesn't exist.
ConstSubnet4Ptr
getBySubnetId
(
const
SubnetID
&
subnet_id
)
const
;
/// @brief Returns const pointer to a subnet which matches the specified
/// prefix in the canonical form.
///
/// The const pointer is returned by this method to prevent a caller from
/// modifying the subnet configuration. Modifications to subnet configuration
/// is dangerous and must be done carefully. The subnets' configruation is
/// held in the multi index container and any modifications to the subnet
/// id or subnet prefix must trigger re-indexing of multi index container.
/// There is no possibility to enforce this when the non-const pointer is
/// returned.
///
/// @param subnet_prefix Subnet prefix, e.g. 10.2.3.0/24
///
/// @return Pointer to the @c Subnet4 object or null pointer if such
/// subnet doesn't exist.
ConstSubnet4Ptr
getByPrefix
(
const
std
::
string
&
subnet_prefix
)
const
;
/// @brief Returns a pointer to the selected subnet.
///
/// This method tries to retrieve the subnet for the client using various
...
...
src/lib/dhcpsrv/cfg_subnets6.cc
View file @
894aeb04
...
...
@@ -33,6 +33,20 @@ CfgSubnets6::add(const Subnet6Ptr& subnet) {
subnets_
.
push_back
(
subnet
);
}
ConstSubnet6Ptr
CfgSubnets6
::
getBySubnetId
(
const
SubnetID
&
subnet_id
)
const
{
const
auto
&
index
=
subnets_
.
get
<
SubnetSubnetIdIndexTag
>
();
auto
subnet_it
=
index
.
find
(
subnet_id
);
return
((
subnet_it
!=
index
.
cend
())
?
(
*
subnet_it
)
:
ConstSubnet6Ptr
());
}
ConstSubnet6Ptr
CfgSubnets6
::
getByPrefix
(
const
std
::
string
&
subnet_text
)
const
{
const
auto
&
index
=
subnets_
.
get
<
SubnetPrefixIndexTag
>
();
auto
subnet_it
=
index
.
find
(
subnet_text
);
return
((
subnet_it
!=
index
.
cend
())
?
(
*
subnet_it
)
:
ConstSubnet6Ptr
());
}
Subnet6Ptr
CfgSubnets6
::
selectSubnet
(
const
SubnetSelector
&
selector
)
const
{
Subnet6Ptr
subnet
;
...
...
@@ -254,171 +268,7 @@ CfgSubnets6::toElement() const {
// Iterate subnets
for
(
Subnet6Collection
::
const_iterator
subnet
=
subnets_
.
cbegin
();
subnet
!=
subnets_
.
cend
();
++
subnet
)
{
// Prepare the map
ElementPtr
map
=
Element
::
createMap
();
// Set subnet id
SubnetID
id
=
(
*
subnet
)
->
getID
();
map
->
set
(
"id"
,
Element
::
create
(
static_cast
<
long
long
>
(
id
)));
// Set relay info
const
Subnet
::
RelayInfo
&
relay_info
=
(
*
subnet
)
->
getRelayInfo
();
ElementPtr
relay
=
Element
::
createMap
();
relay
->
set
(
"ip-address"
,
Element
::
create
(
relay_info
.
addr_
.
toText
()));
map
->
set
(
"relay"
,
relay
);
// Set subnet
map
->
set
(
"subnet"
,
Element
::
create
((
*
subnet
)
->
toText
()));
// Set interface
const
std
::
string
&
iface
=
(
*
subnet
)
->
getIface
();
map
->
set
(
"interface"
,
Element
::
create
(
iface
));
// Set interface-id
const
OptionPtr
&
ifaceid
=
(
*
subnet
)
->
getInterfaceId
();
if
(
ifaceid
)
{
std
::
vector
<
uint8_t
>
bin
=
ifaceid
->
getData
();
std
::
string
ifid
;
ifid
.
resize
(
bin
.
size
());
if
(
!
bin
.
empty
())
{
std
::
memcpy
(
&
ifid
[
0
],
&
bin
[
0
],
bin
.
size
());
}
map
->
set
(
"interface-id"
,
Element
::
create
(
ifid
));
}
else
{
map
->
set
(
"interface-id"
,
Element
::
create
(
std
::
string
()));
}
// Set renew-timer
map
->
set
(
"renew-timer"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getT1
().
get
())));
// Set rebind-timer
map
->
set
(
"rebind-timer"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getT2
().
get
())));
// Set preferred-lifetime
map
->
set
(
"preferred-lifetime"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getPreferred
().
get
())));
// Set valid-lifetime
map
->
set
(
"valid-lifetime"
,
Element
::
create
(
static_cast
<
long
long
>
((
*
subnet
)
->
getValid
().
get
())));
// Set rapid-commit
bool
rapid_commit
=
(
*
subnet
)
->
getRapidCommit
();
map
->
set
(
"rapid-commit"
,
Element
::
create
(
rapid_commit
));
// Set pools
const
PoolCollection
&
pools
=
(
*
subnet
)
->
getPools
(
Lease
::
TYPE_NA
);
ElementPtr
pool_list
=
Element
::
createList
();
for
(
PoolCollection
::
const_iterator
pool
=
pools
.
cbegin
();
pool
!=
pools
.
cend
();
++
pool
)
{
// Prepare the map for a pool (@todo move this code to pool.cc)
ElementPtr
pool_map
=
Element
::
createMap
();
// Set pool
const
IOAddress
&
first
=
(
*
pool
)
->
getFirstAddress
();
const
IOAddress
&
last
=
(
*
pool
)
->
getLastAddress
();
std
::
string
range
=
first
.
toText
()
+
"-"
+
last
.
toText
();
// Try to output a prefix (vs a range)
int
prefix_len
=
prefixLengthFromRange
(
first
,
last
);
if
(
prefix_len
>=
0
)
{
std
::
ostringstream
oss
;
oss
<<
first
.
toText
()
<<
"/"
<<
prefix_len
;
range
=
oss
.
str
();
}
pool_map
->
set
(
"pool"
,
Element
::
create
(
range
));
// Set user-context
ConstElementPtr
context
=
(
*
pool
)
->
getContext
();
if
(
!
isNull
(
context
))
{
pool_map
->
set
(
"user-context"
,
context
);
}
// Set pool options
ConstCfgOptionPtr
opts
=
(
*
pool
)
->
getCfgOption
();
pool_map
->
set
(
"option-data"
,
opts
->
toElement
());
// Push on the pool list
pool_list
->
add
(
pool_map
);
}
map
->
set
(
"pools"
,
pool_list
);
// Set pd-pools
const
PoolCollection
&
pdpools
=
(
*
subnet
)
->
getPools
(
Lease
::
TYPE_PD
);
ElementPtr
pdpool_list
=
Element
::
createList
();
for
(
PoolCollection
::
const_iterator
pool
=
pdpools
.
cbegin
();
pool
!=
pdpools
.
cend
();
++
pool
)
{
// Get it as a Pool6 (@todo move this code to pool.cc)
const
Pool6
*
pdpool
=
dynamic_cast
<
Pool6
*>
(
pool
->
get
());
if
(
!
pdpool
)
{
isc_throw
(
ToElementError
,
"invalid pd-pool pointer"
);
}
// Prepare the map for a pd-pool
ElementPtr
pool_map
=
Element
::
createMap
();
// Set prefix
const
IOAddress
&
prefix
=
pdpool
->
getFirstAddress
();
pool_map
->
set
(
"prefix"
,
Element
::
create
(
prefix
.
toText
()));
// Set prefix-len (get it from min - max)
const
IOAddress
&
last
=
pdpool
->
getLastAddress
();
int
prefix_len
=
prefixLengthFromRange
(
prefix
,
last
);
if
(
prefix_len
<
0
)
{
// The pool is bad: give up
isc_throw
(
ToElementError
,
"invalid prefix range "
<<
prefix
.
toText
()
<<
"-"
<<
last
.
toText
());
}
pool_map
->
set
(
"prefix-len"
,
Element
::
create
(
prefix_len
));
// Set delegated-len
uint8_t
len
=
pdpool
->
getLength
();
pool_map
->
set
(
"delegated-len"
,
Element
::
create
(
static_cast
<
int
>
(
len
)));
// Set excluded prefix
const
Option6PDExcludePtr
&
xopt
=
pdpool
->
getPrefixExcludeOption
();
if
(
xopt
)
{
const
IOAddress
&
xprefix
=
xopt
->
getExcludedPrefix
(
prefix
,
len
);
pool_map
->
set
(
"excluded-prefix"
,
Element
::
create
(
xprefix
.
toText
()));
uint8_t
xlen
=
xopt
->
getExcludedPrefixLength
();
pool_map
->
set
(
"excluded-prefix-len"
,
Element
::
create
(
static_cast
<
int
>
(
xlen
)));
}
else
{
pool_map
->
set
(
"excluded-prefix"
,
Element
::
create
(
std
::
string
(
"::"
)));
pool_map
->
set
(
"excluded-prefix-len"
,
Element
::
create
(
0
));
}
// Set user-context
ConstElementPtr
context
=
pdpool
->
getContext
();
if
(
!
isNull
(
context
))
{
pool_map
->
set
(
"user-context"
,
context
);
}
// Set pool options
ConstCfgOptionPtr
opts
=
pdpool
->
getCfgOption
();
pool_map
->
set
(
"option-data"
,
opts
->
toElement
());
// Push on the pool list
pdpool_list
->
add
(
pool_map
);
}
map
->
set
(
"pd-pools"
,
pdpool_list
);
// Set host reservation-mode
Subnet
::
HRMode
hrmode
=
(
*
subnet
)
->
getHostReservationMode
();
std
::
string
mode
;
switch
(
hrmode
)
{
case
Subnet
::
HR_DISABLED
:
mode
=
"disabled"
;
break
;
case
Subnet
::
HR_OUT_OF_POOL
:
mode
=
"out-of-pool"
;
break
;
case
Subnet
::
HR_ALL
:
mode
=
"all"
;
break
;
default:
isc_throw
(
ToElementError
,
"invalid host reservation mode: "
<<
hrmode
);
}
map
->
set
(
"reservation-mode"
,
Element
::
create
(
mode
));
// Set client-class
const
ClientClasses
&
cclasses
=
(
*
subnet
)
->
getClientClasses
();
if
(
cclasses
.
size
()
>
1
)
{
isc_throw
(
ToElementError
,
"client-class has too many items: "
<<
cclasses
.
size
());
}
else
if
(
!
cclasses
.
empty
())
{
map
->
set
(
"client-class"
,
Element
::
create
(
*
cclasses
.
cbegin
()));
}
// Set options
ConstCfgOptionPtr
opts
=
(
*
subnet
)
->
getCfgOption
();
map
->
set
(
"option-data"
,
opts
->
toElement
());
// Push on the list
result
->
add
(
map
);
result
->
add
((
*
subnet
)
->
toElement
());
}
return
(
result
);
}
...
...
src/lib/dhcpsrv/cfg_subnets6.h
View file @
894aeb04
// Copyright (C) 2014-
2015,
2017 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-2017 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
...
...
@@ -11,9 +11,11 @@
#include <dhcp/option.h>
#include <cc/cfg_to_element.h>
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/subnet_id.h>
#include <dhcpsrv/subnet_selector.h>
#include <util/optional_value.h>
#include <boost/shared_ptr.hpp>
#include <string>
namespace
isc
{
namespace
dhcp
{
...
...
@@ -49,6 +51,40 @@ public:
return
(
&
subnets_
);
}
/// @brief Returns const pointer to a subnet identified by the specified
/// subnet identifier.
///
/// The const pointer is returned by this method to prevent a caller from
/// modifying the subnet configuration. Modifications to subnet configuration
/// is dangerous and must be done carefully. The subnets' configuration is
/// held in the multi index container and any modifications to the subnet
/// id or subnet prefix must trigger re-indexing of multi index container.
/// There is no possibility to enforce this when the non-const pointer is
/// returned.
///
/// @param subnet_id Subnet identifier.
///
/// @return Pointer to the @c Subnet6 object or null pointer if such
/// subnet doesn't exist.
ConstSubnet6Ptr
getBySubnetId
(
const
SubnetID
&
subnet_id
)
const
;
/// @brief Returns const pointer to a subnet which matches the specified
/// prefix in the canonical form.
///
/// The const pointer is returned by this method to prevent a caller from
/// modifying the subnet configuration. Modifications to subnet configuration
/// is dangerous and must be done carefully. The subnets' configruation is
/// held in the multi index container and any modifications to the subnet
/// id or subnet prefix must trigger re-indexing of multi index container.
/// There is no possibility to enforce this when the non-const pointer is
/// returned.
///
/// @param subnet_prefix Subnet prefix, e.g. 2001:db8:1::/64
///
/// @return Pointer to the @c Subnet6 object or null pointer if such
/// subnet doesn't exist.
ConstSubnet6Ptr
getByPrefix
(
const
std
::
string
&
subnet_prefix
)
const
;
/// @brief Selects a subnet using parameters specified in the selector.
///
/// This method tries to retrieve the subnet for the client using various
...
...
src/lib/dhcpsrv/pool.cc
View file @
894aeb04
...
...
@@ -10,6 +10,7 @@
#include <sstream>
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
data
;
namespace
isc
{
namespace
dhcp
{
...
...
@@ -74,6 +75,46 @@ Pool4::Pool4( const isc::asiolink::IOAddress& prefix, uint8_t prefix_len)
capacity_
=
addrsInRange
(
prefix
,
last_
);
}
data
::
ElementPtr
Pool
::
toElement
()
const
{
// Prepare the map
ElementPtr
map
=
Element
::
createMap
();
// Set user-context
ConstElementPtr
context
=
getContext
();
if
(
!
isNull
(
context
))
{
map
->
set
(
"user-context"
,
context
);
}
// Set pool options
ConstCfgOptionPtr
opts
=
getCfgOption
();
map
->
set
(
"option-data"
,
opts
->
toElement
());
return
(
map
);
}
data
::
ElementPtr
Pool4
::
toElement
()
const
{
// Prepare the map
ElementPtr
map
=
Pool
::
toElement
();
// Set pool
const
IOAddress
&
first
=
getFirstAddress
();
const
IOAddress
&
last
=
getLastAddress
();
std
::
string
range
=
first
.
toText
()
+
"-"
+
last
.
toText
();
// Try to output a prefix (vs a range)
int
prefix_len
=
prefixLengthFromRange
(
first
,
last
);
if
(
prefix_len
>=
0
)
{
std
::
ostringstream
oss
;
oss
<<
first
.
toText
()
<<
"/"
<<
prefix_len
;
range
=
oss
.
str
();
}
map
->
set
(
"pool"
,
Element
::
create
(
range
));
return
(
map
);
}
Pool6
::
Pool6
(
Lease
::
Type
type
,
const
isc
::
asiolink
::
IOAddress
&
first
,
const
isc
::
asiolink
::
IOAddress
&
last
)
:
Pool
(
type
,
first
,
last
),
prefix_len_
(
128
),
pd_exclude_option_
()
{
...
...
@@ -235,6 +276,72 @@ Pool6::init(const Lease::Type& type,
}
}
data
::
ElementPtr
Pool6
::
toElement
()
const
{
// Prepare the map
ElementPtr
map
=
Pool
::
toElement
();
switch
(
getType
())
{
case
Lease
::
TYPE_NA
:
{
const
IOAddress
&
first
=
getFirstAddress
();
const
IOAddress
&
last
=
getLastAddress
();
std
::
string
range
=
first
.
toText
()
+
"-"
+
last
.
toText
();
// Try to output a prefix (vs a range)
int
prefix_len
=
prefixLengthFromRange
(
first
,
last
);
if
(
prefix_len
>=
0
)
{
std
::
ostringstream
oss
;
oss
<<
first
.
toText
()
<<
"/"
<<
prefix_len
;
range
=
oss
.
str
();
}