Forum Discussion

Chris_Miller's avatar
Chris_Miller
Icon for Altostratus rankAltostratus
Jun 11, 2010

Most efficient way to do if, else?

Good morning all, This snippet is part of an http_response event. The rule compares the IP of the server responding to datagroups to see which pool the server is in. Based on that, the rule sets a cookie. I'm curious about the most efficient method to do this. I've read (but not completely understood) using switch, elseif, and glob are all options. Here's what I have right now:

if { [matchclass [IP::server_addr] equals $::dg_pool_2A1] } { 
set strPodNumber "2A1" 
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2A2] } { 
set strPodNumber "2A2"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2B1] } { 
set strPodNumber "2B1"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2B2] } { 
set strPodNumber "2B2"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2C1] } { 
set strPodNumber "2C1"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2C2] } { 
set strPodNumber "2C2"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2D1] } { 
set strPodNumber "2D1"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2D2] } { 
set strPodNumber "2D2"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2E1] } { 
set strPodNumber "2E1"
} elseif { [matchclass [IP::server_addr] equals $::dg_pool_2E2] } { 
set strPodNumber "2E2"
}
Here's what I was thinking, with glob, but haven't validated will work:

switch -glob [matchclass[[IP::server_addr]] {
$::dg_pool2A1 {set strPodNumber "2A1"}
{$::dg_pool2A2 {set strPodNumber "2A2"}
{$::dg_pool2B1 {set strPodNumber "2B1"}
{$::dg_pool2B2 {set strPodNumber "2B2"}
{$::dg_pool2C1 {set strPodNumber "2C1"}
{$::dg_pool2C2 {set strPodNumber "2C2"}
{$::dg_pool2D1 {set strPodNumber "2D1"}
{$::dg_pool2D2 {set strPodNumber "2D2"}
{$::dg_pool2E1 {set strPodNumber "2E1"}
{$::dg_pool2E2 {set strPodNumber "2E2"}

5 Replies

  • Hi Chris,

     

     

    Which version are you running? If you're on pre-10.10 I think you'd need to continue with the if/elseif/.../else chain you have above. switch will only allow you to check one string against a list of cases.

     

     

    If you're on 10.1.0 or higher you can use a new "value" option in an address type datagroup to store the strPodNumber as that value. You could then combine all of the IP addresses/ranges into a single datagroup and then use the class command to search that datagroup. See this post for details:

     

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=1167195&ptarget=1167195

     

     

    Aaron
  • Posted By hoolio on 06/11/2010 05:46 AM

     

    Hi Chris,

     

     

    Which version are you running? If you're on pre-10.10 I think you'd need to continue with the if/elseif/.../else chain you have above. switch will only allow you to check one string against a list of cases.

     

     

    If you're on 10.1.0 or higher you can use a new "value" option in an address type datagroup to store the strPodNumber as that value. You could then combine all of the IP addresses/ranges into a single datagroup and then use the class command to search that datagroup. See this post for details:

     

     

    http://devcentral.f5.com/Default.aspx?tabid=53&view=topic&postid=1167195&ptarget=1167195

     

     

    Aaron

     

     

    I'm running 10.2. I'll check that link and reply if I have another question about how to use it. Thanks!
  • I've created a "dg_all_pools" of address-type in which I have all the addresses and their corresponding "strPodNumber. So, essentially, 1.1.1.1:2A1, etc. I'm a bit fuzzy on my syntax now...I know I need to set strPodNumber to the corresponding value corresponding to the address. So, I need to compare IP::server_addr to the datagroup and use the class command to set strPodNumber to the corresponding value...can you help point me in the right direction? Here's my swing at it...I don't quite understand the difference between class match and class search. Can I use class match - value or is -value reserved for class match?
    set strPodNumber "[class search -value [[IP::server_addr] equals $::dg_pool_all]]"
  • The IP/subnet should be added to the datagroup and then set the value for that IP and/or subnet of 2A1 or whatever the strPodNumber is. Then you can use the class command to return the corresponding value:

    The datagroup will look like this in the bigip.conf:

    
      class private_net {
         {
            host 1.1.1.1 { "2A1" }
            network 2.2.2.0/24 { "2A1" }
            host 3.3.3.1 { "2A2" }
            network 4.4.4.0/24 { "2A2" }
         }
    }
    

    And an iRule snippet which references the class:

    
     Look up the server address in the dg_all_pools class and save the corresponding value
    set match [class search -value dg_all_pools equals [IP::server_addr]]
    if {$match ne ""}{
        do something with the match
    }
    

    Aaron