#include "call_priv.h"
-static unlang_action_t unlang_call_resume(rlm_rcode_t *p_result, request_t *request,
+static unlang_action_t unlang_call_resume(UNUSED rlm_rcode_t *p_result, request_t *request,
unlang_stack_frame_t *frame)
{
unlang_group_t *g = unlang_generic_to_group(frame->instruction);
&(unlang_op_t){
.name = "call",
.interpret = unlang_call_frame_init,
+ .rcode_set = true,
.debug_braces = true,
});
}
-
fr_value_box_list_init(&state->out);
- /*
- * Make the rcode available to the caller. Note that the caller can't call
- * unlang_interpret_stack_result(), as that returns the result from the xlat frame, and not from
- * the calling frame.
- */
- request->rcode = *p_result;
-
if (unlang_xlat_push(state, &state->success, &state->out,
request, gext->head, UNLANG_SUB_FRAME) < 0) return UNLANG_ACTION_FAIL;
fr_table_str_by_value(mod_rcode_table, *result, "<invalid>"),
*priority);
+ /*
+ * Update request->rcode if the instruction says we should
+ * We don't care about priorities for this.
+ */
+ if (unlang_ops[instruction->type].rcode_set) {
+ RDEBUG3("Setting rcode to '%s'",
+ fr_table_str_by_value(rcode_table, *result, "<INVALID>"));
+ request->rcode = *result;
+ }
+
/*
* Don't set action or priority if we don't have one.
*/
&(unlang_op_t){
.name = "load-balance group",
.interpret = unlang_load_balance,
+ .rcode_set = true,
.debug_braces = true,
.frame_state_size = sizeof(unlang_frame_state_redundant_t),
.frame_state_type = "unlang_frame_state_redundant_t",
&(unlang_op_t){
.name = "redundant-load-balance group",
.interpret = unlang_redundant_load_balance,
+ .rcode_set = true,
.debug_braces = true,
.frame_state_size = sizeof(unlang_frame_state_redundant_t),
.frame_state_type = "unlang_frame_state_redundant_t",
unlang_register(UNLANG_TYPE_MAP,
&(unlang_op_t){
.name = "map",
+ .rcode_set = true,
.interpret = unlang_map_state_init,
.frame_state_size = sizeof(unlang_frame_state_map_proc_t),
.frame_state_type = "unlang_frame_state_map_proc_t",
&(unlang_op_t){
.name = "module",
.interpret = unlang_module,
+ .rcode_set = true,
.signal = unlang_module_signal,
.frame_state_size = sizeof(unlang_frame_state_module_t),
.frame_state_type = "unlang_frame_state_module_t",
.name = "parallel",
.interpret = unlang_parallel,
.signal = unlang_parallel_signal,
+ .rcode_set = true,
.debug_braces = true
});
}
.name = "subrequest",
.interpret = unlang_subrequest_parent_init,
.signal = unlang_subrequest_signal_child,
+ .rcode_set = true,
.debug_braces = true,
.frame_state_size = sizeof(unlang_frame_state_subrequest_t),
.frame_state_type = "unlang_frame_state_subrequest_t",
bool debug_braces; //!< Whether the operation needs to print braces
///< in debug mode.
+ bool rcode_set; //!< Set request->rcode to the result of this operation.
+
size_t frame_state_size; //!< size of instance data in the stack frame
char const *frame_state_type; //!< talloc name of the frame instance data
--- /dev/null
+# PRE: if if-else
+
+# This is a regression test. We saw the request->rcode being lost after the first condition
+
+notfound
+if (ok || updated) {
+ test_fail
+} elsif (!notfound) {
+ test_fail
+}
+
+success
--- /dev/null
+
+# request->rcode is updated to the result of the subrequest section
+subrequest Access-Request {
+ ok {
+ ok = 10
+ }
+ noop {
+ fail = 1
+ }
+}
+
+if (ok) {
+ success
+} elsif (noop) {
+ test_fail
+}