= &Attribute References

.Syntax
[source,unlang]
----
&Attribute-Name
----

The `&Attribute-Name` operator returns a reference to the named
attribute.

When used as an existence check in a condition, the condition
evaluates to `true` if the attribute exists.  Otherwise, the condition
evaluates to `false`.

When used elsewhere, such as in xref:unlang/switch.adoc[switch], it returns
the value of the named attribute.

.Examples
[source,unlang]
----
&User-Name
&NAS-IP-Address
----

== Lists

The attribute reference can also be qualified with a
xref:unlang/list.adoc[list] reference.  When no list is given, the server
looks in the input packet list for the named attribute.

.Examples

[source,unlang]
----
&request.User-Name
&reply.NAS-IP-Address
----

== Array References

.Syntax
[source,unlang]
----
&Attribute-Name[<index>]
----

When an attribute appears multiple times in a list, this syntax allows
you to address the attributes as if they were array entries.  The
`<index>` value defines which attribute to address.  The `[0]` value
refers to the first attributes, `[1]` refers to the second attribute,
etc.

The `<index>` can be an integer (0..1000).

The indexes are limited to 1000, because there are essentially no
protocols which have more than 1000 attributes.

.Integer Array index
[source,unlang]
----
&EAP-Message[1]
&reply.NAS-IP-Address[2]
----

The `<index>` can also be a special value `n`, which means "the last attribute in the list.

.Last attribute in a list
[source,unlang]
----
&EAP-Message[n]
----

The `<index>` can also be a reference to a numerical attribute.

The reference *must* be to an attribute of numerical data type.  Structural data types and `string` or `octets` types are not allowed.  If the index is out of bounds (e.g. negative), then the reference fails.

The main utility of attribute indexes is in a xref:unlang/foreach.adoc[foreach] loop.

.Attribute reference as Array index
[source,unlang]
----
uint32 foo

&foo = 2

&EAP-Message[&foo]
----

The `<index>` can also be an expression which is calculated at run time.  The expression _must_ not cause the server to call an external database, script, etc.  The main purpose of these expressions is to calculated an index without first placing it into another attribute.

If the index must be calculated from an external database call or script, simply place that value into an attribute first, and then use that attribute as in index.

The expression _must_ be in an expansion block: `%{...}`.

.Expression as an Array index
[source,unlang]
----
&index = 0

&EAP-Message[%{&index + 1}]
----

=== Array References in lists

It is sometimes useful to refer to children of a list, without
addressing the children by name.  In that case, the name of the child
attribute can be omitted, as follow:

.Examples
[source,unlang]
----
&request.[0]
----

i.e. "the first child of the `request` list.

This syntax is most useful in xref:xlat/attribute.adoc[xlat attribute references].

Note that the old syntax of `&request[...]` is disallowed.

== Parent / child references

.Syntax
[source,unlang]
----
&Attribute-Name.Attribute-Name
----

In some cases, attributes are nested or grouped.  The child reference
syntax is used to address a particular child attribute.  Multiple
levels of parent / child nesting can be performed by simply appending
the name of another child attribute, separated by the `.` character.

.Examples

[source,unlang]
----
&TLV-One.Child-one
&TLV-One.Child-one.Child-Three
&reply.TLV[3].Child-Two
----

== Putting it All Together

All of the above syntaxes can be used interchangeably, at any nesting level.  The examples are presented

.Examples
[source,unlang]
----
&TLV-One.Child-one[3].Child-Three
&reply.TLV[3].Child-Two
----

== Compatibility with Older Versions of FreeRADIUS

Older versions of the server did not use the `&` character to
distinguish attribute names from other strings.  Version 4 requires
the use of the `&` character before attribute names.

Without the `&`, the server could interpret a string as `hello-there`
either as a literal string "hello-there", or as a reference to an
attribute named `hello-there`.  This ambiguity made it difficult to
parse the configuration files correctly in all cases.

Adding the leading `&` character means that attribute references are
now easily distinguishable from literal strings.

// Copyright (C) 2022 Network RADIUS SAS.  Licenced under CC-by-NC 4.0.
// This documentation was developed by Network RADIUS SAS.
