From: Arran Cudbard-Bell Date: Sat, 10 May 2025 19:57:34 +0000 (-0600) Subject: Start simplifying rcode handling X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e22d64beb27b810a7b0a45f3e9ab2c6e91359bcd;p=thirdparty%2Ffreeradius-server.git Start simplifying rcode handling --- diff --git a/src/lib/unlang/call.c b/src/lib/unlang/call.c index 2a3915e37e7..d72b057d199 100644 --- a/src/lib/unlang/call.c +++ b/src/lib/unlang/call.c @@ -24,6 +24,7 @@ */ RCSID("$Id$") +#include #include #include @@ -57,7 +58,7 @@ static unlang_action_t unlang_call_children(rlm_rcode_t *p_result, request_t *re * Push the contents of the call { } section onto the stack. * This gets executed after the server returns. */ - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } diff --git a/src/lib/unlang/catch.c b/src/lib/unlang/catch.c index 7c23080f3bb..9c4b350c7a4 100644 --- a/src/lib/unlang/catch.c +++ b/src/lib/unlang/catch.c @@ -24,6 +24,7 @@ */ RCSID("$Id$") +#include #include "unlang_priv.h" #include "catch_priv.h" @@ -57,7 +58,7 @@ static unlang_action_t unlang_catch(rlm_rcode_t *p_result, request_t *request, u */ frame_repeat(frame, catch_skip_to_next); - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } diff --git a/src/lib/unlang/child_request.c b/src/lib/unlang/child_request.c index bea7c6cf3a5..c68c09a706e 100644 --- a/src/lib/unlang/child_request.c +++ b/src/lib/unlang/child_request.c @@ -125,7 +125,7 @@ static void unlang_child_request_signal(request_t *request, UNUSED unlang_stack_ * the child is done executing, it runs this to inform the parent * that its done. */ -static unlang_action_t unlang_child_request_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) +static unlang_action_t unlang_child_request_done(UNUSED rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) { unlang_frame_state_child_request_t *state = talloc_get_type_abort(frame->state, unlang_frame_state_child_request_t); unlang_child_request_t *cr = state->cr; /* Can't use talloc_get_type_abort, may be an array element */ @@ -154,8 +154,8 @@ static unlang_action_t unlang_child_request_done(rlm_rcode_t *p_result, request_ * child be used to control the rcode of * the parallel keyword. */ - cr->result.rcode = *p_result; - cr->result.priority = frame->priority; + cr->result.rcode = frame->result.rcode; + cr->result.priority = frame->result.priority; if (cr->result.p_result) *(cr->result.p_result) = cr->result.rcode; break; @@ -302,7 +302,7 @@ int unlang_child_request_op_init(void) * to end normally so that non-detachable requests are * guaranteed the parent still exists. */ - .flag = UNLANG_OP_FLAG_NO_CANCEL, + .flag = UNLANG_OP_FLAG_NO_FORCE_UNWIND, .frame_state_size = sizeof(unlang_frame_state_child_request_t), .frame_state_type = "unlang_frame_state_child_request_t" }); diff --git a/src/lib/unlang/edit.c b/src/lib/unlang/edit.c index 00f2e3c7030..8f16b476375 100644 --- a/src/lib/unlang/edit.c +++ b/src/lib/unlang/edit.c @@ -1631,7 +1631,6 @@ static unlang_action_t process_edit(rlm_rcode_t *p_result, request_t *request, u RINDENT_RESTORE(request, state); - *p_result = RLM_MODULE_NOOP; if (state->success) *state->success = true; return UNLANG_ACTION_CALCULATE_RESULT; } diff --git a/src/lib/unlang/finally.c b/src/lib/unlang/finally.c index 1307234c2c5..f172e99b72d 100644 --- a/src/lib/unlang/finally.c +++ b/src/lib/unlang/finally.c @@ -162,7 +162,7 @@ void unlang_finally_init(void) &(unlang_op_t){ .name = "finally", .interpret = unlang_finally, - .flag = UNLANG_OP_FLAG_NO_CANCEL, /* No debug braces, the thing that's pushed in unlang finally should have braces */ + .flag = UNLANG_OP_FLAG_NO_FORCE_UNWIND, /* No debug braces, the thing that's pushed in unlang finally should have braces */ .frame_state_size = sizeof(unlang_frame_state_finally_t), .frame_state_type = "unlang_frame_state_finally_t", }); diff --git a/src/lib/unlang/foreach.c b/src/lib/unlang/foreach.c index 681d4443f8e..4e6a021eccc 100644 --- a/src/lib/unlang/foreach.c +++ b/src/lib/unlang/foreach.c @@ -25,6 +25,9 @@ RCSID("$Id$") #include +#include +#include +#include #include #include "foreach_priv.h" @@ -182,10 +185,7 @@ next: state->index++; box = fr_dcursor_next(&state->cursor); - if (!box) { - *p_result = frame->result; - return UNLANG_ACTION_CALCULATE_RESULT; - } + if (!box) return UNLANG_ACTION_EXECUTE_NEXT; /* Don't change the section rcode */ if (unlang_foreach_xlat_key_update(request, state) < 0) goto next; @@ -200,7 +200,7 @@ next: /* * Push the child, and yield for a later return. */ - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } @@ -233,13 +233,12 @@ next: goto next; } - frame->process = unlang_foreach_xlat_next; - repeatable_set(frame); + frame_repeat(frame, unlang_foreach_xlat_next); /* * Push the child, and yield for a later return. */ - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } @@ -324,11 +323,10 @@ static unlang_action_t unlang_foreach_attr_next(rlm_rcode_t *p_result, request_t next: vp = fr_dcursor_next(&state->cursor); if (!vp) { - *p_result = frame->result; #ifndef NDEBUG fr_assert(state->indent == request->log.indent.unlang); #endif - return UNLANG_ACTION_CALCULATE_RESULT; + return UNLANG_ACTION_EXECUTE_NEXT; } unlang_foreach_attr_key_update(request, state); @@ -375,7 +373,7 @@ next: /* * Push the child, and yield for a later return. */ - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } /* @@ -435,9 +433,8 @@ next: vp = fr_dcursor_next(&state->cursor); if (vp) goto next; - *p_result = frame->result; fr_assert(state->indent == request->log.indent.unlang); - return UNLANG_ACTION_CALCULATE_RESULT; + return UNLANG_ACTION_EXECUTE_NEXT; } if (unlang_foreach_pair_copy(state->value, vp, vp->da) < 0) { @@ -469,7 +466,7 @@ next: /* * Push the child, and go process it. */ - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } @@ -535,7 +532,13 @@ static unlang_action_t unlang_break(rlm_rcode_t *p_result, request_t *request, u RDEBUG2("%s", unlang_ops[frame->instruction->type].name); - *p_result = frame->result; + /* + * As we're unwinding intermediary frames we + * won't be taking their rcodes or priorities + * into account. We do however want to record + * the current section rcode. + */ + *p_result = frame->result.rcode; /* * Stop at the next break point, or if we hit diff --git a/src/lib/unlang/function.c b/src/lib/unlang/function.c index 4ed3886cde6..f7a69698234 100644 --- a/src/lib/unlang/function.c +++ b/src/lib/unlang/function.c @@ -94,7 +94,12 @@ static unlang_action_t unlang_function_call_repeat(rlm_rcode_t *p_result, reques caller = request->module; request->module = NULL; RDEBUG4("Calling repeat function %p (%s)", state->repeat, state->repeat_name); - ua = state->repeat(p_result, &frame->priority, request, state->uctx); + + /* + * FIXME: The full scratch rcode/priority should be passed in + * and then passed to this function. + */ + ua = state->repeat(p_result, &frame->result.priority, request, state->uctx); request->module = caller; return ua; @@ -120,7 +125,7 @@ static unlang_action_t unlang_function_call(rlm_rcode_t *p_result, request_t *re request->module = NULL; RDEBUG4("Calling function %p (%s)", state->func, state->func_name); - ua = state->func(p_result, &frame->priority, request, state->uctx); + ua = state->func(p_result, &frame->result.priority, request, state->uctx); switch (ua) { case UNLANG_ACTION_STOP_PROCESSING: break; diff --git a/src/lib/unlang/group.c b/src/lib/unlang/group.c index 2ce631989a6..fb317f49486 100644 --- a/src/lib/unlang/group.c +++ b/src/lib/unlang/group.c @@ -24,12 +24,13 @@ */ RCSID("$Id$") +#include #include "unlang_priv.h" #include "group_priv.h" -unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) +unlang_action_t unlang_group(rlm_rcode_t *p_result, request_t *request, UNUSED unlang_stack_frame_t *frame) { - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } static unlang_action_t unlang_policy(rlm_rcode_t *result, request_t *request, unlang_stack_frame_t *frame) diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index 818a9e05769..28a76f345c4 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -30,6 +30,7 @@ RCSID("$Id$") #include #include #include +#include #include "interpret_priv.h" #include "unlang_priv.h" @@ -87,8 +88,8 @@ static void frame_dump(request_t *request, unlang_stack_frame_t *frame) } else { RDEBUG2("next "); } - RDEBUG2("result %s", fr_table_str_by_value(mod_rcode_table, frame->result, "")); - RDEBUG2("priority %d", frame->priority); + RDEBUG2("rcode %s", fr_table_str_by_value(mod_rcode_table, frame->result.rcode, "")); + RDEBUG2("priority %d", frame->result.priority); RDEBUG2("top_frame %s", is_top_frame(frame) ? "yes" : "no"); RDEBUG2("repeat %s", is_repeatable(frame) ? "yes" : "no"); RDEBUG2("resumable %s", is_yielded(frame) ? "yes" : "no"); @@ -185,8 +186,8 @@ int unlang_interpret_push(request_t *request, unlang_t const *instruction, frame->flag = UNLANG_FRAME_FLAG_NONE; if (top_frame) top_frame_set(frame); - frame->result = default_rcode; - frame->priority = -1; + frame->result.rcode = default_rcode; + frame->result.priority = MOD_ACTION_NOT_SET; frame->indent = request->log.indent; if (!instruction) return 0; @@ -291,24 +292,20 @@ unlang_action_t unlang_interpret_push_children(UNUSED rlm_rcode_t *p_result, req static void instruction_retry_handler(UNUSED fr_timer_list_t *tl, UNUSED fr_time_t now, void *ctx); /** Update the current result after each instruction, and after popping each stack frame - * * * @note When called in frame_eval, result and priority are the frame * - * @param[in] request The current request. - * @param[in] frame The current stack frame. - * @param[in,out] result The current section or stack result. - * @param[in,out] priority The current section or stack priority. + * @param[in] request The current request. * @return * - UNLANG_FRAME_ACTION_NEXT evaluate more instructions. * - UNLANG_FRAME_ACTION_POP the final result has been calculated for this frame. */ static inline CC_HINT(always_inline) -unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t *frame, - rlm_rcode_t *result, unlang_mod_action_t *priority) +unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t *frame, unlang_result_t *result) { unlang_t const *instruction = frame->instruction; unlang_stack_t *stack = request->stack; + unlang_result_t *frame_result = &frame->result; if (is_unwinding(frame)) { RDEBUG4("** [%i] %s - unwinding frame", stack->depth, __FUNCTION__); @@ -319,7 +316,7 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t * Don't calculate a new return code for the frame, just skip * to the next instruction. */ - if (*result == RLM_MODULE_NOT_SET) { + if (result->rcode == RLM_MODULE_NOT_SET) { RDEBUG4("** [%i] %s - skipping frame, no result set", stack->depth, __FUNCTION__); return UNLANG_FRAME_ACTION_NEXT; @@ -327,10 +324,10 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t RDEBUG4("** [%i] %s - have (%s %d) module returned (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, frame->result, ""), - frame->priority, - fr_table_str_by_value(mod_rcode_table, *result, ""), - *priority); + fr_table_str_by_value(mod_rcode_table, frame_result->rcode, ""), + frame_result->priority, + fr_table_str_by_value(mod_rcode_table, result->rcode, ""), + result->priority); /* * Update request->rcode if the instruction says we should @@ -339,10 +336,34 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t * This is the field that's evaluated in unlang conditions * like `if (ok)`. */ - if (is_rcode_set(frame)) { + if (frame->instruction && is_rcode_set(frame)) { RDEBUG3("Setting rcode to '%s'", - fr_table_str_by_value(rcode_table, *result, "")); - request->rcode = *result; + fr_table_str_by_value(rcode_table, result->rcode, "")); + request->rcode = result->rcode; + } + + /* + * Sometimes we don't want the rcode from one frame to + * propogate to the next, like when process modules push + * sections onto the stack for evaluation. + */ + if (!process_rcode(frame)) { + RDEBUG4("** [%i] %s - no rcode set, skipping frame", + stack->depth, __FUNCTION__); + return UNLANG_FRAME_ACTION_NEXT; + } + + /* + * The array holds a default priority for this return + * code. Grab it in preference to any unset priority. + */ + if (result->priority == MOD_ACTION_NOT_SET) { + result->priority = instruction->actions.actions[result->rcode]; + + RDEBUG4("** [%i] %s - using default instruction priority for %s, %d", + stack->depth, __FUNCTION__, + fr_table_str_by_value(mod_rcode_table, result->rcode, ""), + result->priority); } /* @@ -350,20 +371,20 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t * to do something in addition to modifying the frame's * rcode. */ - switch (instruction->actions.actions[*result]) { + switch (result->priority) { /* * The child's prioriy value indicates we * should return from this frame. */ case MOD_ACTION_RETURN: - if (*priority < 0) *priority = 0; - RDEBUG4("** [%i] %s - action says to return with (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, *result, ""), - *priority); - frame->result = *result; - frame->priority = *priority; + fr_table_str_by_value(mod_rcode_table, result->rcode, ""), + result->priority); + + frame_result->priority = 0; + frame_result->rcode = result->rcode; + return UNLANG_FRAME_ACTION_POP; /* @@ -376,14 +397,14 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t * after the module returns... */ case MOD_ACTION_REJECT: - if (*priority < 0) *priority = 0; - RDEBUG4("** [%i] %s - action says to return with (%s %d)", stack->depth, __FUNCTION__, fr_table_str_by_value(mod_rcode_table, RLM_MODULE_REJECT, ""), - *priority); - frame->result = RLM_MODULE_REJECT; - frame->priority = *priority; + result->priority); + + frame_result->priority = 0; + frame_result->rcode = RLM_MODULE_REJECT; + return UNLANG_FRAME_ACTION_POP; case MOD_ACTION_RETRY: @@ -393,8 +414,6 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t RDEBUG4("** [%i] %s - action says to retry with", stack->depth, __FUNCTION__); - if (*priority < 0) *priority = 0; - /* * If this is the first time doing the retry, * then allocate the structure and set the timer. @@ -418,7 +437,7 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t if (fr_timer_in(retry, unlang_interpret_event_list(request)->tl, &retry->ev, instruction->actions.retry.mrd, false, instruction_retry_handler, request) < 0) { RPEDEBUG("Failed inserting retry event"); - *result = RLM_MODULE_FAIL; + frame_result->rcode = RLM_MODULE_FAIL; goto finalize; } } @@ -442,7 +461,7 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t REDEBUG("Retries hit max_rtx_count (%u) - returning 'timeout'", instruction->actions.retry.mrc); timeout: - *result = RLM_MODULE_TIMEOUT; + frame_result->rcode = RLM_MODULE_TIMEOUT; goto finalize; } } @@ -467,30 +486,17 @@ unlang_frame_action_t result_calculate(request_t *request, unlang_stack_frame_t finalize: /* - * The array holds a default priority for this return - * code. Grab it in preference to any unset priority. - */ - if (*priority < 0) { - *priority = instruction->actions.actions[*result]; - - RDEBUG4("** [%i] %s - setting priority to (%s %d)", - stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, *result, ""), - *priority); - } - - /* - * We're higher than any previous priority, remember this + * We're higher or equal to previous priority, remember this * return code and priority. */ - if (*priority > frame->priority) { - frame->result = *result; - frame->priority = *priority; - - RDEBUG4("** [%i] %s - over-riding result from higher priority to (%s %d)", + if (result->priority > frame_result->priority) { + RDEBUG4("** [%i] %s - overwriting existing result (%s %d) with higher priority (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, *result, ""), - *priority); + fr_table_str_by_value(mod_rcode_table, frame_result->rcode, ""), + frame_result->priority, + fr_table_str_by_value(mod_rcode_table, result->rcode, ""), + result->priority); + frame->result = *result; } /* @@ -507,10 +513,8 @@ finalize: * * This function can be seen as moving horizontally. * - * @param[in] request The current request. - * @param[in] frame The current stack frame. - * @param[in,out] result The current section result. - * @param[in,out] priority The current section priority. + * @param[in] request The current request. + * @param[in] frame The current stack frame. * @return * - UNLANG_FRAME_ACTION_NEXT evaluate more instructions in the current stack frame * which may not be the same frame as when this function @@ -518,9 +522,15 @@ finalize: * - UNLANG_FRAME_ACTION_POP the final result has been calculated for this frame. */ static inline CC_HINT(always_inline) -unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame, rlm_rcode_t *result, int *priority) +unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame) { unlang_stack_t *stack = request->stack; + unlang_result_t *scratch = &stack->scratch; + +#define RESULT_RESET(_scratch) do { \ + (_scratch)->rcode = RLM_MODULE_NOT_SET; \ + (_scratch)->priority = MOD_ACTION_NOT_SET; \ +} while (0); /* * Loop over all the instructions in this list. @@ -599,13 +609,14 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame * after this point, and the cached instruction * should be used instead. */ - ua = frame->process(result, request, frame); + ua = frame->process(&scratch->rcode, request, frame); - RDEBUG4("** [%i] %s << %s (%d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(unlang_action_table, ua, ""), *priority); + RDEBUG4("** [%i] %s << %s (%s %d)", stack->depth, __FUNCTION__, + fr_table_str_by_value(unlang_action_table, ua, ""), + fr_table_str_by_value(mod_rcode_table, scratch->rcode, ""), scratch->priority); - fr_assert(*priority >= -1); - fr_assert(*priority <= MOD_PRIORITY_MAX); + fr_assert(scratch->priority >= MOD_ACTION_NOT_SET); + fr_assert(scratch->priority <= MOD_PRIORITY_MAX); /* * If the frame is cancelled we ignore the @@ -624,6 +635,7 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame * and starts popping them. */ unlang_interpret_signal(request, FR_SIGNAL_CANCEL); + RESULT_RESET(scratch); return UNLANG_FRAME_ACTION_POP; /* @@ -637,7 +649,7 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame "but stack depth was not increased", instruction->name); unlang_frame_perf_yield(frame); - *result = frame->result; + RESULT_RESET(scratch); return UNLANG_FRAME_ACTION_NEXT; /* @@ -652,8 +664,8 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame unlang_frame_perf_yield(frame); yielded_set(frame); RDEBUG4("** [%i] %s - yielding with current (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, frame->result, ""), - frame->priority); + fr_table_str_by_value(mod_rcode_table, scratch->rcode, ""), + scratch->priority); DUMP_STACK; return UNLANG_FRAME_ACTION_YIELD; @@ -662,7 +674,7 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame * functions. It reduces boilerplate. */ case UNLANG_ACTION_FAIL: - *result = RLM_MODULE_FAIL; + frame->result.rcode = RLM_MODULE_FAIL; /* Let unlang_calculate figure out if this is the final result */ FALL_THROUGH; /* @@ -693,20 +705,20 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame */ if (RDEBUG_ENABLED && !RDEBUG_ENABLED2) { RDEBUG("# %s (%s)", instruction->debug_name, - fr_table_str_by_value(mod_rcode_table, *result, "")); + fr_table_str_by_value(mod_rcode_table, scratch->rcode, "")); } else { RDEBUG2("} # %s (%s)", instruction->debug_name, - fr_table_str_by_value(mod_rcode_table, *result, "")); + fr_table_str_by_value(mod_rcode_table, scratch->rcode, "")); } } + fa = result_calculate(request, frame, scratch); + /* - * RLM_MODULE_NOT_SET means the instruction - * doesn't want to modify the result. + * Scratch priority and rcode now consumed */ - if (*result != RLM_MODULE_NOT_SET) *priority = instruction->actions.actions[*result]; + RESULT_RESET(scratch); - fa = result_calculate(request, frame, result, priority); switch (fa) { case UNLANG_FRAME_ACTION_POP: goto pop; @@ -731,6 +743,11 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame REXDENT(); RDEBUG2("}"); } + + /* + * Scratch priority and rcode now discarded + */ + RESULT_RESET(scratch); break; } /* switch over return code from the interpret function */ @@ -740,8 +757,8 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame pop: RDEBUG4("** [%i] %s - done current subsection with (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, frame->result, ""), - frame->priority); + fr_table_str_by_value(mod_rcode_table, frame->result.rcode, ""), + frame->result.priority); return UNLANG_FRAME_ACTION_POP; } @@ -758,8 +775,6 @@ pop: */ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) { - rlm_rcode_t rcode; - /* * We don't have a return code yet. */ @@ -775,8 +790,6 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) */ unlang_frame_action_t fa = is_unwinding(frame) ? UNLANG_FRAME_ACTION_POP : UNLANG_FRAME_ACTION_NEXT; - stack->priority = -1; /* Reset */ - #ifndef NDEBUG if (DEBUG_ENABLED5) DEBUG("###### unlang_interpret is starting"); DUMP_STACK; @@ -797,20 +810,15 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) switch (fa) { case UNLANG_FRAME_ACTION_NEXT: /* Evaluate the current frame */ frame = &stack->frame[stack->depth]; - fa = frame_eval(request, frame, &stack->result, &stack->priority); + fa = frame_eval(request, frame); if (fa != UNLANG_FRAME_ACTION_POP) continue; FALL_THROUGH; - case UNLANG_FRAME_ACTION_POP: /* Pop this frame and check the one beneath it */ + case UNLANG_FRAME_ACTION_POP: /* Pop this frame and check the one beneath it */ { bool top_frame = is_top_frame(frame); - /* - * The result / priority is returned from the sub-section, - * and made into our current result / priority, as - * if we had performed a module call. - */ - stack->result = frame->result; - stack->priority = frame->priority; + + unlang_result_t section_result = frame->result; /* record the result of the frame before we pop it*/ /* * Head on back up the stack @@ -818,20 +826,33 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) frame_pop(request, stack); /* - * Transition back to the C stack + * Update the stack frame */ - if (top_frame) break; /* stop */ - frame = &stack->frame[stack->depth]; DUMP_STACK; + /* + * Transition back to the C stack + * + * We still need to merge in the previous frame's result, + * but we don't care about the action, as we're returning. + */ + if (top_frame) { + (void)result_calculate(request, frame, §ion_result); + break; /* stop */ + } + /* * Resume a "foreach" loop, or a "load-balance" section * or anything else that needs to be checked on the way * back on up the stack. */ - if (!is_unwinding(frame) && is_repeatable(frame)) { + (void)result_calculate(request, frame, §ion_result); + RDEBUG4("** [%i] %s - repeating frame with (%s %d)", + stack->depth, __FUNCTION__, + fr_table_str_by_value(mod_rcode_table, frame->result.rcode, ""), + frame->result.priority); fa = UNLANG_FRAME_ACTION_NEXT; continue; } @@ -848,14 +869,14 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) */ if (RDEBUG_ENABLED && !RDEBUG_ENABLED2) { RDEBUG("# %s (%s)", frame->instruction->debug_name, - fr_table_str_by_value(mod_rcode_table, stack->result, "")); + fr_table_str_by_value(mod_rcode_table, section_result.rcode, "")); } else { RDEBUG2("} # %s (%s)", frame->instruction->debug_name, - fr_table_str_by_value(mod_rcode_table, stack->result, "")); + fr_table_str_by_value(mod_rcode_table, section_result.rcode, "")); } } - fa = result_calculate(request, frame, &stack->result, &stack->priority); + fa = result_calculate(request, frame, §ion_result); /* * If we're continuing after popping a frame @@ -865,8 +886,8 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) if (fa == UNLANG_FRAME_ACTION_NEXT) { RDEBUG4("** [%i] %s - continuing after subsection with (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, stack->result, ""), - stack->priority); + fr_table_str_by_value(mod_rcode_table, frame->result.rcode, ""), + frame->result.priority); frame_next(stack, frame); /* @@ -876,8 +897,8 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) } else { RDEBUG4("** [%i] %s - done current subsection with (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, frame->result, ""), - frame->priority); + fr_table_str_by_value(mod_rcode_table, frame->result.rcode, ""), + frame->result.priority); } continue; } @@ -888,7 +909,7 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) RDEBUG4("** [%i] %s - interpret yielding", stack->depth, __FUNCTION__); intp->funcs.yield(request, intp->uctx); - return stack->result; + return RLM_MODULE_NOT_SET; case UNLANG_FRAME_ACTION_RETRY: /* retry the current frame */ fa = UNLANG_FRAME_ACTION_NEXT; @@ -899,50 +920,31 @@ CC_HINT(hot) rlm_rcode_t unlang_interpret(request_t *request, bool running) fr_assert(stack->depth >= 0); - /* - * Nothing in this section, use the top frame stack->result. - */ - if ((stack->priority < 0) || (stack->result == RLM_MODULE_NOT_SET)) { - RDEBUG4("** [%i] %s - empty section, using stack result (%s %d)", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, stack->result, ""), stack->priority); - stack->result = frame->result; - stack->priority = frame->priority; - } - - if (stack->priority > frame->priority) { - frame->result = stack->result; - frame->priority = stack->priority; - - RDEBUG4("** [%i] %s - over-riding stack->result from higher priority to (%s %d)", - stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, stack->result, ""), - stack->priority); - } - /* * We're at the top frame, return the result from the * stack, and get rid of the top frame. */ RDEBUG4("** [%i] %s - interpret exiting, returning %s", stack->depth, __FUNCTION__, - fr_table_str_by_value(mod_rcode_table, frame->result, "")); - - stack->result = frame->result; + fr_table_str_by_value(mod_rcode_table, frame->result.rcode, "")); DUMP_STACK; - /* - * Record this now as the done functions may free - * the request. - */ - rcode = stack->result; + { + rlm_rcode_t rcode; + /* + * Record this now as the done functions may free + * the request. + */ + rcode = frame->result.rcode; - /* - * This usually means the request is complete in its - * entirety. - */ - if ((stack->depth == 0) && !running) unlang_interpret_request_done(request); + /* + * This usually means the request is complete in its + * entirety. + */ + if ((stack->depth == 0) && !running) unlang_interpret_request_done(request); - return rcode; + return rcode; + } } static unlang_group_t empty_group = { @@ -1041,7 +1043,8 @@ void *unlang_interpret_stack_alloc(TALLOC_CTX *ctx) * like too low level to make into a tuneable. */ MEM(stack = talloc_zero_pooled_object(ctx, unlang_stack_t, UNLANG_STACK_MAX, 128)); /* 128 bytes per state */ - stack->result = RLM_MODULE_NOT_SET; + stack->scratch.rcode = RLM_MODULE_NOT_SET; + stack->scratch.priority = MOD_ACTION_NOT_SET; return stack; } @@ -1061,15 +1064,15 @@ void unlang_interpret_request_done(request_t *request) request->master_state = REQUEST_DONE; switch (request->type) { case REQUEST_TYPE_EXTERNAL: - intp->funcs.done_external(request, stack->result, intp->uctx); + intp->funcs.done_external(request, frame_current(request)->result.rcode, intp->uctx); break; case REQUEST_TYPE_INTERNAL: - intp->funcs.done_internal(request, stack->result, intp->uctx); + intp->funcs.done_internal(request, frame_current(request)->result.rcode, intp->uctx); break; case REQUEST_TYPE_DETACHED: - intp->funcs.done_detached(request, stack->result, intp->uctx); /* Callback will usually free the request */ + intp->funcs.done_detached(request, frame_current(request)->result.rcode, intp->uctx); /* Callback will usually free the request */ break; } } @@ -1336,9 +1339,7 @@ int unlang_interpret_stack_depth(request_t *request) */ rlm_rcode_t unlang_interpret_stack_result(request_t *request) { - unlang_stack_t *stack = request->stack; - - return stack->result; + return frame_current(request)->result.rcode; } /** Overwrite the current stack rcode @@ -1348,9 +1349,7 @@ rlm_rcode_t unlang_interpret_stack_result(request_t *request) */ void unlang_interpret_stack_result_set(request_t *request, rlm_rcode_t rcode) { - unlang_stack_t *stack = request->stack; - - stack->result = rcode; + frame_current(request)->result.rcode = rcode; } /** Return whether a request is currently scheduled diff --git a/src/lib/unlang/limit.c b/src/lib/unlang/limit.c index 877c9c8dc5b..9b95242c933 100644 --- a/src/lib/unlang/limit.c +++ b/src/lib/unlang/limit.c @@ -24,6 +24,7 @@ */ RCSID("$Id$") +#include #include "group_priv.h" #include "limit_priv.h" @@ -75,7 +76,7 @@ static unlang_action_t unlang_limit_enforce(rlm_rcode_t *p_result, request_t *re frame_repeat(frame, unlang_limit_resume_done); - action = unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_STOP); + action = unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_STOP); state->thread->active_callers += (action == UNLANG_ACTION_PUSHED_CHILD); diff --git a/src/lib/unlang/load_balance.c b/src/lib/unlang/load_balance.c index 5ad345fcc44..68fb0028a7f 100644 --- a/src/lib/unlang/load_balance.c +++ b/src/lib/unlang/load_balance.c @@ -22,6 +22,7 @@ * * @copyright 2006-2019 The FreeRADIUS server project */ +#include #include #include @@ -81,7 +82,7 @@ static unlang_action_t unlang_load_balance_next(rlm_rcode_t *p_result, request_t /* * Push the child, and yield for a later return. */ - if (unlang_interpret_push(request, redundant->child, frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { + if (unlang_interpret_push(request, redundant->child, RLM_MODULE_NOT_SET, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { return UNLANG_ACTION_STOP_PROCESSING; } @@ -228,7 +229,7 @@ static unlang_action_t unlang_load_balance(rlm_rcode_t *p_result, request_t *req */ if (frame->instruction->type == UNLANG_TYPE_LOAD_BALANCE) { if (unlang_interpret_push(request, redundant->found, - frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { + RLM_MODULE_NOT_SET, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { return UNLANG_ACTION_STOP_PROCESSING; } return UNLANG_ACTION_PUSHED_CHILD; diff --git a/src/lib/unlang/mod_action.h b/src/lib/unlang/mod_action.h index ac78e6c39cd..a9df7162a5c 100644 --- a/src/lib/unlang/mod_action.h +++ b/src/lib/unlang/mod_action.h @@ -37,9 +37,11 @@ extern "C" { * There's also the keyword "reject", represented here by MOD_ACTION_REJECT * to cause an immediate reject. */ typedef enum { - MOD_ACTION_RETURN = -1, - MOD_ACTION_REJECT = -2, + MOD_ACTION_NOT_SET = -4, MOD_ACTION_RETRY = -3, + MOD_ACTION_REJECT = -2, + MOD_ACTION_RETURN = -1, + MOD_PRIORITY_MIN = 0, MOD_PRIORITY_1 = 1, diff --git a/src/lib/unlang/module.c b/src/lib/unlang/module.c index 5b50d837676..05f2c0d9811 100644 --- a/src/lib/unlang/module.c +++ b/src/lib/unlang/module.c @@ -264,7 +264,7 @@ unlang_action_t unlang_module_yield_to_section(rlm_rcode_t *p_result, * frame->result will be overwritten * anyway when we return. */ - stack->result = frame->result = default_rcode; + *p_result = default_rcode; state = talloc_get_type_abort(frame->state, unlang_frame_state_module_t); return resume(p_result, diff --git a/src/lib/unlang/parallel.c b/src/lib/unlang/parallel.c index c8efa28e763..62269bcc77b 100644 --- a/src/lib/unlang/parallel.c +++ b/src/lib/unlang/parallel.c @@ -140,6 +140,8 @@ static unlang_action_t unlang_parallel_resume(rlm_rcode_t *p_result, request_t * fr_assert(state->num_runnable == 0); for (i = 0; i < state->num_children; i++) { + unlang_stack_frame_t *child_frame; + if (state->children[i].state != CHILD_EXITED) continue; REQUEST_VERIFY(state->children[i].request); @@ -150,8 +152,10 @@ static unlang_action_t unlang_parallel_resume(rlm_rcode_t *p_result, request_t * state->children[i].state = CHILD_DONE; - priority = ((unlang_stack_t *)state->children[i].request->stack)->priority; - result = ((unlang_stack_t *)state->children[i].request->stack)->result; + child_frame = frame_current(state->children[i].request); + + priority = child_frame->result.priority; + result = child_frame->result.rcode; /* * Return isn't allowed to make it back @@ -390,6 +394,6 @@ void unlang_parallel_init(void) .name = "parallel", .interpret = unlang_parallel, .signal = unlang_parallel_signal, - .flag = UNLANG_OP_FLAG_DEBUG_BRACES | UNLANG_OP_FLAG_RCODE_SET | UNLANG_OP_FLAG_NO_CANCEL + .flag = UNLANG_OP_FLAG_DEBUG_BRACES | UNLANG_OP_FLAG_RCODE_SET | UNLANG_OP_FLAG_NO_FORCE_UNWIND }); } diff --git a/src/lib/unlang/return.c b/src/lib/unlang/return.c index 2bb9e011083..9a5cbf3e0f6 100644 --- a/src/lib/unlang/return.c +++ b/src/lib/unlang/return.c @@ -31,7 +31,13 @@ unlang_action_t unlang_return(rlm_rcode_t *p_result, request_t *request, unlang_ { RDEBUG2("%s", unlang_ops[frame->instruction->type].name); - *p_result = frame->result; + /* + * As we're unwinding intermediary frames we + * won't be taking their rcodes or priorities + * into account. We do however want to record + * the current section rcode. + */ + *p_result = frame->result.rcode; /* * Stop at the next return point, or if we hit diff --git a/src/lib/unlang/subrequest.c b/src/lib/unlang/subrequest.c index 06fb3ba4fa9..5fcb1745109 100644 --- a/src/lib/unlang/subrequest.c +++ b/src/lib/unlang/subrequest.c @@ -28,6 +28,7 @@ RCSID("$Id$") #include #include #include +#include #include #include "unlang_priv.h" #include "interpret_priv.h" @@ -119,8 +120,11 @@ static unlang_action_t unlang_subrequest_parent_resume(rlm_rcode_t *p_result, re RDEBUG3("subrequest completeed with rcode %s", fr_table_str_by_value(mod_rcode_table, cr->result.rcode, "")); + /* + * FIXME - We should pass in priority + */ *p_result = cr->result.rcode; - frame->priority = cr->result.priority; + frame->result.priority = cr->result.priority; /* * If there's a no destination tmpl, we're done. @@ -263,7 +267,7 @@ static unlang_action_t unlang_subrequest_init(rlm_rcode_t *p_result, request_t * * Push the first instruction the child's * going to run. */ - if (unlang_interpret_push(child, g->children, frame->result, + if (unlang_interpret_push(child, g->children, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING, UNLANG_SUB_FRAME) < 0) goto fail; /* @@ -320,7 +324,7 @@ static unlang_action_t unlang_subrequest_child_done(rlm_rcode_t *p_result, UNUSE } if (cr->result.p_result) *cr->result.p_result = cr->result.rcode; - cr->result.priority = frame->priority; + cr->result.priority = frame->result.priority; /* * We can free the child here as we're its parent @@ -531,7 +535,7 @@ int unlang_subrequest_op_init(void) * to end normally so that non-detachable requests are * guaranteed the parent still exists. */ - .flag = UNLANG_OP_FLAG_DEBUG_BRACES | UNLANG_OP_FLAG_RCODE_SET | UNLANG_OP_FLAG_NO_CANCEL, + .flag = UNLANG_OP_FLAG_DEBUG_BRACES | UNLANG_OP_FLAG_RCODE_SET | UNLANG_OP_FLAG_NO_FORCE_UNWIND, .frame_state_size = sizeof(unlang_child_request_t), .frame_state_type = "unlang_child_request_t", }); diff --git a/src/lib/unlang/switch.c b/src/lib/unlang/switch.c index 21eb6e388e1..2d1739eee36 100644 --- a/src/lib/unlang/switch.c +++ b/src/lib/unlang/switch.c @@ -24,6 +24,7 @@ */ RCSID("$Id$") +#include #include "group_priv.h" #include "switch_priv.h" @@ -110,7 +111,7 @@ do_null_case: */ if (!found) return UNLANG_ACTION_EXECUTE_NEXT; - if (unlang_interpret_push(request, found, frame->result, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { + if (unlang_interpret_push(request, found, RLM_MODULE_NOT_SET, UNLANG_NEXT_STOP, UNLANG_SUB_FRAME) < 0) { return UNLANG_ACTION_STOP_PROCESSING; } diff --git a/src/lib/unlang/timeout.c b/src/lib/unlang/timeout.c index d9e6b6e2f65..c4af970979b 100644 --- a/src/lib/unlang/timeout.c +++ b/src/lib/unlang/timeout.c @@ -134,7 +134,7 @@ static unlang_action_t unlang_timeout_set(rlm_rcode_t *p_result, request_t *requ frame_repeat(frame, unlang_timeout_resume_done); - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } static unlang_action_t unlang_timeout_done(rlm_rcode_t *p_result, request_t *request, unlang_stack_frame_t *frame) diff --git a/src/lib/unlang/transaction.c b/src/lib/unlang/transaction.c index 6b2fe61966b..98e232a0045 100644 --- a/src/lib/unlang/transaction.c +++ b/src/lib/unlang/transaction.c @@ -94,7 +94,7 @@ static unlang_action_t unlang_transaction(rlm_rcode_t *p_result, request_t *requ frame_repeat(frame, unlang_transaction_final); - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } fr_edit_list_t *unlang_interpret_edit_list(request_t *request) diff --git a/src/lib/unlang/try.c b/src/lib/unlang/try.c index 69d2ee5f85a..a1d22cd7b13 100644 --- a/src/lib/unlang/try.c +++ b/src/lib/unlang/try.c @@ -36,7 +36,7 @@ static unlang_action_t unlang_try(rlm_rcode_t *p_result, request_t *request, unl */ frame_repeat(frame, unlang_interpret_skip_to_catch); - return unlang_interpret_push_children(p_result, request, frame->result, UNLANG_NEXT_SIBLING); + return unlang_interpret_push_children(p_result, request, RLM_MODULE_NOT_SET, UNLANG_NEXT_SIBLING); } void unlang_try_init(void) diff --git a/src/lib/unlang/unlang_priv.h b/src/lib/unlang/unlang_priv.h index 6821cec7182..617028d2f6e 100644 --- a/src/lib/unlang/unlang_priv.h +++ b/src/lib/unlang/unlang_priv.h @@ -216,18 +216,18 @@ typedef int (*unlang_thread_instantiate_t)(unlang_t const *instruction, void *th DIAG_OFF(attributes) typedef enum CC_HINT(flag_enum) { - UNLANG_OP_FLAG_NONE = 0x00, //!< No flags. - UNLANG_OP_FLAG_DEBUG_BRACES = 0x01, //!< Print debug braces. - UNLANG_OP_FLAG_RCODE_SET = 0x02, //!< Set request->rcode to the result of this operation. - UNLANG_OP_FLAG_NO_CANCEL = 0x04, //!< Must not be cancelled. - ///< @Note Slightly confusingly, a cancellation signal - ///< can still be delivered to a frame that is not - ///< cancellable, but the frame won't be automatically - ///< unwound. This lets the frame know that cancellation - ///< is desired, but can be ignored. - UNLANG_OP_FLAG_BREAK_POINT = 0x08, //!< Break point. - UNLANG_OP_FLAG_RETURN_POINT = 0x10, //!< Return point. - UNLANG_OP_FLAG_CONTINUE_POINT = 0x20 //!< Continue point. + UNLANG_OP_FLAG_NONE = 0x00, //!< No flags. + UNLANG_OP_FLAG_DEBUG_BRACES = 0x01, //!< Print debug braces. + UNLANG_OP_FLAG_RCODE_SET = 0x02, //!< Set request->rcode to the result of this operation. + UNLANG_OP_FLAG_NO_FORCE_UNWIND = 0x04, //!< Must not be cancelled. + ///< @Note Slightly confusingly, a cancellation signal + ///< can still be delivered to a frame that is not + ///< cancellable, but the frame won't be automatically + ///< unwound. This lets the frame know that cancellation + ///< is desired, but can be ignored. + UNLANG_OP_FLAG_BREAK_POINT = 0x08, //!< Break point. + UNLANG_OP_FLAG_RETURN_POINT = 0x10, //!< Return point. + UNLANG_OP_FLAG_CONTINUE_POINT = 0x20 //!< Continue point. } unlang_op_flag_t; DIAG_ON(attributes) @@ -295,6 +295,12 @@ typedef struct { fr_timer_t *ev; } unlang_retry_t; +typedef struct { + rlm_rcode_t rcode; //!< The current rcode, from executing the instruction + ///< or merging the result from a frame. + unlang_mod_action_t priority; //!< The priority or action for that rcode. +} unlang_result_t; + /** Our interpreter stack, as distinct from the C stack * * We don't call the modules recursively. Instead we iterate over a list of #unlang_t and @@ -325,13 +331,16 @@ struct unlang_stack_frame_s { */ void *state; + /** Running priority and rcode associated with the stack + * + * If this frame is cancelled, the rcode and priority are not merged into + * the frame above and are discarded. + */ + unlang_result_t result; + unlang_retry_t *retry; //!< if the frame is being retried. - rlm_rcode_t result; //!< The result from executing the instruction. - unlang_mod_action_t priority; //!< Result priority. When we pop this stack frame - ///< this priority will be compared with the one of the - ///< frame lower in the stack to determine if the - ///< result stored in the lower stack frame should + rindent_t indent; //!< Indent level of the request when the frame was ///< created. This is used to restore the indent ///< level when the stack is being forcefully unwound. @@ -348,8 +357,15 @@ struct unlang_stack_frame_s { typedef struct { unlang_interpret_t *intp; //!< Interpreter that the request is currently ///< associated with. - unlang_mod_action_t priority; //!< Current priority. - rlm_rcode_t result; //!< The current stack rcode. + + unlang_result_t scratch; //!< This holds the current rcode and + ///< priority for the current instruction. + ///< It's located in the stack struct because + ///< we only need it for the current frame + ///< executing, and we need it to persist + ///< across yields. It should be reset for + ///< each new instruction executed. + int depth; //!< Current depth we're executing at. uint8_t unwind; //!< Unwind to this frame if it exists. ///< This is used for break and return. @@ -390,7 +406,7 @@ static inline bool _frame_has_debug_braces(unlang_stack_frame_t const *frame) { unlang_stack_frame_t const *: _frame_has_debug_braces((unlang_stack_frame_t const *)(_thing)) \ ) static inline bool is_rcode_set(unlang_stack_frame_t const *frame) { return unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_RCODE_SET; } -static inline bool is_cancellable(unlang_stack_frame_t const *frame) { return !(unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_NO_CANCEL); } +static inline bool is_cancellable(unlang_stack_frame_t const *frame) { return !(unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_NO_FORCE_UNWIND); } static inline bool is_break_point(unlang_stack_frame_t const *frame) { return unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_BREAK_POINT; } static inline bool is_return_point(unlang_stack_frame_t const *frame) { return unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_RETURN_POINT; } static inline bool is_continue_point(unlang_stack_frame_t const *frame) { return unlang_ops[frame->instruction->type].flag & UNLANG_OP_FLAG_CONTINUE_POINT; } diff --git a/src/process/radius/base.c b/src/process/radius/base.c index 4255bd4f98e..66745869d06 100644 --- a/src/process/radius/base.c +++ b/src/process/radius/base.c @@ -459,7 +459,7 @@ RESUME(auth_type) [RLM_MODULE_DISALLOW] = FR_RADIUS_CODE_ACCESS_REJECT, }; - rlm_rcode_t rcode = *p_result; + rlm_rcode_t rcode = unlang_interpret_stack_result(request); fr_pair_t *vp; fr_process_state_t const *state;