Forum Discussion

Branden_35485's avatar
Icon for Nimbostratus rankNimbostratus
Jun 14, 2012

LTM v11 iRule Migration

I am trying to upgrade a customer to a new LTM box running v11. There current box is running v10.1.2.



The iRule that they use is not working correctly on v11 or v10.2.3. What happens is when a user clicks on a web page for the first time the iRule runs correctly and the user is presented with the correct webpage in a new window, which is correct. Now if they leave the previous window open and try a different link the iRule runs correctly again.




However, if they close the first window and try a different link the iRule does not run. If you wait approx 60secs and try it again the iRule runs correctly again.




The iRule that they are using I did not create. I know that there are differences for some iRules between versions. I tried looking on F5 knowledge base for the differences and I was unable to locate a difference in the iRule.




So I am just wondering if anyone has run into this issue before? I also am not sure if the iRule is even the problem. So any feed back is appreciate the iRule is posted below.







This iRule parses incoming requests for a particular value in the URI. If present it


will replace the HTTP header and destination IP address with a value retrieved from a


predefined HTTP cookie. It also takes HTTP responses and parses the payload for a


particular string. If present, it will store this value in an HTTP cookie and replace


it with a predefined value.



DevCentral Wiki on HTTP cookie encoding details:


DevCentral for matching on HTTP payload


DevCentral for selecting pool members based on URL Query


DevCentral for using data group list


DevCentral for using stream profiles








Log debug to /var/log/ltm? 1=yes, 0=no.


set debug 0




Disable the stream filter for all requests






Set the node and URL to the value contained in the cookie


if {([string tolower [HTTP::uri]] contains "mastermenu") ||


([string tolower [HTTP::uri]] contains "GISOasis/Login.aspx?Logout=true") ||


([string tolower [HTTP::uri]] contains "oasisaccounting") ||


([string tolower [HTTP::uri]] contains "oasisclaims") ||


([string match -nocase {*DRC[0-9][0-9][0-9][0-9][0-9]*} [HTTP::uri]])} {




Set URL original hostname of Oasis Host


set Cookie_URL [string tolower [HTTP::cookie "DRCShared_IP"]]


HTTP::header replace Host $Cookie_URL




Search for value in data group set list matching Oasis Host


set Cookie_Node [class search -value OASIS_LIST equals $Cookie_URL]




if {$debug != 0} {


log local0. "Node $Cookie_Node is being used for $Cookie_URL"


log local0. "[IP::client_addr]:[TCP::client_port]: Debug enabled on [HTTP::method] request for [HTTP::host][HTTP::uri]"






node $Cookie_Node 80






Prevent the server from sending a compressed response


remove the compression offerings from the client


HTTP::header remove "Accept-Encoding"




Don't allow data to be chunked


if { [HTTP::version] eq "1.1" } {




Force downgrade to HTTP 1.0, but still allow keep-alive connections.


Since 1.1 is keep-alive by default, and 1.0 isn't,


we need make sure the headers reflect the keep-alive status.




Check if this is a keep alive connection


if { [HTTP::header is_keepalive] } {


Replace the connection header value with "Keep-Alive"


HTTP::header replace "Connection" "Keep-Alive"




Set server side request version to 1.0


This forces the server to respond without chunking


HTTP::version "1.0"












Trigger collection for up to 1MB of data


Mandatory for buffering data in HTTP_RESPONSE_DATA


if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{


set content_length [HTTP::header "Content-Length"]


} else {


set content_length 1048576




Check if $content_length is not set to 0


if { $content_length > 0} {


HTTP::collect $content_length






Check if response is a 404 error code and redirect to if it is


if { [HTTP::status] == "404"} {


HTTP::redirect ""






Check for redirect and if location URI::host is present and rewrite to


if { [HTTP::is_redirect] && [string length [URI::host [HTTP::header value Location]]] } {


Replace embedded URL to Oasis Host with URL to VIP of


HTTP::header replace Location [string map -nocase "http:// https:// [URI::host [HTTP::header value Location]]" [HTTP::header value Location]]














Log debug to /var/log/ltm? 1=yes, 0=no.


set debug 0


set found -1




Check for the FQDN of domain oasis.local in the payload


regexp -nocase {GMVM(\d)+\.oasis\.local} [HTTP::payload] found




if {$debug != 0} {


log local0. "[HTTP::payload]"


log local0. "$found is being replaced by"


log local0. "[IP::client_addr]:[TCP::client_port]: Debug enabled" }




if {$found != -1} {


Insert a new cookie with the old host IP name and old cookie's value


HTTP::cookie insert name "DRCShared_IP" value $found domain "" path "/"




Replace embedded URL to Oasis Host with URL to VIP of


STREAM::expression {@http://GMVM(\d)+\.oasis\.local@ @http://gmvm(\d)+\.oasis\.local@}








2 Replies

  • Hi Branden,



    There's a lot going on with that iRule. I'd start by making sure you have a OneConnect profile enabled on the virtual server. If you have SNAT enabled on the virtual server, you can use the default OneConnect profile with a /0 source mask. Else, create a custom OneConnect profile with a /32 source mask. If you still see issues with the iRule, try enabling debug and check the output in /var/log/ltm when a failure occurs.



    That said, there are a few issues/oddities with the iRule:



    1. This condition will never be true as you're setting the URI to lowercase and then checking for a mixed case string:


    ([string tolower [HTTP::uri]] contains "GISOasis/Login.aspx?Logout=true")



    You can replace that whole section with a switch statement to avoid repeating the same [string tolower...] operation on the URI:



     Set the node and URL to the value contained in the cookie
    switch -glob [string tolower [HTTP::uri]] {
    "*mastermenu*" -
    "*gisoasis/login.aspx?logout=true*" -
    "*oasisaccounting*" -
    "*oasisclaims*" -
    "*drc[0-9][0-9][0-9][0-9][0-9]* {



    2. The iRule combines HTTP payload collection with a stream profile. You should either do one or the other but not both. For payload rewriting only, it's more efficient to just use a stream profile. If you need to insert a cookie based on the payload content, I think you'll need to collect the payload.



    3. If the response is a 404, you can just redirect the request and skip the rest of the response logic. So you could move this section to the top of HTTP_RESPONSE and add a return statement to avoid the rest of the code:



    when HTTP_RESPONSE {


    Check if response is a 404 error code and redirect to if it is


    if { [HTTP::status] == 404} {


    HTTP::redirect ""







  • Hi hoolio,



    Thanks for the response. Yes I know there is a lot going on with that iRule.




    I thought I had the default OneConnect Profile enabled however I did not. SNAT is enabled on the virtual server default AutoMap.




    1. This would explain why the Logout button does not work.




    2. I am unfamiliar with stream profiles. Like I said before I did not create this iRule and I am not 100% sure on what is needed. However, I am pretty sure I need to insert a cookie based on payload content. If you could point me in the direction for information or if you could help me out I would greatly appreciate it.




    3. Will move that




    Thanks again.