Table of Contents
The ConfD integrated SNMP agent provides an environment where SNMP and other agents such as NETCONF, Web UI, and CLI, coexist and use the same built-in database (CDB) for configuration storage and the same set of instrumentation functions for controlling managed objects (MOs). Simple bindings from SNMP MIB objects to YANG nodes is all that is needed to open up a configuration database to be accessed by an SNMP manager.
The advantage of having an integrated SNMP agent in ConfD is that configuration data can be accessed directly from the built-in database (CDB) or from user written managed objects without having to do the tedious work of writing a separate set of instrumentation functions just for SNMP. One set of common instrumentation functions is used for serving the NETCONF, CLI, Web UI, and SNMP agents.
confdc --mib2yang is used to make YANG models from MIBs. It also provides the necessary bindings from MIB objects to nodes in the YANG model.
To go the opposite way, from YANG to MIBs, see Section 17.3, “Generating MIBs from YANG”.
The ConfD SNMP agent application provides the following features:
An extensible SNMP agent that understands SNMPv1, SNMPv2c and SNMPv3.
A MIB compiler that understands SMIv1 and SMIv2.
Configuration data is specified in YANG models.
Common instrumentation functions for controlling managed objects (MO's) via NETCONF, CLI, Web UI, and SNMP agent.
The SNMP agent uses ConfD AAA datarules to determine access to data, as well as using the standard SNMP view based and user based access control mechanisms.
The following MIBs are builtin in the ConfD SNMP agent:
The following MIBs define the SMI language:
To set up an SNMP agent to manage objects in the MIB the following information must be provided:
MIB
YANG (.yang
or
.yin
) file.
Associations between objects in the MIB and nodes in the YANG module.
Instrumentation functions (not needed for config data if CDB is used)
The MIBs are typically already existing standard or proprietary enterprise MIBs, but they can also be generated from the YANG models.
The MIB compiler needs a mapping between the MIB object to nodes in the YANG module. This is done by adding YANG statements to the data model, that associate YANG nodes with objects in the MIB. The association statements can be written directly in the YANG module file, or in a separate YANG annotation file (see tailf_yang_extensions(5)).
The confdc compiler verifies that the types of the SNMP objects and the types in the YANG module are compatible.
There are three main use cases to consider when implementing a MIB with ConfD:
The MIB is given, and a YANG module is generated from the MIB.
The YANG modules and associations are generated with the confdc --mib2yang translator program. The generated YANG modules will in this case resemble the structure of the MIBs.
The MIB and YANG module are both given (or written manually).
In this case, MIB associations
should be written to bind MIB objects to the nodes in
the YANG data model. Statements tailf:snmp-name
,
tailf:snmp-oid
, etc. are added either directly in the
YANG module or in a separate annotation file (see tailf_yang_extensions(5)).
The YANG module is given (or written manually), and the MIB is generated from it.
The MIBs are generated using the confdc --emit-mib command.
The ConfD SNMP agent provides SNMP access to the data available through the ConfD management backplane. The same data can also be accessed via other protocols/applications such as NETCONF, Web UI, and CLI. This data can be stored in CDB, or made available by a data provider.
SNMP has certain features that are not meaningful to model in YANG. There are also some requirements on how the data is to be sorted in tables since SNMP operations require a strict lexicographical order of the elements in a table. Below is a listing of some of the SNMP specific behaviors and what needs to be done:
The RowStatus column in tables are handled by the SNMP agent and must not be part of the YANG model. Rows with a RowStatus column set to 'notReady' or 'notInService' are temporarily stored in the SNMP agent and will not show up in the database. Once activated they will be inserted into the database.
SNMP requires objects that are stored in tables to be
ordered in a strict lexicographical order. If we have a
list in a YANG module which is handled by an
instrumentation function, the
get_next()
callback function
(which must be provided by the user), must return the elements in
the same lexicographical order as SNMP expects. If the
order of the elements is not correct, then an SNMP manager will
not be able to correctly traverse the elements in a table.
If the list statement has a
tailf:secondary-index
with the name
snmp, the agent will iterate over the table
using this index. Thus,
the instrumentation code can reply with instances in SNMP
lexicographical order when the objects are retrieved over
SNMP, and a more natural sort order when the objects are
retrieved in the CLI and other northbound interfaces.
Tables with INDEX with dynamic length
must have a length byte as part of the index. If the
table index is specified as IMPLIED,
then the length byte is excluded from the index. The statement
tailf:sort-order
can be specified in
lists and secondary indexes in the YANG module, to control
whether index elements should be ordered with the length
byte included or not.
Enumerations must have the same enumerated values in YANG and in the MIB. Note that the symbolic string associated with the enum may be different in the YANG module and MIB.
SNMP v3 has support for contexts. The ConfD SNMP agent uses "" as the default context where all operations for this context are made towards the running database.
Scalar variables of TestAndIncr are automatically handled by the agent.
The following steps are needed to get a ConfD SNMP agent up and running:
Write a MIB module, generate one from a YANG module, or use an existing one.
Write a YANG module, generate one from a MIB module, or use an existing one.
Write associations that provide the mapping of MIB objects into YANG nodes.
Write instrumentation functions for nodes in the YANG module, or store data in CDB.
Compile the YANG module into an
.fxs
file.
Run the MIB together with the YANG
.fxs
file, and an optional mib
annotations file (.miba
, see
mib_annotations(5)), through
the MIB compiler to produce a
.bin
file.
Configure the agent
(confd.conf
and initial MIB
data). Specify which compiled MIBs are to be loaded
by the agent (.bin
files) in
confd.conf
.
The produced .fxs
file as well as the
.fxs
files for the built-in MIBs must be
found in the loadPath specified in
confd.conf
.
Start ConfD.
The basic objects in a MIB are scalar objects and table
objects. Each MIB object must be mapped to a node in a YANG
module. Scalar MIB objects must be mapped to YANG leafs with
matching types, so that the agent can translate the value
between the SNMP value and the internal value defined by the
YANG type. Tables in the MIB must be mapped to lists in YANG.
The mapping between the MIB objects and the YANG nodes is
specified in the YANG module (or annotation file for
the module) using tailf:snmp-name
and
tail:snmp-oid
statements.
tailf:snmp-name
specifies the symbolic name of a
MIB object, and tailf:snmp-oid
specifies the
corresponding OID.
Let us assume that we have the following MIB named SIMPLE-MIB containing a scalar and table:
-- a scalar numberOfHosts OBJECT-TYPE SYNTAX INTEGER (0..65535) MAX-ACCESS read-only STATUS current DESCRIPTION "Return the current number of hosts" ::= { simpleVariables 1 } -- a table hostTable OBJECT-TYPE SYNTAX SEQUENCE OF HostEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "The table of hosts." ::= { simpleTables 1 } hostEntry OBJECT-TYPE SYNTAX HostEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Information about a host." INDEX { hostName } ::= { hostTable 1 } HostEntry ::= SEQUENCE { hostName DisplayString, hostEnabled TruthValue, hostNumberOfServers Integer32, hostRowStatus RowStatus } hostName OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS not-accessible STATUS current DESCRIPTION "The unique index value of a row in this table." ::= { hostEntry 1 } hostEnabled OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-create STATUS current DESCRIPTION "A bool value saying if host is enabled or not." ::= { hostEntry 2 } hostNumberOfServers OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-only STATUS current DESCRIPTION "A read-only integer saying how many servers there currently are." ::= { hostEntry 3 } hostRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "The status of this conceptual row in the hostTable." ::= { hostEntry 4 }
An association must be written to bind the two SNMP objects (the scalar and the table) into YANG. Below is an example of a simple YANG module with SNMP statements that maps to SNMP objects in the MIB.
Example 17.1. Simple YANG module
module simple { namespace "http://tail-f.com/ns/simple"; prefix simple; import ietf-inet-types { prefix inet; } import tailf-common { prefix tailf; } typedef nameType { type string { length "min .. 255"; } } tailf:snmp-mib-module-name TAIL-F-TEST-MIB; container simpleObjects { leaf numberOfHosts { type uint16; mandatory true; tailf:snmp-name numberOfHosts; } container hosts { list host { key name; max-elements 64; tailf:sort-order snmp; tailf:snmp-name hostTable; tailf:snmp-row-status-column 4; leaf name { type nameType; } leaf enabled { type boolean; mandatory true; tailf:snmp-name hostEnabled; } leaf numberOfServers { type uint16; mandatory true; tailf:snmp-oid .3; } } } } }
In the code listing above there is one variable
numberOfHosts
mapped to the SNMP scalar
variable numberOfHosts
using the
tailf:snmp-name
statement. The
numberOfServers
object uses the alternative
notation with a tailf:snmp-oid
statement. Which
one to use is a matter of taste.
The list host is mapped
to the SNMP table hostTable using
tailf:snmp-name hostTable
. It would also be possible
to specify the tailf:snmp-oid
if preferred. Notice also
that for tables which support creation and deletion of rows
through a RowStatus column, the statement
tailf:snmp-row-status-column
can be given.
(This is not necessary if the model will be used with an existing MIB,
but it is necessary for
confdc --emit-mib
to
generate a writable table if the model is used for generating a new
MIB.) See Section 17.2.9, “The RowStatus column” for more details.
It is possible to map one YANG node to multiple SNMP objects. For example, if an SNMP table augments another table, both these tables can be implemented in a single YANG list, where some leafs are mapped to the base table, and some are mapped to the augmented table.
The following example illustrates the idea. The single YANG list 'interface' is mapped to the MIB tables ifTable, ifXTable, and ipv4InterfaceTable:
list interface { key index; tailf:snmp-name 'ifTable'; // primary table tailf:snmp-name 'ifXTable'; tailf:snmp-name 'IP-MIB:ipv4InterfaceTable'; leaf index { type int32; } leaf description { type string; tailf:snmp-name 'ifDescr'; // mapped to primary table } leaf name { type string; tailf:snmp-name 'ifXTable:ifName'; } leaf ipv4-enable { type boolean; tailf:snmp-name 'IP-MIB:ipv4InterfaceTable:ipv4InterfaceEnableStatus'; } ... }
When the SNMP agent receives a request to GET an object, it will lookup the object in the compiled MIB, and through the association information find the corresponding YANG node. Next, it will retrieve the correct instances value from a data provider. This value will be encoded according to the type in the YANG module. The SNMP agent translates this value to the corresponding SNMP value, and sends the reply to the manager. For this translation to work, the types in the YANG module and MIB must match.
The following table shows how SMI data types are mapped to YANG datatypes. This mapping is used internally in the agent in runtime, and also by the confdc --mib2yang program when a YANG module is generated from a MIB. See the confd_types(3) man page for details about the XSD and confd types.
Table 17.1. SMI mapping to YANG types
SMI | YANG | C value type | XML example |
OBJECT IDENTIFIER | yang:object-identifier | C_OID | 1.3.6.1.2.1 |
IpAddress | inet:ipv4-address | C_IPV4 | 192.168.2.3 |
Unsigned32 | uint32 | C_UINT32 | |
Gauge32 | yang:gauge32 | C_UINT32 | |
Counter32 | yang:counter32 | C_UINT32 | |
TimeTicks | yang:time-ticks | C_UINT32 | |
Integer32 | int32 | C_INT32 | |
Counter64 | yang:counter64 | C_UINT64 | |
INTEGER { enums... } | enumeration | C_ENUMHASH | udp |
INTEGER | int32 | C_INT32 | 42 |
DisplayString | string | C_BUF/C_STR | Hello world! |
OCTET STRING (with DISPLAY-HINT on the form "Na" or "Nt") | string | C_BUF/C_STR | Hello world! |
OCTET STRING (binary), Opaque | tailf:hex-list | C_BINARY | 4f:12:ff |
IPV6-TC::Ipv6Address | inet:ipv6-address | C_IPV6 | ::213.180.94.158 |
SNMPv2-TC::DateAndTime | yang:date-and-time | C_DATETIME | 2006-08-17T16:30:53+02:00 |
SNMPv2-TC::TruthValue | boolean, enumeration (1), empty | C_BOOL, C_ENUMHASH | true |
SNMPv2-TC::PhysAddress | yang:phys-address | C_BINARY | |
SNMPv2-TC::MacAddress | yang:mac-address | C_BINARY | |
SNMPv2-TC::TimeStamp | yang:timestamp | C_UINT32 | |
SNMPv2-TC::TimeInterval | int32 | C_INT32 | |
SNMPv2-TC::TAddress | tailf:octet-list | C_BINARY |
(1) SNMPv2-TC::TruthValue is a bit special. At runtime, the agent can map it either to a normal enumeration (which is how it is defined in SNMPv2-TC), to a boolean, to an empty leaf, or to a presence-container. When confd --mib2yang is used to create the YANG module from a MIB, it uses the enumeration mapping. This is also the recommended mapping. If a boolean is used, it cannot be part of the INDEX in a table.
The following table shows how YANG data types are mapped to SMI datatypes. This mapping is used internally in the agent in runtime, and also by the confdc --emit-mib program when a MIB is generated from a YANG module.
If the association between the MIB and YANG module is written manually, the type mappings in this table must be used.
Some of the more complex YANG types that cannot be easily translated to native SMI types are translated into strings of the type "ConfdString" In this case, the human-readable string value is passed over SNMP. These types cannot be used as INDEX in SNMP tables.
See the confd_types(3) man page for details about the XSD and confd types.
Table 17.2. YANG mapping to SMI types
YANG | SMI | C value type | Use as INDEX |
int32 | Integer32 | C_INT32 | yes |
int16 | Integer32 (-32768..32767) | C_INT16 | yes |
int8 | Integer32 (-128..127) | C_INT8 | yes |
uint64 | ConfdString | C_UINT64 | yes |
uint32 | Unsigned32 | C_UINT32 | yes |
uint16 | Unsigned32 (0..65535) | C_UINT16 | yes |
uint8 | Unsigned32 (0..255) | C_UINT8 | yes |
boolean | SNMPv2-TC::TruthValue | C_BOOL | no |
enumeration | INTEGER { enums... } | C_ENUMHASH | yes |
string | OCTET STRING | C_BUF / C_STR | yes |
decimal64 | ConfdString | C_DECIMAL64 | no |
int64 | ConfdString | C_INT64 | no |
union | ConfdString | depending on type | no |
binary | OCTET STRING | C_BINARY | no |
empty | SNMPV2-TC::TruthValue | C_BOOL | no |
identity | not supported | n/a | n/a |
yang:date-and-time | SNMPv2-TC::DateAndTime | C_DATETIME | yes |
yang:counter32 | Counter32 | C_UINT32 | yes |
yang:counter64 | Counter64 | C_UINT64 | yes |
yang:gauge32 | Gauge32 | C_UINT32 | yes |
yang:object-identifier | OBJECT IDENTIFIER | C_OID | yes |
xs:float, xs:double, xs:decimal | ConfdString | C_DOUBLE | no |
inet:ipv4-address | IpAddress | C_IPV4 | yes |
inet:ipv6-address | IPV6-TC::Ipv6Address | C_IPV6 | yes |
inet:ip-address | OCTET STRING (SIZE (4|16)) | C_IPV4 | C_IPV6 | yes |
inet:host | ConfdString | C_BUF / C_STR | no |
inet:domain-name | ConfdString | C_BUF / C_STR | no |
inet:port-number | Unsigned32 (0..65535) | C_UINT16 | yes |
inet:ipv4-prefix | OCTET STRING (SIZE (5)) | C_IPV4PREFIX | yes |
inet:ipv6-prefix | OCTET STRING (SIZE (17)) | C_IPV6PREFIX | yes |
inet:ip-prefix | OCTET STRING (SIZE (5|17)) | C_IPV4PREFIX | C_IPV6PREFIX | yes |
tailf:size | OCTET STRING | C_BUF / C_STR | no |
tailf:octet-list, tailf:hex-list | OCTET STRING | C_BINARY | yes |
xs:date | ConfdString | C_DATE | no |
xs:time | ConfdString | C_TIME | no |
xs:duration | ConfdString | C_DURATION | no |
xs:hexBinary | OCTET STRING | C_BINARY | no |
xs:QName | not supported | n/a | n/a |
A YANG presence container and a leaf of type empty can be mapped to a SMI scalar or columnar object of type SNMPv2-TC::TruthValue. If the empty leaf or presence container exists, the SMI object is 'true', and if it does not exist, but its parent exists, it has the value 'false'. Setting the SMI object to 'true' creates the leaf or presence container, and setting it to 'false' deletes it.
The
confdc --mib2yang
is used to
generate a YANG (.yang
) files from
MIBs. The element structure in the resulting
YANG module will resemble the structure of the objects in the
MIB.
If the MIB IMPORTs other MIBs, these MIBs must be available
(as .mib files) to the compiler when a YANG module is
generated. By default, all MIBs in the current directory and
all builtin MIBs (see Section 17.1, “Introduction to the ConfD SNMP Agent”)
are available. Since
the compiler uses the tool smidump to
perform the conversion to YANG, the environment variable
SMIPATH
can be set to a colon-separated
list of directories to search for MIB files.
Example 17.2. Generating and compiling YANG from MIB
$ confdc --mib2yang -o SIMPLE-MIB.yang SIMPLE-MIB.mib $ confdc -c -o SIMPLE-MIB.fxs SIMPLE-MIB.yang
Below is the generated YANG module. The structure of the YANG module resembles the structure of the SIMPLE-MIB it was generated from.
Example 17.3. The YANG file generated by confdc --mib2yang
module SIMPLE-MIB { namespace "http://tail-f.com/ns/mibs/SIMPLE-MIB/200702080000Z"; prefix SIMPLE-MIB; tailf:id ""; tailf:snmp-mib-module-name SIMPLE-MIB; import ietf-yang-types { prefix yang; } import ietf-inet-types { prefix inet; } import tailf-common { prefix tailf; } import tailf-xsd-types { prefix xs; } import SNMPv2-TC { prefix SNMPv2-TC; } revision 2007-02-08 { description ""; } container SIMPLE-MIB { container variables { tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.1; leaf numberOfHosts { type int32; tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.1.1; } } container hostTable { list hostEntry { key hostName; tailf:sort-order snmp; tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.2.1; leaf hostName { type hostNameType; tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.2.1.1.1; } leaf hostEnabled { type SNMPv2-TC:TruthValue; tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.2.1.1.2; } leaf hostNumberOfServers { type int32; tailf:snmp-oid 1.3.6.1.4.1.24961.3.1.2.1.1.3; } } } } typedef hostNameType { type string { length "min .. 64"; } } }
Compile the YANG modules representing MIBs the same way that any other YANG module is compiled, using confdc .
Note that all YANG modules representing the builtin MIBs are
available in $CONFD_DIR/src/confd/snmp/yang
directory. The parameter --yangpath can be
given to the compiler to search this directory.
The confdc compiler is used for compiling the MIB into a binary format that can be loaded by the ConfD SNMP agent. The MIB is compiled with the YANG .fxs file with associations that map the YANG nodes into objects in the MIB. The resulting file is a binary (.bin) file that is loaded into the ConfD SNMP agent.
$ confdc -c SIMPLE-MIB.mib simple.fxs
If the MIB IMPORTs other MIBs, these MIBs must be available (as compiled .bin files) to the compiler. By default, all compiled MIBs in the current directory and all builtin MIBs are available. Use the parameters --include-dir or --include-file to specify where the compiler can find the compiled MIBs.
Note that not every object in the MIB must have a mapping to a node in the YANG module. By using a separate MIB annotation file, ConfD can be instructed how these missing objects should be treated by the SNMP agent. The agent can treat the objects either as not implemented, or as implemented but non-existent.
The format of an annotation line is
object-name
annotation, where
object-name is the name of an object
type (column or scalar), and annotation
has the form behavior=noSuchObject
,
behavior=noSuchInstance
,
max_access=not_accessible
,
max_access=read_only
.
If a line is blank or starts with a #
character, it
is ignored. An object name may occur on several lines.
Example:
$ cat HOST-RESOURCES-MIB.miba # tell the agent to not implement these objects hrPartitionID behavior=noSuchInstance hrSWInstalledDate behavior=noSuchObject $ confdc -c HOST_RESOURCES-MIB.mib \ --mib-annotation HOST_RESOURCES.miba host-resources.fxs
The ConfD SNMP agent have the following built-in MIBs:
SNMPv2-MIB, a mandatory MIB for an agent. This MIB is always loaded at start-up.
SNMP-MPD-MIB, a mandatory MIB for an agent. This MIB is always loaded at start-up if the agent is configured for SNMPv3.
SNMP-FRAMEWORK-MIB, a mandatory MIB for an agent. This MIB is always loaded at start-up if the agent is configured for SNMPv3.
SNMP-COMMUNITY-MIB, handles SNMP v1 and v2c communities.
SNMP-VIEW-BASED-ACM-MIB, handles the view based access control.
SNMP-USER-BASED-SM-MIB, handles the user based access control.
SNMP-TARGET-MIB, to be able to configure targets for SNMP traps.
SNMP-NOTIFICATION-MIB, defines SNMP traps.
IPV6-TC, defines some IPv6 specific TEXTUAL-CONVENTIONs.
TRANSPORT-ADDRESS-MIB, defines some OBJECT-IDENTITYs for transport protocols. This MIB module cannot be loaded as a built-in module in the agent. If some other MIB IMPORTs this MIB, then it needs to be compiled and loaded as other non-built-in MIBs.
SNMP-USM-AES-MIB, defines an OBJECT-IDENTITY for the AES privacy protocol. This MIB module must not be loaded into the agent.
These MIBs of course must have their corresponding YANG .fxs files loaded in order for the SNMP agent to work (see the next section). The MIBs themselves are not required to be loaded. The user decides which MIBs should be loaded, and there may be reasons to not provide SNMP access to certain MIBs.
The MIBs SNMPv2-MIB, SNMP-MPD-MIB, and SNMP-FRAMEWORK-MIB, are always loaded into the ConfD SNMP agent at start-up. These MIBs are required for an SNMP agent.
The other built-in MIBs are not loaded per default, which
means that they cannot be accessed/configured via SNMP but
of course via for example CDB init files (see Section 5.8, “Loading initial data into CDB”) NETCONF, or even CLI
directly. If the intention is to have these MIBs loaded,
they must be listed in confd.conf
without any explicit paths to where they are stored as
shown in the example below.
Other MIBs (that are not built-in) are loaded by
specifying their absolute or relative paths, or
alternatively the MIBs can be loaded from
ConfDs
loadPath. We recommend that these MIBs are loaded from
the load path. This is how other data model files
(.fxs
etc) are handled.
The main reason for this recommendation is how MIBs can be dynamically reloaded. MIBs that are explicitly listed are reloaded by giving the command confd --reload. If any MIB cannot be loaded for whatever reason, ConfD halts. MIBs in the load path are reloaded using the data model upgrade functions, see Chapter 13, In-service Data Model Upgrade.
Example 17.4. Specifying built-in MIBs to be loaded into the agent
<snmpAgent> <enabled>true</enabled> <mibs> <!-- Load built-in MIBS --> <file>SNMP-COMMUNITY-MIB.bin</file> <file>SNMP-VIEW-BASED-ACM-MIB.bin</file> <file>SNMP-USER-BASED-SM-MIB.bin</file> <file>SNMP-TARGET-MIB.bin</file> <file>SNMP-NOTIFICATION-MIB.bin</file> <!-- Load specific user MIBs --> <file>/etc/confd/mibs/SIMPLE-MIB.bin</file> <!-- Load all MIBs present in the loadPath --> <fromLoadPath>true</fromLoadPath> </mibs> </snmpAgent>
The SNMP agent has a few built-in MIBs that store its
configuration data in CDB. The following .fxs
files defines namespaces for the built-in MIBs and must be
loaded at start-up if the SNMP agent is enabled:
SNMPv2-MIB.fxs
,
SNMPv2-SMI.fxs
,
SNMPv2-TC.fxs
- contains base
SNMPv2 types
SNMP-FRAMEWORK-MIB.fxs
SNMP-MPD-MIB.fxs
SNMP-COMMUNITY-MIB.fxs
SNMP-VIEW-BASED-ACM-MIB.fxs
SNMP-USER-BASED-SM-MIB.fxs
SNMP-TARGET-MIB.fxs
SNMP-NOTIFICATION-MIB.fxs
Preferably a loadPath
in the
confd.conf
file can be set to the
directory where these files are installed. If ConfD fails
to load these files it will terminate with a fatal error.
The built-in .fxs
files are delivered as
pre-built, but the YANG source code is provided
as well. Tampering with these files is not advised and may
result in a serious internal error. However we may wish
to recompile these YANG modules using the
confdc
compiler flag --export
, to not expose the built-in
MIB data to other ConfD internal protocols/applications
such as NETCONF, CLI, and Web UI. The YANG source
code is provided for this reason. Also it is possible to
provide external callpoints for the built-in MIB data to
store the data in an external database instead of CDB.
The rowstatus column for tables is always handled by the
SNMP agent and should not be modeled in the YANG
modules. The tailf:snmp-row-status-column
statement can be left out and the row status column will
be looked up by the compiler.
The RowStatus column in an SNMP table is used for reading the status of a conceptual row in a table and for creating and deleting new conceptual rows in the table. The following values are always defined for the row status:
active (1) - indicates that the conceptual row is available.
notInService (2) - indicates that the conceptual row is unavailable. This is a temporary state where the row is stored in the SNMP agent and not in the database. A row with a RowStatus of 'notInService' can be made 'active' which means that the row will be inserted into the database.
notReady (3) - indicates that the conceptual row is missing information. This is a temporary state where the row is stored in the SNMP agent and not in the database. A RowStatus of 'notReady' is returned to indicate that the row is missing a value for one or more mandatory column(s). When the row have all the mandatory values set, a RowStatus of 'notInService' will be returned instead of 'notReady'.
createAndGo (4) - set by manager to create new row instance.
createAndWait (5) - set by manager to create new row instance but not make it available. A RowStatus of 'notInService' or 'notReady' is returned depending on if all values for the mandatory columns are set or not.
destroy (6) - set by manager to delete all instances in the conceptual row.
The createAndWait creates a new
instance of a conceptual row in a temporary state where
the row will have a RowStatus set to 'notReady' or
'notInService' depending on if all the mandatory columns
are set for the column or not. It can be made 'active' and
will then be inserted into the database. Note that there
are no guarantees that the row will exist more than 5
minutes (by default) in the temporary storage in the SNMP
Agent. The temporary cache used by the SNMP agent for
this storage is volatile. The temporary storage time can
be configured in by setting
temporaryStorageTime in
confd.conf
.
To delete a conceptual row the destroy value is used.
When a YANG module is generated from a MIB, and the MIB contains any scalar object of type TestAndIncr, these objects are not translated into the YANG module, since they don't make sense outside SNMP. Then, when the MIB is compiled, the compiler generates code so ConfD automatically handles these objects. No coding is required.
Objects in MIBs can be read-only or writable. In YANG, nodes are marked as representing configuration or non-configuration data.
If a MIB object is read-only, it can be mapped to a configuration or non-configuration YANG node.
When a YANG module is generated from a MIB, all read-only MIB objects are translated into non-configuration YANG nodes.
If a MIB object is writable, it is usually mapped to a
configuration YANG node. However, in some cases, the MIB
object doesn't really represent configuration, but is
rather writable operational data. An example could be a
scalar variable rebootRouter
. When written
to, the router will reboot. In order to support this,
non-configuration YANG nodes can be marked with
tailf:writable true
. Writable MIB objects
can be mapped into non-configuration YANG nodes that are
marked with tailf:writable true
.
When a YANG module is generated from a MIB, writable MIB objects are translated into configuration YANG nodes, unless the MIB object is marked as representing writable operational data in a MIB annotation file (see mib_annotations(5)).
If the SNMP agent receives a SET PDU with one or more
writable operational objects, it will start a read-write
transaction towards CONFD_OPERATIONAL
. In
this transaction, the agent will write all variables from
the PDU, and then it will commit the transaction.
Instrumentation code needs to be written to handle these
writes.
See Section 7.8, “Writable operational data”
for how these objects are implemented, and
examples.confd/snmpa/9-writable-operational
in the ConfD examples collection for an example of how
this can be implemented.
There is no protocol support in SNMP to delete optional
nodes. Conceptual table rows are typically created and
deleted by using a RowStatus
column, but there
is no standardized way to delete optional nodes. One
technique to handle this is to introduce a special value for
the object, so that the object is deleted when it is set to
this special value. ConfD supports this technique with
the YANG extension tailf:snmp-delete-value
.
In order to use this technique, an optional leaf in the YANG
model is mapped to a scalar or columnar object in the MIB
module. The data type definition of the MIB object allows
the same values as the corresponding YANG leaf, and in
addition it also allows one extra value, not allowed by the
YANG leaf. This special value is also defined in the YANG
model in the tailf:snmp-delete-value
statement.
In the following example, we define a MIB object
fooOptionalLeaf
, and corresponding YANG leaf
foo-optional-leaf
.
Example 17.5. SMI definition of an optional object
fooOptionalLeaf OBJECT-TYPE SYNTAX Integer32 (0..255) MAX-ACCESS read-create STATUS current DESCRIPTION "The special value zero means not used." ::= { fooEntry 3 }
Example 17.6. YANG definition of an optional leaf
leaf foo-optional-leaf { type int32 { range "1..255"; } tailf:snmp-delete-value 0; tailf:snmp-name fooOptionalLeaf; }
When the SNMP agent receives a SET request to set this object to '0', the leaf will be deleted.
If the tailf:snmp-delete-value
statement has
the substatement
tailf:snmp-send-delete-value
, the same
special value will be returned on a GET request, instead
of the default noSuchInstance
.
Tables in SNMP are strictly lexicographically ordered. An
SNMP table is typically traversed with
GET-NEXT
requests, where given a previous
index of a row the next greater index is returned. Since
the table is specified in a YANG module and may be stored in
an external database or perhaps as a managed object (MO)
written in
C, it is important that the
get_next()
function
returns the
elements in correct order. If the get-next
function doesn't return the elements properly in order,
SNMP will not work. If CDB is used to store the data the
ordering of the elements will be correct. Note that the
tailf:sort-order
statement may have to be
specified for indexes with dynamic length (see Section 17.2.8, “Loading YANG modules for built-in MIBs”).
Types with dynamic length in SNMP like OCTET STRING will have a length indicator when they are part of the INDEX, so the ordering for strings stored in such a table will be on length first, unless they are declared as IMPLIED as in IMPLIED OCTET STRING. In this case the index will not have any length indicator included, and the table should be sorted as normal.
The following values can be given to the
tailf:sort-order
statement:
normal
This is the default and means that the table is sorted using the key values. This value should be used when the corresponding SNMP table does not have any INDEX object with dynamic length.
snmp
This value means that when sorting, any key element of dynamic length will have the length prepended to the value before sorting. It should be used if the corresponding SNMP table has any INDEX object with dynamic length, and no IMPLIED object.
snmp-implied
This value is the same as
snmp
, except that the last
key element will not prepend the length indicator to
the key value. It should be used if the
corresponding SNMP table has any IMPLIED INDEX.
Here's an example of a MIB table with a DisplayString with dynamic length as index.
Example 17.7. simple.mib
hostTable OBJECT-TYPE SYNTAX SEQUENCE OF HostEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "The table of hosts." ::= { simpleTables 1 } hostEntry OBJECT-TYPE SYNTAX HostEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Information about a host." INDEX { hostName } ::= { hostTable 1 } HostEntry ::= SEQUENCE { hostName DisplayString, hostEnabled TruthValue, hostNumberOfServers INTEGER, hostRowStatus RowStatus }
If the list corresponding to this SNMP table is
stored in CDB, the definition in the YANG module must specify
tailf:sort-order snmp
so that the table is
sorted correctly (with length indicator included).
Example 17.8. simple.yang
list host { key name; tailf:sort-order snmp; leaf name { type nameType; } leaf enabled { type boolean; mandatory true; } leaf numberOfServers { type uint16; mandatory true; } }
When the sort order is set to "snmp" or "snmp-implied" on
a list, it affects the displayed sort order in
all northbound interfaces. Thus the list of hosts above
will be sorted according to SNMP lexicographical ordering,
even in e.g. the CLI. Sometimes this may be confusing to
users. This problem can be solved by adding a
tailf:secondary-index
to the list:
Example 17.9. simple.yang with secondary index
list host { key name; tailf:secondary-index snmp { tailf:index-leafs "name"; tailf:sort-order snmp; } leaf name { type nameType; } leaf enabled { type boolean; mandatory true; } leaf numberOfServers { type uint16; mandatory true; } }
When the SNMP agent traverses a table, it checks if there is a secondary-index with the reserved name "snmp" defined for the table. If there is such an index, the agent traverses the table using this index.
In the example above, the host
table is
sorted in normal order, which means that
"arthur" appears before
"ford". But since there is a
secondary-index called snmp, the SNMP
agent will use this index when traversing the table, so
that 4."ford" appears before
5."arthur" over SNMP.
Note that the presence of a secondary-index in the YANG module is not enough; the instrumentation code must be prepared to perform the actual sorting. See confd_lib_dp(3) for details.
Enumerations in SNMP have textual representation mapped to an integer. A simple example would be the definition for TruthValue:
Example 17.10. TruthValue from the SNMPv2-TC
TruthValue ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "Represents a boolean value." SYNTAX INTEGER { true(1), false(2) }
The confdc --mib2yang tool produces the following type definition for TruthValue:
Example 17.11. A typedef for TruthValue
typedef TruthValue { type enumeration { enum true { value 1; } enum false { value 2; } } }
Notifications are defined by the NOTIFICATION-TYPE macro in SMIv2. There are two types of notifications in SNMP: trap and inform. When the managed object needs to send trap notifications the following functions should be called (from MO's written in C).
Example 17.12. Functions for sending notification from C
int confd_register_snmp_notification( struct confd_daemon_ctx *dx, int fd, const char *notify_name, const char *ctx_name, struct confd_notification_ctx **nctx); int confd_notification_send_snmp( struct confd_notification_ctx *nctx, const char *notification, struct confd_snmp_varbind *varbinds, int num_vars);
The
confd_register_snmp_notification()
function is typically called once to register the
parameters common to a set of notifications, and then the
individual notifications are sent by calling
confd_notification_send_snmp()
. The
daemon context pointer dx
is obtained by
calling confd_init_daemon()
, and the
socket file descriptor fd
is a worker socket
connected to the ConfD daemon via a call to
confd_connect()
. See confd_lib_dp(3) man page for details about
these functions. Note also that a control socket must be
connected to the ConfD daemon before calling
confd_register_snmp_notification()
.
The notify_name
parameter matches the
NotifyName in the snmpNotifyTable in the
SNMP-NOTIFICATION-MIB. Trap will be sent to targets
pointed out by NotifyName. If NotifyName is
""; the normal procedure defined in
SNMP-NOTIFICATION-MIB is used, i.e. the trap is sent to
all managers. Otherwise, the NotifyName is used to find
an entry in the SnmpNotifyTable which defines how to send
the notification (as an Inform or a Trap), and to select
targets from SnmpTargetAddrTable (using the Tag).
The ctx_name
is the name of the context.
The default context is "".
The notification
string is the notification
name. For example "coldStart"
or
"warmStart"
. This symbolic name of a notification
must be defined in a MIB that is loaded into the agent.
If the empty string is used as notification name, the notification
to send is constructed from the varbinds
array alone,
which must then contain a value for the snmpTrapOID
variable.
The varbinds
array contains
variable bindings for parameters that
should be sent along in the notification.
The include file confd_lib.h
defines
data structures for these:
Example 17.13. SNMP varbind structures from confd_maapi.h
enum confd_snmp_var_type { CONFD_SNMP_VARIABLE = 1, CONFD_SNMP_OID = 2, CONFD_SNMP_COL_ROW = 3 }; struct confd_snmp_oid { int oid[128]; int len; }; struct confd_snmp_col_row { char column[256]; struct confd_snmp_oid rowindex; }; struct confd_snmp_varbind { enum confd_snmp_var_type type; union { char name[256]; struct confd_snmp_oid oid; struct confd_snmp_col_row cr; } var; confd_value_t val; };
Each varbind is either:
a symbolic name of a scalar variable referred to in the notification specification.
a symbolic name of a column variable. Rowindex is the index of the specified column.
for the instance of an object, scalar variable or column variable.
If a value is given it will be used. If it is not given
(i.e. set to C_NOEXISTS
) then the agent will look up
the value with a GET
operation.
Example 17.14. Notification registration
int setup(struct confd_daemon_ctx *dctx, int workersock, struct confd_notification_ctx **nctx) { if (confd_register_snmp_notification(dctx, workersock, "std_v1_trap", "", nctx)) != CONFD_OK) return CONFD_ERR; return confd_register_done(dctx); }
Example 17.15. Sending a coldStart notification
int test1(struct confd_notification_ctx *nctx) { return confd_notification_send_snmp(nctx, "coldStart", NULL, 0); }
Example 17.16. Sending a notification with a varbind
int test2(struct confd_notification_ctx *nctx) { struct confd_snmp_varbind vb; vb.type = CONFD_SNMP_VARIABLE; strcpy(vb.var.name, "myVariable"); CONFD_SET_INT32(&vb.val, 32); return confd_notification_send_snmp(nctx, "notif1", &vb, 1); }
The inform type notifications are similar to the trap type except there is an acknowledgment sent back from the manager that received the inform. Two callbacks needs to be registered to receive the result of the inform, and there's a separate function for sending an inform.
int confd_register_notification_snmp_inform_cb( struct confd_daemon_ctx *dx, const struct confd_notification_snmp_inform_cbs *cb);
int confd_notification_send_snmp_inform( struct confd_notification_ctx *nctx, const char *notification, struct confd_snmp_varbind *varbinds, int num_vars, const char *cb_id, int ref);
The struct confd_notification_snmp_inform_cbs is defined as:
struct confd_notification_snmp_inform_cbs { char cb_id[MAX_CALLPOINT_LEN]; void (*targets)(struct confd_notification_ctx *nctx, int ref, struct confd_snmp_target *targets, int num_targets); void (*result)(struct confd_notification_ctx *nctx, int ref, struct confd_snmp_target *target, int got_response); void *cb_opaque; /* private user data */ };
In order to debug the notification sending process in ConfD, the
/confdConfig/logs/developerLogLevel
in confd.conf(5) can be set to "trace".
The previous sections have discussed the scenario where there is an existing set of MIB files, and then confdc --mib2yang is used to convert these to YANG with the associations that the agent needs.
If instead no MIBs exist, but a number of YANG files
(complied to .fxs
files), these can be
translated to MIB files (in SMIv2 syntax), using the
--emit-mib
option of
confdc.
The normal operation of the translator is to select those
nodes that have an tailf:snmp-oid
statement,
and ignore the others. If the option
--generate-oids
is given (described later
in this section), all elements are selected, unless
explicitly marked with
tailf:snmp-exclude-object
.
The value of the tailf:snmp-oid
statement can be either a
one-component suffix,
for example ".4", or a full OID, such as "1.3.6.1.4.1.12345" or
"private.1.12345". If it's a suffix, a full OID should
be specified for some ancestor element, in the YANG module
header, or using the --oid
option.
In order to be selected for translation to the MIB file, an
element must also match the module name. The module name can
be given as an tailf:snmp-mib-module-name
statement in the YANG module header, which is then inherited
by all nodes, or using the --module
option. It can also be specified on a node, which then
overrides the value from the header or ancestor nodes.
Since tables can not reside inside tables in SMI, lists containing lists are handled by moving the inner lists up to top level.
Nodes inside containers in lists are given OIDs directly below the table entry, and names which are the concatenation of the path down from the table level. The containers should not have an OID.
If a RowStatus column is desired for a table, use the statement
tailf:snmp-row-status-column
on the corresponding list.
The statement's value should be the column number
(i.e., the last OID component, with no leading period). The
object will be called rowstatus
.
The form of the translation command is shown below (using fictitious parameters):
confdc --emit-mib FOO-MIB.mib --oid enterprises.24961 -- foo.fxs
The basename of the output file (here,
FOO-MIB
) by default becomes the name of the
module (with all letters made upper case). The option
--module
can be used to specify the
module name.
Any other .fxs
files we depend on have to be given
with -f
, as
usual.
confdc --emit-mib FOO-MIB.mib --oid enterprises.24961 -f types.fxs -- foo.fxs
To build the .bin
file to be loaded by the ConfD SNMP
agent, do
confdc -c FOO-MIB.mib foo.fxs -f types.fxs
During translation, problems are reported as warnings or errors. When an error occurs, translation continues so that a complete MIB file is still produced, but the exit status from confdc is 1, rather than 0.
With the option --generate-oids
, the
translator selects all nodes, inventing OIDs for the nodes
which don't already have an tailf:snmp-oid
statement. If a node has a
tailf:snmp-exclude-object
statement, it is
ignored. The --generate-oids
is useful
when the original YANG module cannot be modified.
By default, the OID suffixes of child elements are numbered
consecutively, starting with 1. This can be overridden with a
suffix tailf:snmp-oid
on a node. The
suffixes of the following elements will continue from that point.
A RowStatus element is always generated.
Since the MIB compiler (i.e., confdc -c when given a MIB file) needs to know the association between MIB objects and YANG nodes, and this association is not present in the YANG module (if it was, there would be no need for generating OIDs), we use YANG annotation files.
A YANG annotation file is used to define the mapping between YANG nodes and MIB objects. The YANG annotation file can be written by hand, or generated from the YANG module. Since it is important in SNMP that OIDs once assigned do not change, it is recommended to generate an initial version of a YANG annotation file, and then update it manually as the YANG module evolves. The process to do this is:
Compile the YANG module: confdc -c foo.yang
Generate an initial YANG annotation file: confdc --emit-mib FOO-MIB.mib --oid experimental.1 --generate-oids --generate-yang-annotation foo.fxs
The YANG annotation file will be called
foo-ann.yang
.
Once the initial YANG annotation file is generated, it should be kept and updated as the original YANG module is updated. The MIB can then be generated as needed:
Compile the YANG module and annotation file: confdc -c -a foo-ann.yang foo.yang
Generate the MIB: confdc --emit-mib FOO-MIB.mib foo.fxs
Compile the MIB: confdc -c FOO-MIB.mib foo.fxs
At the start of the generated MIB file, a header of comments gives
some
information on how the file was produced, including the
confdc
invocation, the namespace of the .fxs
file,
and
the current date and time. (Any --
strings are converted
to ++
because the former cannot occur in SMI comments.)
The only field in the module header which can be filled in
with information from the .fxs
file
is the first DESCRIPTION
field, which is
taken from the YANG module's description
statement, if one exists.
The remaining fields have the following format, in order to facilitate automatic editing of the values:
LAST-UPDATED "@LAST-UPDATED" ORGANIZATION "@ORGANIZATION" CONTACT-INFO "@CONTACT-INFO" REVISION "@REVISION" DESCRIPTION "@REVISION-DESCRIPTION"
The names of the objects are constructed by joining all
the parts of the full tag path of the nodes, capitalizing
each part. An alternative is to not
capitalize, and join the parts with "-
" (with
the option --join-names hyphen
see the section called “Emit SMIv2 MIB options”).
If the statement tailf:snmp-name
is used on a
node, its value is taken as the full name of the
object. For containers and tables, it also becomes the
first part of its children's names.
The characters '.
' and '_
' can
occur in YANG identifiers but not in SNMP identifiers;
they are converted to '-
', unless the option
--join-names force-capitalize
is given.
In this case, such identifiers are capitalized (to
lowerCamelCase).
If generated names clash with each other (for example both
/x/a/b-c
and
/x/a-b/c
yielding the name x-a-b-c
), an error
is reported.
YANG types are mapped according to the table in Table 17.2, “YANG mapping to SMI types”. .
The type restrictions that deal with lengths ranges are
translated. The remaining restrictions (pattern
,
fraction-digits
) are silently ignored.
If inet:ipv6-address is used, Ipv6Address is
imported from
IPV6-TC. Otherwise, imports are only made from
SNMPv2-SMI
, SNMPv2-CONF
and SNMPv2-TC
.
Leafs with types which are not handled are skipped in the translation, with a warning.
Identifiers which have an invalid syntax (for example, start with a digit) are kept in the translation, but a warning is given.
If a leaf with type yang:counter64 is used as an index or as writable, a warning is given.
STATUS is current
by default for all objects. To cause
STATUS to be deprecated
or obsolete
, use the
YANG statement status
with the corresponding value on the
YANG node.
MAX-ACCESS is read-only
for operational nodes
(having config false;
).
Actions are silently ignored.
Before each generated OBJECT-TYPE and OBJECT IDENTIFIER, a comment containing the word "tagpath" indicates which YANG node the object corresponds to.
DESCRIPTION
is copied from the .fxs
file, when
available (if the description
statement is present).
For containers, they are emitted as
comments instead (the string "--
" is replaced with
"- -
"). description
for nodes that are not
translated into
any OID are lost. Double quote characters, which can't
occur in DESCRIPTION
, are replaced with single quotes.
For a string with a min length, but no max length, the max length is assumed to be 65535.
tailf:sort-order snmp-implied;
results in the IMPLIED
keyword, if appropriate for the type.
If a type containing negative values is used as an index, or if a string with unlimited length is used as an index, a warning is given.
If a list uses tailf:sort-order normal
,
the child nodes may
not appear in SNMP order when listed, and so some elements
may get lost, or confuse the manager. A warning is given
for such cases.
If tailf:sort-order snmp-implied
is used for one list
list, which contains another list, the last index of the
outer list (with implied length) can no longer have
implied length in SNMP, so agent communication will most
likely fail.
DEFVAL
clauses are emitted for string and integer types
(including bit types), but not for others.
Configuration data for the ConfD SNMP agent consists of:
data in confd.conf
data for built-in MIBs
The configuration data in confd.conf
is
typically only configured once and then never changed. (It
is possible to change however).
To store initial data for the built-in MIBs, CDB init files
can be used. CDB init files are loaded the first time the
system is started and the database is initialized with this
data. See Section 5.8, “Loading initial data into CDB”. Typically
these files will define access rules and users of the agent.
Updating the MIB data is done directly from the northbound
agents such as NETCONF or CLI. The
confdc
compiler flag
--export
can be used to grant access for
applications / protocols such as NETCONF and CLI to modify
the built-in SNMP data. For this reason the YANG source for
the built-in MIBs are provided so that they can be
recompiled with the --export
flag.
The data for the SNMP agent built-in MIBs are by default stored in CDB, but it is also possible have this data in an external database. In this case the user needs to add external callpoints to the YANG modules and recompile them.
There are a few elements that must be configured in
confd.conf
in order for the SNMP agent to start.
First of all the ConfD SNMP agent must be
enabled, and it must have an address and a port
that it will try to bind to at start-up. If if fails to
bind to the port, ConfD will fail to start. It should
also have a list of MIBs that should be loaded into the
agent. If it fails to load any of the MIBs, ConfD will
fail to start.
Several options can be given to control the behavior of the SNMP agent:
enabled
Whether or not the agent should be started.
ip, port
The IP address and port that the agent will bind and listen for incoming requests to.
mibs
The MIBs that the agent should load at start-up.
snmpVersions
The version of the SNMP protocol that the agent will understand (the supported versions are v1, v2c, and v3).
snmpEngineID, snmpEngineMaxMessageSize
The engine identifier and max message size that this agent can handle.
sysDescr
Description of the entity. The description should include the full name and version identification of the system. See SNMPv2-MIB for more information.
sysObjectID
The vendor's authoritative identification of the network management subsystem contained in the entity. See SNMPv2-MIB for more information.
sysServices
A value which identifies the set of services that this entity primarily offers. See SNMPv2-MIB for more information.
sysORTable
An optional table with SNMP agent capabilities. These entries will populate the real sysORTable in the SNMPv2-MIB.
Below is an example of a confd.conf
file:
Example 17.17. Example of a confd.conf
<snmpAgent> <enabled>true</enabled> <ip>0.0.0.0</ip> <port>161</port> <mibs> <file>SIMPLE-MIB.bin</file> </mibs> <snmpVersions> <v1>true</v1> <v2c>true</v2c> <v3>false</v3> </snmpVersions> <snmpEngine> <snmpEngineID>80:00:61:81:05:01</snmpEngineID> </snmpEngine> <system> <sysDescr>Tail-f ConfD agent</sysDescr> <sysObjectID>1.3.6.1.4.1.24961</sysObjectID> </system> </snmpAgent>
This will enable the SNMP agent, which will listen to
requests incoming to locally at port 161. The MIB file
SIMPLE-MIB.bin
is loaded in the
agent, and the agent will understand SNMP versions v1 and
v2c, but not v3.
The data stored in confd.conf
can be changed by
modifying the file and then issuing a confd
--reload command. This will trigger an already running
ConfD daemon to check its configuration data and make the
necessary changes. Certain changes like the SNMP agents IP
address will trigger an internal restart of the SNMP agent
(ConfD will still remain up), other changes like the MIBs
that are loaded can be done without restarting the SNMP
agent. It's thus possible to update the MIBs in a running
ConfD SNMP agent without restarting the SNMP agent.
Example 17.18. Old confd.conf content
<snmpAgent> <enabled>true</enabled> <ip>0.0.0.0</ip> <port>161</port> <mibs> <file>SIMPLE-MIB.bin</file> </mibs> </snmpAgent>
Example 17.19. Updated confd.conf content
<snmpAgent> <enabled>true</enabled> <ip>0.0.0.0</ip> <port>161</port> <mibs> <file>SIMPLE-MIB.bin</file> <file>SIMPLE-MIB2.bin</file> </mibs> </snmpAgent>
The example above will on a confd --reload command
unload all the loaded MIBs that were specified on the old
configuration, and load the MIBs specified in the updated
configuration. The MIB SIMPLE-MIB.bin
is
unloaded and then loaded again, which can be useful
during development to update to a newer version of the
MIB.
There is a set of standard MIBs which are used to control and configure an SNMP agent. These MIBs are implemented in this agent. The user can control which of these MIBs are actually loaded into the agent, and thus made visible to SNMP managers. For example, in a non-secure environment, it might be a good idea to not make MIBs that define access control visible. Note, the data that the MIBs define is used internally in the agent, even if the MIBs are not loaded.
Any SNMP agent must implement the system group and the snmp group, defined in SNMPv2-MIB. This MIB will be loaded by default.
An SNMPv3 agent must implement the SNMP-FRAMEWORK-MIB and SNMP-MPD-MIB. These MIBs are also loaded by default, if the agent is configured for SNMPv3.
There are five other standard MIBs, which also may be loaded into the agent. These MIBs are:
SNMP-TARGET-MIB and SNMP-NOTIFICATION-MIB which defines managed objects for configuration of management targets, i.e. receivers of notifications (traps and informs). These MIBs can be used with any SNMP version.
SNMP-VIEW-BASED-ACM-MIB, which defines managed objects for access control. This MIB can be used with any SNMP version.
SNMP-COMMUNITY-MIB, which defines managed objects for coexistence of SNMPv1 and SNMPv2c with SNMPv3. This MIB is only useful if SNMPv1 or SNMPv2c is used, possibly in combination with SNMPv3.
SNMP-USER-BASED-SM-MIB, which defines managed objects for authentication and privacy. This MIB is only useful with SNMPv3.
Initial config data for communities, access rules, users
etc. is preferably stored in CDB init files. They are read
once when the system is started for the first time and put
in the database. The files must be located in the
dbDir. Typically a system have the
following CDB init files for the built-in MIBs (the file
name can be anything but must end with the suffix
_init.xml
):
community_init.xml
Data for SNMP-COMMUNITY-MIB. Defines the communities that have access to the system.
vacm_init.xml
Data for SNMP-VIEW-BASED-ACM-MIB. Defines view based access.
usm_init.xml
Data for SNMP-USER-BASED-SM-MIB. Defines user based access used with authentication and privacy. This is only used with SNMP v3.
target_init.xml
Data for SNMP-TARGET-MIB. Defines trap targets.
notify_init.xml
Data for SNMP-NOTIFICATION-MIB. Defines notifications.
Below is an example of an init file to define a community within the agent.
Example 17.20. Example community_init.xml
<SNMP-COMMUNITY-MIB xmlns="http://tail-f.com/ns/mibs/SNMP-COMMUNITY-MIB/200308060000Z"> <snmpCommunityTable> <snmpCommunityEntry> <snmpCommunityIndex>public</snmpCommunityIndex> <snmpCommunityName>public</snmpCommunityName> <snmpCommunitySecurityName>public</snmpCommunitySecurityName> <snmpCommunityContextEngineID>80:00:61:81:05:01</snmpCommunityContextEngineID> <snmpCommunityContextName/> <snmpCommunityTransportTag/> <snmpCommunityStorageType>permanent</snmpCommunityStorageType> </snmpCommunityEntry </snmpCommunityTable> </SNMP-COMMUNITY-MIB>
The following values are supported for the object
snmpTargetAddrTDomain
:
SNMPv2-TM::snmpUDPDomain
UDP over IPv4
TRANSPORT-ADDRESS-MIB::transportDomainUdpIpv4
UDP over IPv4 (same as snmpUDPDomain above)
TRANSPORT-ADDRESS-MIB::transportDomainUdpIpv6
UDP over IPv6
The following authentication algorithms are supported:
SNMP-USER-BASED-SM-MIB::usmNoAuthProtocol
No Authentication Protocol.
SNMP-USER-BASED-SM-MIB::usmHMACMD5AuthProtocol
The HMAC-MD5-96 Digest Authentication Protocol.
SNMP-USER-BASED-SM-MIB::usmHMACSHAAuthProtocol
The HMAC-SHA-96 Digest Authentication Protocol.
The following privacy algorithms are supported:
SNMP-USER-BASED-SM-MIB::usmNoPrivProtocol
No Privacy Protocol.
SNMP-USER-BASED-SM-MIB::usmDESPrivProtocol
The CBC-DES Symmetric Encryption Protocol.
SNMP-USM-AES-MIB::usmAesCfb128Protocol
The CFB128-AES-128 Privacy Protocol.
All data access to ConfD is done through user sessions. Once a user session is established, it can open read-only or read-write transactions towards a data store or towards operational data.
All requests start transactions towards the running data store.
SNMP over UDP does not have a concept of a user session. Each packet is (in theory) handled independently. However, for performance reasons, the SNMP agent creates a user session and a transaction when it receives the first packet. It then caches the session and transaction, and if it gets a new packet with the same source IP address, same UDP port, and same securityName, it reuses the session and transaction.
If no packet has been received during a 10 second period, the session and transaction are closed.
The cache has a limit of 32 sessions. If the cache is full when the agent needs to create a new session, an old session can be closed for this purpose, even though it was in use less than 10 seconds ago.
The confd.conf
parameters for session
limits can be used to limit the number of concurrent SNMP
user sessions or configuration transactions, but note that
higher values than 32 (the session cache limit described above)
will not have any effect.
When the SNMP agent receives a SNMP request, it determines the securityName and SNMP context for the request. If SNMPv1 or SNMPv2c is used, the snmpCommunityTable is consulted to determine the securityName and SNMP context. If SNMPv3 is used, the SNMP context is explicitly given in the request, and the securityName is determined from the usmUserTable.
When the SNMP agent starts a user session in ConfD, it uses
the securityName as the username, the string "snmp" as ConfD
AAA context, and no groups. If the username is a member of
any of ConfD's AAA groups, it will be placed in these
groups. Otherwise, if there is a defaultGroup configured in
confd.conf
, the user will be placed in
this group. Otherwise, the user does not belong to any
group.
Note that the user is authenticated by the SNMP agent, and not by ConfD's AAA.
For each SNMP object the user tries to access, VACM is consulted to see if the user's securityName has access, in the given context. If it has, the SNMP agent will try to access the corresponding YANG object. ConfD's normal AAA authorization is consulted to see if the groups the user belongs to have access to the YANG object.
Since both VACM and ConfD's AAA are consulted, a ConfD user can choose to use one of them, or both. One usage strategy can be to add VACM rules which gives full access to everyone, and then rely on ConfD's AAA datarules. Another strategy could be to have detailed rules in VACM, and then give full access to the "snmp" context in ConfD's AAA.
If ConfD is run in HA mode, the SNMP variables
sysUpTime
, snmpEngineTime
, and
snmpEngineBoots
are automatically replicated.
This means that if a slave ConfD takes over as master,
these variables will keep their values.
It is essential that each ConfD instance in the cluster
has the same snmpEngineID
configured. This value
is defined in confd.conf
, and it is the
responsibility of the user to make sure it has the same
value on all nodes in the cluster. However, if ConfD's
configuration is stored in CDB (see Section 28.4.2, “Storing ConfD configuration parameters in CDB”), then since
CDB is replicated, the snmpEngineID
will always
be the same in the cluster.
The ConfD integrated SNMP agent can run as subagent to the NET-SNMP master agent. This is useful in scenarios where you want to use NET-SNMP agents for monitoring the host, or reuse other NET-SNMP subagents in your solution.
The easiest way to run the agent as sub-agent is to configure the
proxy alternative in NET-SNMP snmpd.conf
.
(See the snmpd.conf man page)
Make sure that you have created an access view with the correct OID root.
You need to add a proxy command entry to the snmpd.conf
file.
proxy [-Cn CONTEXTNAME] [SNMPCMD_ARGS] HOST OID [REMOTEOID]
Values for the proxy configuration:
SNMPCMD_ARGS : these are the authentication parameters you want to pass to the ConfD SNMP agent. Note that the original auth parameters will not be used. (See snmpcmd man page). In the simplest configuration you specify a community string, for example -c secret where secret will be used as community string for all requests forwarded to ConfD.
HOST : IPv4-address[:port] : the IP address and the port of the ConfD SNMP agent. Make sure that ConfD uses a different port than the standard ports which you probably have configured for the NET-SNMP master agent.
OID : the SNMP OBJECT-IDENTIFIER of the root of the tree managed by ConfD SNMP agent.
After adding the values in the snmpd.conf
file, restart the snmpd service.
The example below will forward all requests for Tail-f specific objects to the
ConfD agent running on
localhost on port 5000 using the communit string secret
.
proxy -c secret localhost:5000 1.3.1.6.4.24961