This article has been re-released as part of the new Intermediate iRules series in the Handling Lists article.


An iRule is a powerful and flexible feature of BIG-IP devices based on F5's exclusive TMOS architecture. iRules provide you with unprecedented control to directly manipulate and manage any IP application traffic. iRules utilizes an easy to learn scripting syntax and enables you to customize how you intercept, inspect, transform, and direct inbound or outbound application traffic. In this series of tech tips, we'll talk about the TCL language, its usage and control structures, as well as iRule extensions to the TCL language.  Other articles in the series: 


TCL: List Handling Commands

Most of the TCL commands for use in manipulating lists are available in iRules:

The remaining documented list handling commands, lrepeat, lreverse, & dict, are not available within iRules. We’ll cover the commands from above that get the most traffic here on the forums.

Split string ?splitChars?

Returns a list created by splitting string at each character that is in the splitChars argument. Each element of the result list will consist of the characters from string that lie between instances of the characters in splitChars. Empty list elements will be generated if string contains adjacent characters in splitChars, or if the first or last character of string is in splitChars. If splitChars is an empty string then each character of string becomes a separate element of the result list. SplitChars defaults to the standard white-space characters. In this example, split is used to separate the hours/minutes/seconds returned from the formatted clock command into separate list elements: 

% set caTime [clock format [clock seconds] -format {%H:%M:%S}]
% set l [split $caTime :]
10 38 30

Join string ?splitChars?

The list argument must be a valid Tcl list. This command returns the string formed by joining all of the elements of list together with joinString separating each adjacent pair of elements. The joinString argument defaults to a space character. In this example, the user is building the IP address using join and the “.” as the splitChar.

foreach num $IPtmp {
lappend IP [expr ($num + 0x100) % 0x100]
set ::attr_value1 [join $IP .]

Using a TCL shell, the output follows:

% set IPtmp { 0x8c 0xaf 0x55 0x44 }
0x8c 0xaf 0x55 0x44
% foreach num $IPtmp {
lappend IP [expr ($num + 0x100) % 0x100]
% puts $IP
140 175 85 68
% set IP [join $IP .]

concat ?arg arg … ?

This command joins each of its arguments together with spaces after trimming leading and trailing white-space from each of them. If all the arguments are lists, this has the same effect as concatenating them into a single list. It permits any number of arguments; if no args are supplied, the result is an empty string. Here’s an excellent example of concat joining the contents of a cookie with the values from LB::server and virtual name

HTTP::cookie insert path / name ltmcookie value [concat [virtual name] [LB::server]]
using the TCL shell, need variables in place of the calls to [virtual name] and [LB::server]:
% set virtual_name myVip
% set lb_server "myPool 443"
myPool 443
% set ltmcookie_value [concat $virtual_name $lb_server]
myVip myPool 443

lindex list ?index … ?

The lindex command accepts a parameter, list, which it treats as a Tcl list. It also accepts zero or more indices into the list. The indices may be presented either consecutively on the command line, or grouped in a Tcl list and presented as a single argument. This example, from the same iRule as the concat example above, shows the extraction of the list elements into usable variables:

set vipid [lindex [HTTP::cookie ltmcookie] 0]
set poolid [lindex [HTTP::cookie ltmcookie] 1]
set serverid [lindex [HTTP::cookie ltmcookie] 2]
set portid [lindex [HTTP::cookie ltmcookie] 3]
Using the cookie variable we set in the above concat example, we can now extract the list items:
% set vipid [lindex $ltmcookie_value 0]
% set poolid [lindex $ltmcookie_value 1]
% set serverid [lindex $ltmcookie_value 2]
% set portid [lindex $ltmcookie_value 3]

Better to avoid the variables, but a good illustration none-the-less. Often you’ll see split and lindex used together: 

set trimID [lindex [split [HTTP::cookie "JSESSIONID"] "!" ] 0]
Stepping through that, you can see first the split occur, then the indexing:
% set jsessionID_cookie "zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn!956498630!-34852364"
% set l [split $jsessionID_cookie !]
zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn 956498630 -34852364
% set jsessID [lindex $l 0]


Get the Flash Player to see this player.