Forum Discussion
data group iRule
- Apr 09, 2014
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 } } }
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
static::
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 a static::
namespace variable is visible in an iRule executing for any connection serviced by the TMM in which the value is set. That's why static:
: namespace variables are usually declared in RULE_INIT
. Each TMM instance independently executes the RULE_INIT
event. Thus, if, in an iRule -- I'll call it ruleA --, you have the following:
RULE_INIT {
set static::somevar 10
}
then an instance of
static::somevar
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 access $static::somevar
, as well.
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
RULE_INIT
. This is, however, almost always a bad idea, and may produce an unexpected and undesirable result. Let us say that you had the following:
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 '
after
' command (as well as a few others) suspends the execution of a connection and allow another connection to proceed. That other connection will potentially set static::ip
before the first connection is un-suspended.
The general rule is, only set static:: variables once, and only in the
RULE_INIT
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 a static::
namespace variable that is set to 0 if you don't want debug logging, and 1 if you do, as in:
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
static::debug
in ruleA to 1 and static::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:
when RULE_INIT {
set static::ruleA_debug 1
}
when CLIENT_ACCEPTED {
if { $static::ruleA_debug } { log ... }
}
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