Forum Discussion

vbhugra's avatar
vbhugra
Icon for Nimbostratus rankNimbostratus
Nov 10, 2023

SNAT and Next hop based on Node address

I have a requirement wherein I have 2-nodes in a pool; of which 1 node is directly connected to F5 and the other one is behind a layer-3 router.

I want to make an iRule if the directly connected node goes off, it does SNAT Automap and also changes the next-hop.

I tried a couple of options, nothing worked, Please help

1.  when LB_SELECTED {
    if { [IP::addr [LB::server addr] equals 10.222.45.252] } {
   LB::reselect snat automap
   LB::reselect nexthop /DBS/DBS_CLIENT_174 10.219.30.65
  }
  }

2. when CLIENT_ACCEPTED {
if { [IP::addr [serverside {IP::remote_addr}] equals 10.222.45.252] } {
snat automap
nexthop /DBS/DBS_CLIENT_174 10.219.30.65
}
}

  • Hello,
    Correct this iRule and test this one and let me know :

    when LB_SELECTED {
    # Once pool member has been selected check if it's 1.0.0.2
    if { [IP::addr [LB::server addr] equals 1.0.0.2] } {
    snat automap
    }  }
    In this iRule, when a pool member is selected, it checks if the server's IP address (`[LB::server addr]`) is equal to `1.0.0.2`. If the condition is true, it applies the `snat automap` command, enabling automatic SNAT.

    make sure you are assigning specific route for such routed flow for this node. and note that the iRule assumes the IP address `1.0.0.2` is the specific condition you want to match. Make sure to adjust it according to your specific requirement and don't enable snat under such VIP but only this iRule.

    Best,
    MSaeed

  • vbhugra Any particular reason you can't always have a static route for the single host that is behind the router? In addition to that I do not recommend using snat automap and instead I would use a snatpool and then use the IP of the virtual server in question in that snatpool and name that snatpool as SNAT-<VS_IP>. The other thing I would do is create 2 pools, one for the device directly connected to the F5 and then the other with the device that is behind the router. After you have done that you should be able to use the following iRule to accomplish what you would like. Make sure the pool that has the pool member that is directly connected to the F5 is associated as the default pool for the Virtual Server in question.

    when CLIENT_ACCEPTED priority 500 {
    
        set DEFAULT_POOL [LB::server pool]
    
    }
    
    when HTTP_REQUEST priority 500 {
    
        if { [active_members [LB::server pool]] == 0} {
            snatpool SNAT-<VS_IP>
            pool POOL-ServerBehindRouter
        } else {
            pool ${DEFAULT_POOL}
        }
    
    }
    • vbhugra's avatar
      vbhugra
      Icon for Nimbostratus rankNimbostratus

      Hello Paulius,

      The reason for not having a static route is we have clients coming from different interfaces.

      The second thing is we do not have HTTP traffic coming to this VIP.  we have TCP traffic (SQL).

      What else we can have other than HTTP_REQUEST?

      when CLIENT_ACCEPTED priority 500 {

      set DEFAULT_POOL [LB::server pool]

      }

      when <> priority 500 {

      if { [active_members [LB::server pool]] == 0} {
      snatpool SNAT_REP
      pool DBS5G_REP_REMOTE
      nexthop /DBS/DBS_CLIENT_174 10.219.30.65
      } else {
      pool ${DBS5G_REP_LOCAL}
      }

      }

      • Paulius's avatar
        Paulius
        Icon for MVP rankMVP

        vbhugra The following iRule should work for the SQL communication.

        when CLIENT_ACCEPTED priority 500 {
        
            set DEFAULT_POOL [LB::server pool]
        
            if { [active_members [LB::server pool]] == 0} {
                snatpool SNAT-<VS_IP>
                pool POOL-ServerBehindRouter
            } else {
                pool ${DEFAULT_POOL}
            }
        
        }

        I do not see why you cannot have the permanent route in place even if traffic is coming from different interfaces because the way the F5 reaches it will always be the same direction.

  • Hi vbhugra,

    Please try follow step below,

    1. You have to create pool with priority group less than 1 and prefer prioruty on direct node more than other node

    2. Create irule below and apply to virtual server

    when CLIENT_ACCEPTED {
    if { [active_members your-pool] > 2 } {
    snat automap
    }
    }

    or

    when LB_SELECTED {
    if { [IP::addr [LB::server addr] equals 10.222.45.252] } {

    snat automap
    }
    }

     

    https://clouddocs.f5.com/api/irules/LB__server.html

     

    I hope this information will help you

     

    • vbhugra's avatar
      vbhugra
      Icon for Nimbostratus rankNimbostratus

      Hello, 

      I tried what you mentioned but did not work. The thing I observed is my first condition is not working, the second one always works. So I assigned the priority 10.219.45.114 - 30 and 10.222.45.252 - 20.  The Irule does not work. Whereas I changed the priority and moved 10.222.45.252 - 40, it works.

      when LB_SELECTED {
      if { [IP::addr [LB::server addr] equals 10.219.45.114] } {
      node 10.219.45.114
      } else {
      LB::reselect snat automap
      LB::reselect nexthop /DBS/DBS_CLIENT_174 10.219.30.65
      }
      }

       

       

  • Thanks everyone I figured the solution 

     

    when CLIENT_ACCEPTED priority 500 {

    set DEFAULT_POOL [LB::server pool]

    }

    when LB_FAILED priority 500 {

    if { [active_members [LB::server pool]] == 0} {
    LB::reselect snatpool SNAT_REP
    LB::reselect pool DBS5G_REP_REMOTE
    LB::reselect nexthop /DBS/DBS_CLIENT_174 10.219.30.65
    } else {
    pool DBS5G_REP_LOCAL
    }

    }