Forum Discussion

Richard__Harlan's avatar
Historic F5 Account
Dec 01, 2011

adding iRule

Has anyone got a more complex iRule to add through iApps? WHen trying the the following iRule into a config I get the following error



script did not successfully complete: (can't read "source_addr": no such variable


while executing


"set irule_buffer "{




set source_addr \[IP::client_addr\]


set dest_ip_port \[IP::loca..."


invoked from within


"if { $irule_firewall == $YES_ANSWER } {


set irule_firewall_rule $::basic__irule_firewall_rule


set rule [ split $irule_firewall_rule ; ]


..." line:83)





set source_addr \[IP::client_addr\]/


set dest_ip_port \[IP::local_addr\]:\[TCP::local_port\]/


log local0. \"Source = $source_addr Dest_IP:Port = $dest_ip_port\"/


set dest_addr \[class match -value -- \[IP::client_addr\] equals test\]/


log local0. \"Class info - $dest_addr\"/


if { $dest_addr != $dest_ip_port || $dest_addr equals \"\" } {/




log local0. \"Rest connection from $source_addr to $dest_ip_port\"/







I have been playing with this for a while and no matter how I escape the iRule the iApp TCL is treating the iRule Tcl not as a variable but as code to run. Any help would be great.





1 Reply

  • Brent_Blood_768's avatar
    Historic F5 Account
    Hi Richard,



    Embedding an iRule written in TCL into the implementation script written in TCL can be daunting - you have to escape all the square and curly braces and dollar signs in order to avoid the TCL interpreter running the implementation script from treating it like TCL that it should act on. For anything more than a trivial iRule, I recommend taking a look at this:





    It's a templating system that lets you avoid all of the escaping and really makes it easier to handle large/complicated iRules in iApps.



    Anyways, I gave your rule a shot and was able to get it to import. My code looks like this:



    set code "when CLIENT_ACCEPTED \{\n"
    append code "set source_addr \[IP::client_addr\]\n"
    append code "set dest_ip_port \[IP::local_addr\]:\[TCP::local_port\]\n"
    append code "log local0. \"Source = \$source_addr Dest_IP:Port = \$dest_ip_port\"\n"
    append code "set dest_addr \[class match -value -- \[IP::client_addr\] equals test\]\n"
    append code "log local0. \"Class info - \$dest_addr\"\n"
    append code "if \{ \$dest_addr != \$dest_ip_port || \$dest_addr equals \"\" \} \{\n"
    append code " reject\n"
    append code "   log local0. \"Rest connection from \$source_addr to \$dest_ip_port\"\n"
    append code "  \}\n"
    append code "\}"
    tmsh::create ltm rule rh { $code }



    There are other ways to do it - and repeatedly using "append" isn't the prettiest - but I was able to get the rule to create. The biggest change I made was to escape all of the dollar signs and curlies as you were missing a couple.