/*
* Get the right list in the specified context
*/
- list_head = tmpl_list_head(request, tmpl_list(vpt));
- if (!list_head) {
- if (err) {
- *err = -2;
+ if (!vpt->rules.list_as_attr) {
+ list_head = tmpl_list_head(request, tmpl_list(vpt));
+ if (!list_head) {
fr_strerror_printf("List \"%s\" not available in this context",
fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
+ goto error;
}
- goto error;
+ list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
+ } else {
+ list_head = &request->pair_root->vp_group;
+ list_ctx = request->pair_root;
}
- list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
/*
* Initialise the temporary cursor context
}
}
- /*
- * Get the right list in the specified context
- */
- list_head = tmpl_list_head(request, tmpl_list(vpt));
- if (!list_head) {
- fr_strerror_printf("List \"%s\" not available in this context",
- fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
- return -2;
+ if (!vpt->rules.list_as_attr) {
+ /*
+ * Get the right list in the specified context
+ */
+ list_head = tmpl_list_head(request, tmpl_list(vpt));
+ if (!list_head) {
+ fr_strerror_printf("List \"%s\" not available in this context",
+ fr_table_str_by_value(pair_list_table, tmpl_list(vpt), "<INVALID>"));
+ return -2;
+ }
+ list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
+ } else {
+ list_head = &request->pair_root->vp_group;
+ list_ctx = request->pair_root;
}
- list_ctx = tmpl_list_ctx(request, tmpl_list(vpt));
/*
* If it's a list, just return the list head
* later.
*/
if (tmpl_is_attr(vpt) && is_raw) tmpl_attr_to_raw(vpt);
+
+ /*
+ * Check to see what the first attribute reference
+ * was. If it wasn't a known list group attribute
+ * and we're parsing in list_as_attr mode, then
+ * we need to add in a default list.
+ */
+ if (t_rules->list_as_attr) {
+ tmpl_attr_t *ar;
+
+ ar = fr_dlist_head(&vpt->data.attribute.ar);
+ fr_assert(ar != NULL);
+
+ if ((ar->ar_type != TMPL_ATTR_TYPE_NORMAL) ||
+ ((ar->ar_da != request_attr_request) &&
+ (ar->ar_da != request_attr_reply) &&
+ (ar->ar_da != request_attr_control) &&
+ (ar->ar_da != request_attr_state))) {
+ MEM(ar = talloc(vpt, tmpl_attr_t));
+ *ar = (tmpl_attr_t){
+ .ar_type = TMPL_ATTR_TYPE_NORMAL,
+ .ar_parent = fr_dict_root(fr_dict_internal())
+ };
+
+ switch (t_rules->list_def) {
+ default:
+ case PAIR_LIST_REQUEST:
+ ar->ar_da = request_attr_request;
+ break;
+
+ case PAIR_LIST_REPLY:
+ ar->ar_da = request_attr_reply;
+ break;
+
+ case PAIR_LIST_CONTROL:
+ ar->ar_da = request_attr_control;
+ break;
+
+ case PAIR_LIST_STATE:
+ ar->ar_da = request_attr_state;
+ break;
+ }
+
+ /*
+ * Prepend the list ref so it gets evaluated
+ * first.
+ */
+ fr_dlist_insert_head(&vpt->data.attribute.ar, ar);
+ }
+ }
}
/*