💾 Archived View for gmi.noulin.net › rfc › rfc4011.gmi captured on 2023-06-14 at 20:16:49. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-01-08)
-=-=-=-=-=-=-
Keywords: [--------|p], management information base, Simple Network Management Protocol, snmp, infrastructures, scripting language, script execution environment
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 Waldbusser, et al. Standards Track [Page 1] RFC 4011 Policy Based Management MIB March 2005 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 Waldbusser, et al. Standards Track [Page 2] RFC 4011 Policy Based Management MIB March 2005 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]. Waldbusser, et al. Standards Track [Page 3] RFC 4011 Policy Based Management MIB March 2005 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) Waldbusser, et al. Standards Track [Page 4] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 5] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 6] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 7] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 8] RFC 4011 Policy Based Management MIB March 2005 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 | | | | | ----------------------- | | | -------------------------------- | ------------------------------------------------------- Waldbusser, et al. Standards Track [Page 9] RFC 4011 Policy Based Management MIB March 2005 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 Waldbusser, et al. Standards Track [Page 10] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 11] RFC 4011 Policy Based Management MIB March 2005 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 Waldbusser, et al. Standards Track [Page 12] RFC 4011 Policy Based Management MIB March 2005 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, Waldbusser, et al. Standards Track [Page 13] RFC 4011 Policy Based Management MIB March 2005 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 Waldbusser, et al. Standards Track [Page 14] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 15] RFC 4011 Policy Based Management MIB March 2005 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* Waldbusser, et al. Standards Track [Page 16] RFC 4011 Policy Based Management MIB March 2005 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 ';' Waldbusser, et al. Standards Track [Page 17] RFC 4011 Policy Based Management MIB March 2005 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"; Waldbusser, et al. Standards Track [Page 18] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 19] RFC 4011 Policy Based Management MIB March 2005 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. Waldbusser, et al. Standards Track [Page 20] RFC 4011 Policy Based Management MIB March 2005 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) Waldbusser, et al. Standards Track [Page 21] RFC 4011 Policy Based Management MIB March 2005 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)) Waldbusser, et al. Standards Track [Page 22] RFC 4011 Policy Based Management MIB March 2005 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"; Waldbusser, et al. Standards Track [Page 23] RFC 4011 Policy Based Management MIB March 2005 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); Waldbusser, et al. Standards Track [Page 24] RFC 4011 Policy Based Management MIB March 2005 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 '