From: Alan T. DeKok Date: Fri, 4 Dec 2020 21:43:03 +0000 (-0500) Subject: copy keyed structures, and update DHCPv6 dict and tests X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c6f9592c5ce497276f898e2d790dd391b48ae1df;p=thirdparty%2Ffreeradius-server.git copy keyed structures, and update DHCPv6 dict and tests --- diff --git a/share/dictionary/dhcpv6/dictionary.rfc3315 b/share/dictionary/dhcpv6/dictionary.rfc3315 index 2a9ff831b5c..8c24d9ea4ed 100644 --- a/share/dictionary/dhcpv6/dictionary.rfc3315 +++ b/share/dictionary/dhcpv6/dictionary.rfc3315 @@ -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 diff --git a/share/dictionary/dhcpv6/dictionary.rfc6355 b/share/dictionary/dhcpv6/dictionary.rfc6355 index eb57210bc2a..88985854ae5 100644 --- a/share/dictionary/dhcpv6/dictionary.rfc6355 +++ b/share/dictionary/dhcpv6/dictionary.rfc6355 @@ -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] diff --git a/src/lib/util/dict_tokenize.c b/src/lib/util/dict_tokenize.c index 93690babf4d..aa97a47fc6d 100644 --- a/src/lib/util/dict_tokenize.c +++ b/src/lib/util/dict_tokenize.c @@ -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, "")); 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, ""), 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; } diff --git a/src/lib/util/dict_util.c b/src/lib/util/dict_util.c index 7e63d911918..1b3258d9698 100644 --- a/src/lib/util/dict_util.c +++ b/src/lib/util/dict_util.c @@ -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, "")); + 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 index 00000000000..c8a0e730f62 --- /dev/null +++ b/src/tests/unit/protocols/dhcpv6/server.txt @@ -0,0 +1,24 @@ +# -*- text -*- +# Copyright (C) 2019 Network RADIUS SARL +# 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