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
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
*/
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)) {