Forum Discussion

PiotrL's avatar
PiotrL
Icon for Cirrus rankCirrus
Dec 18, 2015

iRule size limitation

Hi, iRules are limited to 65,520 characters (SOL9204). Is there any way to split an oversized irule into 2 irules ? I have a following irule (each client is directed to its own port on a server 10.55.55.55):

 

when CLIENT_ACCEPTED {

 

switch -glob [IP::client_addr] {

 

"10.10.10.11" {node 10.55.55.55 10001}

 

"10.10.10.12" {node 10.55.55.55 10002}

 

...

 

"10.x.x.x {node 10.55.55.55 1xxxx}

 

}

 

}

 

Configuring 2 irules as above with different client to server lines is not working. Is there any solution for this limitation (without configuring 2nd vs) ?

 

3 Replies

  • Write a new iRule where you use Data Group.

    ltm data-group internal data_www.someapp.com_sourceIP_destPort_pairs {
        records {
            10.10.10.11/32 {
                data 10001
            }
            10.10.10.12/32 {
                data 10002
            }
        }
        type ip
    }
    

    iRule:

    when CLIENT_ACCEPTED {
    
          if { [class match [IP::client_addr] equals data_www.someapp.com_sourceIP_destPort_pairs] }{
            node 10.55.55.55 [class match -value [IP::client_addr] equals data_www.someapp.com_sourceIP_destPort_pairs]
          }
    }
    

    Thats all you need, and it will achieve the same results of your 65k digit Switch-Monster.

  • Hi Piotr,

    If you need to split an existing iRule because of the 64k limit, then you have to consider not to break the syntax of each independent script. In addition you may include an additional condition, so that the second script would only be triggered if the first script wasn't successful. This would increase the performance very much.

    iRule 1:

    when CLIENT_ACCEPTED priority 400 {
        switch -glob [IP::client_addr] {
            "10.10.10.11" {node 10.55.55.55 10001}
            "10.10.10.12" {node 10.55.55.55 10002}
            ....
            "10.10.10.253" {node 10.55.55.55 10241}
            "10.10.10.254" {node 10.55.55.55 10242} 
        }
    }
    

    iRule 2:

    when CLIENT_ACCEPTED priority 401 {
        if { [LB::server name] eq "" } {
            switch -glob [IP::client_addr] {
                "10.10.11.11" {node 10.55.55.55 11001}
                "10.10.11.12" {node 10.55.55.55 11002}
                ....
                "10.10.11.253" {node 10.55.55.55 11241}
                "10.10.11.254" {node 10.55.55.55 11242} 
            }
        }
    }
    

    Alternativly you could also migrate the

    [switch]
    selection into datagroups and select the pool member into a external datagroup query. It would solve your problem while also consuming less CPU ressources.

    when CLIENT_ACCEPTED {
        node [class lookup [IP::client_addr] MY_POOL_DATAGROUP]
    }
    

    The external datagroup would then look like that.

    "10.10.10.11" := "10.55.55.55 10001",
    "10.10.10.12" := "10.55.55.55 10002",
    ...
    "10.10.10.253" := "10.55.55.55 10241",
    "10.10.10.254" := "10.55.55.55 10242",  
    "10.10.11.11" := "10.55.55.55 11001", 
    "10.10.11.12" := "10.55.55.55 11001",
    ...
    "10.10.11.253" := "10.55.55.55 11241",
    "10.10.11.254" := "10.55.55.55 11242",
    

    If both approaches are not still not suitable for you, then you have to experiment with iFiles to store +64k TCL scripts in static::variables during RULE_INIT and the execute the script using

    [eval]
    .

    when RULE_INIT {
         Combine up to 4Mbyte TCL scripts using iFile
           set static::my_very_long_script [ifile filename_part1.txt]
        append static::my_very_long_script [ifile filename_part2.txt]
    }
    when CLIENT_ACCEPTED {
         Execute TCL scripts up to 50Mbyte
        eval $static::my_very_long_script
    }
    

    Note: But be aware the

    [eval]
    technique should be considered as "experimental", since I haven't seen the F5 employees using nor recommending nor disagreeeing this approach...

    Cheers, Kai

  • Hannes, Kai thank you very much for your answers, each one is very useful.

     

    I think that I go for the option with two irules, as it will be easier to implement on my production environment (now we have one big irule, but the size limit is very close).