Forum Discussion

grabarz666's avatar
grabarz666
Icon for Nimbostratus rankNimbostratus
Aug 26, 2018

iRule to cap traffic on VIP to 10Mbit/s with HTML OOS response if limit exceeded

Hi All,

 

I am looking at developing an iRule which will count a number of bytes incoming to VIP by using [IP::stats bytes in] event and based on the cap ("if" function) provide OOS HTML message back to the clinet ("The service is currently down" etc.). In the simplest terms this is bandwidth (not rate limit) throttling with OOS page...

 

First I thought of was to utilize session subtables for each HTTP_REQUEST event, store [IP::stats bytes in] value in subtable as a key, collect all the keys in a list and sum them up, this would give me a total value at a given time. Key values should be expiring in let's say 1-2 seconds.

 

Pseudo code

 

Create main table which consists of 1/2/3....x subtables (each subtable will be unique client IP:port

 

if first client's HTTP_REQUEST collect bytes in add to individual subtable as key

 

if second client's HTTP_REQUEST in parallel collect bytes in add to individual subtable as key

 

for each key in the subtable add to main list sum up elements in the list

 

if sum up value is >= i.e. 200000 bytes HTTP::respond OOS page drop else continue

 

Pseudo code

 

I also looked at the shaping and bandwidth classes, but cannot see how I can call it from iRule event to provide OOS message when limit is reached.

 

Can anybody provide some recommendations?

 

Thanks,

 

  • I developed this iRule, it seems like counter now works properly. Can someone cast an eye for efficiency and whether iRule makes sense?

     

    Thanks,

     

    when HTTP_REQUEST {

     

    set limit 10000000

     

    set tbl "rate_limit"

     

    set key [expr {[IP::stats bytes in]}]

     

     

    Sum up values function

     

    foreach element $key {

     

    log local0. "Per request rate is: $element"

     

    lappend IP [expr (0 + {$element})]

     

    set sum [expr [join $IP +]]

     

    log local0. "Sum of all requests is: $sum" }

     

    Bandwidth cap condition

     

    if {$sum >= $limit} {

     

    HTTP::respond 200 content {

     

     

     

    OOS page

     

     

     

    Sorry, page is currently OOS, please refresh in a while...

     

     

     

    }

     

    table delete -subtable $tbl $key

     

    log local0. "dropping..."

     

    TCP::close

     

    } else {

     

    table set -subtable $tbl $key "new_tbl" 2 2

     

    }

     

    }

     

  • Are you trying to set a limit for bandwidth or just stopping transmitting after a counter?

     

    You have already BWC and Rate Shaping to set bandwidth limits, which are more efficient:

     

    RateShaping -> https://support.f5.com/kb/en-us/products/big-ip-aam/manuals/product/aam-concepts-12-1-0/4.html

     

    BWC -> https://support.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/tmos-implementations-12-0-0/8.html

     

    Also, you can apply both using an iRule condition.

     

    KR, Dario.