diff --git a/src/hooks/dhcp/lease_cmds/binding_variables.cc b/src/hooks/dhcp/lease_cmds/binding_variables.cc index d2d8b03d39..346831145f 100644 --- a/src/hooks/dhcp/lease_cmds/binding_variables.cc +++ b/src/hooks/dhcp/lease_cmds/binding_variables.cc @@ -221,5 +221,29 @@ BindingVariableMgr::configure(data::ConstElementPtr config) { } } +bool +BindingVariableMgr::evaluateVariables(PktPtr query, PktPtr response, LeasePtr lease) { + if (!cache_->size()) { + return(false); + } + + auto const variables = cache_->getAll(); + ElementPtr values = Element::createMap(); + for (auto const& variable : *variables) { + try { + auto value = evaluateString(*(variable->getExpression()), + (variable->getSource() == BindingVariable::QUERY ? + *query : *response)); + if (!value.empty()) { + values->set(variable->getName(), Element::create(value)); + } + } catch (const std::exception& ex) { + isc_throw(Unexpected, "expression blew up: " << ex.what()); + } + } + + return (lease->updateUserContextISC("binding-variables", values)); +} + } // end of namespace lease_cmds } // end of namespace isc diff --git a/src/hooks/dhcp/lease_cmds/binding_variables.h b/src/hooks/dhcp/lease_cmds/binding_variables.h index ee37ecce14..786743f4d1 100644 --- a/src/hooks/dhcp/lease_cmds/binding_variables.h +++ b/src/hooks/dhcp/lease_cmds/binding_variables.h @@ -11,9 +11,10 @@ #include #include #include +#include +#include #include #include -#include #include #include @@ -286,8 +287,19 @@ public: /// @throw DhcpConfigError if the configuration is invalid. void configure(data::ConstElementPtr config); - /// @todo - place holder - // bool evaluateVariables(LeasePtr lease, PktPtr query, PktPtr response); + /// @brief Evaluates the binding variables for a given lease and packet pair. + /// + /// @param query Client packet which produced the lease. Variables whose source + /// is "query" will be evaluated against this packet. + /// @param response Server response conveying the lease. Variables whose source + /// is "response" will be evaluated against this packet. + /// @param lease Lease whose use-context will be updated with the evaluation + /// results. If the results of the evaluation are idnentical the the lease's + /// exising binding-variables value, the lease is not altered. This allows + /// a subsequent lease store update to only occur when needed. + /// @return True if the lease's user-context was udpated, false otherwise. + bool evaluateVariables(dhcp::PktPtr query, dhcp::PktPtr response, + dhcp::LeasePtr lease); /// @brief Fetches the current variables cache. /// diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 36be5ee81c..b783a2397e 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -5029,36 +5029,8 @@ AllocEngine::updateLease4ExtendedInfo(const Lease4Ptr& lease, } } - // Get a mutable copy of the lease's current user context. - ConstElementPtr user_context = lease->getContext(); - ElementPtr mutable_user_context; - if (user_context && (user_context->getType() == Element::map)) { - mutable_user_context = copy(user_context, 0); - } else { - mutable_user_context = Element::createMap(); - } - - // Get a mutable copy of the ISC entry. - ConstElementPtr isc = mutable_user_context->get("ISC"); - ElementPtr mutable_isc; - if (isc && (isc->getType() == Element::map)) { - mutable_isc = copy(isc, 0); - } else { - mutable_isc = Element::createMap(); - } - - // Add/replace the extended info entry. - ConstElementPtr old_extended_info = mutable_isc->get("relay-agent-info"); - if (!old_extended_info || (*old_extended_info != *extended_info)) { - changed = true; - mutable_isc->set("relay-agent-info", extended_info); - mutable_user_context->set("ISC", mutable_isc); - } - - // Update the lease's user_context. - lease->setContext(mutable_user_context); - - return (changed); + // Return true if the extended-info on the lease changed. + return (lease->updateUserContextISC("relay-agent-info", extended_info)); } void @@ -5139,34 +5111,10 @@ AllocEngine::updateLease6ExtendedInfo(const Lease6Ptr& lease, extended_info->add(relay_elem); } - // Get a mutable copy of the lease's current user context. - ConstElementPtr user_context = lease->getContext(); - ElementPtr mutable_user_context; - if (user_context && (user_context->getType() == Element::map)) { - mutable_user_context = copy(user_context, 0); - } else { - mutable_user_context = Element::createMap(); - } - - // Get a mutable copy of the ISC entry. - ConstElementPtr isc = mutable_user_context->get("ISC"); - ElementPtr mutable_isc; - if (isc && (isc->getType() == Element::map)) { - mutable_isc = copy(isc, 0); - } else { - mutable_isc = Element::createMap(); - } - - // Add/replace the extended info entry. - ConstElementPtr old_extended_info = mutable_isc->get("relay-info"); - if (!old_extended_info || (*old_extended_info != *extended_info)) { + // If extended info changed set the action to UPDATE. + if (lease->updateUserContextISC("relay-info", extended_info)) { lease->extended_info_action_ = Lease6::ACTION_UPDATE; - mutable_isc->set("relay-info", extended_info); - mutable_user_context->set("ISC", mutable_isc); } - - // Update the lease's user context. - lease->setContext(mutable_user_context); } void diff --git a/src/lib/dhcpsrv/lease.cc b/src/lib/dhcpsrv/lease.cc index 4f2e764bb5..dc3eb4f6b2 100644 --- a/src/lib/dhcpsrv/lease.cc +++ b/src/lib/dhcpsrv/lease.cc @@ -743,6 +743,40 @@ Lease6::fromElement(const data::ConstElementPtr& element) { return (lease); } +bool +Lease::updateUserContextISC(const std::string elem_name, + ConstElementPtr new_values) { + // Get a mutable copy of the lease's current user context. + ConstElementPtr user_context = getContext(); + ElementPtr mutable_user_context; + if (user_context && (user_context->getType() == Element::map)) { + mutable_user_context = copy(user_context, 0); + } else { + mutable_user_context = Element::createMap(); + } + + // Get a mutable copy of the ISC entry. + ConstElementPtr isc = mutable_user_context->get("ISC"); + ElementPtr mutable_isc; + if (isc && (isc->getType() == Element::map)) { + mutable_isc = copy(isc, 0); + } else { + mutable_isc = Element::createMap(); + } + + // Add/replace the new_values entry + bool changed = false; + ConstElementPtr old_values = mutable_isc->get(elem_name); + if (!old_values || (*old_values != *new_values)) { + changed = true; + mutable_isc->set(elem_name, new_values); + mutable_user_context->set("ISC", mutable_isc); + setContext(mutable_user_context); + } + + return(changed); +} + std::ostream& operator<<(std::ostream& os, const Lease& lease) { os << lease.toText(); diff --git a/src/lib/dhcpsrv/lease.h b/src/lib/dhcpsrv/lease.h index c9152d097e..9d5b25bbe0 100644 --- a/src/lib/dhcpsrv/lease.h +++ b/src/lib/dhcpsrv/lease.h @@ -274,6 +274,18 @@ struct Lease : public isc::data::UserContext, public isc::data::CfgToElement { /// @ref cltt_ and @ref valid_lft_ void updateCurrentExpirationTime(); + /// Update the ISC entry in the lease's user-context + /// + /// Adds or updates the named element within the "ISC" map + /// with the lease's "user-context". The update occurs only if + /// the new value(s) are different than the existing values for the + /// element. + /// + /// @param elem_name ISC element name to add/update. + /// @param new_values The new element values of the element. + /// @return True the user-context was modified. + bool updateUserContextISC(const std::string elem_name, + data::ConstElementPtr new_values); protected: /// @brief Sets common (for v4 and v6) properties of the lease object.