Forum Discussion
rjordan
Nimbostratus
May 04, 2011Stop processing iRule if condition is met?
I have an existing iRule that directs traffic to various pools based on the host name. It was requested that connections from specific source IPs be directed to specific nodes. I added this functionality in the CLIENT_ACCEPTED event in the iRule but the node decision seems to be "overridden" during the HTTP_REQUEST event. Is there a way to stop processing the rule in my IF statement? Or should move the IF statement into the HTTP_REQUEST?
Below is a simplified version of the iRule. Please excuse minor syntax issues, I just wrote it so you can see the basic functionality and flow.
when CLIENT_ACCEPTED {
if { [IP::client_addr] equals 1.2.3.4 } {
node 192.168.10.10 80
}
}
when HTTP_REQUEST {
if { [HTTP::host] contains domain1.com {
pool domain1.com_pool
}
elseif { [HTTP::host] contains domain2.com {
pool domain2.com_pool
}
else {
pool domain.com_pool
}
}
9 Replies
- rjordan
Nimbostratus
I also tried the rule below but it behaves the same way. I need any request from 1.2.3.4 to direct to 192.168.10.10 80, regardless of the hostname. Instead, it is directing the request to one of the pools.when HTTP_REQUEST { if { [IP::remote_addr] equals 1.2.3.4 } { node 192.168.10.10 80 } if { HTTP::host contains "domain1.com" } { pool domain1.com_pool } elseif {HTTP::host contains "domain2.com" } { pool domain2.com_pool } else { pool domain.com_pool } } - Colin_Walker_12Historic F5 AccountTry this:
when CLIENT_ACCEPTED { set httpfunctions 1 if { [IP::client_addr] equals 1.2.3.4 } { node 192.168.10.10 80 unset httpfunctions } } when HTTP_REQUEST { if { [info exists httpfunctions]} { if { [HTTP::host] contains domain1.com { pool domain1.com_pool } elseif { [HTTP::host] contains domain2.com { pool domain2.com_pool } else { pool domain.com_pool } } }
Basically you want to do an event disable, but only for the context of this iRule, not all the HTTP_REQUEST events in all the iRules. So this should get you there.
Colin - rjordan
Nimbostratus
Hey Colin,
Your example does work but it is a bit more complex than I thought I needed. I saw in the documentation that if multiple conditions are met, the last pool specified will be used. For some odd reason, I thought that node command would be handled differently. In any case, I just moved the new IF statement below my hostname stuff and it works. Below is what I'm using.when HTTP_REQUEST { if { HTTP::host contains "domain1.com" } { pool domain1.com_pool } elseif {HTTP::host contains "domain2.com" } { pool domain2.com_pool } elseif { [IP::remote_addr] equals 1.2.3.4 } { node 192.168.10.10 80 } else { pool domain.com_pool } } - Matt_Breedlove_
Nimbostratus
This seems like one of these should work. Will need syntax correction most likely
The third one is probably the best one, since the return will mean that its only checked during tcp setup, no need to check every GET/POST request, but it won't hurt on an underutilized LTM.
Return works well for stopping processing of the current irule, and its nice that if there are multiple irules assocated to a VS, the return only exits execution of the current irule, so other irules still execute
Maybe there is an issue using 'return' after a node call, assumption is not, since clearly the original rule is continuing to apply even after tcp setup for subsequent GET/POST requests?
Hope this helpswhen HTTP_REQUEST { if { [IP::remote_addr] equals 1.2.3.4 } { node 192.168.10.10 80 return } if { HTTP::host contains "domain1.com" } { pool domain1.com_pool } elseif {HTTP::host contains "domain2.com" } { pool domain2.com_pool } else { pool domain.com_pool } }
or thiswhen HTTP_REQUEST { if { [IP::remote_addr] equals 1.2.3.4 } { node 192.168.10.10 80 } else { if { HTTP::host contains "domain1.com" } { pool domain1.com_pool } elseif {HTTP::host contains "domain2.com" } { pool domain2.com_pool } else { pool domain.com_pool } } }
this is the closest to the originalwhen CLIENT_ACCEPTED { if { [IP::client_addr] equals 1.2.3.4 } { node 192.168.10.10 80 return } } when HTTP_REQUEST { if { [HTTP::host] contains domain1.com { pool domain1.com_pool } elseif { [HTTP::host] contains domain2.com { pool domain2.com_pool } else { pool domain.com_pool } } - rjordan
Nimbostratus
Yeah, I think return should do the trick. I will probably use this in other iRules where I can't simply manipulate the order of the statements. For now, my current iRule is working properly. I would estimate only .01% of the requests actually match the IP, so I don't expect much more load than doing it in CLIENT_ACCEPTED. Thanks Colin and Matt for all the suggestions. - Colin_Walker_12Historic F5 AccountI was just trying to keep the node command up in the CLIENT_ACCEPTED event where you put it originally. If you're okay with moving it to the end of the if/else chain, then that's definitely the simplest solution.
Just keep in mind that it doesn't take priority this way. Since it's in an if/else chain, it only gets fired if one of the conditions above it are not met. What I mean is, in my example if you get a request from 1.2.3.4 to domain1.com, it will get directed to the particular node as you desired. In your example, it will get sent to the pool that all other domain1.com requests are sent to.
Colin - Colin_Walker_12Historic F5 AccountAs far as the return command, that will probably work but I'd want to test it to be sure it kicks you all the way out of the iRule every time, not just out of the CLIENT_ACCEPTED event.
Like I said, it should work, I just like to use more explicit statements usually. ;)
Colin - hoolio
Cirrostratus
return will only exit the current event in the current rule. If you want to prevent all subsequent iRule events from any iRule on the virtual server from running, you can use 'event disable all'. Or if you want to do it just for select code in this or another rule on the same virtual server, you could set a variable in CLIENT_ACCEPTED and then check the value in subsequent code before running it.
http://devcentral.f5.com/wiki/default.aspx/iRules/return
http://devcentral.f5.com/wiki/default.aspx/iRules/event
Aaron - Colin_Walker_12Historic F5 AccountSee, I knew I was leery for a reason, I just couldn't recall (since I rarely use return) and didn't get to testing it yet (whee conference calls!).
Thanks for the info Aaron, now I don't feel dumb for forgetting about return as an option here...since it's not. ;)
Colin
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
