static bool modcall_recurse(REQUEST *request, rlm_components_t component, int depth,
- modcall_stack_entry_t *entry);
+ modcall_stack_entry_t *entry, bool do_children);
/*
* Call a child of a block.
*/
static void modcall_child(REQUEST *request, rlm_components_t component, int depth,
modcall_stack_entry_t *entry, modcallable *c,
- rlm_rcode_t *result)
+ rlm_rcode_t *result, bool do_children)
{
modcall_stack_entry_t *next;
next->unwind = 0;
if (!modcall_recurse(request, component,
- depth, next)) {
+ depth, next, do_children)) {
*result = RLM_MODULE_FAIL;
return;
}
* Interpret the various types of blocks.
*/
static bool modcall_recurse(REQUEST *request, rlm_components_t component, int depth,
- modcall_stack_entry_t *entry)
+ modcall_stack_entry_t *entry, bool do_children)
{
bool if_taken, was_if;
modcallable *c;
next->priority = 0;
next->unwind = 0;
- if (!modcall_recurse(request, component, depth + 1, next)) {
+ if (!modcall_recurse(request, component, depth + 1, next, true)) {
break;
}
MOD_LOG_OPEN_BRACE;
modcall_child(request, component,
depth + 1, entry, g->children,
- &result);
+ &result, true);
MOD_LOG_CLOSE_BRACE;
goto calculate_result;
} /* MOD_GROUP */
do_null_case:
talloc_free(data.ptr);
- modcall_child(request, component, depth + 1, entry, found, &result);
+ modcall_child(request, component, depth + 1, entry, found, &result, true);
MOD_LOG_CLOSE_BRACE;
goto calculate_result;
} /* MOD_SWITCH */
if (c->type == MOD_LOAD_BALANCE) {
modcall_child(request, component,
depth + 1, entry, found,
- &result);
+ &result, false);
} else {
this = found;
do {
modcall_child(request, component,
depth + 1, entry, this,
- &result);
+ &result, false);
if (this->actions[result] == MOD_ACTION_RETURN) {
priority = -1;
break;
}
next_sibling:
- entry->c = entry->c->next;
+ if (do_children) {
+ entry->c = entry->c->next;
- if (entry->c) goto redo;
+ if (entry->c) goto redo;
+ }
finish:
/*
/*
* Call the main handler.
*/
- if (!modcall_recurse(request, component, 0, &stack[0])) {
+ if (!modcall_recurse(request, component, 0, &stack[0], true)) {
return RLM_MODULE_FAIL;
}
--- /dev/null
+# PRE: update if foreach redundant redundant-load-balance
+#
+# Nested redundant blocks.
+#
+#
+update request {
+ Tmp-Integer-2 := 0
+ Tmp-Integer-3 := 0
+ Tmp-Integer-4 := 0
+ Tmp-Integer-5 := 0
+}
+
+redundant {
+ redundant-load-balance {
+ group {
+ update request {
+ Tmp-Integer-2 := "%{expr:&Tmp-Integer-2 + 1}"
+ }
+ fail
+ }
+ group {
+ update request {
+ Tmp-Integer-3 := "%{expr:&Tmp-Integer-3 + 1}"
+ }
+ fail
+ }
+ group {
+ update request {
+ Tmp-Integer-4 := "%{expr:&Tmp-Integer-4 + 1}"
+ }
+ fail
+ }
+ group {
+ update request {
+ Tmp-Integer-5 := "%{expr:&Tmp-Integer-5 + 1}"
+ }
+ fail
+ }
+ }
+ ok
+}
+
+if (&Tmp-Integer-2 != 1) {
+ update reply {
+ Filter-Id += 'Fail 3a'
+ }
+ return
+}
+
+if (&Tmp-Integer-3 != 1) {
+ update reply {
+ Filter-Id += 'Fail 3b'
+ }
+ return
+}
+
+if (&Tmp-Integer-4 != 1) {
+ update reply {
+ Filter-Id += 'Fail 3c'
+ }
+ return
+}
+
+if (&Tmp-Integer-5 != 1) {
+ update reply {
+ Filter-Id += 'Fail 3d'
+ }
+ return
+}
+
+update reply {
+ Filter-Id := "filter"
+}
\ No newline at end of file