Forum Discussion

Wil_Schultz_101's avatar
Wil_Schultz_101
Icon for Nimbostratus rankNimbostratus
Jul 02, 2007

My iRule stopped working?!

I've got an irule that (to the best of my knowledge anyway) has been working for quite some time, for some strange reason part of it stopped working yesterday. Here is what it looks like:


when HTTP_REQUEST {
 if { [matchclass [IP::remote_addr] equals $::private_net] } {
  use pool my_pool
 }
 switch -glob [string tolower [HTTP::uri]] {
  
  }
  default {
   pool myother_pool
  }
 }
}

In the class private_net I have defined: 192.168.0.0 / 255.255.0.0

I set up a logging trap and put it at the end of the switch:

    
default {
 set remoteip [IP::remote_addr]
  log local0. "my.com, $remoteip"
  pool myother_pool
 }

And receive the following in my log:

Jul 2 14:28:30 tmm tmm[1026]: Rule my : my.com, 192.168.22.57

Can anyone shed some light on this? This is a security feature I have set up which is bypassed at the moment.
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    I think you may have been caught by a common misperception: The "pool" command in v9 doesn't terminate request processing and send the traffic immediately to the pool as it did in v4.

     

     

    Since your conditions are not mutually exclusive, and the last pool selected is the one to which traffic will be sent, I'd bet the "failure" you are seeing is that the requests matching the private IP list but not matching your specified switch URIs are hitting the default condition and going to "myother_pool" rather than to "my_pool".

     

     

    You can verify that by placing a similar log statement inside the "if" command to verify that the first condition is evaluating as you expect, and if it's what I suspect, you can correct the problem by enclosing the switch in a "else" clause to the existing "if" command.

     

     

    HTH

     

    /deb

     

     

  • Interesting.... I could have sworn that this worked in the past.

     

     

    So, I suppose if I wrap the rest in an elseif it will work.
  • Posted By wschultz on 07/02/2007 4:20 PM

    Interesting.... I could have sworn that this worked in the past.

    So, I suppose if I wrap the rest in an elseif it will work.

    Yup, looks okay like this:

    
    when HTTP_REQUEST {
     if { [matchclass [IP::remote_addr] equals $::private_net] } {
      use pool my_pool
     }
     elseif { [HTTP::uri] starts_with "/" } {
      switch -glob [string tolower [HTTP::uri]] {
       
       }
       default {
        pool myother_pool
       }
      }
     }
    }
  • Posted By wschultz on 07/02/2007 4:28 PM

    Posted By wschultz on 07/02/2007 4:20 PM

    Interesting.... I could have sworn that this worked in the past.

    So, I suppose if I wrap the rest in an elseif it will work.

    Yup, looks okay like this:

    
    when HTTP_REQUEST {
     if { [matchclass [IP::remote_addr] equals $::private_net] } {
      use pool my_pool
     }
     elseif { [HTTP::uri] starts_with "/" } {
      switch -glob [string tolower [HTTP::uri]] {
       
       }
       default {
        pool myother_pool
       }
      }
     }
    }

    Okay, so I might be crazy but I definitely tested this rule last night and it worked great.

    Yet again this morning the irule stopped working?!

    What is happening is when I hit the VIP from $::private_net I am being send to myother_pool instead of mypool.

    I guess I could make it something like below, but I'm perplexed as to why my rule will work at some times while not at others. Am I experiencing expected behavior?

    
    when HTTP_REQUEST {
     if { [matchclass [IP::remote_addr] equals $::private_net] } {
      use pool my_pool
     }
     elseif {! [matchclass [IP::remote_addr] equals $::private_net] } {
      switch -glob [string tolower [HTTP::uri]] {
       
       }
       default {
        pool myother_pool
       }
      }
     }
    }
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Logging will help you see what's going on.

    (You shouldn't need to invert your first condition in the else clause -- it's implied when it failed the "if" part.)

    I'd test with a simpler rule that includes logging at every decision point, then add conditions as necessary, again logging in each until you have it working the way you want. Start here:
    when HTTP_REQUEST {
      if {[matchclass [IP::remote_addr] == $::private_net]}{
        log local0. "Matched on client IP [IP::remote_addr]"
        pool my_pool
      } else {
        log local0. "No match on client IP [IP::remote_addr]"
        pool myother_pool
      }
    }

    HTH

    /deb

  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    The tcl "return" command will cause an exit from the calling event. (In this case, would end processing of HTTP_REQUEST when called.)

     

     

    However, I'd still probably use the "else" clause though, since it's really clear then how the logic is intended to flow.

     

     

    HTH

     

    /deb