mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-31 22:15:23 +00:00
[master] Merge branch 'trac3152': PD support in solicit/request
Conflicts: ChangeLog
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
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
|
686. [bug] tomek
|
||||||
b10-dhcp6 now sends back relayed traffic to proper port.
|
b10-dhcp6 now sends back relayed traffic to proper port.
|
||||||
(Trac #3177, git 6b33de4bea92eecb64b6c673bf1b8ae51f8edcf1)
|
(Trac #3177, git 6b33de4bea92eecb64b6c673bf1b8ae51f8edcf1)
|
||||||
|
@@ -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
|
some reason the reload failed. Other error messages issued from the
|
||||||
hooks framework will indicate the nature of the problem.
|
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
|
This debug message indicates that the server successfully advertised
|
||||||
a lease. It is up to the client to choose one server out of the
|
an address lease. It is up to the client to choose one server out of the
|
||||||
advertised servers and continue allocation with that server. This
|
advertised servers and continue allocation with that server. This
|
||||||
is a normal behavior and indicates successful operation.
|
is a normal behavior and indicates successful operation.
|
||||||
|
|
||||||
% DHCP6_LEASE_ADVERT_FAIL failed to advertise a lease for client duid=%1, iaid=%2
|
% DHCP6_PD_LEASE_ADVERT prefix lease %1/%2 advertised (client duid=%3, iaid=%4)
|
||||||
This message indicates that the server failed to advertise (in response to
|
This debug message indicates that the server successfully advertised
|
||||||
received SOLICIT) a lease for a given client. There may be many reasons for
|
a prefix lease. It is up to the client to choose one server out of the
|
||||||
such failure. Each specific failure is logged in a separate log entry.
|
advertised servers and continue allocation with that server. This
|
||||||
|
is a normal behavior and indicates successful operation.
|
||||||
|
|
||||||
% DHCP6_LEASE_ALLOC lease %1 has been allocated (client duid=%2, iaid=%3)
|
% DHCP6_LEASE_ADVERT_FAIL failed to advertise an address lease for client duid=%1, iaid=%2
|
||||||
This debug message indicates that the server successfully granted (in
|
This message indicates that in response to a received SOLICIT, the server
|
||||||
response to client's REQUEST message) a lease. This is a normal behavior
|
failed to advertise a non-temporary lease for a given client. There may
|
||||||
and indicates successful operation.
|
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_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_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_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
|
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
|
received REQUEST) a prefix lease for a given client. There may be many reasons
|
||||||
such failure. Each specific failure is logged in a separate log entry.
|
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
|
% DHCP6_LEASE_WITHOUT_DUID lease for address %1 does not have a DUID
|
||||||
This error message indicates a database consistency failure. The lease
|
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.
|
failure is given in the message.
|
||||||
|
|
||||||
% DHCP6_PROCESS_IA_NA_REQUEST server is processing IA_NA option (duid=%1, iaid=%2, hint=%3)
|
% 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
|
This is a debug message that indicates the processing of a received
|
||||||
option. It may optionally contain an address that may be used by the server
|
IA_NA option. It may optionally contain an address that may be used by
|
||||||
as a hint for possible requested address.
|
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
|
% 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.
|
A debug message listing the data received from the client or relay.
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#include <dhcp/option6_client_fqdn.h>
|
#include <dhcp/option6_client_fqdn.h>
|
||||||
#include <dhcp/option6_ia.h>
|
#include <dhcp/option6_ia.h>
|
||||||
#include <dhcp/option6_iaaddr.h>
|
#include <dhcp/option6_iaaddr.h>
|
||||||
#include <dhcp/option6_iaaddr.h>
|
#include <dhcp/option6_iaprefix.h>
|
||||||
#include <dhcp/option_custom.h>
|
#include <dhcp/option_custom.h>
|
||||||
#include <dhcp/option_int_array.h>
|
#include <dhcp/option_int_array.h>
|
||||||
#include <dhcp/pkt6.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
|
// We need to allocate addresses for all IA_NA options in the client's
|
||||||
// question (i.e. SOLICIT or REQUEST) message.
|
// question (i.e. SOLICIT or REQUEST) message.
|
||||||
// @todo add support for IA_TA
|
// @todo add support for IA_TA
|
||||||
// @todo add support for IA_PD
|
|
||||||
|
|
||||||
// We need to select a subnet the client is connected in.
|
// We need to select a subnet the client is connected in.
|
||||||
Subnet6Ptr subnet = selectSubnet(question);
|
Subnet6Ptr subnet = selectSubnet(question);
|
||||||
@@ -883,6 +882,14 @@ Dhcpv6Srv::assignLeases(const Pkt6Ptr& question, Pkt6Ptr& answer,
|
|||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1310,6 +1317,107 @@ Dhcpv6Srv::assignIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
|||||||
return (ia_rsp);
|
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
|
OptionPtr
|
||||||
Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
|
||||||
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia,
|
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia,
|
||||||
|
@@ -206,7 +206,7 @@ protected:
|
|||||||
/// @brief Processes IA_NA option (and assigns addresses if necessary).
|
/// @brief Processes IA_NA option (and assigns addresses if necessary).
|
||||||
///
|
///
|
||||||
/// Generates response to IA_NA. This typically includes selecting (and
|
/// 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) an address lease and creating
|
||||||
/// IAADDR option. In case of allocation failure, it may contain
|
/// IAADDR option. In case of allocation failure, it may contain
|
||||||
/// status code option with non-zero status, denoting cause of the
|
/// status code option with non-zero status, denoting cause of the
|
||||||
/// allocation failure.
|
/// allocation failure.
|
||||||
@@ -224,6 +224,23 @@ protected:
|
|||||||
Option6IAPtr ia,
|
Option6IAPtr ia,
|
||||||
const Option6ClientFqdnPtr& fqdn);
|
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
|
/// @brief Renews specific IA_NA option
|
||||||
///
|
///
|
||||||
/// Generates response to IA_NA in Renew. This typically includes finding a
|
/// Generates response to IA_NA in Renew. This typically includes finding a
|
||||||
|
@@ -70,7 +70,7 @@ TESTS += dhcp6_unittests
|
|||||||
dhcp6_unittests_SOURCES = dhcp6_unittests.cc
|
dhcp6_unittests_SOURCES = dhcp6_unittests.cc
|
||||||
dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
|
dhcp6_unittests_SOURCES += dhcp6_srv_unittest.cc
|
||||||
dhcp6_unittests_SOURCES += hooks_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 += ctrl_dhcp6_srv_unittest.cc
|
||||||
dhcp6_unittests_SOURCES += config_parser_unittest.cc
|
dhcp6_unittests_SOURCES += config_parser_unittest.cc
|
||||||
dhcp6_unittests_SOURCES += marker_file.cc
|
dhcp6_unittests_SOURCES += marker_file.cc
|
||||||
|
@@ -97,7 +97,7 @@ public:
|
|||||||
OptionPtr srvid = OptionPtr()) {
|
OptionPtr srvid = OptionPtr()) {
|
||||||
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(msg_type, 1234));
|
Pkt6Ptr pkt = Pkt6Ptr(new Pkt6(msg_type, 1234));
|
||||||
pkt->setRemoteAddr(IOAddress("fe80::abcd"));
|
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) {
|
if (msg_type != DHCPV6_REPLY) {
|
||||||
IOAddress hint("2001:db8:1:1::dead:beef");
|
IOAddress hint("2001:db8:1:1::dead:beef");
|
||||||
@@ -149,7 +149,7 @@ public:
|
|||||||
|
|
||||||
// Adds IA option to the message. Option holds an address.
|
// Adds IA option to the message. Option holds an address.
|
||||||
void addIA(const uint32_t iaid, const IOAddress& addr, Pkt6Ptr& pkt) {
|
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,
|
Option6IAAddrPtr opt_iaaddr(new Option6IAAddr(D6O_IAADDR, addr,
|
||||||
300, 500));
|
300, 500));
|
||||||
opt_ia->addOption(opt_iaaddr);
|
opt_ia->addOption(opt_iaaddr);
|
||||||
@@ -158,7 +158,7 @@ public:
|
|||||||
|
|
||||||
// Adds IA option to the message. Option holds status code.
|
// Adds IA option to the message. Option holds status code.
|
||||||
void addIA(const uint32_t iaid, const uint16_t status_code, Pkt6Ptr& pkt) {
|
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);
|
addStatusCode(status_code, "", opt_ia);
|
||||||
pkt->addOption(opt_ia);
|
pkt->addOption(opt_ia);
|
||||||
}
|
}
|
||||||
@@ -312,7 +312,7 @@ TEST_F(NakedDhcpv6SrvTest, SolicitNoSubnet) {
|
|||||||
|
|
||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
||||||
sol->addOption(generateIA(234, 1500, 3000));
|
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
|
||||||
OptionPtr clientid = generateClientId();
|
OptionPtr clientid = generateClientId();
|
||||||
sol->addOption(clientid);
|
sol->addOption(clientid);
|
||||||
|
|
||||||
@@ -335,7 +335,7 @@ TEST_F(NakedDhcpv6SrvTest, RequestNoSubnet) {
|
|||||||
// Let's create a REQUEST
|
// Let's create a REQUEST
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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
|
// with a hint
|
||||||
IOAddress hint("2001:db8:1:1::dead:beef");
|
IOAddress hint("2001:db8:1:1::dead:beef");
|
||||||
@@ -373,7 +373,7 @@ TEST_F(NakedDhcpv6SrvTest, RenewNoSubnet) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -408,7 +408,7 @@ TEST_F(NakedDhcpv6SrvTest, ReleaseNoSubnet) {
|
|||||||
// Let's create a RELEASE
|
// Let's create a RELEASE
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr released_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(released_addr_opt);
|
ia->addOption(released_addr_opt);
|
||||||
@@ -563,7 +563,7 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
|
|||||||
|
|
||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
||||||
sol->addOption(generateIA(234, 1500, 3000));
|
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
|
||||||
OptionPtr clientid = generateClientId();
|
OptionPtr clientid = generateClientId();
|
||||||
sol->addOption(clientid);
|
sol->addOption(clientid);
|
||||||
|
|
||||||
@@ -647,7 +647,7 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
|
|||||||
|
|
||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
||||||
sol->addOption(generateIA(234, 1500, 3000));
|
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
|
||||||
OptionPtr clientid = generateClientId();
|
OptionPtr clientid = generateClientId();
|
||||||
sol->addOption(clientid);
|
sol->addOption(clientid);
|
||||||
|
|
||||||
@@ -671,6 +671,53 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
|
|||||||
checkClientId(reply, clientid);
|
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
|
// This test verifies that incoming SOLICIT can be handled properly, that an
|
||||||
// ADVERTISE is generated, that the response has an address and that address
|
// ADVERTISE is generated, that the response has an address and that address
|
||||||
// really belongs to the configured pool.
|
// really belongs to the configured pool.
|
||||||
@@ -692,7 +739,7 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
|
|||||||
// Let's create a SOLICIT
|
// Let's create a SOLICIT
|
||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
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
|
// with a valid hint
|
||||||
IOAddress hint("2001:db8:1:1::dead:beef");
|
IOAddress hint("2001:db8:1:1::dead:beef");
|
||||||
@@ -747,7 +794,7 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
|
|||||||
// Let's create a SOLICIT
|
// Let's create a SOLICIT
|
||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
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");
|
IOAddress hint("2001:db8:1::cafe:babe");
|
||||||
ASSERT_FALSE(subnet_->inPool(Lease::TYPE_NA, hint));
|
ASSERT_FALSE(subnet_->inPool(Lease::TYPE_NA, hint));
|
||||||
OptionPtr hint_opt(new Option6IAAddr(D6O_IAADDR, hint, 300, 500));
|
OptionPtr hint_opt(new Option6IAAddr(D6O_IAADDR, hint, 300, 500));
|
||||||
@@ -798,9 +845,9 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
|
|||||||
sol2->setRemoteAddr(IOAddress("fe80::1223"));
|
sol2->setRemoteAddr(IOAddress("fe80::1223"));
|
||||||
sol3->setRemoteAddr(IOAddress("fe80::3467"));
|
sol3->setRemoteAddr(IOAddress("fe80::3467"));
|
||||||
|
|
||||||
sol1->addOption(generateIA(1, 1500, 3000));
|
sol1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
|
||||||
sol2->addOption(generateIA(2, 1500, 3000));
|
sol2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
|
||||||
sol3->addOption(generateIA(3, 1500, 3000));
|
sol3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
|
||||||
|
|
||||||
// different client-id sizes
|
// different client-id sizes
|
||||||
OptionPtr clientid1 = generateClientId(12);
|
OptionPtr clientid1 = generateClientId(12);
|
||||||
@@ -878,7 +925,7 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
|
|||||||
// Let's create a REQUEST
|
// Let's create a REQUEST
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_REQUEST, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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
|
// with a valid hint
|
||||||
IOAddress hint("2001:db8:1:1::dead:beef");
|
IOAddress hint("2001:db8:1:1::dead:beef");
|
||||||
@@ -921,6 +968,74 @@ TEST_F(Dhcpv6SrvTest, RequestBasic) {
|
|||||||
LeaseMgrFactory::instance().deleteLease(addr->getAddress());
|
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
|
// 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
|
// 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
|
// 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"));
|
req2->setRemoteAddr(IOAddress("fe80::1223"));
|
||||||
req3->setRemoteAddr(IOAddress("fe80::3467"));
|
req3->setRemoteAddr(IOAddress("fe80::3467"));
|
||||||
|
|
||||||
req1->addOption(generateIA(1, 1500, 3000));
|
req1->addOption(generateIA(D6O_IA_NA, 1, 1500, 3000));
|
||||||
req2->addOption(generateIA(2, 1500, 3000));
|
req2->addOption(generateIA(D6O_IA_NA, 2, 1500, 3000));
|
||||||
req3->addOption(generateIA(3, 1500, 3000));
|
req3->addOption(generateIA(D6O_IA_NA, 3, 1500, 3000));
|
||||||
|
|
||||||
// different client-id sizes
|
// different client-id sizes
|
||||||
OptionPtr clientid1 = generateClientId(12);
|
OptionPtr clientid1 = generateClientId(12);
|
||||||
@@ -1050,7 +1165,7 @@ TEST_F(Dhcpv6SrvTest, RenewBasic) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -1136,7 +1251,7 @@ TEST_F(Dhcpv6SrvTest, RenewReject) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, transid));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, transid));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -1247,7 +1362,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) {
|
|||||||
// Let's create a RELEASE
|
// Let's create a RELEASE
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr released_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(released_addr_opt);
|
ia->addOption(released_addr_opt);
|
||||||
@@ -1324,7 +1439,7 @@ TEST_F(Dhcpv6SrvTest, ReleaseReject) {
|
|||||||
// Let's create a RELEASE
|
// Let's create a RELEASE
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, transid));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, transid));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr released_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(released_addr_opt);
|
ia->addOption(released_addr_opt);
|
||||||
|
130
src/bin/dhcp6/tests/dhcp6_test_utils.cc
Normal file
130
src/bin/dhcp6/tests/dhcp6_test_utils.cc
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
// 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);
|
||||||
|
boost::shared_ptr<Option6IAAddr> addr = boost::dynamic_pointer_cast<Option6IAAddr>(tmp);
|
||||||
|
return (addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Option6IAPrefix>
|
||||||
|
Dhcpv6SrvTest::checkIA_PD(const Pkt6Ptr& rsp, uint32_t expected_iaid,
|
||||||
|
uint32_t expected_t1, uint32_t expected_t2) {
|
||||||
|
OptionPtr tmp = rsp->getOption(D6O_IA_PD);
|
||||||
|
// Can't use ASSERT_TRUE() in method that returns something
|
||||||
|
if (!tmp) {
|
||||||
|
ADD_FAILURE() << "IA_PD option not present in response";
|
||||||
|
return (boost::shared_ptr<Option6IAPrefix>());
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(tmp);
|
||||||
|
if (!ia) {
|
||||||
|
ADD_FAILURE() << "IA_PD cannot convert option ptr to Option6";
|
||||||
|
return (boost::shared_ptr<Option6IAPrefix>());
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(expected_iaid, ia->getIAID());
|
||||||
|
EXPECT_EQ(expected_t1, ia->getT1());
|
||||||
|
EXPECT_EQ(expected_t2, ia->getT2());
|
||||||
|
|
||||||
|
tmp = ia->getOption(D6O_IAPREFIX);
|
||||||
|
boost::shared_ptr<Option6IAPrefix> addr = boost::dynamic_pointer_cast<Option6IAPrefix>(tmp);
|
||||||
|
return (addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks if the lease sent to client is present in the database
|
||||||
|
// and is valid when checked agasint the configured subnet
|
||||||
|
Lease6Ptr
|
||||||
|
Dhcpv6SrvTest::checkLease(const DuidPtr& duid, const OptionPtr& ia_na,
|
||||||
|
boost::shared_ptr<Option6IAAddr> addr) {
|
||||||
|
boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_na);
|
||||||
|
|
||||||
|
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
|
||||||
|
addr->getAddress());
|
||||||
|
if (!lease) {
|
||||||
|
std::cout << "Lease for " << addr->getAddress().toText()
|
||||||
|
<< " not found in the database backend.";
|
||||||
|
return (Lease6Ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(addr->getAddress().toText(), lease->addr_.toText());
|
||||||
|
EXPECT_TRUE(*lease->duid_ == *duid);
|
||||||
|
EXPECT_EQ(ia->getIAID(), lease->iaid_);
|
||||||
|
EXPECT_EQ(subnet_->getID(), lease->subnet_id_);
|
||||||
|
|
||||||
|
return (lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
Lease6Ptr
|
||||||
|
Dhcpv6SrvTest::checkPdLease(const DuidPtr& duid, const OptionPtr& ia_pd,
|
||||||
|
boost::shared_ptr<Option6IAPrefix> prefix){
|
||||||
|
boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_pd);
|
||||||
|
|
||||||
|
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD,
|
||||||
|
prefix->getAddress());
|
||||||
|
if (!lease) {
|
||||||
|
std::cout << "PD lease for " << prefix->getAddress().toText()
|
||||||
|
<< " not found in the database backend.";
|
||||||
|
return (Lease6Ptr());
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(prefix->getAddress().toText(), lease->addr_.toText());
|
||||||
|
EXPECT_TRUE(*lease->duid_ == *duid);
|
||||||
|
EXPECT_EQ(ia->getIAID(), lease->iaid_);
|
||||||
|
EXPECT_EQ(subnet_->getID(), lease->subnet_id_);
|
||||||
|
|
||||||
|
return (lease);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Generate IA_NA option with specified parameters
|
||||||
|
boost::shared_ptr<Option6IA>
|
||||||
|
NakedDhcpv6SrvTest::generateIA(uint16_t type, uint32_t iaid, uint32_t t1,
|
||||||
|
uint32_t t2) {
|
||||||
|
boost::shared_ptr<Option6IA> ia =
|
||||||
|
boost::shared_ptr<Option6IA>(new Option6IA(type, iaid));
|
||||||
|
ia->setT1(t1);
|
||||||
|
ia->setT2(t2);
|
||||||
|
return (ia);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end of isc::test namespace
|
||||||
|
}; // end of isc namespace
|
@@ -16,11 +16,15 @@
|
|||||||
///
|
///
|
||||||
/// @brief This file contains utility classes used for DHCPv6 server testing
|
/// @brief This file contains utility classes used for DHCPv6 server testing
|
||||||
|
|
||||||
|
#ifndef DHCP6_TEST_UTILS_H
|
||||||
|
#define DHCP6_TEST_UTILS_H
|
||||||
|
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <dhcp/pkt6.h>
|
#include <dhcp/pkt6.h>
|
||||||
#include <dhcp/option6_ia.h>
|
#include <dhcp/option6_ia.h>
|
||||||
#include <dhcp/option6_iaaddr.h>
|
#include <dhcp/option6_iaaddr.h>
|
||||||
|
#include <dhcp/option6_iaprefix.h>
|
||||||
#include <dhcp/option_int_array.h>
|
#include <dhcp/option_int_array.h>
|
||||||
#include <dhcp/option_custom.h>
|
#include <dhcp/option_custom.h>
|
||||||
#include <dhcp/iface_mgr.h>
|
#include <dhcp/iface_mgr.h>
|
||||||
@@ -145,14 +149,9 @@ public:
|
|||||||
valid_iface_ = ifaces.begin()->getName();
|
valid_iface_ = ifaces.begin()->getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate IA_NA option with specified parameters
|
// Generate IA_NA or IA_PD option with specified parameters
|
||||||
boost::shared_ptr<Option6IA> generateIA(uint32_t iaid, uint32_t t1, uint32_t t2) {
|
boost::shared_ptr<Option6IA> generateIA(uint16_t type, uint32_t iaid,
|
||||||
boost::shared_ptr<Option6IA> ia =
|
uint32_t t1, uint32_t t2);
|
||||||
boost::shared_ptr<Option6IA>(new Option6IA(D6O_IA_NA, iaid));
|
|
||||||
ia->setT1(t1);
|
|
||||||
ia->setT2(t2);
|
|
||||||
return (ia);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief generates interface-id option, based on text
|
/// @brief generates interface-id option, based on text
|
||||||
///
|
///
|
||||||
@@ -328,32 +327,35 @@ public:
|
|||||||
CfgMgr::instance().addSubnet6(subnet_);
|
CfgMgr::instance().addSubnet6(subnet_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that server response (ADVERTISE or REPLY) contains proper IA_NA option
|
void configurePdPool() {
|
||||||
// It returns IAADDR option for each chaining with checkIAAddr method.
|
pd_pool_ = Pool6Ptr(new Pool6(Lease::TYPE_PD, IOAddress("2001:db8:1:2::"), 64, 80));
|
||||||
boost::shared_ptr<Option6IAAddr> checkIA_NA(const Pkt6Ptr& rsp, uint32_t expected_iaid,
|
subnet_->addPool(pd_pool_);
|
||||||
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);
|
|
||||||
boost::shared_ptr<Option6IAAddr> addr = boost::dynamic_pointer_cast<Option6IAAddr>(tmp);
|
|
||||||
return (addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Checks that server response (ADVERTISE or REPLY) contains proper
|
||||||
|
/// IA_NA option
|
||||||
|
///
|
||||||
|
/// @param rsp server's response
|
||||||
|
/// @param expected_iaid expected IAID value
|
||||||
|
/// @param expected_t1 expected T1 value
|
||||||
|
/// @param expected_t2 expected T2 value
|
||||||
|
/// @return IAADDR option for easy chaining with checkIAAddr method
|
||||||
|
boost::shared_ptr<Option6IAAddr>
|
||||||
|
checkIA_NA(const Pkt6Ptr& rsp, uint32_t expected_iaid,
|
||||||
|
uint32_t expected_t1, uint32_t expected_t2);
|
||||||
|
|
||||||
|
/// @brief Checks that server response (ADVERTISE or REPLY) contains proper
|
||||||
|
/// IA_PD option
|
||||||
|
///
|
||||||
|
/// @param rsp server's response
|
||||||
|
/// @param expected_iaid expected IAID value
|
||||||
|
/// @param expected_t1 expected T1 value
|
||||||
|
/// @param expected_t2 expected T2 value
|
||||||
|
/// @return IAPREFIX option for easy chaining with checkIAAddr method
|
||||||
|
boost::shared_ptr<Option6IAPrefix>
|
||||||
|
checkIA_PD(const Pkt6Ptr& rsp, uint32_t expected_iaid,
|
||||||
|
uint32_t expected_t1, uint32_t expected_t2);
|
||||||
|
|
||||||
// Check that generated IAADDR option contains expected address
|
// Check that generated IAADDR option contains expected address
|
||||||
// and lifetime values match the configured subnet
|
// and lifetime values match the configured subnet
|
||||||
void checkIAAddr(const boost::shared_ptr<Option6IAAddr>& addr,
|
void checkIAAddr(const boost::shared_ptr<Option6IAAddr>& addr,
|
||||||
@@ -375,24 +377,11 @@ public:
|
|||||||
// Checks if the lease sent to client is present in the database
|
// Checks if the lease sent to client is present in the database
|
||||||
// and is valid when checked agasint the configured subnet
|
// and is valid when checked agasint the configured subnet
|
||||||
Lease6Ptr checkLease(const DuidPtr& duid, const OptionPtr& ia_na,
|
Lease6Ptr checkLease(const DuidPtr& duid, const OptionPtr& ia_na,
|
||||||
boost::shared_ptr<Option6IAAddr> addr) {
|
boost::shared_ptr<Option6IAAddr> addr);
|
||||||
boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(ia_na);
|
|
||||||
|
|
||||||
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_NA,
|
Lease6Ptr checkPdLease(const DuidPtr& duid, const OptionPtr& ia_pd,
|
||||||
addr->getAddress());
|
boost::shared_ptr<Option6IAPrefix> prefix);
|
||||||
if (!lease) {
|
|
||||||
std::cout << "Lease for " << addr->getAddress().toText()
|
|
||||||
<< " not found in the database backend.";
|
|
||||||
return (Lease6Ptr());
|
|
||||||
}
|
|
||||||
|
|
||||||
EXPECT_EQ(addr->getAddress().toText(), lease->addr_.toText());
|
|
||||||
EXPECT_TRUE(*lease->duid_ == *duid);
|
|
||||||
EXPECT_EQ(ia->getIAID(), lease->iaid_);
|
|
||||||
EXPECT_EQ(subnet_->getID(), lease->subnet_id_);
|
|
||||||
|
|
||||||
return (lease);
|
|
||||||
}
|
|
||||||
|
|
||||||
// see wireshark.cc for descriptions
|
// see wireshark.cc for descriptions
|
||||||
// The descriptions are too large and too closely related to the
|
// The descriptions are too large and too closely related to the
|
||||||
@@ -416,9 +405,14 @@ public:
|
|||||||
/// A subnet used in most tests
|
/// A subnet used in most tests
|
||||||
Subnet6Ptr subnet_;
|
Subnet6Ptr subnet_;
|
||||||
|
|
||||||
/// A pool used in most tests
|
/// A normal, non-temporary pool used in most tests
|
||||||
Pool6Ptr pool_;
|
Pool6Ptr pool_;
|
||||||
|
|
||||||
|
/// A prefix pool used in most tests
|
||||||
|
Pool6Ptr pd_pool_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}; // end of isc::test namespace
|
}; // end of isc::test namespace
|
||||||
}; // end of isc namespace
|
}; // end of isc namespace
|
||||||
|
|
||||||
|
#endif // DHCP6_TEST_UTILS_H
|
||||||
|
@@ -924,7 +924,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
|
|||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
||||||
sol->setIface(valid_iface_);
|
sol->setIface(valid_iface_);
|
||||||
sol->addOption(generateIA(234, 1500, 3000));
|
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
|
||||||
OptionPtr clientid = generateClientId();
|
OptionPtr clientid = generateClientId();
|
||||||
sol->addOption(clientid);
|
sol->addOption(clientid);
|
||||||
|
|
||||||
@@ -992,7 +992,7 @@ TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
|
|||||||
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
Pkt6Ptr sol = Pkt6Ptr(new Pkt6(DHCPV6_SOLICIT, 1234));
|
||||||
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
sol->setRemoteAddr(IOAddress("fe80::abcd"));
|
||||||
sol->setIface(valid_iface_);
|
sol->setIface(valid_iface_);
|
||||||
sol->addOption(generateIA(234, 1500, 3000));
|
sol->addOption(generateIA(D6O_IA_NA, 234, 1500, 3000));
|
||||||
OptionPtr clientid = generateClientId();
|
OptionPtr clientid = generateClientId();
|
||||||
sol->addOption(clientid);
|
sol->addOption(clientid);
|
||||||
|
|
||||||
@@ -1064,7 +1064,7 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_renew) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -1161,7 +1161,7 @@ TEST_F(HooksDhcpv6SrvTest, leaseUpdate_lease6_renew) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -1252,7 +1252,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_renew) {
|
|||||||
// Let's create a RENEW
|
// Let's create a RENEW
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RENEW, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr renewed_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(renewed_addr_opt);
|
ia->addOption(renewed_addr_opt);
|
||||||
@@ -1320,7 +1320,7 @@ TEST_F(HooksDhcpv6SrvTest, basic_lease6_release) {
|
|||||||
// Let's create a RELEASE
|
// Let's create a RELEASE
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr released_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(released_addr_opt);
|
ia->addOption(released_addr_opt);
|
||||||
@@ -1401,7 +1401,7 @@ TEST_F(HooksDhcpv6SrvTest, skip_lease6_release) {
|
|||||||
// Let's create a RELEASE
|
// Let's create a RELEASE
|
||||||
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
Pkt6Ptr req = Pkt6Ptr(new Pkt6(DHCPV6_RELEASE, 1234));
|
||||||
req->setRemoteAddr(IOAddress("fe80::abcd"));
|
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));
|
OptionPtr released_addr_opt(new Option6IAAddr(D6O_IAADDR, addr, 300, 500));
|
||||||
ia->addOption(released_addr_opt);
|
ia->addOption(released_addr_opt);
|
||||||
|
Reference in New Issue
Block a user