Skip to content
GitLab
Menu
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
94280840
Commit
94280840
authored
Apr 27, 2016
by
Marcin Siodelski
Browse files
[master] Merge branch 'trac4303'
parents
a0477d9f
97f5350c
Changes
26
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/dhcp4_srv.cc
View file @
94280840
...
...
@@ -22,6 +22,7 @@
#include <dhcpsrv/addr_utilities.h>
#include <dhcpsrv/callout_handle_store.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/cfg_host_operations.h>
#include <dhcpsrv/cfg_subnets4.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
...
...
@@ -137,9 +138,17 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
.
arg
(
query
->
getLabel
())
.
arg
(
subnet
->
getID
());
}
// Find static reservations if not disabled for our subnet.
if
(
subnet
->
getHostReservationMode
()
!=
Subnet
::
HR_DISABLED
)
{
// Before we can check for static reservations, we need to prepare a set
// of identifiers to be used for this.
setHostIdentifiers
();
// Check for static reservations.
alloc_engine
->
findReservation
(
*
context_
);
}
}
// Check for static reservations.
alloc_engine
->
findReservation
(
*
context_
);
};
void
...
...
@@ -232,6 +241,60 @@ Dhcpv4Exchange::copyDefaultOptions() {
}
}
void
Dhcpv4Exchange
::
setHostIdentifiers
()
{
const
ConstCfgHostOperationsPtr
cfg
=
CfgMgr
::
instance
().
getCurrentCfg
()
->
getCfgHostOperations4
();
// Collect host identifiers. The identifiers are stored in order of preference.
// The server will use them in that order to search for host reservations.
BOOST_FOREACH
(
const
Host
::
IdentifierType
&
id_type
,
cfg
->
getIdentifierTypes
())
{
switch
(
id_type
)
{
case
Host
::
IDENT_HWADDR
:
if
(
context_
->
hwaddr_
&&
!
context_
->
hwaddr_
->
hwaddr_
.
empty
())
{
context_
->
addHostIdentifier
(
id_type
,
context_
->
hwaddr_
->
hwaddr_
);
}
break
;
case
Host
::
IDENT_DUID
:
if
(
context_
->
clientid_
)
{
const
std
::
vector
<
uint8_t
>&
vec
=
context_
->
clientid_
->
getDuid
();
if
(
!
vec
.
empty
())
{
// Client identifier type = DUID? Client identifier holding a DUID
// comprises Type (1 byte), IAID (4 bytes), followed by the actual
// DUID. Thus, the minimal length is 6.
if
((
vec
[
0
]
==
CLIENT_ID_OPTION_TYPE_DUID
)
&&
(
vec
.
size
()
>
5
))
{
// Extract DUID, skip IAID.
context_
->
addHostIdentifier
(
id_type
,
std
::
vector
<
uint8_t
>
(
vec
.
begin
()
+
5
,
vec
.
end
()));
}
/// @todo Add support for other client identifiers (see #4317).
}
}
break
;
case
Host
::
IDENT_CIRCUIT_ID
:
{
OptionPtr
rai
=
query_
->
getOption
(
DHO_DHCP_AGENT_OPTIONS
);
if
(
rai
)
{
OptionPtr
circuit_id_opt
=
rai
->
getOption
(
RAI_OPTION_AGENT_CIRCUIT_ID
);
if
(
circuit_id_opt
)
{
const
OptionBuffer
&
circuit_id_vec
=
circuit_id_opt
->
getData
();
if
(
!
circuit_id_vec
.
empty
())
{
context_
->
addHostIdentifier
(
id_type
,
circuit_id_vec
);
}
}
}
}
break
;
default:
;
}
}
}
const
std
::
string
Dhcpv4Srv
::
VENDOR_CLASS_PREFIX
(
"VENDOR_CLASS_"
);
Dhcpv4Srv
::
Dhcpv4Srv
(
uint16_t
port
,
const
bool
use_bcast
,
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
94280840
...
...
@@ -137,6 +137,14 @@ private:
/// not NULL.
void
copyDefaultOptions
();
/// @brief Set host identifiers within a context.
///
/// This method sets an ordered list of host identifier types and
/// values which the server should use to find host reservations.
/// The order of the set is determined by the configuration parameter,
/// host-reservation-identifiers
void
setHostIdentifiers
();
/// @brief Pointer to the allocation engine used by the server.
AllocEnginePtr
alloc_engine_
;
/// @brief Pointer to the DHCPv4 message sent by the client.
...
...
src/bin/dhcp4/json_config_parser.cc
View file @
94280840
...
...
@@ -448,6 +448,8 @@ DhcpConfigParser* createGlobalDhcp4ConfigParser(const std::string& config_id,
parser
=
new
ExpirationConfigParser
();
}
else
if
(
config_id
.
compare
(
"client-classes"
)
==
0
)
{
parser
=
new
ClientClassDefListParser
(
config_id
,
globalContext
());
}
else
if
(
config_id
.
compare
(
"host-reservation-identifiers"
)
==
0
)
{
parser
=
new
HostReservationIdsParser4
();
}
else
{
isc_throw
(
DhcpConfigError
,
"unsupported global configuration parameter: "
...
...
src/bin/dhcp4/tests/dhcp4_client.cc
View file @
94280840
// Copyright (C) 2014-201
5
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
6
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
...
...
@@ -49,7 +49,8 @@ Dhcp4Client::Dhcp4Client(const Dhcp4Client::State& state) :
server_facing_relay_addr_
(
"10.0.0.2"
),
srv_
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
(
new
NakedDhcpv4Srv
(
0
))),
state_
(
state
),
use_relay_
(
false
)
{
use_relay_
(
false
),
circuit_id_
()
{
}
Dhcp4Client
::
Dhcp4Client
(
boost
::
shared_ptr
<
NakedDhcpv4Srv
>
srv
,
...
...
@@ -67,7 +68,8 @@ Dhcp4Client::Dhcp4Client(boost::shared_ptr<NakedDhcpv4Srv> srv,
server_facing_relay_addr_
(
"10.0.0.2"
),
srv_
(
srv
),
state_
(
state
),
use_relay_
(
false
)
{
use_relay_
(
false
),
circuit_id_
()
{
}
void
...
...
@@ -468,6 +470,15 @@ Dhcp4Client::sendMsg(const Pkt4Ptr& msg) {
msg
->
setHops
(
1
);
msg
->
setGiaddr
(
relay_addr_
);
msg
->
setLocalAddr
(
server_facing_relay_addr_
);
// Insert RAI
OptionPtr
rai
(
new
Option
(
Option
::
V4
,
DHO_DHCP_AGENT_OPTIONS
));
// Insert circuit id, if specified.
if
(
!
circuit_id_
.
empty
())
{
rai
->
addOption
(
OptionPtr
(
new
Option
(
Option
::
V4
,
RAI_OPTION_AGENT_CIRCUIT_ID
,
OptionBuffer
(
circuit_id_
.
begin
(),
circuit_id_
.
end
()))));
}
msg
->
addOption
(
rai
);
}
// Repack the message to simulate wire-data parsing.
msg
->
pack
();
...
...
src/bin/dhcp4/tests/dhcp4_client.h
View file @
94280840
// Copyright (C) 2014-201
5
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
6
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
...
...
@@ -284,6 +284,14 @@ public:
const
uint8_t
option2
=
0
,
const
uint8_t
option3
=
0
);
/// @brief Sets circuit-id value to be included in the circuit-id
/// sub option of the RAI option.
///
/// @param circuit_id New circuit-id value.
void
setCircuitId
(
const
std
::
string
&
circuit_id
)
{
circuit_id_
=
circuit_id
;
}
/// @brief Sets destination address for the messages being sent by the
/// client.
///
...
...
@@ -468,6 +476,10 @@ private:
/// @brief Enable relaying messages to the server.
bool
use_relay_
;
/// @brief Specifies value to be inserted into circuit-id sub option
/// of the RAI option.
std
::
string
circuit_id_
;
/// @brief Extra options the client will send.
OptionCollection
extra_options_
;
};
...
...
src/bin/dhcp4/tests/dora_unittest.cc
View file @
94280840
// Copyright (C) 2014-201
5
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
6
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
...
...
@@ -57,6 +57,11 @@ namespace {
/// - 1 pool: 10.0.0.10-10.0.0.100
/// - match-client-id flag is set to false, thus the server
/// uses HW address for lease lookup, rather than client id
///
/// - Configuration 4:
/// - The same as configuration 2, but using different values in
/// 'host-reservation-identifiers'
///
const
char
*
DORA_CONFIGS
[]
=
{
// Configuration 0
"{
\"
interfaces-config
\"
: {"
...
...
@@ -125,6 +130,14 @@ const char* DORA_CONFIGS[] = {
" {"
"
\"
hw-address
\"
:
\"
aa:bb:cc:dd:ee:ff
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.7
\"
"
" },"
" {"
"
\"
duid
\"
:
\"
01:02:03:04:05
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.8
\"
"
" },"
" {"
"
\"
circuit-id
\"
:
\"
'charter950'
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.9
\"
"
" }"
" ]"
"} ]"
...
...
@@ -146,6 +159,32 @@ const char* DORA_CONFIGS[] = {
" } ]"
" } ]"
"}"
,
// Configuration 4
"{
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
host-reservation-identifiers
\"
: [
\"
circuit-id
\"
,
\"
hw-address
\"
],"
"
\"
valid-lifetime
\"
: 600,"
"
\"
subnet4
\"
: [ { "
"
\"
subnet
\"
:
\"
10.0.0.0/24
\"
, "
"
\"
pools
\"
: [ {
\"
pool
\"
:
\"
10.0.0.10-10.0.0.100
\"
} ],"
"
\"
reservations
\"
: [ "
" {"
"
\"
hw-address
\"
:
\"
aa:bb:cc:dd:ee:ff
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.7
\"
"
" },"
" {"
"
\"
duid
\"
:
\"
01:02:03:04:05
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.8
\"
"
" },"
" {"
"
\"
circuit-id
\"
:
\"
'charter950'
\"
,"
"
\"
ip-address
\"
:
\"
10.0.0.9
\"
"
" }"
" ]"
"} ]"
"}"
};
/// @brief Test fixture class for testing 4-way (DORA) exchanges.
...
...
@@ -688,6 +727,71 @@ TEST_F(DORATest, reservation) {
ASSERT_TRUE
(
subnet
->
inPool
(
Lease
::
TYPE_V4
,
clientB
.
config_
.
lease_
.
addr_
));
}
// This test checks that it is possible to make a reservation by
// circuit-id inserted by the relay agent.
TEST_F
(
DORATest
,
reservationByCircuitId
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
// Use relay agent so as the circuit-id can be inserted.
client
.
useRelay
(
true
,
IOAddress
(
"10.0.0.1"
),
IOAddress
(
"10.0.0.2"
));
// Specify circuit-id.
client
.
setCircuitId
(
"charter950"
);
// Configure DHCP server.
configure
(
DORA_CONFIGS
[
2
],
*
client
.
getServer
());
// Client A performs 4-way exchange and should obtain a reserved
// address.
ASSERT_NO_THROW
(
client
.
doDORA
(
boost
::
shared_ptr
<
IOAddress
>
(
new
IOAddress
(
"0.0.0.0"
))));
// Make sure that the server responded.
ASSERT_TRUE
(
client
.
getContext
().
response_
);
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
// Make sure that the server has responded with DHCPACK.
ASSERT_EQ
(
DHCPACK
,
static_cast
<
int
>
(
resp
->
getType
()));
// Make sure that the client has got the lease for the reserved address.
ASSERT_EQ
(
"10.0.0.9"
,
client
.
config_
.
lease_
.
addr_
.
toText
());
}
// This test verifies that order in which host identifiers are used to
// retrieve host reservations can be controlled.
TEST_F
(
DORATest
,
hostIdentifiersOrder
)
{
Dhcp4Client
client
(
Dhcp4Client
::
SELECTING
);
client
.
setHWAddress
(
"aa:bb:cc:dd:ee:ff"
);
// Use relay agent so as the circuit-id can be inserted.
client
.
useRelay
(
true
,
IOAddress
(
"10.0.0.1"
),
IOAddress
(
"10.0.0.2"
));
// Specify circuit-id.
client
.
setCircuitId
(
"charter950"
);
// Configure DHCP server.
configure
(
DORA_CONFIGS
[
2
],
*
client
.
getServer
());
// Perform 4-way exchange to obtain reserved address.
// The client has in fact two reserved addresses, but the one assigned
// should be by hw-address.
ASSERT_NO_THROW
(
client
.
doDORA
(
boost
::
shared_ptr
<
IOAddress
>
(
new
IOAddress
(
"0.0.0.0"
))));
// Make sure that the server responded.
ASSERT_TRUE
(
client
.
getContext
().
response_
);
Pkt4Ptr
resp
=
client
.
getContext
().
response_
;
// Make sure that the server has responded with DHCPACK.
ASSERT_EQ
(
DHCPACK
,
static_cast
<
int
>
(
resp
->
getType
()));
// Make sure that the client has got the lease for the reserved address.
ASSERT_EQ
(
"10.0.0.7"
,
client
.
config_
.
lease_
.
addr_
.
toText
());
// Reconfigure the server to change the preference order of the
// host identifiers. The 'circuit-id' should now take precedence over
// the hw-address.
configure
(
DORA_CONFIGS
[
4
],
*
client
.
getServer
());
ASSERT_NO_THROW
(
client
.
doDORA
(
boost
::
shared_ptr
<
IOAddress
>
(
new
IOAddress
(
"0.0.0.0"
))));
// Make sure that the server responded.
ASSERT_TRUE
(
client
.
getContext
().
response_
);
resp
=
client
.
getContext
().
response_
;
// Make sure that the server has responded with DHCPACK.
ASSERT_EQ
(
DHCPACK
,
static_cast
<
int
>
(
resp
->
getType
()));
// Make sure that the client has got the lease for the reserved address.
ASSERT_EQ
(
"10.0.0.9"
,
client
.
config_
.
lease_
.
addr_
.
toText
());
}
// This test checks that setting the match-client-id value to false causes
// the server to ignore changing client identifier when the client is
// using consistent HW address.
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
94280840
...
...
@@ -28,6 +28,7 @@
#include <dhcp6/dhcp6_log.h>
#include <dhcp6/dhcp6_srv.h>
#include <dhcpsrv/callout_handle_store.h>
#include <dhcpsrv/cfg_host_operations.h>
#include <dhcpsrv/cfgmgr.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/lease_mgr_factory.h>
...
...
@@ -276,10 +277,40 @@ AllocEngine::ClientContext6
Dhcpv6Srv
::
createContext
(
const
Pkt6Ptr
&
pkt
)
{
AllocEngine
::
ClientContext6
ctx
;
ctx
.
subnet_
=
selectSubnet
(
pkt
);
ctx
.
query_
=
pkt
;
ctx
.
duid_
=
pkt
->
getClientId
();
ctx
.
hwaddr_
=
getMAC
(
pkt
);
ctx
.
query_
=
pkt
;
alloc_engine_
->
findReservation
(
ctx
);
// Collect host identifiers if host reservations enabled. The identifiers
// are stored in order of preference. The server will use them in that
// order to search for host reservations.
if
(
ctx
.
subnet_
&&
(
ctx
.
subnet_
->
getHostReservationMode
()
!=
Subnet
::
HR_DISABLED
))
{
const
ConstCfgHostOperationsPtr
cfg
=
CfgMgr
::
instance
().
getCurrentCfg
()
->
getCfgHostOperations6
();
BOOST_FOREACH
(
const
Host
::
IdentifierType
&
id_type
,
cfg
->
getIdentifierTypes
())
{
switch
(
id_type
)
{
case
Host
::
IDENT_DUID
:
if
(
ctx
.
duid_
)
{
ctx
.
addHostIdentifier
(
id_type
,
ctx
.
duid_
->
getDuid
());
}
break
;
case
Host
::
IDENT_HWADDR
:
if
(
ctx
.
hwaddr_
)
{
ctx
.
addHostIdentifier
(
id_type
,
ctx
.
hwaddr_
->
hwaddr_
);
}
break
;
default:
;
}
}
// Find host reservations using specified identifiers.
alloc_engine_
->
findReservation
(
ctx
);
}
return
(
ctx
);
}
...
...
@@ -1321,6 +1352,7 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer,
ctx
.
hwaddr_
=
orig_ctx
.
hwaddr_
;
ctx
.
host_
=
orig_ctx
.
host_
;
ctx
.
query_
=
orig_ctx
.
query_
;
ctx
.
host_identifiers_
=
orig_ctx
.
host_identifiers_
;
Lease6Collection
leases
=
alloc_engine_
->
allocateLeases6
(
ctx
);
...
...
@@ -1442,6 +1474,7 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& answer,
ctx
.
hwaddr_
=
orig_ctx
.
hwaddr_
;
ctx
.
host_
=
orig_ctx
.
host_
;
ctx
.
query_
=
orig_ctx
.
query_
;
ctx
.
host_identifiers_
=
orig_ctx
.
host_identifiers_
;
Lease6Collection
leases
=
alloc_engine_
->
allocateLeases6
(
ctx
);
...
...
src/bin/dhcp6/json_config_parser.cc
View file @
94280840
...
...
@@ -702,6 +702,8 @@ DhcpConfigParser* createGlobal6DhcpConfigParser(const std::string& config_id,
parser
=
new
ClientClassDefListParser
(
config_id
,
globalContext
());
}
else
if
(
config_id
.
compare
(
"server-id"
)
==
0
)
{
parser
=
new
DUIDConfigParser
();
}
else
if
(
config_id
.
compare
(
"host-reservation-identifiers"
)
==
0
)
{
parser
=
new
HostReservationIdsParser6
();
}
else
{
isc_throw
(
DhcpConfigError
,
"unsupported global configuration parameter: "
...
...
src/bin/dhcp6/tests/dhcp6_client.h
View file @
94280840
// Copyright (C) 2014-201
5
Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2014-201
6
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
...
...
@@ -412,6 +412,13 @@ public:
iface_name_
=
iface_name
;
}
/// @brief Sets link local address used by the client.
///
/// @param link_local New link local address.
void
setLinkLocal
(
const
asiolink
::
IOAddress
&
link_local
)
{
link_local_
=
link_local
;
}
/// @brief Set an address hint to be sent to a server.
///
/// @param pref_lft Preferred lifetime.
...
...
src/bin/dhcp6/tests/host_unittest.cc
View file @
94280840
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2015
-2016
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
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <asiolink/io_address.h>
#include <dhcp/tests/iface_mgr_test_config.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/tests/dhcp6_client.h>
using
namespace
isc
;
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
dhcp
::
test
;
...
...
@@ -19,6 +21,11 @@ namespace {
///
/// - Configuration 0:
/// Single subnet with two reservations, one with a hostname, one without
/// - Configuration 1:
/// Multiple reservations using different host identifiers.
/// - Configuration 2:
/// Same as configuration 1 but 'host-reservation-identifiers' specified
/// in non-default order.
const
char
*
CONFIGS
[]
=
{
// Configuration 0:
"{ "
...
...
@@ -45,6 +52,61 @@ const char* CONFIGS[] = {
"
\"
ip-addresses
\"
: [
\"
2001:db8:1:1::babf
\"
]"
" } ]"
" } ]"
"}"
,
// Configuration 1:
"{ "
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
valid-lifetime
\"
: 4000, "
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
mac-sources
\"
: [
\"
ipv6-link-local
\"
], "
"
\"
subnet6
\"
: [ "
" { "
"
\"
subnet
\"
:
\"
2001:db8:1::/48
\"
, "
"
\"
pools
\"
: [ {
\"
pool
\"
:
\"
2001:db8:1::/64
\"
} ],"
"
\"
interface
\"
:
\"
eth0
\"
, "
"
\"
reservations
\"
: ["
" {"
"
\"
hw-address
\"
:
\"
38:60:77:d5:ff:ee
\"
,"
"
\"
ip-addresses
\"
: [
\"
2001:db8:1::1
\"
]"
" },"
" {"
"
\"
duid
\"
:
\"
01:02:03:05
\"
,"
"
\"
ip-addresses
\"
: [
\"
2001:db8:1::2
\"
]"
" } ]"
" } ]"
"}"
,
// Configuration 2:
"{ "
"
\"
interfaces-config
\"
: {"
"
\"
interfaces
\"
: [
\"
*
\"
]"
"},"
"
\"
host-reservation-identifiers
\"
: [
\"
duid
\"
,
\"
hw-address
\"
],"
"
\"
valid-lifetime
\"
: 4000, "
"
\"
preferred-lifetime
\"
: 3000,"
"
\"
rebind-timer
\"
: 2000, "
"
\"
renew-timer
\"
: 1000, "
"
\"
mac-sources
\"
: [
\"
ipv6-link-local
\"
], "
"
\"
subnet6
\"
: [ "
" { "
"
\"
subnet
\"
:
\"
2001:db8:1::/48
\"
, "
"
\"
pools
\"
: [ {
\"
pool
\"
:
\"
2001:db8:1::/64
\"
} ],"
"
\"
interface
\"
:
\"
eth0
\"
, "
"
\"
reservations
\"
: ["
" {"
"
\"
hw-address
\"
:
\"
38:60:77:d5:ff:ee
\"
,"
"
\"
ip-addresses
\"
: [
\"
2001:db8:1::1
\"
]"
" },"
" {"
"
\"
duid
\"
:
\"
01:02:03:05
\"
,"
"
\"
ip-addresses
\"
: [
\"
2001:db8:1::2
\"
]"
" } ]"
" } ]"
"}"
};
...
...
@@ -59,6 +121,39 @@ public:
iface_mgr_test_config_
(
true
)
{
}
/// @brief Verifies that the reservation is retrieved by the server
/// using one of the host identifiers.
///
/// @param client Reference to a client to be used in the test.
/// The client should be preconfigured to insert a specific identifier
/// into the message, e.g. DUID, HW address etc.
/// @param config_index Index of the configuration to use in the CONFIGS
/// table.
/// @param exp_ip_address Expected IPv6 address in the returned
/// reservation.
void
testReservationByIdentifier
(
Dhcp6Client
&
client
,
const
unsigned
int
config_index
,
const
std
::
string
exp_ip_address
)
{
configure
(
CONFIGS
[
config_index
],
*
client
.
getServer
());
const
Subnet6Collection
*
subnets
=
CfgMgr
::
instance
().
getCurrentCfg
()
->
getCfgSubnets6
()
->
getAll
();
ASSERT_EQ
(
1
,
subnets
->
size
());
// Configure client to request IA_NA and append IA_NA option
// to the client's message.
client
.
useNA
();
ASSERT_NO_THROW
(
client
.
useHint
(
100
,
200
,
64
,
"2001:db8:1:1::dead:beef"
));
// Perform 4-way exchange.
ASSERT_NO_THROW
(
client
.
doSARR
());
// Verify that the client we got the reserved address
ASSERT_EQ
(
1
,
client
.
getLeaseNum
());
Lease6
lease_client
=
client
.
getLease
(
0
);
EXPECT_EQ
(
exp_ip_address
,
lease_client
.
addr_
.
toText
());
}
/// @brief Interface Manager's fake configuration control.
IfaceMgrTestConfig
iface_mgr_test_config_
;
};
...
...
@@ -246,4 +341,39 @@ TEST_F(HostTest, sarrAndRebind) {
EXPECT_EQ
(
"alice"
,
lease_server2
->
hostname_
);
}
// This test verfies that the host reservation by DUID is found by the
// server.
TEST_F
(
HostTest
,
reservationByDUID
)
{
Dhcp6Client
client
;
// Set DUID matching the one used to create host reservations.
client
.
setDUID
(
"01:02:03:05"
);
// Run the actual test.
testReservationByIdentifier
(
client
,
1
,
"2001:db8:1::2"
);
}
// This test verfies that the host reservation by HW address is found
// by the server.
TEST_F
(
HostTest
,
reservationByHWAddress
)
{
Dhcp6Client
client
;
// Set link local address for the client which the server will
// use to decode the HW address as 38:60:77:d5:ff:ee. This
// decoded address will be used to search for host reservations.
client
.
setLinkLocal
(
IOAddress
(
"fe80::3a60:77ff:fed5:ffee"
));
// Run the actual test.
testReservationByIdentifier
(
client
,
1
,
"2001:db8:1::1"
);
}
// This test verifies that order in which host identifiers are used to
// retrieve host reservations can be controlled.
TEST_F
(
HostTest
,
hostIdentifiersOrder
)
{
Dhcp6Client
client
;
// Set DUID matching the one used to create host reservations.
client
.
setDUID
(
"01:02:03:05"
);
// Set link local address for the client which the server will
// use to decode the HW address as 38:60:77:d5:ff:ee. This
// decoded address will be used to search for host reservations.
client
.
setLinkLocal
(
IOAddress
(
"fe80::3a60:77ff:fed5:ffee"
));
testReservationByIdentifier
(
client
,
2
,
"2001:db8:1::2"
);
}
}
// end of anonymous namespace
src/lib/dhcp/dhcp4.h
View file @
94280840
...
...
@@ -283,6 +283,9 @@ static const uint16_t RAI_OPTION_VIRTUAL_SUBNET_SELECT_CTRL = 152; //RFC6607
#endif
/* Client identifier types */
static
const
uint8_t
CLIENT_ID_OPTION_TYPE_DUID
=
255
;
}
// end of isc::dhcp namespace
}
// end of isc namespace
...
...
src/lib/dhcpsrv/Makefile.am
View file @
94280840
...
...
@@ -90,6 +90,7 @@ libkea_dhcpsrv_la_SOURCES += cfg_duid.cc cfg_duid.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_hosts.cc cfg_hosts.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_iface.cc cfg_iface.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_expiration.cc cfg_expiration.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_host_operations.cc cfg_host_operations.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_option.cc cfg_option.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_option_def.cc cfg_option_def.h
libkea_dhcpsrv_la_SOURCES
+=
cfg_rsoo.cc cfg_rsoo.h
...
...
src/lib/dhcpsrv/alloc_engine.cc
View file @
94280840
...
...
@@ -12,6 +12,7 @@
#include <dhcp_ddns/ncr_msg.h>
#include <dhcpsrv/alloc_engine.h>
#include <dhcpsrv/alloc_engine_log.h>