Forum Discussion
AppleBee_108607
Nov 02, 2010Historic F5 Account
CMP compatible strict Round Robin
Hi,
In addition to my another post, I have to urgently write an iRule to facilitate strict Round Robin event if the Virtual is CMPenabled.
I wrote code as follows but still have two difficulities:
(1) Initializing data in table
It seems "table" command cannot be used in RULE_INIT event.
(2) I'm not clear how to specify variable type: numeric or string (Ooops..)
and having difficulty in calculating variables.
(3) Want to set general variables in RULE_INIT
--> Probably I can just use "static::xxx"
Excuse me for newbee question.
--------------------------------
when RULE_INIT {
}
when CLIENT_ACCEPTED {
set poolname "test-pool"
set num_pool_member 4
set pool_port 80
set ip_pm0 "10.100.11.11"
set ip_pm1 "10.100.11.12"
set ip_pm2 "10.100.12.11"
set ip_pm3 "10.100.12.12"
get next poolmember's index
set last_mod [table lookup -subtable "rr_table" "last_mod"]
---- Here, not sure how to set correct data tye ------
set new_mod [ expr { expr { $last_mod + 1 } % $num_pool_member} ]
table set -subtable "rr_table" "last_mod" $new_mod
-----
Here I want to check the validily of the variable as "table" cannot be initialized in RULE_INIT
I also want to check if it's not empty but non-numeric value is set.
if { $last_mod == "" } {
table set -subtable "rr_table" "last_mod" 0 indefinite indefinite
set new_mod 1
}
switch pool member based on the index
switch $new_mod {
0 {
if { [LB::status pool $poolname member $ip_pm0 $pool_port up] } {
pool $::poolname member $ip_pm0 $pool_port
log local0.info "LBed to pm 0"
} else {
continue
}
}
1 {
if { [LB::status pool $poolname member $ip_pm1 $pool_port up] } {
pool $poolname member $ip_pm1 $pool_port
log local0.info "LBed to pm 1"
} else {
continue
}
}
2 {
if { [LB::status pool $poolname member $ip_pm2 $pool_port up] } {
pool $::poolname member $ip_pm2 $pool_port
log local0.info "LBed to pm 2"
} else {
continue
}
}
3 {
if { [LB::status pool $::poolname member $ip_pm3 $pool_port up] } {
pool $::poolname member $ip_pm3 $pool_port
log local0.info "LBed to pm 3"
} else {
continue
}
}
default {
log "no pool to assign for Virtual Server XX"
}
}
}
--------------------------------
- AppleBee_108607Historic F5 AccountWheeww. I finally got it working, referring to an iRule from my colleague, which I guess comes from somewhere in DevCentral.
- spark_86682Historic F5 AccountTo answer your questions:
Again, not actually tested or syntax-checked code, and written for clarity, not compactness or performance.when CLIENT_ACCEPTED { set poolname "test-pool" if { [active_members $poolname] < 1 } { No active pool members; reset client reject return } set count [members $poolname] set attempt 0 while { $attempt < $count } { set num [table incr "round-robin:$poolname"] set num [expr $num % $count] set mbr [lindex [members -list $poolname]] set mbr_ip [lindex $mbr 0] set mbr_port [lindex $mbr 1] if { [LB::status pool $poolname member $mbr_ip $mbr_port up } { pool $poolname member $mbr_ip $mbr_port return } incr attempt } }
- spark_86682Historic F5 AccountThis rule is good, but the session table is a shared global structure, and this iRule does what's referred to as a "read-modify-write" to that data, which is bad. The three lines are:
The first one reads some data from the session table, the second one modifies that data, and the third one writes it back. Hence, "read-modify-write". Consider what would happen if two different connections came in at the same time and both executed this code. They would both read in a value (say, 3), both modify it (so new_mod would be 4), and both write it back out. So the two connections would both use the 4th pool member, which isn't what you want. In my other post, I use "table incr", which does an atomic increment, so this couldn't happen, since there's no read-modify-write happening. If two connections do an increment at the same time, one incrment command will actually be serviced first, so the "table incr" command will never return the same value to the two connections, so they'll always go to different pool members. Make sense?set last_mod [table lookup -subtable tbl_rr_$static::poolname "last_mod"] set new_mod [expr {[expr {$last_mod + 1}] % $num_pm}] table set -subtable tbl_rr_$static::poolname "last_mod" $new_mod
- AppleBee_108607Historic F5 AccountHi Spark,
Recent Discussions
Related Content
DevCentral Quicklinks
* 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
Discover DevCentral Connects