RFC 4011 - Policy Based Management MIB (Formats: TXT)
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 '$' 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.
Waldbusser, et al. Standards Track [Page 25]
RFC 4011 Policy Based Management MIB March 2005
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.
Waldbusser, et al. Standards Track [Page 26]
RFC 4011 Policy Based Management MIB March 2005
6. Index Information for 'this element'
PolicyScript code needs a convenient way to get the components of the
index for 'this element' so that they can perform SNMP operations on
it or on related elements.
Two mechanisms are provided.
1. For all OID input parameters to all SNMP Library Functions (but
not OID utility functions), the token "$n" ('$' followed by an
integer between 0 and 128) can be used in place of any decimal
sub-identifier. This token is expanded by the agent at execution
time to contain the nth subid of the index for the current
element. For example, if the element is interface 7, and the
objectIdentifier is "1.3.6.1.2.1.2.2.1.3.$0", it will be expanded
to "1.3.6.1.2.1.2.2.1.3.7". The special token "$*" is expanded to
contain all of the subidentifiers of the index of the current
element, separated by '.' characters.
It is an RTE if a token is specified that is beyond the length of
the index for the current element.
Note that the "$n" convention is only active within strings.
2. The ec() and ev() functions allow access to the components of the
index for 'this element'. ec() takes no argument and returns the
number of index components that exist. ev() takes an integer
argument specifying which component of the index (numbered
starting at 0) and returns an integer containing the value of the
n'th subidentifier. Refer to the Library functions section for
the complete definition of ec() and ev().
For example, if 'this element' is frCircuitDLCI.5.57
(ifIndex = 5, DLCI = 57)
then ec() returns 2
ev(0) returns 5
ev(1) returns 57
This is helpful when one wishes to address a related element.
Extending the previous example, to find the port speed of the
port, the circuit (above) runs over:
portSpeed = getVar("ifSpeed." + ev(0));
A script may check the type of 'this element' by calling the
elementName() function. Although it is possible to write a script
that will work with different types of elements, many scripts will
Waldbusser, et al. Standards Track [Page 27]
RFC 4011 Policy Based Management MIB March 2005
assume a particular element type and will work incorrectly if used
on different element types.
7. Library Functions
Library functions are built-in functions available primarily to
provide access to information on the local system or to manipulate
this information more efficiently. A group of functions is organized
into a library, the unit of conformance for function implementation.
In order to claim conformance to a library, an implementation must
implement all functions in a library to the specifications of the
library.
In order for a management station or a condition or action to
understand whether a certain library of functions is implemented,
each library will have a name that it registers in the role table as
a characteristic of the system element ("0.0") in the default SNMP
context. Thus, conformance to a library can be tested with the
roleMatch library function (in the base library) with the call
roleMatch ("libraryName", "0.0").
Note that in the descriptions of these functions below, the function
prototype describes the type of argument expected. Even though
variables are not declared with a particular type, their contents
must be appropriate for each function argument. If the type is
variable, the keyword 'var' will be used. If only a string is
appropriate, the keyword 'string' will be used. If only an integer
is appropriate, the keyword 'integer' will be used. If the argument
is declared as 'string' or 'integer' and a value of a different type
is passed, the argument will be coerced with ToInteger() or
ToString(). Any failure of this coercion will cause an RTE (in
particular for ToInteger(), which will fail if its string-valued
argument is not a well-formed integer).
In the function prototype, if the '&' character precedes the
identifier for an argument, that argument may be modified by the
function (e.g., "integer &result, ...)"). Arguments without the '&'
character cannot be modified by the function. In a script,
modifiable arguments don't have to be preceded by a '&'. It is an
RTE if a constant is passed to a modifiable function argument
(regardless of whether the function actually writes to the argument).
In the function prototype, the '[' and ']' characters surround
arguments that are optional. In PolicyScript code, the optional
argument may only be included if all optional arguments to the left
of it are included. The function may place restrictions on when an
optional argument must, or must not, be included.
Waldbusser, et al. Standards Track [Page 28]
RFC 4011 Policy Based Management MIB March 2005
In the function prototype, if a type is listed before the name of the
function, the function returns a value of that type. If no type is
listed, the function returns no value.
8. Base Function Library
A standard base library of functions is available to all systems that
implement this specification. This library is registered with the
name "pmBaseFunctionLibrary". Although the specification of this
library is modularized into 4 separate sections, conformance to the
library requires implementation of all functions in all sections.
The sections are:
- SNMP library functions
- Policy library functions
- Utility functions
- Library Functions
8.1. SNMP Library Functions
Two sets of SNMP Library functions are available with different
situations in mind:
- Convenience SNMP Functions
In an effort to keep simple things simple, these functions are easy
to use and code that is easy to understand. These functions will
suffice for the majority of situations, where a single variable is
referenced and the desired error recovery is simply (and
immediately) to give up (and move to the next policy-element
combination). In more complex cases, the General SNMP Functions
can be used at the cost of several times the code complexity.
The convenience SNMP functions are getVar, exists, setVar,
setRowStatus, createRow, counterRate, and searchColumn.
- General SNMP Functions
The General SNMP functions allow nearly any legal SNMP Message to
be generated, including those with multiple varbinds, getNext
operations, notifications, and messages with explicit addressing or
security specifications.
The general SNMP functions are writeVar, readVar, snmpSend,
readError, and writeBulkParameters.
Waldbusser, et al. Standards Track [Page 29]
RFC 4011 Policy Based Management MIB March 2005
8.1.1. SNMP Operations on Non-Local Systems
From time to time, a script may have to perform an operation on a
different SNMP system than that on which 'this element' resides.
Scripts may also have to specify the use of alternate security
parameters. In order to do this, the following optional arguments
are provided for the SNMP library functions:
snmp-function(...[, integer mPModel,
string tDomain, string tAddress,
integer secModel, string secName,
integer secLevel, string contextEngineID
])
For example:
getVar("sysDescr.0", "", SNMPv3, "transportDomainUdpIpv4",
"192.168.1.1:161", USM, "joe", NoAuthNoPriv);
The use of these arguments is denoted in function definitions by the
keyword 'NonLocalArgs'. The definitions of these arguments are as
follows:
'mPModel' is the integer value of the SnmpMessageProcessingModel
to use for this operation.
'tDomain' is a string containing an ASCII dotted-decimal object
identifier representing the transport domain to use for this
operation.
'tAddress' is a string containing the transport address formatted
according to the 'tDomain' argument. The ASCII formats for
various values of 'tDomain' are defined by the DISPLAY-HINT for a
TEXTUAL-CONVENTION that represents an address of that type. The
DISPLAY-HINTs used are:
tDomain Source of DISPLAY-HINT [5] [11]
------- ----------------------
transportDomainUdpIpv4 TransportAddressIPv4
transportDomainUdpIpv6 TransportAddressIPv6
transportDomainUdpDns TransportAddressDns
snmpCLNSDomain snmpOSIAddress
snmpCONSDomain snmpOSIAddress
snmpDDPDomain snmpNBPAddress
snmpIPXDomain snmpIPXAddress
rfc1157Domain snmpUDPAddress
Other Use DISPLAY-HINT "1x:"
Waldbusser, et al. Standards Track [Page 30]
RFC 4011 Policy Based Management MIB March 2005
'secModel' is the integer value of the SnmpSecurityModel to use
for this operation.
'secName' is a string value representing the SnmpSecurityName to
use for this operation.
'secLevel' is the integer value of the SnmpSecurityLevel to use
for this operation.
An SNMP operation will be sent to the target system by using
security parameters retrieved from a local configuration datastore
based on 'secModel', 'secName', and 'secLevel'. It is the
responsibility of the agent to ensure that sensitive information
in the local configuration datastore is used on behalf of the
correct principals, as identified by the security credentials of
the last entity to modify the pmPolicyAdminStatus for a policy.
To illustrate how this must be configured, consider an example in
which 'joe' installs a policy on 'PMAgent' that will periodically
configure objects on 'TargetAgent' with the credentials of
'Operator'. The following conditions must be true for this policy
to execute with the proper privileges:
- 'Operator's security credentials for TargetAgent must be
installed in PMAgent's local configuration datastore (e.g.,
usmUserTable [6]) indexed by TargetAgent's engineID and
'Operator'.
- VACM [9] must be configured on PMAgent so that 'joe' has access
to the above entry in the appropriate MIB for the local
configuration datastore (e.g., usmUserTable).
- 'joe' must be the last user to modify the pmPolicyAdminStatus
object for the policy.
See the Security Considerations section for more information.
For convenience, constants for 'mPModel', 'secModel', and
'secLevel' are defined in the "Constants" section below.
'contextEngineID' is a string representing the contextEngineID of
the SNMP entity targeted by this operation. It is encoded as a
pair of hex digits (upper- and lowercase are valid) for each octet
of the contextEngineID. If 'tDomain' and 'tAddress' are provided
but 'contextEngineID' is not, then the operation will be directed
to the SNMP entity reachable at 'tDomain' and 'tAddress'.
In order for PolicyScript code to use any of these arguments, all
optional arguments to the left must be included. 'mPModel',
'tDomain', 'tAddress', 'secModel', 'secName', and 'secLevel' must
Waldbusser, et al. Standards Track [Page 31]
RFC 4011 Policy Based Management MIB March 2005
be used as a group; if one is specified, they must all be.
'contextEngineID' may only be specified if all others are
specified.
Note that a function that uses NonLocalArgs must provide a
parameter for the contextName that will be required when the
NonLocalArgs are present. Many functions will have the following
logic:
ContextName NonLocalArgs
Supplied Supplied
No No Addressed to default context on
local system.
Yes No Addressed to named context on
local system.
Yes Yes Addressed to named context on
potentially remote system.
No Yes Not allowed.
8.1.2. Form of SNMP Values
Many of the library functions have input or output parameters that
may be one of the many SMI data types. The actual type is not
encoded in the value but is specified elsewhere, possibly by nature
of the situation in which it is used. The exact usage for input and
output is as follows:
Any Integer value
(INTEGER, Integer32, Counter32, Counter64, Gauge32, Unsigned32,
TimeTicks, Counter64):
On input:
An Integer or a String that can be successfully coerced to an
Integer with the ToInteger() operator. It is an RTE if a
string is passed that cannot be converted by ToInteger() into
an integer.
A string of the form
enum_decimal: [ letter | digit | '-' ]* '(' decimal_constant
')'
will also be accepted. In this case the sequence of characters
before the parentheses and the parentheses themselves are
completely ignored, and the decimal_constant inside the
parentheses is converted. Thus, "frame-relay(32)" translates
to the integer 32.
Waldbusser, et al. Standards Track [Page 32]
RFC 4011 Policy Based Management MIB March 2005
On output:
An Integer containing the returned value.
Octet String
On input:
Either a String or an Integer. If an Integer, it will be
coerced to a String with the ToString() function. This string
will be used as an unencoded representation of the octet string
value.
On output:
A String containing the unencoded value of the octet string.
Object Identifier
On input and on output:
A String containing a decimal ASCII encoded object identifier
of the following form:
oid: subid [ '.' subid ]* [ '.' ]
subid: '0' | decimal_constant
It is an RTE if an Object Identifier argument is not in the form
above. Note that a trailing '.' is acceptable and will simply be
ignored. (Note, however, that a trailing dot could cause a
strncmp() comparison of two otherwise-identical OIDs to fail;
instead, use oidncmp().)
Note that ASCII descriptors (e.g., "ifIndex") are never used in
these encodings "over the wire". They are never returned from
library functions; nor are they ever accepted by them. NMS user
interfaces are encouraged to allow humans to view object
identifiers with ASCII descriptors, but they must translate those
descriptors to dotted-decimal format before sending them in MIB
objects to policy agents.
Null
On input:
The input is ignored.
On output:
A zero length string.
Waldbusser, et al. Standards Track [Page 33]
RFC 4011 Policy Based Management MIB March 2005
8.1.3. Convenience SNMP Functions
8.1.3.1. getVar()
The getVar() function is used to retrieve the value of an SNMP MIB
object instance.
string getVar(string oid [, string contextName, NonLocalArgs])
'oid' is a string containing an ASCII dotted-decimal
representation of an object identifier (e.g.,
"1.3.6.1.2.1.1.1.0").
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform an SNMP operation on a system different
from that of 'this element'.
It is an RTE if the queried object identifier value does not
exist.
This function returns a string containing the returned value,
encoded according to the returned type. Note that no actual
SNMP PDU has to be generated and parsed when the policy MIB
agent resides on the same system as the managed elements.
It is recommended that NMS user interfaces display and allow
input of MIB object names by their descriptor values, followed
by the index in dotted-decimal form (e.g., "ifType.7").
8.1.3.2. exists()
The exists() function is used to verify the existence of an SNMP MIB
object instance.
integer exists(string oid [, string contextName, NonLocalArgs])
'oid' is a string containing an ASCII dotted-decimal
representation of an object identifier (e.g.,
"1.3.6.1.2.1.1.1.0").
Waldbusser, et al. Standards Track [Page 34]
RFC 4011 Policy Based Management MIB March 2005
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform an SNMP operation on a system different
from that of 'this element'.
This function returns the value 1 if the SNMP instance exists
and 0 if it doesn't exist. Note that no actual SNMP PDU has to
be generated and parsed when the policy MIB agent resides on
the same system as the managed elements.
It is recommended that NMS user interfaces display and allow
input of MIB object names by their descriptor values, followed
by the index in dotted-decimal form (e.g., "ifType.7").
8.1.3.3. setVar()
The setVar() function is used to set a MIB object instance to a
certain value. The setVar() function is only valid in policyActions.
setVar(string oid, var value, integer type
[, string contextName, NonLocalArgs] )
'oid' is a string containing an ASCII dotted-decimal
representation of an object identifier (e.g.,
"1.3.6.1.2.1.1.1.0").
'value' is a string encoded in the format appropriate to the
'type' parameter. The agent will set the variable specified by
'oid' to the value specified by 'value'.
'type' will be the type of the 'value' parameter and will be
set to one of the values for DataType Constants.
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform an SNMP operation on a system different
from that of 'this element'. Note that no actual SNMP PDU has
to be generated and parsed when the policy MIB agent resides on
the same system as the managed elements.
Waldbusser, et al. Standards Track [Page 35]
RFC 4011 Policy Based Management MIB March 2005
It is an RTE if the set encounters any error.
It is recommended that NMS user interfaces display and allow
input of MIB object names by their descriptor values, followed
by the index in dotted-decimal form (e.g., "ifType.7").
8.1.3.4. searchColumn()
integer searchColumn(string columnoid, string &oid,
string pattern, integer mode
[, string contextName, NonLocalArgs])
searchColumn performs an SNMP walk on a portion of the MIB
searching for objects with values equal to the 'pattern'
parameter.
'columnoid' constrains the search to those variables that share
the same OID prefix (i.e., those that are beneath it in the OID
tree).
A getnext request will be sent requesting the object identifier
'oid'. If 'oid' is an empty string, the value of 'columnoid'
will be sent.
The value returned in each response packet will be transformed
to a string representation of the value of the returned
variable. The string representation of the value will be
formed by putting the value in the form dictated by the "Form
of SNMP Values" rules, and then by performing the ToString()
function on this value, forming 'SearchString'.
The 'mode' value controls what type of match to perform on this
'SearchString' value. There are 6 possibilities for mode:
Mode Search Action
ExactMatch Case sensitive exact match of 'pattern'
and 'SearchString'.
ExactCaseMatch Case insensitive exact match of 'pattern'
and 'SearchString'.
SubstringMatch Case sensitive substring match, finding
'pattern' in 'SearchString'.
SubstringCaseMatch Case insensitive substring match, finding
'pattern' in 'SearchString'.
RegexpMatch Case sensitive regular expression match,
searching 'SearchString' for the regular
expression given in 'pattern'.
Waldbusser, et al. Standards Track [Page 36]
RFC 4011 Policy Based Management MIB March 2005
RegexpCaseMatch Case insensitive regular expression match,
searching 'SearchString' for the regular
expression given in 'pattern'.
Constants for the values of 'mode' are defined in the
'Constants' section below.
searchColumn uses the POSIX extended regular expressions
defined in POSIX 1003.2.
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform SNMP operations on a system different
from that of 'this element'.
If a match is found, 'oid' is set to the OID of the matched
value, and 1 is returned. If the search traverses beyond
columnoid or returns an error without finding a match, zero is
returned, and 'oid' isn't modified.
To find the first match, the caller should set 'oid' to the
empty string. To find additional matches, subsequent calls to
searchColumn should have 'oid' set to the OID of the last
match, an operation that searchColumn performs automatically.
For example:
To find an ethernet interface
oid = "";
searchColumn("ifType", oid, "6", 0);
This sends a getnext request for ifType and continues to walk
the tree until a value matching 6 is found or a variable
returns that is not in the 'ifType' subtree.
To find the next ethernet interface, assuming that interface 3
was discovered to be the first:
oid = "ifType.3";
searchColumn("ifType", oid, "6", 0);
Waldbusser, et al. Standards Track [Page 37]
RFC 4011 Policy Based Management MIB March 2005
In a loop to determine all the ethernet interfaces, this looks
as follows:
oid = "";
while(searchColumn("ifType", oid, "6", 0)){
/* Do something with oid */
}
Note that in the preceding examples, "ifType" is used as a
notational convenience, and the actual code downloaded to the
policy MIB agent must use the string "1.3.6.1.2.1.2.2.1.3" as
there may be no MIB compiler (or MIB file) available on the
policy MIB agent.
Note that if the value of 'columnoid' is too short and thus
references too much of the object identifier tree (e.g.,
"1.3.6"), 'columnoid' could end up searching a huge number of
variables (if the value was "1.3.6", it would search ALL
variables on the agent). It is the responsibility of the
caller to make sure that 'columnoid' is set appropriately.
8.1.3.5. setRowStatus()
integer setRowStatus(string oid, integer maxTries
[, integer freeOnException , integer seed
, string contextName, NonLocalArgs])
setRowStatus is used to automate the process of finding an
unused row in a read-create table that uses RowStatus whose
index contains an arbitrary integer component for uniqueness.
'oid' is a string containing an ASCII dotted-decimal
representation of an object identifier, with one of the subids
replaced with a '*' character (e.g.,
"1.3.6.1.3.1.99.1.2.1.9.*"). 'oid' must reference an
'instance' of the RowStatus object, and the '*' must replace
any integer index item that may be set to some random value.
setRowStatus will come up with a number for the selected index
item and will attempt to create the instance with the
createAndWait state. If the attempt fails, it will retry with
a different random index value. It will attempt this no more
than 'maxTries' times.
If the optional 'freeOnException' argument is present and equal
to 1, the agent will free this row by setting RowStatus to
'destroy' if, later in the same script invocation, this script
Waldbusser, et al. Standards Track [Page 38]
RFC 4011 Policy Based Management MIB March 2005
dies with a run-time exception or by a call to fail(). Note
that this does not apply to exceptions experienced in
subsequent invocations of the script.
If the optional 'seed' argument is present, the initial index
will be set to 'seed'. Otherwise it will be random. 'seed'
may not be present if the 'freeOnException' argument is not
present.
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform an SNMP operation on a system different
from that of 'this element'.
setRowStatus returns the successful integer value for the
index. If it is unsuccessful after 'maxTries', or if zero or
more than one '*' is in OID, -1 will be returned.
The createRow function (below) can also be used when adding
rows to tables. Although createRow has more functionality,
setRowStatus may be preferable in certain situations (for
example, to have the opportunity to inspect default values
created by the agent).
8.1.3.6. createRow()
integer createRow(integer reqPDU, integer reqNumVarbinds,
integer statusColumn, integer maxTries,
integer indexRange,
integer &respPDU, integer &respNumVarbinds,
integer &index
[, integer freeOnException, string contextName,
NonLocalArgs])
createRow is used to automate the process of creating a row in
a read-create table whose index contains an arbitrary integer
component for uniqueness. In particular, it encapsulates the
algorithm behind either the createAndWait or createAndGo
mechanism and the algorithm for finding an unused row in the
table. createRow is not useful for creating rows in tables
whose indexes don't contain an arbitrary integer component.
createRow will perform the operation by sending 'reqPDU' and
returning the results in 'respPDU'. Both 'reqPDU' and
Waldbusser, et al. Standards Track [Page 39]
RFC 4011 Policy Based Management MIB March 2005
'respPDU' must previously have been allocated with newPDU.
'reqPDU' and 'respPDU' may both contain the same PDU handle, in
which case the 'reqPDU' is sent and then replaced with the
contents of the received PDU.
'reqNumVarbinds' is an integer greater than zero that specifies
which varbinds in the PDU will be used in this operation. The
first 'reqNumVarbinds' in the PDU are used. Each such varbind
must be of a special form in which the object name must have
one of its subids replaced with a '*' character (e.g.,
"1.3.6.1.3.1.99.1.2.1.9.*"). The subid selected to be replaced
will be an integer index item that may be set to some random
value. The same subid should be selected in each varbind in
the PDU.
'respNumVarbinds' will be modified to contain the number of
varbinds received in the last response PDU.
'statusColumn' identifies which varbind in 'pdu' should be
treated as the RowStatus column, where 0 identifies the 1st
varbind.
createRow will come up with a random integer index value and
will substitute that value in place of the '*' subid in each
varbind. It will then set the value of the RowStatus column to
select the 'createAndGo' mechanism and execute the set. If the
attempt fails due to the unavailability of the 'createAndGo'
mechanism, it will retry with the 'createAndWait' mechanism
selected. If the attempt fails because the chosen index value
is already in use, the operation will be retried with a
different random index value. It will continue to retry
different index values until it succeeds, until it has made
'maxTries' attempts, or until it encounters an error. The
value of 'maxTries' should be chosen to be high enough to
minimize the chance that as the table fills up an attempt to
create a new entry will 'collide' too often and fail.
All random index values must be between 1 and 'indexRange',
inclusive. This is so that values are not attempted for an
index that fall outside of that index's restricted range (e.g.,
1..65535).
If the optional 'freeOnException' argument is present and equal
to 1, the agent will free this row by setting RowStatus to
'destroy' if, later in the same script invocation, this script
dies with a run-time exception or by a call to fail(). Note
that this does not apply to exceptions experienced in
subsequent invocations of the script.
Waldbusser, et al. Standards Track [Page 40]
RFC 4011 Policy Based Management MIB March 2005
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
The optional 'NonLocalArgs' provide addressing and security
information to perform an SNMP operation on a system different
from that of 'this element'.
Note that no actual SNMP PDU has to be generated and parsed
when the policy MIB agent resides on the same system as the
managed elements. If no PDU is generated, the agent must
correctly simulate the behavior of the SNMP Response PDU,
particularly in case of an error.
This function returns zero unless an error occurs, in which
case it returns the proper SNMP Error Constant. If an error
occurred, respPDU will contain the last response PDU as
received from the agent unless no response PDU was received, in
which case respNumVarbinds will be 0. In any event, readError
may be called on the PDU to determine error information for the
transaction.
The 'index' parameter returns the chosen index. If successful,
'index' will be set to the successful integer index. If no
SNMP error occurs but the operation does not succeed due to the
following reasons, 'index' will be set to -1:
1) Unsuccessful after 'maxTries'.
2) An object name had no '*' in it.
3) An object name had more than one '*' in it.
For example, createRow() might be used as follows:
var index, pdu = newPDU(), nVars = 0;
writeVar(pdu, nVars++, "hlHostControlDataSource.*",
"ifIndex." + ev(0), Oid);
writeVar(pdu, nVars++, "hlHostControlNlMaxDesiredEntries.*",
1000, Integer);
writeVar(pdu, nVars++, "hlHostControlAlMaxDesiredEntries.*",
1000, Integer);
writeVar(pdu, nVars++, "hlHostControlOwner.*", "policy",
String);
writeVar(pdu, nVars++, "hlHostControlStatus.*", "active(1)",
Integer);
if (createRow(pdu, nVars, 4, 20, 65535,
pdu, nVars, index) != 0
Waldbusser, et al. Standards Track [Page 41]
RFC 4011 Policy Based Management MIB March 2005
|| index == -1)
return;
// index now contains index of new row
8.1.3.7. counterRate()
When a policy wishes to make a decision based on the rate of a
counter, it faces a couple of problems:
1. It may have to run every X minutes but have to make decisions on
rates calculated over at least Y minutes, where Y > X. This would
require the complexity of managing a queue of old counter values.
2. The policy script has no control over exactly when it will run.
The counterRate() function is designed to surmount these problems
easily.
integer counterRate(string oid, integer minInterval
[, integer 64bit,
string discOid, integer discMethod,
string contextName, NonLocalArgs])
'counterRate' retrieves the variable specified by oid once per
invocation. It keeps track of timestamped values retrieved on
previous invocations by this execution context so that it can
calculate a rate over a period longer than that since the last
invocation.
'oid' is the object identifier of the counter value that will
be retrieved. The most recent previously saved value of the
same object identifier that is at least 'minInterval' seconds
old will be subtracted from the newly retrieved value, yielding
a delta. If 'minInterval' is zero, this delta will be
returned. Otherwise, this delta will be divided by the number
of seconds elapsed between the two retrievals, and the
integer-valued result will be returned (rounding down when
necessary).
If there was no previously saved retrieval older than
'minInterval' seconds, then -1 will be returned. It is an RTE
if the query returns noSuchName, noSuchInstance, or
noSuchObject or an object that is not of type Counter32 or
Counter64.
Waldbusser, et al. Standards Track [Page 42]
RFC 4011 Policy Based Management MIB March 2005
The delta calculation will allow for 32-bit counter semantics
if it encounters rollover between the two retrievals, unless
the optional argument '64bit' is present and equal to 1, in
which case it will allow for 64-bit counter semantics.
'discOid' and 'discMethod' may only be present together.
'discOid' contains an object identifier of a discontinuity
indicator value that will be retrieved simultaneously with each
counter value:
1. If 'discMethod' is equal to 1 and the discontinuity
indicator is less than the last one retrieved, then a
discontinuity is indicated.
2. If 'discMethod' is equal to 2 and the discontinuity
indicated is different from the last one retrieved, then
a discontinuity is indicated.
If this value indicates a discontinuity, this counter value
(and its timestamp) will be stored, but all previously stored
counter values will be invalidated and -1 will be returned.
The implementation will have to store a number of timestamped
counter values. The implementation must keep all values that
are newer than minInterval seconds, plus the newest value that
is older than minInterval seconds. Other than this one value
that is older than minInterval seconds, the implementation
should discard any older values.
For example:
Policy that executes every 60 seconds:
rate = counterRate("ifInOctets.$*", 300);
if (rate > 1000000)
...
Another example, with a discontinuity indicator:
Policy that executes every 60 seconds:
rate = counterRate("ifInOctets.$*", 300, 0,
"sysUpTime.0", 1);
if (rate > 1000000)
...
Another example, with zero minInterval:
Policy that executes every 60 seconds:
delta = counterRate("ifInErrors.$*", 0);
if (delta > 100)
...
Waldbusser, et al. Standards Track [Page 43]
RFC 4011 Policy Based Management MIB March 2005
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
8.1.4. General SNMP Functions
It is desirable that a general SNMP interface have the ability to
perform SNMP operations on multiple variables at once and that it
allow multiple varbind lists to exist at once. The newPdu, readVar,
and writeVar functions exist to provide these facilities in a
language without pointers, arrays, and memory allocators.
newPDU is called to allocate a PDU and return an integer handle to
it. As PDUs are automatically freed when the script exits and can be
reused during execution, there is no freePDU().
readVar and writeVar access a variable length varbind list for a PDU.
The PDU handle and the index of the variable within that PDU are
specified in every readVar and writeVar operation. Once a PDU has
been fully specified by one or more calls to writeVar, it is passed
to snmpSend (by referencing the PDU handle) and the number of
varbinds to be included in the operation. When a response is
returned, the contents of the response are returned in another PDU
and may be read by one or more calls to readVar. Error information
may be read from the PDU with the readError function. Because
GetBulk PDUs send additional information in the SNMP header, the
writeBulkParameters function is provided to configure these
parameters.
Varbinds in this data store are created automatically whenever they
are written by any writeVar or snmpSend operation.
For example:
var pdu = newPDU();
var nVars = 0, oid, type, value;
writeVar(pdu, nVars++, "sysDescr.0", "", Null);
writeVar(pdu, nVars++, "sysOID.0", "", Null);
writeVar(pdu, nVars++, "ifNumber.0", "", Null);
if (snmpSend(pdu, nVars, Get, pdu, nVars))
return;
readVar(pdu, 0, oid, value, type);
readVar(pdu, 1, oid, value, type);
readVar(pdu, 2, oid, value, type);
...
Waldbusser, et al. Standards Track [Page 44]
RFC 4011 Policy Based Management MIB March 2005
or,
var pdu = newPDU();
var nVars = 0, oid1, oid2;
writeVar(pdu, nVars++, "ifIndex", "", Null);
writeVar(pdu, nVars++, "ifType", "", Null);
while(!done){
if (snmpSend(pdu, nVars, Getnext, pdu, nVars))
continue;
readVar(pdu, 0, oid1, value, type);
readVar(pdu, 1, oid2, value, type);
/* leave OIDs alone, now PDU #0 is set up for next step
in table walk. */
if (oidncmp(oid1, "ifIndex", oidlen("ifIndex")))
done = 0;
...
}
Note that in the preceding examples, descriptors such as ifType and
sysDescr are used in object identifiers solely as a notational
convenience. The actual code downloaded to the policy MIB agent must
use a dotted decimal notation only, as there may be no MIB compiler
(or MIB file) available on the policy MIB agent.
To conform to this specification, implementations must allow each
policy script invocation to allocate at least 5 PDUs with at least 64
varbinds per list. It is suggested that implementations limit the
total number of PDUs per invocation to protect other script
invocations from a malfunctioning script (e.g., a script that calls
newPDU() in a loop).
8.1.4.1. newPDU()
integer newPDU()
newPDU will allocate a new PDU and return a handle to the PDU.
If no PDU could be allocated, -1 will be returned. The PDU's
initial values of nonRepeaters and maxRepetitions will be zero.
8.1.4.2. writeVar()
writeVar(integer pdu, integer varBindIndex,
string oid, var value, integer type)
writeVar will store 'oid', 'value', and 'type' in the specified
varbind.
'pdu' is the handle to a PDU allocated by newPDU().
Waldbusser, et al. Standards Track [Page 45]
RFC 4011 Policy Based Management MIB March 2005
'varBindIndex' is a non-negative integer that identifies the
varbind within the specified PDU modified by this call. The
first varbind is number 0.
'oid' is a string containing an ASCII dotted-decimal
representation of an object identifier (e.g.,
"1.3.6.1.2.1.1.1.0").
'value' is the value to be stored, of a type appropriate to the
'type' parameter.
'type' will be the type of the value parameter and will be set
to one of the values for DataType Constants.
It is an RTE if any of the parameters don't conform to the
rules above.
8.1.4.3. readVar()
readVar(integer pdu, integer varBindIndex, string &oid,
var &value, integer &type)
readVar will retrieve the oid, the value, and its type from the
specified varbind.
'pdu' is the handle to a PDU allocated by newPDU().
'varBindIndex' is a non-negative integer that identifies the
varbind within the specified PDU read by this call. The first
varbind is number 0.
The object identifier value of the referenced varbind will be
copied into the 'oid' parameter, formatted in an ASCII dotted-
decimal representation (e.g., "1.3.6.1.2.1.1.1.0").
'value' is the value retrieved, of a type appropriate to the
'type' parameter.
'type' is the type of the value parameter and will be set to
one of the values for DataType Constants.
It is an RTE if 'pdu' doesn't reference a valid PDU or
'varBindIndex' doesn't reference a valid varbind.
Waldbusser, et al. Standards Track [Page 46]
RFC 4011 Policy Based Management MIB March 2005
8.1.4.4. snmpSend()
integer snmpSend(integer reqPDU, integer reqNumVarbinds,
integer opcode,
integer &respPDU, integer &respNumVarbinds,
[, string contextName , NonLocalArgs] )
snmpSend will perform an SNMP operation by sending 'reqPDU' and
returning the results in 'respPDU'. Both 'reqPDU' and
'respPDU' must previously have been allocated with newPDU.
'reqPDU' and 'respPDU' may both contain the same PDU handle, in
which case the 'reqPDU' is sent and then replaced with the
contents of the received PDU. If the opcode specifies a Trap
or V2trap, 'respPDU' will not be modified.
'reqNumVarbinds' is an integer greater than zero that specifies
which varbinds in the PDU will be used in this operation. The
first 'reqNumVarbinds' in the PDU are used. 'respNumVarbinds'
will be modified to contain the number of varbinds received in
the response PDU, which, in the case of GetBulk or an error,
may be substantially different from reqNumVarbinds.
'opcode' is the type of SNMP operation to perform and must be
one of the values for SNMP Operation Constants listed in the
'Constants' section below.
The optional 'contextName' argument contains the SNMP context
on which to operate. If 'contextName' is not present, the
contextName of 'this element' will be used. If 'contextName'
is the zero-length string, the default context is used.
Note that no actual SNMP PDU has to be generated and parsed
when the policy MIB agent resides on the same system as the
managed elements. If no PDU is generated, the agent must
correctly simulate the behavior of the SNMP Response PDU,
particularly in case of an error.
This function returns zero unless an error occurs, in which
case it returns the proper SNMP Error Constant. If an error
occurred, respPDU will contain the response PDU as received
from the agent, unless no response PDU was received, in which
case respNumVarbinds will be 0. In any event, readError may be
called on the PDU to determine error information for the
transaction.
If an SNMP Version 1 trap is requested (the opcode is Trap(4)),
then SNMP Version 2 trap parameters are supplied and converted
according to the rules of RFC 3584 [8], section 3.2. The first
Waldbusser, et al. Standards Track [Page 47]
RFC 4011 Policy Based Management MIB March 2005
variable binding must be sysUpTime.0, and the second must be
snmpTrapOID.0, as per RFC 3416 [7], section 4.2.6. Subsequent
variable bindings are copied to the SNMP Version 1 trap PDU in
the usual fashion.
8.1.4.5. readError()
readError(integer pdu, integer numVarbinds, integer &errorStatus,
integer &errorIndex, integer &hasException)
Returns the error information in a PDU.
'errorStatus' contains the error-status field from the response
PDU or a local error constant if the error was generated
locally. If no error was experienced or no PDU was ever copied
into this PDU, this value will be 0.
'errorIndex' contains the error-index field from the response
PDU. If no PDU was ever copied into this PDU, this value will
be 0.
'hasException' will be 1 if any of the first 'numVarbinds'
varbinds in the PDU contain an exception (Nosuchobject,
Nosuchinstance, Endofmibview); otherwise it will be 0.
It is an RTE if 'pdu' does not reference a valid PDU or if
'numVarbinds' references varbinds that aren't valid.
8.1.4.6. writeBulkParameters()
writeBulkParameters(integer pdu, integer nonRepeaters,
integer maxRepetitions)
Modifies the parameters in a PDU in any subsequent GetBulk
operation sent by the PDU. 'nonRepeaters' will be copied into
the PDU's non-repeaters field, and 'maxRepetitions' into the
max-repetitions field.
This function may be called before or after writeVar is called
to add varbinds to the PDU, but it must be called before the
PDU is sent; otherwise, it will have no effect. A new PDU is
initialized with nonRepeaters set to zero and maxRepetitions
set to zero. If a Bulk PDU is sent before writeBulkParameters
is called, these default values will be used. If
writeBulkParameters is called to modify a PDU, it is acceptable
if this PDU is later sent as a type other than bulk. The
writeBulkParameters call will only affect subsequent sends of
Bulk PDUs. If a PDU is used to receive the contents of a
Waldbusser, et al. Standards Track [Page 48]
RFC 4011 Policy Based Management MIB March 2005
response, the values of nonRepeaters and maxRepetitions are
never modified.
8.1.5. Constants for SNMP Library Functions
The following constants are defined for use with all SNMP Library
Functions. Policy code will be executed in an environment where the
following constants are declared. (Note that the constant
declarations below will not be visible in the policyCondition or
policyAction code.) These constants are reserved words and cannot be
used for any variable or function name.
Although these declarations are expressed here as C 'const's, the
'const' construct itself is not available to be used in policy code.
// Datatype Constants
// From RFC 2578 [2]
const integer Integer = 2;
const integer Integer32 = 2;
const integer String = 4;
const integer Bits = 4;
const integer Null = 5;
const integer Oid = 6;
const integer IpAddress = 64;
const integer Counter32 = 65;
const integer Gauge32 = 66;
const integer Unsigned32 = 66;
const integer TimeTicks = 67;
const integer Opaque = 68;
const integer Counter64 = 70;
// SNMP Exceptions from RFC 3416 [7]
const integer NoSuchObject = 128;
const integer NoSuchInstance = 129;
const integer EndOfMibView = 130;
// SNMP Error Constants from RFC 3416 [7]
const integer NoError = 0;
const integer TooBig = 1;
const integer NoSuchName = 2;
const integer BadValue = 3;
const integer ReadOnly = 4;
const integer GenErr = 5;
const integer NoAccess = 6;
const integer WrongType = 7;
const integer WrongLength = 8;
const integer WrongEncoding = 9;
Waldbusser, et al. Standards Track [Page 49]
RFC 4011 Policy Based Management MIB March 2005
const integer WrongValue = 10;
const integer NoCreation = 11;
const integer InconsistentValue = 12;
const integer ResourceUnavailable = 13;
const integer CommitFailed = 14;
const integer UndoFailed = 15;
const integer AuthorizationError = 16;
const integer NotWritable = 17;
const integer InconsistentName = 18;
// "Local" Errors
// These are also possible choices for errorStatus returns
// For example: unknown PDU, maxVarbinds is bigger than number
// written with writeVar, unknown opcode, etc.
const integer BadParameter = 1000;
// Request would have created a PDU larger than local limitations
const integer TooLong = 1001;
// A response to the request was received but errors were encountered
// when parsing it.
const integer ParseError = 1002;
// Local system has complained of an authentication failure
const integer AuthFailure = 1003;
// No valid response was received in a timely fashion
const integer TimedOut = 1004;
// General local failure including lack of resources
const integer GeneralFailure = 1005;
// SNMP Operation Constants from RFC 3416 [7]
const integer Get = 0;
const integer Getnext = 1;
const integer Set = 3;
const integer Trap = 4;
const integer Getbulk = 5;
const integer Inform = 6;
const integer V2trap = 7;
// Constants from RFC 3411 [1] for SnmpMessageProcessingModel
const integer SNMPv1 = 0;
const integer SNMPv2c = 1;
const integer SNMPv3 = 3;
Waldbusser, et al. Standards Track [Page 50]
RFC 4011 Policy Based Management MIB March 2005
// Constants from RFC 3411 [1] for SnmpSecurityModel
const integer SNMPv1 = 1;
const integer SNMPv2c = 2;
const integer USM = 3;
// SnmpSecurityLevel Constants from RFC 3411 [1]
const integer NoAuthNoPriv = 1;
const integer AuthNoPriv = 2;
const integer AuthPriv = 3;
// Constants for use with searchColumn
const integer ExactMatch = 0;
const integer ExactCaseMatch = 1;
const integer SubstringMatch = 2;
const integer SubstringCaseMatch = 3;
const integer RegexpMatch = 4;
const integer RegexpCaseMatch = 5;
8.2. Policy Library Functions
Policy Library Functions provide access to information specifically
related to the execution of policies.
8.2.1. elementName()
The elementName() function is used to determine what the current
element is and can be used to provide information about the type of
element and how it is indexed.
string elementName()
elementName returns a string containing an ASCII dotted-decimal
representation of an object identifier (e.g.,
1.3.6.1.2.1.1.1.0). This object identifier identifies an
instance of a MIB object that is an attribute of 'this
element'.
8.2.2. elementAddress()
elementAddress(&tDomain, &tAddress)
elementAddress finds a domain/address pair that can be used to
access 'this element' and returns the values in 'tDomain' and
'tAddress'.
Waldbusser, et al. Standards Track [Page 51]
RFC 4011 Policy Based Management MIB March 2005
8.2.3. elementContext()
string elementContext()
elementContext() returns a string containing the SNMP
contextName of 'this element'.
8.2.4. ec()
The ec() (element count) and ev() (element value) functions provide
convenient access to the components of the index for 'this element'.
Typical uses will be in creating the index to other, r |