From: Alan T. DeKok Date: Fri, 11 Jul 2025 23:05:05 +0000 (-0400) Subject: move redundant to its own function X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=01165b739811b203ab8da00c10c20e91430d58f8;p=thirdparty%2Ffreeradius-server.git move redundant to its own function it's not really a group. Instead, it should share the redundancy functionality of redundant-load-balance --- diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index fe1de147b8..b87356dc26 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -499,31 +499,6 @@ static void compile_set_default_actions(unlang_t *c, unlang_compile_ctx_t *unlan * the retries to apply only to the _current_ section. */ - /* - * Children of "redundant" and "redundant-load-balance" - * have RETURN for all actions except fail. But THEIR children are normal. - */ - if (c->parent && - ((c->parent->type == UNLANG_TYPE_REDUNDANT) || - (c->parent->type == UNLANG_TYPE_REDUNDANT_LOAD_BALANCE))) { - for (i = 0; i < RLM_MODULE_NUMCODES; i++) { - switch (i) { - case RLM_MODULE_FAIL: - case RLM_MODULE_TIMEOUT: - if (!c->actions.actions[i]) { - c->actions.actions[i] = 1; - } - continue; - - default: - if (!c->actions.actions[i]) c->actions.actions[i] = MOD_ACTION_RETURN; - break; - } - } - - return; - } - /* * Set the default actions if they haven't already been * set. diff --git a/src/lib/unlang/group.c b/src/lib/unlang/group.c index ee000c5b28..8576f4d671 100644 --- a/src/lib/unlang/group.c +++ b/src/lib/unlang/group.c @@ -46,24 +46,6 @@ static unlang_t *unlang_compile_group(unlang_t *parent, unlang_compile_ctx_t *un return unlang_compile_section(parent, unlang_ctx, cf_item_to_section(ci), UNLANG_TYPE_GROUP); } -static unlang_t *unlang_compile_redundant(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci) -{ - CONF_SECTION *cs = cf_item_to_section(ci); - - if (!cf_item_next(cs, NULL)) return UNLANG_IGNORE; - - if (!unlang_compile_limit_subsection(cs, cf_section_name1(cs))) { - return NULL; - } - - if (cf_section_name2(cs) != NULL) { - cf_log_warn(cs, "Ignoring name for 'redundant' section"); - } - - return unlang_compile_section(parent, unlang_ctx, cs, UNLANG_TYPE_REDUNDANT); -} - - void unlang_group_init(void) { unlang_register(&(unlang_op_t){ @@ -78,18 +60,6 @@ void unlang_group_init(void) .unlang_name = "unlang_group_t", }); - unlang_register(&(unlang_op_t){ - .name = "redundant", - .type = UNLANG_TYPE_REDUNDANT, - .flag = UNLANG_OP_FLAG_DEBUG_BRACES, - - .compile = unlang_compile_redundant, - .interpret = unlang_group, - - .unlang_size = sizeof(unlang_group_t), - .unlang_name = "unlang_group_t", - }); - unlang_register(&(unlang_op_t){ .name = "policy", .type = UNLANG_TYPE_POLICY, diff --git a/src/lib/unlang/load_balance.c b/src/lib/unlang/load_balance.c index 93a27d43d7..57d644dc01 100644 --- a/src/lib/unlang/load_balance.c +++ b/src/lib/unlang/load_balance.c @@ -47,11 +47,16 @@ static unlang_action_t unlang_load_balance_next(unlang_result_t *p_result, reque } /* - * We are in a resumed frame. Check if running the child resulting in an rcode that we can use. - * If so, stop. + * We are in a resumed frame. Check if running the child resulted in a failure rcode which + * requires us to keep going. If not, return to the caller. */ - if ((redundant->result.rcode != RLM_MODULE_NOT_SET) && - (redundant->child->actions.actions[redundant->result.rcode] == MOD_ACTION_RETURN)) { + switch (redundant->result.rcode) { + case RLM_MODULE_FAIL: + case RLM_MODULE_TIMEOUT: + case RLM_MODULE_NOT_SET: + break; + + default: if (p_result) { p_result->priority = MOD_PRIORITY_MIN; p_result->rcode = redundant->result.rcode; @@ -94,6 +99,21 @@ push: return UNLANG_ACTION_PUSHED_CHILD; } +static unlang_action_t unlang_redundant(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame) +{ + unlang_frame_state_redundant_t *redundant = talloc_get_type_abort(frame->state, + unlang_frame_state_redundant_t); + unlang_group_t *g = unlang_generic_to_group(frame->instruction); + + /* + * Start at the first child, and then continue from there. + */ + redundant->start = g->children; + + frame->process = unlang_load_balance_next; + return unlang_load_balance_next(p_result, request, frame); +} + static unlang_action_t unlang_load_balance(unlang_result_t *p_result, request_t *request, unlang_stack_frame_t *frame) { unlang_frame_state_redundant_t *redundant; @@ -307,47 +327,36 @@ static unlang_t *unlang_compile_load_balance(unlang_t *parent, unlang_compile_ct return compile_load_balance_subsection(parent, unlang_ctx, cf_item_to_section(ci), UNLANG_TYPE_LOAD_BALANCE); } -static void compile_redundant_actions(unlang_t *c) +static unlang_t *unlang_compile_redundant_load_balance(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci) { - int i; - unlang_group_t *g; - unlang_t *child; - unlang_mod_actions_t actions; + return compile_load_balance_subsection(parent, unlang_ctx, cf_item_to_section(ci), UNLANG_TYPE_REDUNDANT_LOAD_BALANCE); +} - /* - * Children of "redundant" and "redundant-load-balance" - * have RETURN for all actions except fail and timeout. - */ - for (i = 0; i < RLM_MODULE_NUMCODES; i++) { - switch (i) { - case RLM_MODULE_FAIL: - case RLM_MODULE_TIMEOUT: - actions.actions[i] = MOD_PRIORITY_MIN; - break; - default: - actions.actions[i] = MOD_ACTION_RETURN; - break; - } - } +static unlang_t *unlang_compile_redundant(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci) +{ + CONF_SECTION *cs = cf_item_to_section(ci); - g = unlang_generic_to_group(c); + if (!cf_item_next(cs, NULL)) return UNLANG_IGNORE; - for (child = g->children; child != NULL; child = child->next) { - child->actions = actions; + if (!unlang_compile_limit_subsection(cs, cf_section_name1(cs))) { + return NULL; } -} + /* + * "redundant foo" is allowed only inside of a "modules" section, where the name is the instance + * name. + * + * @todo - static versus dynamic modules? + */ -static unlang_t *unlang_compile_redundant_load_balance(unlang_t *parent, unlang_compile_ctx_t *unlang_ctx, CONF_ITEM const *ci) -{ - unlang_t *c; - - c = compile_load_balance_subsection(parent, unlang_ctx, cf_item_to_section(ci), UNLANG_TYPE_REDUNDANT_LOAD_BALANCE); - if (!c || (c == UNLANG_IGNORE)) return c; + if (cf_section_name2(cs) && + (strcmp(cf_section_name1(cf_item_to_section(cf_parent(cs))), "modules") != 0)) { + cf_log_err(cs, "Cannot specify a key for 'redundant'"); + return NULL; + } - compile_redundant_actions(c); - return c; + return unlang_compile_section(parent, unlang_ctx, cs, UNLANG_TYPE_REDUNDANT); } @@ -382,4 +391,20 @@ void unlang_load_balance_init(void) .frame_state_size = sizeof(unlang_frame_state_redundant_t), .frame_state_type = "unlang_frame_state_redundant_t", }); + + unlang_register(&(unlang_op_t){ + .name = "redundant", + .type = UNLANG_TYPE_REDUNDANT, + .flag = UNLANG_OP_FLAG_DEBUG_BRACES | UNLANG_OP_FLAG_RCODE_SET, + + .compile = unlang_compile_redundant, + .interpret = unlang_redundant, + + .unlang_size = sizeof(unlang_group_t), + .unlang_name = "unlang_group_t", + + .frame_state_size = sizeof(unlang_frame_state_redundant_t), + .frame_state_type = "unlang_frame_state_redundant_t", + }); + }