]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
copy keyed structures, and update DHCPv6 dict and tests
authorAlan T. DeKok <aland@freeradius.org>
Fri, 4 Dec 2020 21:43:03 +0000 (16:43 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 6 Dec 2020 02:48:07 +0000 (21:48 -0500)
share/dictionary/dhcpv6/dictionary.rfc3315
share/dictionary/dhcpv6/dictionary.rfc6355
src/lib/util/dict_tokenize.c
src/lib/util/dict_util.c
src/tests/unit/protocols/dhcpv6/server.txt [new file with mode: 0644]

index 2a9ff831b5c3631db0f354669d89fcaa87988e26..8c24d9ea4ed0a93b67208cd2bd19777df84170c6 100644 (file)
@@ -38,27 +38,10 @@ MEMBER              Hardware-Type                           uint16 key
 STRUCT Ethernet                        Hardware-Type           1
 MEMBER         Address                                 ether
 
-ATTRIBUTE      Server-ID                               2       struct
-MEMBER         DUID                                    uint16 key
-
-STRUCT LLT                             DUID                    1
-MEMBER         Hardware-Type                           uint16 key
-MEMBER         Time                                    date
-
-#  Sub-struct of Server-ID.LLT.Hardware-Type
-STRUCT Ethernet                        Hardware-Type           1
-MEMBER         Address                                 ether
-
-STRUCT EN                              DUID                    2
-MEMBER         Enterprise-Number                       uint32
-MEMBER         Identifier                              octets
-
-STRUCT LL                              DUID                    3
-MEMBER         Hardware-Type                           uint16 key
-
-#  Sub-struct of Server-ID.LL.Hardware-Type
-STRUCT Ethernet                        Hardware-Type           1
-MEMBER         Address                                 ether
+#
+#  Server-ID is a clone of Client-ID
+#
+ATTRIBUTE      Server-ID                               2       struct clone=Client-ID
 
 ATTRIBUTE      IA-NA                                   3       struct
 MEMBER         IAID                                    uint32
index eb57210bc2a8b5978c7ef06a40c1287908baee5f..88985854ae58a42141a834ee75d6097fa34e16da 100644 (file)
@@ -14,8 +14,6 @@ STRUCT        UUID                    Client-ID.DUID                  4
 MEMBER         Value                                   octets[16]
 
 #
-#  Duplicate sub-struct as the server cannot (yet) reference structs
+#  Defining DUID for the Client-ID will automatically
+#  clone that definition for Server-ID.  See dictionary.rfc3315
 #
-
-STRUCT UUID                    Server-ID.DUID                  4
-MEMBER         Value                                   octets[16]
index 93690babf4dacd4e7f40563f0e9aa2588a0ed9a6..aa97a47fc6d58c628acfe14fcc0e4fd7335abfdb 100644 (file)
@@ -518,7 +518,7 @@ static int dict_process_flag_field(dict_tokenize_ctx_t *ctx, char *name, fr_type
                                return -1;
                        }
 
-                       if (type != FR_TYPE_TLV) {
+                       if ((type != FR_TYPE_TLV) && (type != FR_TYPE_STRUCT)) {
                                fr_strerror_printf("The 'clone' flag cannot be used for type '%s'",
                                                   fr_table_str_by_value(fr_value_box_type_table, type, "<UNKNOWN>"));
                                return -1;
@@ -1759,8 +1759,12 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx)
                        da = dict_find_or_load_reference(&dict, fixup->ref, fixup->filename, fixup->line);
                        if (!da) return -1;
 
-                       if (da->type != FR_TYPE_TLV) {
-                               fr_strerror_printf("Clone references MUST be to attributes of type 'tlv' at %s[%d]",
+                       /*
+                        *      We can only clone attributes of the same data type.
+                        */
+                       if (da->type != fixup->da->type) {
+                               fr_strerror_printf("Clone references MUST be to attributes of type '%s' at %s[%d]",
+                                                  fr_table_str_by_value(fr_value_box_type_table, fixup->da->type, "<UNKNOWN>"),
                                                   fr_cwd_strip(fixup->filename), fixup->line);
                                return -1;
                        }
@@ -1782,7 +1786,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx)
                        }
 
                        cloned->attr = fixup->da->attr;
-                       cloned->parent = fixup->parent;
+                       cloned->parent = fixup->parent; /* we need to re-parent this attribute */
 
                        /*
                         *      Copy any pre-existing children over.
@@ -1795,7 +1799,7 @@ static int fr_dict_finalise(dict_tokenize_ctx_t *ctx)
                        }
 
                        if (dict_attr_acopy_children(dict, cloned, da) < 0) {
-                               fr_strerror_printf("Failed cloned attribute '%s' from children of %s", da->name, fixup->ref);
+                               fr_strerror_printf("Failed cloning attribute '%s' from children of %s", da->name, fixup->ref);
                                return -1;
                        }
 
index 7e63d9119189e5c78de1500232d55b42fafaee90..1b3258d96981940c7af582c39eebfebd2d694233 100644 (file)
@@ -728,9 +728,15 @@ int dict_attr_acopy_children(fr_dict_t *dict, fr_dict_attr_t *dst, fr_dict_attr_
        fr_dict_attr_t const *child = NULL;
        fr_dict_attr_t *copy;
 
-       if ((dst->type != FR_TYPE_TLV) && (dst->type != FR_TYPE_STRUCT)) return -1;
+       if ((dst->type != FR_TYPE_TLV) && (dst->type != FR_TYPE_STRUCT) && !fr_dict_attr_is_key_field(src)) {
+               fr_strerror_printf_push("Invalid destination type %s",
+                                       fr_table_str_by_value(fr_value_box_type_table, dst->type, "<UNKNOWN>"));
+               return -1;
+       }
 
        fr_assert(fr_dict_attr_has_ext(dst, FR_DICT_ATTR_EXT_CHILDREN));
+       fr_assert(dst->type == src->type);
+       fr_assert(fr_dict_attr_is_key_field(src) == fr_dict_attr_is_key_field(dst));
 
        for (child = fr_dict_attr_iterate_children(src, &child);
             child != NULL;
diff --git a/src/tests/unit/protocols/dhcpv6/server.txt b/src/tests/unit/protocols/dhcpv6/server.txt
new file mode 100644 (file)
index 0000000..c8a0e73
--- /dev/null
@@ -0,0 +1,24 @@
+#  -*- 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
+
+encode-pair Client-ID.DUID = UUID, Client-ID.DUID.UUID.Value = 0x000100012750f52702420a0000090000
+match 00 01 00 12 00 04 00 01 00 01 27 50 f5 27 02 42 0a 00 00 09 00 00
+
+decode-pair -
+match Client-ID.DUID = UUID, Client-ID.DUID.UUID.Value = 0x000100012750f52702420a0000090000
+
+encode-pair Server-ID.DUID = UUID, Server-ID.DUID.UUID.Value = 0x000100012750f52702420a0000090000
+match 00 02 00 12 00 04 00 01 00 01 27 50 f5 27 02 42 0a 00 00 09 00 00
+
+decode-pair -
+match Server-ID.DUID = UUID, Server-ID.DUID.UUID.Value = 0x000100012750f52702420a0000090000
+
+count
+match 10