Forum Discussion

forsan's avatar
forsan
Icon for Altostratus rankAltostratus
Apr 29, 2014

node select iRule

Hi,

 

I have created an iRule that that is supposed to send traffic to a specific node depending on input from the URI. The iRule looks like this:

 

when HTTP_REQUEST { set node_ip [getfield [HTTP::uri] "/" 4] if { $node_ip >= 160 and $node_ip <= 253 } { HTTP::uri [string map [list $node_ip ""] [HTTP::uri]] node "10.1.1.$node_ip" 80 } else { pool mediaroot-pool } }

 

The idé is that if I use the url http://example.com/foo/bar/mediaroot/image1.jpg I will be sent to the "default" pool mediaroot-pool. But if I go to the url http://example.com/foo/bar/170/mediaroot/image1.jpg I will be sent to the node 10.1.1.170 and the URI will be changed to /foo/bar/mediaroot/image1.jpg with a rewrite.

 

I have created nodes between .160 and .253.

 

The part of the iRule that is not working is this: if { $node_ip >= 160 and $node_ip <= 253 }

 

If I go to the URL http://example.com/foo/bar/170/mediaroot/image1.jpg its sent to the correct node but with the URL http://example.com/foo/bar/mediaroot/image1.jpg the if statement thinks that mediaroot (getfield value 4) is correct.

 

Is the if statement that checks if the $node_ip is between 160-253 wrong?

 

Regards Andréas

 

  • with the URL http://example.com/foo/bar/mediaroot/image1.jpg the if statement thinks that mediaroot (getfield value 4) is correct.

     

    it went to mediaroot-pool pool here. how did you know it went to the wrong node?

     

  • e.g.

     config
    
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 9
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set node_ip [getfield [HTTP::uri] "/" 4]
      log local0. "node_ip $node_ip"
      if { $node_ip >= 160 and $node_ip <= 253 } {
        HTTP::uri [string map [list $node_ip ""] [HTTP::uri]]
        log local0. "HTTP::uri [string map [list $node_ip ""] [HTTP::uri]] "
        log local0. "node 10.1.1.$node_ip 80"
      } else {
        log local0. "pool mediaroot-pool"
      }
    }
    }
    
     test
    
    [root@ve11a:Active:In Sync] config  curl -I http://example.com/foo/bar/mediaroot/image1.jpg
    HTTP/1.1 404 Not Found
    Date: Tue, 29 Apr 2014 12:37:51 GMT
    Server: Apache/2.2.3 (CentOS)
    Content-Type: text/html; charset=iso-8859-1
    
    [root@ve11a:Active:In Sync] config  tail /var/log/ltm
    Apr 29 05:47:42 ve11a info tmm1[13022]: Rule /Common/qux : node_ip mediaroot
    Apr 29 05:47:42 ve11a info tmm1[13022]: Rule /Common/qux : pool mediaroot-pool
    
  • Hi,

    I got the following error in the log: May 12 09:07:04 bigip err tmm[9415]: 01220001:3: TCL error: /Common/mediaroot - bad IP address format (line 😎 invoked from within "node "10.1.1.$node_ip" 80"

    I have now found that if I use I URL other than a number or /mediaroot/ as the 4:th argument in the URI the iRule do not match any of the if statements. What I have done is that I modified the first elseif statement to elseif { $node_ip starts_with "1" || $node_ip starts_with "2" && $node_ip >= 160 } to check that its a number and then added an else statement that drops the connection if its not matching the other statements.

    when HTTP_REQUEST {
        set node_ip [getfield [HTTP::uri] "/" 4]
        if { [HTTP::uri] starts_with “/foo/bar/mediaroot/“ } {
            log local0. "starts with /foo/bar/mediaroot/"
            pool mediaroot-pool
        } elseif { $node_ip starts_with "1" || $node_ip starts_with "2" && $node_ip >= 160 } {
            HTTP::uri [string map [list $node_ip ""] [HTTP::uri]]
            node "10.1.1.$node_ip" 80
        } else {
            drop
        }
    }