summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/examples/kea4/all-keys.json3
-rw-r--r--doc/examples/kea6/all-keys.json3
-rw-r--r--src/bin/dhcp4/dhcp4_messages.cc2
-rw-r--r--src/bin/dhcp4/dhcp4_messages.h1
-rw-r--r--src/bin/dhcp4/dhcp4_messages.mes5
-rw-r--r--src/bin/dhcp4/dhcp4_srv.cc179
-rw-r--r--src/bin/dhcp4/dhcp4_srv.h78
-rw-r--r--src/bin/dhcp4/tests/classify_unittest.cc136
-rw-r--r--src/bin/dhcp4/tests/dhcp4_test_utils.cc7
-rw-r--r--src/bin/dhcp4/tests/dhcp4_test_utils.h25
-rw-r--r--src/bin/dhcp4/tests/get_config_unittest.cc76
-rw-r--r--src/bin/dhcp6/dhcp6_messages.cc2
-rw-r--r--src/bin/dhcp6/dhcp6_messages.h1
-rw-r--r--src/bin/dhcp6/dhcp6_messages.mes5
-rw-r--r--src/bin/dhcp6/dhcp6_srv.cc249
-rw-r--r--src/bin/dhcp6/dhcp6_srv.h30
-rw-r--r--src/bin/dhcp6/tests/classify_unittests.cc215
-rw-r--r--src/bin/dhcp6/tests/dhcp6_srv_unittest.cc72
-rw-r--r--src/bin/dhcp6/tests/dhcp6_test_utils.h13
-rw-r--r--src/bin/dhcp6/tests/fqdn_unittest.cc7
-rw-r--r--src/bin/dhcp6/tests/get_config_unittest.cc64
-rw-r--r--src/bin/dhcp6/tests/hooks_unittest.cc14
-rw-r--r--src/bin/dhcp6/tests/vendor_opts_unittest.cc12
-rw-r--r--src/lib/dhcpsrv/alloc_engine.cc52
-rw-r--r--src/lib/dhcpsrv/alloc_engine.h10
25 files changed, 1029 insertions, 232 deletions
diff --git a/doc/examples/kea4/all-keys.json b/doc/examples/kea4/all-keys.json
index e7fdc163c2..01b38b8464 100644
--- a/doc/examples/kea4/all-keys.json
+++ b/doc/examples/kea4/all-keys.json
@@ -457,7 +457,8 @@
// Boolean parameter which controls whether an early global host
// reservations lookup should be performed. This lookup takes place
- // before first classification step so before subnet selection.
+ // before subnet selection and when a global reservation is found
+ // with some client classes triggers a second phase classification.
// It can be used too to drop queries using host reservations as
// a decision table indexed by reservation identifiers.
"early-global-reservations-lookup": true,
diff --git a/doc/examples/kea6/all-keys.json b/doc/examples/kea6/all-keys.json
index 530e7a456e..3c7ce10960 100644
--- a/doc/examples/kea6/all-keys.json
+++ b/doc/examples/kea6/all-keys.json
@@ -400,7 +400,8 @@
// Boolean parameter which controls whether an early global host
// reservations lookup should be performed. This lookup takes place
- // before first classification step so before subnet selection.
+ // before subnet selection and when a global reservation is found
+ // with some client classes triggers a second phase classification.
// It can be used too to drop queries using host reservations as
// a decision table indexed by reservation identifiers.
"early-global-reservations-lookup": true,
diff --git a/src/bin/dhcp4/dhcp4_messages.cc b/src/bin/dhcp4/dhcp4_messages.cc
index f7f8184544..175b45409c 100644
--- a/src/bin/dhcp4/dhcp4_messages.cc
+++ b/src/bin/dhcp4/dhcp4_messages.cc
@@ -109,6 +109,7 @@ extern const isc::log::MessageID DHCP4_PACKET_DROP_0010 = "DHCP4_PACKET_DROP_001
extern const isc::log::MessageID DHCP4_PACKET_DROP_0011 = "DHCP4_PACKET_DROP_0011";
extern const isc::log::MessageID DHCP4_PACKET_DROP_0012 = "DHCP4_PACKET_DROP_0012";
extern const isc::log::MessageID DHCP4_PACKET_DROP_0013 = "DHCP4_PACKET_DROP_0013";
+extern const isc::log::MessageID DHCP4_PACKET_DROP_0014 = "DHCP4_PACKET_DROP_0014";
extern const isc::log::MessageID DHCP4_PACKET_NAK_0001 = "DHCP4_PACKET_NAK_0001";
extern const isc::log::MessageID DHCP4_PACKET_NAK_0002 = "DHCP4_PACKET_NAK_0002";
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003 = "DHCP4_PACKET_NAK_0003";
@@ -267,6 +268,7 @@ const char* values[] = {
"DHCP4_PACKET_DROP_0011", "dropped as sent by the same client than a packet being processed by another thread: dropped %1 by thread %2 as duplicate of %3 processed by %4",
"DHCP4_PACKET_DROP_0012", "dropped as sent by the same client than a packet being processed by another thread: dropped %1 by thread %2 as duplicate of %3 processed by %4",
"DHCP4_PACKET_DROP_0013", "dropped as member of the special class 'DROP' after host reservation lookup: %1",
+ "DHCP4_PACKET_DROP_0014", "dropped as member of the special class 'DROP' after early global host reservations lookup: %1",
"DHCP4_PACKET_NAK_0001", "%1: failed to select a subnet for incoming packet, src %2, type %3",
"DHCP4_PACKET_NAK_0002", "%1: invalid address %2 requested by INIT-REBOOT",
"DHCP4_PACKET_NAK_0003", "%1: failed to advertise a lease, client sent ciaddr %2, requested-ip-address %3",
diff --git a/src/bin/dhcp4/dhcp4_messages.h b/src/bin/dhcp4/dhcp4_messages.h
index d589725488..e992b55091 100644
--- a/src/bin/dhcp4/dhcp4_messages.h
+++ b/src/bin/dhcp4/dhcp4_messages.h
@@ -110,6 +110,7 @@ extern const isc::log::MessageID DHCP4_PACKET_DROP_0010;
extern const isc::log::MessageID DHCP4_PACKET_DROP_0011;
extern const isc::log::MessageID DHCP4_PACKET_DROP_0012;
extern const isc::log::MessageID DHCP4_PACKET_DROP_0013;
+extern const isc::log::MessageID DHCP4_PACKET_DROP_0014;
extern const isc::log::MessageID DHCP4_PACKET_NAK_0001;
extern const isc::log::MessageID DHCP4_PACKET_NAK_0002;
extern const isc::log::MessageID DHCP4_PACKET_NAK_0003;
diff --git a/src/bin/dhcp4/dhcp4_messages.mes b/src/bin/dhcp4/dhcp4_messages.mes
index 5235ea901a..be6d65fb5c 100644
--- a/src/bin/dhcp4/dhcp4_messages.mes
+++ b/src/bin/dhcp4/dhcp4_messages.mes
@@ -602,6 +602,11 @@ This debug message is emitted when an incoming packet was classified
after host reservation lookup into the special class 'DROP' and dropped.
The packet details are displayed.
+% DHCP4_PACKET_DROP_0014 dropped as member of the special class 'DROP' after early global host reservations lookup: %1
+This debug message is emitted when an incoming packet was classified
+after early global host reservations lookup into the special class 'DROP'
+and dropped. The packet details are displayed.
+
% DHCP4_PACKET_NAK_0001 %1: failed to select a subnet for incoming packet, src %2, type %3
This error message is output when a packet was received from a subnet
for which the DHCPv4 server has not been configured. The most probable
diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc
index 483d12caf8..ea74b135ab 100644
--- a/src/bin/dhcp4/dhcp4_srv.cc
+++ b/src/bin/dhcp4/dhcp4_srv.cc
@@ -151,10 +151,11 @@ namespace dhcp {
Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
const Pkt4Ptr& query,
+ AllocEngine::ClientContext4Ptr& context,
const Subnet4Ptr& subnet,
bool& drop)
: alloc_engine_(alloc_engine), query_(query), resp_(),
- context_(new AllocEngine::ClientContext4()) {
+ context_(context) {
if (!alloc_engine_) {
isc_throw(BadValue, "alloc_engine value must not be NULL"
@@ -165,31 +166,35 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
isc_throw(BadValue, "query value must not be NULL when"
" creating an instance of the Dhcpv4Exchange");
}
+
+ // Reset the given context argument.
+ context.reset();
+
// Create response message.
initResponse();
// Select subnet for the query message.
context_->subnet_ = subnet;
- // Hardware address.
- context_->hwaddr_ = query->getHWAddr();
- // Pointer to client's query.
- context_->query_ = query;
// If subnet found, retrieve client identifier which will be needed
// for allocations and search for reservations associated with a
// subnet/shared network.
SharedNetwork4Ptr sn;
- if (subnet) {
+ if (subnet && !context_->early_global_reservations_lookup_) {
OptionPtr opt_clientid = query->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
if (opt_clientid) {
context_->clientid_.reset(new ClientId(opt_clientid->getData()));
}
+ }
+ if (subnet) {
// Find static reservations if not disabled for our subnet.
if (subnet->getReservationsInSubnet() ||
subnet->getReservationsGlobal()) {
// Before we can check for static reservations, we need to prepare a set
// of identifiers to be used for this.
- setHostIdentifiers();
+ if (!context_->early_global_reservations_lookup_) {
+ setHostIdentifiers(context_);
+ }
// Check for static reservations.
alloc_engine->findReservation(*context_);
@@ -207,7 +212,8 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
// affect selection of a pool within the selected subnet.
auto global_host = context_->globalHost();
auto current_host = context_->currentHost();
- if ((global_host && !global_host->getClientClasses4().empty()) ||
+ if ((!context_->early_global_reservations_lookup_ &&
+ global_host && !global_host->getClientClasses4().empty()) ||
(!sn && current_host && !current_host->getClientClasses4().empty())) {
// We have already evaluated client classes and some of them may
// be in conflict with the reserved classes. Suppose there are
@@ -223,19 +229,9 @@ Dhcpv4Exchange::Dhcpv4Exchange(const AllocEnginePtr& alloc_engine,
// a result, the first_class set via the host reservation will
// replace the second_class because the second_class will this
// time evaluate to false as desired.
- const ClientClassDictionaryPtr& dict =
- CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
- const ClientClassDefListPtr& defs_ptr = dict->getClasses();
- for (auto def : *defs_ptr) {
- // Only remove evaluated classes. Other classes can be
- // assigned via hooks libraries and we should not remove
- // them because there is no way they can be added back.
- if (def->getMatchExpr()) {
- context_->query_->classes_.erase(def->getName());
- }
- }
+ removeDependentEvaluatedClasses(query);
setReservedClientClasses(context_);
- evaluateClasses(context_->query_, false);
+ evaluateClasses(query, false);
}
// Set KNOWN builtin class if something was found, UNKNOWN if not.
@@ -392,7 +388,7 @@ Dhcpv4Exchange::copyDefaultOptions() {
}
void
-Dhcpv4Exchange::setHostIdentifiers() {
+Dhcpv4Exchange::setHostIdentifiers(AllocEngine::ClientContext4Ptr context) {
const ConstCfgHostOperationsPtr cfg =
CfgMgr::instance().getCurrentCfg()->getCfgHostOperations4();
@@ -402,23 +398,23 @@ Dhcpv4Exchange::setHostIdentifiers() {
cfg->getIdentifierTypes()) {
switch (id_type) {
case Host::IDENT_HWADDR:
- if (context_->hwaddr_ && !context_->hwaddr_->hwaddr_.empty()) {
- context_->addHostIdentifier(id_type, context_->hwaddr_->hwaddr_);
+ if (context->hwaddr_ && !context->hwaddr_->hwaddr_.empty()) {
+ context->addHostIdentifier(id_type, context->hwaddr_->hwaddr_);
}
break;
case Host::IDENT_DUID:
- if (context_->clientid_) {
- const std::vector<uint8_t>& vec = context_->clientid_->getDuid();
+ if (context->clientid_) {
+ const std::vector<uint8_t>& vec = context->clientid_->getDuid();
if (!vec.empty()) {
// Client identifier type = DUID? Client identifier holding a DUID
// comprises Type (1 byte), IAID (4 bytes), followed by the actual
// DUID. Thus, the minimal length is 6.
if ((vec[0] == CLIENT_ID_OPTION_TYPE_DUID) && (vec.size() > 5)) {
// Extract DUID, skip IAID.
- context_->addHostIdentifier(id_type,
- std::vector<uint8_t>(vec.begin() + 5,
- vec.end()));
+ context->addHostIdentifier(id_type,
+ std::vector<uint8_t>(vec.begin() + 5,
+ vec.end()));
}
}
}
@@ -426,13 +422,13 @@ Dhcpv4Exchange::setHostIdentifiers() {
case Host::IDENT_CIRCUIT_ID:
{
- OptionPtr rai = query_->getOption(DHO_DHCP_AGENT_OPTIONS);
+ OptionPtr rai = context->query_->getOption(DHO_DHCP_AGENT_OPTIONS);
if (rai) {
OptionPtr circuit_id_opt = rai->getOption(RAI_OPTION_AGENT_CIRCUIT_ID);
if (circuit_id_opt) {
const OptionBuffer& circuit_id_vec = circuit_id_opt->getData();
if (!circuit_id_vec.empty()) {
- context_->addHostIdentifier(id_type, circuit_id_vec);
+ context->addHostIdentifier(id_type, circuit_id_vec);
}
}
}
@@ -440,10 +436,10 @@ Dhcpv4Exchange::setHostIdentifiers() {
break;
case Host::IDENT_CLIENT_ID:
- if (context_->clientid_) {
- const std::vector<uint8_t>& vec = context_->clientid_->getDuid();
+ if (context->clientid_) {
+ const std::vector<uint8_t>& vec = context->clientid_->getDuid();
if (!vec.empty()) {
- context_->addHostIdentifier(id_type, vec);
+ context->addHostIdentifier(id_type, vec);
}
}
break;
@@ -453,7 +449,7 @@ Dhcpv4Exchange::setHostIdentifiers() {
break;
}
- CalloutHandlePtr callout_handle = getCalloutHandle(context_->query_);
+ CalloutHandlePtr callout_handle = getCalloutHandle(context->query_);
Host::IdentifierType type = Host::IDENT_FLEX;
std::vector<uint8_t> id;
@@ -465,7 +461,7 @@ Dhcpv4Exchange::setHostIdentifiers() {
ScopedCalloutHandleState callout_handle_state(callout_handle);
// Pass incoming packet as argument
- callout_handle->setArgument("query4", context_->query_);
+ callout_handle->setArgument("query4", context->query_);
callout_handle->setArgument("id_type", type);
callout_handle->setArgument("id_value", id);
@@ -482,7 +478,7 @@ Dhcpv4Exchange::setHostIdentifiers() {
LOG_DEBUG(packet4_logger, DBGLVL_TRACE_BASIC, DHCP4_FLEX_ID)
.arg(Host::getIdentifierAsText(type, &id[0], id.size()));
- context_->addHostIdentifier(type, id);
+ context->addHostIdentifier(type, id);
}
break;
}
@@ -493,6 +489,21 @@ Dhcpv4Exchange::setHostIdentifiers() {
}
void
+Dhcpv4Exchange::removeDependentEvaluatedClasses(const Pkt4Ptr& query) {
+ const ClientClassDictionaryPtr& dict =
+ CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
+ const ClientClassDefListPtr& defs_ptr = dict->getClasses();
+ for (auto def : *defs_ptr) {
+ // Only remove evaluated classes. Other classes can be
+ // assigned via hooks libraries and we should not remove
+ // them because there is no way they can be added back.
+ if (def->getMatchExpr()) {
+ query->classes_.erase(def->getName());
+ }
+ }
+}
+
+void
Dhcpv4Exchange::setReservedClientClasses(AllocEngine::ClientContext4Ptr context) {
if (context->currentHost() && context->query_) {
const ClientClasses& classes = context->currentHost()->getClientClasses4();
@@ -934,6 +945,79 @@ Dhcpv4Srv::sendPacket(const Pkt4Ptr& packet) {
IfaceMgr::instance().send(packet);
}
+bool
+Dhcpv4Srv::earlyGHRLookup(const Pkt4Ptr& query,
+ AllocEngine::ClientContext4Ptr ctx) {
+ // Pointer to client's query.
+ ctx->query_ = query;
+
+ // Hardware address.
+ ctx->hwaddr_ = query->getHWAddr();
+
+ // Get the early-global-reservations-lookup flag value.
+ data::ConstElementPtr egrl = CfgMgr::instance().getCurrentCfg()->
+ getConfiguredGlobal(CfgGlobals::EARLY_GLOBAL_RESERVATIONS_LOOKUP);
+ if (egrl) {
+ ctx->early_global_reservations_lookup_ = egrl->boolValue();
+ }
+
+ // Perform early global reservations lookup when wanted.
+ if (ctx->early_global_reservations_lookup_) {
+ // Retrieve retrieve client identifier.
+ OptionPtr opt_clientid = query->getOption(DHO_DHCP_CLIENT_IDENTIFIER);
+ if (opt_clientid) {
+ ctx->clientid_.reset(new ClientId(opt_clientid->getData()));
+ }
+
+ // Get the host identifiers.
+ Dhcpv4Exchange::setHostIdentifiers(ctx);
+
+ // Check for global host reservations.
+ ConstHostPtr global_host = alloc_engine_->findGlobalReservation(*ctx);
+
+ if (global_host && !global_host->getClientClasses4().empty()) {
+ // Remove dependent evaluated classes.
+ Dhcpv4Exchange::removeDependentEvaluatedClasses(query);
+
+ // Add classes from the global reservations.
+ const ClientClasses& classes = global_host->getClientClasses4();
+ for (ClientClasses::const_iterator cclass = classes.cbegin();
+ cclass != classes.cend(); ++cclass) {
+ query->addClass(*cclass);
+ }
+
+ // Evaluate classes before KNOWN.
+ Dhcpv4Exchange::evaluateClasses(query, false);
+ }
+
+ if (global_host) {
+ // Add the KNOWN class;
+ query->addClass("KNOWN");
+ LOG_DEBUG(dhcp4_logger, DBG_DHCP4_BASIC, DHCP4_CLASS_ASSIGNED)
+ .arg(query->getLabel())
+ .arg("KNOWN");
+
+ // Evaluate classes after KNOWN.
+ Dhcpv4Exchange::evaluateClasses(query, true);
+
+ // Check the DROP special class.
+ if (query->inClass("DROP")) {
+ LOG_DEBUG(packet4_logger, DBGLVL_PKT_HANDLING,
+ DHCP4_PACKET_DROP_0014)
+ .arg(query->toText());
+ isc::stats::StatsMgr::instance().addValue("pkt4-receive-drop",
+ static_cast<int64_t>(1));
+ return (false);
+ }
+
+ // Store the reservation.
+ ctx->hosts_[SUBNET_ID_GLOBAL] = global_host;
+ }
+ }
+
+ return (true);
+}
+
int
Dhcpv4Srv::run() {
#ifdef ENABLE_AFL
@@ -1281,12 +1365,15 @@ Dhcpv4Srv::processDhcp4Query(Pkt4Ptr& query, Pkt4Ptr& rsp,
}
}
- AllocEngine::ClientContext4Ptr ctx;
+ AllocEngine::ClientContext4Ptr ctx(new AllocEngine::ClientContext4());
+ if (!earlyGHRLookup(query, ctx)) {
+ return;
+ }
try {
switch (query->getType()) {
case DHCPDISCOVER:
- rsp = processDiscover(query);
+ rsp = processDiscover(query, ctx);
break;
case DHCPREQUEST:
@@ -1305,7 +1392,7 @@ Dhcpv4Srv::processDhcp4Query(Pkt4Ptr& query, Pkt4Ptr& rsp,
break;
case DHCPINFORM:
- rsp = processInform(query);
+ rsp = processInform(query, ctx);
break;
default:
@@ -1363,8 +1450,8 @@ Dhcpv4Srv::processDhcp4Query(Pkt4Ptr& query, Pkt4Ptr& rsp,
if (allow_packet_park) {
// Get the parking limit. Parsing should ensure the value is present.
uint32_t parked_packet_limit = 0;
- data::ConstElementPtr ppl = CfgMgr::instance().
- getCurrentCfg()->getConfiguredGlobal("parked-packet-limit");
+ data::ConstElementPtr ppl = CfgMgr::instance().getCurrentCfg()->
+ getConfiguredGlobal(CfgGlobals::PARKED_PACKET_LIMIT);
if (ppl) {
parked_packet_limit = ppl->intValue();
}
@@ -3047,7 +3134,7 @@ Dhcpv4Srv::getNetmaskOption(const Subnet4Ptr& subnet) {
}
Pkt4Ptr
-Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
+Dhcpv4Srv::processDiscover(Pkt4Ptr& discover, AllocEngine::ClientContext4Ptr& context) {
// server-id is forbidden.
sanityCheck(discover, FORBIDDEN);
@@ -3059,7 +3146,7 @@ Dhcpv4Srv::processDiscover(Pkt4Ptr& discover) {
return (Pkt4Ptr());
}
- Dhcpv4Exchange ex(alloc_engine_, discover, subnet, drop);
+ Dhcpv4Exchange ex(alloc_engine_, discover, context, subnet, drop);
// Stop here if Dhcpv4Exchange constructor decided to drop the packet
if (drop) {
@@ -3130,7 +3217,7 @@ Dhcpv4Srv::processRequest(Pkt4Ptr& request, AllocEngine::ClientContext4Ptr& cont
return (Pkt4Ptr());
}
- Dhcpv4Exchange ex(alloc_engine_, request, subnet, drop);
+ Dhcpv4Exchange ex(alloc_engine_, request, context, subnet, drop);
// Stop here if Dhcpv4Exchange constructor decided to drop the packet
if (drop) {
@@ -3472,7 +3559,7 @@ Dhcpv4Srv::declineLease(const Lease4Ptr& lease, const Pkt4Ptr& decline,
}
Pkt4Ptr
-Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
+Dhcpv4Srv::processInform(Pkt4Ptr& inform, AllocEngine::ClientContext4Ptr& context) {
// server-id is supposed to be forbidden (as is requested address)
// but ISC DHCP does not enforce either. So neither will we.
sanityCheck(inform, OPTIONAL);
@@ -3485,7 +3572,7 @@ Dhcpv4Srv::processInform(Pkt4Ptr& inform) {
return (Pkt4Ptr());
}
- Dhcpv4Exchange ex(alloc_engine_, inform, subnet, drop);
+ Dhcpv4Exchange ex(alloc_engine_, inform, context, subnet, drop);
// Stop here if Dhcpv4Exchange constructor decided to drop the packet
if (drop) {
diff --git a/src/bin/dhcp4/dhcp4_srv.h b/src/bin/dhcp4/dhcp4_srv.h
index 147d12c121..b8ce076cef 100644
--- a/src/bin/dhcp4/dhcp4_srv.h
+++ b/src/bin/dhcp4/dhcp4_srv.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -72,9 +72,11 @@ public:
/// @param alloc_engine Pointer to the instance of the Allocation Engine
/// used by the server.
/// @param query Pointer to the client message.
+ /// @param context Pointer to the client context.
/// @param subnet Pointer to the subnet to which the client belongs.
/// @param drop if it is true the packet will be dropped.
Dhcpv4Exchange(const AllocEnginePtr& alloc_engine, const Pkt4Ptr& query,
+ AllocEngine::ClientContext4Ptr& context,
const Subnet4Ptr& subnet, bool& drop);
/// @brief Initializes the instance of the response message.
@@ -126,6 +128,24 @@ public:
/// server's response.
void setReservedMessageFields();
+ /// @brief Set host identifiers within a context.
+ ///
+ /// This method sets an ordered list of host identifier types and
+ /// values which the server should use to find host reservations.
+ /// The order of the set is determined by the configuration parameter,
+ /// host-reservation-identifiers
+ ///
+ /// @param context pointer to the context.
+ static void setHostIdentifiers(AllocEngine::ClientContext4Ptr context);
+
+ /// @brief Removed evaluated client classes.
+ ///
+ /// @todo: keep the list of dependent evaluated classes so
+ /// removed only them.
+ ///
+ /// @param query the query message.
+ static void removeDependentEvaluatedClasses(const Pkt4Ptr& query);
+
/// @brief Assigns classes retrieved from host reservation database.
///
/// @param context pointer to the context.
@@ -152,16 +172,6 @@ public:
/// @param pkt packet to be classified
static void classifyPacket(const Pkt4Ptr& pkt);
-private:
-
- /// @public
- /// @brief Assign class using vendor-class-identifier option
- ///
- /// @note This is the first part of @ref classifyPacket
- ///
- /// @param pkt packet to be classified
- static void classifyByVendor(const Pkt4Ptr& pkt);
-
/// @brief Evaluate classes.
///
/// @note Second part of the classification.
@@ -174,6 +184,16 @@ private:
/// UNKNOWN classes are skipped, if true only these classes are evaluated.
static void evaluateClasses(const Pkt4Ptr& pkt, bool depend_on_known);
+private:
+
+ /// @public
+ /// @brief Assign class using vendor-class-identifier option
+ ///
+ /// @note This is the first part of @ref classifyPacket
+ ///
+ /// @param pkt packet to be classified
+ static void classifyByVendor(const Pkt4Ptr& pkt);
+
/// @brief Copies default parameters from client's to server's message
///
/// Some fields are copied from client's message into server's response,
@@ -196,14 +216,6 @@ private:
/// not NULL.
void copyDefaultOptions();
- /// @brief Set host identifiers within a context.
- ///
- /// This method sets an ordered list of host identifier types and
- /// values which the server should use to find host reservations.
- /// The order of the set is determined by the configuration parameter,
- /// host-reservation-identifiers
- void setHostIdentifiers();
-
/// @brief Pointer to the allocation engine used by the server.
AllocEnginePtr alloc_engine_;
@@ -453,6 +465,16 @@ public:
return (test_send_responses_to_source_);
}
+ /// @brief Initialize client context and perform early global
+ /// reservations lookup.
+ ///
+ /// @param query The query message.
+ /// @param ctx Pointer to client context.
+ /// @return true if processing can continue, false if the query must be
+ /// dropped.
+ bool earlyGHRLookup(const Pkt4Ptr& query,
+ AllocEngine::ClientContext4Ptr ctx);
+
protected:
/// @name Functions filtering and sanity-checking received messages.
@@ -566,9 +588,10 @@ protected:
/// as an offer to a client if it should be served.
///
/// @param discover DISCOVER message received from client
+ /// @param context pointer to the client context
///
/// @return OFFER message or NULL
- Pkt4Ptr processDiscover(Pkt4Ptr& discover);
+ Pkt4Ptr processDiscover(Pkt4Ptr& discover, AllocEngine::ClientContext4Ptr& context);
/// @brief Processes incoming REQUEST and returns REPLY response.
///
@@ -580,8 +603,8 @@ protected:
/// Returns ACK message, NAK message, or NULL
///
/// @param request a message received from client
- /// @param [out] context pointer to the client context where allocated
- /// and deleted leases are stored.
+ /// @param context pointer to the client context where allocated and
+ /// deleted leases are stored.
///
/// @return ACK or NAK message
Pkt4Ptr processRequest(Pkt4Ptr& request, AllocEngine::ClientContext4Ptr& context);
@@ -592,8 +615,8 @@ protected:
/// this function does not return anything.
///
/// @param release message received from client
- /// @param [out] context pointer to the client context where released
- /// lease is stored.
+ /// @param context pointer to the client context where released lease is
+ /// stored.
void processRelease(Pkt4Ptr& release, AllocEngine::ClientContext4Ptr& context);
/// @brief Process incoming DHCPDECLINE messages.
@@ -603,16 +626,17 @@ protected:
/// the client and if it does, calls @ref declineLease.
///
/// @param decline message received from client
- /// @param [out] context pointer to the client context where declined
- /// lease is stored.
+ /// @param context pointer to the client context where declined lease is
+ /// stored.
void processDecline(Pkt4Ptr& decline, AllocEngine::ClientContext4Ptr& context);
/// @brief Processes incoming DHCPINFORM messages.
///
/// @param inform message received from client
+ /// @param context pointer to the client context
///
/// @return DHCPACK to be sent to the client.
- Pkt4Ptr processInform(Pkt4Ptr& inform);
+ Pkt4Ptr processInform(Pkt4Ptr& inform, AllocEngine::ClientContext4Ptr& context);
/// @brief Build the configured option list
///
diff --git a/src/bin/dhcp4/tests/classify_unittest.cc b/src/bin/dhcp4/tests/classify_unittest.cc
index eb11c25763..7c8d2d6a43 100644
--- a/src/bin/dhcp4/tests/classify_unittest.cc
+++ b/src/bin/dhcp4/tests/classify_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -107,6 +107,21 @@ namespace {
/// evaluation to the classification point after the host reservation
/// lookup, i.e. indirect KNOWN / UNKNOWN dependency.
///
+/// - Configuration 8:
+/// - Used for the early global reservations lookup / select subnet.
+/// - 2 subnets: 10.0.0.0/24 guarded by first and 10.0.1.0/24
+/// - 2 pools: 10.0.0.10-10.0.0.100 and 10.0.1.10-10.0.1.100
+/// - 1 global reservation for HW address 'aa:bb:cc:dd:ee:ff'
+/// setting the first class
+/// - the following class defined: first
+///
+/// - Configuration 9:
+/// - Used for the early global reservations lookup / drop.
+/// - 1 subnet: 10.0.0.0/24
+/// - 1 pool: 10.0.0.10-10.0.0.100
+/// - 1 reservation for HW address 'aa:bb:cc:dd:ee:ff'
+/// setting the DROP class
+///
const char* CONFIGS[] = {
// Configuration 0
"{ \"interfaces-config\": {"
@@ -369,7 +384,53 @@ const char* CONFIGS[] = {
" \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
" \"client-classes\": [ \"allowed\" ] } ]"
" } ]"
- "}"
+ "}",
+
+ // Configuration 8
+ "{ \"interfaces-config\": {"
+ " \"interfaces\": [ \"*\" ]"
+ "},"
+ "\"valid-lifetime\": 600,"
+ "\"early-global-reservations-lookup\": true,"
+ "\"client-classes\": ["
+ "{"
+ " \"name\": \"first\""
+ "}],"
+ "\"subnet4\": ["
+ "{"
+ " \"subnet\": \"10.0.0.0/24\","
+ " \"id\": 1,"
+ " \"interface\": \"eth0\","
+ " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ],"
+ " \"client-class\": \"first\""
+ "},"
+ "{"
+ " \"subnet\": \"10.0.1.0/24\","
+ " \"interface\": \"eth0\","
+ " \"id\": 2,"
+ " \"pools\": [ { \"pool\": \"10.0.1.10-10.0.1.100\" } ]"
+ "}],"
+ "\"reservations\": [ {"
+ " \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
+ " \"client-classes\": [ \"first\" ] } ]"
+ "}",
+
+ // Configuration 9
+ "{ \"interfaces-config\": {"
+ " \"interfaces\": [ \"*\" ]"
+ "},"
+ "\"valid-lifetime\": 600,"
+ "\"early-global-reservations-lookup\": true,"
+ "\"subnet4\": [ { "
+ " \"subnet\": \"10.0.0.0/24\", "
+ " \"id\": 1,"
+ " \"interface\": \"eth0\","
+ " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ] } ],"
+ "\"reservations\": [ {"
+ " \"hw-address\": \"aa:bb:cc:dd:ee:ff\","
+ " \"client-classes\": [ \"DROP\" ] } ]"
+ "}",
+
};
/// @brief Test fixture class for testing classification.
@@ -1308,4 +1369,75 @@ TEST_F(ClassifyTest, dropClassReservedClass) {
EXPECT_EQ(1, drop_stat->getInteger().first);
}
+// This test checks the early global reservations lookup for selecting
+// a guarded subnet.
+TEST_F(ClassifyTest, earlySubnet) {
+ Dhcp4Client client(Dhcp4Client::SELECTING);
+
+ // Configure DHCP server.
+ configure(CONFIGS[8], *client.getServer());
+
+ // Set the HW address to the reservation.
+ client.setHWAddress("aa:bb:cc:dd:ee:ff");
+
+ // Send the discover.
+ client.doDiscover();
+
+ // Check response.
+ Pkt4Ptr resp = client.getContext().response_;
+ ASSERT_TRUE(resp);
+ EXPECT_EQ("10.0.0.10", resp->getYiaddr().toText());
+
+ // Try with a different HW address.
+ Dhcp4Client client2(Dhcp4Client::SELECTING);
+
+ // Set the HW address to another value.
+ client2.setHWAddress("aa:bb:cc:01:ee:ff");
+
+ // Send the discover.
+ client2.doDiscover();
+
+ // Check response.
+ resp = client2.getContext().response_;
+ ASSERT_TRUE(resp);
+ EXPECT_EQ("10.0.1.10", resp->getYiaddr().toText());
+}
+
+// This test checks the early global reservations lookup for dropping.
+TEST_F(ClassifyTest, earlyDrop) {
+ Dhcp4Client client(Dhcp4Client::SELECTING);
+
+ // Configure DHCP server.
+ configure(CONFIGS[9], *client.getServer());
+
+ // Set the HW address to the reservation.
+ client.setHWAddress("aa:bb:cc:dd:ee:ff");
+
+ // Send the discover.
+ client.doDiscover();
+
+ // Match the reservation so dropped.
+ EXPECT_FALSE(client.getContext().response_);
+
+ // There should also be pkt4-receive-drop stat bumped up.
+ stats::StatsMgr& mgr = stats::StatsMgr::instance();
+ stats::ObservationPtr drop_stat = mgr.getObservation("pkt4-receive-drop");
+
+ // This statistic must be present and must be set to 1.
+ ASSERT_TRUE(drop_stat);
+ EXPECT_EQ(1, drop_stat->getInteger().first);
+
+ // Try with a different HW address.
+ Dhcp4Client client2(Dhcp4Client::SELECTING);
+
+ // Set the HW address to another value.
+ client2.setHWAddress("aa:bb:cc:01:ee:ff");
+
+ // Send the discover.
+ client2.doDiscover();
+
+ // Not matchine so not dropped.
+ EXPECT_TRUE(client2.getContext().response_);
+}
+
} // end of anonymous namespace
diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.cc b/src/bin/dhcp4/tests/dhcp4_test_utils.cc
index c16df94e3a..e987b5872d 100644
--- a/src/bin/dhcp4/tests/dhcp4_test_utils.cc
+++ b/src/bin/dhcp4/tests/dhcp4_test_utils.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -919,7 +919,10 @@ Dhcpv4SrvTest::createExchange(const Pkt4Ptr& query) {
bool drop = false;
Subnet4Ptr subnet = srv_.selectSubnet(query, drop);
EXPECT_FALSE(drop);
- Dhcpv4Exchange ex(srv_.alloc_engine_, query, subnet, drop);
+ AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ EXPECT_TRUE(srv_.earlyGHRLookup(query, context));
+ Dhcpv4Exchange ex(srv_.alloc_engine_, query, context, subnet, drop);
+ EXPECT_FALSE(context);
EXPECT_FALSE(drop);
return (ex);
}
diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.h b/src/bin/dhcp4/tests/dhcp4_test_utils.h
index 6fe8c87c40..cb36bd8aeb 100644
--- a/src/bin/dhcp4/tests/dhcp4_test_utils.h
+++ b/src/bin/dhcp4/tests/dhcp4_test_utils.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -211,12 +211,23 @@ public:
virtual ~NakedDhcpv4Srv() {
}
+ /// @brief Runs processing DHCPDISCOVER.
+ ///
+ /// @param discover a message received from client
+ /// @return DHCPOFFER message or null
+ Pkt4Ptr processDiscover(Pkt4Ptr& discover) {
+ AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ earlyGHRLookup(discover, context);
+ return (processDiscover(discover, context));
+ }
+
/// @brief Runs processing DHCPREQUEST.
///
/// @param request a message received from client
/// @return DHCPACK or DHCPNAK message
Pkt4Ptr processRequest(Pkt4Ptr& request) {
AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ earlyGHRLookup(request, context);
return (processRequest(request, context));
}
@@ -225,6 +236,7 @@ public:
/// @param release message received from client
void processRelease(Pkt4Ptr& release) {
AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ earlyGHRLookup(release, context);
processRelease(release, context);
}
@@ -233,9 +245,20 @@ public:
/// @param decline message received from client
void processDecline(Pkt4Ptr& decline) {
AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ earlyGHRLookup(decline, context);
processDecline(decline, context);
}
+ /// @brief Runs processing DHCPINFORM.
+ ///
+ /// @param inform a message received from client
+ /// @return DHCPACK message
+ Pkt4Ptr processInform(Pkt4Ptr& inform) {
+ AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4());
+ earlyGHRLookup(inform, context);
+ return (processInform(inform, context));
+ }
+
/// @brief Dummy server identifier option used by various tests.
OptionPtr server_id_;
diff --git a/src/bin/dhcp4/tests/get_config_unittest.cc b/src/bin/dhcp4/tests/get_config_unittest.cc
index 4fbb56f289..9717c95f60 100644
--- a/src/bin/dhcp4/tests/get_config_unittest.cc
+++ b/src/bin/dhcp4/tests/get_config_unittest.cc
@@ -2353,6 +2353,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -2434,6 +2435,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -2541,6 +2543,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -2648,6 +2651,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -2759,6 +2763,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -2949,6 +2954,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3139,6 +3145,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3248,6 +3255,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3360,6 +3368,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3472,6 +3481,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3581,6 +3591,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3690,6 +3701,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3828,6 +3840,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -3965,6 +3978,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4103,6 +4117,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4240,6 +4255,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4351,6 +4367,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4495,6 +4512,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4604,6 +4622,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4693,6 +4712,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4782,6 +4802,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4880,6 +4901,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -4969,6 +4991,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5058,6 +5081,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5147,6 +5171,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5236,6 +5261,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5362,6 +5388,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5488,6 +5515,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5624,6 +5652,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5741,6 +5770,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -5903,6 +5933,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6038,6 +6069,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6192,6 +6224,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6318,6 +6351,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6449,6 +6483,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6575,6 +6610,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6692,6 +6728,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6845,6 +6882,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -6969,6 +7007,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7097,6 +7136,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7178,6 +7218,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7259,6 +7300,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7368,6 +7410,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7477,6 +7520,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7586,6 +7630,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7695,6 +7740,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7804,6 +7850,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -7997,6 +8044,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -8121,6 +8169,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -8387,6 +8436,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -8526,6 +8576,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -8813,6 +8864,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -8952,6 +9004,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9031,6 +9084,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9110,6 +9164,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9189,6 +9244,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 35,\n"
@@ -9268,6 +9324,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9377,6 +9434,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9486,6 +9544,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9595,6 +9654,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9704,6 +9764,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9839,6 +9900,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -9969,6 +10031,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10074,6 +10137,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10183,6 +10247,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10293,6 +10358,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10407,6 +10473,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10521,6 +10588,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10660,6 +10728,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -10846,6 +10915,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11037,6 +11107,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11209,6 +11280,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11345,6 +11417,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11481,6 +11554,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11562,6 +11636,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
@@ -11641,6 +11716,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring4\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"echo-client-id\": true,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
diff --git a/src/bin/dhcp6/dhcp6_messages.cc b/src/bin/dhcp6/dhcp6_messages.cc
index cd2a55a691..6d3bed10d1 100644
--- a/src/bin/dhcp6/dhcp6_messages.cc
+++ b/src/bin/dhcp6/dhcp6_messages.cc
@@ -99,6 +99,7 @@ extern const isc::log::MessageID DHCP6_OPEN_SOCKET_FAIL = "DHCP6_OPEN_SOCKET_FAI
extern const isc::log::MessageID DHCP6_PACKET_DROP_DHCP_DISABLED = "DHCP6_PACKET_DROP_DHCP_DISABLED";
extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS = "DHCP6_PACKET_DROP_DROP_CLASS";
extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS2 = "DHCP6_PACKET_DROP_DROP_CLASS2";
+extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS_EARLY = "DHCP6_PACKET_DROP_DROP_CLASS_EARLY";
extern const isc::log::MessageID DHCP6_PACKET_DROP_DUPLICATE = "DHCP6_PACKET_DROP_DUPLICATE";
extern const isc::log::MessageID DHCP6_PACKET_DROP_PARSE_FAIL = "DHCP6_PACKET_DROP_PARSE_FAIL";
extern const isc::log::MessageID DHCP6_PACKET_DROP_SERVERID_MISMATCH = "DHCP6_PACKET_DROP_SERVERID_MISMATCH";
@@ -258,6 +259,7 @@ const char* values[] = {
"DHCP6_PACKET_DROP_DHCP_DISABLED", "%1: DHCP service is globally disabled",
"DHCP6_PACKET_DROP_DROP_CLASS", "dropped as member of the special class 'DROP': %1",
"DHCP6_PACKET_DROP_DROP_CLASS2", "dropped as member of the special class 'DROP' after host reservation lookup: %1",
+ "DHCP6_PACKET_DROP_DROP_CLASS_EARLY", "dropped as member of the special class 'DROP' after early global host reservations lookup: %1",
"DHCP6_PACKET_DROP_DUPLICATE", "dropped as sent by the same client than a packet being processed by another thread: dropped %1 by thread %2 as duplicate of %3 processed by %4",
"DHCP6_PACKET_DROP_PARSE_FAIL", "failed to parse packet from %1 to %2, received over interface %3, reason: %4",
"DHCP6_PACKET_DROP_SERVERID_MISMATCH", "%1: dropping packet with server identifier: %2, server is using: %3",
diff --git a/src/bin/dhcp6/dhcp6_messages.h b/src/bin/dhcp6/dhcp6_messages.h
index 29189dce11..4d0e10ffa2 100644
--- a/src/bin/dhcp6/dhcp6_messages.h
+++ b/src/bin/dhcp6/dhcp6_messages.h
@@ -100,6 +100,7 @@ extern const isc::log::MessageID DHCP6_OPEN_SOCKET_FAIL;
extern const isc::log::MessageID DHCP6_PACKET_DROP_DHCP_DISABLED;
extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS;
extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS2;
+extern const isc::log::MessageID DHCP6_PACKET_DROP_DROP_CLASS_EARLY;
extern const isc::log::MessageID DHCP6_PACKET_DROP_DUPLICATE;
extern const isc::log::MessageID DHCP6_PACKET_DROP_PARSE_FAIL;
extern const isc::log::MessageID DHCP6_PACKET_DROP_SERVERID_MISMATCH;
diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes
index c26879ba53..0799929d59 100644
--- a/src/bin/dhcp6/dhcp6_messages.mes
+++ b/src/bin/dhcp6/dhcp6_messages.mes
@@ -563,6 +563,11 @@ after a specified amount of time since receiving "dhcp-disable" command.
This debug message is emitted when an incoming packet was classified
into the special class 'DROP' and dropped. The packet details are displayed.
+% DHCP6_PACKET_DROP_DROP_CLASS_EARLY dropped as member of the special class 'DROP' after early global host reservations lookup: %1
+This debug message is emitted when an incoming packet was classified
+after early global host reservations lookup into the special class 'DROP'
+and dropped. The packet details are displayed.
+
% DHCP6_PACKET_DROP_DROP_CLASS2 dropped as member of the special class 'DROP' after host reservation lookup: %1
This debug message is emitted when an incoming packet was classified
after host reservation lookup into the special class 'DROP' and dropped.
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index d497005107..76c0ba0274 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -359,17 +359,146 @@ Dhcpv6Srv::testUnicast(const Pkt6Ptr& pkt) const {
}
void
+Dhcpv6Srv::setHostIdentifiers(AllocEngine::ClientContext6& ctx) {
+ const ConstCfgHostOperationsPtr cfg =
+ CfgMgr::instance().getCurrentCfg()->getCfgHostOperations6();
+ BOOST_FOREACH(const Host::IdentifierType& id_type,
+ cfg->getIdentifierTypes()) {
+ switch (id_type) {
+ case Host::IDENT_DUID:
+ if (ctx.duid_) {
+ ctx.addHostIdentifier(id_type, ctx.duid_->getDuid());
+ }
+ break;
+
+ case Host::IDENT_HWADDR:
+ if (ctx.hwaddr_) {
+ ctx.addHostIdentifier(id_type, ctx.hwaddr_->hwaddr_);
+ }
+ break;
+ case Host::IDENT_FLEX:
+ // At this point the information in the packet has been unpacked into
+ // the various packet fields and option objects has been created.
+ // Execute callouts registered for host6_identifier.
+ if (HooksManager::calloutsPresent(Hooks.hook_index_host6_identifier_)) {
+ CalloutHandlePtr callout_handle = getCalloutHandle(ctx.query_);
+
+ Host::IdentifierType type = Host::IDENT_FLEX;
+ std::vector<uint8_t> id;
+
+ // Use the RAII wrapper to make sure that the callout handle state is
+ // reset when this object goes out of scope. All hook points must do
+ // it to prevent possible circular dependency between the callout
+ // handle and its arguments.
+ ScopedCalloutHandleState callout_handle_state(callout_handle);
+
+ // Pass incoming packet as argument
+ callout_handle->setArgument("query6", ctx.query_);
+ callout_handle->setArgument("id_type", type);
+ callout_handle->setArgument("id_value", id);
+
+ // Call callouts
+ HooksManager::callCallouts(Hooks.hook_index_host6_identifier_,
+ *callout_handle);
+
+ callout_handle->getArgument("id_type", type);
+ callout_handle->getArgument("id_value", id);
+
+ if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
+ !id.empty()) {
+
+ LOG_DEBUG(packet6_logger, DBGLVL_TRACE_BASIC, DHCP6_FLEX_ID)
+ .arg(Host::getIdentifierAsText(type, &id[0], id.size()));
+
+ ctx.addHostIdentifier(type, id);
+ }
+ }
+ break;
+ default:
+ ;
+ }
+ }
+}
+
+bool
+Dhcpv6Srv::earlyGHRLookup(const Pkt6Ptr& query,
+ AllocEngine::ClientContext6& ctx) {
+ // Pointer to client's query.
+ ctx.query_ = query;
+
+ // DUID.
+ ctx.duid_ = query->getClientId();
+
+ // Hardware address.
+ ctx.hwaddr_ = getMAC(query);
+
+ // Get the early-global-reservations-lookup flag value.
+ data::ConstElementPtr egrl = CfgMgr::instance().getCurrentCfg()->
+ getConfiguredGlobal(CfgGlobals::EARLY_GLOBAL_RESERVATIONS_LOOKUP);
+ if (egrl) {
+ ctx.early_global_reservations_lookup_ = egrl->boolValue();
+ }
+
+ // Perform early global reservations lookup when wanted.
+ if (ctx.early_global_reservations_lookup_) {
+ // Get the host identifiers.
+ setHostIdentifiers(ctx);
+
+ // Check for global host reservations.
+ ConstHostPtr global_host = alloc_engine_->findGlobalReservation(ctx);
+
+ if (global_host && !global_host->getClientClasses6().empty()) {
+ // Remove dependent evaluated classes.
+ removeDependentEvaluatedClasses(query);
+
+ // Add classes from the global reservations.
+ const ClientClasses& classes = global_host->getClientClasses6();
+ for (ClientClasses::const_iterator cclass = classes.cbegin();
+ cclass != classes.cend(); ++cclass) {
+ query->addClass(*cclass);
+ }
+
+ // Evaluate classes before KNOWN.
+ evaluateClasses(query, false);
+ }
+
+ if (global_host) {
+ // Add the KNOWN class;
+ query->addClass("KNOWN");
+ LOG_DEBUG(dhcp6_logger, DBG_DHCP6_BASIC, DHCP6_CLASS_ASSIGNED)
+ .arg(query->getLabel())
+ .arg("KNOWN");
+
+ // Evaluate classes after KNOWN.
+ evaluateClasses(query, true);
+
+ // Check the DROP special class.
+ if (query->inClass("DROP")) {
+ LOG_DEBUG(packet6_logger, DBGLVL_PKT_HANDLING,
+ DHCP6_PACKET_DROP_DROP_CLASS_EARLY)
+ .arg(query->toText());
+ StatsMgr::instance().addValue("pkt6-receive-drop",
+ static_cast<int64_t>(1));
+ return (false);
+ }
+
+ // Store the reservation.
+ ctx.hosts_[SUBNET_ID_GLOBAL] = global_host;
+ }
+ }
+
+ return (true);
+}
+
+void
Dhcpv6Srv::initContext(const Pkt6Ptr& pkt,
AllocEngine::ClientContext6& ctx,
bool& drop) {
ctx.subnet_ = selectSubnet(pkt, drop);
- ctx.duid_ = pkt->getClientId(),
ctx.fwd_dns_update_ = false;
ctx.rev_dns_update_ = false;
ctx.hostname_ = "";
- ctx.query_ = pkt;
ctx.callout_handle_ = getCalloutHandle(pkt);
- ctx.hwaddr_ = getMAC(pkt);
if (drop) {
// Caller will immediately drop the packet so simply return now.
@@ -381,63 +510,10 @@ Dhcpv6Srv::initContext(const Pkt6Ptr& pkt,
// order to search for host reservations.
SharedNetwork6Ptr sn;
if (ctx.subnet_) {
- const ConstCfgHostOperationsPtr cfg =
- CfgMgr::instance().getCurrentCfg()->getCfgHostOperations6();
- BOOST_FOREACH(const Host::IdentifierType& id_type,
- cfg->getIdentifierTypes()) {
- switch (id_type) {
- case Host::IDENT_DUID:
- if (ctx.duid_) {
- ctx.addHostIdentifier(id_type, ctx.duid_->getDuid());
- }
- break;
-
- case Host::IDENT_HWADDR:
- if (ctx.hwaddr_) {
- ctx.addHostIdentifier(id_type, ctx.hwaddr_->hwaddr_);
- }
- break;
- case Host::IDENT_FLEX:
- // At this point the information in the packet has been unpacked into
- // the various packet fields and option objects has been created.
- // Execute callouts registered for host6_identifier.
- if (HooksManager::calloutsPresent(Hooks.hook_index_host6_identifier_)) {
- CalloutHandlePtr callout_handle = getCalloutHandle(pkt);
-
- Host::IdentifierType type = Host::IDENT_FLEX;
- std::vector<uint8_t> id;
-
- // Use the RAII wrapper to make sure that the callout handle state is
- // reset when this object goes out of scope. All hook points must do
- // it to prevent possible circular dependency between the callout
- // handle and its arguments.
- ScopedCalloutHandleState callout_handle_state(callout_handle);
-
- // Pass incoming packet as argument
- callout_handle->setArgument("query6", pkt);
- callout_handle->setArgument("id_type", type);
- callout_handle->setArgument("id_value", id);
-
- // Call callouts
- HooksManager::callCallouts(Hooks.hook_index_host6_identifier_,
- *callout_handle);
-
- callout_handle->getArgument("id_type", type);
- callout_handle->getArgument("id_value", id);
-
- if ((callout_handle->getStatus() == CalloutHandle::NEXT_STEP_CONTINUE) &&
- !id.empty()) {
-
- LOG_DEBUG(packet6_logger, DBGLVL_TRACE_BASIC, DHCP6_FLEX_ID)
- .arg(Host::getIdentifierAsText(type, &id[0], id.size()));
-
- ctx.addHostIdentifier(type, id);
- }
- }
- break;
- default:
- ;
- }
+ // Before we can check for static reservations, we need to prepare
+ // a set of identifiers to be used for this.
+ if (!ctx.early_global_reservations_lookup_) {
+ setHostIdentifiers(ctx);
}
// Find host reservations using specified identifiers.
@@ -455,7 +531,8 @@ Dhcpv6Srv::initContext(const Pkt6Ptr& pkt,
// affect selection of a pool within the selected subnet.
auto global_host = ctx.globalHost();
auto current_host = ctx.currentHost();
- if ((global_host && !global_host->getClientClasses6().empty()) ||
+ if ((!ctx.early_global_reservations_lookup_ &&
+ global_host && !global_host->getClientClasses6().empty()) ||
(!sn && current_host && !current_host->getClientClasses6().empty())) {
// We have already evaluated client classes and some of them may
// be in conflict with the reserved classes. Suppose there are
@@ -471,17 +548,7 @@ Dhcpv6Srv::initContext(const Pkt6Ptr& pkt,
// a result, the first_class set via the host reservation will
// replace the second_class because the second_class will this
// time evaluate to false as desired.
- const ClientClassDictionaryPtr& dict =
- CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
- const ClientClassDefListPtr& defs_ptr = dict->getClasses();
- for (auto def : *defs_ptr) {
- // Only remove evaluated classes. Other classes can be
- // assigned via hooks libraries and we should not remove
- // them because there is no way they can be added back.
- if (def->getMatchExpr()) {
- ctx.query_->classes_.erase(def->getName());
- }
- }
+ removeDependentEvaluatedClasses(pkt);
setReservedClientClasses(pkt, ctx);
evaluateClasses(pkt, false);
}
@@ -823,13 +890,6 @@ Dhcpv6Srv::processPacket(Pkt6Ptr& query, Pkt6Ptr& rsp) {
return;
}
- if (query->getType() == DHCPV6_DHCPV4_QUERY) {
- // This call never throws. Should this change, this section must be
- // enclosed in try-catch.
- processDhcp4Query(query);
- return;
- }
-
processDhcp6Query(query, rsp);
}
@@ -874,6 +934,18 @@ Dhcpv6Srv::processDhcp6Query(Pkt6Ptr& query, Pkt6Ptr& rsp) {
// Let's create a simplified client context here.
AllocEngine::ClientContext6 ctx;
+ if (!earlyGHRLookup(query, ctx)) {
+ return;
+ }
+
+ if (query->getType() == DHCPV6_DHCPV4_QUERY) {
+ // This call never throws. Should this change, this section must be
+ // enclosed in try-catch.
+ processDhcp4Query(query);
+ return;
+ }
+
+ // Complete the client context initialization.
bool drop = false;
initContext(query, ctx, drop);
@@ -1034,8 +1106,8 @@ Dhcpv6Srv::processDhcp6Query(Pkt6Ptr& query, Pkt6Ptr& rsp) {
// Get the parking limit. Parsing should ensure the value is present.
uint32_t parked_packet_limit = 0;
- data::ConstElementPtr ppl = CfgMgr::instance().
- getCurrentCfg()->getConfiguredGlobal("parked-packet-limit");
+ data::ConstElementPtr ppl = CfgMgr::instance().getCurrentCfg()->
+ getConfiguredGlobal(CfgGlobals::PARKED_PACKET_LIMIT);
if (ppl) {
parked_packet_limit = ppl->intValue();
}
@@ -3804,6 +3876,21 @@ void Dhcpv6Srv::evaluateClasses(const Pkt6Ptr& pkt, bool depend_on_known) {
}
void
+Dhcpv6Srv::removeDependentEvaluatedClasses(const Pkt6Ptr& pkt) {
+ const ClientClassDictionaryPtr& dict =
+ CfgMgr::instance().getCurrentCfg()->getClientClassDictionary();
+ const ClientClassDefListPtr& defs_ptr = dict->getClasses();
+ for (auto def : *defs_ptr) {
+ // Only remove evaluated classes. Other classes can be
+ // assigned via hooks libraries and we should not remove
+ // them because there is no way they can be added back.
+ if (def->getMatchExpr()) {
+ pkt->classes_.erase(def->getName());
+ }
+ }
+}
+
+void
Dhcpv6Srv::setReservedClientClasses(const Pkt6Ptr& pkt,
const AllocEngine::ClientContext6& ctx) {
if (ctx.currentHost() && pkt) {
diff --git a/src/bin/dhcp6/dhcp6_srv.h b/src/bin/dhcp6/dhcp6_srv.h
index 4a891a7081..f18e786380 100644
--- a/src/bin/dhcp6/dhcp6_srv.h
+++ b/src/bin/dhcp6/dhcp6_srv.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -255,6 +255,26 @@ public:
/// Called during reconfigure and shutdown.
void discardPackets();
+ /// @brief Initialize client context and perform early global
+ /// reservations lookup.
+ ///
+ /// @param query The query message.
+ /// @param ctx Reference to client context.
+ /// @return true if processing can continue, false if the query must be
+ /// dropped.
+ bool earlyGHRLookup(const Pkt6Ptr& query,
+ AllocEngine::ClientContext6& ctx);
+
+ /// @brief Set host identifiers within a context.
+ ///
+ /// This method sets an ordered list of host identifier types and
+ /// values which the server should use to find host reservations.
+ /// The order of the set is determined by the configuration parameter,
+ /// host-reservation-identifiers
+ ///
+ /// @param ctx reference to the context.
+ static void setHostIdentifiers(AllocEngine::ClientContext6& ctx);
+
protected:
/// @brief This function sets statistics related to DHCPv6 packets processing
@@ -822,6 +842,14 @@ protected:
/// UNKNOWN classes are skipped, if true only these classes are evaluated.
void evaluateClasses(const Pkt6Ptr& pkt, bool depend_on_known);
+ /// @brief Removed evaluated client classes.
+ ///
+ /// @todo: keep the list of dependent evaluated classes so
+ /// removed only them.
+ ///
+ /// @param pkt the packet.
+ static void removeDependentEvaluatedClasses(const Pkt6Ptr& pkt);
+
/// @brief Assigns classes retrieved from host reservation database.
///
/// @param pkt Pointer to the packet to which classes will be assigned.
diff --git a/src/bin/dhcp6/tests/classify_unittests.cc b/src/bin/dhcp6/tests/classify_unittests.cc
index 0a2899b3dc..8791a80654 100644
--- a/src/bin/dhcp6/tests/classify_unittests.cc
+++ b/src/bin/dhcp6/tests/classify_unittests.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2016-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2016-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -85,7 +85,7 @@ namespace {
/// - Configuration 5:
/// - Used for the DROP class and reservation class
/// - 1 subnet: 2001:db8:1::/48
-/// - 2 pool: 2001:db8:1:1::/64
+/// - 1 pool: 2001:db8:1:1::/64
/// - the following class defined:
/// - allowed
/// - member('KNOWN') or member('UNKNOWN'), t
@@ -94,6 +94,19 @@ namespace {
/// evaluation to the classification point after the host reservation
/// lookup, i.e. indirect KNOWN / UNKNOWN dependency
///
+/// - Configuration 6:
+/// - Used for the early global reservations lookup / select subnet.
+/// - 2 subnets: 2001:db8:1::/48 (guarded) and 2001:db8:2::/48
+/// - 2 pools: 2001:db8:1:1::/64 and 2001:db8:2:1::/64
+/// - 1 global reservation setting the first class
+/// - the following class defined: first
+///
+/// - Configuration 7:
+/// - Used for the early global reservations lookup / drop.
+/// - 1 subnet: 2001:db8:1::/48
+/// - 1 pool: 2001:db8:1:1::/64
+/// - 1 global reservation setting the DROP class
+///
const char* CONFIGS[] = {
// Configuration 0
"{ \"interfaces-config\": {"
@@ -364,7 +377,67 @@ const char* CONFIGS[] = {
" \"client-classes\": [ \"allowed\" ]"
" } ]"
" } ],"
- "\"valid-lifetime\": 4000 }"
+ "\"valid-lifetime\": 4000 }",
+
+ // Configuration 6
+ "{ \"interfaces-config\": {"
+ " \"interfaces\": [ \"*\" ]"
+ "},"
+ "\"early-global-reservations-lookup\": true, "
+ "\"preferred-lifetime\": 3000, "
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"client-classes\": ["
+ "{"
+ " \"name\": \"first\""
+ "}"
+ "],"
+ "\"subnet6\": [ "
+ "{"
+ " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], "
+ " \"subnet\": \"2001:db8:1::/48\", "
+ " \"interface\": \"eth1\","
+ " \"id\": 1,"
+ " \"client-class\": \"first\""
+ "},"
+ "{"
+ " \"pools\": [ { \"pool\": \"2001:db8:2::/64\" } ], "
+ " \"subnet\": \"2001:db8:2::/48\", "
+ " \"interface\": \"eth1\","
+ " \"id\": 2"
+ "}"
+ "],"
+ "\"reservations\": ["
+ "{"
+ " \"duid\": \"01:02:03:04\","
+ " \"client-classes\": [ \"first\" ]"
+ "}"
+ "],"
+ "\"valid-lifetime\": 4000 }",
+
+ // Configuration 7
+ "{ \"interfaces-config\": {"
+ " \"interfaces\": [ \"*\" ]"
+ "},"
+ "\"early-global-reservations-lookup\": true, "
+ "\"preferred-lifetime\": 3000, "
+ "\"rebind-timer\": 2000, "
+ "\"renew-timer\": 1000, "
+ "\"subnet6\": [ "
+ "{"
+ " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ], "
+ " \"subnet\": \"2001:db8:1::/48\", "
+ " \"interface\": \"eth1\","
+ " \"id\": 1"
+ "}"
+ "],"
+ "\"reservations\": ["
+ "{"
+ " \"duid\": \"01:02:03:04\","
+ " \"client-classes\": [ \"DROP\" ]"
+ "}"
+ "],"
+ "\"valid-lifetime\": 4000 }"
};
/// @brief Test fixture class for testing client classification by the
@@ -545,15 +618,20 @@ TEST_F(ClassifyTest, matchClassification) {
// Process queries
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(query3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(query3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response3 = srv.processSolicit(ctx3);
@@ -651,15 +729,20 @@ TEST_F(ClassifyTest, required) {
// Process queries
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(query3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(query3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response3 = srv.processSolicit(ctx3);
@@ -754,15 +837,20 @@ TEST_F(ClassifyTest, requiredClassification) {
// Process queries
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(query3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(query3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response3 = srv.processSolicit(ctx3);
@@ -840,7 +928,8 @@ TEST_F(ClassifyTest, subnetClassPriority) {
// Process the query
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(query, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response = srv.processSolicit(ctx);
@@ -905,7 +994,8 @@ TEST_F(ClassifyTest, subnetGlobalPriority) {
// Process the query
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(query, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response = srv.processSolicit(ctx);
@@ -979,7 +1069,8 @@ TEST_F(ClassifyTest, classGlobalPriority) {
// Process the query
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(query, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response = srv.processSolicit(ctx);
@@ -1046,7 +1137,8 @@ TEST_F(ClassifyTest, classGlobalPersistency) {
// Process the query
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(query, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response = srv.processSolicit(ctx);
@@ -1167,7 +1259,8 @@ TEST_F(ClassifyTest, clientClassifyPool) {
// be serviced
srv.classifyPacket(query1);
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
@@ -1182,6 +1275,8 @@ TEST_F(ClassifyTest, clientClassifyPool) {
// Still not supported, because it belongs to wrong class.
srv.classifyPacket(query2);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
@@ -1196,6 +1291,8 @@ TEST_F(ClassifyTest, clientClassifyPool) {
// This time it should work
srv.classifyPacket(query3);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(query3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(query3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response3 = srv.processSolicit(ctx3);
@@ -1251,7 +1348,8 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) {
// First pool requires reservation so the second will be used
srv.classifyPacket(query1);
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
@@ -1280,6 +1378,8 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) {
// Now the first pool will be used
srv.classifyPacket(query2);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
@@ -1576,15 +1676,20 @@ TEST_F(ClassifyTest, member) {
// Process queries
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(query1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(query1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response1 = srv.processSolicit(ctx1);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(query2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(query2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response2 = srv.processSolicit(ctx2);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(query3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(query3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response3 = srv.processSolicit(ctx3);
@@ -2280,4 +2385,88 @@ TEST_F(ClassifyTest, dropClassReservedClass) {
EXPECT_EQ(1, drop_stat->getInteger().first);
}
+// This test checks the early global reservations lookup for selecting
+// a guarded subnet.
+TEST_F(ClassifyTest, earlySubnet) {
+ Dhcp6Client client;
+ client.setDUID("01:02:03:04");
+ client.setInterface("eth1");
+ client.requestAddress();
+
+ // Configure DHCP server.
+ ASSERT_NO_THROW(configure(CONFIGS[6], *client.getServer()));
+
+ // Send a message to the server.
+ ASSERT_NO_THROW(client.doSolicit(true));
+
+ // Check response.
+ Pkt6Ptr resp = client.getContext().response_;
+ ASSERT_TRUE(resp);
+ OptionPtr ia_na = resp->getOption(D6O_IA_NA);
+ ASSERT_TRUE(ia_na);
+ EXPECT_FALSE(ia_na->getOption(D6O_STATUS_CODE));
+ OptionPtr iaaddr = ia_na->getOption(D6O_IAADDR);
+ ASSERT_TRUE(iaaddr);
+ boost::shared_ptr<Option6IAAddr> addr =
+ boost::dynamic_pointer_cast<Option6IAAddr>(iaaddr);
+ ASSERT_TRUE(addr);
+ EXPECT_EQ("2001:db8:1::", addr->getAddress().toText());
+
+ // Retry with another DUID.
+ Dhcp6Client client2;
+ client2.setDUID("01:02:03:05");
+ client2.setInterface("eth1");
+ client2.requestAddress();
+
+ ASSERT_NO_THROW(client2.doSolicit(true));
+
+ // Check response.
+ resp = client2.getContext().response_;
+ ASSERT_TRUE(resp);
+ ia_na = resp->getOption(D6O_IA_NA);
+ ASSERT_TRUE(ia_na);
+ EXPECT_FALSE(ia_na->getOption(D6O_STATUS_CODE));
+ iaaddr = ia_na->getOption(D6O_IAADDR);
+ ASSERT_TRUE(iaaddr);
+ addr = boost::dynamic_pointer_cast<Option6IAAddr>(iaaddr);
+ ASSERT_TRUE(addr);
+ EXPECT_EQ("2001:db8:2::", addr->getAddress().toText());
+}
+
+// This test checks the early global reservations lookup for dropping.
+TEST_F(ClassifyTest, earlyDrop) {
+ Dhcp6Client client;
+ client.setDUID("01:02:03:04");
+ client.setInterface("eth1");
+ client.requestAddress();
+
+ // Configure DHCP server.
+ ASSERT_NO_THROW(configure(CONFIGS[7], *client.getServer()));
+
+ // Send a message to the server.
+ ASSERT_NO_THROW(client.doSolicit(true));
+
+ // Match the reservation so dropped.
+ EXPECT_FALSE(client.getContext().response_);
+
+ // There should also be pkt6-receive-drop stat bumped up.
+ stats::StatsMgr& mgr = stats::StatsMgr::instance();
+ stats::ObservationPtr drop_stat = mgr.getObservation("pkt6-receive-drop");
+
+ // This statistic must be present and must be set to 1.
+ ASSERT_TRUE(drop_stat);
+ EXPECT_EQ(1, drop_stat->getInteger().first);
+
+ // Retry with another DUID.
+ Dhcp6Client client2;
+ client2.setDUID("01:02:03:05");
+ client2.setInterface("eth1");
+ client2.requestAddress();
+
+ ASSERT_NO_THROW(client2.doSolicit(true));
+
+ // Not matchine so not dropped.
+ EXPECT_TRUE(client2.getContext().response_);
+}
+
} // end of anonymous namespace
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index c0865b73b8..f6d0eeef81 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2011-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -162,7 +162,8 @@ TEST_F(NakedDhcpv6SrvTest, SolicitNoSubnet) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -388,7 +389,8 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_.processSolicit(ctx);
@@ -416,6 +418,8 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) {
// Need to process SOLICIT again after requesting new option.
AllocEngine::ClientContext6 ctx2;
+ drop = !srv_.earlyGHRLookup(sol, ctx2);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx2, drop);
ASSERT_FALSE(drop);
adv = srv_.processSolicit(ctx2);
@@ -481,7 +485,8 @@ TEST_F(Dhcpv6SrvTest, SolicitBasic) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -530,7 +535,8 @@ TEST_F(Dhcpv6SrvTest, pdSolicitBasic) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -572,7 +578,8 @@ TEST_F(Dhcpv6SrvTest, defaultLifetimeSolicit) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -619,7 +626,8 @@ TEST_F(Dhcpv6SrvTest, hintZeroLifetimeSolicit) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -668,7 +676,8 @@ TEST_F(Dhcpv6SrvTest, hintLifetimeSolicit) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -715,7 +724,8 @@ TEST_F(Dhcpv6SrvTest, minLifetimeSolicit) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -764,7 +774,8 @@ TEST_F(Dhcpv6SrvTest, maxLifetimeSolicit) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -823,7 +834,8 @@ TEST_F(Dhcpv6SrvTest, SolicitHint) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -881,7 +893,8 @@ TEST_F(Dhcpv6SrvTest, SolicitInvalidHint) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -946,15 +959,20 @@ TEST_F(Dhcpv6SrvTest, ManySolicits) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx1;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol1, ctx1);
+ ASSERT_FALSE(drop);
srv.initContext(sol1, ctx1, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply1 = srv.processSolicit(ctx1);
AllocEngine::ClientContext6 ctx2;
+ drop = !srv.earlyGHRLookup(sol2, ctx2);
+ ASSERT_FALSE(drop);
srv.initContext(sol2, ctx2, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply2 = srv.processSolicit(ctx2);
AllocEngine::ClientContext6 ctx3;
+ drop = !srv.earlyGHRLookup(sol3, ctx3);
+ ASSERT_FALSE(drop);
srv.initContext(sol3, ctx3, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply3 = srv.processSolicit(ctx3);
@@ -1043,7 +1061,8 @@ TEST_F(Dhcpv6SrvTest, SolicitCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -1114,7 +1133,8 @@ TEST_F(Dhcpv6SrvTest, pdSolicitCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
@@ -1409,7 +1429,8 @@ TEST_F(Dhcpv6SrvTest, RequestCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(req, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(req, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processRequest(ctx);
@@ -1480,7 +1501,8 @@ TEST_F(Dhcpv6SrvTest, pdRequestCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(req, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(req, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processRequest(ctx);
@@ -1693,7 +1715,8 @@ TEST_F(Dhcpv6SrvTest, RenewCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(req, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(req, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processRenew(ctx);
@@ -1764,7 +1787,8 @@ TEST_F(Dhcpv6SrvTest, pdRenewCache) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(req, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(req, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processRenew(ctx);
@@ -2613,7 +2637,8 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) {
// Let the server process it and generate a response.
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr response = srv_.processSolicit(ctx);
@@ -2633,6 +2658,8 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) {
// Let the server process it again. This time the name-servers
// option should be present.
AllocEngine::ClientContext6 ctx2;
+ drop = !srv_.earlyGHRLookup(sol, ctx2);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx2, drop);
ASSERT_FALSE(drop);
response = srv_.processSolicit(ctx2);
@@ -2653,6 +2680,8 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) {
// Let the server process it again.
AllocEngine::ClientContext6 ctx3;
+ drop = !srv_.earlyGHRLookup(sol, ctx3);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx3, drop);
ASSERT_FALSE(drop);
response = srv_.processSolicit(ctx3);
@@ -3430,7 +3459,8 @@ TEST_F(Dhcpv6SrvTest, calculateTeeTimers) {
subnet_->setT1Percent((*test).t1_percent_);
subnet_->setT2Percent((*test).t2_percent_);
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr reply = srv.processSolicit(ctx);
diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h
index f894b213f1..69a7021c0e 100644
--- a/src/bin/dhcp6/tests/dhcp6_test_utils.h
+++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -230,7 +230,7 @@ public:
/// @return REPLY message or NULL
Pkt6Ptr processRequest(const Pkt6Ptr& request) {
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !earlyGHRLookup(request, ctx);
initContext(request, ctx, drop);
if (drop) {
return (Pkt6Ptr());
@@ -244,7 +244,7 @@ public:
/// @return REPLY message or NULL
Pkt6Ptr processRenew(const Pkt6Ptr& renew) {
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !earlyGHRLookup(renew, ctx);
initContext(renew, ctx, drop);
if (drop) {
return (Pkt6Ptr());
@@ -258,7 +258,7 @@ public:
/// @return REPLY message or NULL
Pkt6Ptr processRebind(const Pkt6Ptr& rebind) {
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !earlyGHRLookup(rebind, ctx);
initContext(rebind, ctx, drop);
if (drop) {
return (Pkt6Ptr());
@@ -272,7 +272,7 @@ public:
/// @return REPLY message or NULL
Pkt6Ptr processRelease(const Pkt6Ptr& release) {
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !earlyGHRLookup(release, ctx);
initContext(release, ctx, drop);
if (drop) {
return (Pkt6Ptr());
@@ -286,7 +286,7 @@ public:
/// @return REPLY message or NULL
Pkt6Ptr processDecline(const Pkt6Ptr& decline) {
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !earlyGHRLookup(decline, ctx);
initContext(decline, ctx, drop);
if (drop) {
return (Pkt6Ptr());
@@ -312,6 +312,7 @@ public:
using Dhcpv6Srv::shutdown_;
using Dhcpv6Srv::name_change_reqs_;
using Dhcpv6Srv::VENDOR_CLASS_PREFIX;
+ using Dhcpv6Srv::earlyGHRLookup;
using Dhcpv6Srv::initContext;
using Dhcpv6Srv::server_port_;
using Dhcpv6Srv::client_port_;
diff --git a/src/bin/dhcp6/tests/fqdn_unittest.cc b/src/bin/dhcp6/tests/fqdn_unittest.cc
index 7237dd2b94..1cca731d92 100644
--- a/src/bin/dhcp6/tests/fqdn_unittest.cc
+++ b/src/bin/dhcp6/tests/fqdn_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -454,7 +454,7 @@ public:
}
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(query, ctx);
srv_->initContext(query, ctx, drop);
Pkt6Ptr answer = generateMessageWithIds(DHCPV6_ADVERTISE);
@@ -515,7 +515,8 @@ public:
// functions to generate response.
Pkt6Ptr reply;
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(req, ctx);
+ ASSERT_FALSE(drop);
srv_->initContext(req, ctx, drop);
ASSERT_FALSE(drop);
diff --git a/src/bin/dhcp6/tests/get_config_unittest.cc b/src/bin/dhcp6/tests/get_config_unittest.cc
index aa0a7fd4fa..cb9512bab6 100644
--- a/src/bin/dhcp6/tests/get_config_unittest.cc
+++ b/src/bin/dhcp6/tests/get_config_unittest.cc
@@ -2076,6 +2076,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -2162,6 +2163,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -2282,6 +2284,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -2485,6 +2488,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -2688,6 +2692,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -2891,6 +2896,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3011,6 +3017,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3128,6 +3135,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3245,6 +3253,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3398,6 +3407,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3514,6 +3524,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3632,6 +3643,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3752,6 +3764,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -3887,6 +3900,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4005,6 +4019,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4099,6 +4114,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4193,6 +4209,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4296,6 +4313,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4390,6 +4408,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4484,6 +4503,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4617,6 +4637,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4750,6 +4771,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -4893,6 +4915,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5015,6 +5038,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5184,6 +5208,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5347,6 +5372,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5516,6 +5542,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5647,6 +5674,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5782,6 +5810,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5868,6 +5897,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -5954,6 +5984,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6070,6 +6101,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6186,6 +6218,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6392,6 +6425,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6523,6 +6557,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6662,6 +6697,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6778,6 +6814,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -6894,6 +6931,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7010,6 +7048,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7259,6 +7298,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7398,6 +7438,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7484,6 +7525,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7570,6 +7612,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -7876,6 +7919,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8024,6 +8068,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8110,6 +8155,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8194,6 +8240,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8278,6 +8325,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8362,6 +8410,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 35,\n"
" \"hold-reclaimed-time\": 1800,\n"
@@ -8460,6 +8509,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8576,6 +8626,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8692,6 +8743,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8809,6 +8861,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -8931,6 +8984,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9053,6 +9107,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9171,6 +9226,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9290,6 +9346,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9414,6 +9471,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9546,6 +9604,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9754,6 +9813,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -9970,6 +10030,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -10056,6 +10117,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -10140,6 +10202,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
@@ -10240,6 +10303,7 @@ const char* UNPARSED_CONFIGS[] = {
" \"queue-type\": \"kea-ring6\"\n"
" },\n"
" \"dhcp4o6-port\": 0,\n"
+" \"early-global-reservations-lookup\": false,\n"
" \"expired-leases-processing\": {\n"
" \"flush-reclaimed-timer-wait-time\": 25,\n"
" \"hold-reclaimed-time\": 3600,\n"
diff --git a/src/bin/dhcp6/tests/hooks_unittest.cc b/src/bin/dhcp6/tests/hooks_unittest.cc
index 48e7e5687f..3f2f0ea683 100644
--- a/src/bin/dhcp6/tests/hooks_unittest.cc
+++ b/src/bin/dhcp6/tests/hooks_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2013-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2013-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -1696,7 +1696,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6Select) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_->initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_->processSolicit(ctx);
@@ -1781,7 +1782,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6SelectChange) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_->initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_->processSolicit(ctx);
@@ -4982,7 +4984,8 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_->initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_->processSolicit(ctx);
@@ -5064,7 +5067,8 @@ TEST_F(HooksDhcpv6SrvTest, host6Identifier_hwaddr) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_->earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_->initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_->processSolicit(ctx);
diff --git a/src/bin/dhcp6/tests/vendor_opts_unittest.cc b/src/bin/dhcp6/tests/vendor_opts_unittest.cc
index f8ba1d8147..51bb4b5df1 100644
--- a/src/bin/dhcp6/tests/vendor_opts_unittest.cc
+++ b/src/bin/dhcp6/tests/vendor_opts_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2019-2021 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2019-2022 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -114,7 +114,8 @@ public:
// Pass it to the server and get an advertise.
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_.processSolicit(ctx);
@@ -137,6 +138,8 @@ public:
// Need to process SOLICIT again after requesting new option.
AllocEngine::ClientContext6 ctx2;
+ drop = !srv_.earlyGHRLookup(sol, ctx2);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx2, drop);
ASSERT_FALSE(drop);
adv = srv_.processSolicit(ctx2);
@@ -415,7 +418,8 @@ TEST_F(VendorOptsTest, vendorPersistentOptions) {
// Pass it to the server and get an advertise
AllocEngine::ClientContext6 ctx;
- bool drop = false;
+ bool drop = !srv_.earlyGHRLookup(sol, ctx);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx, drop);
ASSERT_FALSE(drop);
Pkt6Ptr adv = srv_.processSolicit(ctx);
@@ -451,6 +455,8 @@ TEST_F(VendorOptsTest, vendorPersistentOptions) {
// Need to process SOLICIT again after requesting new option.
AllocEngine::ClientContext6 ctx2;
+ drop = !srv_.earlyGHRLookup(sol, ctx2);
+ ASSERT_FALSE(drop);
srv_.initContext(sol, ctx2, drop);
ASSERT_FALSE(drop);
adv = srv_.processSolicit(ctx2);
diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc
index 687c0a5ad0..9fb6bf3ba6 100644
--- a/src/lib/dhcpsrv/alloc_engine.cc
+++ b/src/lib/dhcpsrv/alloc_engine.cc
@@ -456,10 +456,11 @@ namespace isc {
namespace dhcp {
AllocEngine::ClientContext6::ClientContext6()
- : query_(), fake_allocation_(false), subnet_(), host_subnet_(), duid_(),
- hwaddr_(), host_identifiers_(), hosts_(), fwd_dns_update_(false),
- rev_dns_update_(false), hostname_(), callout_handle_(), ias_(),
- ddns_params_() {
+ : query_(), fake_allocation_(false),
+ early_global_reservations_lookup_(false), subnet_(), host_subnet_(),
+ duid_(), hwaddr_(), host_identifiers_(), hosts_(),
+ fwd_dns_update_(false), rev_dns_update_(false), hostname_(),
+ callout_handle_(), ias_(), ddns_params_() {
}
AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet,
@@ -470,7 +471,8 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet,
const bool fake_allocation,
const Pkt6Ptr& query,
const CalloutHandlePtr& callout_handle)
- : query_(query), fake_allocation_(fake_allocation), subnet_(subnet),
+ : query_(query), fake_allocation_(fake_allocation),
+ early_global_reservations_lookup_(false), subnet_(subnet),
duid_(duid), hwaddr_(), host_identifiers_(), hosts_(),
fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), hostname_(hostname),
callout_handle_(callout_handle), allocated_resources_(), new_leases_(),
@@ -598,8 +600,6 @@ AllocEngine::ClientContext6::getDdnsParams() {
void
AllocEngine::findReservation(ClientContext6& ctx) {
- ctx.hosts_.clear();
-
// If there is no subnet, there is nothing to do.
if (!ctx.subnet_) {
return;
@@ -607,12 +607,15 @@ AllocEngine::findReservation(ClientContext6& ctx) {
auto subnet = ctx.subnet_;
- std::map<SubnetID, ConstHostPtr> host_map;
- SharedNetwork6Ptr network;
- subnet->getSharedNetwork(network);
+ // If already done just return.
+ if (ctx.early_global_reservations_lookup_ &&
+ !subnet->getReservationsInSubnet()) {
+ return;
+ }
// @todo: This code can be trivially optimized.
- if (subnet->getReservationsGlobal()) {
+ if (!ctx.early_global_reservations_lookup_ &&
+ subnet->getReservationsGlobal()) {
ConstHostPtr ghost = findGlobalReservation(ctx);
if (ghost) {
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;
@@ -624,6 +627,10 @@ AllocEngine::findReservation(ClientContext6& ctx) {
}
}
+ std::map<SubnetID, ConstHostPtr> host_map;
+ SharedNetwork6Ptr network;
+ subnet->getSharedNetwork(network);
+
// If the subnet belongs to a shared network it is usually going to be
// more efficient to make a query for all reservations for a particular
// client rather than a query for each subnet within this shared network.
@@ -3414,7 +3421,8 @@ namespace isc {
namespace dhcp {
AllocEngine::ClientContext4::ClientContext4()
- : subnet_(), clientid_(), hwaddr_(),
+ : early_global_reservations_lookup_(false),
+ subnet_(), clientid_(), hwaddr_(),
requested_address_(IOAddress::IPV4_ZERO_ADDRESS()),
fwd_dns_update_(false), rev_dns_update_(false),
hostname_(""), callout_handle_(), fake_allocation_(false),
@@ -3431,7 +3439,8 @@ AllocEngine::ClientContext4::ClientContext4(const Subnet4Ptr& subnet,
const bool rev_dns_update,
const std::string& hostname,
const bool fake_allocation)
- : subnet_(subnet), clientid_(clientid), hwaddr_(hwaddr),
+ : early_global_reservations_lookup_(false),
+ subnet_(subnet), clientid_(clientid), hwaddr_(hwaddr),
requested_address_(requested_addr),
fwd_dns_update_(fwd_dns_update), rev_dns_update_(rev_dns_update),
hostname_(hostname), callout_handle_(),
@@ -3533,8 +3542,6 @@ AllocEngine::allocateLease4(ClientContext4& ctx) {
void
AllocEngine::findReservation(ClientContext4& ctx) {
- ctx.hosts_.clear();
-
// If there is no subnet, there is nothing to do.
if (!ctx.subnet_) {
return;
@@ -3542,12 +3549,15 @@ AllocEngine::findReservation(ClientContext4& ctx) {
auto subnet = ctx.subnet_;
- std::map<SubnetID, ConstHostPtr> host_map;
- SharedNetwork4Ptr network;
- subnet->getSharedNetwork(network);
+ // If already done just return.
+ if (ctx.early_global_reservations_lookup_ &&
+ !subnet->getReservationsInSubnet()) {
+ return;
+ }
// @todo: This code can be trivially optimized.
- if (subnet->getReservationsGlobal()) {
+ if (!ctx.early_global_reservations_lookup_ &&
+ subnet->getReservationsGlobal()) {
ConstHostPtr ghost = findGlobalReservation(ctx);
if (ghost) {
ctx.hosts_[SUBNET_ID_GLOBAL] = ghost;
@@ -3559,6 +3569,10 @@ AllocEngine::findReservation(ClientContext4& ctx) {
}
}
+ std::map<SubnetID, ConstHostPtr> host_map;
+ SharedNetwork4Ptr network;
+ subnet->getSharedNetwork(network);
+
// If the subnet belongs to a shared network it is usually going to be
// more efficient to make a query for all reservations for a particular
// client rather than a query for each subnet within this shared network.
diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h
index 6d33e74967..ef22751a41 100644
--- a/src/lib/dhcpsrv/alloc_engine.h
+++ b/src/lib/dhcpsrv/alloc_engine.h
@@ -473,6 +473,11 @@ public:
/// update existing lease.
bool fake_allocation_;
+ /// @brief Indicates if early global reservation is looked for.
+ ///
+ /// This caches the early-global-reservations-lookup value.
+ bool early_global_reservations_lookup_;
+
/// @brief Subnet selected for the client by the server.
Subnet6Ptr subnet_;
@@ -1373,6 +1378,11 @@ public:
/// information to the allocation engine methods is that adding
/// new information doesn't modify the API of the allocation engine.
struct ClientContext4 : public boost::noncopyable {
+ /// @brief Indicates if early global reservation is looked for.
+ ///
+ /// This caches the early-global-reservations-lookup value.
+ bool early_global_reservations_lookup_;
+
/// @brief Subnet selected for the client by the server.
Subnet4Ptr subnet_;