Applies To:
Show Versions![Show Versions](/etc/designs/pcx/techdocs/images/expandversions.gif)
BIG-IP versions 1.x - 4.x
- 4.5.14, 4.5.13, 4.5.12, 4.5.11, 4.5.10
5
iRules
- Introducing iRules
- Creating rules
- Understanding rules syntax
- Using rules to select pools
- Using rules to redirect HTTP requests
- Configuring class lists
- Additional rule examples
Introducing iRules
iRules is a powerful and flexible feature that you can use to balance your network traffic. The iRules feature not only allows you to create rules and classes to select pools, but also to configure persistence scenarios that allow the BIG-IP system to search on any type of connection data that you define. Thus, the iRules feature significantly enhances your ability to customize your content-switching to suit your exact needs.
What is a rule?
An element of the iRules feature, a rule is a user-written script that chooses among two or more load balancing pools. In other words, a rule selects a pool associated with a virtual server. Rules are an optional feature that you can use if you do not want traffic to target the default pool defined for a virtual server. Rules allow you to more directly specify the pools to which you want traffic to be directed.
Once you have created a rule to select a pool, you can then configure that pool to further direct traffic to individual pool members, either to implement persistence or to meet your specific load balancing requirements. When configuring that pool, you can conveniently use the same expression syntax that you use for rules, to specify the expressions that your pool definition might require for persistence. For information on configuring pools, see Chapter 4, Pools .
When a packet arrives destined for a virtual server that does not match a current connection, the BIG-IP system can select a pool by evaluating a rule associated with a virtual server. The rule can direct traffic to a pool based on specific data such as IP packet headers, HTTP headers or TCP content. Thus, rules can be configured to ask true or false questions such as:
- Does the packet data contain an HTTP request with a URI ending in cgi?
- Does the source address of the packet begin with the octet 206?
- Does the TCP packet data contain the string ABC?
In addition to creating a rule to select a pool, you can also create a rule to redirect a client request to a specific host name, port number, or URI path.
Rules are made up of statements and expressions. Within those expressions, you can use many elements, such as functions, operands, literals, and operators. For descriptions of these elements, see Expressions .
A rule example
The rules you create can be simple or complex, depending on your content-switching needs. Figure 5.1 shows an example of a simple rule.
if ( http_uri ends_with "gif" or http_uri ends_with "html" ) { use ( cache_pool ) } else { use ( server_pool ) } |
This simple rule sends .gif and .html content to pool cache_pool and all other content to pool server_pool.
Creating rules
You can create rules using either the Configuration utility or the bigpipe rule command. Each of these methods is described in this section.
To create a rule using the Configuration utility
- In the navigation pane, click Rules.
The Rules screen opens. - Click the Add button.
The Add Rule screen opens. - In the Name box, type a 1- to 31-character name.
- In the Type box, select either Rule Builder or Text Input.
If you select Rule Builder, the BIG-IP system automatically creates a rule for you, based on rule elements that you select or type in the GUI. - If you select Text Input, a screen appears in which you can type the complete text of your rule.
- In the Type box, select either Rule Builder or Text Input.
- Click Done.
To create a rule from the command line
To create a rule from the command line, use the following syntax:
rule <rule_name> { <if_statement> | <discard_statement> |<use_statement>|<cache_statement> | <redirect_statement> | <log_statement> | <accumulate_statement> }
For detailed syntax information on building rule statements, see the remainder of this chapter.
Once you have created a rule, you need to configure a virtual server to reference that rule. For information on configuring a virtual server to reference a rule, see Referencing BIG-IP system resources .
Understanding rules syntax
Rules consist of statements, which are made up of a number of different elements, such as functions, constants, variables, and operators. Together, these elements can be used to construct a rule that selects a particular pool associated with a virtual server. They can also be used to redirect client requests.
Rule statements
A rule consists of one or more statements. Rules support the following types of statements:
- An if statement asks a true or false question and, depending on the answer, takes some action.
- A discard statement discards the request. This statement must be conditionally associated with an if statement.
- A use pool statement uses a selected pool for load balancing. This statement must be conditionally associated with an if statement.
- A cache statement uses a selected pool for load balancing. This statement can be conditionally associated with an if statement.
- A redirect to statement sends traffic to a specific destination, rather than to a pool for load balancing.
- A log statement logs a message to the Syslog facility. The statement does this by performing variable expansion on the message as defined for the header insert pool attribute. For more information on the header insert pool attribute, see Chapter 4, Pools .
- An accumulate statement terminates rules processing until another another packet containing additional data is received from the originating client. This statement is useful with the http_content and tcp_content rule variables, when not enough data has been received to be successfully evaluated. For information on these rule variables, see Variables .
If not used appropriately, a log statement can produce large amounts of output.
Table 5.1 shows the syntax for rule statements.
Element |
Syntax |
---|---|
if statements |
if ( <expression> ) { <statement> } |
discard statements |
discard |
use pool statements |
use pool ( <pool_name> ) |
cache statements |
cache ( <expression> ) { origin_pool <pool_name> cache_pool <pool_name> [ hot_pool <pool_name> ] [ hot_threshold <hit_rate> ] [ cool_threshold <hit_rate> ] [ hit_period <seconds> ][ content_hash_size <sets_in_content_hash> ] [ persist <expression> ]} |
redirect to statements |
redirect to ( <redirect URL> ) |
log statements |
log [<facility>.<level>] "<message>" |
accumulate statements |
accumulate |
The maximum number of if statements that you can nest in a rule is 100.
Expressions
Expressions can be specified within rule statements or within pool definitions. Their purpose is to describe some action that the rule or pool is to take, and to provide any data the rule or pool requires to take the action.
Table 5.2 shows the elements that an expression can contain, and their syntax.
Elements |
Syntax |
---|---|
Functions |
findstr() substr() getfield() findclass() decode_uri() domain() imid() mapclass2node() node() wlnode() |
Constant operands |
<regex_literal> - A regular expression literal that must be a string of 1 to 63 characters enclosed in quotes that can contain other regular expressions. <string_literal> - A string literal that must be a string of 1 to 63 characters enclosed in quotes. <address_literal> - A string containing an address in dotted decimal notation [netmask <dot_notation>], where the dot notation longword must be in the form <0-255>.<0-255>.<0-255>.<0-255>. Character constants - Examples are: <0x13> (hexadecimal) and <19> {decimal). TCP - A constant that you can use with variable operands and operators. UDP - A constant that you can use with variable operands and operators. |
Variable operands |
client_addr ip_protocol link_qos http_content http_content_collected tcp_content tcp_bytes_collected vlan_id |
Relational operators |
contains + |
Logical operators |
not and or |
Cache statement attributes |
origin_pool <pool name> cache_pool <pool name> persist <expr> |
Figure 5.2 is a rule that shows two examples of an expression within a rule. The expressions are indicated in boldface type.
rule my_rule { if (tcp_content contains "XYZ") { use pool xyz_servers } else if (substr(tcp_content(100), 50, 3)) == "ABC" { use pool abc_servers } else { use pool web_servers } } |
Figure 5.2 Examples of expressions specified within a rule
In Figure 5.2 , the element tcp_content is the variable operand. The element contains is the relational operator, and the element substr() is the function. The expressions also contain some literals, such as 50, 3, "XYZ", and "ABC".
Expressions for use within rules and pools include several important features:
- Expression syntax can be used outside of rules, such as within pool persistence definitions.
- Expressions support several functions for enabling persistence and direct selection of pool members.
- Expression functions, variables, and literals can exist on either side of an operator.
- Expressions allow string concatenation using the plus (+) operator.
- Expressions promote integers, addresses, and so on to strings when used with string concatenation.
- Functions with no arguments can be specified without parentheses ().
- The syntax for the http_header and http_cookie variables matches the syntax for functions (for example, http_header(<header_tag_string>)).
The following sections describe all of the elements that an expression can contain.
The maximum number of if statements that you can nest in a rule is 100.
Functions
There are functions available that you can use as part of expressions. A primary use of such expressions is to specify them within pool definitions, to either return a string for persistence, or to return a node to which the pool can send traffic directly.
Functions that return a string
The following functions return a string that you specify. They are:
- findstr() - Finds a string within another string and returns the string starting at the offset specified from the match.
- substr() - Returns the string starting at the offset specified.
- getfield() - Splits a string on a character and returns the string corresponding to the specific field.
- findclass() - Finds the member of a class that contains the result of the specified expression and returns that class member.
- decode_uri() - Evaluates the expression and returns a string with any %XX escape sequences decoded as per HTTP escape sequences defined in RFC2396.
- domain() - Parses and returns up to the specified number of trailing parts of a domain name from the specified expression.
- imid() - Used to parse the http_uri variable and user-agent header field for an i-mode identifier string that can be used for i-mode persistence.
findstr()
The findstr() function finds a string within another string and returns the string starting at the offset specified from the match. The function returns an empty string if:
- The argument <expr> does not evaluate into a string.
- The string specified by the argument <string> is not found in the evaluated expression.
- The specified offset would put the return string outside the evaluated expression.
Syntax
The findstr() function takes the following arguments:
findstr(<expr>, <string>, <offset>)
findstr(<expr>, <string>, <offset>, <length>)
findstr(<expr>, <string>, <offset>, <termchr>)
where:
<expr> is the expression to be searched.
<string> is a literal string to search for. A literal string uses double quotation marks, for example, "user=".
<offset> is the offset from the found string of the string to return.
<length> is the number of characters of the string to return.
<termchr> is a literal character the string to return is ended at. A literal character uses apostrophes (single quotation marks), for example, ';'.
Examples
This expression returns the string following a query character:
findstr(http_uri, "?", 1)
This expression returns the three characters following x=:
findstr(http_uri, "x=", 2, 3)
This expression returns the string following user= up to the & character:
findstr(http_uri, "user=", 5, `&')
substr()
The substr() function returns the string starting at the offset specified. The function returns an empty string if:
- The value of the <expr> argument does not evaluate into a string
- The value of the <offset> argument puts the return string outside of the evaluated expression.
Syntax
The substr() function takes the following arguments:
substr(<expr>, <offset>)
substr(<expr>, <offset>, <length>)
substr(<expr>, <offset>, <termchr>)
where:
<expr> is the expression providing the source string.
<offset> is the offset from the beginning of the string to return.
<length> is the number of characters of the string to return.
<termchr> is a literal character with which the string to return is ended.
Examples
This expression returns the string starting after the first character:
substr(http_uri, 1)
This expression returns a string of three characters starting after the second character:
substr(http_uri, 2, 3)
This expression returns the string starting at the fifth character and ending at the & character:
substr(http_uri, 5, '&')
getfield()
The getfield() function splits a string on a character, and returns the string corresponding to the specific field. The function returns an empty string if the value of <expr> does not evaluate into a string, or if the specified <fieldnum> value is greater than the number of fields the evaluated <expr> was split into. If the specified <split> character or string is not found in the evaluated <expr>, then it is treated as one field.
Syntax
The getfield() function takes the following arguments:
getfield(<expr>, <split>, <fieldnum>)
where:
<expr> is the expression to be split.
<split> is a literal character or string used to split the string into fields. A literal character uses apostrophes (single quotation marks), for example, `;'.
<fieldnum> is the number of the field to return.
Example
The following example of the getfield function returns the third field after splitting on a ; character:
getfield(http_uri, `;', 3)
Using this example, the expression ABC;DEF;123 returns the string 123.
findclass()
The findclass() function finds the member of a class that starts with or matches the beginning of that class member. This function returns the value of that class member. This is similar to the one of class identifier, except that the member is not required to be equal; instead, the member is only required to start with the string and returns the entire member value.
Syntax
The findclass() function takes the following arguments:
findclass(<expr>, <classname>)
where:
<expr> is the expression whose result is searched for in members.
<classname> is a literal class name in which to search for a member.
Example
This expression returns the member containing the domain portion of the http_host string:
findclass(domain(http_host, 2), external_servers)
decode_uri()
The decode_uri() function evaluates the expression and returns a string with any %XX escape sequences decoded as per HTTP escape sequences defined in RFC2396.
Syntax
The decode_uri() function takes the following arguments:
decode_uri(<expr>)
where:
<expr> is the expression providing the string to convert.
Example
This expression returns the HTTP URI with any escape sequences decoded:
decode_uri(http_uri)
This expression returns the binary string 0x00 0x03:
decode_uri("%00%03")
domain()
The domain() function parses and returns up to the specified number of trailing parts of a domain name from the specified expression. The function automatically parses out the portion following a `:' (representing a port or service) from the return string. The function also detects a dotted quad and returns the full quad regardless of the <count> specified. If the evaluated domain name does not have the specified number of trailing parts, the number of parts found are returned.
Syntax
The domain() function takes the following arguments:
domain(<expr>, <count>)
where:
<expr> is the expression to be parsed for a domain name.
<count> is the number of trailing parts in the domain name to return.
Example
The following example of the domain function returns the last two parts of a domain name:
domain(http_host, 2)
Using this example, the host name www.mysite.com returns the string mysite.com.
imid()
The imid() function is specifically used to parse the http_uri variable and user-agent header field for an i-modeTM identifier string that can be used for i-mode persistence. The imid() function takes no arguments and simply returns the string representing the i-mode identifier or the empty string, if none is found.
Functions that return a node address
There are a number of expressions that you can use primarily to directly select a particular node (pool member) within a pool. They are:
- node() - Returns a literal node address converted from a string representation of an address and port.
- mapclass2node - Represents a short-hand combination of the functions findclass(), findstr(), and node().
- wlnode() - Returns a literal node address converted from a specific BEA WebLogicTM string format, representing the application IP address and service, into a literal node address.
node()
The node() function returns a literal node address converted from a string representation of an address and port. This function is designed primarily to be used with the persist expressions for directly selecting a node to which to persist.
Syntax
The node() function takes the following arguments:
node(<expr>)
where:
<expr> is the expression providing the string to convert.
Examples
node("10.0.0.3:80") // returns the node represented by 10.0.0.3, port 80
node(getfield(http_cookie("SERVER"), ';', 1))
mapclass2node()
The mapclass2node() function is a short-hand combination of the functions findclass(), findstr(), and node(). The function is equivalent to the following syntax:
node(findstr(findclass(<expr>, <classname>), "",1))
where "" represents a space character.
Syntax
The mapclass2node() function takes the following arguments:
mapclass2node(<expr>, <classname>, [<delim>])
where:
<expr> is the expression whose result is searched for in members of the named class.
<classname> is a literal name for the class in which to search for a member.
<delim> is the delimiter separating the matched string from the node address and service.
Examples
For the following class:
class external_servers {
"ABC 10.0.0.1:80",
"DEF 10.0.0.2:80"
}
this example returns a node that matches one of the server names found in the class external_servers:
mapclass2node(findstr(http_uri, 'server=', 7, 6), external_servers)
wlnode()
The wlnode() function returns a literal node address converted from a string of the BEA WebLogic format for identifying the application node to which the connection should persist.
The wlnode() function is designed primarily to be used with the persist expressions for directly selecting a node to which to persist.
Syntax
The wlnode() function takes the following arguments:
wlnode(<expr>)
where:
<expr> is the expression providing the BEA WebLogic string.
Examples
wlnode("10.0.0.3:80") // returns the node represented by 10.0.0.3, port 80
wlnode(http_cookie("JSESSIONID"))
Constant and variable operands
Operands are of two types: constant operands (constants) and variable operands (variables). You can use both types of operands in an expression.
Constants
Constants are elements of an expression whose values do not change. Possible constants are:
- IP protocol constants, for example:
UDP or TCP - IP addresses expressed in masked dot notation, for example:
206.0.0.0 netmask 255.0.0.0
- Strings of ASCII characters, for example:
"pictures/bigip.gif"
- Regular expression strings
Variables
Variables are elements of an expression that have changeable values. Therefore, they need to be referred to by a constant descriptive name. The variables available depend on the context in which the rule containing them is evaluated. Following are descriptions of the variables that you can use within a rule.
IP packet header variable
Table 5.3 lists and describes the available IP packet header variables for use within a rule.
Variable Name |
Description |
---|---|
client_addr |
Used by a client to represent a source IP address. This variable is replaced with an unmasked IP address. |
server_addr |
Used to represent a destination IP address. This variable is replaced with an unmasked IP address. The server_addr variable is used to represent the destination address of the packet. This variable is useful when load balancing traffic to a wildcard virtual server. |
client_port |
Used to represent a client port number. |
server_port |
Used to represent a server port number. |
ip_protocol |
Used to represent an IP protocol. This variable is replaced with a numeric value representing an IP protocol such as TCP, UDP, or IPSEC |
link_qos |
Used to represent the Quality of Service (QoS) level. |
ip_tos |
Used to represent that Type of Service (ToS) level. |
vlan_id |
Used to represent a VLAN ID. |
HTTP request string variables
The BIG-IP system replaces all HTTP request string variables with string literals. In command line syntax, you refer to HTTP request variables by a predefined set of names. Internally, an HTTP request variable points to a method for extracting the desired string from the current HTTP request header or content data. Before an HTTP request variable is used in a relational expression, the BIG-IP system replaces the variable with the extracted string.
Table 5.4 lists and describes the available HTTP request string variables for use within a rule.
Variable Name |
Description |
---|---|
http_method |
The http_method variable specifies the action of the HTTP request. Common values are GET or POST. |
http_uri |
The http_uri variable specifies the URL, but does not include the protocol and the fully qualified domain name (FQDN). For example, if the URL is http://www.mysite.com/buy.asp, then the URI is /buy.asp. |
http_version |
The http_version variable specifies the HTTP protocol version string. Possible values are "HTTP/1.0" or "HTTP/1.1". |
http_host |
The http_host variable specifies the value in the Host: header of the HTTP request. It indicates the actual FQDN that the client requested. Possible values are a FQDN or a host IP address in dot notation. |
http_cookie(<cookie_name>) |
The HTTP cookie header variable specifies the value in the Cookie: header for the specified cookie name. An HTTP cookie header line can contain one or more cookie name value pairs. The http_cookie <cookie name> variable evaluates to the value of the cookie with the name <cookie name>. For example, given a request with the following cookie header line: Cookie: green-cookie=4; blue-cookie=horses The variable http_cookie blue-cookie evaluates to the string horses. The variable http_cookie green-cookie evaluates to the string 4. |
http_header(<header_tag_string>) |
The http_header variable evaluates the string following an HTTP header tag that you specify. For example, you can specify the http_host variable with the http_header variable. In a rule specification, if you want to load balance based on the host name andrew, the rule statement might look as follows: if ( http_header "Host" starts_with "andrew" ) { use ( \ andrew_pool ) } else { use ( main_pool ) } |
http_content[(<minlength>)] |
The http_content variable evaluates the string following an HTTP content tag that you specify. For example, if you want to load balance traffic based on the value of the string date, the rule statement might look as follows: if (findstr (http_content, "date=",5,6) == "052102" { } Note the following: The http_content variable uses the content_length or transfer_encoding fields to determine the available content. If these headers cannot be found, the http_content variable simply returns the amount received and does not know if there is more data to be sent. If not enough data is found to meet the specified minimum required, the connection can hang. To avoid this, we recommend using the accumulate statement and the http_content_collected variable in any rule containing the http_content variable. The system uses a buffer space of 16384 bytes to store all HTTP-collected content, including headers. Therefore, headers reduce the available buffer space for the data that the http_content variable returns. |
http_content_collected |
The http_content_collected variable returns the amount of content that has currently been collected. |
TCP string variables
The BIG-IP system replaces all TCP request string variables with string literals. In command line syntax, you refer to TCP request variables by a predefined set of names. Internally, a TCP request variable points to a method for extracting the desired string from the current TCP request data. Before a TCP request variable is used in a relational expression, the BIG-IP system replaces the variable with the extracted string.
Table 5.5 lists and describes the available TCP request string variables for use within a rule.
Variable Name |
Description |
---|---|
tcp_content |
The tcp_content variable allows you to create a basic expression that load balances traffic based on arbitrary data within a TCP/IP connection. The variable returns TCP data content up to the BIG-IP system's maximum application buffer size (currently 16384 bytes). The most likely use of the tcp_content variable is to search for specific strings when establishing a non-HTTP connection. If the tcp_content variable does not receive the amount of minimum data required, the connection hangs until the timeout expires. To avoid this, we recommend that you carefully use the accumulate statement and the tcp_bytes_collected variable in any rule containing the tcp_content variable. |
tcp_bytes_collected |
The tcp_bytes_collected variable returns the amount of content that has currently been collected. |
Operators
Operators can be of two types: relational operators and logical operators.
Relational operators
In a rule, relational operators compare two operands to form relational expressions. Table 5.6 lists the relational operators and the corresponding meanings.
Relational operators and their allowed operands |
Meaning |
---|---|
<expression> contains <expression> |
Does the value returned by the first expression contain the value returned by the second expression? |
<expression> ends_with <expression> |
Is the value returned by the second expression a suffix of the value returned by the first expression? |
<expression> equals <expression> |
Are the values returned by the two expressions identical? |
exists <expression> |
Does the specified expression exist? |
<expression> matches_regex <regular_expression> |
Do the value returned by the expression and the value returned by the regular expression match? (Note: The value of <regular_expression> must be a string containing a regular expression, and therefore cannot include the one of class identifier and a class name.) |
<expression> starts_with <expression> |
Is the value returned by the second expression a prefix of the value returned by the first expression? |
<expression> == <expression> |
Is the value returned by the first expression equal to the value returned by the second expression? |
<expression> != <expression> |
Is the value returned by the first expression not equal to the value returned by the second expression? |
<expression> > <expression> |
Is the value returned by the first expression greater than the value returned by the second expression? |
<expression> => <expression> |
Is the value returned by the first expression equal to or greater than the value returned by the second expression? |
<expression> >= <expression> |
Is the value returned by the first expression greater than or equal to the value returned by the second expression? |
<expression> < <expression> |
Is the value returned by the first expression less than the value returned by the second expression>? |
<expression> <= <expression> |
Is the value returned by the first expression less than or equal to the value returned by the second expression? |
<expression> + <expression> |
This operator concatenates the value returned by two expressions. |
It is useful to note that while the contains and matches_regex operators provide similar functionality, they require different operands on the right side of the expression. The contains operator requires a literal string operand, whereas the matches_regex operator requires a regular expression.
Relational expressions using the contains operator require less processing than similar expressions using the matches_regex operator. It is therefore recommended that you use contains instead of matches_regex wherever possible.
Logical operators
Logical operators modify an expression or connect two expressions together to form a logical expression. Arguments to logical operators must return a value of true. Table 5.7 lists the logical operators and their meanings.
Logical Operators |
Meanings |
---|---|
not <expression> |
Is the value returned by the expression not true? |
<expression> and <expression> |
Are the values returned by both expressions true? |
<expression> or <expression> |
Is the value returned by either expression true? |
Using rules to select pools
Rules can search for various kinds of data within a request before selecting the appropriate pool to service that request. Table 5.8 lists the various criteria you can use when creating a rule to select a pool.
Pool-selection criteria |
Description |
---|---|
Header or content data |
You can send connections to a pool or pools based on header or content information that you specify. |
IP packet header data |
You can send connections to a pool or pools based on IP addresses, port numbers, IP protocol numbers, Quality of Service (Qos), and Type of Service (ToS) levels defined within a packet. |
one of class identifier |
You can send connections to a pool or pools based on whether the destination address is a member of a specific named class, such as one of AOL. |
HTTP header data (cache rule) |
This type of rule is any rule that contains a cache statement. A cache rule selects a pool based on HTTP header data. You cannot use it with FTP. |
You must define a pool before you can define a rule that references the pool.
Selecting pools based on header or content data
Using rule variables such as http_header, http_content, and tcp_content, you can create a rule that selects a pool based on data that resides in the header or content of a request.
For example, you may want a rule that logically states: "If the packet data contains an HTTP request with a URI ending in cgi, then load balance using the pool cgi_pool. Otherwise, load balance using the pool default_pool".
Figure 5.3 shows a rule that illustrates this example.
rule cgi_rule { if (http_uri ends_with "cgi") { use pool cgi_pool } else { use pool default_pool } } |
Regarding the tcp_content variable, you might want a rule that logically states: "If the packet data contains a TCP request containing the string "XYZ", then load balance using the pool xyz_servers. If the string is not found, search for the string "ABC" at the specified offset and load balance using the pool abc_servers. If the string "ABC" is not found, load balance using the pool web_servers".
Figure 5.4 shows a rule that illustrates this example.
rule my_rule { if (tcp_content contains "XYZ") { use pool xyz_servers } else if (substr(tcp_content(100), 50, 3)) == "ABC" { use pool abc_servers } else { use pool web_servers } } |
Figure 5.4 Sample rule using a TCP request string variable
Another example is shown in Figure 5.5 .
rule my_rule { if (http_content contains "ABC") { use pool http_pool } else if (http_content_collected < 20) { accumulate } else { discard } } |
Figure 5.5 Sample rule using an HTTP request string variable
Note that in Figure 5.5 , the search for string "ABC" is not limited to the first 20 bytes in the HTTP content. If you want to restrict a search to a specific region of the content, such as the first 20 bytes, you can include an expression in the rule, using the substr() function. Figure 5.6 shows an example.
if (substr(http_content, 0, 20) contains "ABC") { use pool http_pool } else if (http_content_collected < 20) { accumulate } else { discard } } |
Figure 5.6 Sample rule that restricts a search to the first 20 bytes of data
For information on functions such as the substr() function shown in the above example, see Functions .
To specify HTTP request string or TCP request string variables within a rule using the Configuration utility
- In the navigation pane, click Rules.
- Click the Add button.
- In the Name box, type a unique name for the rule.
- In the Type box, click the button for Rule Builder.
- Click Next.
- On the left side of the screen, select a variable.
- Fill in all information within the row.
- Click Next.
- Select Discard.
- Click Next.
- Select either No Action or Discard from the box.
- Click Done.
To specify HTTP request string or TCP request string variables within a rule from the command line
The following example shows the syntax for specifying an IP packet header variable within a rule.
b rule my_rule { if '( http_uri ends_with "cgi" )' { use '( cgi_pool )' }\
else { use '( another_pool )' } }
For examples of rules that select pools based on header information inserted into HTTP requests by an SSL Accelerator proxy, see Inserting headers into HTTP requests .
Selecting pools based on IP packet header data
In addition to specifying the HTTP and TCP request string variables within a rule, you can also select a pool by specifying IP packet header information. The types of information you can specify in a rule are:
- Client IP address
- Server IP address
- Client port number
- Server port number
- IP protocol number
- QoS level
- ToS level
The following sections describe these specific types of IP packet header data that you can specify within a rule. For the procedure on specifying IP packet header variables within a rule, see To specify IP packet header variables within a rule using the Configuration utility .
IP addresses
You can specify the client_addr or the server_addr variable within a rule to select a pool. For example, if you want to load balance based on part of the client's IP address, you might want a rule that states:
"All client requests with the first byte of their source address equal to 206 will load balance using a pool named clients_from_206 pool. All other requests will load balance using a pool named other_clients_pool."
Figure 5.7 shows a rule that implements the preceding statement.
rule clients_from_206_rule { if ( client_addr equals 206.0.0.0 netmask 255.0.0.0 ) { { use pool clients_from_206 } else { use pool other_clients_pool } } |
For additional examples of rules using IP packet header information, see Additional rule examples .
Port numbers
The BIG-IP system includes rule variables that you can use to select a pool based on the port number of the client or server. These variables are client_port and server_port.
To configure a rule to select a pool based on a port number, use the syntax shown in the example in Figure 5.8 .
rule my_rule { if (client_port > 1000) { use pool slow_pool } else { use pool fast_pool } } |
IP protocol numbers
The BIG-IP system includes a rule variable, ip_protocol, that you can use to select a pool based on an IP protocol number.
To configure a rule to select a pool based on an IP protocol number, use the syntax shown in the example in Figure 5.9 .
rule my_rule { if (ip_protocol == 6) { use pool tcp_pool } else { use pool slow_pool } } |
Quality of Service (QoS) level
The Quality of Service (QoS) standard is a means by which network equipment can identify and treat traffic differently based on an identifier. As traffic enters the site, the BIG-IP system can apply a rule that sends the traffic to different pools of servers based on the QoS level within a packet.
To configure a rule to select a pool based on the QoS level of a packet, you can use the link_qos rule variable, as shown in the example in Figure 5.10 .
rule my_rule { if (link_qos > 2) { use pool fast_pool } else { use pool slow_pool } } |
For information on setting QoS values on packets based on the pool selected for that packet, see Configuring the Quality of Service (QoS) level .
IP Type-Of-Service (ToS) level
The Type of Service (ToS) standard is a means by which network equipment can identify and treat traffic differently based on an identifier. As traffic enters the site, the BIG-IP system can apply a rule that sends the traffic to different pools of servers based on the ToS level within a packet.
The variable that you use to set the ToS level on a packet is ip_tos. This variable is sometimes referred to as the DiffServ variable.
To configure a rule to select a pool based on the ToS level of a packet, you can use the ip_tos rule variable, as shown in the example in Figure 5.11 .
rule my_rule { if (ip_tos == 16) { use pool telnet_pool } else { use pool slow_pool } } |
For information on setting ToS values on packets based on the pool selected for that packet, see Configuring the Type of Service (ToS) level .
Specifying IP packet header variables within a rule
You can use either the Configuration utility or the bigpipe rule command to specify IP packet header variables within a rule.
To specify IP packet header variables within a rule using the Configuration utility
- In the navigation pane, click Rules.
- Click the Add button.
- In the Name box, enter a unique name for the rule.
- In the Type box, click the button for Rule Builder.
- Click Next.
- On the left side of the screen, select a variable.
- Fill in all information within the row.
- Click Next.
- Select Discard.
- Click Next.
- Select No Action or Discard from the box.
- Click Done.
To specify IP packet header variables within a rule from the command line
The following example shows the syntax for specifying an IP packet header variable within a rule.
b rule my_rule { if '( client_addr == 10.12.12.10 )' { use '( pool_A80 )' } }
Using the one of class identifier
The BIG-IP system includes a class identifier called one of, which you can use to match a variable to members of class. Using the one of identifier means that the BIG-IP system applies the relational operator to the left of the one of identifier to members of the named class.
For example, prior to the availability of the one of identifier, a rule that was intended to send incoming AOL connections to the pool aol_pool was written as shown in Figure 5.12 , where multiple values for the client_addr variable had to be individually specified.
rule my_rule { if ( client_addr equals 152.163.128.0 netmask 255.255.128.0 or client_addr equals 195.93.0.0 netmask 255.255.254.0 or client_addr equals 205.188.128.0 netmask 255.255.128.0 ) { use pool aol_pool } else { use pool all_pool } } |
Using the one of identifier instead, you can cause the BIG-IP system to load balance all incoming AOL connections to the pool aol_pool, if the value of the client_addr variable is a member of the class AOL. Figure 5.13 shows this type of rule. In this case, the one of indicates that the variable aol is actually a list of values.
rule my_rule { if (client_addr equals one of aol) { use pool aol_pool } else { use pool all_pool } } |
Note that the value of an expression such as client_addr equals one of aol is true if the expression is true for at least one member the class.
The one of class identifier requires a class name as one of its operands. Also, you cannot use the one of identifier with the relational operator matches_regex. For more information on the one of identifier, see Configuring class lists .
For more information on the types of classes that the BIG-IP system allows and the commands for creating classes, see Configuring class lists .
Selecting pools based on HTTP header data
A rule can contain a cache statement that selects a pool based on HTTP header data. A cache statement returns either the origin pool, the hot pool, or the cache pool. When the cache pool is selected, it is accompanied by the indicated node address and port. When a rule returns both a pool and a node, the BIG-IP system does not do any additional load balancing or persistence processing.
Figure 5.14 shows an example of a rule containing a cache statement.
Cache statements
A cache statement may be either the only statement in a rule, or it may be nested within an if statement. Rules with cache statements are used to select pools based on HTTP header data. Figure 5.15 shows an example of a cache statement within a rule.
cache(http_method == "GET") { origin_pool pool1 cache_pool pool2 persist (domain(http_host, 2) + http_uri) } |
Figure 5.15 Example of a cache statement within a rule
Table 5.9 describes the cache statement attributes and their syntax.
Attribute |
Description |
Required? |
---|---|---|
origin_pool <pool_name> |
Specifies a pool of servers with all the content to which requests are load balanced when the requested content is not cacheable or when all the cache servers are unavailable or when you use a BIG-IP system to redirect a missed request from a cache. |
Yes |
cache_pool <pool_name> |
Specifies a pool of cache servers to which requests are directed to optimize cache performance. |
Yes |
hot_pool <pool_name> |
Specifies a pool of servers that contain content to which requests are load balanced when the requested content is frequently requested (hot). If you specify any of the following attributes in this table, the hot_pool attribute is required. |
No |
persist <expr> |
Specifies an expression that will be evaluated and used to persist to the same node within the cache pool. |
No |
hot_threshold <hit_rate> |
Specifies the minimum number of requests for content that cause the content to change from cool to hot at the end of the period (hit_period). |
No |
cool_threshold <hit_rate> |
Specifies the maximum number of requests for specified content that cause the content to change from hot to cool at the end of the period. |
No |
hit_period <seconds> |
Specifies the period in seconds over which to count requests for particular content before deciding whether to change the hot or cool state of the content. |
No |
content_hash_size <sets_in_content_hash> |
Specifies the number subsets into which the content is divided when calculating whether content is hot or cool. The requests for all content in the same subset are summed and a single hot or cool state is assigned to each subset. This attribute should be within the same order of magnitude as the actual number of requests possible. For example, if the entire site is composed of 500,000 pieces of content, a content_hash_size of 100,000 would be typical. |
No |
Using rules to redirect HTTP requests
In addition to configuring a rule to select a specific pool, you can also configure a rule to redirect an HTTP request to a specific location, using the redirect to operator and a set of format strings included in the BIG-IP system. The location can be either a host name, port number, or URI. The format strings are: %h, %p, and %u. These format strings can be used within a redirection string to indicate which parts of the string (host name, port number, and URI path) do not indicate a redirection.
For example, the string https://%h:443/%u specifies that the HTTP request is to be redirected to a different protocol (https instead of the standard http) and a different port number (443). The host name and the URI path remain the same, indicated by the %h and %u format strings.
Figure 5.16 shows a rule that is configured to redirect an HTTP request.
rule my_rule { if (http_uri ends_with "baz") { redirect to "https://%h:8080/%u/" } else { use pool web_pool } } |
The preceding rule applies the format string to the URL. In this case, the format string sets the protocol to https, strips the requested port number (if any), changes it to 8080, and applies a trailing slash (/) to the end of the URI, if the URI ends with the string baz.
The %u format string strips the first character of the URI path. This is usually a slash (/), and this modification is done purely for aesthetic reasons. Thus when describing a URL, the string http://%h/%u is used instead of http://%h%u.
For more information on HTTP redirection and format strings, see Redirecting HTTP requests .
Configuring class lists
Class lists are useful for simplifying rules. Using the one of identifier and a class name within a rule eliminates the need to specify multiple values for a relational operator within the expression. For a more detailed explanation, see Using the one of class identifier .
The remainder of this section describes the types of class lists that you are allowed to create, the storage options available, some predefined classes included in the BIG-IP system, and the procedure for creating a class.
Class types
When using the one of identifier within a rule, you can specify any of three types of classes: classes of IP addresses, classes of strings, and classes of numeric values.
Although the one of identifier works with string classes, you cannot use it with the relational operator matches_regex.
IP address classes
There are two types of IP address classes: network IP address and host IP address.
The following command creates a network IP address class named my_netwk and contains network IP addresses:
b class my_ntwk { network 10.2.2.0 mask 255.255.255.0 }
Figure 5.17 shows the resulting network IP address type of class.
class my_netwk { network 10.2.2.0 mask 255.255.255.0 } |
The following command creates a host IP address class named my_host and contains one or more host IP addresses:
b class my_host { host 10.1.1.1 }
Figure 5.18 shows the resulting host IP address type of class.
class my_host { host 10.1.1.1 } |
Figure 5.18 An example of a host IP address type of class
String classes
The following command creates a string class named images.
b class images { \".gif\" }
Note: This example shows the use of escape characters for the quotation marks.
Figure 5.19 shows the resulting string type of class.
Numeric value classes
The following command creates a numeric value class named my_protos.
b class my_protos { 27 38 93 }
Figure 5.20 shows the resulting numeric value type of class.
The size of a class is limited by system resources only.
Storage options
The BIG-IP system allows you to store classes in two ways, either in-line or externally.
In-line storage
Classes that are stored in-line are saved in their entirety in the bigip.conf file. Also, when any data in the class needs to be updated, the entire class must be reloaded. In general, in-line storage uses additional system resources due to extensive searching requirements on large classes. Also, in-line storage requires you to reload entire classes when incrementally updating data.
To create an in-line class using the Configuration utility
- In the navigation pane, click Rules.
- Click the Classes tab.
This displays a list of the currently-defined in-line classes. - Click the Add button.
This displays the Add Class screen. - In the Class Name box, type in a class name.
- In the Class Type box, select a class type, either Address, String, or Value.
- In the File Mode box, select a file mode, either Read or Read/Write.
- In the Sizing box, type a number.
- Click Done.
External storage
You have the option to store classes in another location on the BIG-IP system, that is, outside of the bigip.conf file. Such classes are called external classes. The default location for storing external classes is the /config directory. Because the class is stored externally in another location, the bigip.conf file itself contains only meta-data for the class. The data in an externally-stored class file is stored as a comma-separated list of values (CSV format).
Creating external classes is useful because data does not need to be sorted when being loaded. Instead, data is stored in a hash-table in the kernel. This storage method translates to improvements in performance when a rule uses a large class to direct traffic to a pool.
The syntax for the class meta-data that is stored in the bigip.conf file is as follows:
class <name> extern {
<variable> <value>
<variable> <value>
...
}
The value of the <name> field is the name that you want to assign to the class.
Table 5.10 lists and describes the allowed values for the <variable> field, along with the corresponding values for the <value> field. Note that the value of the <value> field varies depending on the whether the <variable> field is filename, type, mode, or sizing.
<variable> Values |
Description |
<value> Values |
---|---|---|
filename |
The location of the externally-stored class |
Any pathname |
type |
One of the three allowed class types |
string, value, or ip |
mode |
A permission value that determines whether or not the BIG-IP system can write to the externally-stored class file during a save operation. If the mode is set to read, the class file cannot be modified during a save operation or deleted when a class is removed. |
read or readwrite |
sizing |
The expected size of the class. This value is used when creating the kernel hash table for the class. The actual class size can be larger or smaller than the sizing value. |
Any number |
Figure 5.21 shows an example of class meta-data in the bigip.conf file. Note that this meta-data references the externally-stored class file /home/ip2.class.
class ipvals extern { filename /home/ip2.class type ip mode readwrite sizing 10000 } |
The data in an external class file is stored in comma-separated lists, and the formats of any data values, such as IP addresses, match the formats used in the bigip.conf file. Continuing with the example above, Figure 5.22 shows the contents of the class file /home/ip2.class.
network 195.93.32.0 mask 255.255.255.0 ,network 195.93.33.0 mask 255.255.255.0 ,network 195.93.34.0 mask 255.255.255.0 ,network 195.93.48.0 mask 255.255.255.0 ,network 195.93.49.0 mask 255.255.255.0 ,network 195.93.50.0 mask 255.255.255.0 |
Creating and deleting external classes
Using the Configuration utility, you can create or delete externally-stored classes.
To create an external class using the Configuration utility
- In the navigation pane, click Rules.
- Click the External Classes tab.
This displays a list of the currently-defined external classes. - Click the Add button.
This displays the Add External Class screen. - In the Class Name box, type in a class name.
- In the Class Type box, select a class type, either Address, String, or Value.
- In the File Name box, type the path name to the class.
- In the File Mode box, select a file mode, either Read or Read/Write. The default value is Read.
- In the Sizing box, type a number. The default value is 1024.
- Click Done.
To delete an external class using the Configuration utility
- In the navigation pane, click Rules.
- Click the External Classes tab.
This displays a list of the currently-defined external classes. - In the Delete column, click the Delete button (trashcan icon) corresponding to a class name.
If you use the bigpipe reset command to delete configuration components, the command does not delete any externally-stored classes. You must delete externally-stored classes explicitly, using the Configuration utility as shown above.
Displaying external class data
Using either the Configuration utility or the bigpipe command, you can display the properties of an existing external class, or you can display either the class meta-data or the contents of the external class.
To display the properties of an external class using the Configuration utility
- In the navigation pane, click Rules.
- Click the External Classes tab.
This displays a list of the currently-defined external classes. - In the Class Name column, click a class name.
To display external class meta-data from the command line
You can display the meta-data information for an externally stored class using the following bigpipe command syntax, where <name> is the class name.
b class <name> show
To display the contents of an external class from the command line
You can display the contents of an external class file using the following bigpipe command syntax, where <name> is the class name.
b class <name> dump
To display a class member from the command line
You can display the contents of a particular class member using the following bigpipe command syntax, where <name> is the class name and <value> is the name of the member.
b class <name> member show <value>
Managing external class members
From the properties page of an external class, you can add, delete, or search for class members. This ability to manage class members eliminates the need to re-load the entire class list when the class needs to change incrementally.
You can only add or delete a class member when the class mode is set to ReadWrite. To change the class mode, use the Configuration utility.
To manage external class members using the Configuration utility
- In the navigation pane, click Rules.
- Click the External Classes tab.
This displays a list of the currently-defined external classes. - In the Class Name column, click a class name.
- Enter the appropriate member data.
- In the Resources box, click the ADD, DEL, or FIND button.
Clicking one of these buttons causes the change to take effect immediately.
To manage external class members from the command line
You can add or delete a member from an external class using the following bigpipe command syntax, where <name> is the class name and <value list> is a list of one or more elements of the appropriate type (Address, String, or Value).
b class <name> member add | delete { <value list> }
For example, the following command adds the member ".gif" to the class my_class:
b class my_class member add \".gif\"
Including external class lists when synchronizing configurations
When you synchronize a BIG-IP system configuration for redundant systems, the BIG-IP system only includes class lists that reside in the /config directory (that is, in-line stored class lists). If you want the synchronization to include externally-stored class lists, you must add anassociated entry for each class list into the bigip.conf file. You add these entries using the bigpipe db command.
To include external class lists when synchronizing configurations
When you want the BIG-IP system to include externally-stored class lists when synchronizing configurations for redundant systems, use the bigpipe db command to create special entries in the bigip.conf file. For example, the following command adds an entry into the bigip.conf file for the externally-stored class list /home/string/class. The 700 number designates the entry as corresponding to an externally stored class list.
b db set Common.Bigip.Sync.700.file = "/home/string/class"
Predefined classes
The BIG-IP system includes a number of predefined classes. They are:
- AOL Network
- Image Extensions
- Non-routable addresses
These classes are located in the file /etc/default_classes.txt. When the bigpipe load command is issued, the lists are loaded. Unless modified by a user, these lists are not saved to the file bigip.conf.
To view classes
To view classes, including the default classes, use the following command.
bigpipe class show
Additional rule examples
This section contains additional examples of rules including:
- Cookie rule
- Language rule
- AOL rule
- Cache rule
- Protocol specific rule
Cookie rule
Figure 5.23 shows a cookie rule that load balances based on the user ID that contains the word VIRTUAL.
if ( exists http_cookie ("user-id") and http_cookie ("user-id") contains "VIRTUAL" ) { use pool virtual_pool } else { use pool other_pool } |
Language rule
Figure 5.24 shows a rule that load balances based on the language requested by the browser.
AOL rule
Figure 5.25 and 5.26 are examples of rules that you can use to load balance incoming AOL connections.
port 80 443 enable pool aol_pool { min_active_members 1 member 12.0.0.31:80 priority 4 member 12.0.0.32:80 priority 3 member 12.0.0.33:80 priority 2 member 12.0.0.3:80 priority 1 } pool other_pool { member 12.0.0.31:80 member 12.0.0.32:80 member 12.0.0.33:80 member 12.0.0.3:80 } pool aol_pool_https { min_active_members 1 member 12.0.0.31:443 priority 4 member 12.0.0.32:443 priority 3 member 12.0.0.33:443 priority 2 member 12.0.0.3:443 priority 1 } pool other_pool_https{ member 12.0.0.31:443 member 12.0.0.32:443 member 12.0.0.33:443 member 12.0.0.3:443 } rule aol_rule { if (client_addr equals one of aol) { use pool aol_pool } else { use pool other_pool } } |
rule aol_rule_https { if ( client_addr equals 152.163.128.0 netmask 255.255.128.0 or client_addr equals 195.93.0.0 netmask 255.255.254.0 or client_addr equals 205.188.128.0 netmask 255.255.128.0 ) { use pool aol_pool_https } else { use pool other_pool_https } } virtual 15.0.140.1:80 { use rule aol_rule } virtual 15.0.140.1:443 { use rule aol_rule_https special ssl 30 } |
Cache rule
Figure 5.27 shows an example of a rule that you can use to send cache content, such as .gifs, to a specific pool.
if ( http_uri ends_with "gif" or http_uri ends_with "html" ) { use pool cache_pool } else { use pool server_pool } |
Rule using the ip_protocol variable
Figure 5.28 shows a rule that uses the ip_protocol variable.
rule myrule { if ( ip_protocol == 37 ) { use pool bootp_pool } else if ( ip_protocol == 22 ){ use pool ipsec_pool } else { use pool slow_pool } } |
Rule using IP address and port variables
Figure 5.29 shows a rule that uses the server_addr and server_port rule variables.
rule myrule { if ( server_addr equals 10.0.0.0 netmask 255.255.0.0 ) { use pool fast_pool } else if ( server_port equals 80 ){ use pool fast_pool } else { use pool slow_pool } } |
Rule using the one of class identifier
A good use of the one of class identifier in a rule is when you create a string class, and then write a rule to match a variable to the members of that class. For example, Figure 5.30 shows a string class that you could create, called images.
Given the above class, you could then create a rule that uses the one of identifier to to match the value of the variable http_uri to one or more members of the class images. Figure 5.31 shows this rule.
rule myrule { if ( http_uri ends_with one of images ) { use pool image_pool } else { use pool dynamic_pool } |
Rule based on HTTP header insertion
You can create rules based on headers that an SSL Accelerator proxy has inserted into HTTP requests. For examples of these types of rules, see Inserting headers into HTTP requests .
The variables that the SSL Accelerator proxy uses to insert headers into HTTP requests cannot be used within pool and rule expressions.