and add API to see if the dictionaries are compatible.
Because we can no longer depend on comparing pointers
* |_ RADIUS attribute
*/
if (found_in != fr_dict_internal() &&
- !at_rules->allow_foreign && (found_in != fr_dict_by_da(our_parent))) {
+ !at_rules->allow_foreign && !fr_dict_compatible(found_in, fr_dict_by_da(our_parent))) {
fr_strerror_printf("Foreign %s attribute found. Only %s attributes are allowed here",
fr_dict_root(found_in)->name,
fr_dict_root(dict_def)->name);
*/
if (mrlm->dict && *mrlm->dict && unlang_ctx->rules && unlang_ctx->rules->attr.dict_def &&
(unlang_ctx->rules->attr.dict_def != fr_dict_internal()) &&
- (*(mrlm->dict) != unlang_ctx->rules->attr.dict_def)) {
- cf_log_err(ci, "The \"%s\" module can only used with 'namespace = %s'. It cannot be used with 'namespace = %s'.",
+ !fr_dict_compatible(*(mrlm->dict), unlang_ctx->rules->attr.dict_def)) {
+ cf_log_err(ci, "The \"%s\" module can only be used with 'namespace = %s'. It cannot be used with 'namespace = %s'.",
inst->module->name,
fr_dict_root(*mrlm->dict)->name,
fr_dict_root(unlang_ctx->rules->attr.dict_def)->name);
fr_dict_t const *fr_dict_by_attr_name(fr_dict_attr_t const **found, char const *name);
+bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2) CC_HINT(nonnull);
+
/** Return true if this attribute is parented directly off the dictionary root
*
* @param[in] da to check.
fr_hash_table_t *autoref; //!< other dictionaries that we loaded via references
+ fr_dict_t const *next; //!< for attribute overloading
+
fr_table_num_ordered_t const *subtype_table; //!< table of subtypes for this protocol
size_t subtype_table_len; //!< length of table of subtypes for this protocol
return dict_by_da(da);
}
+/** See if two dictionaries have the same end parent
+ *
+ * @param[in] dict1 one dictionary
+ * @param[in] dict2 two dictionary
+ * @return
+ * - true the dictionaries have the same end parent
+ * - false the dictionaries do not have the same end parent.
+ */
+bool fr_dict_compatible(fr_dict_t const *dict1, fr_dict_t const *dict2)
+{
+ while (dict1->next) dict1 = dict1->next;
+
+ while (dict2->next) dict2 = dict2->next;
+
+ return (dict1 == dict2);
+}
+
/** Look up a vendor by one of its child attributes
*
* @param[in] da The vendor attribute.