nonbulk: use GETNEXT instead of GET for the first packet#53
Open
dmueckli wants to merge 1 commit into
Open
Conversation
The first packet in NONBULK mode used a plain GET against a hardcoded instance (ifDescr.1 etc.), while every subsequent packet already used GETNEXT against the base OID. This meant NONBULK mode silently failed (noSuchName under SNMPv1, zero interfaces found) on any device whose first ifIndex is not 1, instead of walking the table as documented. This aligns the first packet with the GETNEXT-based walk already used for all following packets. No behavior change for devices that start at ifIndex 1 (verified against a local snmpd v1 agent - old and new binary produce byte-identical output); fixes the case of devices with a non-contiguous or non-1-starting ifIndex range (reproduced with snmpsim against a simulated agent starting at ifIndex 5). No change to session setup (community/v1 forcing in start_session(), SNMPv3 handling in start_session_v3()) or to default/cisco/bintec modes.
e016196 to
2cda69e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
NONBULKmode's very first SNMP request used a plainGETagainst ahardcoded instance (e.g.
ifDescr.1), while every subsequent packet in thesame walk already used
GETNEXTagainst the base OID. This meantNONBULKmode silently failed on any device whose first
ifIndexis not1-instead of performing the "traditional tree-walk" the mode is documented to
do (see README /
-musage text).Symptom on affected devices:
noSuchNamefor the whole PDU (since v1has no per-varbind exception values), and the plugin aborts with
Error in packet / Reason: (noSuchName) There is no such variable name in this MIB.(
noSuchInstance), which the plugin doesn't recognize as an error, so itsilently reports zero interfaces found instead of walking the table.
This PR makes the first packet consistent with all following packets:
GETNEXTon the base OID, no hardcoded instance, noGETBULK.Root cause
snmp_bulkget.c,create_pdu():while the main loop's follow-up packets already do:
check_interfaces.c,main(): because the first packet used a plainGET, it required a fixed-instance OID list (oid_if_get,oid_alias_get,oid_names_get- all ending in a hardcoded.1/.0instance), instead of the base OIDs (
oid_if_bulkgetetc.) used bydefaultmode.Changes
snmp_bulkget.c:create_pdu()now createsSNMP_MSG_GETNEXT(notSNMP_MSG_GET) forNONBULK, matching the follow-up packets.check_interfaces.c:NONBULKnow shares the same base OID arrays asdefaultmode (oid_if_bulkget,oid_alias_bulkget,oid_names_bulkget) instead of the fixed-instance*_getarrays. Thechoice between
GETBULKandGETNEXTis already handled bycreate_pdu()/config.mode, so no further branching is needed here.What did NOT change
start_session()still forcesSNMP_VERSION_1forNONBULKon the community-string path;start_session_v3()is unchanged and used whenever-uis given,independent of mode.
default,cisco, andbintecmodes are not touched by this diff.create_request()(per-interface counter fetch) is unchanged.NONBULKstill never issuesGETBULK, for either community or SNMPv3sessions - this was already true before this patch and remains true
after it.
Testing
1. Regression check: devices starting at ifIndex 1 (the common case)
Local
snmpd(v1), default single-NIC setup,ifIndexstarts at1:→ empty diff, byte-identical output between the pre-patch and post-patch
binary.
2. Bug reproduction: device with a non-1-starting ifIndex range
Simulated with
snmpsim(communityifindex-gap, two interfaces atifIndex5 and 6 instead of 1/2):Before the patch:
After the patch:
Motivation / real-world trigger
Encountered with an Ekinops router whose
GETBULKimplementation loopsindefinitely by always restarting from index
0instead of honoring therequested starting OID.
-m nonbulkis the documented workaround forbroken
GETBULKimplementations, but it turned out to be broken itselffor devices that don't start numbering interfaces at
ifIndex1 - whichis common among devices with buggy SNMP stacks in the first place, and
was indeed the case here.
This fix was verified both against a synthetic
snmpsimfixture (seebelow) and against the actual Ekinops router in production: with the
patch,
-m nonbulknow successfully retrieves the interface list whereit previously returned zero interfaces.
Notes for reviewers
create_request()treats
SNMP_ERR_NOSUCHNAME(SNMPv1) as success even though thereturned varbinds are then empty placeholders, which can make a
device look like all counters are
0/interfaces are "down" if asingle one of the requested standard OIDs (e.g.
ifInDiscards) isn'tsupported by that device. Happy to open a separate issue for this if
useful - keeping this PR focused on the
NONBULKwalk fix.