Unlang Policy Language

The server supports a simple processing language called "Unlang", which is short for "unlanguage". The original intention of using an "unlanguage" was to avoid creating yet another programming language.

Unlang allows simple conditional checks and editing of attributes and attribute lists. Where more complicated functionality is required, Perl or Python modules rlm_perl or rlm_python are recommended.

The goal of Unlang is to allow simple policies to be written with minimal effort. Conditional checks can be performed by the policies, which can then update the request or response attributes based on the results of those checks. Unlang can only be used in a processing section (e.g., authorize, authenticate, post-auth, preacct, accounting, pre-proxy, post-proxy, and session); it cannot be used anywhere else, including in configuration sections for a client or a module. The reason for this limitation is that the language is intended to perform specific actions on requests and responses. The client and module sections contain definitions for a client or module; they do not define how a request is processed.

Unlang uses the same the basic syntax as the configuration files. The discussion there of lines, comments, sections, sub-section, etc., all apply to Unlang.

Where Unlang differs from the basic configuration file format is in complexity and operation. The normal configuration files are declarative and they are static. That is, they declare variables and values for those variables. Those values do not change when the server is running.

In contrast, Unlang performs run-time processing of requests. Conditional statements such as if are evaluated for every packet that is received. Attribute editing statements such as update can be used to edit attribute contents or lists of attributes.

As a result of this complexity, Unlang is documented in a separate chapter from the standard configuration files.

Unlang has three main areas concepts. Keywords, which are the basic statements of the language, e.g., if, else, etc.; Conditional expressions, which are used to check if conditions evaluate to true or false; finally, update statements are used to edit attributes and lists of attributes.

Example
# First, the keyword 'if'

# followed by condition which checks that the User-Name
# attribute has value "bob"

if (&User-Name == "bob") {
    # keyword "update"

    # followed by instructions to add the Reply-Message
    # attribute to the "reply" list, with contents
    # "Hello, bob"

    update reply {
        Reply-Message := "Hello, bob"
    }
}