Forum Discussion

James_Thomson's avatar
Apr 11, 2005

intelligent SNAT using server_selected

I read post http://devcentral.f5.com/default.aspx?tabid=28&view=topic&forumid=5&postid=1540 and it was helpful. I am trying to do the same type of thing, but add 1 more piece. I have a BIG-IP with external and internal vlans. Each, their own subnet. There is 1 virtual server.

If a connection comes from vlan 1 and is getting load balanced to a server on vlan 1, then it needs to get snat'd for bounceback reasons. If a connection comes from vlan 2 and is getting load balanced to a server on vlan 1, then it should not get snat'd.

The same is true in the opposite sense. Connection from vlan 1 getting load balanced to a server in vlan 2 should not get snat'd, but a connection from vlan 2 getting load balanced to a server in vlan 2 needs to be snat'd.

I have a SNAT automap defined and SNAT enabled in the pool which is the default.

I'm trying to create a rule that is triggered when the BIG-IP selects a server (SERVER_SELECTED) because I would then write a rule like if client IP and server_selected IP are on the same subnet, then snat, otherwise, continue on through the virtual server/pool, which I would then turn snat off for.

I'm getting an error that the SERVER_SELECTED event is unknown.

line 1: [unknown event (SERVER_SELECTED)] [when SERVER_SELECTED

I used LB_SELECTED and it accepted this, but I don't know if that happens after a server is selected so that if I use IP::server_addr, it will pick the real server's IP address.

If I figure that out, I think this would get the trick done.

when SERVER_SELECTED { 
 if {[IP::client_addr] equals "[IP::server_addr]/255.255.255.0"} { 
 snat}} 
 

It doesn't seem like it will let me just do just the command "snat" at the end, so I might have to change it to SNAT none and then leave SNAT on the pool. That means that I will have to change the rule context to say if the client_addr does NOT match the server_addr, snat none. Will the operand != work to compare those?

If I change it to lb_selected, then I case use

when LB_SELECTED { 
 if {[IP::client_addr] != "[IP::server_addr]/255.255.255.0"} { 
 snat none}}

I need to test to see if this works.

Any ideas?

4 Replies

  • Actually, I just read another post and figured I could do this:

    when LB_SELECTED { 
     if {[IP::client_addr] equals "[IP::server_addr]/255.255.255.0"} { 
     snat automap} 
     else { 
     snat none} 
     } 
     

    I will try that. I guess SERVER_SELECTED was replaced by LB_SELECTED?
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Yes, SERVER_SELECTED was replaced by LB_SELECTED along time ago, docs has just been playing catchup.

    My only other concern is your comparison of IP addresses. It doesn't work to simply use '==' or '!=' as Tcl treats those as string comparisons. Obviously with network masks, this doesn't apply very well. So, there is a command IP::addr that is used for comparing IP addresses.

    Here is your example updated to use IP::addr for the comparisons:

     
     when LB_SELECTED { 
        if {[IP::addr "[IP::client_addr]/24" equals "[IP::server_addr]/24"]} { 
           snat automap 
        } else { 
           snat none 
        } 
     } 
     

    At this point, I'm not certain if IP::server_addr is available at the time of LB_SELECTED or if you need to get it from the "LB::server addr" command.
  • So, I updated with this:

    when LB_SELECTED { 
     if {[IP::addr "[IP::client_addr]/24" equals "[LB::server addr]/24"]} { 
     snat automap 
     log "snat automap" 
     } 
     else { 
     snat none 
     log "snat none"}} 
     

    You were right, IP::server_addr was not available. So, I thought this would work without defining a snat automap in the SNATS section, but it doesn't. It logs the correct way, but the command "snat automap" does not trigger the snat'ing. If I create a snat automap through the SNAT's section, it gets automapped every time, even though I see it log "snat none" in /var/log/ltm, it doesn't seem to be running the snat none command.

    So, the if command is working ok, but the snat commands are not.

    I even tried changing it to this and taking off the snat I had defined.

     
     when LB_SELECTED { 
     if {[IP::addr "[IP::client_addr]/24" equals "[LB::server addr]/24"]} { 
     use snat automap 
     log "snat automap" 
     }} 
     

    It logs "snat automap", but it does not snat it.

    Any ideas?

  • I spoke with support and the fact that the irule does not snat the packet was a bug and was fixed with a hotfix and will be fixed in the next release.

    When I applied the hotfix, it worked with this rule:

     
     when LB_SELECTED {  
      if {[IP::addr "[IP::client_addr]/24" equals "[LB::server addr]/24"]} {  
      snat automap 
      }}