Commit daf53e75 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[3153] PD renewal implemented.

parent bec7f219
......@@ -452,10 +452,25 @@ 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
possible reasons for such behavior.
% DHCP6_UNKNOWN_RENEW received RENEW from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to renew a lease,
but no such lease is known by the server. It typically means that
client has attempted to use its lease past its lifetime: causes of this
% DHCP6_UNKNOWN_RENEW_NA received unknown IA_NA RENEW from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to renew an address lease
(in IA_NA option), but no such lease is known by the server. It typically means
that client has attempted to use its lease past its lifetime: causes of this
include a adjustment of the clients date/time setting or poor support
for sleep/recovery. A properly implemented client will recover from such
a situation by restarting the lease allocation process after receiving
a negative reply from the server.
An alternative cause could be that the server has lost its database
recently and does not recognize its well-behaving clients. This is more
probable if you see many such messages. Clients will recover from this,
but they will most likely get a different IP addresses and experience
a brief service interruption.
% DHCP6_UNKNOWN_RENEW_PD received unknown IA_NA RENEW from client (duid=%1, iaid=%2) in subnet %3
This warning message is printed when client attempts to renew an address lease
(in IA_NA option), but no such lease is known by the server. It typically means
that client has attempted to use its lease past its lifetime: causes of this
include a adjustment of the clients date/time setting or poor support
for sleep/recovery. A properly implemented client will recover from such
a situation by restarting the lease allocation process after receiving
......
......@@ -1454,7 +1454,7 @@ Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"Sorry, no known leases for this duid/iaid."));
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_UNKNOWN_RENEW)
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_UNKNOWN_RENEW_NA)
.arg(duid->toText())
.arg(ia->getIAID())
.arg(subnet->toText());
......@@ -1563,6 +1563,108 @@ Dhcpv6Srv::renewIA_NA(const Subnet6Ptr& subnet, const DuidPtr& duid,
return (ia_rsp);
}
OptionPtr
Dhcpv6Srv::renewIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia) {
if (!subnet) {
// There's no subnet select for this client. There's nothing to renew.
boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_PD, ia->getIAID()));
// Insert status code NoAddrsAvail.
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"Sorry, no known leases for this duid/iaid."));
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_RENEW_UNKNOWN_SUBNET)
.arg(duid->toText())
.arg(ia->getIAID());
return (ia_rsp);
}
Lease6Ptr lease = LeaseMgrFactory::instance().getLease6(Lease::TYPE_PD,
*duid, ia->getIAID(),
subnet->getID());
if (!lease) {
// client renewing a lease that we don't know about.
// Create empty IA_NA option with IAID matching the request.
boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_PD, ia->getIAID()));
// Insert status code NoAddrsAvail.
ia_rsp->addOption(createStatusCode(STATUS_NoBinding,
"Sorry, no known leases for this duid/iaid."));
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_DETAIL, DHCP6_UNKNOWN_RENEW_PD)
.arg(duid->toText())
.arg(ia->getIAID())
.arg(subnet->toText());
return (ia_rsp);
}
// Keep the old data in case the callout tells us to skip update
Lease6 old_data = *lease;
lease->preferred_lft_ = subnet->getPreferred();
lease->valid_lft_ = subnet->getValid();
lease->t1_ = subnet->getT1();
lease->t2_ = subnet->getT2();
lease->cltt_ = time(NULL);
// Create empty IA_NA option with IAID matching the request.
boost::shared_ptr<Option6IA> ia_rsp(new Option6IA(D6O_IA_PD, ia->getIAID()));
ia_rsp->setT1(subnet->getT1());
ia_rsp->setT2(subnet->getT2());
boost::shared_ptr<Option6IAPrefix>
prefix(new Option6IAPrefix(D6O_IAPREFIX, lease->addr_, lease->prefixlen_,
lease->preferred_lft_, lease->valid_lft_));
ia_rsp->addOption(prefix);
bool skip = false;
// Execute all callouts registered for packet6_send
if (HooksManager::getHooksManager().calloutsPresent(Hooks.hook_index_lease6_renew_)) {
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);
// Pass the IA option to be sent in response
callout_handle->setArgument("ia_pd", ia_rsp);
// Call all installed callouts
HooksManager::callCallouts(Hooks.hook_index_lease6_renew_, *callout_handle);
// Callouts decided to skip the next processing step. The next
// processing step would to actually renew the lease, so skip at this
// stage means "keep the old lease as it is".
if (callout_handle->getSkip()) {
skip = true;
LOG_DEBUG(dhcp6_logger, DBG_DHCP6_HOOKS, DHCP6_HOOK_LEASE6_RENEW_SKIP);
}
}
if (!skip) {
LeaseMgrFactory::instance().updateLease6(lease);
} else {
// Copy back the original date to the lease. For MySQL it doesn't make
// much sense, but for memfile, the Lease6Ptr points to the actual lease
// in memfile, so the actual update is performed when we manipulate fields
// of returned Lease6Ptr, the actual updateLease6() is no-op.
*lease = old_data;
}
return (ia_rsp);
}
void
Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply,
const Option6ClientFqdnPtr& fqdn) {
......@@ -1617,6 +1719,16 @@ Dhcpv6Srv::renewLeases(const Pkt6Ptr& renew, Pkt6Ptr& reply,
}
break;
}
case D6O_IA_PD: {
OptionPtr answer_opt = renewIA_PD(subnet, duid, renew,
boost::dynamic_pointer_cast<
Option6IA>(opt->second));
if (answer_opt) {
reply->addOption(answer_opt);
}
break;
}
default:
break;
}
......
......@@ -257,6 +257,20 @@ protected:
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia,
const Option6ClientFqdnPtr& fqdn);
/// @brief Renews specific IA_PD option
///
/// Generates response to IA_PD in Renew. This typically includes finding a
/// lease that corresponds to the received prefix. If no such lease is
/// found, an IA_PD response is generated with an appropriate status code.
///
/// @param subnet subnet the sender belongs to
/// @param duid client's duid
/// @param query client's message
/// @param ia IA_PD option that is being renewed
/// @return IA_PD option (server's response)
OptionPtr renewIA_PD(const Subnet6Ptr& subnet, const DuidPtr& duid,
const Pkt6Ptr& query, boost::shared_ptr<Option6IA> ia);
/// @brief Releases specific IA_NA option
///
/// Generates response to IA_NA in Release message. This covers finding and
......
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