- Support for newer models and Nortel BladeCenter Layer2-3 GbE Switch Modules.

- Support for new VLAN read methods.
This commit is contained in:
Eric Miller
2007-12-07 04:18:32 +00:00
parent 98e6693525
commit a2ab73c24a

View File

@@ -34,73 +34,99 @@ $VERSION = '1.07';
use strict; use strict;
use Exporter; use Exporter;
use SNMP::Info;
use SNMP::Info::Layer3; use SNMP::Info::Layer3;
use SNMP::Info::Bridge;
use vars qw/$VERSION $DEBUG %GLOBALS %FUNCS $INIT %MIBS %MUNGE /; 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//; @SNMP::Info::Layer3::AlteonAD::EXPORT_OK = qw//;
%MIBS = ( %MIBS = (
%SNMP::Info::MIBS,
%SNMP::Info::Layer3::MIBS, %SNMP::Info::Layer3::MIBS,
%SNMP::Info::Bridge::MIBS, 'ALTEON-ROOT-MIB' => 'aceswitch184',
'ALTEON-TIGON-SWITCH-MIB' => 'agSoftwareVersion', 'ALTEON-TIGON-SWITCH-MIB' => 'hwPowerSupplyStatus',
'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt', 'ALTEON-CHEETAH-SWITCH-MIB' => 'hwFanStatus',
'ALTEON-TS-NETWORK-MIB' => 'agPortTableMaxEnt', 'ALTEON-TS-PHYSICAL-MIB' => 'agPortTableMaxEnt',
'ALTEON-CS-PHYSICAL-MIB' => 'vlanCurCfgLearn',
'ALTEON-TS-NETWORK-MIB' => 'ripCurCfgSupply',
'ALTEON-CHEETAH-NETWORK-MIB' => 'ripCurCfgIntfSupply',
); );
%GLOBALS = ( %GLOBALS = (
%SNMP::Info::GLOBALS,
%SNMP::Info::Layer3::GLOBALS, %SNMP::Info::Layer3::GLOBALS,
%SNMP::Info::Bridge::GLOBALS, 'old_sw_ver' => 'ALTEON_TIGON_SWITCH_MIB__agSoftwareVersion',
'sw_ver' => 'agSoftwareVersion', 'new_sw_ver' => 'ALTEON_CHEETAH_SWITCH_MIB__agSoftwareVersion',
'tftp_action' => 'agTftpAction', 'old_tftp_action' => 'ALTEON_TIGON_SWITCH_MIB__agTftpAction',
'tftp_host' => 'agTftpServer', 'new_tftp_action' => 'ALTEON_CHEETAH_SWITCH_MIB__agTftpAction',
'tftp_file' => 'agTftpCfgFileName', 'old_tftp_host' => 'ALTEON_TIGON_SWITCH_MIB__agTftpServer',
'tftp_result' => 'agTftpLastActionStatus', '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 = ( %FUNCS = (
%SNMP::Info::FUNCS,
%SNMP::Info::Layer3::FUNCS, %SNMP::Info::Layer3::FUNCS,
%SNMP::Info::Bridge::FUNCS,
# From agPortCurCfgTable # From agPortCurCfgTable
'ag_p_cfg_idx' => 'agPortCurCfgIndx', 'old_ag_p_cfg_idx' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgIndx',
'ag_p_cfg_pref' => 'agPortCurCfgPrefLink', 'new_ag_p_cfg_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgIndx',
'ag_p_cfg_pvid' => 'agPortCurCfgPVID', 'old_ag_p_cfg_pref' => 'agPortCurCfgPrefLink',
'ag_p_cfg_fe_auto' => 'agPortCurCfgFastEthAutoNeg', 'new_ag_p_cfg_pref' => 'agPortCurCfgPreferred',
'ag_p_cfg_fe_mode' => 'agPortCurCfgFastEthMode', 'old_ag_p_cfg_pvid' => 'ALTEON_TS_PHYSICAL_MIB__agPortCurCfgPVID',
'ag_p_cfg_ge_auto' => 'agPortCurCfgGigEthAutoNeg', 'new_ag_p_cfg_pvid' => 'ALTEON_CHEETAH_SWITCH_MIB__agPortCurCfgPVID',
'ag_p_cfg_name' => 'agPortCurCfgPortName', '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 # From portInfoTable
'p_info_idx' => 'portInfoIndx', 'old_p_info_idx' => 'ALTEON_TS_PHYSICAL_MIB__portInfoIndx',
'p_info_mode' => 'portInfoMode', 'new_p_info_idx' => 'ALTEON_CHEETAH_SWITCH_MIB__portInfoIndx',
# From portInfoTable 'old_p_info_mode' => 'ALTEON_TS_PHYSICAL_MIB__portInfoMode',
'ip_cfg_vlan' => 'ipCurCfgIntfVlan', '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 = ( %MUNGE = (
%SNMP::Info::MUNGE,
%SNMP::Info::Layer3::MUNGE, %SNMP::Info::Layer3::MUNGE,
%SNMP::Info::Bridge::MUNGE,
); );
sub model { sub model {
my $alteon = shift; my $alteon = shift;
my $desc = $alteon->description();
return undef unless defined $desc;
return 'AD2' if ($desc =~ /AD2/); my $id = $alteon->id();
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/);
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 { sub vendor {
@@ -108,12 +134,12 @@ sub vendor {
} }
sub os { sub os {
return 'webos'; return 'alteon';
} }
sub os_ver { sub os_ver {
my $alteon = shift; my $alteon = shift;
my $version = $alteon->sw_ver(); my $version = $alteon->new_sw_ver() || $alteon->old_sw_ver();
return undef unless defined $version; return undef unless defined $version;
return $version; return $version;
@@ -121,8 +147,9 @@ sub os_ver {
sub interfaces { sub interfaces {
my $alteon = shift; my $alteon = shift;
my $interfaces = $alteon->i_index(); my $interfaces = $alteon->i_index();
my $descriptions = $alteon->i_description(); my $descriptions = $alteon->i_description();
my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max();
my %interfaces = (); my %interfaces = ();
foreach my $iid (keys %$interfaces){ foreach my $iid (keys %$interfaces){
@@ -132,8 +159,10 @@ sub interfaces {
if ($desc =~ /(^net\d+)/) { if ($desc =~ /(^net\d+)/) {
$desc = $1; $desc = $1;
} }
elsif (($iid > 256) and ($iid < 266)) { # IP interfaces are first followed by physical, number possible
$desc = ($iid % 256); # varies by switch model
elsif (defined $ip_max and $iid > $ip_max ) {
$desc = ($iid % $ip_max);
} }
$interfaces{$iid} = $desc; $interfaces{$iid} = $desc;
} }
@@ -142,9 +171,10 @@ sub interfaces {
sub i_duplex { sub i_duplex {
my $alteon = shift; 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; my %i_duplex;
foreach my $if (keys %$p_mode){ foreach my $if (keys %$p_mode){
my $duplex = $p_mode->{$if}; my $duplex = $p_mode->{$if};
@@ -153,7 +183,7 @@ sub i_duplex {
$duplex = 'half' if $duplex =~ /half/i; $duplex = 'half' if $duplex =~ /half/i;
$duplex = 'full' if $duplex =~ /full/i; $duplex = 'full' if $duplex =~ /full/i;
my $idx = $if + 256; my $idx = $if + $ip_max if (defined $ip_max);
$i_duplex{$idx}=$duplex; $i_duplex{$idx}=$duplex;
} }
@@ -163,10 +193,11 @@ sub i_duplex {
sub i_duplex_admin { sub i_duplex_admin {
my $alteon = shift; my $alteon = shift;
my $ag_pref = $alteon->ag_p_cfg_pref(); my $ag_pref = $alteon->new_ag_p_cfg_pref() || $alteon->old_ag_p_cfg_pref() || {};
my $ag_fe_auto = $alteon->ag_p_cfg_fe_auto(); my $ag_fe_auto = $alteon->new_ag_p_cfg_fe_auto() || $alteon->old_ag_p_cfg_fe_auto() || {};
my $ag_fe_mode = $alteon->ag_p_cfg_fe_mode(); my $ag_fe_mode = $alteon->new_ag_p_cfg_fe_mode() || $alteon->old_ag_p_cfg_fe_mode() || {};
my $ag_ge_auto = $alteon->ag_p_cfg_ge_auto(); 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; my %i_duplex_admin;
foreach my $if (keys %$ag_pref){ 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 = 'full' if ($fe_mode =~ /full/i and $fe_auto =~ /off/i);
$string = 'auto' if $fe_auto =~ /on/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; $i_duplex_admin{$idx}=$string;
} }
return \%i_duplex_admin; 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 { sub i_vlan {
my $alteon = shift; my $alteon = shift;
my $ag_vlans = $alteon->ag_p_cfg_pvid(); my $ag_vlans = $alteon->new_ag_p_cfg_pvid() || $alteon->old_ag_p_cfg_pvid() || {};
my $ip_vlans = $alteon->ip_cfg_vlan(); 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; my %i_vlan;
foreach my $if (keys %$ip_vlans){ foreach my $if (keys %$ip_vlans){
@@ -211,36 +272,50 @@ sub i_vlan {
my $ag_vlanid = $ag_vlans->{$if}; my $ag_vlanid = $ag_vlans->{$if};
next unless defined $ag_vlanid; next unless defined $ag_vlanid;
my $idx = $if + 256; my $idx = $if + $ip_max if (defined $ip_max);
$i_vlan{$idx}=$ag_vlanid; $i_vlan{$idx}=$ag_vlanid;
} }
return \%i_vlan; return \%i_vlan;
} }
sub i_name { sub i_vlan_membership {
my $alteon = shift; my $alteon = shift;
my $p_name = $alteon->ag_p_cfg_name();
my %i_name; my $v_ports = $alteon->old_vlan_ports() || $alteon->new_vlan_ports() || {};
foreach my $iid (keys %$p_name){ my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max();
my $name = $p_name->{$iid};
next unless defined $name; my $i_vlan_membership = {};
my $idx = $iid + 256; foreach my $vlan (keys %$v_ports) {
$i_name{$idx} = $name; 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 { sub bp_index {
my $alteon = shift; my $alteon = shift;
my $b_index = $alteon->orig_bp_index(); my $b_index = $alteon->orig_bp_index();
my $ip_max = $alteon->new_ip_max() || $alteon->old_ip_max();
my %bp_index; my %bp_index;
foreach my $iid (keys %$b_index){ foreach my $iid (keys %$b_index){
my $port = $b_index->{$iid}; my $port = $b_index->{$iid};
next unless defined $port; next unless defined $port;
$port = $port + 256; $port = $port + $ip_max if (defined $ip_max and $iid == $ip_max);
$bp_index{$iid} = $port; $bp_index{$iid} = $port;
} }
@@ -252,8 +327,8 @@ __END__
=head1 NAME =head1 NAME
SNMP::Info::Layer3::AlteonAD - Perl5 Interface to Nortel Networks' Alteon Ace SNMP::Info::Layer3::AlteonAD - SNMP Interface to Nortel Alteon Layer 2-7
Director Series Layer 2-7 Switches. Switches.
=head1 AUTHOR =head1 AUTHOR
@@ -277,8 +352,8 @@ Eric Miller
=head1 DESCRIPTION =head1 DESCRIPTION
Abstraction subclass for Layer 2-7 load balancing switches running Nortel Networks' Abstraction subclass for Nortel Alteon Series Layer 2-7 load balancing switches
Alteon Web OS Traffic Control Software. and Nortel BladeCenter Layer2-3 GbE Switch Modules.
For speed or debugging purposes you can call the subclass directly, but not after For speed or debugging purposes you can call the subclass directly, but not after
determining a more specific class using the method above. determining a more specific class using the method above.
@@ -289,9 +364,7 @@ determining a more specific class using the method above.
=over =over
=item SNMP::Info =item SNMP::Info::Layer3
=item SNMP::Info::Bridge
=back =back
@@ -299,25 +372,23 @@ determining a more specific class using the method above.
=over =over
=item ALTEON-ROOT-MIB
=item ALTEON-TIGON-SWITCH-MIB =item ALTEON-TIGON-SWITCH-MIB
=item ALTEON-TS-PHYSICAL-MIB =item ALTEON-TS-PHYSICAL-MIB
=item ALTEON-TS-NETWORK-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 =item ALTEON-CHEETAH-SWITCH-MIB
contract status. Go to http://www.nortelnetworks.com Techninal Support,
Browse Technical Support, Select by Product Families, Alteon, =item ALTEON-CHEETAH-NETWORK-MIB
Alteon Web OS Traffic Control Software, Software. Filter on mibs and download
the latest version's archive.
=item Inherited Classes' MIBs =item Inherited Classes' MIBs
See L<SNMP::Info/"Required MIBs"> for its own MIB requirements. See L<SNMP::Info::Layer3/"Required MIBs"> for its own MIB requirements.
See L<SNMP::Info::Bridge/"Required MIBs"> for its own MIB requirements.
=back =back
@@ -329,7 +400,9 @@ These are methods that return scalar value from SNMP
=item $alteon->model() =item $alteon->model()
Returns the model extracted from B<sysDescr> 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() =item $alteon->vendor()
@@ -337,7 +410,7 @@ Returns 'nortel'
=item $alteon->os() =item $alteon->os()
Returns 'webos' Returns 'alteon'
=item $alteon->os_ver() =item $alteon->os_ver()
@@ -361,13 +434,9 @@ Returns the software version reported by B<agSoftwareVersion>
=back =back
=head2 Globals imported from SNMP::Info =head2 Globals imported from SNMP::Info::Layer3
See documentation in L<SNMP::Info/"GLOBALS"> for details. See documentation in L<SNMP::Info::Layer3/"GLOBALS"> for details.
=head2 Globals imported from SNMP::Info::Bridge
See documentation in L<SNMP::Info::Bridge/"GLOBALS"> for details.
=head1 TABLE METHODS =head1 TABLE METHODS
@@ -395,7 +464,26 @@ Returns reference to hash. Maps port admin duplexes to IIDs.
=item $alteon->i_vlan() =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() =item $alteon->i_name()
@@ -407,12 +495,8 @@ Returns a mapping between ifIndex and the Bridge Table.
=back =back
=head2 Table Methods imported from SNMP::Info =head2 Table Methods imported from SNMP::Info::Layer3
See documentation in L<SNMP::Info/"TABLE METHODS"> for details. See documentation in L<SNMP::Info::Layer3/"TABLE METHODS"> for details.
=head2 Table Methods imported from SNMP::Info::Bridge
See documentation in L<SNMP::Info::Bridge/"TABLE METHODS"> for details.
=cut =cut