nav icon indicating copy to clipboard operation
nav copied to clipboard

Implement SNMPv3 contexts as alternative to community indexing for retrieval of logical BRIDGE-MIB instances on Cisco switches

Open lunkwill42 opened this issue 1 year ago • 3 comments

lunkwill42 avatar Feb 19 '24 12:02 lunkwill42

NAV currently uses ENTITY-MIB::entLogicalTable entries (if it can) to discover alternate logical views of the BRIDGE-MIB (SNMPv2-SMI::mib-2.17).

For matching entries, it fetches an alternative community from ENTITY-MIB::entLogicalCommunity:

entLogicalCommunity OBJECT-TYPE
  -- FROM	ENTITY-MIB
  SYNTAX	OCTET STRING (0..255)
  MAX-ACCESS	read-only
  STATUS	deprecated
  DESCRIPTION	"An SNMPv1 or SNMPv2C community-string, which can be used to
            access detailed management information for this logical
            entity.  The agent should allow read access with this
            community string (to an appropriate subset of all managed
            objects) and may also return a community string based on the
            privileges of the request used to read this object.  Note
            that an agent may return a community string with read-only
            privileges, even if this object is accessed with a
            read-write community string.  However, the agent must take

            care not to return a community string that allows more
            privileges than the community string used to access this
            object.

            A compliant SNMP agent may wish to conserve naming scopes by
            representing multiple logical entities in a single 'default'
            naming scope.  This is possible when the logical entities,
            represented by the same value of entLogicalCommunity, have
            no object instances in common.  For example, 'bridge1' and
            'repeater1' may be part of the main naming scope, but at
            least one additional community string is needed to represent
            'bridge2' and 'repeater2'.

            Logical entities 'bridge1' and 'repeater1' would be
            represented by sysOREntries associated with the 'default'
            naming scope.

            For agents not accessible via SNMPv1 or SNMPv2C, the value
            of this object is the empty string.  This object may also
            contain an empty string if a community string has not yet
            been assigned by the agent, or if no community string with
            suitable access rights can be returned for a particular SNMP
            request.

            Note that this object is deprecated.  Agents which implement
            SNMPv3 access should use the entLogicalContextEngineID and
            entLogicalContextName objects to identify the context
            associated with each logical entity.  SNMPv3 agents may
            return a zero-length string for this object, or may continue
            to return a community string (e.g., tri-lingual agent
            support)."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) entityMIB(47) entityMIBObjects(1) entityLogical(2) entLogicalTable(1) entLogicalEntry(1) 4 }

For SNMPv3, it should rather look at ENTITY-MIB::entLogicalContextName (and, potentially, heed ENTITY-MIB::entLogicalContextEngineID):

entLogicalContextName OBJECT-TYPE
  -- FROM	ENTITY-MIB
  -- TEXTUAL CONVENTION SnmpAdminString
  SYNTAX	OCTET STRING (0..255)
  DISPLAY-HINT	"255t"
  MAX-ACCESS	read-only
  STATUS	current
  DESCRIPTION	"The contextName that can be used to send an SNMP message
            concerning information held by this logical entity, to the
            address specified by the associated
            'entLogicalTAddress/entLogicalTDomain' pair.

            This object, together with the associated
            entLogicalContextEngineID object, defines the context
            associated with a particular logical entity, and allows

            access to SNMP engines identified by a contextEngineId and
            contextName pair.

            If no value has been configured by the agent, a zero-length
            string is returned, or the agent may choose not to
            instantiate this object at all."
::= { iso(1) org(3) dod(6) internet(1) mgmt(2) mib-2(1) entityMIB(47) entityMIBObjects(1) entityLogical(2) entLogicalTable(1) entLogicalEntry(1) 8 }

lunkwill42 avatar May 15 '24 14:05 lunkwill42

Two mibretriever implementations implement retrieve_alternate_bridge_mibs: entity_mib and cisco_vtp_mib. The former fetched from ENTITY-MIB, the latter synthesizes entries from inspecting the proprietary CISCO-VTP-MIB.

These are both used from this function (responses from ENTITY-MIB being preferred): https://github.com/Uninett/nav/blob/276e9f47fdfea81ccaf462a5141249e2528a639e/python/nav/ipdevpoll/utils.py#L146

The signature of the return values of these functions must likely be changed to include optional SNMPv3 contexts and engine IDs.

lunkwill42 avatar May 15 '24 14:05 lunkwill42

The results of these functions are used by this class to implement collection across multiple logical instances of a MIB:

https://github.com/Uninett/nav/blob/a21c6b2b2910b1aaf035387f8a96711045a4b67a/python/nav/mibs/mibretriever.py#L580-L610

The instance list is still a plain list of tuples of (description, community), and if we are to extend these tuples, they should probably be more formalized as a NamedTuple and annotated properly in modern Python.

lunkwill42 avatar May 15 '24 14:05 lunkwill42