]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add migration flag for key field transition
authorAlan T. DeKok <aland@freeradius.org>
Mon, 25 Aug 2025 12:19:57 +0000 (08:19 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 25 Aug 2025 12:19:57 +0000 (08:19 -0400)
there's no configuration for it, but the flag is added automatically

src/lib/server/tmpl_eval.c
src/lib/server/tmpl_tokenize.c
src/lib/util/dict.h
src/lib/util/dict_ext.c
src/lib/util/dict_fixup.c
src/lib/util/dict_tokenize.c
src/lib/util/dict_unknown.c
src/lib/util/dict_util.c
src/lib/util/dict_validate.c
src/lib/util/pair.c
src/lib/util/pair_legacy.c

index ea437fb01b33c6eac006c5c0967ec7b87a650207..a370b09ca66d3216c065972f7a1db8cf7140e9b4 100644 (file)
@@ -892,6 +892,8 @@ int pair_append_by_tmpl_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t
                         *
                         *      We just skip one level down an don't create or update
                         *      the key pair.
+                        *
+                        *      @todo - remove after migration_union_key is deleted
                         */
                        if (vp && fr_dict_attr_is_key_field(ar->da) && fr_type_is_leaf(vp->data.type)) {
                                ar = tmpl_attr_list_next(ar_list, ar);
index e6dd2d54ea5fab8361703cff83ddb16581bd985b..89d829788ad86caa06e1b143e42fc0abefdc4e1b 100644 (file)
@@ -2108,6 +2108,8 @@ do_suffix:
                        /*
                         *      Key fields can have children, because we really don't know how else to
                         *      represent the child structures.
+                        *
+                        *      @todo - remove after migration_union_key is deleted
                         */
                        if (fr_dict_attr_is_key_field(da)) goto is_union;
 
index 98dc6de8f6382b5830e7d1fa3a55e8132b9dd303..6c122acea810c658867a3bbabe37286c8953c372 100644 (file)
@@ -120,6 +120,8 @@ typedef struct {
 
        unsigned int            has_fixup : 1;                  //! needs a fixup during dictionary parsing
 
+       unsigned int            migration_union_key;            //!< for migrating key fields
+
        /*
         *      main: extra is set, then this field is is key, bit, or a uint16 length field.
         *      radius: is one of 9 options for flags
index f9b35ba37babc47f5c049f484c1ef02ae1aa2a44..01e45b7109259f7605906d2c9a93690122d368b1 100644 (file)
@@ -66,7 +66,11 @@ static int fr_dict_attr_ext_enumv_copy(UNUSED int ext,
        fr_dict_attr_ext_enumv_t        *src_ext = src_ext_ptr;
        fr_hash_iter_t                  iter;
        fr_dict_enum_value_t                    *enumv;
-       bool                            has_child = fr_dict_attr_is_key_field(da_src);
+
+       /*
+        *      @todo - remove after migration_union_key is deleted
+        */
+       bool                            has_child = fr_dict_attr_is_key_field(da_src) && !da_src->flags.migration_union_key;
 
        if (!src_ext->value_by_name) return 0;
 
index f10989427844ed5ad7c6fe49be2dff9064daac33..47c5c630611510363843ac19cda2cd2a257ee305 100644 (file)
@@ -541,6 +541,8 @@ int dict_fixup_clone(fr_dict_attr_t **dst_p, fr_dict_attr_t const *src)
 
        /*
         *      Can't clone KEY fields directly, you MUST clone the parent struct.
+        *
+        *      @todo - remove after migration_union_key is deleted
         */
        if (!fr_type_is_non_leaf(src->type) || fr_dict_attr_is_key_field(src) || fr_dict_attr_is_key_field(dst)) {
                fr_strerror_printf("Invalid reference from '%s' to %s", dst->name, src->name);
index 4e9de584cfba95f0a7326dd205c1ed48a0cff5d7..95deb64be87dd87bbd0da8739750fad1d186adfa 100644 (file)
@@ -1440,6 +1440,8 @@ static int dict_read_process_attribute(dict_tokenize_ctx_t *dctx, char **argv, i
                key = ext->ref;
                fr_assert(key);
                fr_assert(fr_dict_attr_is_key_field(key));
+               da = UNCONST(fr_dict_attr_t *, key);
+               da->flags.migration_union_key = true;
        }
 
        da = dict_attr_alloc_null(dctx->dict->pool, dctx->dict->proto);
@@ -2546,6 +2548,9 @@ static int dict_read_process_struct(dict_tokenize_ctx_t *dctx, char **argv, int
                                return -1;
                        }
 
+                       /*
+                        *      @todo - remove after migration_union_key is deleted
+                        */
                        if (!fr_dict_attr_is_key_field(parent)) {
                                fr_strerror_printf("Attribute '%s' is not a 'key' attribute", key_attr);
                                return -1;
index 8d5e7a5616ce315d34d53b6692fb798a00ac8d13..59c7eea54b0b4d1467fbb199d7d077169afb7020 100644 (file)
@@ -306,6 +306,9 @@ fr_dict_attr_t *fr_dict_attr_unknown_typed_afrom_num_raw(TALLOC_CTX *ctx, fr_dic
                return NULL;
 
        default:
+               /*
+                *      @todo - remove after migration_union_key is deleted
+                */
                if (fr_dict_attr_is_key_field(parent)) break;
 
                if (!fr_type_is_structural_except_vsa(parent->type)) {
index 0bca91fe6c61c1f1a5e27d9afef40ee7180a592a..5500f6236aaa5cc8967b367317b843f525e982ac 100644 (file)
@@ -1479,6 +1479,8 @@ bool dict_attr_can_have_children(fr_dict_attr_t const *da)
                /*
                 *      Children are allowed here, but ONLY if this
                 *      attribute is a key field.
+                *
+                *      @todo - remove after migration_union_key is deleted
                 */
                if (da->parent && (da->parent->type == FR_TYPE_STRUCT) && fr_dict_attr_is_key_field(da)) return true;
                break;
@@ -1868,6 +1870,8 @@ int dict_attr_enum_add_name(fr_dict_attr_t *da, char const *name,
         *
         *      Perhaps this can be done as a special case after we convert to UNIONs?  Because then
         *      we can allow ATTRIBUTE Global-VPN 255 struct[0].
+        *
+        *      @todo - remove after migration_union_key is deleted
         */
        if (fr_dict_attr_is_key_field(da) && !key_child_ref) {
                fr_strerror_const("Child attribute must be defined for VALUEs associated with a 'key' attribute");
@@ -5019,6 +5023,8 @@ bool fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const
        /*
         *      Child is a STRUCT which has a parent key field.  The
         *      child pair nesting, though, is in the grandparent.
+        *
+        *      @todo - remove after migration_union_key is deleted
         */
        if (fr_dict_attr_is_key_field(child->parent)) {
                fr_assert(child->parent->parent == parent);
index 17bc7dad4d065ca8eeb4e649b789d9c114060793..59a726e1710897c158f69960ae92fc00874ccd5e 100644 (file)
@@ -622,6 +622,9 @@ bool dict_attr_flags_valid(fr_dict_attr_t *da)
        case FR_TYPE_UINT8:
        case FR_TYPE_UINT16:
        case FR_TYPE_UINT32:
+               /*
+                *      @todo - remove after migration_union_key is deleted
+                */
                if (fr_dict_attr_is_key_field(parent)) break;
                FALL_THROUGH;
 
index af392fb493ee66f1d685921bdc9d362b0b709fc5..09f8078b85a67c53a8b09f607546c366df98b183 100644 (file)
@@ -431,6 +431,8 @@ fr_pair_t *fr_pair_afrom_da_depth_nested(TALLOC_CTX *ctx, fr_pair_list_t *list,
                 *      Otherwise if we're creating a child struct (which is magically parented by the key
                 *      field), then don't bother creating the key field.  It will be automatically filled in
                 *      by the encoder.
+                *
+                *      @todo - remove after migration_union_key is deleted
                 */
                if ((find != da) && fr_dict_attr_is_key_field(find)) {
                        continue;
@@ -3430,6 +3432,8 @@ static fr_pair_t *pair_alloc_parent(fr_pair_t *in, fr_pair_t *item, fr_dict_attr
         *
         *      If we're asked to create children of a keyed
         *      structure, just create the children in the parent.
+        *
+        *      @todo - remove after migration_union_key is deleted
         */
        if (!fr_type_is_structural(da->type)) {
                fr_assert(fr_dict_attr_is_key_field(da));
index f1f0844cb44e73d3a92f4401c6b6d1cb546492bd..3eed1c66694e5b606879dae0ad4618bb347d058f 100644 (file)
@@ -556,10 +556,10 @@ redo:
                case FR_TYPE_UINT16:
                case FR_TYPE_UINT32:
                        /*
-                        *      Key fields have children in their namespace, but the children go into the
-                        *      parents context and list.
+                        *      Key fields have children in their namespace, but for OLD style, the children
+                        *      go into the parents context and list.
                         */
-                       if (fr_dict_attr_is_key_field(vp->da)) {
+                       if (fr_dict_attr_is_key_field(vp->da) && !vp->da->flags.migration_union_key) {
                                fr_pair_t *parent_vp;
 
                                parent_vp = fr_pair_parent(vp);