Forum Discussion

hooleylist's avatar
hooleylist
Icon for Cirrostratus rankCirrostratus
Jun 10, 2008

Using node or pool to change the destination port?

I was trying to adapt the Codeshare example to support HTTP and HTTPS requests on the same VIP (Click here) using a single pool of servers defined on port 0. To do this, I'm attempting to change the port which is used on the server side, after the pool member is selected, but before the serverside connection is established.

I have a few questions:

1. Does the 'pool $pool_name member $ip $port' command require that the specified IP:port is a member of the pool? I don't get any errors when the IP:port isn't but it also doesn't seem to change the destination IP and port. If the IP:port does need to be defined in the pool, why isn't there a runtime error?

2. Is the main technical difference between using the pool and node command that stats would be counted only when using the pool command (and possibly that the IP:port doesn't have to be pre-defined when using the node command)?

3. How does LTM handle destination IP:port selection when using the pool or node command? If you specify a new destination using pool/node before LB_SELECTED, does LTM use that, or will it use load balancing/persistence based on the LB algorithm and/or the persistence profile(s) and/or the default pool on the VIP? Should you be able to specify a new destination IP/port with pool or node in the LB_SELECTED event?

I thought that using node/pool in events before LB_SELECTED would get overridden by LTM in the LB_SELECTED event, but that doesn't seem to be the case. I would have assumed that you'd need to use node or pool in LB_SELECTED to override the default destination selection.

4. In the example below, it looks like the final IP:port selected is 192.168.0.20:2. I thought it would have been 192.168.0.20:8080 as 'node 192.168.0.20 8080' is the last command used to specify the destination. Can you elaborate on what the logic is that results in port 2 being used?

Here is a rule I was using to test on 9.4.4 using a standard HTTP VIP with a single pool member, 192.168.0.20:80.

 
 virtual generic_http_vs { 
    destination 192.168.0.10:http 
    snat automap 
    ip protocol tcp 
    profile http tcp 
    pool test_http_pool 
    rule change_pool_port_rule 
 } 
 

 
 when CLIENT_ACCEPTED priority 250 { 
    log local0. "[IP::client_addr]:[TCP::client_port]: new request to [IP::local_addr]:[TCP::local_port] with pool [LB::server pool]" 
  
    set default_pool [LB::server pool] 
    set a_member "192.168.0.20" 
 } 
 when CLIENT_ACCEPTED { 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: original: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: using 'pool [LB::server pool] member $a_member 1'" 
    pool [LB::server pool] member $a_member 1 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: updated: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: using 'node 192.168.0.20 2'" 
    node 192.168.0.20 2 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: updated: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: using 'pool $default_pool member $a_member 3'" 
    pool $default_pool member $a_member 3 
     
    log local0. "[IP::client_addr]:[TCP::client_port]: updated: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
 } 
 when LB_SELECTED { 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: original: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: using 'pool $default_pool member $a_member 4'" 
    pool $default_pool member $a_member 4 
     
    log local0. "[IP::client_addr]:[TCP::client_port]: updated: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: using 'node 192.168.0.20 8080'" 
    node 192.168.0.20 8080 
  
    log local0. "[IP::client_addr]:[TCP::client_port]: updated: \[LB::server\]: [LB::server], \[LB::server pool\]: [LB::server pool], \[LB::server addr\]: [LB::server addr]" 
 } 
 when SERVER_CONNECTED { 
    log local0. "[IP::client_addr]:[TCP::client_port]: connected to [IP::remote_addr]:[TCP::remote_port]" 
 } 
 when CLIENT_CLOSED { 
    log local0. "[IP::client_addr]:[TCP::client_port]: connected to [IP::server_addr]:[TCP::server_port]" 
 } 
 

=====================

9.4.4 log output:

Rule change_pool_port_rule : 192.168.99.65:3697: new request to 192.168.101.40:80 with pool test_http_pool

Rule change_pool_port_rule : 192.168.99.65:3697: original: [LB::server]: test_http_pool, [LB::server pool]: test_http_pool, [LB::server addr]:

Rule change_pool_port_rule : 192.168.99.65:3697: using 'pool test_http_pool member 192.168.0.20 1'

Rule change_pool_port_rule : 192.168.99.65:3697: updated: [LB::server]: test_http_pool, [LB::server pool]: test_http_pool, [LB::server addr]:

Rule change_pool_port_rule : 192.168.99.65:3697: using 'node 192.168.0.20 2'

Rule change_pool_port_rule : 192.168.99.65:3697: updated: [LB::server]: 192.168.0.20 2, [LB::server pool]: , [LB::server addr]: 192.168.0.20

Rule change_pool_port_rule : 192.168.99.65:3697: using 'pool test_http_pool member 192.168.0.20 3'

Rule change_pool_port_rule : 192.168.99.65:3697: updated: [LB::server]: 192.168.0.20 2, [LB::server pool]: , [LB::server addr]: 192.168.0.20

Rule change_pool_port_rule : 192.168.99.65:3697: original: [LB::server]: 192.168.0.20 2, [LB::server pool]: , [LB::server addr]: 192.168.0.20

Rule change_pool_port_rule : 192.168.99.65:3697: using 'pool test_http_pool member 192.168.0.20 4'

Rule change_pool_port_rule : 192.168.99.65:3697: updated: [LB::server]: 192.168.0.20 2, [LB::server pool]: , [LB::server addr]: 192.168.0.20

Rule change_pool_port_rule : 192.168.99.65:3697: using 'node 192.168.0.20 8080'

Rule change_pool_port_rule : 192.168.99.65:3697: updated: [LB::server]: 192.168.0.20 8080, [LB::server pool]: , [LB::server addr]: 192.168.0.20

Rule change_pool_port_rule : 192.168.99.65:3697: connected to 192.168.0.20:2

Thanks,

Aaron

6 Replies

  • Hi,

     

     

    1. Yes. The pool member must exist in the pool in order to be assigned

     

    2. Sorry, I don't know about the statistics part, but you are correct in that the node command doesn't require a previous pool definition.

     

    3. When assigning a pool to the connection, the LTM will load balance the request based on the load balancing policy that is configured in the pool. LB_SELECTED triggers just after the pool/node statement, so you can't reselect a pool/node after it. That just explains your 4th question.

     

    4. "node 192.168.0.20 2" is the last valid statement in the iRule. I'm sure that "pool $default_pool member $a_member 3" fails because 192.168.0.20:3 is not specified as a pool member in default_pool.

     

    The "node 192.168.0.20 8080" statement is not being used since you can't modify the pool after the LB_SELECTED event.

     

     

    Maybe you can do a LB:reselect, i'll try and see if it works.

     

     

    Regards.

     

  • Thanks for the info. I'll try testing again with that in mind.

     

     

    Aaron
  • I got back to testing this today and think I'm stuck. I'd like to use LTM's pool member selection to pick a pool member, but then change the destination port based on the clientside port requested. To do this, I was hoping to be able to use the node command in LB_SELECTED. However, mgabaldon and testing both indicate you can't do this in LB_SELECTED.

     

     

    Is there a way of modifying the destination port in LB_SELECTED or would I have to do the pool member selection on my own prior to LB_SELECTED?

     

     

    Thanks,

     

    Aaron
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    Looking at the code, doing an LB::reselect with an explicit pool member or node looks like it should work. I can't test this tonight; maybe tomorrow.
  • I was getting TMM restarts on 9.4.4 when trying to use LB::reselect and then node in LB_SELECTED. If you see something different, I'd be interested in seeing it.

     

     

    Thanks,

     

    Aaron
  • Thanks for the example Spark. I was getting the restarts using node I don't think I ran into problems using pool. I'll try it again and open a case.

     

     

    Aaron