From 06be19c83ef6ad8e8f4a3a06314c26e270f00cdd Mon Sep 17 00:00:00 2001 From: Francis Dupont Date: Sun, 6 Feb 2022 17:54:00 +0100 Subject: [#2249] Checkpoint: doc to finish --- doc/examples/kea4/all-keys.json | 3 +- doc/examples/kea6/all-keys.json | 3 +- src/bin/dhcp4/dhcp4_messages.cc | 2 + src/bin/dhcp4/dhcp4_messages.h | 1 + src/bin/dhcp4/dhcp4_messages.mes | 5 + src/bin/dhcp4/dhcp4_srv.cc | 179 +++++++++++++++----- src/bin/dhcp4/dhcp4_srv.h | 78 ++++++--- src/bin/dhcp4/tests/classify_unittest.cc | 136 ++++++++++++++- src/bin/dhcp4/tests/dhcp4_test_utils.cc | 7 +- src/bin/dhcp4/tests/dhcp4_test_utils.h | 25 ++- src/bin/dhcp4/tests/get_config_unittest.cc | 76 +++++++++ src/bin/dhcp6/dhcp6_messages.cc | 2 + src/bin/dhcp6/dhcp6_messages.h | 1 + src/bin/dhcp6/dhcp6_messages.mes | 5 + src/bin/dhcp6/dhcp6_srv.cc | 249 +++++++++++++++++++--------- src/bin/dhcp6/dhcp6_srv.h | 30 +++- src/bin/dhcp6/tests/classify_unittests.cc | 215 ++++++++++++++++++++++-- src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 72 +++++--- src/bin/dhcp6/tests/dhcp6_test_utils.h | 13 +- src/bin/dhcp6/tests/fqdn_unittest.cc | 7 +- src/bin/dhcp6/tests/get_config_unittest.cc | 64 +++++++ src/bin/dhcp6/tests/hooks_unittest.cc | 14 +- src/bin/dhcp6/tests/vendor_opts_unittest.cc | 12 +- src/lib/dhcpsrv/alloc_engine.cc | 52 +++--- src/lib/dhcpsrv/alloc_engine.h | 10 ++ 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& vec = context_->clientid_->getDuid(); + if (context->clientid_) { + const std::vector& 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(vec.begin() + 5, - vec.end())); + context->addHostIdentifier(id_type, + std::vector(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& vec = context_->clientid_->getDuid(); + if (context->clientid_) { + const std::vector& 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 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; } @@ -492,6 +488,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_) { @@ -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(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 @@ -358,18 +358,147 @@ Dhcpv6Srv::testUnicast(const Pkt6Ptr& pkt) const { return (true); } +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 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(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 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(); } @@ -3803,6 +3875,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) { 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 addr = + boost::dynamic_pointer_cast(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(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 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 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 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 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_; -- cgit v1.2.3