Commit da42fc31 authored by Francis Dupont's avatar Francis Dupont
Browse files

[295-min-max-lease-time-configuration-options] checkpoint

parent fea5ff07
......@@ -9,6 +9,7 @@
#include <dhcp/dhcp6.h>
#include <dhcp/pkt4.h>
#include <dhcp/pkt6.h>
#include <dhcp/option_int.h>
#include <dhcp_ddns/ncr_msg.h>
#include <dhcpsrv/alloc_engine.h>
#include <dhcpsrv/alloc_engine_log.h>
......@@ -3437,6 +3438,17 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
isc_throw(BadValue, "Can't create a lease without a subnet");
}
// Use the dhcp-lease-time content or the default for lease length.
uint32_t valid_lft = ctx.subnet_->getValid();
OptionPtr opt = ctx.query_->getOption(DHO_DHCP_LEASE_TIME);
OptionUint32Ptr opt_lft;
if (opt) {
opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
}
if (opt_lft) {
valid_lft = ctx.subnet_->getValid().get(opt_lft->getValue());
}
time_t now = time(NULL);
// @todo: remove this kludge?
......@@ -3447,8 +3459,7 @@ AllocEngine::createLease4(const ClientContext4& ctx, const IOAddress& addr,
const uint8_t* local_copy0 = local_copy.empty() ? 0 : &local_copy[0];
Lease4Ptr lease(new Lease4(addr, ctx.hwaddr_, local_copy0, local_copy.size(),
ctx.subnet_->getValid(),
now, ctx.subnet_->getID()));
valid_lft, now, ctx.subnet_->getID()));
// Set FQDN specific lease parameters.
lease->fqdn_fwd_ = ctx.fwd_dns_update_;
......@@ -3852,7 +3863,17 @@ AllocEngine::updateLease4Information(const Lease4Ptr& lease,
lease->hwaddr_ = ctx.hwaddr_;
lease->client_id_ = ctx.subnet_->getMatchClientId() ? ctx.clientid_ : ClientIdPtr();
lease->cltt_ = time(NULL);
lease->valid_lft_ = ctx.subnet_->getValid();
// Use the dhcp-lease-time content or the default for lease length.
OptionPtr opt = ctx.query_->getOption(DHO_DHCP_LEASE_TIME);
OptionUint32Ptr opt_lft;
if (opt) {
opt_lft = boost::dynamic_pointer_cast<OptionInt<uint32_t> >(opt);
}
if (opt_lft) {
lease->valid_lft_ = ctx.subnet_->getValid().get(opt_lft->getValue());
} else {
lease->valid_lft_ = ctx.subnet_->getValid();
}
lease->fqdn_fwd_ = ctx.fwd_dns_update_;
lease->fqdn_rev_ = ctx.rev_dns_update_;
lease->hostname_ = ctx.hostname_;
......
......@@ -171,8 +171,22 @@ Network::toElement() const {
// Set valid-lifetime
if (!valid_.unspecified()) {
map->set("valid-lifetime",
Element::create(static_cast<long long>(valid_.get())));
if ((valid_.get() == valid_.getMin()) &&
(valid_.get() == valid_.getMax())) {
map->set("valid-lifetime",
Element::create(static_cast<long long>(valid_.get())));
} else {
map->set("default-valid-lifetime",
Element::create(static_cast<long long>(valid_.get())));
if (valid_.get() != valid_.getMin()) {
map->set("min-valid-lifetime",
Element::create(static_cast<long long>(valid_.getMin())));
}
if (valid_.get() != valid_.getMax()) {
map->set("max-valid-lifetime",
Element::create(static_cast<long long>(valid_.getMax())));
}
}
}
// Set reservation mode
......@@ -291,8 +305,22 @@ Network6::toElement() const {
// Set preferred-lifetime
if (!preferred_.unspecified()) {
map->set("preferred-lifetime",
Element::create(static_cast<long long>(preferred_.get())));
if ((preferred_.get() == preferred_.getMin()) &&
(preferred_.get() == preferred_.getMax())) {
map->set("preferred-lifetime",
Element::create(static_cast<long long>(preferred_.get())));
} else {
map->set("default-preferred-lifetime",
Element::create(static_cast<long long>(preferred_.get())));
if (preferred_.get() != preferred_.getMin()) {
map->set("min-preferred-lifetime",
Element::create(static_cast<long long>(preferred_.getMin())));
}
if (preferred_.get() != preferred_.getMax()) {
map->set("max-preferred-lifetime",
Element::create(static_cast<long long>(preferred_.getMax())));
}
}
}
// Set interface-id
......
......@@ -15,23 +15,88 @@ using namespace isc::util;
namespace isc {
namespace dhcp {
const Triplet<uint32_t>
BaseNetworkParser::parseLifetime(const ConstElementPtr& scope,
const std::string& name) {
uint32_t value;
bool has_value = false;
uint32_t min_value;
bool has_min = false;
uint32_t max_value;
bool has_max = false;
if (scope->contains(name)) {
value = getInteger(scope, name);
has_value = true;
}
if (scope->contains("default-" + name)) {
if (has_value) {
isc_throw(DhcpConfigError, "have both " << name << " and default-"
<< name << " in " << scope->getPosition());
}
value = getInteger(scope, "default-" + name);
has_value = true;
}
if (scope->contains("min-" + name)) {
min_value = getInteger(scope, "min-" + name);
has_min = true;
}
if (scope->contains("max-" + name)) {
max_value = getInteger(scope, "max-" + name);
has_max = true;
}
if (!has_value && !has_min && !has_max) {
return (Triplet<uint32_t>());
}
if (has_value) {
if (!has_min && !has_max) {
// default only.
min_value = value;
max_value = value;
} else if (!has_min) {
// default and max.
min_value = value;
} else if (!has_max) {
// default and min.
max_value = value;
}
} else if (has_min) {
// min only.
if (!has_max) {
value = min_value;
max_value = min_value;
} else {
// min and max.
isc_throw(DhcpConfigError, "have min-" << name << " and max-"
<< name << " but no default-" << name << " nor "
<< name << " in " << scope->getPosition());
}
} else {
// max only.
min_value = max_value;
value = max_value;
}
// Check that value is between min and max.
if ((value < min_value) || (value > max_value)) {
isc_throw(DhcpConfigError, "the value of default-" << name << " ("
<< value << ") is not between min-" << name << " ("
<< min_value << ") and max-" << name << " ("
<< max_value << ")");
}
return (Triplet<uint32_t>(min_value, value, max_value));
}
void
BaseNetworkParser::parseCommonTimers(const ConstElementPtr& network_data,
NetworkPtr& network) {
Triplet<uint32_t> t1;
if (network_data->contains("renew-timer")) {
network->setT1(getInteger(network_data, "renew-timer"));
}
Triplet<uint32_t> t2;
if (network_data->contains("rebind-timer")) {
network->setT2(getInteger(network_data, "rebind-timer"));
}
Triplet<uint32_t> valid;
if (network_data->contains("valid-lifetime")) {
network->setValid(getInteger(network_data, "valid-lifetime"));
}
network->setValid(parseLifetime(network_data, "valid-lifetime"));
}
void
......
......@@ -19,6 +19,17 @@ namespace dhcp {
class BaseNetworkParser : public data::SimpleParser {
protected:
/// @brief Parses DHCP lifetime.
///
/// Used here for valid-lifetime but reused for preferred-lifetime.
///
/// @param scope Data element holding e.g. shared network configuration
/// to be parsed.
/// @param name Base name of the lifetime parameter.
/// @return A triplet with the parsed lifetime value.
const Triplet<uint32_t> parseLifetime(const data::ConstElementPtr& scope,
const std::string& name);
/// @brief Parses common DHCP timers.
///
/// The parsed parameters are:
......
......@@ -1165,10 +1165,7 @@ Subnet6ConfigParser::initSubnet(data::ConstElementPtr params,
}
// Parse preferred lifetime as it is not parsed by the common function.
Triplet<uint32_t> pref;
if (params->contains("preferred-lifetime")) {
pref = getInteger(params, "preferred-lifetime");
}
Triplet<uint32_t> pref = parseLifetime(params, "preferred-lifetime");
// Create a new subnet.
Subnet6* subnet6 = new Subnet6(addr, len, Triplet<uint32_t>(),
......
......@@ -200,11 +200,8 @@ SharedNetwork6Parser::parse(const data::ConstElementPtr& shared_network_data) {
parseCommonTimers(shared_network_data, network);
// preferred-lifetime
Triplet<uint32_t> preferred;
if (shared_network_data->contains("preferred-lifetime")) {
shared_network->setPreferred(getInteger(shared_network_data,
"preferred-lifetime"));
}
shared_network->setPreferred(parseLifetime(shared_network_data,
"preferred-lifetime"));
// Get interface-id option content. For now we support string
// representation only
......
......@@ -37,6 +37,9 @@ namespace dhcp {
/// Order follows global_param rule in bison grammar.
const SimpleKeywords SimpleParser4::GLOBAL4_PARAMETERS = {
{ "valid-lifetime", Element::integer },
{ "default-valid-lifetime", Element::integer },
{ "min-valid-lifetime", Element::integer },
{ "max-valid-lifetime", Element::integer },
{ "renew-timer", Element::integer },
{ "rebind-timer", Element::integer },
{ "decline-probation-period", Element::integer },
......@@ -183,6 +186,9 @@ const ParamsList SimpleParser4::INHERIT_TO_SUBNET4 = {
"reservation-mode",
"server-hostname",
"valid-lifetime",
"default-valid-lifetime",
"min-valid-lifetime",
"max-valid-lifetime",
"calculate-tee-times",
"t1-percent",
"t2-percent"
......
......@@ -37,7 +37,13 @@ namespace dhcp {
const SimpleKeywords SimpleParser6::GLOBAL6_PARAMETERS = {
{ "data-directory", Element::string },
{ "preferred-lifetime", Element::integer },
{ "default-preferred-lifetime", Element::integer },
{ "min-preferred-lifetime", Element::integer },
{ "max-preferred-lifetime", Element::integer },
{ "valid-lifetime", Element::integer },
{ "default-valid-lifetime", Element::integer },
{ "min-valid-lifetime", Element::integer },
{ "max-valid-lifetime", Element::integer },
{ "renew-timer", Element::integer },
{ "rebind-timer", Element::integer },
{ "decline-probation-period", Element::integer },
......@@ -156,12 +162,18 @@ const ParamsList SimpleParser6::INHERIT_TO_SUBNET6 = {
"interface",
"interface-id",
"preferred-lifetime",
"default-preferred-lifetime",
"min-preferred-lifetime",
"max-preferred-lifetime",
"rapid-commit",
"rebind-timer",
"relay",
"renew-timer",
"reservation-mode",
"valid-lifetime",
"default-valid-lifetime",
"min-valid-lifetime",
"max-valid-lifetime",
"calculate-tee-times",
"t1-percent",
"t2-percent"
......
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