Unlang policy to remove duplicate attributes from reply?
Hello, 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 π I'll try to explain in sudo-code what I mean: if (number of Framed-IP-Address attributes > 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] ββββ} ββββ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 ββββ} } Everything I've tried is either invalid syntax, or a comma is expected after the cast statement, or freeradius cannot resolve to IP address, or it just doesn't work. It's starting to drive me crazy π 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!
On 25/06/2025 10:22, tach yon wrote:
if (number of Framed-IP-Address attributes > 1) {
You want to use the [#] suffix to get the number of instances of an attribute - so if (&reply: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]
Why use Tmp-String-0 - just use Tmp-IP-Address-0 to keep the data type consistent - then there won't be any casting issues. Of, since you're putting the result you want in the control list, you can just use Framed-IP-Address- so update control { &Framed-IP-Address := &reply:Framed-IP-Address[0] } -- Nick Porter
On Jun 25, 2025, at 5:22β―AM, tach yon <tachyon@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.
Hi Alan, Thanks very much for your help!
update { &control:Framed-IP-Address := &reply:Framed-IP-Address[0] &reply:Framed-IP-Address !* ANY &reply:Framed-IP-Address := &control:Framed-IP-Address }
This worked great, thanks! Gosh it was driving me nuts last night, looks straightforward when you know how, thanks again π
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.
I tried with both <> and (), because google was pulling out examples of both. I have no idea why freeradius would be saying it expected a comma either. I tried so many things and got various different errors. I didn't make sense to me, I dunno. Perhaps a big part of the confusion, was that I was working on docs for version 3.0, which doesn't have a lot of info version 4.x docs has. I realise now I should have relied more on "man unlang", sorry π It seems as so many docs are online now-a-days, it's become natural to use a browser for checking docs, and terminals for writing / modifying code.
Do read "man unlang" and the documentation on the web site. Don't use third-party web sites. Don't use AI.
After the best part of the day and continuing into the night. A seemingly unending cycle of reading/trial/error, plus trying newer freeradius versions, yeah... I did eventually realise Google and the AIs weren't making any sense. For other languages like python, google and the AIs are surprisingly good; but a less widely used language like unlang, you're right, nothing works π I guess it was at that point I realised I needed real help from humans - with proper examples of what syntax can and can't be used together, hehe. Thanks again! π
participants (3)
-
Alan DeKok -
Nick Porter -
tach yon