Forum Discussion

ibehavior_37902's avatar
ibehavior_37902
Icon for Nimbostratus rankNimbostratus
Aug 31, 2010

Load balance on source ip address

Hello -

 

 

I need to be able to load balance incoming traffic to one of 4 back end pools based on some part of the source IP address. I have found several examples of how to do this at the subnet level but this is an internet facing device and I could get traffic from any subnet. A suggestion what to use some portion of the IP address, like the last octet and load balance based on the value.

 

For example:

 

000 - 064 - Pool_1

 

065 - 128 - Pool_2

 

129 - 192 - Pool_3

 

193 - 255 - Pool_4

 

 

Another thought was to do a MD5 hash on the source IP address but I did not have any luck finding any information on this.

 

 

Any help would be appreciated, kind of new to the F5's

 

 

Thanks

 

 

Dan

 

  • Hoolio wrote something up for SNATing based on the 3rd Octet...that logic could easily be ported over...if I find time today, I'll try writing something up

    http://devcentral.f5.com/Forums/tabid/1082223/asg/52/showtab/groupforums/afv/topic/aff/31/aft/813179/Default.aspx

    
     
      when CLIENT_ACCEPTED {  
        
          Use a local array to configure the 5 SNAT addresses  
         set snat_ips(0) 1.1.1.1  
         set snat_ips(1) 2.2.2.2  
         set snat_ips(2) 3.3.3.3  
         set snat_ips(3) 4.4.4.4  
         set snat_ips(4) 5.5.5.5  
        
          Use getfield to parse the third octet from the client IP address  
          Get the modulus of the third octet against the number of the SNAT IPs in the array  
         set snat_number [expr {[getfield [IP::client_addr] "." 3] % [array size snat_ips]}]  
         log local0. "Client IP: [IP::client_addr], SNAT number $snat_number, SNAT IP: $snat_ips($snat_number)"  
        
          Apply the SNAT  
         snat $snat_ips($snat_number)  
      }  
      
  • Quick mod....test it out and see whether it works for you...I pretty much just did find and replace so I very well may have missed something.

      when HTTP_REQUEST {  
        
          Use a local array to configure the 4 pools 
         set pool_choice(0) pool_1 
         set pool_choice(1) pool_2 
         set pool_choice(2) pool_3 
         set pool_choice(3) pool_4 
         
        
          Use getfield to parse the third octet from the client IP address  
          Get the modulus of the third octet against the pool members in the array  
         set pool_number [expr {[getfield [IP::client_addr] "." 3] % [array size pool_choice]}]  
         log local0. "Client IP: [IP::client_addr], Pool number $pool_number, Pool Choice: $pool_choice($pool_choice)"  
        
          choose a pool
         pool $pool_choice($pool_number)  
      }  
    
  • Chris -

     

     

    Thank you for the quick reply! We are not currently using SNAT and I am not sure I want to change what is currently working...

     

     

    What do you think about this which I modified from this http://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/108/iRules-Optimization-101--01--if-elseif-and-switch.aspx

     

     

    I believe that this will route an traffic with the IP address ending in 1 or 2 to pool_1 and any traffic with the IP address ending in 3 or 4 to pool_2 and so on.

     

    when CLIENT_ACCEPTED {

     

    Determine which pool based on last digit of Clinet IP Address

     

    switch -regexp [IP::client_addr ] {

     

    ".*[1,2]$" { pool pool_1 }

     

    ".*[3,4]$" { pool pool_2 }

     

    ".*[5,6]$" { pool pool_3 }

     

    ".*[7,8]$" { pool pool_4 }

     

    ".*[9,0]$" { pool pool_5 }

     

    }

     

    }

     

     

    Thanks

     

  • Hi Dan,

     

    I would avoid using regex. Another method is to use lindex and split tcl commands

     

     

     

    when CLIENT_ACCEPTED {

     

    set ip4 [lindex [split [IP::client_addr] "."] 3]

     

    if { ($ip4 >= 0) and ($ip4 < 65) } {

     

    pool pool_1

     

    } else if { ($ip4 >= 65) and ($ip4 < 129) } {

     

    pool pool_2

     

    } else if { ($ip4 >= 129) and ($ip4 < 193) } {

     

    pool pool_3

     

    } else if { ($ip4 >= 193) and ($ip4 < 256) } {

     

    pool pool_4

     

    }

     

    }

     

     

     

    This is untested of course

     

     

    I hope this helps

     

     

    Bhattman
  • Bhattman -

     

     

    Thank you for the reply. Might I ask why you are against regular expressions?

     

  • Hi Dan,

     

    I'm actually not against it's use, but avoid it all costs because Regular expressions are very CPU intensive. It would certainly be the only option I would use if I can't find another method.

     

     

    Bhattman