25#include <freeradius-devel/server/rcode.h>
26#include <freeradius-devel/server/request_data.h>
27#include <freeradius-devel/util/hash.h>
28#include <freeradius-devel/util/rand.h>
47 if (!frame->
prev.frame_load_balance)
return 0;
51 frame = &
stack->frame[frame->
prev.frame_load_balance];
54 child = redundant->
child;
55 if (!child) child = redundant->
start;
71 if (!frame->
prev.frame_load_balance)
return 0;
75 frame = &
stack->frame[frame->
prev.frame_load_balance];
80 return redundant->
num;
83#define unlang_redundant_load_balance unlang_load_balance
95 if (!redundant->
child) {
124 if (!redundant->
child) {
135 if (p_result) *p_result = redundant->
result;
179#ifdef STATIC_ANALYZER
192 if (redundant->
start) {
198 for (i = 0; i < unlang_list_num_elements(&g->
children); i++) {
202 RDEBUG3(
"load-balance starting at child %u", redundant->
num);
217 num = unlang_list_num_elements(&g->
children);
227 REDEBUG(
"Failed finding attribute %s - choosing random statement", gext->
vpt->name);
228 goto randomly_choose;
238 REDEBUG(
"Failed expanding %s - choosing random statement", gext->
vpt->name);
239 goto randomly_choose;
246 if ((box->type ==
FR_TYPE_UINT8) && (box->vb_uint8 <= num)) {
247 start = box->vb_uint8;
253 RDEBUG3(
"load-balance starting at child %u", start);
256 redundant->
num = start;
269 }
while (two == one);
274 if (t1->active <= t2->active) {
280 RDEBUG3(
"load-balance starting at child %u", start);
282 redundant->
num = start;
401 switch (gext->
vpt->type) {
403 cf_log_err(cs,
"Invalid type in '%s': data will not result in a load-balance key", name2);
411 cf_log_err(cs,
"Invalid attribute reference in '%s': load-balancing can only be done on 'leaf' data types", name2);
425 cf_log_err(cs,
"Cannot use constant data for 'load-balance' statement");
475 cf_log_err(cs,
"Cannot specify a key for 'redundant'");
486 .name =
"load-balance",
494 .unlang_name =
"unlang_load_balance_t",
497 .frame_state_type =
"unlang_frame_state_redundant_t",
501 .name =
"redundant-load-balance",
509 .unlang_name =
"unlang_load_balance_t",
512 .frame_state_type =
"unlang_frame_state_redundant_t",
524 .unlang_name =
"unlang_group_t",
527 .frame_state_type =
"unlang_frame_state_redundant_t",
#define RETURN_UNLANG_ACTION_FATAL
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_PUSHED_CHILD
unlang_t pushed a new child onto the stack, execute it instead of continuing.
@ UNLANG_ACTION_FAIL
Encountered an unexpected error.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Common header for all CONF_* types.
A section grouping multiple CONF_PAIR.
fr_token_t cf_section_argv_quote(CONF_SECTION const *cs, int argc)
Return the quoting for one of the variadic arguments.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
CONF_ITEM * cf_section_to_item(CONF_SECTION const *cs)
Cast a CONF_SECTION to a CONF_ITEM.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the first identifier of a CONF_SECTION.
CONF_SECTION * cf_item_to_section(CONF_ITEM const *ci)
Cast a CONF_ITEM to a CONF_SECTION.
char const * cf_section_argv(CONF_SECTION const *cs, int argc)
Return variadic argument at the specified index.
fr_token_t cf_section_name2_quote(CONF_SECTION const *cs)
Return the quoting of the name2 identifier.
#define cf_log_err(_cf, _fmt,...)
#define cf_canonicalize_error(_ci, _slen, _msg, _str)
#define cf_item_next(_parent, _curr)
unlang_t * unlang_compile_section(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_SECTION *cs, unlang_type_t type)
bool pass2_fixup_tmpl(UNUSED TALLOC_CTX *ctx, tmpl_t **vpt_p, CONF_ITEM const *ci, fr_dict_t const *dict)
bool unlang_compile_limit_subsection(CONF_SECTION *cs, char const *name)
TALLOC_CTX * unlang_interpret_frame_talloc_ctx(request_t *request)
Get a talloc_ctx which is valid only for this frame.
unlang_thread_t const * unlang_thread_stats(unlang_t const *instruction)
int unlang_interpret_push(unlang_result_t *p_result, request_t *request, unlang_t const *instruction, unlang_frame_conf_t const *conf, bool do_next_sibling)
Push a new frame onto the stack.
unlang_mod_action_t priority
The priority or action for that rcode.
#define UNLANG_RESULT_NOT_SET
#define FRAME_CONF(_default_rcode, _top_frame)
rlm_rcode_t rcode
The current rcode, from executing the instruction or merging the result from a frame.
static TALLOC_CTX * unlang_ctx
void unlang_register(unlang_op_t *op)
Register an operation with the interpreter.
static char * stack[MAX_STACK]
static unlang_t * unlang_compile_redundant(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
static unlang_t * compile_load_balance_subsection(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_SECTION *cs, unlang_type_t type)
uint8_t unlang_load_balance_child(request_t *request)
Returns the current child of the load balance section.
void unlang_load_balance_init(void)
static unlang_action_t unlang_redundant(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
static unlang_t * unlang_compile_redundant_load_balance(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
static unlang_t * unlang_compile_load_balance(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci)
int unlang_load_balance_persist(request_t *request)
Persist the current load-balance selection.
static unlang_action_t unlang_load_balance(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
static unlang_action_t unlang_redundant_next(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame)
#define unlang_redundant_load_balance
tmpl_t * vpt
template to expand for keyed balancing
static unlang_load_balance_t * unlang_group_to_load_balance(unlang_group_t *g)
Cast a group structure to the load_balance keyword extension.
unlang_result_t result
for intermediate child results
uint32_t num
the current child number
unlang_t * child
the current child we're processing
unlang_t * start
the starting child
unlang_t ** children
array of child instructions.
State of a redundant operation.
@ FR_TYPE_VALUE_BOX
A boxed value.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
uint32_t fr_rand(void)
Return a 32-bit random number.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_TIMEOUT
Module (or section) timed out.
@ RLM_MODULE_NOT_SET
Error resolving rcode (should not be returned by modules).
void * request_data_get(request_t *request, void const *unique_ptr, int unique_int)
Get opaque data from a request.
#define request_data_add_const(_request, _unique_ptr, _unique_int, _opaque, _persist)
Add const opaque data to a request_t.
#define FR_SBUFF_IN_STR(_start)
int tmpl_find_vp(fr_pair_t **out, request_t *request, tmpl_t const *vpt))
Returns the first VP matching a tmpl_t.
#define tmpl_is_attr(vpt)
@ TMPL_TYPE_ATTR
Reference to one or more attributes.
@ TMPL_TYPE_XLAT
Pre-parsed xlat expansion.
ssize_t tmpl_afrom_substr(TALLOC_CTX *ctx, tmpl_t **out, fr_sbuff_t *in, fr_token_t quote, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules))
Convert an arbitrary string into a tmpl_t.
#define tmpl_aexpand_type(_ctx, _out, _type, _request, _vpt)
Expand a tmpl to a C type, allocing a new buffer to hold the string.
tmpl_attr_rules_t attr
Rules/data for parsing attribute references.
static fr_dict_attr_t const * tmpl_attr_tail_da(tmpl_t const *vpt)
Return the last attribute reference da.
Optional arguments passed to vp_tmpl functions.
fr_aka_sim_id_type_t type
unsigned int allow_unknown
Allow unknown attributes i.e.
Stores an attribute, a value and various bits of other data.
unsigned int constant
xlat is just tmpl_attr_tail_data, or XLAT_BOX
Private interpreter structures and functions.
#define RULES_VERIFY(_rules)
void * state
Stack frame specialisations.
struct unlang_stack_frame_s::@126 prev
#define unlang_list_foreach(_list_head, _iter)
static unlang_group_t * unlang_generic_to_group(unlang_t const *p)
char const * name
Unknown...
unlang_type_t
Types of unlang_t nodes.
@ UNLANG_TYPE_LOAD_BALANCE
Load balance section.
@ UNLANG_TYPE_REDUNDANT
exactly like group, but with different default return codes
@ UNLANG_TYPE_REDUNDANT_LOAD_BALANCE
Redundant load balance section.
unlang_t const * instruction
The unlang node we're evaluating.
@ UNLANG_OP_FLAG_DEBUG_BRACES
Print debug braces.
@ UNLANG_OP_FLAG_RCODE_SET
Set request->rcode to the result of this operation.
static void repeatable_set(unlang_stack_frame_t *frame)
unlang_process_t process
function to call for interpreting this stack frame
unlang_type_t type
The specialisation of this node.
Generic representation of a grouping.
A node in a graph of unlang_op_t (s) that we execute.
Our interpreter stack, as distinct from the C stack.
An unlang stack associated with a request.
#define fr_type_is_leaf(_x)
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
String expansion ("translation").
xlat_flags_t flags
Flags that control resolution and evaluation.