]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3463] Add BindingVariableMgr::evaluateVariables
authorThomas Markwalder <tmark@isc.org>
Tue, 28 Jan 2025 20:52:54 +0000 (15:52 -0500)
committerThomas Markwalder <tmark@isc.org>
Tue, 18 Feb 2025 18:54:19 +0000 (18:54 +0000)
/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.

src/hooks/dhcp/lease_cmds/binding_variables.cc
src/hooks/dhcp/lease_cmds/binding_variables.h
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/lease.h

index d2d8b03d39df1eaec0eb06de2f4055efcd63e6ae..346831145f99b88dc4bdad52fd15606a2b1001bf 100644 (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
index ee37ecce145260f8066b63b3289f38144f706c5a..786743f4d14375b0c640eff9976d488013e85f45 100644 (file)
 #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.
     ///
index 36be5ee81c32a4ad9e2127b7971a8c458822bd3f..b783a2397eb0b9995a1cab85e732932043d536e4 100644 (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
index 4f2e764bb5b65e688f574a22f80e71928b2d05b5..dc3eb4f6b2dadc39e0b6e40dc3cf57f6f830751a 100644 (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();
index c9152d097e7b82551c2085625059773534c23281..9d5b25bbe0a1484664c4e3a4f7f541f97a0cd7a0 100644 (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.