Description of SNMP NED.
NSO can use SNMP to configure a managed device, under certain circumstances. SNMP in general is not suitable for configuration, and it is important to understand why:
In SNMP, the size of a SET request, which is used to write to a device, is limited to what fits into one UDP packet. This means that a large configuration change must be split into many packets. Each such packet contains some parameters to set, and each such packet is applied on its own by the device. If one SET request out of many fails, there is no abort command to undo the already applied changes, meaning that rollback is very difficult.
The data modeling language used in SNMP, SMIv2, does not distinguish between configuration objects and other writable objects. This means that it is not possible to retrieve only the configuration from a device without explicit, exact knowledge of all objects in all MIBs supported by the device.
SNMP supports only two basic operations, read and write. There is no protocol support for creating or deleting data. Such operations must be modeled in the MIBs, explicitly.
SMIv2 has limited support for semantic constraints in the data model. This means that it is difficult to know if a certain configuration will apply cleanly on a device. If it doesn't, rollback is tricky, as explained above.
Because of all of the above, ordering of SET requests becomes very important. If a device refuses to create some object A before another B, an SNMP manager must make sure to create B before creating A. It is also common that objects cannot be modified without first making them disabled or inactive. There is no standard way to do this, so again, different data models do this in different ways.
Despite all this, if a device can be configured over SNMP, NSO can use its built-in multilingual SNMP manager to communicate with the device. However, to solve the problems mentioned above, the MIBs supported by the device need to be carefully annotated with some additional information that instructs NSO on how to write configuration data to the device. This additional information is described in detail below.
To add a device, the following steps need to be followed. They are described in more detail in the following sections.
(See the Makefile snmp-ned/basic/packages/ex-snmp-ned/src/Makefile
, for an example of the below description.) Make sure that you have all MIBs available, including import dependencies, and that they contain no errors.
The ncsc --ncs-compile-mib-bundle
compiler is used to compile MIBs and MIB annotation files into NSO load files. Assuming a directory with input MIB files (and optional MIB annotation files) exist, the following command compiles all the MIBs in device-models
and writes the output to ncs-device-model-dir
.
The compilation steps performed by the ncsc --ncs-compile-mib-bundle
are elaborated below:
Transform the MIBs into YANG according to the IETF standardized mapping (https://www.ietf.org/rfc/rfc6643.txt). The IETF-defined mapping makes all MIB objects read-only over NETCONF.
Generate YANG deviations from the MIB, this makes SMIv2 read-write
objects YANG config true
as a YANG deviation.
Include the optional MIB annotations.
Merge the read-only YANG from step 1 with the read-write deviation from step 2.
Compile the merged YANG files into NSO load format.
These steps are illustrated in the figure below:
Finally make sure that the NSO configuration file points to the correct device model directory:
Each managed device is configured with a name, IP address, and port (161 by default), and the SNMP version to use (v1, v2c, or v3).
To minimize the necessary configuration, the authentication group concept (see Authentication Groups) is used also for SNMP. A configured managed device of the type snmp
refers to an SNMP authgroup. An SNMP authgroup contains community strings for SNMP v1 and v2c and USM parameters for SNMP v3.
In the example above, when NSO needs to speak to the device r3
, it sees that the device is of type snmp
, and that SNMP v3 should be used with authentication parameters from the SNMP authgroup my-authgroup
. This authgroup maps the local NSO user admin
to the USM user admin
, with explicit remote passwords given. These passwords will be localized for each SNMP engine that NSO communicates with. While the passwords above are shown encrypted, when you enter them in the CLI you write them in clear text. Note also that the remote engine ID is not configured; NSO performs a discovery process to find it automatically.
No NSO user other than admin
is mapped by the authgroup my-authgroup
for SNMP v3.
With SNMP, there is no standardized, generic way for an SNMP manager to learn which MIBs an SNMP agent implements. By default, NSO assumes that an SNMP device implements all MIBs known to NSO, i.e., all MIBs that have been compiled with the ncsc --ncs-compile-mib-bundle
command. This works just fine if all SNMP devices NSO manages are of the same type, and implement the same set of MIBs. But if NSO is configured to manage many different SNMP devices, some other mechanism is needed.
In NSO, this problem is solved by using MIB groups. MIB group is a named collection of MIB module names. A managed SNMP device can refer to one or more MIB groups. For example, below two MIB groups are defined:
The wildcard *
can be used only at the end of a string; it is thus used to define a prefix of the MIB module name. So the string SNMP*
matches all loaded standard SNMP modules, such as SNMPv2-MIB, SNMP-TARGET-MIB, etc.
An SNMP device can then be configured to refer to one or more of the MIB groups:
Most annotations for MIB objects are used to instruct NSO on how to split a large transaction into suitable SNMP SET requests. This step is not necessary for a default integration. But when for example ordering dependencies in the MIB is discovered it is better to add this as annotations and let NSO handle the ordering rather than leaving it to the CLI user or Java programmer.
In some cases, NSO can automatically understand when rows in a table must be created or deleted before rows in some other table. Specifically, NSO understands that if table B has an INDEX object in table A (i.e., B sparsely augments A), then rows in table B must be created after rows in table B, and vice versa for deletions. NSO also understands that if table B AUGMENTS table A, then a row in table A must be created before any column in B is modified.
However, in some MIBs, table dependencies cannot be detected automatically. In this case, these tables must be annotated with a sort-priority
. By default, all rows have sort-priority 0. If table A has a lower sort priority than table B, then rows in table A are created before rows in table B.
In some tables, existing rows cannot be modified unless the row is inactivated. Once inactive, the row can be modified and then activated again. Unfortunately, there is no formal way to declare this is SMIv2, so these tables must be annotated with two statements; ned-set-before-row-modification
and ned-modification-dependent
. The former is used to instruct NSO which column and which value is used to inactivate a row, and the latter is used on each column that requires the row to be inactivated before modification. ned-modification-dependent
can be used in the same table as ned-set-before-row-modification
, or in a table that augments or sparsely augments the table with ned-set-before-row-modification
.
By default, NSO treats a writable SMIv2 object as configuration, except if the object is of type RowStatus. Any writable object that does not represent configuration must be listed in a MIB annotation file when the MIB is compiled, with the "operational" modifier.
When NSO retrieves data from an SNMP device, e.g., when doing a sync from-device
, it uses the GET-NEXT request to scan the table for available rows. When doing the GET-NEXT, NSO must ask for an accessible column. If the row has a column of type RowStatus, NSO uses this column. Otherwise, if one of the INDEX objects is accessible, it uses this object. Otherwise, if the table has been annotated with ned-accessible-column
, this column is used. And, as a last resort, NSO does not indicate any column in the first GET-NEXT request, and uses the column returned from the device in subsequent requests. If the table has "holes" for this column, i.e., the column is not instantiated in all rows, NSO will not detect those rows.
NSO can automatically create and delete table rows for tables that use the RowStatus TEXTUAL-CONVENTION, defined in RFC 2580.
It is pretty common to mix configuration objects with non-configuration objects in MIBs. Specifically, it is quite common that rows are created automatically by the device, but then some columns in the row are treated as configuration data. In this case, the application programmer must tell NSO to sync from the device before attempting to modify the configuration columns, to let NSO learn which rows exist on the device.
Some SNMP agents require a certain order of row deletions and creations. By default, the SNMP NED sends all creates before deletes. The annotation ned-delete-before-create
can be used on a table entry to send row deletions before row creations, for that table.
Sometimes rows in some SNMP agents cannot be modified once created. Such rows can be marked with the annotation ned-recreate-when-modified
. This makes the SNMP NED to first delete the row, and then immediately recreate it with the new values.
A good starting point for understanding annotations is to look at the example in examples.ncs/snmp-ned
directory. The BASIC-CONFIG-MIB mib has a table where rows can be modified if the bscActAdminState
is set to locked. To have NSO do this automatically when modifying entries rather than leaving it to users an annotation file can be created. See the BASIC-CONFIG-MIB.miba
which contains the following:
This tells NSO that before modifying the bscActFlow
column set the bscActAdminState
to locked and restore the previous value after committing the set operation.
All MIB annotations for a particular MIB are written to a file with the file suffix .miba
. See mib_annotations(5) in manual pages for details.
Make sure that the MIB annotation file is put into the directory where all the MIB files are which is given as input to the ncsc --ncs-compile-mib-bundle
command
NSO can manage SNMP devices within transactions, a transaction can span Cisco devices, NETCONF devices, and SNMP devices. If a transaction fails NSO will generate the reverse operation to the SNMP device.
The basic features of the SNMP will be illustrated below by using the examples.ncs/snmp-ned
example. First, try to connect to all SNMP devices:
When NSO executes the connect request for SNMP devices it performs a get-next request with 1.1 as var-bind. When working with the SNMP NED it is helpful to turn on the NED tracing:
This creates a trace file named ned-devicename.trace
. The trace for the NCS connect
action looks like:
When looking at SNMP trace files it is useful to have the OBJECT-DESCRIPTOR rather than the OBJECT-IDENTIFIER. To do this, pipe the trace file to the smixlate
tool:
You can access the data in the SNMP systems directly (read-only and read-write objects):
NSO can synchronize all writable objects into CDB:
All the standard features of NSO with transactions and roll-backs will work with SNMP devices. The sequence below shows how to enable authentication traps for all devices as one transaction. If any device fails, NSO will automatically roll back the others. At the end of the CLI sequence a manual rollback is shown: