Linux SNMP interface names / when are SNMP sections used?

Hi,

when fetching network interfaces from Linux hosts via SNMP, the description was always set to the name of the network hardware (e.g. “Red Hat, Inc. Device 0001” for a virtio card) from OID .1.3.6.1.2.1.2.2.1.2, but I wanted the system name (e.g. “ens18” or “eth0”) from OID .1.3.6.1.2.1.31.1.1.1.1 instead.

So maybe that’s where I turned the wrong way, but I adapted the if_fortigate check to this:

from .agent_based_api.v1 import (
    register,
    SNMPTree,
    startswith,
)
from .utils import if64

# Use ifName under the guise of ifDescr in order to make technical interface names available.
END_OIDS = if64.END_OIDS[:1] + ["31.1.1.1.1"] + if64.END_OIDS[2:]

register.snmp_section(
    name="if_linux_snmp",
    parse_function=if64.parse_if64,
    parsed_section_name="if64",
    fetch=[
        SNMPTree(
            base=if64.BASE_OID,
            oids=END_OIDS,
        ),
    ],
    detect=startswith(".1.3.6.1.2.1.1.2.0", ".1.3.6.1.4.1.8072.3.2.10"),
    supersedes=['if', 'if64'],
)

This works great for the Linux hosts! However, the “detect” doesn’t seem to work: Switches from other vendors (e.g. Ubituiqi, but even Cisco) have problems now.

Curiously, during service discovery, everything looks fine, too! But when running the checks, the interface checks all say “Item not found in monitoring data”. When running

cmk -vv --debug $HOST

I can see that it fetches the if_linux_snmp section, even though it shouldn’t, because:

$ snmpget -Oa -v2c -c $COMMUNITY $HOST .1.3.6.1.2.1.1.2.0 -On
.1.3.6.1.2.1.1.2.0 = OID: .1.3.6.1.4.1.4413

It didn’t fetch OID .1.3.6.1.2.1.31.1.1.1.1 during discovery either.

So seemingly, there is a discrepancy in what SNMP sections are fetched during discovery and during check, which I don’t yet quite understand. Can anybody explain?

I was able to work around this by disabling the if_linux_snmp SNMP section for switches (and some others), but I’m sure this will pop up again at some point, and working around this with rules will become ever more cumbersome, so I’d really like to understand what went wrong.

You tried to configure the rule “Network and switch port discovery” before you modified the code?
There you have the option to use the description (.1.3.6.1.2.1.2.2.1.2) or alias (.1.3.6.1.2.1.31.1.1.1.1).

I have, but the alias is not .1.3.6.1.2.1.31.1.1.1.1, but .1.3.6.1.2.1.31.1.1.1.18 (ifAlias) - which is empty by default in Linux (and we sometimes use it to display the string set by ip link set alias).

The only plugins using 1.3.6.1.2.1.31.1.1.1.1 by default are if_brocade_lancom and if_fortigate - hence I used if_fortigate as a base (though if_fortigate uses it as alias, not as description as I did)

Ok then it would be better to have a generic approach with not only ifDescription and ifAlias but also ifName as an selection what is wanted as service name.

Well that would be an option, of course. But the interfaces check framework is so convoluted that I wouldn’t want to introduce such a change.

So since the ifName doesn’t seem to be available natively: Do you know what I am missing regarding the detect option of my check?

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed. Contact @fayepal if you think this should be re-opened.