Forum Discussion
Brian_Herr_1028
Nimbostratus
Feb 13, 2007Changing destination pool TCP port via iRules
Nickel tour: In order to change the destination port on a flow we have to define the pool, member, and port as the destination in the iRule. We need to be able to define the pool and port and let the load balancing choose the member.
Detailed explanation:
We need to change the destination port of a TCP flow before it hits a load balanced pool member using iRules. The first suggestion everyone has to this problem is to use a pool for each server port destination. The problem is that in our environment it would require thousands of pools. So the basic logic is this. Based upon data with in the TCP flow a lookup takes place against a data class. The goal is to pick a pool and have it choose the member based upon the pool definition and member/service availability and then change the destination port based upon the iRule. The data class can change based on business logic so on next connect the session could be moved to a different port or pool combination. All the documentation we have found points to one of these three scenarios:
1. Pool [pool_name] --> load balanced per pool definition
2. Pool [pool_name] member [member_name] --> specify a pool and a certain member w/ no intelligent load balancing or service checking
3. Pool [pool_name] member [member_name]:[port] --> specify a pool, a certain member and port w/ no intelligent load balancing or service checking
What we are looking for is a way to have the flexibility and features of the pool and yet change the destination port when it hits the pool member. And changing SNATs on the fly would not be a good solution. An example solution would be to set a variable that is the result of load balancing decision and then using that in the Pool [pool_name] member [dynamic_member_variable]:[port] statement. If someone knows how to do that let me know. The other option would be a feature enhancement for Pool [pool_name]:[port] or Pool [pool_name] member [some keyword for LB result]:[port]. The last suggestion everyone has is to do a round robin load balance in the rules. That is not fault tolerant so that is out the window as well. Our short term solution is to have a pool defined with members that have the ports changed and we manually load balance the flows and manually move traffic in case of server failures. This method defeats the purpose of an intelligent load balancer/front end processor.
Any ideas are greatly appreciated.
- JRahm
Admin
This takes a class that has special TCP payload data that is mapped to a specific destination port. TCP is collected and analyzed for that special data, if it exists, findclass will pull out the appropriate port number and set the variable new_port, which you can then use in the LB_SELECTED event to direct to the appropriate pool member. Is this what you're looking for?class port_map { "special_data1 port1" "special_data2 port2" "special_data3 port3" ... "special_data1500 port 1500" } when CLIENT_ACCEPTED { TCP::collect XX } when CLIENT_DATA { if { [TCP::payload XX] contains "myData" } { set new_port [findclass [TCP::payload XX] $::port_map " " ] } TCP::release } when LB_SELECTED { pool [LB::server pool] member [LB::server addr] $new_port }
- Corey_Smith_174
Nimbostratus
Using this rule set:when CLIENT_ACCEPTED { set dport [TCP::local_port] if { [lsearch $dport [list 12005]] != -1 } { TCP::collect 1 return } } when CLIENT_DATA { if { [TCP::payload] contains "myData" } { set new_port 12007 } TCP::release } when LB_SELECTED { pool member [LB::server addr] $new_port }
- JRahm
Admin
Sorry about that, you'll need [LB::server pool]. I edited my earlier post. - Corey_Smith_174
Nimbostratus
This rule properly changes the destination port: - Corey_Smith_174
Nimbostratus
Of course it works in CLIENT_ACCEPTED but that doesn't particularly matter if you want to make load balancing decisions in CLIENT_DATA. We are looking for the ability to read the first message from the socket and then to change the destination port while still letting the F5 select which node to load balance to. - unRuleY_95363Historic F5 AccountPlease try Colin's suggestion with your rule:
when CLIENT_ACCEPTED { set dport [TCP::local_port] if { [lsearch $dport [list 12005]] != -1 } { TCP::collect 1 return } } when CLIENT_DATA { if { [TCP::payload] contains "myData" } { set new_port 12007 } TCP::release } when LB_SELECTED { LB::reselect pool [LB::server pool] member [LB::server addr] $new_port }
- Corey_Smith_174
Nimbostratus
01070151:3: Rule [Test_LB] error: - Brian_Herr_1028
Nimbostratus
Has this feature been implemented yet? We are still eagerly awaiting this ability. - Deb_Allen_18Historic F5 AccountIf you mean the ability to reselect in LB_SELECTED, then Yes, I know it works in LTM v9.4, perhaps earlier versions as well.
- Brian_Herr_1028
Nimbostratus
If what you are describing is the ability to select a pool and then some method to let the LTM select the member but we change the node destination port then I will be very excited to see it work. I'll upgrade a box to 9.4.1 shortly and test it out. I hope this works. We are coming under the gun to find some way to get this running. Thanks for the help.
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects