]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow relative references in "clone="
authorAlan T. DeKok <aland@freeradius.org>
Sat, 6 Apr 2024 15:10:38 +0000 (11:10 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 6 Apr 2024 15:18:42 +0000 (11:18 -0400)
remove code which allowed clone to reference other protocols.
The "reference protocol" code was changed during the refactoring
to support

ATTRIBUTE ... group ref=..DHCPv4

which now makes this code invalid.  So we fix up this code to work,
and (at least temporarily) remove the ability to reference other
protocols.

Now that the framework supports relative references, it should be
fairly simply to re-add protocol references as a separate commit.

share/dictionary/radius/dictionary.wimax
src/lib/util/dict_fixup.c

index 1b70ae810de5d5272ff5f00564f2b389f8936e6e..9f87656478e06e13adb32414c619bf1e6ccefeb6 100644 (file)
@@ -217,7 +217,7 @@ VALUE       Assigned                        Src-Assigned            1
 VALUE  Assigned                        Dst-Assigned            2
 VALUE  Assigned                        Src-Dst-Assigned        3
 
-ATTRIBUTE      Dst-Spec                                28.11.6 tlv clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor.Classifier.Src-Spec
+ATTRIBUTE      Dst-Spec                                28.11.6 tlv clone=.Src-Spec
 
 ATTRIBUTE      IP-TOS/DSCP-Range-and-Mask              28.11.7 octets
 ATTRIBUTE      VLAN-ID                                 28.11.8 integer
@@ -475,12 +475,12 @@ ATTRIBUTE Priority                                .2      byte
 ATTRIBUTE      Protocol                                .3      byte
 ATTRIBUTE      Direction                               .4      byte
 
-ATTRIBUTE      Src-Spec                                84.9.5  tlv  clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor.Classifier.Src-Spec
+ATTRIBUTE      Src-Spec                                84.9.5  tlv  clone=...Packet-Flow-Descriptor.Classifier.Src-Spec
 #  Add these two, also
 ATTRIBUTE      MAC-Address                             .8      ether
 ATTRIBUTE      MAC-Mask                                .9      ether
 
-ATTRIBUTE      Dest-Spec                               84.9.6  tlv clone=Vendor-Specific.WiMAX.Packet-Flow-Descriptor-v2.Classifier.Src-Spec
+ATTRIBUTE      Dest-Spec                               84.9.6  tlv clone=.Src-Spec
 
 ATTRIBUTE      Classifier-IP-ToS-DSCP                  84.9.7  byte
 
index c88e559812a1cd381094924c73775946d550afc4..32532812ba65083d58940e709365825e61dbe292 100644 (file)
@@ -416,36 +416,59 @@ int dict_fixup_clone(dict_fixup_ctx_t *fctx, char const *filename, int line,
  */
 static inline CC_HINT(always_inline) int dict_fixup_clone_apply(UNUSED dict_fixup_ctx_t *fctx, dict_fixup_clone_t *fixup)
 {
-       fr_dict_attr_t const    *da;
+       fr_dict_attr_t const    *da, *root;
        fr_dict_attr_t          *cloned;
        fr_dict_t               *dict = fr_dict_unconst(fr_dict_by_da(fixup->da));
+       char const              *ref = fixup->ref;
 
        /*
-        *      Find the reference
+        *      Allow relative attribute references.
         */
-       da = fr_dict_attr_by_oid(NULL, fr_dict_root(dict), fixup->ref);
-       if (da) {
-               /*
-                *      The referenced DA is higher than the one we're
-                *      creating.  Ensure it's not a parent.
-                */
-               if (da->depth < fixup->da->depth) {
-                       fr_dict_attr_t const *parent;
-
-                       for (parent = fixup->da->parent; !parent->flags.is_root; parent = parent->parent) {
-                               if (parent == da) {
-                                       fr_strerror_printf("References MUST NOT refer to a parent attribute %s at %s[%d]",
-                                                          parent->name, fr_cwd_strip(fixup->common.filename), fixup->common.line);
-                                       return -1;
-                               }
+       if (ref[0] == '.') {
+               root = fixup->da->parent;
+               ref++;
+
+               while (ref[0] == '.') {
+                       /*
+                        *      @todo - allow references to other protocols.
+                        */
+                       if (root->flags.is_root) {
+                               fr_strerror_printf("Too many '.' in clone=%s at %s[%d]",
+                                                  fixup->ref, fr_cwd_strip(fixup->common.filename), fixup->common.line);
+                               return -1;
                        }
+
+                       root = root->parent;
+                       ref++;
                }
        } else {
-               /*
-                *      @todo - cloning foreign attributes is not a well-tested path.
-                */
-               da = dict_protocol_reference(&dict, fixup->ref, fixup->common.filename, fixup->common.line);
-               if (!da) return -1;
+               root = fr_dict_root(dict);
+       }
+
+       /*
+        *      Find the reference
+        */
+       da = fr_dict_attr_by_oid(NULL, root, ref);
+       if (!da) {
+               fr_strerror_printf("Unknown attribute reference in clone=%s at parent %s %s[%d]",
+                                  fixup->ref, root->name, fr_cwd_strip(fixup->common.filename), fixup->common.line);
+               return -1;
+       }
+
+       /*
+        *      The referenced DA is higher than the one we're
+        *      creating.  Ensure it's not a parent.
+        */
+       if (da->depth < fixup->da->depth) {
+               fr_dict_attr_t const *parent;
+
+               for (parent = fixup->da->parent; !parent->flags.is_root; parent = parent->parent) {
+                       if (parent == da) {
+                               fr_strerror_printf("References MUST NOT refer to a parent attribute %s at %s[%d]",
+                                                  parent->name, fr_cwd_strip(fixup->common.filename), fixup->common.line);
+                               return -1;
+                       }
+               }
        }
 
        if (fr_dict_attr_ref(da)) {