Forum Discussion

LillyM_9417's avatar
LillyM_9417
Icon for Altostratus rankAltostratus
Dec 15, 2011

Switch & external datagroup file

Hello,

 

 

I need to create an irule with the following properties..

 

 

Thanks a lot in advance..

 

 

---Firstly, I am doing all the following items with IF claues in prod enviroment without any problem but we want to make cpu utilization & if it is possible we want to use switch clause.

 

 

* I have 4- 5 Ip ranges, and I need to decide which external group files will be chose.

 

* I have many external data group files. They all have many string values inside.

 

* I need to check $trx1 (I am doing binary scan to catch the value from the data packet) value, with these string values those inside the external datagroup files

 

* I could do this with IF statement but it comsumes so much CPU

 

* Thats why I am trying to using SWITCH clause instead of IF clause

 

 

 

Example:

 

 

If ip is in the x.x.x.x/24 ip range

 

If $trx1 in the A external datagroup file - do something

 

If $trx1 in the B external datagroup file- do something

 

If $trx1 in the C external datagroup file- do something

 

else- do something else

 

 

If ip is in the y.y.y.y/24 ip range

 

If $trx1 in the D external datagroup file - do something

 

If $trx1 in the E external datagroup file - do something

 

If $trx1 in the F external datagroup file - do something

 

else - do something else

 

 

else

 

do something - go to default pool

7 Replies

  • Hamish's avatar
    Hamish
    Icon for Cirrocumulus rankCirrocumulus
    I'd use a single datagroup for your lookups... Merge the A,B,C datagroups and add a value to each $trx value in there that helps to differentiate between whether you want to do actionA, B or C.

     

     

     

    H
  • Hamish's avatar
    Hamish
    Icon for Cirrocumulus rankCirrocumulus
    Oh... You don't mention what $trx actually is... How long is that string?

     

     

    H
  • trx is'a 4 byte string like:

     

     

    datagroup A & the values inside of it: zxcv, zxcb, zxch, ....

     

    datagroup B & the values inside of it: xxcv, xxcb, xxch, ...

     

    datagroup C & the values inside of it: yxcv, yxcb, yxch, ...

     

     

    $trx1 can be any of them it may be yxcv or yxcb etc.

     

     

    Thanks a lot

     

     

     

  • I agree with Hamish that it would be more efficient to combine the entries into one datagroup if it will work with your scenario. However, if you want to check a separate datagroup for different IP ranges, you could do something like this with a datagroup which maps host/networks to separate datagroups:

     Datagroups 
    class ip_to_dg_name_dg {
       {
          host 10.10.10.10 { "classA" }
          host 10.11.10.10 { "classB" }
          network 10.12.0.0/16 { "classB" }
          network 10.13.0.0/16 { "classC" }
       }
    }

    class classA {
       {
          "classA_trx1" { "poolA" }
          "classA_trx2" { "poolB" }
       }
    }

    class classB {
       {
          "classB_trx1" { "poolC" }
          "classB_trx2" { "poolD" }
       }
    }

    class classC {
       {
          "classC_trx1" { "poolE" }
          "classC_trx2" { "poolF" }
       }
    }

    iRule snippet

    
    when CLIENT_DATA {
        set pay1 [TCP::payload 8]
        binary scan $pay1 IA4 len1 trx
         Check if $trx was matched
        if {$trx ne ""}{
             Look up the client IP in the ip to datagroup name datagroup
            set dg [class match -value [IP::client_addr] equals ip_to_dg_name_dg]
        
             Check if there was a match and the datagroup exists
            if {$dg ne "" and [class exists $dg]}{
                 Look up $trx and get the corresponding pool
                set trx_value [class match -value $trx equals $dg]
                 Check if there was a value returned from the class match
                if {$trx_value ne ""}{
                     Do something with the return value, like assign a pool
                    if {[catch {pool $trx_value} result]==0}{
                         Assigned the $trx_value pool successfully, so stop processing the iRule
                        return
                    } else {
                         Failed to assign the $trx_value pool
                    }
                } else {
                     Lookup of $trx in $dg failed
                }
            } else {
                 $dg was not matched or did not exist
            }
        } else {
             $trx was not found
        }
    }

    Aaron
  • Hello Aaron,

     

     

    I want to thank you to spend time for my question. But I the code that you sent is running with only IF clauses, I actually managed to run this scenario with IF clauses and it works well for months.

     

    Can't I do them with switch -globe?

     

     

    Thanks again
  • You can only perform string comparisons with switch. IP::addr does support bitwise address comparisons. I can't see a switch working if you need to support CIDR ranges. If you can do single host or classed networks (class A, B, C) and don't mind the loss of performance you could use switch:

    switch -glob [IP::client_addr] {
       1.1.1.1 {
           client IP was 1.1.1.1, do something
       }
       2.2.2.2 {
           client IP was 2.2.2.2, do something
       }
       2.2.3.* {
           client IP was 2.2.3.x, do something
       }
       2.3.*.* {
           client IP was 2.3.x.x, do something
       }
       default {
           client IP was not matched, do something by default
       }
    }
    

    Aaron