Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
a9cd7cf1
Commit
a9cd7cf1
authored
Oct 07, 2013
by
Tomek Mrugalski
🛰
Browse files
[master] Merge branch 'trac3152': PD support in solicit/request
Conflicts: ChangeLog
parents
be15d120
a0e73dd7
Changes
9
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
a9cd7cf1
687. [func] tomek
b10-dhcp6: Prefix Delegation (IA_PD and IAPREFIX options) is now
supported in Solicit and Request messages.
(Trac #3152, git a0e73dd74658f2deb22fad2c7a1f56d122aa9021)
686. [bug] tomek
b10-dhcp6 now sends back relayed traffic to proper port.
(Trac #3177, git 6b33de4bea92eecb64b6c673bf1b8ae51f8edcf1)
...
...
src/bin/dhcp6/dhcp6_messages.mes
View file @
a9cd7cf1
...
...
@@ -166,26 +166,50 @@ A "libreload" command was issued to reload the hooks libraries but for
some reason the reload failed. Other error messages issued from the
hooks framework will indicate the nature of the problem.
% DHCP6_LEASE_ADVERT lease %1 advertised (client duid=%2, iaid=%3)
% DHCP6_LEASE_ADVERT
address
lease %1 advertised (client duid=%2, iaid=%3)
This debug message indicates that the server successfully advertised
a lease. It is up to the client to choose one server out of the
a
n address
lease. It is up to the client to choose one server out of the
advertised servers and continue allocation with that server. This
is a normal behavior and indicates successful operation.
% DHCP6_LEASE_ADVERT_FAIL failed to advertise a lease for client duid=%1, iaid=%2
This message indicates that the server failed to advertise (in response to
received SOLICIT) a lease for a given client. There may be many reasons for
such failure. Each specific failure is logged in a separate log entry.
% DHCP6_PD_LEASE_ADVERT prefix lease %1/%2 advertised (client duid=%3, iaid=%4)
This debug message indicates that the server successfully advertised
a prefix lease. It is up to the client to choose one server out of the
advertised servers and continue allocation with that server. This
is a normal behavior and indicates successful operation.
% DHCP6_LEASE_ADVERT_FAIL failed to advertise an address lease for client duid=%1, iaid=%2
This message indicates that in response to a received SOLICIT, the server
failed to advertise a non-temporary lease for a given client. There may
be many reasons for such failure. Each failure is logged in a separate
log entry.
% DHCP6_PD_LEASE_ADVERT_FAIL failed to advertise a prefix lease for client duid=%1, iaid=%2
This message indicates that in response to a received SOLICIT, the
server failed to advertise a prefix lease for the client. There may
be many reasons for such failure. Each failure is logged in a separate
log entry.
% DHCP6_LEASE_ALLOC address lease %1 has been allocated (client duid=%2, iaid=%3)
This debug message indicates that in response to a client's REQUEST
message, the server successfully granted an non-temporary address
lease. This is a normal behavior and indicates successful operation.
% DHCP6_PD_LEASE_ALLOC prefix lease %1/%2 has been allocated (client duid=%3, iaid=%4)
This debug message indicates that in response to a client's REQUEST
message, the server successfully granted a prefix delegation lease. This
is a normal behavior and indicates successful operation.
% DHCP6_LEASE_ALLOC lease %1 has been allocated (client duid=%2, iaid=%3)
This debug message indicates that the server successfully granted (in
response to client's REQUEST message) a lease. This is a normal behavior
and indicates successful operation.
% DHCP6_LEASE_ALLOC_FAIL failed to grant an address lease for client duid=%1, iaid=%2
This message indicates that in response to a received REQUEST, the server
failed to grant a non-temporary address lease for the client. There may
be many reasons for such failure. Each failure is logged in a separate
log entry.
% DHCP6_LEASE_ALLOC_FAIL failed to grant a lease for client duid=%1, iaid=%2
% DHCP6_
PD_
LEASE_ALLOC_FAIL failed to grant a
prefix
lease for client duid=%1, iaid=%2
This message indicates that the server failed to grant (in response to
received REQUEST) a lease for a given client. There may be many reasons
for
such failure. Each
specific
failure is logged in a separate log entry.
received REQUEST) a
prefix
lease for a given client. There may be many reasons
for
such failure. Each failure is logged in a separate log entry.
% DHCP6_LEASE_WITHOUT_DUID lease for address %1 does not have a DUID
This error message indicates a database consistency failure. The lease
...
...
@@ -278,9 +302,14 @@ parsing actions and committal of changes failed. The reason for the
failure is given in the message.
% DHCP6_PROCESS_IA_NA_REQUEST server is processing IA_NA option (duid=%1, iaid=%2, hint=%3)
This is a debug message that indicates a processing of received IA_NA
option. It may optionally contain an address that may be used by the server
as a hint for possible requested address.
This is a debug message that indicates the processing of a received
IA_NA option. It may optionally contain an address that may be used by
the server as a hint for possible requested address.
% DHCP6_PROCESS_IA_PD_REQUEST server is processing IA_PD option (duid=%1, iaid=%2, hint=%3)
This is a debug message that indicates a processing of received IA_PD
option. It may optionally contain an prefix that may be used by the server
as a hint for possible requested prefix.
% DHCP6_QUERY_DATA received packet length %1, data length %2, data is %3
A debug message listing the data received from the client or relay.
...
...
src/bin/dhcp6/dhcp6_srv.cc
View file @
a9cd7cf1
...
...
@@ -24,7 +24,7 @@
#include <dhcp/option6_client_fqdn.h>
#include <dhcp/option6_ia.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_ia
addr
.h>
#include <dhcp/option6_ia
prefix
.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int_array.h>
#include <dhcp/pkt6.h>
...
...
@@ -825,7 +825,6 @@ Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer,
// We need to allocate addresses for all IA_NA options in the client's
// question (i.e. SOLICIT or REQUEST) message.
// @todo add support for IA_TA
// @todo add support for IA_PD
// We need to select a subnet the client is connected in.
Subnet6Ptr
subnet
=
selectSubnet
(
question
);
...
...
@@ -883,6 +882,14 @@ Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer,
}
break
;
}
case
D6O_IA_PD
:
{
OptionPtr
answer_opt
=
assignIA_PD
(
subnet
,
duid
,
question
,
boost
::
dynamic_pointer_cast
<
Option6IA
>
(
opt
->
second
));
if
(
answer_opt
)
{
answer
->
addOption
(
answer_opt
);
}
}
default:
break
;
}
...
...
@@ -1310,6 +1317,107 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
return
(
ia_rsp
);
}
OptionPtr
Dhcpv6Srv
::
assignIA_PD
(
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
const
Pkt6Ptr
&
query
,
boost
::
shared_ptr
<
Option6IA
>
ia
)
{
// Create IA_PD that we will put in the response.
// Do not use OptionDefinition to create option's instance so
// as we can initialize IAID using a constructor.
boost
::
shared_ptr
<
Option6IA
>
ia_rsp
(
new
Option6IA
(
D6O_IA_PD
,
ia
->
getIAID
()));
// If there is no subnet selected for handling this IA_PD, the only thing to
// do left is to say that we are sorry, but the user won't get an address.
// As a convenience, we use a different status text to indicate that
// (compare to the same status code, but different wording below)
if
(
!
subnet
)
{
// Insert status code NoAddrsAvail.
ia_rsp
->
addOption
(
createStatusCode
(
STATUS_NoPrefixAvail
,
"Sorry, no subnet available."
));
return
(
ia_rsp
);
}
// Check if the client sent us a hint in his IA_PD. Clients may send an
// address in their IA_NA options as a suggestion (e.g. the last address
// they used before).
boost
::
shared_ptr
<
Option6IAPrefix
>
hintOpt
=
boost
::
dynamic_pointer_cast
<
Option6IAPrefix
>
(
ia
->
getOption
(
D6O_IAPREFIX
));
IOAddress
hint
(
"::"
);
if
(
hintOpt
)
{
hint
=
hintOpt
->
getAddress
();
}
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_DETAIL
,
DHCP6_PROCESS_IA_PD_REQUEST
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
).
arg
(
ia
->
getIAID
())
.
arg
(
hintOpt
?
hint
.
toText
()
:
"(no hint)"
);
// "Fake" allocation is processing of SOLICIT message. We pretend to do an
// allocation, but we do not put the lease in the database. That is ok,
// because we do not guarantee that the user will get that exact lease. If
// the user selects this server to do actual allocation (i.e. sends REQUEST)
// it should include this hint. That will help us during the actual lease
// allocation.
bool
fake_allocation
=
(
query
->
getType
()
==
DHCPV6_SOLICIT
);
CalloutHandlePtr
callout_handle
=
getCalloutHandle
(
query
);
// Use allocation engine to pick a lease for this client. Allocation engine
// will try to honour the hint, but it is just a hint - some other address
// may be used instead. If fake_allocation is set to false, the lease will
// be inserted into the LeaseMgr as well.
Lease6Collection
leases
=
alloc_engine_
->
allocateLeases6
(
subnet
,
duid
,
ia
->
getIAID
(),
hint
,
Lease
::
TYPE_PD
,
false
,
false
,
string
(),
fake_allocation
,
callout_handle
);
if
(
!
leases
.
empty
())
{
ia_rsp
->
setT1
(
subnet
->
getT1
());
ia_rsp
->
setT2
(
subnet
->
getT2
());
for
(
Lease6Collection
::
iterator
l
=
leases
.
begin
();
l
!=
leases
.
end
();
++
l
)
{
// We have a lease! Let's wrap its content into IA_PD option
// with IAADDR suboption.
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_DETAIL
,
fake_allocation
?
DHCP6_PD_LEASE_ADVERT
:
DHCP6_PD_LEASE_ALLOC
)
.
arg
((
*
l
)
->
addr_
.
toText
())
.
arg
(
static_cast
<
int
>
((
*
l
)
->
prefixlen_
))
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
)
.
arg
(
ia
->
getIAID
());
boost
::
shared_ptr
<
Option6IAPrefix
>
addr
(
new
Option6IAPrefix
(
D6O_IAPREFIX
,
(
*
l
)
->
addr_
,
(
*
l
)
->
prefixlen_
,
(
*
l
)
->
preferred_lft_
,
(
*
l
)
->
valid_lft_
));
ia_rsp
->
addOption
(
addr
);
}
// It would be possible to insert status code=0(success) as well,
// but this is considered waste of bandwidth as absence of status
// code is considered a success.
}
else
{
// Allocation engine did not allocate a lease. The engine logged
// cause of that failure. The only thing left is to insert
// status code to pass the sad news to the client.
LOG_DEBUG
(
dhcp6_logger
,
DBG_DHCP6_DETAIL
,
fake_allocation
?
DHCP6_PD_LEASE_ADVERT_FAIL
:
DHCP6_PD_LEASE_ALLOC_FAIL
)
.
arg
(
duid
?
duid
->
toText
()
:
"(no-duid)"
)
.
arg
(
ia
->
getIAID
());
ia_rsp
->
addOption
(
createStatusCode
(
STATUS_NoPrefixAvail
,
"Sorry, no prefixes could be allocated."
));
}
return
(
ia_rsp
);
}
OptionPtr
Dhcpv6Srv
::
renewIA_NA
(
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
const
Pkt6Ptr
&
query
,
boost
::
shared_ptr
<
Option6IA
>
ia
,
...
...
src/bin/dhcp6/dhcp6_srv.h
View file @
a9cd7cf1
...
...
@@ -206,7 +206,7 @@ protected:
/// @brief Processes IA_NA option (and assigns addresses if necessary).
///
/// Generates response to IA_NA. This typically includes selecting (and
/// allocating a lease in case of REQUEST) a lease and creating
/// allocating a lease in case of REQUEST) a
n address
lease and creating
/// IAADDR option. In case of allocation failure, it may contain
/// status code option with non-zero status, denoting cause of the
/// allocation failure.
...
...
@@ -224,6 +224,23 @@ protected:
Option6IAPtr
ia
,
const
Option6ClientFqdnPtr
&
fqdn
);
/// @brief Processes IA_PD option (and assigns prefixes if necessary).
///
/// Generates response to IA_PD. This typically includes selecting (and
/// allocating in the case of REQUEST) a prefix lease and creating an
/// IAPREFIX option. In case of an allocation failure, it may contain a
/// status code option with non-zero status denoting the cause of the
/// allocation failure.
///
/// @param subnet subnet the client is connected to
/// @param duid client's duid
/// @param query client's message (typically SOLICIT or REQUEST)
/// @param ia pointer to client's IA_PD option (client's request)
/// @return IA_PD option (server's response)
OptionPtr
assignIA_PD
(
const
Subnet6Ptr
&
subnet
,
const
DuidPtr
&
duid
,
const
Pkt6Ptr
&
query
,
boost
::
shared_ptr
<
Option6IA
>
ia
);
/// @brief Renews specific IA_NA option
///
/// Generates response to IA_NA in Renew. This typically includes finding a
...
...
src/bin/dhcp6/tests/Makefile.am
View file @
a9cd7cf1
...
...
@@ -70,7 +70,7 @@ TESTS += dhcp6_unittests
dhcp6_unittests_SOURCES
=
dhcp6_unittests.cc
dhcp6_unittests_SOURCES
+=
dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
hooks_unittest.cc
dhcp6_unittests_SOURCES
+=
dhcp6_test_utils.h
dhcp6_unittests_SOURCES
+=
dhcp6_test_utils.cc
dhcp6_test_utils.h
dhcp6_unittests_SOURCES
+=
ctrl_dhcp6_srv_unittest.cc
dhcp6_unittests_SOURCES
+=
config_parser_unittest.cc
dhcp6_unittests_SOURCES
+=
marker_file.cc
...
...
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
View file @
a9cd7cf1
...
...
@@ -97,7 +97,7 @@ public:
OptionPtr
srvid
=
OptionPtr
())
{
Pkt6Ptr
pkt
=
Pkt6Ptr
(
new
Pkt6
(
msg_type
,
1234
));
pkt
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
Option6IAPtr
ia
=
generateIA
(
234
,
1500
,
3000
);
Option6IAPtr
ia
=
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
);
if
(
msg_type
!=
DHCPV6_REPLY
)
{
IOAddress
hint
(
"2001:db8:1:1::dead:beef"
);
...
...
@@ -149,7 +149,7 @@ public:
// Adds IA option to the message. Option holds an address.
void
addIA
(
const
uint32_t
iaid
,
const
IOAddress
&
addr
,
Pkt6Ptr
&
pkt
)
{
Option6IAPtr
opt_ia
=
generateIA
(
iaid
,
1500
,
3000
);
Option6IAPtr
opt_ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
Option6IAAddrPtr
opt_iaaddr
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
opt_ia
->
addOption
(
opt_iaaddr
);
...
...
@@ -158,7 +158,7 @@ public:
// Adds IA option to the message. Option holds status code.
void
addIA
(
const
uint32_t
iaid
,
const
uint16_t
status_code
,
Pkt6Ptr
&
pkt
)
{
Option6IAPtr
opt_ia
=
generateIA
(
iaid
,
1500
,
3000
);
Option6IAPtr
opt_ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
addStatusCode
(
status_code
,
""
,
opt_ia
);
pkt
->
addOption
(
opt_ia
);
}
...
...
@@ -312,7 +312,7 @@ TEST_F(NakedDhcpv6SrvTest, SolicitNoSubnet) {
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
sol
->
addOption
(
generateIA
(
234
,
1500
,
3000
));
sol
->
addOption
(
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
));
OptionPtr
clientid
=
generateClientId
();
sol
->
addOption
(
clientid
);
...
...
@@ -335,7 +335,7 @@ TEST_F(NakedDhcpv6SrvTest, RequestNoSubnet) {
// Let's create a REQUEST
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_REQUEST
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
234
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
);
// with a hint
IOAddress
hint
(
"2001:db8:1:1::dead:beef"
);
...
...
@@ -373,7 +373,7 @@ TEST_F(NakedDhcpv6SrvTest, RenewNoSubnet) {
// Let's create a RENEW
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RENEW
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
OptionPtr
renewed_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
renewed_addr_opt
);
...
...
@@ -408,7 +408,7 @@ TEST_F(NakedDhcpv6SrvTest, ReleaseNoSubnet) {
// Let's create a RELEASE
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RELEASE
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
OptionPtr
released_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
released_addr_opt
);
...
...
@@ -563,7 +563,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
sol
->
addOption
(
generateIA
(
234
,
1500
,
3000
));
sol
->
addOption
(
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
));
OptionPtr
clientid
=
generateClientId
();
sol
->
addOption
(
clientid
);
...
...
@@ -647,7 +647,7 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
sol
->
addOption
(
generateIA
(
234
,
1500
,
3000
));
sol
->
addOption
(
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
));
OptionPtr
clientid
=
generateClientId
();
sol
->
addOption
(
clientid
);
...
...
@@ -671,6 +671,53 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
checkClientId
(
reply
,
clientid
);
}
// This test verifies that incoming SOLICIT can be handled properly, that an
// ADVERTISE is generated, that the response has a prefix and that prefix
// really belongs to the configured pool.
//
// This test sends a SOLICIT without any hint in IA_PD.
//
// constructed very simple SOLICIT message with:
// - client-id option (mandatory)
// - IA option (a request for address, without any addresses)
//
// expected returned ADVERTISE message:
// - copy of client-id
// - server-id
// - IA that includes IAPREFIX
TEST_F
(
Dhcpv6SrvTest
,
pdSolicitBasic
)
{
configurePdPool
();
NakedDhcpv6Srv
srv
(
0
);
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
sol
->
addOption
(
generateIA
(
D6O_IA_PD
,
234
,
1500
,
3000
));
OptionPtr
clientid
=
generateClientId
();
sol
->
addOption
(
clientid
);
// Pass it to the server and get an advertise
Pkt6Ptr
reply
=
srv
.
processSolicit
(
sol
);
// check if we get response at all
checkResponse
(
reply
,
DHCPV6_ADVERTISE
,
1234
);
// check that IA_NA was returned and that there's an address included
boost
::
shared_ptr
<
Option6IAPrefix
>
prefix
=
checkIA_PD
(
reply
,
234
,
subnet_
->
getT1
(),
subnet_
->
getT2
());
ASSERT_TRUE
(
prefix
);
// Check that the assigned prefix is indeed from the configured pool
checkIAAddr
(
prefix
,
prefix
->
getAddress
(),
Lease
::
TYPE_PD
,
subnet_
->
getPreferred
(),
subnet_
->
getValid
());
EXPECT_EQ
(
pd_pool_
->
getLength
(),
prefix
->
getLength
());
// check DUIDs
checkServerId
(
reply
,
srv
.
getServerID
());
checkClientId
(
reply
,
clientid
);
}
// This test verifies that incoming SOLICIT can be handled properly, that an
// ADVERTISE is generated, that the response has an address and that address
// really belongs to the configured pool.
...
...
@@ -692,7 +739,7 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
// Let's create a SOLICIT
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
234
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
);
// with a valid hint
IOAddress
hint
(
"2001:db8:1:1::dead:beef"
);
...
...
@@ -747,7 +794,7 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
// Let's create a SOLICIT
Pkt6Ptr
sol
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_SOLICIT
,
1234
));
sol
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
234
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
);
IOAddress
hint
(
"2001:db8:1::cafe:babe"
);
ASSERT_FALSE
(
subnet_
->
inPool
(
Lease
::
TYPE_NA
,
hint
));
OptionPtr
hint_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
hint
,
300
,
500
));
...
...
@@ -798,9 +845,9 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
sol2
->
setRemoteAddr
(
IOAddress
(
"fe80::1223"
));
sol3
->
setRemoteAddr
(
IOAddress
(
"fe80::3467"
));
sol1
->
addOption
(
generateIA
(
1
,
1500
,
3000
));
sol2
->
addOption
(
generateIA
(
2
,
1500
,
3000
));
sol3
->
addOption
(
generateIA
(
3
,
1500
,
3000
));
sol1
->
addOption
(
generateIA
(
D6O_IA_NA
,
1
,
1500
,
3000
));
sol2
->
addOption
(
generateIA
(
D6O_IA_NA
,
2
,
1500
,
3000
));
sol3
->
addOption
(
generateIA
(
D6O_IA_NA
,
3
,
1500
,
3000
));
// different client-id sizes
OptionPtr
clientid1
=
generateClientId
(
12
);
...
...
@@ -878,7 +925,7 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
// Let's create a REQUEST
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_REQUEST
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
234
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
234
,
1500
,
3000
);
// with a valid hint
IOAddress
hint
(
"2001:db8:1:1::dead:beef"
);
...
...
@@ -921,6 +968,74 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
LeaseMgrFactory
::
instance
().
deleteLease
(
addr
->
getAddress
());
}
// This test verifies that incoming REQUEST can be handled properly, that a
// REPLY is generated, that the response has a prefix and that prefix
// really belongs to the configured pool.
//
// This test sends a REQUEST with IA_PD that contains a valid hint.
//
// constructed very simple REQUEST message with:
// - client-id option (mandatory)
// - IA option (a request for address, with an address that belongs to the
// configured pool, i.e. is valid as hint)
//
// expected returned REPLY message:
// - copy of client-id
// - server-id
// - IA that includes IAPREFIX
TEST_F
(
Dhcpv6SrvTest
,
pdRequestBasic
)
{
configurePdPool
();
NakedDhcpv6Srv
srv
(
0
);
// Let's create a REQUEST
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_REQUEST
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_PD
,
234
,
1500
,
3000
);
// with a valid hint
IOAddress
hint
(
"2001:db8:1:2:f::"
);
ASSERT_TRUE
(
subnet_
->
inPool
(
Lease
::
TYPE_PD
,
hint
));
OptionPtr
hint_opt
(
new
Option6IAPrefix
(
D6O_IAPREFIX
,
hint
,
64
,
300
,
500
));
ia
->
addOption
(
hint_opt
);
req
->
addOption
(
ia
);
OptionPtr
clientid
=
generateClientId
();
req
->
addOption
(
clientid
);
// server-id is mandatory in REQUEST
req
->
addOption
(
srv
.
getServerID
());
// Pass it to the server and hope for a REPLY
Pkt6Ptr
reply
=
srv
.
processRequest
(
req
);
// check if we get response at all
checkResponse
(
reply
,
DHCPV6_REPLY
,
1234
);
OptionPtr
tmp
=
reply
->
getOption
(
D6O_IA_PD
);
ASSERT_TRUE
(
tmp
);
// check that IA_NA was returned and that there's an address included
boost
::
shared_ptr
<
Option6IAPrefix
>
prf
=
checkIA_PD
(
reply
,
234
,
subnet_
->
getT1
(),
subnet_
->
getT2
());
ASSERT_TRUE
(
prf
);
// check that we've got the address we requested
checkIAAddr
(
prf
,
hint
,
Lease
::
TYPE_PD
,
subnet_
->
getPreferred
(),
subnet_
->
getValid
());
EXPECT_EQ
(
pd_pool_
->
getLength
(),
prf
->
getLength
());
// check DUIDs
checkServerId
(
reply
,
srv
.
getServerID
());
checkClientId
(
reply
,
clientid
);
// check that the lease is really in the database
Lease6Ptr
l
=
checkPdLease
(
duid_
,
reply
->
getOption
(
D6O_IA_PD
),
prf
);
EXPECT_TRUE
(
l
);
EXPECT_TRUE
(
LeaseMgrFactory
::
instance
().
deleteLease
(
prf
->
getAddress
()));
}
// This test checks that the server is offering different addresses to different
// clients in REQUEST. Please note that ADVERTISE is not a guarantee that such
// and address will be assigned. Had the pool was very small and contained only
...
...
@@ -941,9 +1056,9 @@ TEST_F(Dhcpv6SrvTest, ManyRequests) {
req2
->
setRemoteAddr
(
IOAddress
(
"fe80::1223"
));
req3
->
setRemoteAddr
(
IOAddress
(
"fe80::3467"
));
req1
->
addOption
(
generateIA
(
1
,
1500
,
3000
));
req2
->
addOption
(
generateIA
(
2
,
1500
,
3000
));
req3
->
addOption
(
generateIA
(
3
,
1500
,
3000
));
req1
->
addOption
(
generateIA
(
D6O_IA_NA
,
1
,
1500
,
3000
));
req2
->
addOption
(
generateIA
(
D6O_IA_NA
,
2
,
1500
,
3000
));
req3
->
addOption
(
generateIA
(
D6O_IA_NA
,
3
,
1500
,
3000
));
// different client-id sizes
OptionPtr
clientid1
=
generateClientId
(
12
);
...
...
@@ -1050,7 +1165,7 @@ TEST_F(Dhcpv6SrvTest, RenewBasic) {
// Let's create a RENEW
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RENEW
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
OptionPtr
renewed_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
renewed_addr_opt
);
...
...
@@ -1136,7 +1251,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
// Let's create a RENEW
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RENEW
,
transid
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
bogus_iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
bogus_iaid
,
1500
,
3000
);
OptionPtr
renewed_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
renewed_addr_opt
);
...
...
@@ -1247,7 +1362,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
// Let's create a RELEASE
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RELEASE
,
1234
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
iaid
,
1500
,
3000
);
OptionPtr
released_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
released_addr_opt
);
...
...
@@ -1324,7 +1439,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
// Let's create a RELEASE
Pkt6Ptr
req
=
Pkt6Ptr
(
new
Pkt6
(
DHCPV6_RELEASE
,
transid
));
req
->
setRemoteAddr
(
IOAddress
(
"fe80::abcd"
));
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
bogus_iaid
,
1500
,
3000
);
boost
::
shared_ptr
<
Option6IA
>
ia
=
generateIA
(
D6O_IA_NA
,
bogus_iaid
,
1500
,
3000
);
OptionPtr
released_addr_opt
(
new
Option6IAAddr
(
D6O_IAADDR
,
addr
,
300
,
500
));
ia
->
addOption
(
released_addr_opt
);
...
...
src/bin/dhcp6/tests/dhcp6_test_utils.cc
0 → 100644
View file @
a9cd7cf1
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <gtest/gtest.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
namespace
isc
{
namespace
test
{
// Checks that server response (ADVERTISE or REPLY) contains proper IA_NA option
// It returns IAADDR option for each chaining with checkIAAddr method.
boost
::
shared_ptr
<
Option6IAAddr
>
Dhcpv6SrvTest
::
checkIA_NA
(
const
Pkt6Ptr
&
rsp
,
uint32_t
expected_iaid
,
uint32_t
expected_t1
,
uint32_t
expected_t2
)
{
OptionPtr
tmp
=
rsp
->
getOption
(
D6O_IA_NA
);
// Can't use ASSERT_TRUE() in method that returns something
if
(
!
tmp
)
{
ADD_FAILURE
()
<<
"IA_NA option not present in response"
;
return
(
boost
::
shared_ptr
<
Option6IAAddr
>
());
}
boost
::
shared_ptr
<
Option6IA
>
ia
=
boost
::
dynamic_pointer_cast
<
Option6IA
>
(
tmp
);
if
(
!
ia
)
{
ADD_FAILURE
()
<<
"IA_NA cannot convert option ptr to Option6"
;
return
(
boost
::
shared_ptr
<
Option6IAAddr
>
());
}
EXPECT_EQ
(
expected_iaid
,
ia
->
getIAID
());
EXPECT_EQ
(
expected_t1
,
ia
->
getT1
());
EXPECT_EQ
(
expected_t2
,
ia
->
getT2
());
tmp
=
ia
->
getOption
(
D6O_IAADDR
);