OUR SITES NetworkRADIUS FreeRADIUS

Unlang Policy Language

The server supports a simple processing language called "Unlang", which is short for "un-language". The original intention of using an "un-language" was to avoid creating yet another programming language. Instead, the unlang syntax allows for simple if / then / else checks, and attribute editing. It does not support recursion, subroutines, or more complex flow controls.

Where more complicated functionality is required, we recommend using the lua, perl or python modules. Those modules allow the insertion of full-featured scripts at any point in the packet processing.

The documentation is this directory is reference documentation. That is, it describes the syntax of unlang keywords, using minimal examples. The reference documentation does not, however, describe when to use the keywords, or how to create policies. Please see the howto directory for more in-depth "how to" guides.

The documentation is organized so that each item is on its own page. The page beings with a description of the item, followed by some text explaining what the item does. The page concludes with one or more examples of using the item in unlang policies.

The unlang processing can be split into some high-level concepts.

Keywords

Keywords, which are the basic statements of the language, e.g., load-balance, if, else, etc.

Example
load-balance {
	sql1
	sql2
	sql3
}

Interpreter

The Interpreter processes an input "request" packet, by running policies which contain Keywords. The result of the interpretation is usually an output "reply" packet.

While the interpreter allows some fairly complex policies to be made, it is not a general purpose programming language. The purpose of the language is to receive packets, process their contents, and send replies. A secondary goal is to do that as quickly as possible.

Conditional Expressions

Conditional expressions, which are used to check if conditions evaluate to true or false. Conditional expressions can be used to control the flow of processing.

Example
if ((&User-Name == "bob") && (&Calling-Station-Id == "00:01:03:04:05")) {
	...
}

Editing Attributes and lists.

Attribute editing statements are used to edit attributes and lists of attributes. The old-style update sections are deprecated, and no longer supported.

Local variables can be defined, so that the local dictionary file no longer needs to be modified.

Most request packets will result in reply packets that contain additional information for the requestor. Attribute editing allows policies to add attributes to requests, replies, or to other places.

Example
&reply.Session-Timeout := 3600
&reply.Framed-IP-Address := 192.0.2.4

Dynamic Expansions

Dynamic expansion Using %{…​} to perform dynamic expansions. (also known as xlat)

Dynamic expansions are usually performed in order to get additional information which is not immediately available to the policy. This information can be taken from almost any source, including other attributes, databases, and scripts.

Example
&reply.Framed-IP-Address := %sql("SELECT static_ip from table WHERE user = '%{User-Name}'")

Data Types

Each attribute used by the server has an associated data type. The unlang interpreter enforces restrictions on assignments, so that only valid data types can be assigned to an attribute. Invalid assignments result in an error.

Example
&reply += {
	&Framed-IP-Address = 192.0.2.4
	&Session-Timeout = 5
	&Reply-Message = "hello"
}

Design Goals of Unlang

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, 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 a syntax similar to the configuration files. The policies can contain comments, whitespace, sections, etc.

Where unlang differs from the basic configuration file format is in its 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 can be used to edit attribute contents or 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") {
    # followed by instructions to add the Reply-Message
    # attribute to the "reply" list, with contents
    # "Hello, bob"

    &reply.Reply-Message := "Hello, bob"
}