]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Better handle group refs to somewhere in the middle of the tree
authorAlan T. DeKok <aland@freeradius.org>
Thu, 5 Dec 2024 20:30:47 +0000 (15:30 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 7 Dec 2024 13:44:32 +0000 (08:44 -0500)
doc/antora/modules/reference/pages/type/all_types.adoc
src/lib/util/pair_print.c
src/tests/unit/protocols/dhcpv6/dictionary
src/tests/unit/protocols/dhcpv6/group-tlv.txt [new file with mode: 0644]

index 3e5392870d2da7f4e7f182a31715a363ffece5f9..4587de9d53e9496f44baf16bad0bb5966a9ff446 100644 (file)
@@ -78,6 +78,10 @@ missing, then the relevant field is filled with zeros.
 
 group: A `group` contains an arbitrary collection of children, in any order.
 +
+A `group` is really a reference to some other attribute elsewhere in
+the same protocol dictionary, or to a different protocol dictionary.
+The `group` allows for dictionaries to contain cross-references.
++
 The `group` can contain any child attributes, so long as they are
 within the same protocol namespace.  See the
 dictionary/attribute.adoc[ATTRIBUTE] documentation for more
@@ -86,7 +90,7 @@ information.
 The `group` only encodes the child attributes which have been created
 and stored within the `group`.  The order of children does not matter.
 
-tlv:: A `tlv` is a `group` which has a limited subset of children.
+tlv:: A `tlv` defines a hierarchy of children, which can only be contained in the `tlv`.
 +
 The `tlv` can only contain child attributes which have been defined as
 children of the `tlv.`
index dac3d1a80d1c580c4e9d02c90ff92e6375358698..667ac1c28012f82b5218f371576907d332798f29 100644 (file)
  *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
+/*
+ *     Groups are printed from the referenced attribute.
+ */
+#define fr_pair_reset_parent(parent) do { \
+       if (parent && (parent->type == FR_TYPE_GROUP)) { \
+               parent = fr_dict_attr_ref(parent); \
+               if (parent->flags.is_root) parent = NULL; \
+       } \
+  } while (0)
+
 /** Pair serialisation API
  *
  * @file src/lib/util/pair_print.c
@@ -114,10 +124,7 @@ ssize_t fr_pair_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t c
                token = "<INVALID-TOKEN>";
        }
 
-       /*
-        *      Groups are printed from the root.
-        */
-       if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
+       fr_pair_reset_parent(parent);
 
        if (vp->vp_raw) FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "raw.");
        FR_DICT_ATTR_OID_PRINT_RETURN(&our_out, parent, vp->da, false);
@@ -176,10 +183,7 @@ ssize_t fr_pair_print_secure(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_p
                token = "<INVALID-TOKEN>";
        }
 
-       /*
-        *      Groups are printed from the root.
-        */
-       if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
+       fr_pair_reset_parent(parent);
 
        if (vp->vp_raw) FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "raw.");
        FR_DICT_ATTR_OID_PRINT_RETURN(&our_out, parent, vp->da, false);
@@ -241,10 +245,7 @@ ssize_t fr_pair_list_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pai
                return fr_sbuff_used(out);
        }
 
-       /*
-        *      Groups are printed from the root.
-        */
-       if (parent && (parent->type == FR_TYPE_GROUP)) parent = NULL;
+       fr_pair_reset_parent(parent);
 
        while (true) {
                FR_SBUFF_RETURN(fr_pair_print, &our_out, parent, vp);
index 1e244109e988b672491b0f38e0a60b7fccaf96b8..17d83493611e8cf60f4b02609fbb2528cf779dbc 100644 (file)
@@ -1,50 +1,9 @@
 BEGIN PROTOCOL DHCPv6          3
 
-#
-#      Basic options needed by the DHCPv6 pair encoder and decoder
-#
-ATTRIBUTE      Packet-Type                             65536   uint32  internal
-ATTRIBUTE      Transaction-ID                          65537   uint32  internal
+ATTRIBUTE      test-tlv        6809    tlv
+ATTRIBUTE      child1          .1      uint32
+ATTRIBUTE      child2          .2      uint32
 
-ATTRIBUTE      Option-Request                          65535   uint16 array    # Magic option listing requested options
-
-#
-#      Test attributes
-#
-ATTRIBUTE      Test-string                             1       string
-ATTRIBUTE      Test-octets                             2       octets
-
-ATTRIBUTE      Test-ipaddr                             3       ipaddr
-ATTRIBUTE      Test-ipv4addr                           4       ipv4addr
-ATTRIBUTE      Test-ipv4prefix                         5       ipv4prefix
-ATTRIBUTE      Test-ipv6addr                           6       ipv6addr
-ATTRIBUTE      Test-ipv6prefix                         7       ipv6prefix
-ATTRIBUTE      Test-ifid                               8       ifid
-ATTRIBUTE      Test-ether                              11      ether
-
-ATTRIBUTE      Test-bool                               12      bool
-
-ATTRIBUTE      Test-uint8                              13      uint8
-ATTRIBUTE      Test-uint16                             14      uint16
-ATTRIBUTE      Test-uint32                             15      uint32
-ATTRIBUTE      Test-uint64                             16      uint64
-
-ATTRIBUTE      Test-int8                               17      int8
-ATTRIBUTE      Test-int16                              18      int16
-ATTRIBUTE      Test-int32                              19      int32
-ATTRIBUTE      Test-int64                              20      int64
-
-ATTRIBUTE      Test-float32                            21      float32
-
-ATTRIBUTE      Test-time-delta                         23      time_delta
-ATTRIBUTE      Test-date                               24      date
-
-ATTRIBUTE      Test-size                               26      size
-
-ATTRIBUTE      Test-tlv                                27      tlv
-ATTRIBUTE      Test-struct                             28      struct
-
-ATTRIBUTE      Test-vsa                                30      vsa
-ATTRIBUTE      Test-group                              32      group
+ATTRIBUTE      test-group      6810    group ref=test-tlv
 
 END-PROTOCOL   DHCPv6
diff --git a/src/tests/unit/protocols/dhcpv6/group-tlv.txt b/src/tests/unit/protocols/dhcpv6/group-tlv.txt
new file mode 100644 (file)
index 0000000..861369c
--- /dev/null
@@ -0,0 +1,30 @@
+#  -*- text -*-
+#  Copyright (C) 2019 Network RADIUS SARL (legal@networkradius.com)
+#  This work is licensed under CC-BY version 4.0 https://creativecommons.org/licenses/by/4.0
+#
+#  Version $Id$
+#
+
+proto dhcpv6
+proto-dictionary dhcpv6
+load-dictionary dictionary
+fuzzer-out dhcpv6
+
+pair test-group = { child1 = 1 }
+match test-group = { child1 = 1 }
+
+
+encode-pair    test-group = { child1 = 1 }
+match 1a 9a 00 0c 1a 99 00 08 00 01 00 04 00 00 00 01
+
+#
+#  Yeah, this is wrong.  The decoder can only handle group refs which
+#  point to the top of the tree.
+#
+#  @todo - fix it!
+#
+decode-pair -
+match test-group = {  = { child1 = 1 } }
+
+count
+match 10