Forum Discussion

wpduhe_174647's avatar
wpduhe_174647
Icon for Nimbostratus rankNimbostratus
Oct 20, 2014

10.2.4 LB::reselect doesn't seem to work

I have the below iRule that will change the destination port to a specific node in a pool. The log messages show up in the /var/log/ltm file indicating that the "if" statement works and the variables are set to the proper values. However, when the traffic is forwarded from the backside interface, the TCP port has not been incremented. I have contacted support and they confirm that this iRule works. Can anyone help?

when LB_SELECTED {

if { [IP::addr [LB::server addr] equals 10.234.133.222] } {
set port [clientside {TCP::local_port}]
log local0.debug "Port = $port"
set new_port [expr {$port + 1}]
log local0.debug "New port is $new_port"
LB::reselect node 10.234.133.222 $new_port
 }

}

9 Replies

  • BinaryCanary_19's avatar
    BinaryCanary_19
    Historic F5 Account

    Does 10.234.133.222 $new_port actually exist in the pool?

    I ask this because I think that LB:: commands typically are going to apply to the pool configured on the virtual server, or previously choosen with the "pool" command.

    Yours is a truly odd requirement, but I think that the way to accomplish what you wish to accomplish is to make the selection earlier than LB_SELECTED (and not use LB::reselect), and then use the "node" command directly.

    So for example, your irule look like:

    `when CLIENT_ACCEPTED {
        get the relevant port number
        Call the node command to point to the IP address and server
    
    }`
    

    Possibly also since you seem to need the IP address of the server that the LTM will normally load balance to, instead of calling LB::reselect in your current irule, call LB::detach instead, and then call "node" to send the traffic to your desired server and IP address.

    https://devcentral.f5.com/articles/irules-101-05-selecting-pools-pool-members-and-nodes

    • BinaryCanary_19's avatar
      BinaryCanary_19
      Historic F5 Account
      when LB_SELECTED { if { [IP::addr [LB::server addr] equals 10.234.133.222] } { set port [clientside {TCP::local_port}] log local0.debug "Port = $port" set new_port [expr {$port + 1}] log local0.debug "New port is $new_port" LB::detach node 10.234.133.222 $new_port } } This is a modification of your original irule, to call LB::detach, and then node . If LB::detach gives you any errors remove it (I haven't verified if LB_SELECTED is fired before or after the server-side connection is established) -- so if LB::detach gives you an error, it is most likely because there is not yet a server-side connection, and thus the command is unnecessary.
  • Yes. The IP exists in the pool, but the members are set to listen on any port.

    There are two nodes in the pool and the load balancing method is observed(member) (Probably should be observed(node)), but that is why I'm trying to do this after the load balancing decision has been made. By defining what node to use at Client_Accepted I negate the load balancing. Essentially, if srvA is chosen I want to use the original destination port, but if srvB is selected the port must be incremented by one (it has something to do with the application design). We have attempted to use Client_Accepted, the rule was like this:

    when CLIENT_ACCEPTED {

    eval [LB::select]
    if { [IP::addr [LB::server addr] equals 10.234.133.222] } {
    set port [clientside {TCP::local_port}]
    log local0.debug "Port = $port"
    set new_port [expr {$port + 1}]
    log local0.debug "New port is $new_port"
    node 10.234.133.222 $new_port
    

    } }

    Using this rule, however, I never saw the log messages for this rule in /var/log/ltm and using a tcpdump, no traffic was ever forwarded from the backside interface when a connection was attempted to the VIP. It was as if the iRule stopped the traffic processing on that VIP all together. Perhaps the eval statement didn't have anything to evaluate and that is why log messages never appeared and no traffic was forwarded?

    We will certainly try the LB::detach idea today. Thanks for the input. It is much appreciated. I will follow up with my results later.

    • BinaryCanary_19's avatar
      BinaryCanary_19
      Historic F5 Account
      Note, you will never see a log message in your irule above because: LB::server addr will not equal 10.234.133.222 -- it probably doesn't exist yet.
  • can you try something like this?

     configuration
    
    root@ve10(Active)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.9:any
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            tcp { }
        }
        rules {
            qux
        }
        snat automap
    }
    root@ve10(Active)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:any { }
            200.200.200.111:any { }
        }
    }
    root@ve10(Active)(tmos) list ltm rule qux
    ltm rule qux {
        when CLIENT_ACCEPTED {
      set pick [LB::select]
      log local0. "pick=$pick"
      set ip [lindex [split $pick " "] 3]
      log local0. "ip=$ip"
      switch $ip {
        200.200.200.101 {
          node $ip [TCP::local_port]
        }
        200.200.200.111 {
          node $ip [expr {[TCP::local_port] + 1}]
        }
        default {
           do something
        }
      }
    }
    when SERVER_CONNECTED {
      log local0. "client=[IP::client_addr]:[TCP::client_port] \
        virtual=[clientside {IP::local_addr}]:[clientside {TCP::local_port}] \
        server=[IP::server_addr]:[TCP::server_port]"
    }
    }
    
     /var/log/ltm
    
    [root@ve10:Active] config  tail -f /var/log/ltm
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : pick=pool foo member 200.200.200.111 0
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : ip=200.200.200.111
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : client=172.28.24.1:32828  virtual=172.28.24.9:80  server=200.200.200.111:81
    
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : pick=pool foo member 200.200.200.101 0
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : ip=200.200.200.101
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : client=172.28.24.1:32829  virtual=172.28.24.9:80  server=200.200.200.101:80
    
  • can you try something like this?

     configuration
    
    root@ve10(Active)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.9:any
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            tcp { }
        }
        rules {
            qux
        }
        snat automap
    }
    root@ve10(Active)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:any { }
            200.200.200.111:any { }
        }
    }
    root@ve10(Active)(tmos) list ltm rule qux
    ltm rule qux {
        when CLIENT_ACCEPTED {
      set pick [LB::select]
      log local0. "pick=$pick"
      set ip [lindex [split $pick " "] 3]
      log local0. "ip=$ip"
      switch $ip {
        200.200.200.101 {
          node $ip [TCP::local_port]
        }
        200.200.200.111 {
          node $ip [expr {[TCP::local_port] + 1}]
        }
        default {
           do something
        }
      }
    }
    when SERVER_CONNECTED {
      log local0. "client=[IP::client_addr]:[TCP::client_port] \
        virtual=[clientside {IP::local_addr}]:[clientside {TCP::local_port}] \
        server=[IP::server_addr]:[TCP::server_port]"
    }
    }
    
     /var/log/ltm
    
    [root@ve10:Active] config  tail -f /var/log/ltm
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : pick=pool foo member 200.200.200.111 0
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : ip=200.200.200.111
    Oct 21 22:20:16 local/tmm info tmm[4955]: Rule qux : client=172.28.24.1:32828  virtual=172.28.24.9:80  server=200.200.200.111:81
    
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : pick=pool foo member 200.200.200.101 0
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : ip=200.200.200.101
    Oct 21 22:20:38 local/tmm info tmm[4955]: Rule qux : client=172.28.24.1:32829  virtual=172.28.24.9:80  server=200.200.200.101:80
    
  • Kudos to everyone here for these outstanding suggestions! Excellent work! Below is what I ultimately used to accomplish my goal.

    when CLIENT_ACCEPTED {
        set pick [LB::select]  
        set ip [lindex [split $pick " "] 3]  
        switch $ip {  
          10.234.133.221 {
           node $ip [TCP::local_port]
           persist uie "[IP::local_addr]:[TCP::local_port]"
          }
          10.234.133.222 {
           node $ip [expr {[TCP::local_port] + 1}]
           persist uie "[IP::local_addr]:[TCP::local_port]" 
          }
          default {
            do something
          }
        }
    }