Unlang policy to remove duplicate attributes from reply?

Alan DeKok aland at deployingradius.com
Wed Jun 25 11:50:35 UTC 2025


On Jun 25, 2025, at 5:22 AM, tach yon <tachyon at live.co.uk> wrote:
> I've spent many hours searching the docs, examples, list posts, etc, plus AI generators - testing as many permutations I can think of - trying to find the correct syntax and method to do this with Unlang, but nothing seems to work 🙁

  The server comes with tons of documentation.  See "man radiusd" and "man unlang".  Much of the syntax is documented,

  There's also tons of documentation online at https://www.freeradius.org/documentation/freeradius-server/3.2.8/

  Generally speaking most third-party web pages are out-dated or wrong.  And anything produced by AI is almost completely wrong.

  And as a process, trying random things isn't useful.  The server includes not just documentation, but descriptive errors which indicate what went wrong, and where.  These errors should help to point you in the right direction.

> I'll try to explain in sudo-code what I mean:
> 
> if (number of Framed-IP-Address attributes > 1) {

  Framed-IP-Address[#] > 1

>     update control {
>         # Save the first Framed-IP-Address to a temporary String (because I read ipaddr type isn't available).
>         &Tmp-String-0 := &reply:Framed-IP-Address[0]

  Where did you read that the ipaddr type isn't available?

  You can also search the dictionaries for attributes:  grep -i tmp /usr/share/freeradius/dictionary/* | grep -i ip

  The will produce Tmp-IP-Address-0 and friends.  But as Nick pointed out, you don't need that.  See below.

>     }
>     update reply {
>         # Remove all Framed-IP-Address entries currently in the reply.
>         &Framed-IP-Address !* ANY
>         # Re-create Framed-IP-Address with the first value we saved temporarily.
>         # Cast as ipaddr because Framed-IP-Address needs that data type.
>         &Framed-IP-Address := (ipaddr) &control:Tmp-String-0
>     }

  The whole thing can be done via the following "update" section:

    update {
	&control:Framed-IP-Address := &reply:Framed-IP-Address[0]
	&reply:Framed-IP-Address !* ANY
	&reply:Framed-IP-Address := &control:Framed-IP-Address
     }

> Everything I've tried is either invalid syntax, or a comma is expected after the cast statement,

  Huh?  There's no comma after the cast statement.  Plus, the cast documentation says that casting is done via <>, and not ().  See "man unlang", or the online documentation.

  We've fixed that in v4...

> or freeradius cannot resolve to IP address, or it just doesn't work. It's starting to drive me crazy 🙁

  The server doesn't resolve IP addresses by default.  I suspect what's going on is that this error is a side effect of you putting the IP address into a "string" data type.  Hint: don't do that.  The server supports "ipaddr" as a native data type.

> If anyone could please help me understand what I'm doing wrong, it would be very much appreciated. Thank you in advance for your time and consideration!

  Do read "man unlang" and the documentation on the web site.  Don't use third-party web sites.  Don't use AI.

  Alan DeKok.




More information about the Freeradius-Users mailing list