Tech-invite3GPPspaceIETFspace
959493929190898887868584838281807978777675747372717069686766656463626160595857565554535251504948474645444342414039383736353433323130292827262524232221201918171615141312111009080706050403020100
in Index   Prev   Next

RFC 4011

Policy Based Management MIB

Pages: 121
Proposed Standard
Part 1 of 4 – Pages 1 to 26
None   None   Next

Top   ToC   RFC4011 - Page 1
Network Working Group                                      S. Waldbusser
Request for Comments: 4011                                    Nextbeacon
Category: Standards Track                                     J. Saperia
                                                    JDS Consulting, Inc.
                                                               T. Hongal
                                               Riverstone Networks, Inc.
                                                              March 2005


                      Policy Based Management MIB

Status of This Memo

   This document specifies an Internet standards track protocol for the
   Internet community, and requests discussion and suggestions for
   improvements.  Please refer to the current edition of the "Internet
   Official Protocol Standards" (STD 1) for the standardization state
   and status of this protocol.  Distribution of this memo is unlimited.

Copyright Notice

   Copyright (C) The Internet Society (2005).

Abstract

This memo defines a portion of the Management Information Base (MIB) for use with network management protocols in TCP/IP-based internets. In particular, this MIB defines objects that enable policy-based monitoring and management of Simple Network Management Protocol (SNMP) infrastructures, a scripting language, and a script execution environment.

Table of Contents

1. The Internet-Standard Management Framework .................. 3 2. Overview .................................................... 4 3. Policy-Based Management Architecture ........................ 4 4. Policy-Based Management Execution Environment ............... 10 4.1. Terminology ........................................... 10 4.2. Execution Environment - Elements of Procedure ......... 10 4.3. Element Discovery ..................................... 11 4.3.1. Implementation Notes .......................... 12 4.4. Element Filtering ..................................... 13 4.4.1. Implementation Notes .......................... 13 4.5. Policy Enforcement .................................... 13 4.5.1. Implementation Notes .......................... 14 5. The PolicyScript Language ................................... 14 5.1. Formal Definition ..................................... 15
Top   ToC   RFC4011 - Page 2
       5.2.  Variables .............................................  18
             5.2.1.  The Var Class .................................  19
       5.3.  PolicyScript QuickStart Guide .........................  23
             5.3.1.  Quickstart for C Programmers ..................  25
             5.3.2.  Quickstart for Perl Programmers ...............  25
             5.3.3.  Quickstart for TCL Programmers ................  25
             5.3.4.  Quickstart for Python Programmers .............  26
             5.3.5.  Quickstart for JavaScript/ECMAScript/JScript
                     Programmers ...................................  26
       5.4.  PolicyScript Script Return Values .....................  26
   6.  Index Information for `this element' ........................  27
   7.  Library Functions ...........................................  28
   8.  Base Function Library .......................................  29
       8.1.  SNMP Library Functions ................................  29
             8.1.1.  SNMP Operations on Non-Local Systems ..........  30
             8.1.2.  Form of SNMP Values ...........................  32
             8.1.3.  Convenience SNMP Functions ....................  34
                     8.1.3.1.  getVar() ............................  34
                     8.1.3.2.  exists() ............................  34
                     8.1.3.3.  setVar() ............................  35
                     8.1.3.4.  searchColumn() ......................  36
                     8.1.3.5.  setRowStatus() ......................  38
                     8.1.3.6.  createRow() .........................  39
                     8.1.3.7.  counterRate() .......................  42
             8.1.4.  General SNMP Functions ........................  44
                     8.1.4.1.  newPDU() ............................  45
                     8.1.4.2.  writeVar() ..........................  45
                     8.1.4.3.  readVar() ...........................  46
                     8.1.4.4.  snmpSend() ..........................  47
                     8.1.4.5.  readError() .........................  48
                     8.1.4.6.  writeBulkParameters() ...............  48
             8.1.5.  Constants for SNMP Library Functions ..........  49
       8.2.  Policy Library Functions ..............................  51
             8.2.1.  elementName() .................................  51
             8.2.2.  elementAddress() ..............................  51
             8.2.3.  elementContext() ..............................  52
             8.2.4.  ec() ..........................................  52
             8.2.5.  ev() ..........................................  52
             8.2.6.  roleMatch() ...................................  52
             8.2.7.  Scratchpad Functions ..........................  53
             8.2.8.  setScratchpad() ...............................  55
             8.2.9.  getScratchpad() ...............................  56
             8.2.10. signalError() .................................  57
             8.2.11. defer() .......................................  57
             8.2.12. fail() ........................................  58
             8.2.13. getParameters() ...............................  58
       8.3.  Utility Library Functions .............................  59
             8.3.1.  regexp() ......................................  59
Top   ToC   RFC4011 - Page 3
             8.3.2.  regexpReplace() ...............................  60
             8.3.3.  oidlen() ......................................  60
             8.3.4.  oidncmp() .....................................  60
             8.3.5.  inSubtree() ...................................  60
             8.3.6.  subid() .......................................  61
             8.3.7.  subidWrite() ..................................  61
             8.3.8.  oidSplice() ...................................  61
             8.3.9.  parseIndex() ..................................  62
             8.3.10. stringToDotted() ..............................  63
             8.3.11. integer() .....................................  64
             8.3.12. string() ......................................  64
             8.3.13. type() ........................................  64
             8.3.14. chr() .........................................  64
             8.3.15. ord() .........................................  64
             8.3.16. substr() ......................................  65
       8.4.  General Functions .....................................  65
   9.  International String Library ................................  65
       9.1.  stringprep() ..........................................  66
             9.1.1.  Stringprep Profile ............................  66
       9.2.  utf8Strlen() ..........................................  67
       9.3.  utf8Chr() .............................................  68
       9.4.  utf8Ord() .............................................  68
       9.5.  utf8Substr() ..........................................  68
   10. Schedule Table ..............................................  69
   11. Definitions .................................................  70
   12. Relationship to Other MIB Modules ........................... 113
   13. Security Considerations ..................................... 114
   14. IANA Considerations ......................................... 117
   15. Acknowledgements ............................................ 118
   16. References .................................................. 118
       16.1. Normative References .................................. 118
       16.2. Informative References ................................ 119
   Authors' Addresses .............................................. 120
   Full Copyright Statement ........................................ 121

1. The Internet-Standard Management Framework

For a detailed overview of the documents that describe the current Internet-Standard Management Framework, please refer to section 7 of RFC 3410 [16]. Managed objects are accessed via a virtual information store, termed the Management Information Base or MIB. MIB objects are generally accessed through the Simple Network Management Protocol (SNMP). Objects in the MIB are defined using the mechanisms defined in the Structure of Management Information (SMI). This memo specifies a MIB module that is compliant to the SMIv2, which is described in STD 58, RFC 2578 [2], STD 58, RFC 2579 [3], and STD 58, RFC 2580 [4].
Top   ToC   RFC4011 - Page 4

2. Overview

Large IT organizations have developed management strategies to cope with the extraordinarily large scale and complexity of today's networks. In particular, they have tried to configure the network as a whole by describing and implementing high-level business policies, rather than manage device by device, where orders of magnitude more decisions (and mistakes) may be made. The following are examples of "business policies": - All routers will run code version 6.2. - On-site contractors will only be connected to ports that are configured with special security restrictions. - All voice over cable ports in California must provide free local calling. - Apply special forwarding to all ports whose customers have paid for premium service. Each of these policies could represent an action applied to hundreds of thousands of variables. To automate this practice, customers need software tools that will implement business policies across their networks, as well as standard protocols that will ensure that policies can be applied to all of their devices, regardless of the vendor. This practice is called Policy-Based Management. This document defines managed objects for the Simple Network Management Protocol that are used to distribute policies in a common form throughout the network.

3. Policy-Based Management Architecture

Policy-based management is the practice of applying management operations globally on all managed elements that share certain attributes. Policies are intended to express a notion of: if (an element has certain characteristics) then (apply an operation to that element)
Top   ToC   RFC4011 - Page 5
   Policies take the following normal form:

      if (policyCondition) then (policyAction)

   A policyCondition is a script that results in a boolean to determine
   whether an element is a member of a set of elements upon which an
   action is to be performed.

   A policyAction is an operation performed on an element or a set of
   elements.

   These policies are most often executed on or near managed devices
   where the elements live (and thus their characteristics may be easily
   inspected) and where operations on those elements will be performed.

   A management station is responsible for distributing an
   organization's policies to all the managed devices in the
   infrastructure.  The pmPolicyTable provides managed objects for
   representing a policy on a managed device.

   An element is an instance of a physical or logical entity and is
   embodied by a group of related MIB variables, such as all the
   variables for interface 7.  This enables policies to be expressed
   more efficiently and concisely.  Elements can also model circuits,
   CPUs, queues, processes, systems, etc.

   Conceptually, policies are executed in the following manner:

   for each element for which policyCondition returns true, execute
      policyAction on that element

   For example:

   If (interface is fast ethernet)       then (apply full-duplex mode)
   If (interface is access)              then (apply security filters)
   If (circuit w/gold service paid for)  then (apply special queuing)

   Each unique combination of policy and element is called an execution
   context.  Within a particular execution context, the phrase 'this
   element' is often used to refer to the associated element, as most
   policy operations will be applied to 'this element'.  The address of
   'this element' contains the object identifier of any attribute of the
   element, the SNMP context the element was discovered in, and the
   address of the system on which the element was discovered.
Top   ToC   RFC4011 - Page 6
   Policies can manage elements on the same system:

         -----------------------------------------------------
         |                                                   |
         |              Managed System                       |
         |                                                   |
         |                                                   |
         |   ------------------             Managed Elements |
         |   |                |               interfaces     |
         |   | Policy Manager | manages...    circuits       |
         |   |                |               queues         |
         |   ------------------               processes      |
         |                                    ...            |
         |                                                   |
         -----------------------------------------------------

   or they can manage elements on other systems:

                                            --------------------------
                                            |  Managed System        |
     --------------------------             |    Managed Elements    |
     |                        |             |      interfaces        |
     |  Management Station or |             |      circuits          |
     |    Mid-Level Manager   |             |      ...               |
     |                        |             --------------------------
     |   ------------------   | manages...
     |   | Policy Manager |   |             --------------------------
     |   ------------------   |             |  Managed System        |
     |                        |             |    Managed Elements    |
     --------------------------             |      interfaces        |
                                            |      circuits          |
                                            |      ...               |
                                            --------------------------

                                            ...

   PolicyConditions have the capability of performing comparison
   operations on SNMP variables, logical expressions, and other
   functions.  Many device characteristics are already defined in MIB
   Modules and are easy to include in policyCondition expressions
   (ifType == ethernet, frCircuitCommittedBurst < 128K, etc).  However,
   there are important characteristics that aren't currently in MIB
   objects, and, worse, it is not current practice to store this
   information on managed devices.  Therefore, this document defines MIB
   objects for this information.  To meet today's needs there are three
   missing areas:  roles, capabilities, and time.
Top   ToC   RFC4011 - Page 7
   Roles

   A role is an administratively specified characteristic of a managed
   element.  As a selector for policies, it determines the applicability
   of the policy to a particular managed element.

   Some examples of roles are political, financial, legal, geographical,
   or architectural characteristics, typically not directly derivable
   from information stored on the managed system.  For example, "paid
   for premium service" or "is plugged into a UPS" are examples of
   roles, whereas the "percent utilization of a link" would not be.

   Some types of information one would put into a role include the
   following:

   political - describes the role of a person or group of people, or of
               a service that a group of people uses.  Examples:
               executive, sales, outside-contractor, customer.
        If (attached user is executive) then (apply higher bandwidth)
        If (attached user is outside-contractor) then (restrict access)

   financial/legal - describes what financial consideration was
                     received.  Could also include contractual or legal
                     considerations.  Examples: paid, gold, free, trial,
                     demo, lifeline.
        If (gold service paid for) then (apply special queuing)

   geographical - describes the location of an element.  Examples:
                  California, Headquarters, insecure conduit.
        If (interface leaves the building) then (apply special security)

   architectural - describes the network architects "intent" for an
                   element.  Examples: backup, trunk.
        If (interface is backup) then (set ifAdminStatus = down)

      Roles in this model are human-defined strings that can be
      referenced by policy code.  The role table in this MIB may be used
      to assign role strings to elements and to view all role string
      assignments.  Implementation-specific mechanisms may also be used
      to assign role strings; however, these assignments must be visible
      in the role table.  Multiple roles may be assigned to each
      element.  Because policy code has access to data in MIB objects
      that represent the current state of the system and (in contrast)
      role strings are more static, it is recommended that role strings
      not duplicate information available in MIB objects.  Role strings
      generally should be used to describe information not accessible in
      MIB objects.
Top   ToC   RFC4011 - Page 8
      Policy scripts may inspect role assignments to make decisions
      based on whether an element has a particular role assigned to it.

      The pmRoleTable allows a management station to learn what roles
      exist on a managed system.  The management station may choose not
      to install policies that depend on a role that does not exist on
      any elements in the system.  The management station can then
      register for notifications of new roles.  Upon receipt of a
      pmNewRoleNotification, it may choose to install new policies that
      make use of that new role.

   Capabilities

      The capabilities table allows a management station to learn what
      capabilities exist on a managed system.  The management station
      may choose not to install policies that depend on a capability
      that does not exist on any elements in the system.  The management
      station can then register for notifications of new capabilities.
      Upon receipt of a pmNewCapabilityNotification, it may choose to
      install new policies that make use of that new capability.

   Time

      Managers may wish to define policies that are intended to apply
      for certain periods of time.  This might mean that a policy is
      installed and is dormant for a period of time, becomes ready, and
      then later goes dormant again.  Sometimes these time periods will
      be regular (Monday-Friday 9-5), and sometimes ad hoc.  This MIB
      provides a schedule table that can schedule when a policy is ready
      and when it is dormant.
Top   ToC   RFC4011 - Page 9
   A policy manager contains the following:

         -------------------------------------------------------
         | Policy Manager                                      |
         |                                                     |
         |   ----------------------------------------          |
         |   | Agent                                |          |
         |   |                                      |          |
         |   |  ---------------------------------   |          |
         |   |  | Policy Download and Control   |   |          |
         |   |  |   pmPolicyTable               |   |          |
         |   |  |   pmElementTypeRegTable       |   |          |
         |   |  |   pmSchedTable                |   |          |
         |   |  ---------------------------------   |          |
         |   |                                      |          |
         |   |  ---------------------------------   |          |
         |   |  | Policy Environment Control    |   |          |
         |   |  |   pmRoleTable                 |   |          |
         |   |  |   pmCapabilitiesTables        |   |          |
         |   |  ---------------------------------   |          |
         |   |                                      |          |
         |   |  ---------------------------------   |          |
         |   |  | Policy Monitoring             |   |          |
         |   |  |   pmTrackingTables            |   |          |
         |   |  |   pmDebuggingTable            |   |          |
         |   |  ---------------------------------   |          |
         |   ----------------------------------------          |
         |                                                     |
         |   --------------------------------                  |
         |   | Execution Environment        |                  |
         |   |                              |                  |
         |   |  -----------------------     |                  |
         |   |  | Policy Scheduler    |     |                  |
         |   |  -----------------------     |                  |
         |   |  -----------------------     |                  |
         |   |  | Language            |     |                  |
         |   |  -----------------------     |                  |
         |   |  -----------------------     |                  |
         |   |  | Function Library    |     |                  |
         |   |  -----------------------     |                  |
         |   --------------------------------                  |
         -------------------------------------------------------
Top   ToC   RFC4011 - Page 10

4. Policy-Based Management Execution Environment

4.1. Terminology

Active Schedule - A schedule specifies certain times that it will be considered active. A schedule is active during those times. Valid Policy - A valid policy is a policy that is fully configured and enabled to run. A valid policy may run unless it is linked to a schedule entry that says the policy is not currently active. Ready Policy - A ready policy is a valid policy that either has no schedule or is linked to a schedule that is currently active. Precedence Group - Multiple policies can be assigned to a precedence group with the resulting behavior that for each element, of the ready policies that match the condition, only the one with the highest precedence value will be active. For example, if there is a default bronze policy that applies to any interface and a special policy for gold interfaces, the higher precedence of the gold policy will ensure that it is run on gold ports and that the bronze policy isn't. Active Execution Context - An active execution context is a pairing of a ready policy with an element that matches the element type filter and the policy condition. If there are multiple policies in the precedence group, it is also necessary that no higher precedence policy in the group match the policy condition. Run-Time Exception (RTE) - A run-time exception is a fatal error caused in language or function processing. If, during the invocation of a script, a run-time exception occurs, execution of that script is immediately terminated. If a policyCondition experiences a run-time exception while processing an element, the element is not matched by the condition and the associated action will not be run on that element. A run-time exception can cause an entry to be added to the pmDebuggingTable and will be reflected in the pmTrackingPEInfo object.

4.2. Execution Environment - Elements of Procedure

There are several steps performed in order to execute policies in this environment: - Element Discovery - Element Filtering - Policy Enforcement
Top   ToC   RFC4011 - Page 11

4.3. Element Discovery

An element is an instance of a physical or logical entity. Examples of elements include interfaces, circuits, queues, CPUs, and processes. Sometimes various attributes of an entity will be described through tables in several standard and proprietary MIB Modules. As long as the indexing is consistent between these tables, the entity can be modeled as one element. For example, the ifTable and the dot3Stats table both contain attributes of interfaces and share the same index (ifIndex), therefore they can be modeled as one element type. The Element Type Registration table allows the manager to learn what element types are being managed by the system and to register new types, if necessary. An element type is registered by providing the OID of an SNMP object (i.e., without the instance). Each SNMP instance that exists under that object is a distinct element. The index part of the discovered OID will be supplied to policy conditions and actions so that this code can inspect and configure the element. The agent can determine the index portion of discovered OIDs based on the length of the pmElementTypeRegOIDPrefix for the portion of the MIB that is being retrieved. For example, if the OIDPrefix is 'ifEntry', which has 9 subids, the index starts on the 11th subid (skipping the subidentifier for the column; e.g., ifSpeed). For each element that is discovered, the policy condition is called with the element's name as an argument to see whether the element is a member of the set the policy acts upon. Note that agents may automatically configure entries in this table for frequently used element types (interfaces, circuits, etc.). In particular, it may configure elements for which discovery is optimized in one or both of the following ways: 1. The agent may discover elements by scanning internal data structures as opposed to issuing local SNMP requests. It is possible to recreate the exact semantics described in this table even if local SNMP requests are not issued. 2. The agent may receive asynchronous notification of new elements (for example, "card inserted") and use that information to create elements instantly rather than through polling. A similar feature might be available for the deletion of elements. Note that upon restart, the disposition of agent-installed entries is described by the pmPolicyStorageType object.
Top   ToC   RFC4011 - Page 12
   A special element type "0.0" represents the "system element".  "0.0"
   represents the single instance of the system itself and provides an
   execution context for policies to operate on "the system" and on MIB
   objects modeled as scalars.  For example, "0.0" gives an execution
   context for policy-based selection of the operating system code
   version (likely modeled as a scalar MIB object).  The element type
   "0.0" always exists.  As a consequence, no actual discovery will take
   place and the pmElementTypeRegMaxLatency object will have no effect
   for the "0.0" element type.  However, if the "0.0" element type is
   not registered in the table, policies will not be executed on the
   "0.0" element.

   If the agent is discovering elements by polling, it should check for
   new elements no less frequently than pmElementTypeRegMaxLatency would
   dictate.  When an element is first discovered, all policyConditions
   are run immediately, and policyConditions that match will have the
   associated policyAction run immediately.  Subsequently, the
   policyCondition will be run regularly for the element, with no more
   than pmPolicyConditionMaxLatency milliseconds elapsing between each
   invocation.  Note that if an implementation has the ability to be
   alerted immediately when a particular type of element is created, it
   is urged to discover that type of element in this fashion rather than
   through polling, resulting in immediate configuration of the
   discovered element.

4.3.1. Implementation Notes

Note that although the external behavior of this registration process is defined in terms of the walking of MIB tables, implementation strategies may differ. For example, commonly used element types (such as interface) may have purpose-built element discovery capability built-in and advertised to managers through an entry in the pmElementTypeRegTable. Before registering an element type, a manager is responsible for inspecting the table to see whether it is already registered (either by the agent or by another manager). Note that entries that differ only in the last subid (which specifies which object is an entry) are effectively duplicates and should be treated as such by the manager. The system that implements the Policy-Based Management MIB may not have knowledge of the format of object identifiers in other MIB Modules. Therefore it is inappropriate for it to check these OIDs for errors. It is the responsibility of the management station to register well-formed object identifiers. For example, if an extra sub-identifier is supplied when the ifTable is registered, no
Top   ToC   RFC4011 - Page 13
   elements will be discovered.  Similarly, if a sub-identifier is
   missing, every element will be discovered numerous times (once per
   column) and none of the element addresses will be well formed.

4.4. Element Filtering

The first step in executing a policy is to see whether the policy is ready to run based on its schedule. If the pmPolicySchedule object is equal to zero, there is no schedule defined, and the policy is always ready. If the pmPolicySchedule object is non-zero, then the policy is ready only if the referenced schedule group contains at least one valid schedule entry that is active at the current time. If the policy is ready, the next step in executing a policy is to see which elements match the policy condition. The policy condition is called once for each element and runs to completion. The element's name is the only argument that is passed to the condition code for each invocation. No state is remembered within the policy script from the previous invocation of 'this element' or from the previous invocation of the policy condition, except for state accessible through library functions. Two notable examples of these are the scratchpad functions, which explicitly provide for storing state, and the SNMP functions, which can store state in local or remote MIB objects. If any run-time exception occurs, the condition will terminate immediately for 'this element'. If the condition returns non-zero, the corresponding policy action will be executed for 'this element'. If an element matches a condition and it had not matched that condition the last time it was checked (or if it is a newly discovered element), the associated policyAction will be executed immediately. If the element had matched the condition at the last check, it will remain in the set of elements whose policyAction will be run within the policyActionMaxLatency.

4.4.1. Implementation Notes

Whether policy conditions are multi-tasked is an implementation- dependent matter. Each condition/element combination is conceptually its own process and can be scheduled sequentially, or two or more could be run simultaneously.

4.5. Policy Enforcement

For each element that has returned non-zero from the policy condition, the corresponding policy action is called. The element's name is the only argument that is passed to the policy action for each invocation. Except for state accessible from library functions,
Top   ToC   RFC4011 - Page 14
   no state is remembered from the policy condition evaluation, or from
   the previous condition/action invocation of 'this element' or from
   the previous invocation of the policy condition or action on any
   other element.  If any run-time exception occurs, the action will
   terminate immediately for 'this element'.

4.5.1. Implementation Notes

How policy actions are multi-tasked is an implementation-dependent matter. Each condition/element combination is conceptually its own process and can be scheduled sequentially, or two or more could be run simultaneously.

5. The PolicyScript Language

Policy conditions and policy actions are expressed with the PolicyScript language. The PolicyScript language is designed to be a small interpreted language that is simple to understand and implement; it is designed to be appropriate for writing small scripts that make up policy conditions and actions. PolicyScript is intended to be familiar to programmers that know one of several common languages, including Perl and C. Nominally, policyScript is a subset of the C language; however, it was desirable to have access to C++'s operator overloading (solely to aid in documenting the language). Therefore, PolicyScript is defined formally as a subset of the C++ language in which many of the operators are overloaded as part of the "var" class. Note, however, that a PolicyScript program cannot further overload operators, as the syntax to specify overloading is not part of the PolicyScript syntax. A subset was used to provide for easy development of low-cost interpreters of PolicyScript and to take away language constructs that are peculiar to the C/C++ languages. For example, it is expected that both C and Perl programmers will understand the constructs allowed in PolicyScript. Some examples of the C/C++ features that are not available are function definitions, pointer variables, structures, enums, typedefs, floating point and pre-processor functions (except for comments). This language is formally defined as a subset of ISO C++ [10] but only allows constructs that may be expressed in the Extended Backus- Naur Form (EBNF) documented here. This is because although EBNF doesn't fully specify syntactical rules (it allows constructs that are invalid) and doesn't specify semantic rules, it can successfully be used to define the subset of the language that is required for
Top   ToC   RFC4011 - Page 15
   conformance to this specification.  Unless explicitly described
   herein, the meaning of any construct expressed in the EBNF can be
   found by reference to the ISO C++ standard.

   The use of comments and newlines are allowed and encouraged in order
   to promote readability of PolicyScript code.  Comments begin with
   '/*' and end with '*/' or begin with '//' and go until the end of the
   line.

   One subset is not expressible in the EBNF syntax: all variables
   within an instance of a PolicyScript script are within the same
   scope.  In other words, variables defined in a block delimited with
   '{' and '}' are not in a separate scope from variables in the
   enclosing block.

   PolicyScript code must be expressed in the ASCII character set.

   In the EBNF used here, terminals are character set members (singly or
   in a sequence) that are enclosed between two single-quote characters
   or described as a phrase between '<' and '>' characters.
   Nonterminals are a sequence of letters and underscore characters.  A
   colon (:) following a nonterminal introduces its definition, a
   production.  In a production, a '|' character separates alternatives.
   The '(' and ')' symbols group the enclosed items.  The '[' and ']'
   symbols indicate that the enclosed items are optional.  A '?'  symbol
   following an item indicates that the item is optional.  A '*' symbol
   following an item indicates that the item is repeated zero, one, or
   more times.  A '+' symbol following an item indicates that the item
   is repeated one or more times.  The symbol '--' begins a comment that
   ends at the end of the line.

5.1. Formal Definition

The PolicyScript language follows the syntax and semantics of ISO C++ [10], but is limited to that which can be expressed in the EBNF below. The following keywords are reserved words and cannot be used in any policy script. This prevents someone from using a common keyword in another language as an identifier in a script, thereby confusing the meaning of the script. The reserved words are: auto, case, char, const, default, do, double, enum, extern, float, goto, inline, int, long, register, short, signed, sizeof, static, struct, switch, typedef, union, unsigned, void, and volatile.
Top   ToC   RFC4011 - Page 16
   Any syntax error, use of a reserved keyword, reference to an unknown
   identifier, improper number of function arguments, error in coercing
   an argument to the proper type, exceeding local limitations on string
   length, or exceeding local limitations on the total amount of storage
   used by local variables will cause an RTE.

   PolicyScript permits comments using the comment delimiters, '/*' to
   '*/', or the start of comment symbol '//'.

-- Lexical Grammar

   letter:       '_' | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
               | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm'
               | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't'
               | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'
               | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
               | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M'
               | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T'
               | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z'

   digit:        '0' | '1' | '2' | '3' | '4'
               | '5' | '6' | '7' | '8' | '9'

   non_zero:   '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'

   oct_digit:  '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7'

   hex_digit:    digit | 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
                       | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'

   escape_seq:    '\''   |   '\"'   |   '\?'   |   '\\'
                | '\a'   |   '\b'   |   '\f'   |   '\n'
                | '\r'   |  '\t'    |   '\v'
                | '\' oct_digit+    | '\x' hex_digit+

   non_quote:  Any character in the ASCII character set
               except single quote ('), double quote ("),
               backslash ('\'), or newline.

   c_char:            non_quote | '"' | escape_seq

   string_literal:    '"' s_char* '"'

   s_char:            non_quote | ''' | escape_seq

   char_constant:     ''' c_char '''

   decimal_constant:  non_zero digit*
Top   ToC   RFC4011 - Page 17
   octal_constant:    '0' oct_digit*

   hex_constant:      ( '0x' | '0X' ) hex_digit+

   integer_constant:  decimal_constant | octal_constant | hex_constant

   identifier:        letter ( letter | digit )*

-- Phrase Structure Grammar

   -- Expressions

   primary_expr:      identifier | integer_constant | char_constant
                    | string_literal  |  '(' expression ')'

   postfix_expr:      primary_expr
                    | identifier '(' argument_expression_list? ')'
                    | postfix_expr '++'
                    | postfix_expr '--'
                    | postfix_expr '[' expression ']'

   argument_expression_list:
                      assignment_expr
                    | argument_expression_list ',' assignment_expr

   unary_expr:        postfix_expr  |  unary_op unary_expr

   unary_op:          '+' | '-' | '~' | '!' | '++' | '--'

   binary_expr:  unary_expr | binary_expr binary_op unary_expr

   binary_op:       '||' | '&&' | '|'  | '^'  | '&'  | '!='
                  | '==' | '>=' | '<=' | '>'  | '<'  | '>>'
                  | '<<' |  '-' | '+'  | '%'  | '/'  |  '*'

   assignment_expr:      binary_expr
                       | unary_expr assignment_op assignment_expr

   assignment_op:     '=' | '*='  | '/=' | '%=' | '+=' | '-='
                  | '<<=' | '>>=' | '&=' | '^=' | '|='

   expression:    assignment_expr | expression ',' assignment_expr

   -- Declarations

   declaration:       'var' declarator_list ';'
Top   ToC   RFC4011 - Page 18
   declarator_list:   init_declarator
                    | declarator_list ',' init_declarator

   init_declarator:   identifier [ '=' assignment_expr ]

   -- Statements

   statement:   declaration
              | compound_statement
              | expression_statement
              | selection_statement
              | iteration_statement
              | jump_statement

   compound_statement:    '{' statement* '}'

   expression_statement:  expression? ';'

   selection_statement:
           'if' '(' expression ')' statement
         | 'if' '(' expression ')' statement 'else' statement

   iteration_statement:
           'while' '(' expression ')' statement
         | 'for' '(' expression? ';' expression? ';' expression? ')'
               statement

   jump_statement:    'continue' ';'
                    | 'break' ';'
                    | 'return' expression? ';'

   -- Root production

   PolicyScript:     statement*

5.2. Variables

To promote shorter scripts and ease in writing them, PolicyScript provides a loosely typed data class, "var", that can store both integer and string values. The native C++ types (char, int, etc.) are thus unnecessary and have not been carried into the subset that comprises this language. The semantics of the "var" type are modeled after those of ECMAScript[17]. For example: var number = 0, name = "IETF";
Top   ToC   RFC4011 - Page 19
   This language will be executed in an environment where the following
   typedef is declared.  (Note that this typedef will not be visible in
   the policyCondition or policyAction code.)

      typedef ... var;

   Although this declaration is expressed here as a typedef, the
   'typedef' keyword itself is not available to be used in PolicyScript
   code.

5.2.1. The Var Class

A value is an entity that takes on one of two types: string or integer. The String type is the set of all finite ordered sequences of zero or more 8-bit unsigned integer values ("elements"). The string type can store textual data as well as binary data sequences. Each element is considered to occupy a position within the sequence. These positions are indexed with nonnegative integers. The first element (if any) is at position 0, the next element (if any) at position 1, and so on. The length of a string is the number of elements (i.e., 8-bit values) within it. The empty string has length zero and therefore contains no elements. The integer type is the set of all integer values in the range -9223372036854775808 (-2^63) to 18446744073709551615 (2^64-1). If an integer operation would cause a (positive) overflow, then the result is returned modulo 2^64. If an integer operation would cause a (negative) underflow, then the result is undefined. Integer division rounds toward zero. Prior to initialization, a var object has type String and a length of zero. The policy script runtime system performs automatic type conversion as needed. To clarify the semantics of certain constructs it is useful to define a set of conversion operators: ToInteger(), ToString(), ToBoolean(), and Type(). These operators are not a part of the language; they are defined here to aid the specification of the semantics of the language. The conversion operators are polymorphic; that is, they can accept a value of any standard type.
Top   ToC   RFC4011 - Page 20
   ToInteger

   The operator ToInteger converts its argument to a value of type
   Integer according to the following table:

         Integer            The result equals the input argument
                            (no conversion).
         String             See grammar and note below.
         integer_constant   The result equals the input argument
                            (no conversion).
         string_literal     See grammar and note below.
         char_constant      See grammar and note below.

   ToInteger Applied to Strings

   ToInteger applied to the String Type string_literal and to
   char_constants applies the following grammar to the input.  If the
   grammar cannot interpret the string as an expansion of
   numeric_string, then an RTE is generated.  Note that a numeric_string
   that is empty or contains only white space is converted to 0.

 -- EBNF for numeric_string

   numeric_string : white_space* numeric? white_space*

   white_space :      <TAB> |  <SP> |  <NBSP> |  <FF> |  <VT>
                    | <CR>  |  <LF> |  <LS>   |  <PS> |  <USP>

   numeric :        signed_decimal |  hex_constant | octal_constant |
                    enum_decimal

   signed_decimal:  [ '-' | '+' ] decimal_constant

   enum_decimal:    [ letter | digit | '-' ]* '(' decimal_constant ')'

   -- decimal_constant, hex_constant, and octal_constant are defined
   -- in the PolicyScript EBNF described earlier.

   Note that when the enum_decimal form is converted, the sequence of
   characters before the parenthesis and the pair of parenthesis
   themselves are completely ignored, and the decimal_constant inside
   the parenthesis is converted.  Thus, "frame-relay(32)" translates to
   the integer 32.

   Although this will make the script more readable than using the
   constant "32", the burden is on the code writer to be accurate, as
   "ethernet-csmacd(32)" and "frame-relay(999)" will also be accepted.
Top   ToC   RFC4011 - Page 21
   ToString

   The operator ToString converts its argument to a value of type String
   according to the following table:

      Integer           Return the string containing the decimal
                        representation of the input argument in
                        the form of signed_decimal, except that
                        no leading '+' will be used.
      String            Return the input argument (no conversion)
      integer_constant  Return the string containing the decimal
                        representation of the input argument in the
                        form of signed_decimal except that no
                        leading '+' will be used.
      string_literal    Return the input argument (no conversion)
      char_constant     Return the string of length one containing
                        the value of the input argument.

   ToBoolean

   The operator ToBoolean converts its argument to a value of type
   Integer according to the following table:

      Integer            The result is 0 if the argument is 0.
                         Otherwise the result is 1.
      String             The results is 0 if the argument is the
                         empty string.  Otherwise the result is 1.
      integer_constant   The result is 0 if the argument is 0.
                         Otherwise the result is 1.
      string_literal     The result is 0 if the argument is the
                         empty string.  Otherwise the result is 1.
      char_constant      The result is 1.

   Operators

   The rules below specify the type conversion rules for the various
   operators.

      A++:   A = ToInteger(A); A++;
      A--:   A = ToInteger(A); A--;
      ++A:   A = ToInteger(A); ++A;
      --A:   A = ToInteger(A); --A;
      +A:    ToInteger(A);
      -A:     -1 * ToInteger(A);
      ~A:    ToInteger(A);
      !A:    !ToBoolean(A);
      A * B, A - B, A & B, A ^ B , A | B, A << B, A >> B:
             ToInteger(A) <operator> ToInteger(B)
Top   ToC   RFC4011 - Page 22
      A / B, A % B:
             if (ToInteger(B) == 0)
               RTE, terminate;
             else
               ToInteger(A) <operator> ToInteger(B)
      A + B:
             if (Type(A) == String || Type(B) == String)
               ToString(A) concatenated with ToString(B)
             else
               A + B
      Compound Assignment (<operator>=):
              Simply follow rules above.  Note that type of LHS (Left
              Hand Side) may be changed as a result.

      A < B, A > B, A <= B, A >= B, A == B, A != B:
             if (Type(A) == String && Type(B) == String)
                 lexically compare strings with strcmp() logic
             else
                 ToInteger(A) <operator> ToInteger(B)
       A && B:
              if (ToBoolean(A))
                  ToBoolean(B);
              else
                  false;
       A || B:
              if (ToBoolean(A))
                  true;

              else
                  ToBoolean(B);

       if(A):
              if (ToBoolean(A))
       while(A):
              while(ToBoolean(A))
       for(...; A; ...):
             for(...; ToBoolean(A); ...)

       A[B] as a RHS (Right Hand Side) value:
             if (Type(A) != String
                  || ToInteger(B) >= strlen(A))
                RTE, terminate;
             A[ ToInteger(B) ]
             The contents are returned as a string of length one

        A[B] = C as a LHS value:
             if (Type(A) != String
                  || ToInteger(B) >= strlen(A))
Top   ToC   RFC4011 - Page 23
                RTE, terminate;
             if (strlen(ToString(C)) == 0)
                RTE, terminate
             A[ ToInteger(B) ] = First octet of ToString(C)

             Note that this is only applicable in a simple assignment.

   For example, in the expression

      "getVar("ifSpeed.1") < 128000"

   getVar always returns a string and '128000' is implicitly an integer.
   The rules for '<' dictate that if either argument is an integer then
   a 'numeric less than' is performed on ToInteger(A) and ToInteger(B).

   If "getVar("ifSpeed.1")" returns "64000", the expression can be
   translated to:

        ToInteger("64000") < ToInteger(128000); or,
        64000 < 128000; or,
        True

5.3. PolicyScript QuickStart Guide

PolicyScript is designed so that programmers fluent in other languages can quickly begin to write scripts. One way to become familiar with a language is to see it in action. The following nonsensical script exercises most of the PolicyScript constructs (though it skips some usage options and many arithmetic operators). var x, index = 7, str = "Hello World", oid = "ifSpeed."; x = 0; while(x < 10){ if (str < "Goodbye") /* string comparison */ continue; else break; x++; } if (oidlen(oid) == 10) oid += "." + index; // append index to oid for(x = 0; x < 7; x++){ str += "a";
Top   ToC   RFC4011 - Page 24
            var y = 12;
            index = ((x * 7) + y) % 3;
            if (str[6] == 'W')
                return index;
      }
      return;

   The following examples are more practical:

   For a condition:
      // Return 1 if this is an interface and it is tagged
      // with the role "gold"
      return (inSubtree(elementName(), "ifEntry")
          && roleMatch("gold"))

   A condition/action pair:
   First, register the Host Resources MIB hrSWRunEntry as a new element
   in the pmElementTypeRegTable.  This will cause the policy to run for
   every process on the system.  The token '$*' will be replaced by the
   script interpreter with a process index (see Section 7 for a
   definition of the '$*' token).

   The condition:
      // if it's a process and it's an application and it's
      // consumed more than 5 minutes of CPU time
      return (inSubtree(elementName(), "hrSWRunEntry")
              && getVar("hrSWRunType.$*") == 4  // app, not OS or driver
              && getVar("hrSWRunPerfCPU.$*") > 30000) // 300 seconds

   The action:
      // Kill it
      setVar("hrSWRunStatus.$*", 4, Integer); // invalid(4) kills it

   A more substantial action to start an RMON2 host table on interfaces
   that match the condition:

      var pdu, index;

      pdu = newPDU();
      writeVar(pdu, 0, "hlHostControlDataSource.*",
               "ifIndex." + ev(0), Oid);
      writeVar(pdu, 1, "hlHostControlNlMaxDesiredEntries.*", 1000,
               Integer);
      writeVar(pdu, 2, "hlHostControlAlMaxDesiredEntries.*", 1000,
               Integer);
      writeVar(pdu, 3, "hlHostControlOwner.*", "policy", String);
Top   ToC   RFC4011 - Page 25
      writeVar(pdu, 4, "hlHostControlStatus.*", "active(1)", Integer);
      if (createRow(pdu, 5, 4, 20, 65535, index) == 0
          || index == -1)
          return;

   Because PolicyScript is a least common denominator, it contains
   nothing that would astonish programmers familiar with C, C++, Perl,
   Tcl, JavaScript, or Python.  Although a new programmer may attempt to
   use language constructs that aren't available in PolicyScript, s/he
   should be able to understand any existing PolicyScript and will
   likely know how to use anything that is valid in PolicyScript.  The
   lists below quickly enumerate the changes of note for programmers
   coming from some particular languages.  These lists won't describe
   the unavailable constructs, but it is easy to see from the definition
   above what is available.

5.3.1. Quickstart for C Programmers

- Character constants (i.e., 'c') are treated as one-character strings, not as integers. So operations such as ('M' - 'A') or (x + 'A') will not perform as expected. - Functions can change the value of arguments even though they are not pointers (or called like '&arg'). - All variables are in the same scope.

5.3.2. Quickstart for Perl Programmers

- Comments are '/* comment */' and '// till end of line', not '#'. - No need to put a '$' in front of variables. - Strings are compared with ==, <=, <, etc. (details in Sec. 6.2.1). - Strings are concatenated with '+' (details in Sec. 6.2.1). - No variable substitution in "" strings. '' strings are 1 char only. - Variables must be declared before use (but no type is necessary). - All variables are in the same scope.

5.3.3. Quickstart for TCL Programmers

- Comments are '/* comment */' and '// till end of line', not '#'. - No need to put a '$' in front of variables. - Function calls are func-name(arg1, arg2, ...). - Square braces [] don't interpret their contents. - Double quotes "" surround a string, but no substitutions are performed ("" is like { } in TCL ). - Statements are terminated by a semicolon (;). - Instead of "Set a b", use "b = a;". - Strings are concatenated with '+' (details in Sec. 6.2.1). - All variables are in the same scope.
Top   ToC   RFC4011 - Page 26

5.3.4. Quickstart for Python Programmers

- Comments are '/* comment */' and '// till end of line', not '#'. - Single quotes can be used only for single-character strings ('a'). - Indentation doesn't matter. Braces { } define blocks. - Variables must be declared before use (but no type is necessary). - The expressions for if and while are always surrounded by parenthesis, as in "if (x < 5)". - 'for' syntax is "for(expression; expression; expression)" (see EBNF). - All variables are in the same scope.

5.3.5. Quickstart for JavaScript/ECMAScript/JScript Programmers

- Variables must be declared before use. - Functions can change the value of arguments. - All variables are in the same scope.

5.4. PolicyScript Script Return Values

A PolicyScript script execution is normally ended by the execution of a return statement, or by having the flow of execution reach the end of the final statement in the script. A normal script execution always returns a Boolean value. If no explicit value is specified in the return statement, or if the flow of control proceeds through the end of the script, the return value is implicitly zero. If an expression is provided with the return statement, the expression is evaluated, and the result of the expression is implicitly converted with the ToBoolean operator before being returned to the script execution environment. The return value of a policyCondition script is used to determine whether the associated policyAction script is executed. If the returned value is zero, the associated policyAction script is not executed. If the returned value is one, the associated policyAction script will be executed. The return value of a policyAction script is ignored. An RTE or invocation of the fail() function will cause the return value of the script to be set to zero. Note however, that execution of the defer() or fail() functions may set the defer attribute so that the lower precedence script may be executed. This is independent of the return value of the policy script execution.