]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Make tmpl_attr and tmpl_request lists type safe
authorArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 6 Jan 2022 14:33:01 +0000 (08:33 -0600)
committerArran Cudbard-Bell <a.cudbardb@freeradius.org>
Thu, 6 Jan 2022 15:24:38 +0000 (09:24 -0600)
src/lib/server/tmpl.h
src/lib/server/tmpl_tokenize.c
src/lib/util/dlist.h

index 4bef868b05ac105d43c4d63d41b711c7afafd6d7..39177a200fe0c41ed1b536f86c2fcf8210c691e6 100644 (file)
@@ -74,6 +74,7 @@ extern "C" {
 #endif
 
 #include <freeradius-devel/util/table.h>
+#include <freeradius-devel/util/dlist.h>
 
 /** The maximum number of request references allowed
  *
@@ -361,16 +362,26 @@ typedef enum {
                                                        ///< may be resolved later.
 } tmpl_attr_type_t;
 
+#define tmpl_attr_is_normal(_ar)       (_ar->ar_type == TMPL_ATTR_TYPE_NORMAL)
+#define tmpl_attr_is_unknown(_ar)      (_ar->ar_type == TMPL_ATTR_TYPE_UNKNOWN)
+#define tmpl_attr_is_unresolved(_ar)   (_ar->ar_type == TMPL_ATTR_TYPE_UNRESOLVED)
+
+
 #define NUM_ANY                        INT16_MIN
 #define NUM_ALL                        (INT16_MIN + 1)
 #define NUM_COUNT              (INT16_MIN + 2)
 #define NUM_LAST               (INT16_MIN + 3)
 
+/** Define entry and head types for attribute reference lists
+ *
+ */
+FR_DLIST_TYPES(tmpl_attr)
+
 /** An element in a list of nested attribute references
  *
  */
 typedef struct {
-       fr_dlist_t              _CONST entry;           //!< Entry in the doubly linked list
+       FR_DLIST_ENTRY_TYPE(tmpl_attr)  _CONST entry;           //!< Entry in the doubly linked list
                                                        ///< of attribute references.
 
        fr_dict_attr_t const    * _CONST da;            //!< Resolved dictionary attribute.
@@ -400,16 +411,31 @@ typedef struct {
        tmpl_attr_type_t        _CONST type;            //!< Type of attribute reference.
 } tmpl_attr_t;
 
+
+/** Define manipulation functions for the attribute reference list
+ *
+ */
+FR_DLIST_FUNCS(tmpl_attr, tmpl_attr_t, entry)
+
+/** Define entry and head types for tmpl request references
+ *
+ */
+FR_DLIST_TYPES(tmpl_request)
+
 /** An element in a list of request references
  *
  */
 typedef struct {
-       fr_dlist_t              _CONST entry;           //!< Entry in the doubly linked list
-                                                       ///< of request references.
+       FR_DLIST_ENTRY_TYPE(tmpl_request)       _CONST entry;   //!< Entry in the doubly linked list
+                                                               ///< of request references.
 
-       tmpl_request_ref_t      _CONST request;
+       tmpl_request_ref_t                      _CONST request;
 } tmpl_request_t;
 
+/** Define manipulation functions for the attribute reference list
+ *
+ */
+FR_DLIST_FUNCS(tmpl_request, tmpl_request_t, entry)
 
 /** How many additional headers to allocate in a pool for a tmpl_t
  *
@@ -477,12 +503,11 @@ struct tmpl_s {
                        bool                    ref_prefix;     //!< true if the reference was prefixed
                                                                ///< with a '&'.
 
-                       fr_dlist_head_t         rr;             //!< Request to search or insert in.
-
                        tmpl_pair_list_t        list;           //!< List to search or insert in.
                                                                ///< deprecated.
 
-                       fr_dlist_head_t         ar;             //!< Head of the attribute reference list.
+                       FR_DLIST_HEAD_TYPE(tmpl_request)        rr;     //!< Request to search or insert in.
+                       FR_DLIST_HEAD_TYPE(tmpl_attr)           ar;     //!< Head of the attribute reference list.
 
                        bool                    was_oid;        //!< Was originally a numeric OID.
                } attribute;
@@ -562,7 +587,7 @@ static inline tmpl_request_ref_t tmpl_request(tmpl_t const *vpt)
                         tmpl_is_attr_unresolved(vpt) ||
                         tmpl_is_list(vpt));
 
-       return ((tmpl_request_t *)fr_dlist_tail(&vpt->data.attribute.rr))->request;
+       return ((tmpl_request_t *)fr_dlist_tmpl_request_tail(&vpt->data.attribute.rr))->request;
 }
 
 /** The number of request references contained within a tmpl
@@ -574,7 +599,7 @@ static inline size_t tmpl_request_ref_count(tmpl_t const *vpt)
                         tmpl_is_attr_unresolved(vpt) ||
                         tmpl_is_list(vpt));
 
-       return fr_dlist_num_elements(&vpt->data.attribute.rr);
+       return fr_dlist_tmpl_request_num_elements(&vpt->data.attribute.rr);
 }
 
 /**
@@ -585,21 +610,21 @@ static inline fr_dict_attr_t const *tmpl_da(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt));
 
-       return ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->ar_da;
+       return ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->ar_da;
 }
 
 static inline fr_dict_attr_t const *tmpl_unknown(tmpl_t const *vpt)
 {
        tmpl_assert_type(tmpl_is_attr(vpt));
 
-       return ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->ar_unknown;
+       return ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->ar_unknown;
 }
 
 static inline char const *tmpl_attr_unresolved(tmpl_t const *vpt)
 {
        tmpl_assert_type(vpt->type == TMPL_TYPE_ATTR_UNRESOLVED);
 
-       return ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->ar_unresolved;
+       return ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->ar_unresolved;
 }
 
 /** The number of attribute references contained within a tmpl
@@ -610,7 +635,7 @@ static inline size_t tmpl_attr_count(tmpl_t const *vpt)
        tmpl_assert_type(tmpl_is_attr(vpt) ||
                         tmpl_is_attr_unresolved(vpt));
 
-       return fr_dlist_num_elements(&vpt->data.attribute.ar);
+       return fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar);
 }
 
 static inline int16_t tmpl_num(tmpl_t const *vpt)
@@ -619,9 +644,9 @@ static inline int16_t tmpl_num(tmpl_t const *vpt)
                         tmpl_is_attr_unresolved(vpt) ||
                         tmpl_is_list(vpt));
 
-       if (tmpl_is_list(vpt) && (fr_dlist_num_elements(&vpt->data.attribute.ar) == 0)) return NUM_ALL;
+       if (tmpl_is_list(vpt) && (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) == 0)) return NUM_ALL;
 
-       return ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->ar_num;
+       return ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->ar_num;
 }
 
 static inline tmpl_pair_list_t tmpl_list(tmpl_t const *vpt)
@@ -852,7 +877,7 @@ int                 tmpl_afrom_value_box(TALLOC_CTX *ctx, tmpl_t **out, fr_value_box_t *data,
 
 void                   tmpl_attr_ref_debug(const tmpl_attr_t *ar, int idx);
 
-void                   tmpl_attr_ref_list_debug(fr_dlist_head_t const *ar_head) CC_HINT(nonnull);
+void                   tmpl_attr_ref_list_debug(FR_DLIST_HEAD_TYPE(tmpl_attr) const *ar_head) CC_HINT(nonnull);
 
 void                   tmpl_attr_debug(tmpl_t const *vpt) CC_HINT(nonnull);
 
index 59396ffa8c4daf69f2ed9ba4d45b4267f0357786..933d777a9938fcc06f72398e0f098136729bcf42 100644 (file)
@@ -187,7 +187,7 @@ void tmpl_attr_ref_debug(const tmpl_attr_t *ar, int i)
        }
 }
 
-void tmpl_attr_ref_list_debug(fr_dlist_head_t const *ar_head)
+void tmpl_attr_ref_list_debug(FR_DLIST_HEAD_TYPE(tmpl_attr) const *ar_head)
 {
        tmpl_attr_t             *ar = NULL;
        unsigned int            i = 0;
@@ -196,7 +196,7 @@ void tmpl_attr_ref_list_debug(fr_dlist_head_t const *ar_head)
        /*
         *      Print all the attribute references
         */
-       while ((ar = fr_dlist_next(ar_head, ar))) {
+       while ((ar = fr_dlist_tmpl_attr_next(ar_head, ar))) {
                tmpl_attr_ref_debug(ar, i);
                i++;
        }
@@ -231,7 +231,7 @@ void tmpl_attr_debug(tmpl_t const *vpt)
        /*
         *      Print all the request references
         */
-       while ((rr = fr_dlist_next(&vpt->data.attribute.rr, rr))) {
+       while ((rr = fr_dlist_tmpl_request_next(&vpt->data.attribute.rr, rr))) {
                FR_FAULT_LOG("\t[%u] %s (%u)", i,
                             fr_table_str_by_value(tmpl_request_ref_table, rr->request, "<INVALID>"), rr->request);
                i++;
@@ -479,8 +479,8 @@ static inline CC_HINT(always_inline) void tmpl_type_init(tmpl_t *vpt, tmpl_type_
        case TMPL_TYPE_ATTR:
        case TMPL_TYPE_ATTR_UNRESOLVED:
        case TMPL_TYPE_LIST:
-               fr_dlist_talloc_init(&vpt->data.attribute.ar, tmpl_attr_t, entry);
-               fr_dlist_talloc_init(&vpt->data.attribute.rr, tmpl_request_t, entry);
+               fr_dlist_tmpl_attr_talloc_init(&vpt->data.attribute.ar);
+               fr_dlist_tmpl_request_talloc_init(&vpt->data.attribute.rr);
                break;
 
        default:
@@ -684,17 +684,17 @@ static tmpl_request_t *tmpl_req_ref_add(tmpl_t *vpt, tmpl_request_ref_t request)
        tmpl_request_t  *rr;
        TALLOC_CTX      *ctx;
 
-       if (fr_dlist_num_elements(&vpt->data.attribute.rr) == 0) {
+       if (fr_dlist_tmpl_request_num_elements(&vpt->data.attribute.rr) == 0) {
                ctx = vpt;
        } else {
-               ctx = fr_dlist_tail(&vpt->data.attribute.rr);
+               ctx = fr_dlist_tmpl_request_tail(&vpt->data.attribute.rr);
        }
 
        MEM(rr = talloc(ctx, tmpl_request_t));
        *rr = (tmpl_request_t){
                .request = request
        };
-       fr_dlist_insert_tail(&vpt->data.attribute.rr, rr);
+       fr_dlist_tmpl_request_insert_tail(&vpt->data.attribute.rr, rr);
 
        return rr;
 }
@@ -707,10 +707,10 @@ static tmpl_attr_t *tmpl_attr_add(tmpl_t *vpt, tmpl_attr_type_t type)
        tmpl_attr_t     *ar;
        TALLOC_CTX      *ctx;
 
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) == 0) {
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) == 0) {
                ctx = vpt;
        } else {
-               ctx = fr_dlist_tail(&vpt->data.attribute.ar);
+               ctx = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar);
        }
 
        MEM(ar = talloc(ctx, tmpl_attr_t));
@@ -718,7 +718,7 @@ static tmpl_attr_t *tmpl_attr_add(tmpl_t *vpt, tmpl_attr_type_t type)
                .type = type,
                .num = NUM_ANY
        };
-       fr_dlist_insert_tail(&vpt->data.attribute.ar, ar);
+       fr_dlist_tmpl_attr_insert_tail(&vpt->data.attribute.ar, ar);
 
        return ar;
 }
@@ -772,9 +772,9 @@ int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src)
        /*
         *      Clear any existing attribute references
         */
-       if (fr_dlist_num_elements(&dst->data.attribute.ar) > 0) fr_dlist_talloc_reverse_free(&dst->data.attribute.ar);
+       if (fr_dlist_tmpl_attr_num_elements(&dst->data.attribute.ar) > 0) fr_dlist_tmpl_attr_talloc_reverse_free(&dst->data.attribute.ar);
 
-       while ((src_ar = fr_dlist_next(&src->data.attribute.ar, src_ar))) {
+       while ((src_ar = fr_dlist_tmpl_attr_next(&src->data.attribute.ar, src_ar))) {
                dst_ar = tmpl_attr_add(dst, src_ar->type);
 
                switch (src_ar->type) {
@@ -799,9 +799,11 @@ int tmpl_attr_copy(tmpl_t *dst, tmpl_t const *src)
        /*
         *      Clear any existing request references
         */
-       if (fr_dlist_num_elements(&dst->data.attribute.rr) > 0) fr_dlist_talloc_reverse_free(&dst->data.attribute.rr);
+       if (fr_dlist_tmpl_request_num_elements(&dst->data.attribute.rr) > 0) {
+               fr_dlist_tmpl_request_talloc_reverse_free(&dst->data.attribute.rr);
+       }
 
-       while ((src_rr = fr_dlist_next(&src->data.attribute.rr, src_rr))) {
+       while ((src_rr = fr_dlist_tmpl_request_next(&src->data.attribute.rr, src_rr))) {
                MEM(dst_rr = tmpl_req_ref_add(dst, src_rr->request));
        }
 
@@ -827,8 +829,8 @@ int tmpl_attr_set_da(tmpl_t *vpt, fr_dict_attr_t const *da)
        /*
         *      Clear any existing references
         */
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) > 0) {
-               fr_dlist_talloc_reverse_free(&vpt->data.attribute.ar);
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) > 0) {
+               fr_dlist_tmpl_attr_talloc_reverse_free(&vpt->data.attribute.ar);
        }
 
        /*
@@ -861,17 +863,17 @@ int tmpl_attr_set_leaf_da(tmpl_t *vpt, fr_dict_attr_t const *da)
        /*
         *      Clear any existing references
         */
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) > 0) {
-               if (fr_dlist_num_elements(&vpt->data.attribute.ar) > 1) {
-                       ref = fr_dlist_tail(&vpt->data.attribute.ar);
-                       parent = fr_dlist_prev(&vpt->data.attribute.ar, ref);
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) > 0) {
+               if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) > 1) {
+                       ref = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar);
+                       parent = fr_dlist_tmpl_attr_prev(&vpt->data.attribute.ar, ref);
 
                        if (!fr_dict_attr_common_parent(parent->ar_da, da, true)) {
                                fr_strerror_const("New leaf da and old leaf da do not share the same ancestor");
                                return -1;
                        }
                } else {
-                       ref = fr_dlist_tail(&vpt->data.attribute.ar);
+                       ref = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar);
                }
 
                /*
@@ -909,10 +911,10 @@ void tmpl_attr_set_leaf_num(tmpl_t *vpt, int16_t num)
 
        tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
 
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) == 0) {
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) == 0) {
                ref = tmpl_attr_add(vpt, TMPL_ATTR_TYPE_UNKNOWN);
        } else {
-               ref = fr_dlist_tail(&vpt->data.attribute.ar);
+               ref = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar);
        }
 
        ref->num = num;
@@ -929,9 +931,9 @@ void tmpl_attr_rewrite_leaf_num(tmpl_t *vpt, int16_t from, int16_t to)
 
        tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
 
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) == 0) return;
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) == 0) return;
 
-       ref = fr_dlist_tail(&vpt->data.attribute.ar);
+       ref = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar);
        if (ref->ar_num == from) ref->ar_num = to;
 
        TMPL_ATTR_VERIFY(vpt);
@@ -946,7 +948,7 @@ void tmpl_attr_rewrite_num(tmpl_t *vpt, int16_t from, int16_t to)
 
        tmpl_assert_type(tmpl_is_attr(vpt) || tmpl_is_list(vpt) || tmpl_is_attr_unresolved(vpt));
 
-       while ((ref = fr_dlist_next(&vpt->data.attribute.ar, ref))) if (ref->ar_num == from) ref->ar_num = to;
+       while ((ref = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ref))) if (ref->ar_num == from) ref->ar_num = to;
 
        TMPL_ATTR_VERIFY(vpt);
 }
@@ -959,7 +961,7 @@ void tmpl_attr_set_request(tmpl_t *vpt, tmpl_request_ref_t request)
        fr_assert_msg(tmpl_is_attr(vpt), "Expected tmpl type 'attr', got '%s'",
                      fr_table_str_by_value(tmpl_type_table, vpt->type, "<INVALID>"));
 
-       if (fr_dlist_num_elements(&vpt->data.attribute.rr) > 0) fr_dlist_talloc_reverse_free(&vpt->data.attribute.rr);
+       if (fr_dlist_tmpl_request_num_elements(&vpt->data.attribute.rr) > 0) fr_dlist_tmpl_request_talloc_reverse_free(&vpt->data.attribute.rr);
 
        tmpl_req_ref_add(vpt, request);
 
@@ -1069,7 +1071,7 @@ static inline CC_HINT(always_inline) void tmpl_attr_insert(tmpl_t *vpt, tmpl_att
        /*
         *      Insert the reference into the list.
         */
-       fr_dlist_insert_tail(&vpt->data.attribute.ar, ar);
+       fr_dlist_tmpl_attr_insert_tail(&vpt->data.attribute.ar, ar);
 
        switch (ar->num) {
        case 0:
@@ -1078,7 +1080,7 @@ static inline CC_HINT(always_inline) void tmpl_attr_insert(tmpl_t *vpt, tmpl_att
 
        default:
                ar->resolve_only = true;
-               while ((ar = fr_dlist_prev(&vpt->data.attribute.ar, ar))) ar->resolve_only = true;
+               while ((ar = fr_dlist_tmpl_attr_prev(&vpt->data.attribute.ar, ar))) ar->resolve_only = true;
                break;
        }
 }
@@ -1263,7 +1265,7 @@ int tmpl_attr_afrom_attr_unresolved_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *e
        if (fr_sbuff_next_if_char(name, '.')) {
                ret = tmpl_attr_afrom_attr_unresolved_substr(ctx, err, vpt, NULL, NULL, name, t_rules, depth + 1);
                if (ret < 0) {
-                       fr_dlist_talloc_free_tail(&vpt->data.attribute.ar); /* Remove and free ar */
+                       fr_dlist_tmpl_attr_talloc_free_tail(&vpt->data.attribute.ar); /* Remove and free ar */
                        return -1;
                }
        }
@@ -1370,7 +1372,7 @@ static inline int tmpl_attr_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t
                 *      useful to have the original.
                 */
                if (!da && !vpt->rules.disallow_internal &&
-                   (ar = fr_dlist_tail(&vpt->data.attribute.ar)) &&
+                   (ar = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar)) &&
                    (ar->type == TMPL_ATTR_TYPE_NORMAL) && (ar->ar_da->type == FR_TYPE_GROUP)) {
                        (void)fr_dict_attr_by_name_substr(NULL,
                                                          &da, fr_dict_root(fr_dict_internal()),
@@ -1663,7 +1665,7 @@ do_suffix:
 
                if (ar) tmpl_attr_insert(vpt, ar);
                if (tmpl_attr_afrom_attr_substr(ctx, err, vpt, our_parent, namespace, name, p_rules, t_rules, depth + 1) < 0) {
-                       if (ar) fr_dlist_talloc_free_tail(&vpt->data.attribute.ar); /* Remove and free ar */
+                       if (ar) fr_dlist_tmpl_attr_talloc_free_tail(&vpt->data.attribute.ar); /* Remove and free ar */
                        goto error;
                }
        /*
@@ -1691,12 +1693,12 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_
                                                     tmpl_rules_t const **pt_rules,
                                                     unsigned int depth)
 {
-       tmpl_request_ref_t      ref;
-       size_t                  ref_len;
-       tmpl_request_t          *rr;
-       fr_dlist_head_t         *list = &vpt->data.attribute.rr;
-       fr_sbuff_marker_t       s_m;
-       tmpl_rules_t const      *t_rules = *pt_rules;
+       tmpl_request_ref_t                      ref;
+       size_t                                  ref_len;
+       tmpl_request_t                          *rr;
+       FR_DLIST_HEAD_TYPE(tmpl_request)        *list = &vpt->data.attribute.rr;
+       fr_sbuff_marker_t                       s_m;
+       tmpl_rules_t const                      *t_rules = *pt_rules;
 
        fr_sbuff_marker(&s_m, name);
        fr_sbuff_out_by_longest_prefix(&ref_len, &ref, tmpl_request_ref_table, name, t_rules->request_def);
@@ -1715,7 +1717,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_
                        *rr = (tmpl_request_t){
                                .request = ref
                        };
-                       fr_dlist_insert_tail(list, rr);
+                       fr_dlist_tmpl_request_insert_tail(list, rr);
                }
 
                return 0;
@@ -1756,7 +1758,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_
        *rr = (tmpl_request_t){
                .request = ref
        };
-       fr_dlist_insert_tail(list, rr);
+       fr_dlist_tmpl_request_insert_tail(list, rr);
 
        /*
         *      Update the parsing rules if we go to the parent.
@@ -1771,7 +1773,7 @@ static inline int tmpl_request_ref_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_
         */
        if (fr_sbuff_next_if_char(name, '.')) {
                if (tmpl_request_ref_afrom_attr_substr(ctx, err, vpt, name, p_rules, pt_rules, depth + 1) < 0) {
-                       fr_dlist_talloc_free_tail(list); /* Remove and free rr */
+                       fr_dlist_tmpl_request_talloc_free_tail(list); /* Remove and free rr */
                        return -1;
                }
        }
@@ -1966,7 +1968,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
                if (t_rules->list_as_attr) {
                        tmpl_attr_t *ar;
 
-                       ar = fr_dlist_head(&vpt->data.attribute.ar);
+                       ar = fr_dlist_tmpl_attr_head(&vpt->data.attribute.ar);
                        fr_assert(ar != NULL);
 
                        if ((ar->ar_type != TMPL_ATTR_TYPE_NORMAL) ||
@@ -2003,7 +2005,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
                                 *      Prepend the list ref so it gets evaluated
                                 *      first.
                                 */
-                               fr_dlist_insert_head(&vpt->data.attribute.ar, ar);
+                               fr_dlist_tmpl_attr_insert_head(&vpt->data.attribute.ar, ar);
                        }
                }
        }
@@ -2014,7 +2016,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
         *
         *      Eventually we'll remove TMPL_TYPE_LIST
         */
-       if (fr_dlist_num_elements(&vpt->data.attribute.ar) == 0) {
+       if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) == 0) {
                tmpl_attr_t *ar;
 
                MEM(ar = talloc_zero(vpt, tmpl_attr_t));
@@ -2024,7 +2026,7 @@ ssize_t tmpl_afrom_attr_substr(TALLOC_CTX *ctx, tmpl_attr_error_t *err,
                        break;
 
                case 1:                                         /* Found a filter */
-                       fr_dlist_insert_tail(&vpt->data.attribute.ar, ar);
+                       fr_dlist_tmpl_attr_insert_tail(&vpt->data.attribute.ar, ar);
                        break;
 
                default:                                        /* Parse error */
@@ -3230,7 +3232,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
         *      This emulates what's done in the initial
         *      tokenizer function.
         */
-       ar = fr_dlist_head(&vpt->data.attribute.ar);
+       ar = fr_dlist_tmpl_attr_head(&vpt->data.attribute.ar);
        if (ar->type == TMPL_ATTR_TYPE_UNRESOLVED) {
                (void)fr_dict_attr_search_by_name_substr(NULL,
                                                         &da,
@@ -3257,7 +3259,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
                 *      and correct its parent and
                 *      namespace.
                 */
-               next = fr_dlist_next(&vpt->data.attribute.ar, ar);
+               next = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar);
                if (next) {
                        next->ar_parent = da;
                        next->ar_unresolved_namespace = da;
@@ -3267,7 +3269,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
        /*
         *      Loop, resolving each unresolved attribute in turn
         */
-       while ((ar = fr_dlist_next(&vpt->data.attribute.ar, ar))) {
+       while ((ar = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar))) {
                switch (ar->type) {
                case TMPL_ATTR_TYPE_NORMAL:
                        continue;       /* Don't need to resolve */
@@ -3295,7 +3297,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
                 *      in the internal dictionary.
                 */
                if (!da) {
-                       prev = fr_dlist_prev(&vpt->data.attribute.ar, ar);
+                       prev = fr_dlist_tmpl_attr_prev(&vpt->data.attribute.ar, ar);
                        if (!vpt->rules.disallow_internal && prev && (prev->ar_da->type == FR_TYPE_GROUP)) {
                                (void)fr_dict_attr_by_name_substr(NULL,
                                                                  &da,
@@ -3323,7 +3325,7 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
                 *      Reach into the next reference
                 *      and correct its parent.
                 */
-               next = fr_dlist_next(&vpt->data.attribute.ar, ar);
+               next = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar);
                if (next) {
                        next->ar_parent = da;
                        next->ar_unresolved_namespace = da;
@@ -3343,9 +3345,9 @@ static inline CC_HINT(always_inline) int tmpl_attr_resolve(tmpl_t *vpt, tmpl_res
                 *      an index, the ar is redundant and should
                 *      be removed.
                 */
-               prev = fr_dlist_prev(&vpt->data.attribute.ar, ar);
+               prev = fr_dlist_tmpl_attr_prev(&vpt->data.attribute.ar, ar);
                if (prev && (prev->ar_da->type != FR_TYPE_GROUP) && (prev->ar_num == NUM_ANY)) {
-                       fr_dlist_remove(&vpt->data.attribute.ar, prev);
+                       fr_dlist_tmpl_attr_remove(&vpt->data.attribute.ar, prev);
                        ar->ar_parent = prev->ar_parent;
                        talloc_free(prev);
                }
@@ -3477,8 +3479,8 @@ void tmpl_unresolve(tmpl_t *vpt)
        case TMPL_TYPE_LIST:
        case TMPL_TYPE_ATTR:
        case TMPL_TYPE_ATTR_UNRESOLVED:
-               fr_dlist_talloc_free(&vpt->data.attribute.ar);
-               fr_dlist_talloc_free(&vpt->data.attribute.rr);
+               fr_dlist_tmpl_attr_talloc_free(&vpt->data.attribute.ar);
+               fr_dlist_tmpl_request_talloc_free(&vpt->data.attribute.rr);
                break;
 
        /*
@@ -3572,7 +3574,7 @@ static void attr_to_raw(tmpl_t *vpt, tmpl_attr_t *ref)
  */
 void tmpl_attr_to_raw(tmpl_t *vpt)
 {
-       attr_to_raw(vpt, fr_dlist_tail(&vpt->data.attribute.ar));
+       attr_to_raw(vpt, fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar));
 }
 
 /** Add an unknown #fr_dict_attr_t specified by a #tmpl_t to the main dictionary
@@ -3596,7 +3598,7 @@ int tmpl_attr_unknown_add(tmpl_t *vpt)
 
        if (!tmpl_da(vpt)->flags.is_unknown) return 1;  /* Ensure at least the leaf is unknown */
 
-       while ((ar = fr_dlist_next(&vpt->data.attribute.ar, ar))) {
+       while ((ar = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar))) {
                fr_dict_attr_t const    *unknown, *known;
 
                switch (ar->type) {
@@ -3619,7 +3621,7 @@ int tmpl_attr_unknown_add(tmpl_t *vpt)
                 *      Fixup the parent of the next unknown
                 *      now it's known.
                 */
-               next = fr_dlist_next(&vpt->data.attribute.ar, ar);
+               next = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar);
                if (next && (next->type == TMPL_ATTR_TYPE_UNKNOWN) &&
                    (next->ar_da->parent == unknown)) {
                        if (fr_dict_attr_unknown_parent_to_known(fr_dict_attr_unconst(next->ar_da),
@@ -3804,7 +3806,7 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
        /*
         *      Print request references
         */
-       while ((rr = fr_dlist_next(&vpt->data.attribute.rr, rr))) {
+       while ((rr = fr_dlist_tmpl_request_next(&vpt->data.attribute.rr, rr))) {
                if (rr->request == REQUEST_CURRENT) continue;   /* Don't print the default request */
 
                FR_SBUFF_IN_TABLE_STR_RETURN(&our_out, tmpl_request_ref_table, rr->request, "<INVALID>");
@@ -3818,13 +3820,13 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
                if (printed_rr) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
 
                FR_SBUFF_IN_TABLE_STR_RETURN(&our_out, pair_list_table, tmpl_list(vpt), "<INVALID>");
-               if (fr_dlist_num_elements(&vpt->data.attribute.ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
+               if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
 
        /*
         *      Request qualifier with no list qualifier
         */
        } else if (printed_rr) {
-               if (fr_dlist_num_elements(&vpt->data.attribute.ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
+               if (fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
        }
 
        /*
@@ -3836,7 +3838,7 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
         *      we add the .unknown prefix.
         *
         */
-       if (!tmpl_is_list(vpt) && (ar = fr_dlist_tail(&vpt->data.attribute.ar))) {
+       if (!tmpl_is_list(vpt) && (ar = fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))) {
                switch (ar->type) {
                case TMPL_ATTR_TYPE_NORMAL:
                case TMPL_ATTR_TYPE_UNKNOWN:
@@ -3853,7 +3855,7 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
         *      Print attribute identifiers
         */
        ar = NULL;
-       while ((ar = fr_dlist_next(&vpt->data.attribute.ar, ar))) {
+       while ((ar = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar))) {
                if (!tmpl_is_list(vpt)) switch(ar->type) {
                case TMPL_ATTR_TYPE_NORMAL:
                case TMPL_ATTR_TYPE_UNKNOWN:
@@ -3867,7 +3869,7 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
                        /*
                         *      First component in the list has everything built
                         */
-                       if (ar == fr_dlist_head(&vpt->data.attribute.ar)) {
+                       if (ar == fr_dlist_tmpl_attr_head(&vpt->data.attribute.ar)) {
                                depth = ar->ar_parent->depth - 1;       /* Adjust for array index */
                        /*
                         *      Everything else skips the first component
@@ -3961,7 +3963,7 @@ ssize_t tmpl_attr_print(fr_sbuff_t *out, tmpl_t const *vpt, tmpl_attr_prefix_t a
                        break;
                }
 
-               if (fr_dlist_next(&vpt->data.attribute.ar, ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
+               if (fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar)) FR_SBUFF_IN_CHAR_RETURN(&our_out, '.');
        }
        return fr_sbuff_set(out, &our_out);
 }
@@ -4156,13 +4158,13 @@ void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt)
        /*
         *      Loop detection
         */
-       while ((slow = fr_dlist_next(&vpt->data.attribute.ar, slow)) &&
-              (fast = fr_dlist_next(&vpt->data.attribute.ar, fast))) {
+       while ((slow = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, slow)) &&
+              (fast = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, fast))) {
 
                /*
                 *      Advances twice as fast as slow...
                 */
-               fast = fr_dlist_next(&vpt->data.attribute.ar, fast);
+               fast = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, fast);
                fr_fatal_assert_msg(fast != slow,
                                    "CONSISTENCY CHECK FAILED %s[%u]:  Looping reference list found.  "
                                    "Fast pointer hit slow pointer at \"%s\"",
@@ -4177,7 +4179,7 @@ void tmpl_attr_verify(char const *file, int line, tmpl_t const *vpt)
         *      Known attribute cannot come after unresolved or unknown attributes
         *      Unknown attributes cannot come after unresolved attributes
         */
-       if (!tmpl_is_list(vpt)) while ((ar = fr_dlist_next(&vpt->data.attribute.ar, ar))) {
+       if (!tmpl_is_list(vpt)) while ((ar = fr_dlist_tmpl_attr_next(&vpt->data.attribute.ar, ar))) {
                switch (ar->type) {
                case TMPL_ATTR_TYPE_NORMAL:
                        if (seen_unknown) {
@@ -4331,13 +4333,13 @@ void tmpl_verify(char const *file, int line, tmpl_t const *vpt)
                break;
 
        case TMPL_TYPE_ATTR_UNRESOLVED:
-               if ((fr_dlist_num_elements(&vpt->data.attribute.ar) > 0) &&
-                   ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->da) {
+               if ((fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) > 0) &&
+                   ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->da) {
 #ifndef NDEBUG
                        tmpl_attr_debug(vpt);
 #endif
                        fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_ATTR_UNRESOLVED contains %u "
-                                            "references", file, line, fr_dlist_num_elements(&vpt->data.attribute.ar));
+                                            "references", file, line, fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar));
                }
                break;
 
@@ -4403,13 +4405,13 @@ void tmpl_verify(char const *file, int line, tmpl_t const *vpt)
                                             file, line);
                }
 
-               if ((fr_dlist_num_elements(&vpt->data.attribute.ar) > 0) &&
-                   ((tmpl_attr_t *)fr_dlist_tail(&vpt->data.attribute.ar))->da) {
+               if ((fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar) > 0) &&
+                   ((tmpl_attr_t *)fr_dlist_tmpl_attr_tail(&vpt->data.attribute.ar))->da) {
 #ifndef NDEBUG
                        tmpl_attr_debug(vpt);
 #endif
                        fr_fatal_assert_fail("CONSISTENCY CHECK FAILED %s[%u]: TMPL_TYPE_LIST contains %u "
-                                            "references", file, line, fr_dlist_num_elements(&vpt->data.attribute.ar));
+                                            "references", file, line, fr_dlist_tmpl_attr_num_elements(&vpt->data.attribute.ar));
                }
                break;
 
index 76aaeccd71f5978c99af59c6fe8c4dd6ca900592..b7cd7bd39961ba8d14c6d4208f4bd64431cc1967 100644 (file)
@@ -1047,6 +1047,11 @@ static inline void fr_dlist_sort(fr_dlist_head_t *list, fr_cmp_t cmp)
        }
 }
 
+static inline void fr_dlist_noop(void)
+{
+       return;
+}
+
 /** Expands to the type name used for the entry wrapper structure
  *
  * @param[in] _name    Prefix we add to type-specific structures.
@@ -1085,7 +1090,12 @@ DIAG_OFF(unused-function) \
        static inline   fr_dlist_head_t *fr_dlist_ ## _name ## _list_head(FR_DLIST_HEAD_TYPE(_name) const *list) \
                { return        UNCONST(fr_dlist_head_t *, &list->head); } \
        static inline   void fr_dlist_ ## _name ## _entry_init(_element_type *entry) \
-               {               fr_dlist_entry_init(&entry->_element_entry.entry); } \
+               { \
+                       _Generic((&entry->_element_entry), \
+                                FR_DLIST_ENTRY_TYPE(_name) *: fr_dlist_entry_init(UNCONST(fr_dlist_t *, &entry->_element_entry.entry)), \
+                                FR_DLIST_ENTRY_TYPE(_name) const *: fr_dlist_noop()\
+                       ); \
+               } \
 \
        static inline   void fr_dlist_ ## _name ## _init(FR_DLIST_HEAD_TYPE(_name) *list) \
                {               _fr_dlist_init(&list->head, offsetof(_element_type, _element_entry), NULL); } \