Forum Discussion

AppleBee_108607's avatar
AppleBee_108607
Historic F5 Account
Oct 31, 2010

CMP compatible Connection Limit per pool member

Hi,

 

 

I (think I) wrote an CMP compatible iRule to limit connnections per pool member, just by modificating the sample here:

 

v10.1 - The table Command - Examples (http://devcentral.f5.com/Tutorials/...mples.aspx)

 

 

Please kindly comment if there is anything wrong or can be optimized.

 

One of my 8900 user has some applications where they want to limit connections by max of 5; not by 8 xN, and they cannot afford disabling CMP on the whole box

 

 

I presumed the purpose of "set time ~~" and "after cancel $timer" is to get rid of zombie entry. Right?

 

 

-------------------------------------------------

 

when CLIENT_ACCEPTED {

 

set key "[IP::client_addr]:[TCP::client_port]"

 

 

when LB_SELECTED {

 

set tbl "connlimit:[IP::client_addr]:[TCP::client_port]"

 

 

if { [table keys -subtable $tbl -count] > 5 } {

 

event CLIENT_CLOSED disable

 

reject

 

} else {

 

table set -subtable $tbl $key "ignored" 180

 

set timer [after 60000 -periodic { table lookup -subtable $tbl $key }]

 

}

 

 

when CLIENT_CLOSED {

 

after cancel $timer

 

table delete -subtable $tbl $key

 

}

 

-------------------------------------------------

 

 

 

  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    I don't think that's quite right, no. You're trying to limit the number of connections (keys) that each pool member (subtable) has. So your subtable name should be the pool member, not the client. Also, there's a tiny bug with some examples from that article series, but it's easily fixed:

     

     

    when CLIENT_ACCEPTED {
        set key "[IP::client_addr]:[TCP::client_port]"
    
    when LB_SELECTED {
        set tbl "connlimit:[LB::server]"
    
        table set -subtable $tbl $key "ignored" 180    
        if { [table keys -subtable $tbl -count] > 5 } {
            table delete -subtable $tbl $key
            event CLIENT_CLOSED disable
            reject
        } else {
            set timer [after 60000 -periodic { table lookup -subtable $tbl $key }]
        }
    
    when CLIENT_CLOSED {
        after cancel $timer
        table delete -subtable $tbl $key
    }
    
    I haven't tested this code, but it should work. The purpose of the timer is to keep the entry in the subtable for as long as the connection exists. Otherwise the connection could still be alive but the subtable entry could expire. If the client closes normally, the CLIENT_CLOSED event will fire which will delete the entry and cancel the timer. If there's some very unusual condition and CLIENT_CLOSED doesn't fire, the timer will get cleaned up automatically, and the subtable entry will expire on its own, exactly preventing any zombie subtable entries (which would mess up the count). Finally, if this solution doesn't work for you, you could just disable CMP on the virtuals which need this extremely low connection count.
  • AppleBee_108607's avatar
    AppleBee_108607
    Historic F5 Account
    Hi spark,

     

     

    Thanks a lot for looking into it. I will test this code later in my lab. I'll update how it went on later.

     

    Meanwhile, I have one more urgent iRule to write. I'll probably post another iRule soon....