27 RCSIDH(call_env_h,
"$Id: 66b26b226152c7e6f6263e4a974dfe25eeb95b82 $")
33 #include <freeradius-devel/util/dlist.h>
41 FR_DLIST_TYPEDEFS(call_env_parsed, call_env_parsed_head_t, call_env_parsed_entry_t)
43 #include <freeradius-devel/unlang/action.h>
44 #include <freeradius-devel/server/cf_parse.h>
45 #include <freeradius-devel/server/dl_module.h>
46 #include <freeradius-devel/server/request.h>
47 #include <freeradius-devel/server/tmpl.h>
71 typedef enum CC_HINT(flag_enum) {
101 #define call_env_pair_flags(_flags) (((_flags) & (CALL_ENV_FLAG_SUBSECTION)) == 0)
107 #define call_env_subsection_flags(_flags) (((_flags) & (CALL_ENV_FLAG_CONCAT | CALL_ENV_FLAG_SINGLE | CALL_ENV_FLAG_MULTI | CALL_ENV_FLAG_NULLABLE | CALL_ENV_FLAG_FORCE_QUOTE | CALL_ENV_FLAG_ATTRIBUTE | CALL_ENV_FLAG_PARSE_MISSING)) == 0)
109 #define call_env_required(_flags) ((_flags) & CALL_ENV_FLAG_REQUIRED)
111 #define call_env_concat(_flags) ((_flags) & CALL_ENV_FLAG_CONCAT)
113 #define call_env_single(_flags) ((_flags) & CALL_ENV_FLAG_SINGLE)
115 #define call_env_multi(_flags) ((_flags) & CALL_ENV_FLAG_MULTI)
117 #define call_env_nullable(_flags) ((_flags) & CALL_ENV_FLAG_NULLABLE)
119 #define call_env_force_quote(_flags) ((_flags) & CALL_ENV_FLAG_FORCE_QUOTE)
121 #define call_env_parse_only(_flags) ((_flags) & CALL_ENV_FLAG_PARSE_ONLY)
123 #define call_env_attribute(_flags) ((_flags) & CALL_ENV_FLAG_ATTRIBUTE)
125 #define call_env_is_subsection(_flags) ((_flags) & CALL_ENV_FLAG_SUBSECTION)
127 #define call_env_parse_missing(_flags) ((_flags) & CALL_ENV_FLAG_PARSE_MISSING)
129 #define call_env_secret(_flags) ((_flags) & CALL_ENV_FLAG_SECRET)
181 char const *type_name;
212 #define CALL_ENV_TERMINATOR { NULL }
216 #define FR_CALL_ENV_METHOD_OUT(_inst) \
217 .inst_size = sizeof(_inst), \
218 .inst_type = STRINGIFY(_inst) \
235 #define CALL_ENV_PARSE_TYPE(_s, _f) \
236 _Generic((((_s *)NULL)->_f), \
237 tmpl_t const * : CALL_ENV_PARSE_TYPE_TMPL, \
238 tmpl_t * : CALL_ENV_PARSE_TYPE_TMPL, \
239 fr_value_box_t const * : CALL_ENV_PARSE_TYPE_VALUE_BOX, \
240 fr_value_box_t * : CALL_ENV_PARSE_TYPE_VALUE_BOX, \
241 default : CALL_ENV_PARSE_TYPE_VOID \
246 #define FR_CALL_ENV_SINGLE(_s, _f, _c) \
247 _Generic((((_s *)NULL)->_f), \
248 fr_value_box_t : __builtin_choose_expr(_c, CALL_ENV_FLAG_NONE, CALL_ENV_FLAG_SINGLE), \
249 fr_value_box_t * : __builtin_choose_expr(_c, CALL_ENV_FLAG_NONE, CALL_ENV_FLAG_SINGLE), \
250 fr_value_box_list_t : CALL_ENV_FLAG_NONE, \
251 fr_value_box_list_t * : CALL_ENV_FLAG_NONE, \
252 default : CALL_ENV_FLAG_NONE \
257 #define FR_CALL_ENV_MULTI(_s, _f) \
258 _Generic((((_s *)NULL)->_f), \
259 fr_value_box_t : CALL_ENV_FLAG_NONE, \
260 fr_value_box_t * : CALL_ENV_FLAG_MULTI, \
261 fr_value_box_list_t : CALL_ENV_FLAG_NONE, \
262 fr_value_box_list_t * : CALL_ENV_FLAG_MULTI \
267 #define FR_CALL_ENV_CONCAT(_c, _ct) \
268 __builtin_choose_expr(_ct == FR_TYPE_STRING, _c, \
269 __builtin_choose_expr(_ct == FR_TYPE_OCTETS, _c, \
270 __builtin_choose_expr(_c, (void)0, false)))
274 #define FR_CALL_ENV_DST_TYPE(_s, _f) \
275 _Generic((((_s *)NULL)->_f), \
276 fr_value_box_t : CALL_ENV_RESULT_TYPE_VALUE_BOX, \
277 fr_value_box_t * : CALL_ENV_RESULT_TYPE_VALUE_BOX, \
278 fr_value_box_list_t : CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST, \
279 fr_value_box_list_t * : CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST \
282 #define FR_CALL_ENV_DST_SIZE(_s, _f) \
283 _Generic((((_s *)NULL)->_f), \
284 fr_value_box_t : sizeof(fr_value_box_t), \
285 fr_value_box_t * : sizeof(fr_value_box_t), \
286 fr_value_box_list_t : sizeof(fr_value_box_list_t), \
287 fr_value_box_list_t * : sizeof(fr_value_box_list_t), \
291 #define FR_CALL_ENV_RESULT_TYPE_NAME(_s, _f) \
292 _Generic((((_s *)NULL)->_f), \
293 fr_value_box_t : "fr_value_box_t", \
294 fr_value_box_t * : "fr_value_box_t", \
295 fr_value_box_list_t : "fr_value_box_list_t", \
296 fr_value_box_list_t * : "fr_value_box_list_t", \
302 #define CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field) \
303 (FR_CALL_ENV_CONCAT(((_flags) & CALL_ENV_FLAG_CONCAT), _cast_type) | \
304 FR_CALL_ENV_SINGLE(_struct, _field, ((_flags) & CALL_ENV_FLAG_CONCAT)) | \
305 FR_CALL_ENV_MULTI(_struct, _field) |\
306 ((_flags) & ~CALL_ENV_FLAG_CONCAT)) \
316 #define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field) \
318 .flags = CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field), \
320 .cast_type = _cast_type, \
321 .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
322 .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
323 .type_name = FR_CALL_ENV_RESULT_TYPE_NAME(_struct, _field), \
324 .offset = offsetof(_struct, _field), \
327 .type = CALL_ENV_PARSE_TYPE_TMPL \
341 #define FR_CALL_ENV_PARSE_OFFSET(_name, _cast_type, _flags, _struct, _field, _parse_field) \
343 .flags = CALL_ENV_FLAGS(_cast_type, _flags, _struct, _field), \
345 .cast_type = _cast_type, \
346 .type = FR_CALL_ENV_DST_TYPE(_struct, _field), \
347 .size = FR_CALL_ENV_DST_SIZE(_struct, _field), \
348 .type_name = FR_CALL_ENV_RESULT_TYPE_NAME(_struct, _field), \
349 .offset = offsetof(_struct, _field), \
351 .offset = offsetof(_struct, _parse_field), \
352 .type = CALL_ENV_PARSE_TYPE(_struct, _parse_field) \
365 #define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field) \
367 .flags = (_flags) | CALL_ENV_FLAG_PARSE_ONLY, \
369 .cast_type = _cast_type, \
371 .offset = offsetof(_struct, _parse_field), \
372 .type = CALL_ENV_PARSE_TYPE(_struct, _parse_field) \
378 #define FR_CALL_ENV_SUBSECTION(_name, _ident2, _flags, _subcs ) \
380 .flags = CALL_ENV_FLAG_SUBSECTION | (_flags), \
388 #define FR_CALL_ENV_SUBSECTION_FUNC(_name, _ident2, _flags, _func) \
390 .flags = CALL_ENV_FLAG_SUBSECTION | (_flags), \
430 char const *section_name2,
void const *
data) CC_HINT(
nonnull(3,4,5));
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
call_env_flags_t flags
Flags controlling parser behaviour.
void call_env_parsed_free(call_env_parsed_head_t *parsed, call_env_parsed_t *ptr)
Remove a call_env_parsed_t from the list of parsed call envs.
char const * name
Of conf pair to pass to tmpl_tokenizer.
unlang_action_t call_env_expand(TALLOC_CTX *ctx, request_t *request, call_env_result_t *result, void **env_data, call_env_t const *call_env)
Initialise the expansion of a call environment.
int(* call_env_parse_pair_t)(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, char const *section_name1, char const *section_name2, void const *data, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_PAIR.
call_env_result_type_t
What type of structure is produced by the evaluation phase.
@ CALL_ENV_RESULT_TYPE_VALUE_BOX_LIST
Output of the evaluation phase is a list of value boxes.
@ CALL_ENV_RESULT_TYPE_VALUE_BOX
Output of the evaluation phase is a single value box.
size_t inst_size
Size of per call env.
call_env_parsed_t * call_env_parsed_add(TALLOC_CTX *ctx, call_env_parsed_head_t *head, call_env_parser_t const *rule)
Allocate a new call_env_parsed_t structure and add it to the list of parsed call envs.
call_env_parser_t const * env
Parsing rules for call method env.
void const * uctx
User context for callback functions.
void call_env_parsed_set_multi_index(call_env_parsed_t *parsed, size_t count, size_t index)
Assign a count and index to a call_env_parsed_t.
char const * inst_type
Type of per call env.
void _mismatch_flags
Dummy type used to indicate bad flags.
int call_env_parse_pair(TALLOC_CTX *ctx, void *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, char const *section_name1, char const *section_name2, void const *data, call_env_parser_t const *rule)
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
@ CALL_ENV_FLAG_SUBSECTION
This is a subsection.
@ CALL_ENV_FLAG_SINGLE
If the tmpl produces more than one box this is an error.
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl must contain an attribute reference.
@ CALL_ENV_FLAG_FORCE_QUOTE
Force quote method when parsing tmpl.
@ CALL_ENV_FLAG_PARSE_ONLY
The result of parsing will not be evaluated at runtime.
@ CALL_ENV_FLAG_SECRET
The value is a secret, and should not be logged.
@ CALL_ENV_FLAG_MULTI
Multiple instances of the conf pairs are allowed.
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
@ CALL_ENV_FLAG_PARSE_MISSING
If this subsection is missing, still parse it.
@ CALL_ENV_FLAG_NULLABLE
Tmpl expansions are allowed to produce no output.
int(* call_env_parse_section_t)(TALLOC_CTX *ctx, call_env_parsed_head_t *out, tmpl_rules_t const *t_rules, CONF_ITEM *ci, char const *section_name1, char const *section_name2, void const *data, call_env_parser_t const *rule)
Callback for performing custom parsing of a CONF_SECTION.
void call_env_parsed_set_data(call_env_parsed_t *parsed, void const *data)
Assign data to a call_env_parsed_t.
call_env_parsed_head_t parsed
The per call parsed call environment.
call_env_parse_type_t
What type of structure is produced by the parsing phase.
@ CALL_ENV_PARSE_TYPE_VALUE_BOX
Output of the parsing phase is a single value box (static data).
@ CALL_ENV_PARSE_TYPE_TMPL
Output of the parsing phase is a tmpl_t.
@ CALL_ENV_PARSE_TYPE_VOID
Output of the parsing phase is undefined (a custom structure).
void call_env_parsed_set_value(call_env_parsed_t *parsed, fr_value_box_t const *vb)
Assign a value box to a call_env_parsed_t.
call_env_method_t const * method
The method this call env is for.
void call_env_parsed_set_tmpl(call_env_parsed_t *parsed, tmpl_t const *tmpl)
Assign a tmpl to a call_env_parsed_t.
call_env_t * call_env_alloc(TALLOC_CTX *ctx, char const *name, call_env_method_t const *call_env_method, tmpl_rules_t const *rules, CONF_SECTION *cs, char const *section_name1, char const *section_name2, void const *data))
Given a call_env_method, parse all call_env_pair_t in the context of a specific call to an xlat or mo...
Structure containing both a talloc pool, a list of parsed call_env_pairs.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
#define FR_DLIST_TYPES(_name)
Define type specific wrapper structs for dlists.
#define FR_DLIST_TYPEDEFS(_name, _head, _entry)
Define friendly names for type specific dlist head and entry structures.
Optional arguments passed to vp_tmpl functions.
fr_aka_sim_id_type_t type
Escaping rules for tmpls.
Boxed value structures and functions to manipulate them.
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
static size_t char ** out