SNMP::Info method resolution issue
Closed this issue · 6 comments
As described on IRC: after upgrading our primary management server, suddenly I'm running into problems with SNMP::Info methods that "bleed" from one device class to another.
The situation arises when our script polls devices from different device classes. I managed to create a fairly minimal reproduction script, with the v_name() method as an example.
I called it 'snmp_info_mro_bug.pl'; code is below.
Simply run the script with multiple pairs of hostname/ip and SNMP community, eg './snmp_info_mro_bug.pl switch1 public switch2 private'
or something like that. When 'switch1' is an HP device (Layer2::HP) and 'switch2' is Cisco (Layer3::Cisco), I see on both occasions that v_name() is resolved to Q-BRIDGE-MIB::dot1qVlanStaticName. When I switch the order of switches, suddenly both devices are polled with v_name() resolving to CISCO-VTP-MIB::vtpVlanName. I would expect the order not to matter, and the HP device to always use Q-BRIDGE-MIB for the v_name() method and the Cisco to always use VTP-MIB.
#!/usr/bin/perl -w
use strict;
use warnings;
use SNMP::Info;
use Data::Dumper;
my @mibdirs = (
'/usr/local/netdisco/mibs',
'/usr/local/netdisco/mibs/rfc',
'/usr/local/netdisco/mibs/cisco',
'/usr/local/netdisco/mibs/hp',
'/usr/local/netdisco/mibs/net-snmp',
);
while (@ARGV) {
printf("%s\n", '=' x 40);
my $ip = shift @ARGV;
my $com = shift @ARGV;
my $info = &connect($ip, $com);
print Dumper($info->v_name());
printf("%s\n", '=' x 40);
}
exit;
### end of main ###
sub connect {
my $dns = shift;
my $comm = shift;
my $ver = shift || 2;
my $info = new SNMP::Info(
AutoSpecify => 1,
Debug => 1,
SNMPDebug => 1,,
BulkWalk => 1,
MibDirs => \@mibdirs,
DestHost => $dns,
Community => $comm,
Version => $ver,
IgnoreNetSNMPConf => 1,
);
return $info;
}
Cisco -> HP order:
netmgt@linux469:~/bin$ ./snmp_info_mro_bug.pl simon rocommu sw1-beachveld rocummu
========================================
SNMP::Info::_global layers : SNMPv2-MIB::sysServices.0 : .1.3.6.1.2.1.1.7.0
SNMP::Info::_global description : SNMPv2-MIB::sysDescr.0 : .1.3.6.1.2.1.1.1.0
SNMP::Info::_global id : SNMPv2-MIB::sysObjectID.0 : .1.3.6.1.2.1.1.2.0
SNMP::Info 3.70
SNMP::Info::device_type() layers:01001110 id:9 sysDescr:"Cisco IOS Software, c6848x Software (c6848x-ADVENTERPRISEK9-M), Version 15.5(1)SY5, RELEASE SOFTWARE (fc3) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2020 by Cisco Systems, Inc. Compiled Tue 04-Feb-20 14:27 by prod_rel_team"
SNMP::Info::specify() - Changed Class to SNMP::Info::Layer3::Cisco.
SNMP::Info::_load_attr v_name : CISCO-VTP-MIB::vtpVlanName : .1.3.6.1.4.1.9.9.46.1.3.1.1.4
$VAR1 = {
'1.21' => 'VLAN0021',
'1.1' => 'default',
'1.16' => 'VLAN0016',
'1.11' => 'VLAN0011',
'1.18' => 'VLAN0018',
'1.17' => 'VLAN0017',
'1.12' => 'VLAN0012',
'1.22' => 'VLAN0022',
'1.13' => 'VLAN0013',
'1.23' => 'VLAN0023',
'1.1002' => 'fddi-default',
'1.19' => 'VLAN0019',
'1.15' => 'VLAN0015',
'1.1004' => 'fddinet-default',
'1.20' => 'VLAN0020',
'1.1005' => 'trnet-default',
'1.14' => 'VLAN0014',
'1.1003' => 'token-ring-default'
};
========================================
========================================
SNMP::Info::_global layers : SNMPv2-MIB::sysServices.0 : .1.3.6.1.2.1.1.7.0
SNMP::Info::_global description : SNMPv2-MIB::sysDescr.0 : .1.3.6.1.2.1.1.1.0
SNMP::Info::_global id : SNMPv2-MIB::sysObjectID.0 : .1.3.6.1.2.1.1.2.0
SNMP::Info 3.70
SNMP::Info::device_type() layers:01001010 id:11 sysDescr:"Aruba JL258A 2930F-8G-PoE+-2SFP+ Switch, revision WC.16.10.0007, ROM WC.16.01.0008 (/ws/swbuildm/ajanta_qt_qaoff/code/build/lvm(swbuildm_ajanta_qt_qaoff_ajanta_qt))"
SNMP::Info::specify() - Changed Class to SNMP::Info::Layer2::HP.
SNMP::Info::_load_attr v_name : CISCO-VTP-MIB::vtpVlanName : .1.3.6.1.4.1.9.9.46.1.3.1.1.4
$VAR1 = undef;
========================================
HP -> Cisco order:
netmgt@linux469:~/bin$ ./snmp_info_mro_bug.pl sw1-beachveld rocommu simon rocommu
========================================
SNMP::Info::_global layers : SNMPv2-MIB::sysServices.0 : .1.3.6.1.2.1.1.7.0
SNMP::Info::_global description : SNMPv2-MIB::sysDescr.0 : .1.3.6.1.2.1.1.1.0
SNMP::Info::_global id : SNMPv2-MIB::sysObjectID.0 : .1.3.6.1.2.1.1.2.0
SNMP::Info 3.70
SNMP::Info::device_type() layers:01001010 id:11 sysDescr:"Aruba JL258A 2930F-8G-PoE+-2SFP+ Switch, revision WC.16.10.0007, ROM WC.16.01.0008 (/ws/swbuildm/ajanta_qt_qaoff/code/build/lvm(swbuildm_ajanta_qt_qaoff_ajanta_qt))"
SNMP::Info::specify() - Changed Class to SNMP::Info::Layer2::HP.
SNMP::Info::_load_attr v_name : Q-BRIDGE-MIB::dot1qVlanStaticName : .1.3.6.1.2.1.17.7.1.4.3.1.1
$VAR1 = {
'3164' => 'CAM-POIP',
'3101' => 'CAM-WLAN',
'3102' => 'CAM-VOIP',
'3100' => 'CAM-NMS',
'3113' => 'CAM-Print',
'3118' => 'CAM-CAM',
'3105' => 'CAM-Werkplek',
'3114' => 'CAM-IPTV',
'3108' => 'CAM-Meters',
'103' => 'Campusnet',
'1' => 'DEFAULT_VLAN'
};
========================================
========================================
SNMP::Info::_global layers : SNMPv2-MIB::sysServices.0 : .1.3.6.1.2.1.1.7.0
SNMP::Info::_global description : SNMPv2-MIB::sysDescr.0 : .1.3.6.1.2.1.1.1.0
SNMP::Info::_global id : SNMPv2-MIB::sysObjectID.0 : .1.3.6.1.2.1.1.2.0
SNMP::Info 3.70
SNMP::Info::device_type() layers:01001110 id:9 sysDescr:"Cisco IOS Software, c6848x Software (c6848x-ADVENTERPRISEK9-M), Version 15.5(1)SY5, RELEASE SOFTWARE (fc3) Technical Support: http://www.cisco.com/techsupport Copyright (c) 1986-2020 by Cisco Systems, Inc. Compiled Tue 04-Feb-20 14:27 by prod_rel_team"
SNMP::Info::specify() - Changed Class to SNMP::Info::Layer3::Cisco.
SNMP::Info::_load_attr v_name : Q-BRIDGE-MIB::dot1qVlanStaticName : .1.3.6.1.2.1.17.7.1.4.3.1.1
$VAR1 = undef;
========================================
snmp-info/lib/SNMP/Info/Layer3/C3550.pm
Lines 51 to 55 in 4852ed4
since layer2::hp includes layer3:
snmp-info/lib/SNMP/Info/Layer2/HP.pm
Lines 42 to 47 in e254412
it will depend on the loading order of snmp, which afaik i undefined:
#325 (comment)
netdisco/netdisco-mibs#104
imo the correct fix should be to refine the loading order in layer2::hp or clear cached functions when changing devices (can createa performance hit). https://metacpan.org/pod/SNMP::Info#update()
after upgrading our primary management server
site note, what version of net-snmp & such are provided after the upgrade? 5.7.3, 5.8 or 5.9?
specific in 5.9:
libsnmp:
Scan MIB directories in alphabetical order This guarantees that
e.g. mibs/RFC1213-MIB.txt is read before mibs/SNMPv2-MIB.txt. The
order in which these MIBs is read matters because both define
sysLocation but with different attributes.
#!/usr/bin/perl -w
[...]
while (@argv) {
printf("%s\n", '=' x 40);
my $ip = shift @argv;
my $com = shift @argv;
undef *SNMP::Info::v_name;
my $info = &connect($ip, $com); print Dumper($info->v_name()); printf("%s\n", '=' x 40);
}
exit;
[...]
Adding that 'undef *SNMP::Info::v_name;' line fixes it. Apparently, the v_name() method is added to the (global) Perl script symbol table, under the SNMP::Info namespace. So this is not an issue with MIB loading order, it's the first SNMP::Info instance that leaves SNMP::Info methods lingering around which are then erroneously used by newly created SNMP::Info instances in the script.
Not sure how to fix this, though... @jeneric , iirc you know a lot more about these SNMP::Info internals, hop that you can help out here?
after upgrading our primary management server
site note, what version of net-snmp & such are provided after the upgrade? 5.7.3, 5.8 or 5.9?
Just checked: it's Ubuntu 20.04.01 LTS, with net-snmp 5.8 ("5.8+dfsg-2ubuntu2.3") and Perl 5.30 ("5.30.0-9build1").
The issue doesn't seem to come from net-snmp though, I believe that it's due to SNMP::Info adding AUTOLOAD'ed methods into the SNMP::Info class symbol table.
Edit: can't explain yet why I never ran into issues with this before upgrading (or at least, didn't notice); the specific SNMP::Info bit of code that appears to be at fault was committed in 2012 and was already present in the library version that we used before upgrading. I believe that we used Perl 5.22 earlier, so maybe that made some difference.
I'm gonna say resolved, then?