Forum Discussion
UDP Profile?
I have created an iRules just now, however, it is failed when I tried to assigne to a virtual server.
"01070394:3: UDP::payload in rule (FIP_Route) requires an associated UDP profiles on the virtual server (M1)."
I cannot figure out what I have configured wrong or the problem on iRules itself. can anyone help?
iRule
---------
when CLIENT_ACCEPTED {
if { [UDP::payload] matches " 10.12.1." } {
use pool pool1
}
elseif { [UDP::payload] contains "10.12.2." } {
use pool pool2
}
}
-------------
44 Replies
- rubbishking_110
Nimbostratus
thx
do i need to do a unset if I want to purge the info? - Nicolas_Menant
Employee
not with session command, you can set a timeout at the end (in seconds)
ex: session add uie $::ip "pool1" 1800 - rubbishking_110
Nimbostratus
Hi
it seems that the value stored using "session" command cannot reuse in other iRules for other virtual servers unless the golbal variable is defined in RULE_INIT. am I correct?
below is the coding I am using, I want the other irule that can extract the value in the session table. possible? or do I need to combine two irules into one single irule?
the irule1 for vserver1 while irule2 for vserver2.
- rk
irule1: used for virtual server1 (extract the ip address for the payload. payload will use irule2 for decision)
when RULE_INIT {
array set ::msg_types {
4 "Accounting-Request"
5 "Accounting-Response"
255 "Reserved"
}
array set ::attr_types {
8 "Framed-IP-Address"
}
}
when CLIENT_ACCEPTED {
set client "[IP::client_addr]:[UDP::client_port]"
if { [UDP::payload length] > 4 } {
binary scan [UDP::payload] c hdr_code
Detect the 1st TLV until last
log local0. "RADIUS-Type: $::msg_types($hdr_code)($hdr_code) / RADIUS UDP Payload size: [UDP::payload length] bytes"
binary scan [UDP::payload] @20a* rest_string
while { [string length $rest_string] >4} {
binary scan $rest_string cca* attr_id attr_length rest_string
scan $attr_length %i length
set ff [format "a%da*" [expr {$length} - 2]]
switch $attr_id {
8 {
binary scan $rest_string c4a* IPtmp rest_string
set IP {}
foreach num $IPtmp {
lappend IP [expr ($num + 0x100) % 0x100]
}
set ::attr_value1 [join $IP .]
log local0. "$::attr_types($attr_id)($attr_id): $::attr_value1"
if {[IP::addr $::attr_value1 equals 10.11.0.0/255.255.0.0]} {
pool MPOOL1
log local0. "Pool used for RADIUS Request with Framed-IP-Address <$::attr_value1> from GGSN <$client>."
session add uie {$::attr_value1 any virtual} MPOOL1
Proved the lookup is working
set poolip [session lookup uie {$::attr_value1 any virtual}]
log local0. "$poolip"
}
elseif {[IP::addr $::attr_value1 equals 10.12.0.0/255.255.0.0]} {
pool MPOOL2
log local0. "Pool used for RADIUS Request with Framed-IP-Address <$::attr_value1> from GGSN <$client>."
session add uie {$::attr_value1 any virtual} MPOOL2
Proved the lookup is working
set poolip [session lookup uie {$::attr_value1 any virtual}]
log local0. "$poolip"
}
}
default {
binary scan $rest_string $ff attr_value rest_string
log local0. "attribute id: $::attr_types($attr_id); attribute length: $length; filed value: $attr_value"
}
}
}
}
}
irule2: used for virtual server 2 (packet with src ip 10.12.1.1 access)
when CLIENT_ACCEPTED {
set cIP "[IP::client_addr]"
set poolname [session lookup uie {$cIP any virtual}]
log local0. "fip=$cIP, pool=$poolname"
} - david_wang_2073Historic F5 Accountactually, I want to extract the value of RADIUS attribute "Framed-IP-Address" in RADIUS UDP packet. would you mind advising me what should I do?
help below is helpful:
We can make reference to below irule about the usage of session table:
rule sipclient {
when CLIENT_DATA {
if {[scan [UDP::payload] "%s%s" method uri] == 2} {
puts $method
puts $uri
if {[regexp {Call-ID:\s*([^\r\n]+)[\r\n]+} [UDP::payload] -> callid] == 1} {
puts $callid
persist uie $callid
set lll [list $callid any]
set sss [session lookup uie $lll]
puts $sss
set ppp [persist lookup uie $lll]
puts $ppp
if {$sss != "" && $ppp == ""} {
XXX use your real pool name
use pool sippool member $sss
} else {
persist uie $callid
}
}
}
}
}
rule sipserver {
when CLIENT_DATA {
if {[scan [UDP::payload] "%s%s" method uri] == 2} {
puts "server"
puts $method
puts $uri
if {[regexp {Call-ID:\s*([^\r\n]+)[\r\n]+} [UDP::payload] -> callid] == 1} {
puts $callid
persist uie $callid
puts "[IP::remote_addr] [UDP::remote_port]"
set lll [list $callid any]
set sss [session lookup uie $lll]
puts "find $sss"
if {$sss == ""} {
set lll [list $callid pool sippool]
set lll [list $callid any]
XXX 7 is an example, set to your real port
session add uie $lll [format "%s:%s" [IP::remote_addr] 7]
}
}
}
}
}
profile udp myudp {
defaults from udp
datagram lb enable
}
virtual testsip_external {
destination 10.10.1.1:7000
ip protocol udp
pool sippool
profile myudp
rule sipclient
}
virtual testsip_internal {
destination 10.10.1.2:7
ip protocol udp
translate service disable
translate addr disable
profile myudp
rule sipserver
}
In order to make the first option work, we just need add red lines to Radius LB/persistence irule in SERVER_DATA event as below
8 -
{ 8 "Framed-IP-Address"
binary scan $rest_string c4a* IPtmp rest_string
set IP {}
foreach num $IPtmp {
lappend IP [expr ($num + 0x100) % 0x100]
}
set attr_value [join $IP .]
log "Frame-ip-address value $attr_value"
set lll [list $attr_value any]
set sss [session lookup uie $lll]
puts "find $sss"
if {$sss == ""} {
set lll [list $attr_value any]
XXX 7 is an example, set to your real port
session add uie $lll [format "%s:%s" [IP::remote_addr] 8080] 8080 is the port of WAP gateway
}
}
then use following irule for WAP virtual server in CLIENT_ACCEPTED event:
When CLIENT_ACCEPTED {
set lll [list [IP::remote_addr] any]
set sss [session lookup uie $lll]
puts $sss
set ppp [persist lookup uie $lll]
puts $ppp
if {$sss != "" && $ppp == ""} {
XXX use your real pool name
use pool wappool member $sss
} else {
persist uie [IP::remote_addr]
}
}
Because session table has ever been used in SIP irule to share the information across virtual server and I ever tried session table in other irule, so I think session table should work in this scenario.
But above irule still need been tuned in a test environment, I just write it for prove of concept.
If the Radius and WAP gateway was located in different host, but there is one to one corresponding relationship between radius and WAP, we need add an extra array to map this relation in irule, so that we can find the ip address of WAP server after we get the IP address of a Radius server. - david_wang_2073Historic F5 Accountfor complete Radius Frame-IP-address persistence, please see attached.
- rubbishking_110
Nimbostratus
Hi
thx for the help! however, I cannot read the file. can you post in the other format?
- rk - rubbishking_110
Nimbostratus
Hi David
thx for the info. but I don't think the varliable can be reused in other irule if it is not set in RULE_INIT (in my case is the framed-ip-address). correct?
- rk - david_wang_2073Historic F5 Accountsession can be used to for irule to share information between different virtual servers, needn't defind in RULE_INIT.
8 -
{ 8 "Framed-IP-Address"
binary scan $rest_string c4a* IPtmp rest_string
set IP {}
foreach num $IPtmp {
lappend IP [expr ($num + 0x100) % 0x100]
}
set attr_value [join $IP .]
log "Frame-ip-address value $attr_value"
set lll [list $attr_value any]
set sss [session lookup uie $lll]
puts "find $sss"
if {$sss == ""} {
set lll [list $attr_value any]
XXX 7 is an example, set to your real port
session add uie $lll [format "%s:%s" [IP::remote_addr] 8080] 8080 is the port of WAP gateway
}
}
then use following irule for WAP virtual server in CLIENT_ACCEPTED event:
When CLIENT_ACCEPTED {
set lll [list [IP::remote_addr] any]
set sss [session lookup uie $lll]
puts $sss
set ppp [persist lookup uie $lll]
puts $ppp
if {$sss != "" && $ppp == ""} {
XXX use your real pool name
use pool wappool member $sss
} else {
persist uie [IP::remote_addr]
}
}
Above irule is doing what you want: for Radius virtula server add the frame-ip-address and backend server to the session table, then for HTTP or WAP request, search the session table based on source-ip( frame-ip-address) to find out the backend server ip adress. - Nicolas_Menant
Employee
You need to add the "any virtual" in each of those session commands to make it works between vs. - The_Bhattman
Nimbostratus
Click here to find the reference to "any virtuals" under sessions.
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
