]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
move variables to unlang_group_t
authorAlan T. DeKok <aland@freeradius.org>
Fri, 9 Dec 2022 19:30:44 +0000 (14:30 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 23 Sep 2023 11:57:13 +0000 (07:57 -0400)
so that they can all be defined when the group is entered, and
cleaned up when the group leaves.

This also allows the variables to be used in statements such as
"switch" or "load-balance"

src/lib/unlang/all.mk
src/lib/unlang/base.c
src/lib/unlang/compile.c
src/lib/unlang/unlang_priv.h
src/lib/unlang/variable.c [deleted file]
src/lib/unlang/variable_priv.h [deleted file]

index 821a6023c0a29312b953bbc6b470d68b59068404..3ae74b7faba5d628347b4c0c024553f22dee5be3 100644 (file)
@@ -25,7 +25,6 @@ SOURCES       :=      base.c \
                switch.c \
                timeout.c \
                tmpl.c \
-               variable.c \
                xlat.c \
                xlat_alloc.c \
                xlat_builtin.c \
index 04d6e661abf0773164af0097ef9dc5ae6ad2f078..b03d50a835212e64bdc27ad568e0bc4e6322ab02 100644 (file)
@@ -122,7 +122,6 @@ int unlang_init_global(void)
        unlang_edit_init();
        unlang_timeout_init();
        unlang_limit_init();
-       unlang_variable_init();
 
        instance_count++;
 
index 38796852b99b8a1c9211942eeac80c2d7d02e44e..b90dccd3c9a498b217ea544cc0b28ebffcac92e5 100644 (file)
@@ -43,7 +43,6 @@ RCSID("$Id$")
 #include "edit_priv.h"
 #include "timeout_priv.h"
 #include "limit_priv.h"
-#include "variable_priv.h"
 
 #define UNLANG_IGNORE ((unlang_t *) -1)
 
@@ -466,7 +465,6 @@ static void unlang_dump(unlang_t *instruction, int depth)
                case UNLANG_TYPE_RETURN:
                case UNLANG_TYPE_TMPL:
                case UNLANG_TYPE_XLAT:
-               case UNLANG_TYPE_VARIABLE:
                        DEBUG("%.*s%s", depth, unlang_spaces, c->debug_name);
                        break;
                }
@@ -1702,39 +1700,30 @@ static unlang_t *compile_edit_pair(unlang_t *parent, unlang_compile_t *unlang_ct
  *  Definitions which are adjacent to one another are automatically merged
  *  into one larger variable definition.
  */
-static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx, unlang_t **prev, CONF_PAIR *cp, tmpl_rules_t *t_rules)
+static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx, CONF_PAIR *cp, tmpl_rules_t *t_rules)
 {
-       unlang_variable_t *var, *var_free;
-       unlang_t        *c = NULL, *out = UNLANG_IGNORE;
+       unlang_variable_t *var;
        fr_type_t       type;
        char const      *attr, *value;
        fr_dict_attr_t const *da;
+       unlang_group_t  *group;
 
        fr_dict_attr_flags_t flags = {
                .internal = true,
                .local = true,
        };
 
-       c = *prev;
-       var = var_free = NULL;
-
-       if (c && (c->type == UNLANG_TYPE_VARIABLE)) {
-               var = unlang_generic_to_variable(c);
+       /*
+        *      The variables exist in the parent block.
+        */
+       group = unlang_generic_to_group(parent);
+       if (group->variables) {
+               var = group->variables;
 
        } else {
-               var = talloc_zero(parent, unlang_variable_t);
+               group->variables = var = talloc_zero(parent, unlang_variable_t);
                if (!var) return NULL;
 
-               c = out = unlang_variable_to_generic(var);
-               c->parent = parent;
-               c->next = NULL;
-               c->name = cf_pair_value(cp);
-               c->debug_name = c->name;
-               c->type = UNLANG_TYPE_VARIABLE;
-               c->ci = CF_TO_ITEM(cp);
-
-               var_free = var;
-
                var->dict = fr_dict_protocol_alloc(unlang_ctx->rules->attr.dict_def);
                if (!var->dict) {
                        talloc_free(var);
@@ -1764,7 +1753,6 @@ static unlang_t *compile_variable(unlang_t *parent, unlang_compile_t *unlang_ctx
        type = fr_table_value_by_str(fr_type_table, attr, FR_TYPE_NULL);
        if (type == FR_TYPE_NULL) {
 invalid_type:
-               talloc_free(var_free);
                cf_log_err(cp, "Invalid data type '%s'", attr);
                return NULL;
        }
@@ -1781,7 +1769,6 @@ invalid_type:
         */
        da = fr_dict_attr_by_name(NULL, fr_dict_root(t_rules->parent->attr.dict_def), value);
        if (da) {
-               talloc_free(var_free);
                cf_log_err(cp, "Local variable '%s' duplicates a dictionary attribute.", value);
                return NULL;
        }
@@ -1791,22 +1778,18 @@ invalid_type:
         */
        da = fr_dict_attr_by_name(NULL, var->root, value);
        if (da) {
-               talloc_free(var_free);
                cf_log_err(cp, "Duplicate variable name '%s'.", value);
                return NULL;
        }
 
        if (fr_dict_attr_add(var->dict, var->root, value, var->max_attr, type, &flags) < 0) {
-               talloc_free(var_free);
                cf_log_err(cp, "Failed adding variable '%s'", value);
                return NULL;
        }
 
        var->max_attr++;
 
-       *prev = c;
-
-       return out;
+       return UNLANG_IGNORE;
 }
 
 /*
@@ -2151,7 +2134,6 @@ static unlang_t *compile_children(unlang_group_t *g, unlang_compile_t *unlang_ct
        bool            was_if = false;
        char const      *skip_else = NULL;
        unlang_t        *edit = NULL;
-       unlang_t        *var = NULL;
        unlang_compile_t *unlang_ctx;
        unlang_compile_t unlang_ctx2;
        tmpl_rules_t    t_rules;
@@ -2292,7 +2274,7 @@ static unlang_t *compile_children(unlang_group_t *g, unlang_compile_t *unlang_ct
                         *      Variable definition.
                         */
                        if (cf_pair_operator(cp) == T_OP_CMP_TRUE) {
-                               single = compile_variable(c, unlang_ctx, &var, cp, &t_rules);
+                               single = compile_variable(c, unlang_ctx, cp, &t_rules);
                                if (!single) {
                                        talloc_free(c);
                                        return NULL;
@@ -2300,8 +2282,6 @@ static unlang_t *compile_children(unlang_group_t *g, unlang_compile_t *unlang_ct
                                goto add_child;
                        }
 
-                       var = NULL;
-
                        /*
                         *      Bare "foo = bar" is disallowed.
                         */
index ddb34fd2a77ceb7be5806570735b649dba8831e5..dfb1ab1f8dd91ac1487c63a3d816cfa18854ee89 100644 (file)
@@ -81,7 +81,6 @@ typedef enum {
        UNLANG_TYPE_XLAT,                       //!< Represents one level of an xlat expansion.
        UNLANG_TYPE_TMPL,                       //!< asynchronously expand a tmpl_t
        UNLANG_TYPE_EDIT,                       //!< edit VPs in place.  After 20 years!
-       UNLANG_TYPE_VARIABLE,                   //!< local variables
        UNLANG_TYPE_MAX
 } unlang_type_t;
 
@@ -140,6 +139,12 @@ typedef struct {
        char const              *type_name;     //!< Talloc type name.
 } unlang_ext_t;
 
+typedef struct {
+       fr_dict_t               *dict;          //!< our dictionary
+       fr_dict_attr_t const    *root;          //!< the root of our dictionary
+       int                     max_attr;       //!< 1..N local attributes have been defined
+} unlang_variable_t;
+
 /** Generic representation of a grouping
  *
  * Can represent IF statements, maps, update sections etc...
@@ -151,6 +156,8 @@ typedef struct {
        unlang_t                **tail;         //!< pointer to the tail which gets updated
        CONF_SECTION            *cs;
        int                     num_children;
+
+       unlang_variable_t       *variables;     //!< rarely used, so we don't usually need it
 } unlang_group_t;
 
 /** A naked xlat
@@ -621,7 +628,6 @@ void                unlang_timeout_init(void);
 
 void           unlang_limit_init(void);
 
-void           unlang_variable_init(void);
  /** @} */
 
 #ifdef __cplusplus
diff --git a/src/lib/unlang/variable.c b/src/lib/unlang/variable.c
deleted file mode 100644 (file)
index 6090222..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or
- *   (at your option) any later version.
- *
- *   This program is distributed in the hope that it will be useful,
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *   GNU General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-/**
- * $Id$
- *
- * @file unlang/variable.c
- * @brief Unlang local "variable"s
- *
- * @copyright 2022 Network RADIUS SAS (legal@networkradius.com)
- */
-RCSID("$Id$")
-
-#include "group_priv.h"
-#include "variable_priv.h"
-
-static unlang_action_t unlang_variable(UNUSED rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame)
-{
-       unlang_variable_t               *var;
-
-       var = unlang_generic_to_variable(frame->instruction);
-
-       RDEBUG3("Creating varible max %d", var->max_attr);
-
-       return UNLANG_ACTION_CALCULATE_RESULT;
-}
-
-
-void unlang_variable_init(void)
-{
-       unlang_register(UNLANG_TYPE_VARIABLE,
-                          &(unlang_op_t){
-                               .name = "variable",
-                               .interpret = unlang_variable,
-                          });
-}
diff --git a/src/lib/unlang/variable_priv.h b/src/lib/unlang/variable_priv.h
deleted file mode 100644 (file)
index 5de4aa8..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-#pragma once
-/*
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software Foundation,
- *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-/**
- * $Id$
- *
- * @file unlang/variable_priv.h
- *
- * @copyright 2022 Network RADIUS SAS (legal@networkradius.com)
- */
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "unlang_priv.h"
-
-typedef struct {
-       unlang_t                self;
-       fr_dict_t               *dict;
-       fr_dict_attr_t const    *root;
-       int                     max_attr;
-} unlang_variable_t;
-
-/** Cast a generic structure to the edit extension
- *
- */
-static inline unlang_variable_t *unlang_generic_to_variable(unlang_t const *p)
-{
-       fr_assert(p->type == UNLANG_TYPE_VARIABLE);
-       return UNCONST(unlang_variable_t *, talloc_get_type_abort_const(p, unlang_variable_t));
-}
-
-static inline unlang_t *unlang_variable_to_generic(unlang_variable_t const *p)
-{
-       return UNCONST(unlang_t *, p);
-}
-
-#ifdef __cplusplus
-}
-#endif