Forum Discussion

Terry_Rodecker_'s avatar
Icon for Nimbostratus rankNimbostratus
Nov 23, 2010

iRule to control snatpool based on destination




I apologize right off the bat for what will most likely be an incredibly easy question. We recently implemented 2 F5 Link Controllers to load balance between ISPs. We had engaged an F5 consultant in May (when we originally purchased them) to configure them for us but the implementation was delayed considerably for reasons I won't get into here. We are getting ready to add a bank of cable modems for additional inbound bandwidth (Internet browsing traffic). Most sites we access aren't firewalled and don't care what IP address we present when we access them. There are a few though that are firewalled and need to see us as our current public IP address. The F5 consultant wrote an iRule that's supposed to work and did work in testing but now that we're getting ready to really start implementing the load balancing I'd like to see if there's an easier or better way to do this.



What I'd like to do is have an iRule that determines the appropriate snatpool to use based on what destination domain you're accessing. For a list of predefined objects it will use the Sprint_gw_pool for example and for all others it will simply use snat automap depending on what link it uses to access that site.



Here's what the F5 consultant wrote for us;





if { [IP::addr [IP::local_addr] equals] }{


snatpool Sprint_X_snat


pool Sprint_gw_pool


} elseif { [IP:addr [IP::local_addr] equals] }{


snatpool Cox_Y_snat


pool Cox_gw_pool


} else {


snat automap }






I also found the following on Devcentral;





if { [matchclass [IP::local_addr] equals $::Subnet1] }{


pool FW1


} elseif { [matchclass [IP::local_addr] equals $::Subnet2] }{


pool FW2


} else { snat automap }





It seems like the second method would be more extensible and easier to manage, I just don't know where to define the Subnet info or if I could use a domain name (not a URI) as the value.



Again, I apologize for what will be a newbie type simple question but I just can't seem to get my head wrapped around the iRule language.



Thanks for any and all help!


5 Replies

  • Hi Terry,



    Which version of code are you running? Do you have an LTM license or just LC?



  • Hi Terry,

    With just a LC license, you can't actually parse the HTTP as HTTP. Nor can you collect the TCP payload to look for the HTTP headers. So you're limited to making layer 4 based decisions. You can use the class command (matchclass has been deprecated in 10.x) to check the source or destination IP address against an address type datagroup and make a pool and/or SNAT decision based on that. In 10.x, make sure to not include the old format of $::datagroup_name. Here's an example for 10.x:

       if {[class match [IP::local_addr] equals destination_ips_1_class]}{
           Do something for this destination IP
       } elseif {[class match [IP::local_addr] equals destination_ips_2_class]}{
           Do something else for this destination IP
       } else {
           Take some default action?

  • Thanks! That looks like exactly what I'm looking for. I can create the datagroup with the subnets of the websites and key off of that. We really only need to make one decision, whether to always force the traffic down one connection or not. I really appreciate your help with this.



    In my searching around yesterday, I seem to remember seeing a thread where someone mentioned a problem using a matchclass with an address based datagroup and it not working or something like that. I can't seem to find that thread now though. Does that sound familiar to you?
  • iRuleYou was having a problem, but I think it was down to a problem with how the datagroup was defined. Just make sure to use an address type datagroup and it should work fine. Here was the post: