From a2ab73c24a38eb413132fbe210583c36979c7078 Mon Sep 17 00:00:00 2001 From: Eric Miller <> Date: Fri, 7 Dec 2007 04:18:32 +0000 Subject: [PATCH] - Support for newer models and Nortel BladeCenter Layer2-3 GbE Switch Modules. - Support for new VLAN read methods. --- Info/Layer3/AlteonAD.pm | 282 ++++++++++++++++++++++++++-------------- 1 file changed, 183 insertions(+), 99 deletions(-) diff --git a/Info/Layer3/AlteonAD.pm b/Info/Layer3/AlteonAD.pm index f952d07c..094a11a1 100644 --- a/Info/Layer3/AlteonAD.pm +++ b/Info/Layer3/AlteonAD.pm @@ -34,73 +34,99 @@ $VERSION = '1.07'; use strict; use Exporter; -use SNMP::Info; use SNMP::Info::Layer3; -use SNMP::Info::Bridge; use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE /; -@SNMP::Info::Layer3::AlteonAD::ISA = qw/SNMP::Info SNMP::Info::Layer3 SNMP::Info::Bridge Exporter/; +@SNMP::Info::Layer3::AlteonAD::ISA = qw/SNMP::Info::Layer3 Exporter/; @SNMP::Info::Layer3::AlteonAD::EXPORT_OK = qw//; %MIBS = ( - %SNMP::Info::MIBS, %SNMP::Info::Layer3::MIBS, - %SNMP::Info::Bridge::MIBS, - 'ALTEON-TIGON-SWITCH-MIB' => 'agSoftwareVersion', - 'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt', - 'ALTEON-TS-NETWORK-MIB' => 'agPortTableMaxEnt', + 'ALTEON-ROOT-MIB' => 'aceswitch184', + 'ALTEON-TIGON-SWITCH-MIB' => 'hwPowerSupplyStatus', + 'ALTEON-CHEETAH-SWITCH-MIB' => 'hwFanStatus', + 'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt', + 'ALTEON-CS-PHYSICAL-MIB' => 'vlanCurCfgLearn', + 'ALTEON-TS-NETWORK-MIB' => 'ripCurCfgSupply', + 'ALTEON-CHEETAH-NETWORK-MIB' => 'ripCurCfgIntfSupply', ); %GLOBALS = ( - %SNMP::Info::GLOBALS, %SNMP::Info::Layer3::GLOBALS, - %SNMP::Info::Bridge::GLOBALS, - 'sw_ver' => 'agSoftwareVersion', - 'tftp_action' => 'agTftpAction', - 'tftp_host' => 'agTftpServer', - 'tftp_file' => 'agTftpCfgFileName', - 'tftp_result' => 'agTftpLastActionStatus', + 'old_sw_ver' => 'ALTEON_TIGON_SWITCH_MIB__agSoftwareVersion', + 'new_sw_ver' => 'ALTEON_CHEETAH_SWITCH_MIB__agSoftwareVersion', + 'old_tftp_action' => 'ALTEON_TIGON_SWITCH_MIB__agTftpAction', + 'new_tftp_action' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpAction', + 'old_tftp_host' => 'ALTEON_TIGON_SWITCH_MIB__agTftpServer', + 'new_tftp_host' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpServer', + 'old_tftp_file' => 'ALTEON_TIGON_SWITCH_MIB__agTftpCfgFileName', + 'new_tftp_file' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpCfgFileName', + 'old_tftp_result' => 'ALTEON_TIGON_SWITCH_MIB__agTftpLastActionStatus', + 'new_tftp_result' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpLastActionStatus', + 'old_ip_max' => 'ALTEON_TS_NETWORK_MIB__ipInterfaceTableMax', + 'new_ip_max' => 'ALTEON_CHEETAH_NETWORK_MIB__ipInterfaceTableMax', ); %FUNCS = ( - %SNMP::Info::FUNCS, %SNMP::Info::Layer3::FUNCS, - %SNMP::Info::Bridge::FUNCS, # From agPortCurCfgTable - 'ag_p_cfg_idx' => 'agPortCurCfgIndx', - 'ag_p_cfg_pref' => 'agPortCurCfgPrefLink', - 'ag_p_cfg_pvid' => 'agPortCurCfgPVID', - 'ag_p_cfg_fe_auto' => 'agPortCurCfgFastEthAutoNeg', - 'ag_p_cfg_fe_mode' => 'agPortCurCfgFastEthMode', - 'ag_p_cfg_ge_auto' => 'agPortCurCfgGigEthAutoNeg', - 'ag_p_cfg_name' => 'agPortCurCfgPortName', + 'old_ag_p_cfg_idx' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgIndx', + 'new_ag_p_cfg_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgIndx', + 'old_ag_p_cfg_pref' => 'agPortCurCfgPrefLink', + 'new_ag_p_cfg_pref' => 'agPortCurCfgPreferred', + 'old_ag_p_cfg_pvid' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPVID', + 'new_ag_p_cfg_pvid' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgPVID', + 'old_ag_p_cfg_fe_auto' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgFastEthAutoNeg', + 'new_ag_p_cfg_fe_auto' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgFastEthAutoNeg', + 'old_ag_p_cfg_fe_mode' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgFastEthMode', + 'new_ag_p_cfg_fe_mode' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgFastEthMode', + 'old_ag_p_cfg_ge_auto' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgGigEthAutoNeg', + 'new_ag_p_cfg_ge_auto' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgGigEthAutoNeg', + 'old_ag_p_cfg_name' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPortName', + 'new_ag_p_cfg_name' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgPortName', # From portInfoTable - 'p_info_idx' => 'portInfoIndx', - 'p_info_mode' => 'portInfoMode', - # From portInfoTable - 'ip_cfg_vlan' => 'ipCurCfgIntfVlan', + 'old_p_info_idx' => 'ALTEON_TS_PHYSICAL_MIB__portInfoIndx', + 'new_p_info_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__portInfoIndx', + 'old_p_info_mode' => 'ALTEON_TS_PHYSICAL_MIB__portInfoMode', + 'new_p_info_mode' => 'ALTEON_CHEETAH_SWITCH_MIB__portInfoMode', + # From ipCurCfgIntfTable + 'old_ip_cfg_vlan' => 'ALTEON_TS_NETWORK_MIB__ipCurCfgIntfVlan', + 'new_ip_cfg_vlan' => 'ALTEON_CHEETAH_NETWORK_MIB__ipCurCfgIntfVlan', + # From vlanCurCfgTable + 'old_vlan_id' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgVlanId', + 'new_vlan_id' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgVlanId', + 'old_vlan_state' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgState', + 'new_vlan_state' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgState', + 'old_vlan_name' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgVlanName', + 'new_vlan_name' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgVlanName', + 'old_vlan_ports' => 'ALTEON_TS_PHYSICAL_MIB__vlanCurCfgPorts', + 'new_vlan_ports' => 'ALTEON_CS_PHYSICAL_MIB__vlanCurCfgPorts', ); %MUNGE = ( - %SNMP::Info::MUNGE, %SNMP::Info::Layer3::MUNGE, - %SNMP::Info::Bridge::MUNGE, ); sub model { my $alteon = shift; - my $desc = $alteon->description(); - return undef unless defined $desc; - return 'AD2' if ($desc =~ /AD2/); - return 'AD3' if ($desc =~ /AD3/); - return 'AD4' if ($desc =~ /AD4/); - return '180' if ($desc =~ /180/); - return '183' if ($desc =~ /183/); - return '184' if ($desc =~ /184/); + my $id = $alteon->id(); - return $desc; + unless (defined $id){ + print " SNMP::Info::Layer3::AlteonAD::model() - Device does not support sysObjectID\n" if $alteon->debug(); + return undef; + } + + my $model = &SNMP::translateObj($id); + + return $id unless defined $model; + + $model =~ s/^aceswitch//; + $model =~ s/^acedirector/AD/; + $model =~ s/^(copper|fiber)Module/BladeCenter GbESM/; + + return $model; } sub vendor { @@ -108,12 +134,12 @@ sub vendor { } sub os { - return 'webos'; + return 'alteon'; } sub os_ver { my $alteon = shift; - my $version = $alteon->sw_ver(); + my $version = $alteon->new_sw_ver() || $alteon->old_sw_ver(); return undef unless defined $version; return $version; @@ -121,8 +147,9 @@ sub os_ver { sub interfaces { my $alteon = shift; - my $interfaces = $alteon->i_index(); + my $interfaces = $alteon->i_index(); my $descriptions = $alteon->i_description(); + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %interfaces = (); foreach my $iid (keys %$interfaces){ @@ -132,8 +159,10 @@ sub interfaces { if ($desc =~ /(^net\d+)/) { $desc = $1; } - elsif (($iid > 256) and ($iid < 266)) { - $desc = ($iid % 256); + # IP interfaces are first followed by physical, number possible + # varies by switch model + elsif (defined $ip_max and $iid > $ip_max ) { + $desc = ($iid % $ip_max); } $interfaces{$iid} = $desc; } @@ -142,9 +171,10 @@ sub interfaces { sub i_duplex { my $alteon = shift; - - my $p_mode = $alteon->p_info_mode(); - + + my $p_mode = $alteon->new_p_info_mode() || $alteon->old_p_info_mode() || {}; + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); + my %i_duplex; foreach my $if (keys %$p_mode){ my $duplex = $p_mode->{$if}; @@ -153,7 +183,7 @@ sub i_duplex { $duplex = 'half' if $duplex =~ /half/i; $duplex = 'full' if $duplex =~ /full/i; - my $idx = $if + 256; + my $idx = $if + $ip_max if (defined $ip_max); $i_duplex{$idx}=$duplex; } @@ -163,10 +193,11 @@ sub i_duplex { sub i_duplex_admin { my $alteon = shift; - my $ag_pref = $alteon->ag_p_cfg_pref(); - my $ag_fe_auto = $alteon->ag_p_cfg_fe_auto(); - my $ag_fe_mode = $alteon->ag_p_cfg_fe_mode(); - my $ag_ge_auto = $alteon->ag_p_cfg_ge_auto(); + my $ag_pref = $alteon->new_ag_p_cfg_pref() || $alteon->old_ag_p_cfg_pref() || {}; + my $ag_fe_auto = $alteon->new_ag_p_cfg_fe_auto() || $alteon->old_ag_p_cfg_fe_auto() || {}; + my $ag_fe_mode = $alteon->new_ag_p_cfg_fe_mode() || $alteon->old_ag_p_cfg_fe_mode() || {}; + my $ag_ge_auto = $alteon->new_ag_p_cfg_ge_auto() || $alteon->old_ag_p_cfg_ge_auto() || {}; + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %i_duplex_admin; foreach my $if (keys %$ag_pref){ @@ -186,19 +217,49 @@ sub i_duplex_admin { $string = 'full' if ($fe_mode =~ /full/i and $fe_auto =~ /off/i); $string = 'auto' if $fe_auto =~ /on/i; } - my $idx = $if + 256; + my $idx = $if + $ip_max if (defined $ip_max); $i_duplex_admin{$idx}=$string; } return \%i_duplex_admin; } +sub i_name { + my $alteon = shift; + + my $p_name = $alteon->new_ag_p_cfg_name() || $alteon->old_ag_p_cfg_name() || {}; + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); + + my %i_name; + foreach my $iid (keys %$p_name){ + my $name = $p_name->{$iid}; + next unless defined $name; + my $idx = $iid + $ip_max if (defined $ip_max); + $i_name{$idx} = $name; + } + return \%i_name; +} + +sub v_index { + my $alteon = shift; + my $partial = shift; + + return $alteon->new_vlan_id($partial) || $alteon->old_vlan_id($partial); +} + +sub v_name { + my $alteon = shift; + my $partial = shift; + + return $alteon->new_vlan_name($partial) || $alteon->old_vlan_name($partial); +} + sub i_vlan { my $alteon = shift; - my $ag_vlans = $alteon->ag_p_cfg_pvid(); - my $ip_vlans = $alteon->ip_cfg_vlan(); - + my $ag_vlans = $alteon->new_ag_p_cfg_pvid() || $alteon->old_ag_p_cfg_pvid() || {}; + my $ip_vlans = $alteon->new_ip_cfg_vlan() || $alteon->old_ip_cfg_vlan() || {}; + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %i_vlan; foreach my $if (keys %$ip_vlans){ @@ -211,36 +272,50 @@ sub i_vlan { my $ag_vlanid = $ag_vlans->{$if}; next unless defined $ag_vlanid; - my $idx = $if + 256; + my $idx = $if + $ip_max if (defined $ip_max); $i_vlan{$idx}=$ag_vlanid; } return \%i_vlan; } -sub i_name { +sub i_vlan_membership { my $alteon = shift; - my $p_name = $alteon->ag_p_cfg_name(); - my %i_name; - foreach my $iid (keys %$p_name){ - my $name = $p_name->{$iid}; - next unless defined $name; - my $idx = $iid + 256; - $i_name{$idx} = $name; + my $v_ports = $alteon->old_vlan_ports() || $alteon->new_vlan_ports() || {}; + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); + + my $i_vlan_membership = {}; + foreach my $vlan (keys %$v_ports) { + my $portlist = [split(//, unpack("B*", $v_ports->{$vlan}))]; + my $ret = []; + + # Convert portlist bit array to ifIndex array + for (my $i = 0; $i <= scalar(@$portlist); $i++) { + my $idx = $i + $ip_max if (defined $ip_max); + push(@{$ret}, $idx) if (@$portlist[$i]); + } + + #Create HoA ifIndex -> VLAN array + foreach my $port (@{$ret}) { + push(@{$i_vlan_membership->{$port}}, $vlan); + } } - return \%i_name; + return $i_vlan_membership; } -# Bridge MIB does not map Bridge Port to ifIndex correctly +# Bridge MIB does not map Bridge Port to ifIndex correctly on some code +# versions sub bp_index { my $alteon = shift; + my $b_index = $alteon->orig_bp_index(); + my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max(); my %bp_index; foreach my $iid (keys %$b_index){ my $port = $b_index->{$iid}; next unless defined $port; - $port = $port + 256; + $port = $port + $ip_max if (defined $ip_max and $iid == $ip_max); $bp_index{$iid} = $port; } @@ -252,8 +327,8 @@ __END__ =head1 NAME -SNMP::Info::Layer3::AlteonAD - Perl5 Interface to Nortel Networks' Alteon Ace -Director Series Layer 2-7 Switches. +SNMP::Info::Layer3::AlteonAD - SNMP Interface to Nortel Alteon Layer 2-7 +Switches. =head1 AUTHOR @@ -277,8 +352,8 @@ Eric Miller =head1 DESCRIPTION -Abstraction subclass for Layer 2-7 load balancing switches running Nortel Networks' -Alteon Web OS Traffic Control Software. +Abstraction subclass for Nortel Alteon Series Layer 2-7 load balancing switches +and Nortel BladeCenter Layer2-3 GbE Switch Modules. For speed or debugging purposes you can call the subclass directly, but not after determining a more specific class using the method above. @@ -289,9 +364,7 @@ determining a more specific class using the method above. =over -=item SNMP::Info - -=item SNMP::Info::Bridge +=item SNMP::Info::Layer3 =back @@ -299,25 +372,23 @@ determining a more specific class using the method above. =over +=item ALTEON-ROOT-MIB + =item ALTEON-TIGON-SWITCH-MIB =item ALTEON-TS-PHYSICAL-MIB =item ALTEON-TS-NETWORK-MIB -MIBs can be found on the CD that came with your product. +=item ALTEON-CS-PHYSICAL-MIB -Or, they can be downloaded directly from Nortel Networks regardless of support -contract status. Go to http://www.nortelnetworks.com Techninal Support, -Browse Technical Support, Select by Product Families, Alteon, -Alteon Web OS Traffic Control Software, Software. Filter on mibs and download -the latest version's archive. +=item ALTEON-CHEETAH-SWITCH-MIB + +=item ALTEON-CHEETAH-NETWORK-MIB =item Inherited Classes' MIBs -See L for its own MIB requirements. - -See L for its own MIB requirements. +See L for its own MIB requirements. =back @@ -329,7 +400,9 @@ These are methods that return scalar value from SNMP =item $alteon->model() -Returns the model extracted from B +Returns model type. Checks $alteon->id() against the ALTEON-ROOT-MIB and +then parses out aceswitch, replaces acedirector with AD, and replaces +copperModule/fiberModule with BladeCenter GbESM. =item $alteon->vendor() @@ -337,7 +410,7 @@ Returns 'nortel' =item $alteon->os() -Returns 'webos' +Returns 'alteon' =item $alteon->os_ver() @@ -361,13 +434,9 @@ Returns the software version reported by B =back -=head2 Globals imported from SNMP::Info +=head2 Globals imported from SNMP::Info::Layer3 -See documentation in L for details. - -=head2 Globals imported from SNMP::Info::Bridge - -See documentation in L for details. +See documentation in L for details. =head1 TABLE METHODS @@ -395,7 +464,26 @@ Returns reference to hash. Maps port admin duplexes to IIDs. =item $alteon->i_vlan() -Returns reference to hash. Maps port VLAN ID to IIDs. +Returns a mapping between ifIndex and the PVID or default VLAN. + +=item $alteon->i_vlan_membership() + +Returns reference to hash of arrays: key = ifIndex, value = array of VLAN IDs. +These are the VLANs which are members of the egress list for the port. + + Example: + my $interfaces = $alteon->interfaces(); + my $vlans = $alteon->i_vlan_membership(); + + foreach my $iid (sort keys %$interfaces) { + my $port = $interfaces->{$iid}; + my $vlan = join(',', sort(@{$vlans->{$iid}})); + print "Port: $port VLAN: $vlan\n"; + } + +=item $alteon->v_name() + +Human-entered name for vlans. =item $alteon->i_name() @@ -407,12 +495,8 @@ Returns a mapping between ifIndex and the Bridge Table. =back -=head2 Table Methods imported from SNMP::Info +=head2 Table Methods imported from SNMP::Info::Layer3 -See documentation in L for details. - -=head2 Table Methods imported from SNMP::Info::Bridge - -See documentation in L for details. +See documentation in L for details. =cut