Commit 1ef8a393 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3152] Dhcpv6Srv is now able to allocate prefixes

parent e0966086
......@@ -166,26 +166,48 @@ 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
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
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 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 the server failed to advertise (in response to
received SOLICIT) a non-temporary 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_FAIL failed to advertise a prefix 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.
received SOLICIT) a prefix lease for a given client. There may be many reasons
for such failure. Each specific failure is logged in a separate log entry.
% DHCP6_LEASE_ALLOC lease %1 has been allocated (client duid=%2, iaid=%3)
% DHCP6_LEASE_ALLOC address 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.
response to client's REQUEST message) 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 the server successfully granted (in response
to client's REQUEST message) an prefix delegation lease. This is a normal
behavior and indicates successful operation.
% DHCP6_LEASE_ALLOC_FAIL failed to grant a lease for client duid=%1, iaid=%2
% DHCP6_LEASE_ALLOC_FAIL failed to grant an address 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 non-temporary address 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_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 prefix lease for a given client. There may be many reasons
for such failure. Each specific 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
......@@ -282,6 +304,11 @@ 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.
% 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.
......
......@@ -24,7 +24,7 @@
#include <dhcp/option6_client_fqdn.h>
#include <dhcp/option6_ia.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_iaaddr.h>
#include <dhcp/option6_iaprefix.h>
#include <dhcp/option_custom.h>
#include <dhcp/option_int_array.h>
#include <dhcp/pkt6.h>
......@@ -433,10 +433,10 @@ bool Dhcpv6Srv::run() {
// Pass incoming packet as argument
callout_handle->setArgument("response6", rsp);
// Call callouts
HooksManager::callCallouts(Hooks.hook_index_buffer6_send_, *callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to parse the packet, so skip at this
// stage means drop.
......@@ -444,7 +444,7 @@ bool Dhcpv6Srv::run() {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_BUFFER_SEND_SKIP);
continue;
}
callout_handle->getArgument("response6", rsp);
}
......@@ -875,6 +875,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;
}
......@@ -1302,6 +1310,117 @@ 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) {
// 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) {
// Create empty IA_PD option with IAID matching the request.
// Note that we don't use OptionDefinition class to create this option.
// This is because we prefer using a constructor of Option6IA that
// initializes IAID. Otherwise we would have to use setIAID() after
// creation of the option which has some performance implications.
boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_PD,
ia->getIAID()));
// 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 = false;
if (query->getType() == DHCPV6_SOLICIT) {
/// @todo: Check if we support rapid commit
fake_allocation = true;
}
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_->allocateLease6(subnet, duid,
ia->getIAID(),
hint, Lease::TYPE_PD,
false, false,
string(),
fake_allocation,
callout_handle);
// 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 (!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,
......
......@@ -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) an 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 a lease in case of REQUEST) a prefix lease and creating
/// IAPREFIX option. In case of allocation failure, it may contain
/// status code option with non-zero status, denoting 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
......
......@@ -60,7 +60,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
......
......@@ -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);
......
// 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());