Forum Discussion

crouch_62389's avatar
crouch_62389
Icon for Nimbostratus rankNimbostratus
Feb 26, 2008

SNAT persistance with Outbound Load Balancing

Hi all,

I need some help with what seems to be a quite straight forward outbound persistance request.

We use the F5 to load-balance our outbound traffic equally between our two

ISP connections. An irule assigns a SNAT address to outgoing requests in a round robin fashion.

First outbound request gets a SNAT IP Address of ISP-A and the second request gets a SNAT IP address of ISP-B The irule then forwards the packet to the correct ISP router depending on the SNAT address.

The problem is that certain websites do not accept requests that change ip addresses constantly.

The question is how can I ensure that the outgoing traffic persists? I have tried using persist dest_addr but it does not work with this rule.

when RULE_INIT {

set ::gl_gw_isp_vb "x.x.x.x"

set ::gl_gw_isp_nc "x.x.x.x"

if { [info exists ::gl_snat_isp_vb ] }

{

unset ::gl_snat_isp_vb

}

if { [info exists ::gl_snat_isp_nc ] }

{

unset ::gl_snat_isp_nc

}

set ::gl_snat_isp_vb(x.x.x.x) "a.a.a.a"

set ::gl_snat_isp_nc(x.x.x.x) "b.b.b.b"

}

when LB_SELECTED {

Find internal servers with Static SNAT defined and

change the SNAT address based on the gateway selected

automatically by the pool

log local0. "Event : LB_SELECTED, client_addr is [IP::client_addr]"

We assume that if the client_addr is in

gl_snat_isp_vb, it is in gl_snat_isp_nc too.

if { [info exists ::gl_snat_isp_vb([IP::client_addr])] }

{

log local0. "SNAT found for [IP::client_addr]"

if { [LB::server addr] eq $::gl_gw_isp_vb }

{

log local0. "SNAT [IP::client_addr] natt'ed to $::gl_snat_isp_vb([IP::client_addr]), via ISP VB"

snat $::gl_snat_isp_vb([IP::client_addr])

persist dest_addr

}

elseif { [LB::server addr] eq $::gl_gw_isp_nc }

{

log local0. "SNAT [IP::client_addr] natt'ed to $::gl_snat_isp_nc([IP::client_addr]), via ISP NC"

snat $::gl_snat_isp_nc([IP::client_addr])

persist dest_addr

}

else

{

log local0. "Error : unknown LB Server : [LB::server addr], for Client : [IP::client_addr]"

}

}

else

{

log local0. "SNAT NOT found for [IP::client_addr]"

}

}

when CLIENT_ACCEPTED {

Find internal ip address for which we "force" the pool

unless this ip address must be snat'ed

log local0. "Event CLIENT_ACCEPTED, client_addr is [IP::client_addr]"

We assume that if the client_addr is in

gl_snat_isp_vb, it is in gl_snat_isp_nt too.

if { ![info exists ::gl_snat_isp_vb([IP::client_addr])] }

{

log local0. "client_addr ([IP::client_addr]) must not be natt'ed, check if we must force the outbound pool"

if { [matchclass [IP::client_addr] equals $::network_force_pool_isp_vb] }

{

log local0. "Force Pool ISP VB for IP [IP::client_addr]"

pool VB_default_pool

} elseif { [matchclass [IP::client_addr] equals $::network_force_pool_isp_nc] }

{

log local0. "Force Pool ISP NC for IP [IP::client_addr]"

pool NC_default_pool

} else

{

log local0. "No Need to force Pool for IP [IP::client_addr]"

}

}

else

{

log local0. "client_addr ([IP::client_addr]) must be natt'ed, nothing to do on event CLIENT_ACCEPTED"

}

persist dest_addr

}

3 Replies

  • Hi,

     

     

    With your iRule, do you see any entry in statistics > Persistence records through the GUI ?

     

     

    If it doesn't work with the dest_addr you may try to use this command:

     

     

    persist uie [serverside {IP::remote_addr}]

     

     

    That should do the same thing (you should see some entries in statistics > Persistence records through the GUI)

     

     

    Morover do you need the persistence to be applied among several vs ? if yes you'll need to add some data :

     

     

    persist uie {[serverside {IP::remote_addr}] any virtual}

     

     

    HTH

     

     

     

     

     

  • Hi,

     

     

    With the dest_addr command I did not view any statistics.

     

     

    However when I used

     

     

    persist uie {[serverside {IP::remote_addr}] any virtual}

     

     

    I saw stats but I did not get the required result. So i changed to client;

     

     

    persist uie {[clientside {IP::client_addr}] any virtual}

     

     

    and this appears to be working.

     

    For example whenIgo to whatsmyaddress.com it returns the same IP address when I perform a constant refresh.

     

     

    Whereas, before it would give an alternating address on a constant refresh.

     

     

    Thanks for your help

     

     

    Mark

     

     

  • Hi,

     

     

    Yes it should work too. The thing here is that a client will always use the same outbound link with this persistence

     

     

    If it's fine for you then it's cool!