We've talked about variables in the Getting Started with iRules series, but we're going to cover specifically the list object type of variable. Most of the TCL commands for use in manipulating lists are available in iRules:

  • list - Create a list
  • split - Split a string into a proper Tcl list
  • join - Create a string by joining together list elements
  • concat - Join lists together
  • llength - Count the number of elements in a list
  • lindex - Retrieve an element from a list
  • lrange - Return one or more adjacent elements from a list
  • linsert - Insert elements into a list
  • lreplace - Replace elements in a list with new elements
  • lsort - Sort the elements of a list
  • lsearch - See if a list contains a particular element

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 DevCentral.

split

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}]
10:38:30
% set l [split $caTime :]
10 38 30

join

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 .]
140.175.85.68

concat

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
myVip
% set lb_server "myPool 10.10.10.10 443"
myPool 10.10.10.10 443
% set ltmcookie_value [concat $virtual_name $lb_server]
myVip myPool 10.10.10.10 443

lindex

lindex list ?index … ?

This 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]
myVip
% set poolid [lindex $ltmcookie_value 1]
myPool
% set serverid [lindex $ltmcookie_value 2]
10.10.10.10
% set portid [lindex $ltmcookie_value 3]
443

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"
zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn!956498630!-34852364
% set l [split $jsessionID_cookie !]
zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn 956498630 -34852364
% set jsessID [lindex $l 0]
zytPJpxV0TnpssqZZRLBgsVMLhGS6M2ZNMZ622yCNvpv0gkpTwzn

Given that, you should look up the custom iRules command getfield, which is an lindex/split shortcut.