Conditional Expressions
Conditions are evaluated when parsing if and elsif statements. These conditions allow the server to make complex decisions based on one of a number of possible criteria.
if ( condition ) { ...
elsif ( condition ) { ...
Conditions are expressed using the following syntax:
Syntax | Description |
---|---|
Check for attribute existence. |
|
Check return code of a previous module. |
|
Check value of data. |
|
Compare two kinds of data. |
|
Mathematical expressions. |
|
Check sub-condition |
|
Negate a conditional check |
|
Check a condition AND the next one |
|
Check a condition OR the next one |
if ( &User-Name == "bob" ) {
...
}
if ( &Framed-IP-Address == 127.0.0.1 ) {
...
}
if ( &Calling-Station-Id == "%sql("SELECT ...") ) {
...
}
Load-time Syntax Checks
The server performs a number of checks when it loads the configuration files. Unlike version 2, all of the conditions are syntax checked when the server loads. This checking greatly aids in creating configurations that are correct. Where the configuration is incorrect, a descriptive error is produced.
This error contains the filename and line number of the syntax error. In addition, it will print out a portion of the line that caused the error and will point to the exact character where the error was seen. These descriptive messages mean that most errors are easy to find and fix.
Load-time Optimizations
The server performs a number of optimizations when it loads the configuration files. Conditions that have static values are evaluated and replaced with the result of the conditional comparison.
if (0) {
...
}
The condition 0
is static and will evaluate to false
. Since
it evaluates to false
, the configuration inside of the if
statement is ignored. Any modules referenced inside of the if
statement will not be loaded.
This optimization is most useful for creating configurations that
selectively load (or not) certain policies. If the condition above
was used in version 2, then the configuration inside of the if
statement
would be loaded, even though it would never be used.
Practical Suggestions
We have seen many configurations where conditions are written using dynamic expansions and double-quoted strings for almost everything. For example, the following condition is unnecessarily complex:
if ("%{Framed-IP-Address}" == "192.0.2.1") {
...
}
This kind of condition is unnecessarily complex, and over-uses quotes. It should instead be written as:
if (&Framed-IP-Address == 192.0.2.1) {
...
}
In general, the following rules apply:
-
There is no need to quote attributes.
&User-Name
is almost always preferable to%{User-Name}
. -
There is no need to quote values, unless the value is a string.
192.0.2.1
is always preferable to"192.0.2.1"
-
There is no longer a need to use
%{expr:..}
to do math in conditions. Using the math in-place will work, as withif (1 + 2 == 3)
. See expressions. -
If you want to check that an attribute exists and has a particular value, use
if !(&Attr == value)
, instead ofif (&Attr != value)
. The difference us that if the attribute does not exist, it will match the condition(&Attr != value)
, because the attribute has no value.