Forum Discussion

Dustin_132959's avatar
Dustin_132959
Icon for Nimbostratus rankNimbostratus
Sep 30, 2014

1 VIP multiple ports different pools

I have done some research on this and can't seem to find a good way to achieve what I am looking for. I have a scenario where a single VIP must be routed to 3 different nodes based on the port (approximately 800 different ports). It doesn't seem practical to create several hundred virtual servers to achieve this. I saw that this can be done using iRules which I believe will be my best option. However, putting the logic in the iRule for if statements to check for the ports is not very clean and makes it difficult to read through it. So, my thought was to use a data group list to achieve what I am looking for, but it does not appear that I can do ranges in the data group list (or at least I have not found the proper syntax to do it). Here is an example of what I am looking for:

 

[PUBLIC IP] -> 192.168.1.1 TCP: 443, 36008, 18100-18106, 6070, 1099, 5106, 5347, 5269, 36008-36009 UDP: 18101-18105, 18100 [PUBLIC IP] -> 192.168.1.2 TCP: 6800-6802 UDP: 6004-6261 [PUBLIC IP] -> 192.168.1.3 UDP: 6604-7039

 

Is there an easy way that I can achieve this with an iRule? Any assistance is appreciated.

 

Thanks.

 

3 Replies

  • It didn't format the example correctly, let me try it again: [PUBLIC IP] -> 192.168.1.1 TCP: 443, 36008, 18100-18106, 6070, 1099, 5106, 5347, 5269, 36008-36009 UDP: 18101-18105, 18100 [PUBLIC IP] -> 192.168.1.2 TCP: 6800-6802 UDP: 6004-6261 [PUBLIC IP] -> 192.168.1.3 UDP: 6604-7039
  • we had a similar situation... this is what we did:

     

    Code
    `
    
     This event is triggered when a client -> BigIP connection is established
    
    when CLIENT_ACCEPTED {
    
    ` Look in the Clear or the SSL Pools for the TCP port
    if { [ class match [TCP::local_port] equals Data_group1 ] } {
    
         Disable SSL, assign the pool from the class (and optionally log the pool selection)
        SSL::disable
        set app_pool [class match -value -- [TCP::local_port] equals Data_group2 ]
        pool $app_pool
        if { $static::LOG_ACCEPTED_REQ == 1 }{
            log local0. "Cleartext pool selected: [IP::client_addr]:[TCP::client_port] -> [IP::local_addr]:[TCP::local_port] -> $app_pool"
        }
    } elseif { [ class match [TCP::local_port] equals Data_group1 ] } {
    
         Assign the pool from the class (and optionally log the pool selection)
        set app_pool [class match -value -- [TCP::local_port] equals Data_group2 ]
        pool $app_pool
            }   
            } else {
            discard
            if { $static::LOG_DROPPED_REQ == 1 }{
                log local4.info "No pool selected: [IP::client_addr]:[TCP::client_port] -> [IP::local_addr]:[TCP::local_port]"
            }
    }
    `
    
    }
    
    `Code
  • Hi Dustin, You are thinking about create one VIP with any ports, correct?

    You will translate the source port or the members will have the same that original port?

    You intend to do this listening the TCP and UDP and you don't need specific transport layer profiles? SSL offload?

    You will just setup a pool?

    I don't know if the performance will be degraded using proc, the gurus can talk about it, but, in tcl internet samples has a "rswitch" proc that can meet you needs. Maybe the problem in this solution is the "regexp", as this is non performatic.

    I'm afraid about it, is just one idea.
    VIP 10.1.1.1:* / L4 / Any port with Port translation / Any protocol
    
    http://wiki.tcl.tk/4582 
    proc rswitch {value body} {
       set go 0
       foreach {cond script} $body {
          if {[regexp {(.+)\.\.(.+)} $cond -> from to]} {
               if {$value >= $from && $value <= $to} {incr go}
          } else {
              if {$value == $cond} {incr go}
          }
          if {$go && $script ne "-"} { (2)
              uplevel 1 $script
              break
          }
       }
       if {$cond eq "default" && !$go} {uplevel 1 $script} ;(1)
    }
    
    when CLIENT_ACCEPTED {
        set TCP 6
        set UDP 17
        if { [IP::protocol] eq $TCP } {
            call rswitch [TCP::local_port] {
                443 -
                18100..18106 -
                6070 -
                1099 -
                5106 -
                5347 -
                5269 -
                36008..36009 { pool pool_192_168_1_1 }
                6800..6802 { pool pool_192_168_2_1 }
                default { reject }
            }
        } elseif { [IP::protocol] eq $UDP } {
            call rswitch [UDP::local_port] {
                18100 -
                18101..18105 { pool pool_192_168_1_1 }
                6004..6261 { pool pool_192_168_2_1 }
                6604..7039 { pool pool_192_168_3_1 }
                default { reject }
            }
        } else {
            reject
        }
    }