Forum Discussion

Jasa_74968's avatar
Jasa_74968
Icon for Nimbostratus rankNimbostratus
Mar 31, 2014

Stop processing iRule by referencing a variable

I've set a variable in iRule named "stop_rule_processing" and its value is set to 1 if a particular iRule has a hit:

priority 300
when HTTP_REQUEST { 
   if { [string tolower [HTTP::path]] starts_with "/staging" } { 
      if { !([matchclass [IP::client_addr] equals IP_private_access])} { 
         log local0. "Source address [IP::client_addr] not from Private pool, session discarded" } {
         discard 
         set stop_rule_processing 1 
      }
   }
}

The other iRule check if that variable is set to 1 and if it is i want to use "event disable" stop rule processing immediately:

when HTTP_REQUEST { 
    switch -glob [string tolower [HTTP::path]] {
     "/staging*" {
      log local0. "PreProd URL detected from [IP::client_addr] , sending to preprod pool"
      pool PL-staging-pool
     }
     "/production*" {
      log local0. "Prod URL detected [IP::client_addr] , sending to prod pool"
      pool PL-production-pool
     }
  }

}


However I don't know how to check that variable at the beginning of second rule. I've tried to use multiple syntax versions of "if" command but can't get the syntax right.

10 Replies

  • You need to ensure the variable is set to 0 if it's not set to 1 - so maybe in CLIENT_ACCEPTED;-

    when CLIENT_ACCEPTED {
        set stop_rule_processing 0
    }
    

    Then in your other iRule you just need to say

    if {$stop_rule_processing} {
        event disable
        return
    }
    
  • Thanks IheartF5, what I can't figure out is the syntax of how to call on the variable in the second rule that uses switch.
    
    I'm ok to change that to if/elseif conditional if that would make it easy, but at the moment I simply don't know how to get my second iRule to parse
    
  • Hi Jasa,

     

    Can you try this? Also, event disable all will stop all future iRule events from triggering for the rest of the connection. The client could continue making additional HTTP requests after the current one and those will not be processed by any iRule. If you only want to skip running the iRule code from the second iRule for that request, you could use just 'return' instead.

     

    Aaron

     

    when HTTP_REQUEST {
    
        if {$stop_rule_processing==1}{
            event disable all
            return
        }
        switch -glob [string tolower [HTTP::path]] {
         "/staging*" {
          log local0. "PreProd URL detected from [IP::client_addr] , sending to preprod pool"
          pool PL-staging-pool
         }
         "/production*" {
          log local0. "Prod URL detected [IP::client_addr] , sending to prod pool"
          pool PL-production-pool
         }
      }
    
    }
  • I've tried what you suggested hoolio and the variable gets assigned, but unfortunately it doesn't stop processing in the second rule. I've tried both "return" and "event disable" and the staging pool still gets assigned and clients are given access regardless of where they're coming from.

     

    What I'd like to achieve is filter access to "staging" environment to be allowed only for internal users defined by the address data group.

     

    I thought those two iRules will do the trick, but they aren't.

     

  • Can you try this for your first rule and then add a log statement to your second iRule to see if it is successfully avoided altogether?

    priority 300
    when HTTP_REQUEST { 
        if { [string tolower [HTTP::path]] starts_with "/staging" } { 
            if { !([matchclass [IP::client_addr] equals IP_private_access])} { 
                log local0. "Source address [IP::client_addr] not from Private pool, session discarded" } {
                discard 
                event disable all
                return
            }
        }
    }
    

    Aaron

  • Tried that and I get 2 hits in the log:
        - first one from the "discard" rule (Source address x.x.x.x not from Private pool, session discarded)
        -second one from the following iRule that assigns pool (Staging URL detected from Client:123.243.180.52 , sending to staging pool)
    
    And access to application is unfortunately allowed.
    
  • Just to test can you try reject instead of discard?

     

    Thanks, Aaron

     

  • Tried reject, same entries in the log, same result for the client

     

  • Which LTM version are you running? I did a quick test on 11.4.1 and reject; event disable all, return; works as expected.

    Can you open a case with F5 Support on this. It should "just work".

     tmsh list ltm rule reject*
    ltm rule reject_1_rule {
        when HTTP_REQUEST {
            if {[HTTP::uri] starts_with "/reject"}{
                    log local0. "Calling reject"
                    reject
                    event disable all
                    return
                    log local0. "Called reject"
            }
    }
    when HTTP_REQUEST priority 501 {
            log local0. "Called reject (501)"
    }
    }
    ltm rule reject_2_rule {
        when HTTP_REQUEST {
            log local0. "reject_2_rule"
    }
    }
    

    /var/log/ltm output showing the second iRule doesn't get triggered:

    Mar 31 20:47:30 ve11a info tmm1[8891]: Rule /Common/reject_1_rule : Calling reject
    Mar 31 20:47:30 ve11a err tmm1[8891]: 01230140:3: RST sent from 10.1.0.120:80 to 10.1.0.111:46397, [0x1776da3:4998] iRule execution (reject command)
    

    If I comment out the return statement in the first iRule, I see the rest of that event executed but not anything from the second iRule. This is expected.

    If I comment out the return and event disable all statement in the first iRule, I see the rest of iRule 1 executed as well as the second iRule. This is also expected.

    Aaron

  • I'll open a case because my code is 11.4.1 HF2 so I'd expect it to work similar as yours. Thanks for all the effort mate.