Forum Discussion
data group iRule
Hello iExperts,
I just wanted to double check with you the following irule where i want to double check that the client IP is in a determinate data group range of IPs (ecmvpn_ip_dg) and if so, return a HTTP 302 redirect to such client. Is it the correct and "optimized" way to do it?
when RULE_INIT {
set static::ecmvpn_flag 0
}
when CLIENT_ACCEPTED {
if { [class match [IP::client_addr] equals ecmvpn_ip_dg] } {
set static::ecmvpn_flag 1
}}
when HTTP_REQUEST {
if {$static::ecmvpn_flag==1}{
HTTP::redirect http://ecmvpn.[HTTP::uri]
return
}
switch -glob [string tolower [HTTP::host]] {
"ecm.domain"
{
if { ([HTTP::uri] starts_with "/APPLICATION")} {
HTTP::header insert USER-IP [IP::remote_addr]
persist cookie insert
pool DCTM_ECM_APPLICATION _APPLICATION PORT_PROD (or PREP)
return
}
}
default { return }
}
}
Hi you don't need to use static variables - just use a TCP connection scoped variable set in CLIENT_ACCEPTED. Not too sure what you want from the switch ...anyway updated slightly
when CLIENT_ACCEPTED { set ecmvpn_flag 0 if { [class match [IP::client_addr] equals ecmvpn_ip_dg] } { set ecmvpn_flag 1 } } when HTTP_REQUEST { if {$ecmvpn_flag}{ You need an FQDN here so I've added ".com.au" HTTP::redirect http://ecmvpn.com.au[HTTP::uri] return } switch -glob [string tolower [HTTP::host]] { "ecm.*" { if {[string tolower [HTTP::uri]] starts_with "/application"} { HTTP::header insert USER-IP [IP::remote_addr] You could just use an HTTP persistence profile attached to the virtual for this persist cookie insert pool pl_DCTM_ECM_APPLICATION return } } default { return } } }
- IheartF5_45022Nacreous
Hi you don't need to use static variables - just use a TCP connection scoped variable set in CLIENT_ACCEPTED. Not too sure what you want from the switch ...anyway updated slightly
when CLIENT_ACCEPTED { set ecmvpn_flag 0 if { [class match [IP::client_addr] equals ecmvpn_ip_dg] } { set ecmvpn_flag 1 } } when HTTP_REQUEST { if {$ecmvpn_flag}{ You need an FQDN here so I've added ".com.au" HTTP::redirect http://ecmvpn.com.au[HTTP::uri] return } switch -glob [string tolower [HTTP::host]] { "ecm.*" { if {[string tolower [HTTP::uri]] starts_with "/application"} { HTTP::header insert USER-IP [IP::remote_addr] You could just use an HTTP persistence profile attached to the virtual for this persist cookie insert pool pl_DCTM_ECM_APPLICATION return } } default { return } } }
Cool, yes sure, dynamic variable is easier.
Thanks a lot.
- Vernon_97235Historic F5 Account
Just to be clear, "static" in this context isn't really the opposite of "dynamic", but rather the opposite of "automatic". A variable declared in the
namespace is stored in a TMM scoped memory location and exists for the entire run of that TMM instance. Automatic variables exist for the duration of a connection. As a side-effect of this, the value of astatic::
namespace variable is visible in an iRule executing for any connection serviced by the TMM in which the value is set. That's whystatic::
: namespace variables are usually declared instatic:
. Each TMM instance independently executes theRULE_INIT
event. Thus, if, in an iRule -- I'll call it ruleA --, you have the following:RULE_INIT
RULE_INIT { set static::somevar 10 }
then an instance of
will be created in each TMM's memory space (independently), and the value will be set to 10. This value is globally visible across connections executing on each TMM. That is, if there is another iRule -- I'll call it ruleB --, then that iRule could accessstatic::somevar
, as well.$static::somevar
In every regard, these are normal variables. Most importantly, their value can be altered after being set, and they can be created or altered outside of
. This is, however, almost always a bad idea, and may produce an unexpected and undesirable result. Let us say that you had the following:RULE_INIT
when CLIENT_ACCEPTED { set static::ip [IP::client_addr] ... }
then, on each connection, you are setting the value of a variable that is globally visible to the TMM serving that connection. Particularly before 11.4, because of TMM's thread model, I assume you won't really run into problems until you do something like this:
when CLIENT_ACCEPTED { set static::ip [IP::client_addr] after 1000 log local0. "client is $static::ip" }
The '
' command (as well as a few others) suspends the execution of a connection and allow another connection to proceed. That other connection will potentially setafter
before the first connection is un-suspended.static::ip
The general rule is, only set static:: variables once, and only in the
event. That is, treat them (in Java-speak) like static final variables. Also, beware of using generic identifiers. For example, let's say in your various iRules, you create aRULE_INIT
namespace variable that is set to 0 if you don't want debug logging, and 1 if you do, as in:static::
when RULE_INIT { set static::debug 1 } when CLIENT_ACCEPTED { if { $static::debug } { log local0. "Connect from client [IP::client_addr]" }
Let's say you do that in both ruleA and ruleB. Now let's say you change
in ruleA to 1 andstatic::debug
in ruleB to 0.static::debug
is global to the TMM instance, so it can only have one of those two values. It will ultimately have the value of whichever of the two iRules loaded last. In this way, you could accidentally turn on debugging for an iRule that is not being debugged, and adversely affect system performance. It would be better to do this:static::debug
when RULE_INIT { set static::ruleA_debug 1 } when CLIENT_ACCEPTED { if { $static::ruleA_debug } { log ... } }
- JGCumulonimbus"Particularly before 11.4, because of TMM's thread model" Will you please expand on this? I thought it was 11.3.0 when a multi-threaded architecture started to be used.
- Vernon_97235Historic F5 AccountQuite right. And to clarify, I don't know whether threading affects the behavior of the static namespace.
- VernonWellsEmployee
Just to be clear, "static" in this context isn't really the opposite of "dynamic", but rather the opposite of "automatic". A variable declared in the
namespace is stored in a TMM scoped memory location and exists for the entire run of that TMM instance. Automatic variables exist for the duration of a connection. As a side-effect of this, the value of astatic::
namespace variable is visible in an iRule executing for any connection serviced by the TMM in which the value is set. That's whystatic::
: namespace variables are usually declared instatic:
. Each TMM instance independently executes theRULE_INIT
event. Thus, if, in an iRule -- I'll call it ruleA --, you have the following:RULE_INIT
RULE_INIT { set static::somevar 10 }
then an instance of
will be created in each TMM's memory space (independently), and the value will be set to 10. This value is globally visible across connections executing on each TMM. That is, if there is another iRule -- I'll call it ruleB --, then that iRule could accessstatic::somevar
, as well.$static::somevar
In every regard, these are normal variables. Most importantly, their value can be altered after being set, and they can be created or altered outside of
. This is, however, almost always a bad idea, and may produce an unexpected and undesirable result. Let us say that you had the following:RULE_INIT
when CLIENT_ACCEPTED { set static::ip [IP::client_addr] ... }
then, on each connection, you are setting the value of a variable that is globally visible to the TMM serving that connection. Particularly before 11.4, because of TMM's thread model, I assume you won't really run into problems until you do something like this:
when CLIENT_ACCEPTED { set static::ip [IP::client_addr] after 1000 log local0. "client is $static::ip" }
The '
' command (as well as a few others) suspends the execution of a connection and allow another connection to proceed. That other connection will potentially setafter
before the first connection is un-suspended.static::ip
The general rule is, only set static:: variables once, and only in the
event. That is, treat them (in Java-speak) like static final variables. Also, beware of using generic identifiers. For example, let's say in your various iRules, you create aRULE_INIT
namespace variable that is set to 0 if you don't want debug logging, and 1 if you do, as in:static::
when RULE_INIT { set static::debug 1 } when CLIENT_ACCEPTED { if { $static::debug } { log local0. "Connect from client [IP::client_addr]" }
Let's say you do that in both ruleA and ruleB. Now let's say you change
in ruleA to 1 andstatic::debug
in ruleB to 0.static::debug
is global to the TMM instance, so it can only have one of those two values. It will ultimately have the value of whichever of the two iRules loaded last. In this way, you could accidentally turn on debugging for an iRule that is not being debugged, and adversely affect system performance. It would be better to do this:static::debug
when RULE_INIT { set static::ruleA_debug 1 } when CLIENT_ACCEPTED { if { $static::ruleA_debug } { log ... } }
- JGCumulonimbus"Particularly before 11.4, because of TMM's thread model" Will you please expand on this? I thought it was 11.3.0 when a multi-threaded architecture started to be used.
- VernonWellsEmployeeQuite right. And to clarify, I don't know whether threading affects the behavior of the static namespace.
Recent Discussions
Related Content
* 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