Expressions
Expressions can be used inside of dynamic expansions, or inside of conditions.
The following operators are supported (in order of precedence).
Operator | Description |
---|---|
& |
binary AND |
| |
binary OR |
<< |
left shift |
>> |
right shift |
+ |
addition |
- |
subtraction |
* |
multiplication |
/ |
division |
% |
remainder |
^ |
xor |
(…) |
sub-expression |
The following unary operators are also supported:
Operator | Description |
---|---|
- |
unary minus |
~ |
unary complement |
! |
unary not |
Operator precedence follows the normal rules. Division by zero means that the entire expression is invalid.
See the edit documentation for a list of attribute editing operators.
Conditions
Conditions in expressions are also supported. For example:
&NAS-Port = 5 + (&User-Name == "bob")
This expression will return 6
if the users name is bob
, and 5
otherwise.
Similarly, expressions are also supported in conditions. There is no
need to use %{expr:…}
in conditions, as was needed in earlier
versions of the server. You can just use math in-place.
You do not even need to use %{expr:…}
in double-quoted strings.
You can just put math in-place, as with the following example:
&Filter-Id = "Adding %{NAS-Port} + 4 = %{&NAS-Port + 4}"
Data Types
The new expression parser accepts significantly more data types than
the old rlm_expr
module. The rlm_expr
module assumed that all
inputs were signed 64-bit integers. Any attempt to use other data
types resulted in an error.
For example, the ` operator can be applied to `string` and `octet`
data types. (And incidentally, `-` is the inverse of `
!)
&Reply-Message := "foo" + "bar"
Will result in &Reply-Message == "foobar"
.
The suffix can then be "subtracted" off, with:
&Reply-Message -= "bar"
Will result in &Reply-Message == "foo"
!.
Note that the -=
operator behaves differently from earlier versions
of the server! Since the server no longer needs update
sections, we
could re-purpose the operator.
Other data types will generally yield results which make sense. For example:
-
adding an integer to an
ipv4prefix
type will result in anipv4addr
data type, -
&
and|
will work onstring
andoctets
data types, -
Using
&
withipv4addr
data types anuint32
will result in anipv4prefix
data type, -
`ipv4addr`s can be subtracted, and will return a number,
-
date`s can be subtracted, and will return a `time_delta
, -
operations on integers are upgraded to the next largest integer size when necessary,
-
the logical operators
&&
and||
return the value which caused them to succeed, e.g.&Foo := (&User-Password || "help")
will return the contents of&User-Name
if it exists, otherwise it will return the stringhelp
.
In most cases, the data types are derived from the attribute dictionaries. However, it is sometimes necessary to force the fields (or output) of an expression to be parsed in a particular manner.
Casts
Type casting is supported via the (type)
syntax. The old-style syntax of <type>
is accepted, but is
deprecated.
&NAS-Port-Id = (uint32) "%sql("SELECT...") + 4
Errors
Mathematical operations which cause overflow, underflow, or division
by zero will return a null
result. This result will propagate
through any calculations, so that an expression which relies on null
will generally also return null
.
A null
result can be removed via the ||
operator. For example:
&NAS-Port-Id = (5 - "foo") || 6
Will return 6
, as the left side expression of the ||
operator evaluates to null
.