14.3 WAN Policy Structure

A WAN policy consists of three sections:

14.3.1 Declaration Section

The Declaration section of a policy contains definitions of local variables and variables coming in through a client request. These definitions are used within the Selector and Provider sections. These variables are stored along with system-defined variables.

Variable declarations are separated by a semicolon (;). Multiple declarations for the same type can be combined in one line or wrapped to the next line and are not line sensitive. A sample Declaration section is shown below:

REQUIRED INT R1;
REQUIRED TIME R2;
REQUIRED BOOLEAN R3,R4;
REQUIRED NETADDRESS R5,R6;
OPTIONAL INT P1 := 10;
OPTIONAL BOOLEAN := FALSE;
LOCAL INT L1 :=10;
LOCAL INT L2;
LOCAL TIME L3;
LOCAL BOOLEAN L4 :=TRUE, L5 :=FALSE;
LOCAL NETADDRESS L6;

The required and optional declarations are specific to a particular traffic type. Policies that do not contain the required variables will not run. The optional declarations must have a value to provide a default if none is passed in. WAN Traffic Manager provides system symbols (predefined variables) for use with all traffic types.

Each declaration consists of three parts:

  • Scope

  • Type

  • List of names/optional value pairs

Scope

Valid scopes are listed in the following table.

Scope

Description

REQUIRED

Variables defined as REQUIRED in scope can be used in multiple sections, but only once within the Declaration section.

No values can be defined for a REQUIRED scope variable. Its value must come from the GetWanPolicy request.

OPTIONAL

Variables defined as OPTIONAL in scope can be used in multiple sections of a policy, but only once within the Declaration section.

OPTIONAL scope variables are assigned to a default value. These values are not initialized. They are set only if a value is not passed. If a WAN policy request does not pass a new value to the parameter that matches in both name and type, the value defined in the Declaration is used when processing the policy.

You must assign a value to variables defined as OPTIONAL in scope. Therefore, because TIME and NETADDRESS types cannot be initialized in the Declaration section, do not use an OPTIONAL scope with these variable types.

LOCAL

Variables defined as LOCAL in scope can be used in multiple sections, but only once within the Declaration section.

LOCAL scope variables exist only for a particular policy. Their values are not returned to the calling client.

All parameter types can be defined. However, because TIME and NETADDRESS types cannot be initialized in the Declaration section, do not assign values to these types.

SYSTEM

Variables defined as SYSTEM in scope can be used in multiple sections, but only once within the Declaration section.

Type

Valid types are listed in the following table.

Type

Description

INT

Reflects the traffic type of the GetWanPolicy request that the policy is being run for. For example, the following policy specifies a Traffic Type of NDS_SYNC:

IF TrafficType=NDS_SYNC THEN action END.

BOOLEAN

Used for values of only TRUE or FALSE. The value will be indeterminate if it is not set in a Declaration or a WAN policy request.

TIME

TIME scope variables must receive their values in the Selector or Provider sections or from the WAN policy request. Do not assign values to TIME scope variables in the Declaration.

NETADDRESS

NETADDRESS scope variables must receive their values in the Selector or Provider sections. Do not assign values to NETADDRESS scope variables in the Declaration.

You cannot assign values to Time and Netaddress types in the Declaration section. If these types do not already have a value, they receive their values in the Selector or Provider sections. Only single types are initialized in the Declaration section.

Names/Optional Value Pairs

Variable names are combinations of alphanumeric characters in a string of any length. Because only the first 31 characters are used, a variable must begin with a unique 31-character string. A variable name must start with an alphabetic character, or the symbol is interpreted as a numeric constant.

Variable names are case sensitive. For example, the variable R1 is not the same as the variable r1. The underscore character (_) is allowed in variable names.

Values in a declaration must be constants rather than variables or expressions. Thus, the declaration LOCAL INT L2:= L3; is not allowed. A value initializing a variable in the Declaration section can be changed in the Selector and Provider sections of the policy.

14.3.2 Selector Section

The Selector section of a policy begins with the keyword SELECTOR and concludes with the keyword END. Selector sections are evaluated to determine which loaded policy will be used.

The Selector sections of all the currently loaded policies are run to determine which policy has the greatest weight. When evaluated, the section returns a weight between 0-100, where 0 means do not use this policy, 1-99 means use this policy if no other policy returns a higher value, and 100 means use this policy.

The result of a Selector section is given in a RETURN declaration. If no RETURN declaration is made, a default value of 0 is returned. The following is a sample Selector section:

SELECTOR
RETURN 49;
END

When the Selector sections of multiple policies are evaluated, more than one policy might return the same value. In this case, it is indeterminate which policy will be selected. All else being equal, a server policy overrides a WAN policy.

For more information on writing declarations, see Construction Used within Policy Sections. See also Provider Section.

14.3.3 Provider Section

The Provider section begins with the keyword PROVIDER and concludes with the keyword END. The body of the Provider section consists of a list of declarations.

The result of this Declarations list is a value representing the policy's suggestion to SEND or DONT_SEND.

The result of a Provider section is given in a RETURN declaration. If no RETURN declaration is made, a default value of SEND is returned.

The following is a sample Provider section:

PROVIDER
RETURN SEND;
END

For more information on writing declarations, see Construction Used within Policy Sections.

14.3.4 Construction Used within Policy Sections

The following statements and constructions can be used, except as noted, in the Selector and Provider sections of a WAN policy. For more information on how to construct the Declaration section of a policy, see Declaration Section.

Comments

Comments can be indicated by using /* at the beginning of the line and */ at the end. For example:

/* This is a comment. */

Comments can also be distinguished by // at the end of the line before a comment. For example:

IF L2 > L3 THEN //This is a comment.

IF-THEN Statement

IF-THEN statements are used to run a block of declarations conditionally.

Examples:

IF Boolean_expression THEN declarations
END
IF Boolean_expression THEN declarations
ELSE declarations
END
IF Boolean_expression THEN declarations
ELSIF Boolean_expression THEN declarations
END

IF Boolean_Expression THEN

This is the first clause in an IF-THEN statement. The Boolean expression is evaluated for a TRUE or FALSE result. If it is TRUE, the declarations that immediately follow are run. If it is FALSE, execution jumps to the next corresponding ELSE, ELSIF, or END declaration.

ELSE

This declaration marks the beginning of declarations that run if all corresponding preceding IF-THEN and ELSIF statements result in FALSE. For example:

IF Boolean_expression THEN statements
ELSIF Boolean_expression THEN statements
ELSIF Boolean_expression THEN statements
ELSE statements
END

ELSIF Boolean_Expression THEN

The Boolean expression is evaluated if the preceding IF-THEN declaration returns a FALSE. The ELSIF declaration is evaluated for a TRUE or FALSE result. If it is TRUE, the declarations that follow are run. If it is FALSE, execution jumps to the next corresponding ELSE, ELSIF, or END declaration.

For example:

IF Boolean_expression THEN statements
ELSIF Boolean_expression THEN statements
ELSIF Boolean_expression THEN statements
END

END

The END declaration terminates an IF-THEN construction.

RETURN

The RETURN declaration gives the results of the Selector and Provider sections.

Selector

In a Selector section, the RETURN declaration provides the integer result used as a weight for the policy. RETURN assigns a policy weight between 0-100, where 0 means do not use this policy, 1-99 means use this policy if no other policy returns a higher value, and 100 means use this policy. If no RETURN declaration is made in a Selector section, a default value of 0 is returned.

A semicolon (;) is required to terminate the declaration. For example:

RETURN 49;
RETURN L2;
RETURN 39+7;

Provider

In a Provider section, the RETURN declaration provides the SEND or DONT_SEND result. If no RETURN declaration is made, a default value of SEND is returned.

A semicolon (;) is required to terminate the declaration. For example:

RETURN SEND; 
RETURN DONT_SEND;
RETURN L1;

Assignment

The assignment declaration changes the value of a symbol using the := characters. The defined variable or system variable is stated first, then the := with a value, variable, or operation following. The assignment declaration must be terminated with a semicolon (;). For example:

variable.field:=expression; variable:=expression;

t1 and t2 are of type TIME, i1 and i2 are type INTEGER, and b1 and b2 are Boolean valid assignments:

t1 := t2;
b1 := t1 < t2;
i1 := t1.mday - 15;
b2 := t2.year < 2000

Invalid assignments:

b1 := 10 < i2 < 12;

(10 < i2) is Boolean, and a BOOLEAN cannot be compared to an INTEGER.

You could use b1 := (10 < i2) AND (i2 < 12); instead. For example:

  b2 := i1;

b2 is Boolean and i1 is INTEGER. Therefore, they are incompatible types.

You could use b2 := i1 > 0; instead.

Strict type checking is performed. You are not allowed to assign an INT to a TIME variable.

Arithmetic Operators

You can include arithmetic operators in assignment declarations, RETURN declarations, or IF constructions. The valid operators are

  • Addition (+)

  • Subtraction (-)

  • Division (/)

  • Multiplication (*)

  • Module (MOD)

Use only INT variable types with arithmetic operators. Do not use TIME, NETADDRESS, or BOOLEAN variable types in arithmetic expressions.

Avoid operations that result in values outside of the range -2147483648 to +2147483648 or division by 0.

Relational Operators

You can use relational operators in IF constructions. The valid operators are

  • Equal to (=)

  • Not equal to (< >)

  • Greater than (>)

  • Greater than or equal to (>=)

  • Less than (<)

  • Less than or equal to (<=)

You can use any relational operators with TIME and INT variable types. You can also use < > and = with NET ADDRESS and BOOLEAN variable types.

Logical Operators

The valid operators are

  • AND

  • OR

  • NOT

  • Less than (<)

  • Greater than (>)

  • Equal to (=)

Bitwise Operators

You can use bitwise operators on INT variable types to return an integer value. The valid operators are

  • BITAND

  • BITOR

  • BITNOT

Complex Operations

The following precedence rules are enforced when processing complex expressions. Operators with the same precedence order are processed left-to-right. The order is as follows:

  • Parenthesis

  • Unary (+/-)

  • BITNOT

  • BITAND

  • BITOR

  • Multiplication, division, MOD

  • Addition, subtraction

  • Relational (>, >=, <, <=, =)

  • NOT

  • AND

  • OR

If you are not certain of precedence, use parentheses. For example, if A, B, and C are integers or variables, A<B<C is not allowed. A<B would return a Boolean value, not an integer value, which cannot be compared to an integer C. However, (A<B) AND (B<C) would be syntactically correct.

PRINT

You can use PRINT declarations to send text and symbol values to the server’s WAN Traffic Manager display screen and to the log file.

PRINT statements can have any number of arguments that can be literal strings, symbol names or members, integer values, or Boolean values, separated by commas.

You must enclose literal strings in double quotes (“ ”). PRINT declarations must end in a semicolon (;). For example:

PRINT "INT=",10,"BOOL=",TRUE,"SYM=",R1;

TIME and NETADDRESS variables use formatted PRINT declarations. TIME symbols are printed as follows:

m:d:y h:m

NETADDRESS variables are printed as follows:

Type length data

Type is either IP or IPX, length is the number of bytes, and data is the hexadecimal address string.