2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-29 13:07:50 +00:00

[#3463] Add BindingVariableMgr::evaluateVariables

/src/hooks/dhcp/lease_cmds/binding_variables.*
    BindingVariableMgr::evaluateVariables() - initial implementation

/src/lib/dhcpsrv/alloc_engine.cc
    AllocEngine::updateLease4ExtendedInfo()
    AllocEngine::updateLease6ExtendedInfo()
    - use Lease::updateUserContextISC()

/src/lib/dhcpsrv/lease.*
    bool Lease::updateUserContextISC() - new function that
    adds/updates an element in the "ISC" map in the lease's
    user-context.
This commit is contained in:
Thomas Markwalder 2025-01-28 15:52:54 -05:00
parent 6a577ee173
commit 89f08dd667
5 changed files with 89 additions and 59 deletions

View File

@ -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

View File

@ -11,9 +11,10 @@
#include <cc/cfg_to_element.h>
#include <cc/data.h>
#include <cc/simple_parser.h>
#include <dhcp/pkt.h>
#include <dhcpsrv/lease.h>
#include <eval/evaluate.h>
#include <eval/token.h>
#include <dhcp/pkt.h>
#include <boost/scoped_ptr.hpp>
#include <boost/multi_index_container.hpp>
@ -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.
///

View File

@ -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

View File

@ -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();

View File

@ -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.