OUR SITES NetworkRADIUS FreeRADIUS

The redundant Statement

Syntax
redundant {
    [ statements ]
}

The redundant section executes a series of statements in sequence. As soon as one statement succeeds, the rest of the section is skipped.

[ statements ]

One or more unlang commands. Processing starts from the first statement in the list.

If the selected statement succeeds, then the server stops processing the redundant section. If, however, that statement fails, then the next statement in the list is chosen. This process continues until either one statement succeeds or all of the statements have failed.

All of the statements in the list should be modules, and of the same type (e.g., ldap or sql). All of the statements in the list should behave identically, otherwise different requests will be processed through different modules and will give different results.

In general, we recommend using the redundant-load-balance statement instead of redundant.

Example
redundant {
    sql1
    sql2
    sql3
}

Redundant Sections as Modules

It can be useful to use the same redundant section in multiple places. Instead of copying the same text multiple times, a redundant section can be defined as a module in the mods-enabled/ directory.

For example, the following text can be placed into the file mods-enabled/sql_all. Once it is there, it can be used as a module named sql_all, and used anywhere a module is allowed to use.

Example of Redundant SQL module
redundant sql_all {
    sql1
    sql2
    sql3
}

In previous versions of the server, this definition would be placed into the instantiate section of radiusd.conf. This configuration is no longer used, and the `sql_all definition can just be placed as a module definition into the mods-enabled/ directory.

Redundant Expansions

Modules may be used in a redundant section, and modules can register dynamic expansions. It is therefore also useful to define redundant dynamic expansions. The good news is that the server does this automatically.

When a redundant section is defined, and where all of the modules in the redundant section reference the same underlying module (e.g. sql, or ldap), the server then automatically registers a new redundant expansion, with the name of the redundant section. The example below shows how this works.

Example
redundant sql_all {
	sql1
	sql2
	sql3
}

Each sql module will register it’s own dynamic expansions, such as %sql1(…​), and %sql2(…​) and `%sql3(…​). However, there will also be a new SQL expansion defined:

%sql_all(...)

This is a redundant expansion. When it is called, it follows operation of the redundant block which defined it. That is, it will first run %sql1(…​), then if that fails, run %sql2(…​), etc.

Example of Redundant SQL module
&Reply-Message := %sql_all("SELECT message FROM table WHERE name='%{User-Name}'")

The one caveat here is that the arguments passed to the underlying modules are expanded again for each call. If the expansion arguments have side effects, then those side effects can be applied multiple times, once for each redundant attempt.

Additional redundant expansions

Modules can register multiple expansions. If the module’s expansion shares the module’s instance name, the redundant expansion is registered with the redundant section name. Otherwise, the redundant expansion is qualified with the redundant section name.

For example, the sql module provides two expansions, a self-named expansion and a group expansion. Using the example from the previous section, redundant sql_all {…​} would register the following:

%sql_all(...)
%sql_all.group(...)

Module expansion grouping

Module expansions which share the same name are grouped into the same redundant expansion. This may result in only a subset of the module expansions in a redundant section being called by a redundant expansion.

Example
redundant sql_and_ldap {
	sql1
	sql2
	ldap1
    ldap2
}

The sql_and_ldap redundant section would register the following expansions:

  • %sql_and_ldap(…​) which would call %sql1(…​), %sql2(…​), %ldap1(…​), and %ldap2(…​)

  • %sql_and_ldap.group(…​) which would call %sql1.group(…​), %sql2.group(…​), %ldap1.group(…​), %ldap2.group(…​)

  • %sql_and_ldap.profile(…​) which would call %ldap1.profile(…​), %ldap2.profile(…​)

If the arguments passed to the redundant expansion are not compatible with all the module expansions it would call, the server will log an error and either fail to start, or stop processing the expression which called the redundant expansion.