Forum Discussion

ML_108504's avatar
ML_108504
Icon for Nimbostratus rankNimbostratus
Apr 13, 2009

iRule Editor can't find default_pool

Hi folks, I'm experimenting with some simple iRules (I thought) from devcentral examples. When I check the following iRule in the Editor it complains with:

line 5: [can't find pool] [pool default_pool]

I assumed that the 'default_pool' string corresponded to, effectively, a variable representing the default pool for the virtual running the iRule. I want to write this iRule once and apply it to dozens of virtuals, obviously I don't want an individual iRule for each pool, what am I missing? (Hopefully something simple and obvious).

  
 when HTTP_REQUEST {  
 if { [matchclass [string tolower [HTTP::header User-Agent]] contains $::bots] } {  
 pool p_PUB_botfarm  
 } else {  
 pool default_pool  
 }  
 }

Save the noob! (thank you)

15 Replies

  • It might be nice to get the default pool of the VIP using a special command, but 'LB::server pool' does tell you this if you check in CLIENT_ACCEPTED.

     

     

    I'm not sure what you're trying to accomplish with 'event disable'. That's going to prevent your iRule from firing the HTTP_REQUEST event on subsequent requests on the same TCP connection. I assume a bot and non-bot probably aren't going to be making requests over the same TCP connection. But if they did, disabling the event would prevent you from changing the pool from whatever pool was selected previously. You could use return (Click here) to exit that event in that iRule.

     

     

    Aaron
  • Thanks for the feedback Denny! I see what you're saying and will test. I'm not sure why I'd need the default pool for the rule as it is now, but will keep that in mind (at least, I'm all clear on how to do that, cheers).

     

     

    @hoolio:

     

    Right! I was hoping that using event disable would be an efficiency here; it would be acceptable if a handful of connections somehow ended up going to the bot farm when it shouldn't or vice versa. However, 'return' looks like a safer option, and the load imparted by the iRule running on every HTTP_REQUEST event shouldn't be very significant (based on how much similar iRule processing load we're incurring now, which isn't much).

     

    Excellent guys, thanks for the help! I'm testing today and we'll see what happens.
  • OK, we tested our iRule using curl from a handful of individual hosts. The iRule did exactly what we wanted it to do: sent all http requests with bot user-agent strings to our botfarm and all other connections to the default pool.

    We tried using both the 'return' and 'event disable' statements and saw no difference between them, although since the 'event disable' should only be triggering for connections not matching the bots data group, the evidence may have slipped past us.

    If it were possible to cajole this iRule into only executing once per connection (rather than once per http request) for bots, that'd be ideal (and maybe fantasy).

    In any case, we're rolling on this pretty well right now. We didn't see any adverse impact to leaving out an explicit lb::server command, if anyone can speak more about that concern, please do!

    Thanks to everyone who chimed in here!

       
     when HTTP_REQUEST {   
     if { [matchclass [string tolower [HTTP::header User-Agent]] contains $::bots] } {   
     if { [active_members p_PUB_botfarm] > 0 } {   
     pool p_PUB_botfarm   
     } else {   
     event disable   
     }   
     }   
     }   
     

    EDIT: Aaron, can you suggest a convenient way to validate the behavior you suspect with using 'event disable' here? Cheers!
  • So the issue I was thinking of is resolved when using a OneConnect profile. If you don't use a OneConnect profile then you should explicitly set a pool in all cases if you specify a pool in any case. This is described in some detail in SOL9800:

    SOL9800: Using an iRule to load balance HTTP requests to multiple pools

    https://support.f5.com/kb/en-us/solutions/public/9000/800/sol9800.html (Click here)

    To reproduce the issue where a request goes to the last pool specified instead of the VIP's default pool (without a OneConnect profile enabled on the VIP), you can use a simple test rule which selects pool1 for requests which have pool1 in the path and does not specify another pool for non-matching requests:

     
     when HTTP_REQUEST { 
      
        log local0. "[IP::client_addr]:[TCP::client_port]: New request to URI\ 
           [HTTP::uri] (Request [HTTP::request_num] on this TCP connection)." 
      
        if {[HTTP::path] starts_with "/pool1"}{ 
           log local0. "[IP::client_addr]:[TCP::client_port]: Matched /pool1 in URI, using irule_pool" 
           pool irule_pool 
        } else { 
           log local0. "[IP::client_addr]:[TCP::client_port]: iRule check didn't match [HTTP::uri], doing nothing" 
        } 
     } 
     when LB_SELECTED { 
        log local0. "[IP::client_addr]:[TCP::client_port]: Selected pool info: [LB::server]" 
     } 
     when SERVER_CONNECTED { 
        log local0. "[IP::client_addr]:[TCP::client_port]: Selected pool info: [LB::server]" 
     } 
     when SERVER_CLOSED { 
        log local0. "Selected pool info: [LB::server]" 
     } 
     

    Make three requests on the same TCP connection to /pool0, /pool1 and then /pool2, using curl on the LTM command line

    $ curl '10.0.0.10/pool[0-2]'

    No OneConnect (third request goes to the "wrong" pool)

    : 10.10.10.10:3127: New request to URI /pool0 (Request 1 on this TCP connection).

    : 10.10.10.10:3127: iRule check didn't match URI /pool0, doing nothing.

    : 10.10.10.10:3127: Selected pool info: default_pool 2.2.2.2 80

    : 10.10.10.10:3127: Selected pool info: default_pool 2.2.2.2 80

    :10.10.10.10:3127: Selected pool info: default_pool 2.2.2.2 80

    : 10.10.10.10:3127: New request to URI /pool1 (Request 2 on this TCP connection).

    : 10.10.10.10:3127: Matched /pool1 in URI, using pool1 (irule_pool).

    : 10.10.10.10:3127: Selected pool info: irule_pool 1.1.1.1 80

    : Selected pool info: default_pool 2.2.2.2 80 (Server connection for first request is closed here)

    : 10.10.10.10:3127: Selected pool info: irule_pool 1.1.1.1 80

    : 10.10.10.10:3127: Selected pool info: irule_pool 1.1.1.1 80

    : 10.10.10.10:3127: New request to URI /pool2 (Request 3 on this TCP connection).

    : 10.10.10.10:3127: iRule check didn't match URI /pool2, doing nothing.

     

    : 10.10.10.10:3127: Selected pool info: irule_pool 1.1.1.1 80

     

    : Selected pool info: irule_pool 1.1.1.1 80

    Note that the third request goes to the iRule pool even though you might expect it to go to the default pool on the virtual server as the iRule does not match the requested path. If you add a OneConnect profile, the default pool is used for the first and third requests, as you would probably expect.

    Aaron