Commit 4da14c5c authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3153] Support for PD in Release implemented

parent daf53e75
......@@ -132,7 +132,15 @@ client requested renewal of multiples leases (by sending multiple IA
options), the server will skip the renewal of the one in question and
will proceed with other renewals as usual.
% DHCP6_HOOK_LEASE6_RELEASE_SKIP DHCPv6 lease was not released because a callout set the skip flag.
% DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP DHCPv6 address lease was not released because a callout set the skip flag.
This debug message is printed when a callout installed on lease6_release
hook point set the skip flag. For this particular hook point, the
setting of the flag by a callout instructs the server to not release
a lease. If client requested release of multiples leases (by sending
multiple IA options), the server will retains this particular lease and
will proceed with other renewals as usual.
% DHCP6_HOOK_LEASE6_RELEASE_PD_SKIP DHCPv6 prefix lease was not released because a callout set the skip flag.
This debug message is printed when a callout installed on lease6_release
hook point set the skip flag. For this particular hook point, the
setting of the flag by a callout instructs the server to not release
......@@ -209,13 +217,20 @@ 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
% DHCP6_LEASE_NA_WITHOUT_DUID address lease for address %1 does not have a DUID
This error message indicates a database consistency failure. The lease
database has an entry indicating that the given address is in use,
but the lease does not contain any client identification. This is most
likely due to a software error: please raise a bug report. As a temporary
workaround, manually remove the lease entry from the database.
% DHCP6_LEASE_PD_WITHOUT_DUID prefix lease for address %1 does not have a DUID
This error message indicates a database consistency failure. The lease
database has an entry indicating that the given prefix is in use,
but the lease does not contain any client identification. This is most
likely due to a software error: please raise a bug report. As a temporary
workaround, manually remove the lease entry from the database.
% DHCP6_NOT_RUNNING IPv6 DHCP server is not running
A warning message is issued when an attempt is made to shut down the
IPv6 DHCP server but it is not running.
......@@ -312,31 +327,56 @@ 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.
% DHCP6_RELEASE address %1 belonging to client duid=%2, iaid=%3 was released properly.
% DHCP6_RELEASE_NA address %1 belonging to client duid=%2, iaid=%3 was released properly.
This debug message indicates that an address was released properly. It
is a normal operation during client shutdown.
% DHCP6_RELEASE_FAIL failed to remove lease for address %1 for duid=%2, iaid=%3
This error message indicates that the software failed to remove a
% DHCP6_RELEASE_PD prefix %1 belonging to client duid=%2, iaid=%3 was released properly.
This debug message indicates that a prefix was released properly. It
is a normal operation during client shutdown.
% DHCP6_RELEASE_NA_FAIL failed to remove address lease for address %1 for duid=%2, iaid=%3
This error message indicates that the software failed to remove an address
lease from the lease database. It probably due to an error during a
database operation: resolution will most likely require administrator
intervention (e.g. check if DHCP process has sufficient privileges to
update the database). It may also be triggered if a lease was manually
removed from the database during RELEASE message processing.
% DHCP6_RELEASE_FAIL_WRONG_DUID client (duid=%1) tried to release address %2, but it belongs to client (duid=%3)
% DHCP6_RELEASE_PD_FAIL failed to remove prefix lease for address %1 for duid=%2, iaid=%3
This error message indicates that the software failed to remove a prefix
lease from the lease database. It probably due to an error during a
database operation: resolution will most likely require administrator
intervention (e.g. check if DHCP process has sufficient privileges to
update the database). It may also be triggered if a lease was manually
removed from the database during RELEASE message processing.
% DHCP6_RELEASE_NA_FAIL_WRONG_DUID client (duid=%1) tried to release address %2, but it belongs to client (duid=%3)
This warning message indicates that client tried to release an address
that belongs to a different client. This should not happen in normal
circumstances and may indicate a misconfiguration of the client. However,
since the client releasing the address will stop using it anyway, there
is a good chance that the situation will correct itself.
% DHCP6_RELEASE_FAIL_WRONG_IAID client (duid=%1) tried to release address %2, but it used wrong IAID (expected %3, but got %4)
% DHCP6_RELEASE_PD_FAIL_WRONG_DUID client (duid=%1) tried to release prefix %2, but it belongs to client (duid=%3)
This warning message indicates that client tried to release a prefix
that belongs to a different client. This should not happen in normal
circumstances and may indicate a misconfiguration of the client. However,
since the client releasing the prefix will stop using it anyway, there
is a good chance that the situation will correct itself.
% DHCP6_RELEASE_NA_FAIL_WRONG_IAID client (duid=%1) tried to release address %2, but it used wrong IAID (expected %3, but got %4)
This warning message indicates that client tried to release an address
that does belong to it, but the address was expected to be in a different
IA (identity association) container. This probably means that the client's
support for multiple addresses is flawed.
% DHCP6_RELEASE_PD_FAIL_WRONG_IAID client (duid=%1) tried to release prefix %2, but it used wrong IAID (expected %3, but got %4)
This warning message indicates that client tried to release a prefix
that does belong to it, but the address was expected to be in a different
IA (identity association) container. This probably means that the client's
support for multiple prefixes is flawed.
% DHCP6_RELEASE_MISSING_CLIENTID client (address=%1) sent RELEASE message without mandatory client-id
This warning message indicates that client sent RELEASE message without
mandatory client-id option. This is most likely caused by a buggy client
......@@ -447,9 +487,14 @@ That could either mean missing functionality or invalid or broken relay or clien
The list of formally defined message types is available here:
www.iana.org/assignments/dhcpv6-parameters.
% DHCP6_UNKNOWN_RELEASE received RELEASE from unknown client (duid=%1, iaid=%2)
This warning message is printed when client attempts to release a lease,
but no such lease is known by the server. See DHCP6_UNKNOWN_RENEW for
% DHCP6_UNKNOWN_RELEASE_NA received RELEASE from unknown client (IA_NA, duid=%1, iaid=%2)
This warning message is printed when client attempts to release an address lease,
but no such lease is known by the server. See DHCP6_UNKNOWN_RENEW_NA for
possible reasons for such behavior.
% DHCP6_UNKNOWN_RELEASE_PD received RELEASE from unknown client (IA_PD, duid=%1, iaid=%2)
This warning message is printed when client attempts to release an prefix lease,
but no such lease is known by the server. See DHCP6_UNKNOWN_RENEW_PD for
possible reasons for such behavior.
% DHCP6_UNKNOWN_RENEW_NA received unknown IA_NA RENEW from client (duid=%1, iaid=%2) in subnet %3
......
......@@ -1777,7 +1777,14 @@ Dhcpv6Srv::releaseLeases(const Pkt6Ptr& release, Pkt6Ptr& reply) {
}
break;
}
// @todo: add support for IA_PD
case D6O_IA_PD: {
OptionPtr answer_opt = releaseIA_PD(duid, release, general_status,
boost::dynamic_pointer_cast<Option6IA>(opt->second));
if (answer_opt) {
reply->addOption(answer_opt);
}
break;
}
// @todo: add support for IA_TA
default:
// remaining options are stateless and thus ignored in this context
......@@ -1827,7 +1834,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
"Sorry, no known leases for this duid/iaid, can't release."));
general_status = STATUS_NoBinding;
LOG_INFO(dhcp6_logger, DHCP6_UNKNOWN_RELEASE)
LOG_INFO(dhcp6_logger, DHCP6_UNKNOWN_RELEASE_NA)
.arg(duid->toText())
.arg(ia->getIAID());
......@@ -1839,7 +1846,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
// have mandatory DUID information attached. Someone was messing with our
// database.
LOG_ERROR(dhcp6_logger, DHCP6_LEASE_WITHOUT_DUID)
LOG_ERROR(dhcp6_logger, DHCP6_LEASE_NA_WITHOUT_DUID)
.arg(release_addr->getAddress().toText());
general_status = STATUS_UnspecFail;
......@@ -1849,9 +1856,9 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
}
if (*duid != *(lease->duid_)) {
// Sorry, it's not your address. You can't release it.
LOG_INFO(dhcp6_logger, DHCP6_RELEASE_FAIL_WRONG_DUID)
// Sorry, it's not your address. You can't release it.
LOG_INFO(dhcp6_logger, DHCP6_RELEASE_NA_FAIL_WRONG_DUID)
.arg(duid->toText())
.arg(release_addr->getAddress().toText())
.arg(lease->duid_->toText());
......@@ -1864,7 +1871,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
if (ia->getIAID() != lease->iaid_) {
// This address belongs to this client, but to a different IA
LOG_WARN(dhcp6_logger, DHCP6_RELEASE_FAIL_WRONG_IAID)
LOG_WARN(dhcp6_logger, DHCP6_RELEASE_PD_FAIL_WRONG_IAID)
.arg(duid->toText())
.arg(release_addr->getAddress().toText())
.arg(lease->iaid_)
......@@ -1900,7 +1907,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
// stage means "drop response".
if (callout_handle->getSkip()) {
skip = true;
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_LEASE6_RELEASE_SKIP);
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_LEASE6_RELEASE_NA_SKIP);
}
}
......@@ -1918,7 +1925,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
ia_rsp->addOption(createStatusCode(STATUS_UnspecFail,
"Server failed to release a lease"));
LOG_ERROR(dhcp6_logger, DHCP6_RELEASE_FAIL)
LOG_ERROR(dhcp6_logger, DHCP6_RELEASE_NA_FAIL)
.arg(lease->addr_.toText())
.arg(duid->toText())
.arg(lease->iaid_);
......@@ -1926,7 +1933,7 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
return (ia_rsp);
} else {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_RELEASE)
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_RELEASE_NA)
.arg(lease->addr_.toText())
.arg(duid->toText())
.arg(lease->iaid_);
......@@ -1943,6 +1950,152 @@ Dhcpv6Srv::releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
}
}
OptionPtr
Dhcpv6Srv::releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query,
int& general_status, boost::shared_ptr<Option6IA> ia) {
// Release can be done in one of two ways:
// Approach 1: extract address from client's IA_NA and see if it belongs
// to this particular client.
// Approach 2: find a subnet for this client, get a lease for
// this subnet/duid/iaid and check if its content matches to what the
// client is asking us to release.
//
// This method implements approach 1.
// That's our response
boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_PD, ia->getIAID()));
boost::shared_ptr<Option6IAPrefix> release_prefix = boost::dynamic_pointer_cast<Option6IAPrefix>
(ia->getOption(D6O_IAPREFIX));
if (!release_prefix) {
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"You did not include address in your RELEASE"));
general_status = STATUS_NoBinding;
return (ia_rsp);
}
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD,
release_prefix->getAddress());
if (!lease) {
// client releasing a lease that we don't know about.
// Insert status code NoAddrsAvail.
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"Sorry, no known leases for this duid/iaid, can't release."));
general_status = STATUS_NoBinding;
LOG_INFO(dhcp6_logger, DHCP6_UNKNOWN_RELEASE_PD)
.arg(duid->toText())
.arg(ia->getIAID());
return (ia_rsp);
}
if (!lease->duid_) {
// Something is gravely wrong here. We do have a lease, but it does not
// have mandatory DUID information attached. Someone was messing with our
// database.
LOG_ERROR(dhcp6_logger, DHCP6_LEASE_PD_WITHOUT_DUID)
.arg(release_prefix->getAddress().toText());
general_status = STATUS_UnspecFail;
ia_rsp->addOption(createStatusCode(STATUS_UnspecFail,
"Database consistency check failed when trying to RELEASE"));
return (ia_rsp);
}
if (*duid != *(lease->duid_)) {
// Sorry, it's not your address. You can't release it.
LOG_INFO(dhcp6_logger, DHCP6_RELEASE_PD_FAIL_WRONG_DUID)
.arg(duid->toText())
.arg(release_prefix->getAddress().toText())
.arg(lease->duid_->toText());
general_status = STATUS_NoBinding;
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"This address does not belong to you, you can't release it"));
return (ia_rsp);
}
if (ia->getIAID() != lease->iaid_) {
// This address belongs to this client, but to a different IA
LOG_WARN(dhcp6_logger, DHCP6_RELEASE_PD_FAIL_WRONG_IAID)
.arg(duid->toText())
.arg(release_prefix->getAddress().toText())
.arg(lease->iaid_)
.arg(ia->getIAID());
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"This is your address, but you used wrong IAID"));
general_status = STATUS_NoBinding;
return (ia_rsp);
}
// It is not necessary to check if the address matches as we used
// getLease6(addr) method that is supposed to return a proper lease.
bool skip = false;
// Execute all callouts registered for packet6_send
if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_lease6_release_)) {
CalloutHandlePtr callout_handle = getCalloutHandle(query);
// Delete all previous arguments
callout_handle->deleteAllArguments();
// Pass the original packet
callout_handle->setArgument("query6", query);
// Pass the lease to be updated
callout_handle->setArgument("lease6", lease);
// Call all installed callouts
HooksManager::callCallouts(Hooks.hook_index_lease6_release_, *callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to send the packet, so skip at this
// stage means "drop response".
if (callout_handle->getSkip()) {
skip = true;
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_LEASE6_RELEASE_PD_SKIP);
}
}
// Ok, we've passed all checks. Let's release this prefix.
bool success = false; // was the removal operation succeessful?
if (!skip) {
success = LeaseMgrFactory::instance().deleteLease(lease->addr_);
}
// Here the success should be true if we removed lease successfully
// and false if skip flag was set or the removal failed for whatever reason
if (!success) {
ia_rsp->addOption(createStatusCode(STATUS_UnspecFail,
"Server failed to release a lease"));
LOG_ERROR(dhcp6_logger, DHCP6_RELEASE_PD_FAIL)
.arg(lease->addr_.toText())
.arg(duid->toText())
.arg(lease->iaid_);
general_status = STATUS_UnspecFail;
return (ia_rsp);
} else {
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_RELEASE_PD)
.arg(lease->addr_.toText())
.arg(duid->toText())
.arg(lease->iaid_);
ia_rsp->addOption(createStatusCode(STATUS_Success,
"Lease released. Thank you, please come again."));
return (ia_rsp);
}
}
Pkt6Ptr
Dhcpv6Srv::processSolicit(const Pkt6Ptr& solicit) {
......
......@@ -286,12 +286,28 @@ protected:
/// @param duid client's duid
/// @param query client's message
/// @param general_status a global status (it may be updated in case of errors)
/// @param ia IA_NA option that is being renewed
/// @param ia IA_NA option that is being released
/// @return IA_NA option (server's response)
OptionPtr releaseIA_NA(const DuidPtr& duid, const Pkt6Ptr& query,
int& general_status,
boost::shared_ptr<Option6IA> ia);
/// @brief Releases specific IA_PD option
///
/// Generates response to IA_PD in Release message. This covers finding and
/// removal of a lease that corresponds to the received prefix(es). If no such
/// lease is found, an IA_PD response is generated with an appropriate
/// status code.
///
/// @param duid client's duid
/// @param query client's message
/// @param general_status a global status (it may be updated in case of errors)
/// @param ia IA_PD option that is being released
/// @return IA_PD option (server's response)
OptionPtr releaseIA_PD(const DuidPtr& duid, const Pkt6Ptr& query,
int& general_status,
boost::shared_ptr<Option6IA> ia);
/// @brief Copies required options from client message to server answer.
///
/// Copies options that must appear in any server response (ADVERTISE, REPLY)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment