1602 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			1602 lines
		
	
	
		
			41 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
| # SNMP::Info::RapidCity
 | |
| #
 | |
| # Copyright (c) 2014 Eric Miller
 | |
| # All rights reserved.
 | |
| #
 | |
| # Redistribution and use in source and binary forms, with or without
 | |
| # modification, are permitted provided that the following conditions are met:
 | |
| #
 | |
| #     * Redistributions of source code must retain the above copyright notice,
 | |
| #       this list of conditions and the following disclaimer.
 | |
| #     * Redistributions in binary form must reproduce the above copyright
 | |
| #       notice, this list of conditions and the following disclaimer in the
 | |
| #       documentation and/or other materials provided with the distribution.
 | |
| #     * Neither the name of the University of California, Santa Cruz nor the
 | |
| #       names of its contributors may be used to endorse or promote products
 | |
| #       derived from this software without specific prior written permission.
 | |
| #
 | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 | |
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 | |
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 | |
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 | |
| # LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 | |
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 | |
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 | |
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 | |
| # POSSIBILITY OF SUCH DAMAGE.
 | |
| 
 | |
| package SNMP::Info::RapidCity;
 | |
| 
 | |
| use strict;
 | |
| use warnings;
 | |
| use Exporter;
 | |
| use SNMP::Info;
 | |
| 
 | |
| @SNMP::Info::RapidCity::ISA       = qw/SNMP::Info Exporter/;
 | |
| @SNMP::Info::RapidCity::EXPORT_OK = qw//;
 | |
| 
 | |
| our ($VERSION, %FUNCS, %GLOBALS, %MIBS, %MUNGE);
 | |
| 
 | |
| $VERSION = '3.73';
 | |
| 
 | |
| %MIBS = (
 | |
|     'RAPID-CITY' => 'rapidCity',
 | |
|     # These are distinct from RAPID-CITY but are potentially used by
 | |
|     # classes which inherit the RAPID-CITY class
 | |
|     'NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB'    => 'nnRstDot1dStpVersion',
 | |
|     'NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB' => 'nnMstBrgAddress',
 | |
| );
 | |
| 
 | |
| %GLOBALS = (
 | |
|     'rc_serial'    => 'rcChasSerialNumber',
 | |
|     'chassis'      => 'rcChasType',
 | |
|     'slots'        => 'rcChasNumSlots',
 | |
|     'tftp_host'    => 'rcTftpHost',
 | |
|     'tftp_file'    => 'rcTftpFile',
 | |
|     'tftp_action'  => 'rcTftpAction',
 | |
|     'tftp_result'  => 'rcTftpResult',
 | |
|     'rc_ch_rev'    => 'rcChasHardwareRevision',
 | |
|     'rc_base_mac'  => 'rc2kChassisBaseMacAddr',
 | |
|     'rc_virt_ip'   => 'rcSysVirtualIpAddr',
 | |
|     'rc_virt_mask' => 'rcSysVirtualNetMask',
 | |
| );
 | |
| 
 | |
| %FUNCS = (
 | |
| 
 | |
|     # From RAPID-CITY::rcPortTable
 | |
|     'rc_index'        => 'rcPortIndex',
 | |
|     'rc_duplex'       => 'rcPortOperDuplex',
 | |
|     'rc_duplex_admin' => 'rcPortAdminDuplex',
 | |
|     'rc_speed_admin'  => 'rcPortAdminSpeed',
 | |
|     'rc_auto'         => 'rcPortAutoNegotiate',
 | |
|     'rc_alias'        => 'rcPortName',
 | |
| 
 | |
|     # From RAPID-CITY::rc2kCpuEthernetPortTable
 | |
|     'rc_cpu_ifindex'      => 'rc2kCpuEthernetPortIfIndex',
 | |
|     'rc_cpu_admin'        => 'rc2kCpuEthernetPortAdminStatus',
 | |
|     'rc_cpu_oper'         => 'rc2kCpuEthernetPortOperStatus',
 | |
|     'rc_cpu_ip'           => 'rc2kCpuEthernetPortAddr',
 | |
|     'rc_cpu_mask'         => 'rc2kCpuEthernetPortMask',
 | |
|     'rc_cpu_auto'         => 'rc2kCpuEthernetPortAutoNegotiate',
 | |
|     'rc_cpu_duplex_admin' => 'rc2kCpuEthernetPortAdminDuplex',
 | |
|     'rc_cpu_duplex'       => 'rc2kCpuEthernetPortOperDuplex',
 | |
|     'rc_cpu_speed_admin'  => 'rc2kCpuEthernetPortAdminSpeed',
 | |
|     'rc_cpu_speed_oper'   => 'rc2kCpuEthernetPortOperSpeed',
 | |
|     'rc_cpu_mac'          => 'rc2kCpuEthernetPortMgmtMacAddr',
 | |
| 
 | |
|     # From RAPID-CITY::rcVlanPortTable
 | |
|     'rc_i_vlan_if'   => 'rcVlanPortIndex',
 | |
|     'rc_i_vlan_num'  => 'rcVlanPortNumVlanIds',
 | |
|     'rc_i_vlan'      => 'rcVlanPortVlanIds',
 | |
|     'rc_i_vlan_type' => 'rcVlanPortType',
 | |
|     'rc_i_vlan_pvid' => 'rcVlanPortDefaultVlanId',
 | |
|     'rc_i_vlan_tag'  => 'rcVlanPortPerformTagging',
 | |
| 
 | |
|     # From RAPID-CITY::rcVlanTable
 | |
|     'rc_vlan_id'      => 'rcVlanId',
 | |
|     'v_name'          => 'rcVlanName',
 | |
|     'rc_vlan_color'   => 'rcVlanColor',
 | |
|     'rc_vlan_if'      => 'rcVlanIfIndex',
 | |
|     'rc_vlan_stg'     => 'rcVlanStgId',
 | |
|     'rc_vlan_type'    => 'rcVlanType',
 | |
|     'rc_vlan_members' => 'rcVlanPortMembers',
 | |
|     'rc_vlan_no_join' => 'rcVlanNotAllowToJoin',
 | |
|     'rc_vlan_mac'     => 'rcVlanMacAddress',
 | |
|     'rc_vlan_rstatus' => 'rcVlanRowStatus',
 | |
| 
 | |
|     # From RAPID-CITY::rcIpAddrTable
 | |
|     'rc_ip_index' => 'rcIpAdEntIfIndex',
 | |
|     'rc_ip_addr'  => 'rcIpAdEntAddr',
 | |
|     'rc_ip_type'  => 'rcIpAdEntIfType',
 | |
| 
 | |
|     # From RAPID-CITY::rcChasFanTable
 | |
|     'rc_fan_op' => 'rcChasFanOperStatus',
 | |
| 
 | |
|     # From RAPID-CITY::rcChasPowerSupplyTable
 | |
|     'rc_ps_op' => 'rcChasPowerSupplyOperStatus',
 | |
| 
 | |
|     # From RAPID-CITY::rcChasPowerSupplyDetailTable
 | |
|     'rc_ps_type'   => 'rcChasPowerSupplyDetailType',
 | |
|     'rc_ps_serial' => 'rcChasPowerSupplyDetailSerialNumber',
 | |
|     'rc_ps_rev'    => 'rcChasPowerSupplyDetailHardwareRevision',
 | |
|     'rc_ps_part'   => 'rcChasPowerSupplyDetailPartNumber',
 | |
|     'rc_ps_detail' => 'rcChasPowerSupplyDetailDescription',
 | |
| 
 | |
|     # From RAPID-CITY::rcCardTable
 | |
|     'rc_c_type'   => 'rcCardType',
 | |
|     'rc_c_serial' => 'rcCardSerialNumber',
 | |
|     'rc_c_rev'    => 'rcCardHardwareRevision',
 | |
|     'rc_c_part'   => 'rcCardPartNumber',
 | |
| 
 | |
|     # From RAPID-CITY::rc2kCardTable
 | |
|     'rc2k_c_ftype'   => 'rc2kCardFrontType',
 | |
|     'rc2k_c_fdesc'   => 'rc2kCardFrontDescription',
 | |
|     'rc2k_c_fserial' => 'rc2kCardFrontSerialNum',
 | |
|     'rc2k_c_frev'    => 'rc2kCardFrontHwVersion',
 | |
|     'rc2k_c_fpart'   => 'rc2kCardFrontPartNumber',
 | |
|     'rc2k_c_fdate'   => 'rc2kCardFrontDateCode',
 | |
|     'rc2k_c_fdev'    => 'rc2kCardFrontDeviations',
 | |
|     'rc2k_c_btype'   => 'rc2kCardBackType',
 | |
|     'rc2k_c_bdesc'   => 'rc2kCardBackDescription',
 | |
|     'rc2k_c_bserial' => 'rc2kCardBackSerialNum',
 | |
|     'rc2k_c_brev'    => 'rc2kCardBackHwVersion',
 | |
|     'rc2k_c_bpart'   => 'rc2kCardBackPartNumber',
 | |
|     'rc2k_c_bdate'   => 'rc2kCardBackDateCode',
 | |
|     'rc2k_c_bdev'    => 'rc2kCardBackDeviations',
 | |
| 
 | |
|     # From RAPID-CITY::rc2kMdaCardTable
 | |
|     'rc2k_mda_type'   => 'rc2kMdaCardType',
 | |
|     'rc2k_mda_desc'   => 'rc2kMdaCardDescription',
 | |
|     'rc2k_mda_serial' => 'rc2kMdaCardSerialNum',
 | |
|     'rc2k_mda_rev'    => 'rc2kMdaCardHwVersion',
 | |
|     'rc2k_mda_part'   => 'rc2kMdaCardPartNumber',
 | |
|     'rc2k_mda_date'   => 'rc2kMdaCardDateCode',
 | |
|     'rc2k_mda_dev'    => 'rc2kMdaCardDeviations',
 | |
| 
 | |
|     # From RAPID-CITY::rcMltTable
 | |
|     'rc_mlt_ports'    => 'rcMltPortMembers',
 | |
|     'rc_mlt_index'    => 'rcMltIfIndex',
 | |
|     'rc_mlt_dp'       => 'rcMltDesignatedPort',
 | |
| 
 | |
|     # From RAPID-CITY::rcBridgeSpbmMacTable
 | |
|     'rc_spbm_fw_port'   => 'rcBridgeSpbmMacCPort',
 | |
|     'rc_spbm_fw_status' => 'rcBridgeSpbmMacStatus',
 | |
|     'rc_spbm_fw_vlan'   => 'rcBridgeSpbmMacCVlanId',
 | |
| 
 | |
|     # From RAPID-CITY::rcStgTable
 | |
|     'stp_i_id'           => 'rcStgId',
 | |
|     'rc_stp_i_mac'       => 'rcStgBridgeAddress',
 | |
|     'rc_stp_i_time'      => 'rcStgTimeSinceTopologyChange',
 | |
|     'rc_stp_i_ntop'      => 'rcStgTopChanges',
 | |
|     'rc_stp_i_root'      => 'rcStgDesignatedRoot',
 | |
|     'rc_stp_i_root_port' => 'rcStgRootPort',
 | |
|     'rc_stp_i_priority'  => 'rcStgPriority',
 | |
| 
 | |
|     # From RAPID-CITY::rcStgPortTable
 | |
|     'rc_stp_p_id'       => 'rcStgPort',
 | |
|     'stp_p_stg_id'      => 'rcStgPortStgId',
 | |
|     'rc_stp_p_priority' => 'rcStgPortPriority',
 | |
|     'rc_stp_p_state'    => 'rcStgPortState',
 | |
|     'rc_stp_p_cost'     => 'rcStgPortPathCost',
 | |
|     'rc_stp_p_root'     => 'rcStgPortDesignatedRoot',
 | |
|     'rc_stp_p_bridge'   => 'rcStgPortDesignatedBridge',
 | |
|     'rc_stp_p_port'     => 'rcStgPortDesignatedPort',
 | |
| );
 | |
| 
 | |
| %MUNGE = (
 | |
|     'rc_base_mac'     => \&SNMP::Info::munge_mac,
 | |
|     'rc_vlan_mac'     => \&SNMP::Info::munge_mac,
 | |
|     'rc_cpu_mac'      => \&SNMP::Info::munge_mac,
 | |
|     'rc_vlan_members' => \&SNMP::Info::munge_port_list,
 | |
|     'rc_vlan_no_join' => \&SNMP::Info::munge_port_list,
 | |
|     'rc_mlt_ports'    => \&SNMP::Info::munge_port_list,
 | |
|     'rc_stp_i_mac'       => \&SNMP::Info::munge_mac,
 | |
|     'rc_stp_i_root'      => \&SNMP::Info::munge_prio_mac,
 | |
|     'rc_stp_p_root'      => \&SNMP::Info::munge_prio_mac,
 | |
|     'rc_stp_p_bridge'    => \&SNMP::Info::munge_prio_mac,
 | |
|     'rc_stp_p_port'      => \&SNMP::Info::munge_prio_port,
 | |
| );
 | |
| 
 | |
| # Need to override here since overridden in Layer2 and Layer3 classes
 | |
| sub serial {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     my $ver = $rapidcity->rc_serial();
 | |
|     return $ver unless !defined $ver;
 | |
| 
 | |
|     return;
 | |
| }
 | |
| 
 | |
| sub i_duplex {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $rc_duplex     = $rapidcity->rc_duplex($partial)     || {};
 | |
|     my $rc_cpu_duplex = $rapidcity->rc_cpu_duplex($partial) || {};
 | |
| 
 | |
|     my %i_duplex;
 | |
|     foreach my $if ( keys %$rc_duplex ) {
 | |
|         my $duplex = $rc_duplex->{$if};
 | |
|         next unless defined $duplex;
 | |
| 
 | |
|         $duplex = 'half' if $duplex =~ /half/i;
 | |
|         $duplex = 'full' if $duplex =~ /full/i;
 | |
|         $i_duplex{$if} = $duplex;
 | |
|     }
 | |
| 
 | |
|     # Get CPU Ethernet Interfaces for 8600 Series
 | |
|     foreach my $iid ( keys %$rc_cpu_duplex ) {
 | |
|         my $c_duplex = $rc_cpu_duplex->{$iid};
 | |
|         next unless defined $c_duplex;
 | |
| 
 | |
|         $i_duplex{$iid} = $c_duplex;
 | |
|     }
 | |
| 
 | |
|     return \%i_duplex;
 | |
| }
 | |
| 
 | |
| sub i_duplex_admin {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $rc_duplex_admin     = $rapidcity->rc_duplex_admin()             || {};
 | |
|     my $rc_auto             = $rapidcity->rc_auto($partial)             || {};
 | |
|     my $rc_cpu_auto         = $rapidcity->rc_cpu_auto($partial)         || {};
 | |
|     my $rc_cpu_duplex_admin = $rapidcity->rc_cpu_duplex_admin($partial) || {};
 | |
| 
 | |
|     my %i_duplex_admin;
 | |
|     foreach my $if ( keys %$rc_duplex_admin ) {
 | |
|         my $duplex = $rc_duplex_admin->{$if};
 | |
|         next unless defined $duplex;
 | |
|         my $auto = $rc_auto->{$if} || 'false';
 | |
| 
 | |
|         my $string = 'other';
 | |
|         $string = 'half' if ( $duplex =~ /half/i and $auto =~ /false/i );
 | |
|         $string = 'full' if ( $duplex =~ /full/i and $auto =~ /false/i );
 | |
|         $string = 'auto' if $auto =~ /true/i;
 | |
| 
 | |
|         $i_duplex_admin{$if} = $string;
 | |
|     }
 | |
| 
 | |
|     # Get CPU Ethernet Interfaces for 8600 Series
 | |
|     foreach my $iid ( keys %$rc_cpu_duplex_admin ) {
 | |
|         my $c_duplex = $rc_cpu_duplex_admin->{$iid};
 | |
|         next unless defined $c_duplex;
 | |
|         my $c_auto = $rc_cpu_auto->{$iid};
 | |
| 
 | |
|         my $string = 'other';
 | |
|         $string = 'half' if ( $c_duplex =~ /half/i and $c_auto =~ /false/i );
 | |
|         $string = 'full' if ( $c_duplex =~ /full/i and $c_auto =~ /false/i );
 | |
|         $string = 'auto' if $c_auto =~ /true/i;
 | |
| 
 | |
|         $i_duplex_admin{$iid} = $string;
 | |
|     }
 | |
| 
 | |
|     return \%i_duplex_admin;
 | |
| }
 | |
| 
 | |
| sub set_i_duplex_admin {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $duplex, $iid ) = @_;
 | |
| 
 | |
|     $duplex = lc($duplex);
 | |
|     return unless ( $duplex =~ /(half|full|auto)/ and $iid =~ /\d+/ );
 | |
| 
 | |
|     # map a textual duplex to an integer one the switch understands
 | |
|     my %duplexes = qw/full 2 half 1/;
 | |
|     my $i_auto   = $rapidcity->rc_auto($iid);
 | |
| 
 | |
|     if ( $duplex eq "auto" ) {
 | |
|         return $rapidcity->set_rc_auto( '1', $iid );
 | |
|     }
 | |
|     elsif ( ( $duplex ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) {
 | |
|         return unless ( $rapidcity->set_rc_auto( '2', $iid ) );
 | |
|         return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid );
 | |
|     }
 | |
|     else {
 | |
|         return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid );
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub set_i_speed_admin {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $speed, $iid ) = @_;
 | |
| 
 | |
|     return unless ( $speed =~ /(10|100|1000|auto)/i and $iid =~ /\d+/ );
 | |
| 
 | |
|     # map a textual duplex to an integer one the switch understands
 | |
|     my %speeds = qw/10 1 100 2 1000 3/;
 | |
|     my $i_auto = $rapidcity->rc_auto($iid);
 | |
| 
 | |
|     if ( $speed eq "auto" ) {
 | |
|         return $rapidcity->set_rc_auto( '1', $iid );
 | |
|     }
 | |
|     elsif ( ( $speed ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) {
 | |
|         return unless ( $rapidcity->set_rc_auto( '2', $iid ) );
 | |
|         return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid );
 | |
|     }
 | |
|     else {
 | |
|         return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid );
 | |
|     }
 | |
| }
 | |
| 
 | |
| sub v_index {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     return $rapidcity->rc_vlan_id($partial);
 | |
| }
 | |
| 
 | |
| sub i_vlan {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $i_pvid = $rapidcity->rc_i_vlan_pvid($partial) || {};
 | |
| 
 | |
|     return $i_pvid;
 | |
| }
 | |
| 
 | |
| sub i_vlan_membership {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     my $rc_v_ports = $rapidcity->rc_vlan_members();
 | |
| 
 | |
|     my $i_vlan_membership = {};
 | |
|     foreach my $vlan ( keys %$rc_v_ports ) {
 | |
|         my $portlist = $rc_v_ports->{$vlan};
 | |
|         my $ret      = [];
 | |
| 
 | |
|         # Convert portlist bit array to ifIndex array
 | |
|         for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) {
 | |
|             push( @{$ret}, $i ) if ( @$portlist[$i] );
 | |
|         }
 | |
| 
 | |
|         #Create HoA ifIndex -> VLAN array
 | |
|         foreach my $port ( @{$ret} ) {
 | |
|             push( @{ $i_vlan_membership->{$port} }, $vlan );
 | |
|         }
 | |
|     }
 | |
|     return $i_vlan_membership;
 | |
| }
 | |
| 
 | |
| sub i_vlan_membership_untagged {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     # Traditionally access ports have one VLAN untagged and trunk ports have
 | |
|     # one or more VLANs all tagged
 | |
|     # Newer VOSS device trunks have PerformTagging true or false and also can
 | |
|     # UntagDefaultVlan
 | |
|     # Newer BOSS device trunks have four PerformTagging options true, false,
 | |
|     # tagPvidOnly, and untagPvidOnly
 | |
| 
 | |
|     my $p_members = $rapidcity->i_vlan_membership();
 | |
|     my $i_vlan = $rapidcity->i_vlan();
 | |
|     my $p_tag_opt = $rapidcity->rcVlanPortPerformTagging() || {};
 | |
|     my $p_untag_def = $rapidcity->rcVlanPortUntagDefaultVlan() || {};
 | |
|     my $p_type = $rapidcity->rcVlanPortType() || {};
 | |
| 
 | |
|     my $members_untagged = {};
 | |
|     foreach my $port ( keys %$p_type ) {
 | |
|         my $type = $p_type->{$port};
 | |
|         next unless $type;
 | |
| 
 | |
|         # Easiest case first access ports
 | |
|         if ($type eq 'access') {
 | |
|             # Access ports should only have one VLAN and it should be
 | |
|             # untagged
 | |
|             $members_untagged->{$port} = $p_members->{$port};
 | |
|         }
 | |
|         else {
 | |
|             # If PerformTagging has a value do all checks otherwise we're
 | |
|             # just a trunk and everything is tagged
 | |
|             if ($p_tag_opt->{$port}) {
 | |
|                 if ($p_tag_opt->{$port} eq 'untagPvidOnly') {
 | |
|                     my $vlan = $i_vlan->{$port};
 | |
|                     push( @{ $members_untagged->{$port} }, $vlan );
 | |
|                 }
 | |
|                 elsif (($p_tag_opt->{$port} eq 'true') and
 | |
|                        ($p_untag_def->{$port} and $p_untag_def->{$port} eq 'true'))
 | |
|                 {
 | |
|                     my $vlan = $i_vlan->{$port};
 | |
|                     push( @{ $members_untagged->{$port} }, $vlan );
 | |
|                 }
 | |
|                 elsif ($p_tag_opt->{$port} eq 'tagPvidOnly') {
 | |
|                     my $vlan = $i_vlan->{$port};
 | |
|                     my @arr = $p_members->{$port};
 | |
|                     my $index = 0;
 | |
|                     my $count = scalar @arr;
 | |
|                     $index++ until $arr[$index] eq $vlan or $index==$count;
 | |
|                     splice(@arr, $index, 1);
 | |
|                     $members_untagged->{$port} = @arr;
 | |
|                 }
 | |
|                 # Don't know if this is a legal configuration, but included
 | |
|                 # for completeness
 | |
|                 elsif ($p_tag_opt->{$port} eq 'false') {
 | |
|                     $members_untagged->{$port} = $p_members->{$port};
 | |
|                 }
 | |
|                 else {
 | |
|                     next;
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return $members_untagged;
 | |
| }
 | |
| 
 | |
| sub set_i_pvid {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
 | |
| 
 | |
|     unless ( $rapidcity->set_rc_i_vlan_pvid( $vlan_id, $ifindex ) ) {
 | |
|         $rapidcity->error_throw(
 | |
|             "Unable to change PVID to $vlan_id on IfIndex: $ifindex");
 | |
|         return;
 | |
|     }
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub set_i_vlan {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $new_vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     return
 | |
|         unless ( $rapidcity->_validate_vlan_param( $new_vlan_id, $ifindex ) );
 | |
| 
 | |
|     my $vlan_p_type = $rapidcity->rc_i_vlan_type($ifindex);
 | |
|     unless ( $vlan_p_type->{$ifindex} =~ /access/ ) {
 | |
|         $rapidcity->error_throw("Not an access port");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     my $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex);
 | |
| 
 | |
|     # Store current untagged VLAN to remove it from the port list later
 | |
|     my $old_vlan_id = $i_pvid->{$ifindex};
 | |
| 
 | |
|     # Check that haven't been given the same VLAN we are currently using
 | |
|     if ( $old_vlan_id eq $new_vlan_id ) {
 | |
|         $rapidcity->error_throw(
 | |
|             "Current PVID: $old_vlan_id and New VLAN: $new_vlan_id the same, no change."
 | |
|         );
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     print "Changing VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n"
 | |
|         if $rapidcity->debug();
 | |
| 
 | |
|     # Check if port in forbidden list for the VLAN, haven't seen this used,
 | |
|     # but we'll check anyway
 | |
|     return
 | |
|         unless (
 | |
|         $rapidcity->_check_forbidden_ports( $new_vlan_id, $ifindex ) );
 | |
| 
 | |
|     my $old_vlan_members = $rapidcity->rc_vlan_members($old_vlan_id);
 | |
|     my $new_vlan_members = $rapidcity->rc_vlan_members($new_vlan_id);
 | |
| 
 | |
|     print "Modifying egress list for VLAN: $new_vlan_id \n"
 | |
|         if $rapidcity->debug();
 | |
|     my $new_egress
 | |
|         = $rapidcity->modify_port_list( $new_vlan_members->{$new_vlan_id},
 | |
|         $ifindex, '1' );
 | |
| 
 | |
|     print "Modifying egress list for VLAN: $old_vlan_id \n"
 | |
|         if $rapidcity->debug();
 | |
|     my $old_egress
 | |
|         = $rapidcity->modify_port_list( $old_vlan_members->{$old_vlan_id},
 | |
|         $ifindex, '0' );
 | |
| 
 | |
|     my $vlan_set = [
 | |
|         [ 'rc_vlan_members', "$new_vlan_id", "$new_egress" ],
 | |
| 
 | |
|         #        ['rc_vlan_members',"$old_vlan_id","$old_egress"],
 | |
|     ];
 | |
| 
 | |
|     return
 | |
|         unless ( $rapidcity->set_multi($vlan_set) );
 | |
| 
 | |
|     my $vlan_set2 = [ [ 'rc_vlan_members', "$old_vlan_id", "$old_egress" ], ];
 | |
| 
 | |
|     return
 | |
|         unless ( $rapidcity->set_multi($vlan_set2) );
 | |
| 
 | |
|  # Set new untagged / native VLAN
 | |
|  # Some models/versions do this for us also, so check to see if we need to set
 | |
|     $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex);
 | |
| 
 | |
|     my $cur_i_pvid = $i_pvid->{$ifindex};
 | |
|     print "Current PVID: $cur_i_pvid\n" if $rapidcity->debug();
 | |
|     unless ( $cur_i_pvid eq $new_vlan_id ) {
 | |
|         return unless ( $rapidcity->set_i_pvid( $new_vlan_id, $ifindex ) );
 | |
|     }
 | |
| 
 | |
|     print
 | |
|         "Successfully changed VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n"
 | |
|         if $rapidcity->debug();
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub set_add_i_vlan_tagged {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
 | |
| 
 | |
|     print "Adding VLAN: $vlan_id to IfIndex: $ifindex\n"
 | |
|         if $rapidcity->debug();
 | |
| 
 | |
| # Check if port in forbidden list for the VLAN, haven't seen this used, but we'll check anyway
 | |
|     return
 | |
|         unless ( $rapidcity->_check_forbidden_ports( $vlan_id, $ifindex ) );
 | |
| 
 | |
|     my $iv_members = $rapidcity->rc_vlan_members($vlan_id);
 | |
| 
 | |
|     print "Modifying egress list for VLAN: $vlan_id \n"
 | |
|         if $rapidcity->debug();
 | |
|     my $new_egress
 | |
|         = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex,
 | |
|         '1' );
 | |
| 
 | |
|     unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) {
 | |
|         print
 | |
|             "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n"
 | |
|             if $rapidcity->debug();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     print
 | |
|         "Successfully added IfIndex: $ifindex to VLAN: $vlan_id egress list\n"
 | |
|         if $rapidcity->debug();
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub set_remove_i_vlan_tagged {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
 | |
| 
 | |
|     print "Removing VLAN: $vlan_id from IfIndex: $ifindex\n"
 | |
|         if $rapidcity->debug();
 | |
| 
 | |
|     my $iv_members = $rapidcity->rc_vlan_members($vlan_id);
 | |
| 
 | |
|     print "Modifying egress list for VLAN: $vlan_id \n"
 | |
|         if $rapidcity->debug();
 | |
|     my $new_egress
 | |
|         = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex,
 | |
|         '0' );
 | |
| 
 | |
|     unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) {
 | |
|         print
 | |
|             "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n"
 | |
|             if $rapidcity->debug();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     print
 | |
|         "Successfully removed IfIndex: $ifindex from VLAN: $vlan_id egress list\n"
 | |
|         if $rapidcity->debug();
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub set_create_vlan {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $name, $vlan_id ) = @_;
 | |
|     return unless ( $vlan_id =~ /\d+/ );
 | |
| 
 | |
|     my $vlan_set = [
 | |
|         [ 'v_name',          "$vlan_id", "$name" ],
 | |
|         [ 'rc_vlan_rstatus', "$vlan_id", 4 ],
 | |
|     ];
 | |
| 
 | |
|     unless ( $rapidcity->set_multi($vlan_set) ) {
 | |
|         print "Error: Unable to create VLAN: $vlan_id\n"
 | |
|             if $rapidcity->debug();
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub set_delete_vlan {
 | |
|     my $rapidcity = shift;
 | |
|     my ($vlan_id) = shift;
 | |
|     return unless ( $vlan_id =~ /^\d+$/ );
 | |
| 
 | |
|     unless ( $rapidcity->set_rc_vlan_rstatus( '6', $vlan_id ) ) {
 | |
|         $rapidcity->error_throw("Unable to delete VLAN: $vlan_id");
 | |
|         return;
 | |
|     }
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| #
 | |
| # These are internal methods and are not documented.  Do not use directly.
 | |
| #
 | |
| sub _check_forbidden_ports {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     my $iv_forbidden = $rapidcity->rc_vlan_no_join($vlan_id);
 | |
| 
 | |
|     my @forbidden_ports
 | |
|         = split( //, unpack( "B*", $iv_forbidden->{$vlan_id} ) );
 | |
|     print "Forbidden ports: @forbidden_ports\n" if $rapidcity->debug();
 | |
|     if ( defined( $forbidden_ports[$ifindex] )
 | |
|         and ( $forbidden_ports[$ifindex] eq "1" ) )
 | |
|     {
 | |
|         $rapidcity->error_throw(
 | |
|             "IfIndex: $ifindex in forbidden list for VLAN: $vlan_id unable to add"
 | |
|         );
 | |
|         return;
 | |
|     }
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub _validate_vlan_param {
 | |
|     my $rapidcity = shift;
 | |
|     my ( $vlan_id, $ifindex ) = @_;
 | |
| 
 | |
|     # VID and ifIndex should both be numeric
 | |
|     unless (defined $vlan_id
 | |
|         and defined $ifindex
 | |
|         and $vlan_id =~ /^\d+$/
 | |
|         and $ifindex =~ /^\d+$/ )
 | |
|     {
 | |
|         $rapidcity->error_throw("Invalid parameter");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     # Check that ifIndex exists on device
 | |
|     my $index = $rapidcity->interfaces($ifindex);
 | |
| 
 | |
|     unless ( exists $index->{$ifindex} ) {
 | |
|         $rapidcity->error_throw("ifIndex $ifindex does not exist");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     #Check that VLAN exists on device
 | |
|     unless ( $rapidcity->rc_vlan_id($vlan_id) ) {
 | |
|         $rapidcity->error_throw(
 | |
|             "VLAN $vlan_id does not exist or is not operational");
 | |
|         return;
 | |
|     }
 | |
| 
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| sub agg_ports {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     # TODO: implement partial
 | |
|     my $ports  = $rapidcity->rc_mlt_ports;
 | |
|     my $trunks = $rapidcity->rc_mlt_index;
 | |
|     my $dps    = $rapidcity->rc_mlt_dp || {};
 | |
| 
 | |
|     return {}
 | |
|         unless ref {} eq ref $trunks
 | |
|             and scalar keys %$trunks
 | |
|             and ref {} eq ref $ports
 | |
|             and scalar keys %$ports;
 | |
| 
 | |
|     my $ret = {};
 | |
|     foreach my $m ( keys %$trunks ) {
 | |
|         my $idx = $trunks->{$m};
 | |
|         next unless $idx;
 | |
|         $idx = $dps->{$m} ? $dps->{$m} : $idx;
 | |
|         my $portlist = $ports->{$m};
 | |
|         next unless $portlist;
 | |
|         for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) {
 | |
|             $ret->{$i} = $idx if ( @$portlist[$i] );
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return $ret;
 | |
| }
 | |
| 
 | |
| # break up the rcBridgeSpbmMacEntry INDEX into ISID and MAC Address.
 | |
| sub _spbm_fdbtable_index {
 | |
|     my $idx    = shift;
 | |
|     my @values = split( /\./, $idx );
 | |
|     my $isid = shift(@values);
 | |
|     return ( $isid, join( ':', map { sprintf "%02x", $_ } @values ) );
 | |
| }
 | |
| 
 | |
| sub rc_spbm_fw_mac {
 | |
|     my $rapidcity  = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
 | |
|     my $spbm_fw_mac  = {};
 | |
|     foreach my $idx ( keys %$spbm_fw_ports ) {
 | |
|         my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
 | |
|         $spbm_fw_mac->{$idx} = $mac;
 | |
|     }
 | |
|     return $spbm_fw_mac;
 | |
| }
 | |
| 
 | |
| sub rc_spbm_fw_isid {
 | |
|     my $rapidcity  = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
 | |
|     my $spbm_fw_isid  = {};
 | |
|     foreach my $idx ( keys %$spbm_fw_ports ) {
 | |
|         my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
 | |
|         $spbm_fw_isid->{$idx} = $isid;
 | |
|     }
 | |
|     return $spbm_fw_isid;
 | |
| }
 | |
| 
 | |
| sub stp_ver {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rcSysSpanningTreeOperMode()
 | |
|       || $rapidcity->SUPER::stp_ver();
 | |
| }
 | |
| 
 | |
| # RSTP and ieee8021d operating modes do not populate RAPID-CITY::rcStgTable
 | |
| # or RAPID-CITY::rcStgPortTable but do populate BRIDGE-MIB so check both
 | |
| sub stp_i_mac {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_mac()
 | |
|       || $rapidcity->SUPER::stp_i_mac();
 | |
| }
 | |
| 
 | |
| sub stp_i_time {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_time()
 | |
|       || $rapidcity->SUPER::stp_i_time();
 | |
| }
 | |
| 
 | |
| sub stp_i_ntop {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_ntop()
 | |
|       || $rapidcity->SUPER::stp_i_ntop();
 | |
| }
 | |
| 
 | |
| sub stp_i_root {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_root()
 | |
|       || $rapidcity->SUPER::stp_i_root();
 | |
| }
 | |
| 
 | |
| sub stp_i_root_port {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_root_port()
 | |
|       || $rapidcity->SUPER::stp_i_root_port();
 | |
| }
 | |
| 
 | |
| sub stp_i_priority {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_i_priority()
 | |
|       || $rapidcity->SUPER::stp_i_priority();
 | |
| }
 | |
| 
 | |
| sub stp_p_id {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_id()
 | |
|       || $rapidcity->SUPER::stp_p_id();
 | |
| }
 | |
| 
 | |
| sub stp_p_priority {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_priority()
 | |
|       || $rapidcity->SUPER::stp_p_priority();
 | |
| }
 | |
| 
 | |
| sub stp_p_state {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_state()
 | |
|       || $rapidcity->SUPER::stp_p_state();
 | |
| }
 | |
| 
 | |
| sub stp_p_cost {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_cost()
 | |
|       || $rapidcity->SUPER::stp_p_cost();
 | |
| }
 | |
| 
 | |
| sub stp_p_root {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_root()
 | |
|       || $rapidcity->SUPER::stp_p_root();
 | |
| }
 | |
| 
 | |
| sub stp_p_bridge {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_bridge()
 | |
|       || $rapidcity->SUPER::stp_p_bridge();
 | |
| }
 | |
| 
 | |
| sub stp_p_port {
 | |
|     my $rapidcity = shift;
 | |
| 
 | |
|     return $rapidcity->rc_stp_p_port()
 | |
|       || $rapidcity->SUPER::stp_p_port();
 | |
| }
 | |
| 
 | |
| sub mst_vlan2instance {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     return $rapidcity->rcVlanStgId($partial);
 | |
| }
 | |
| 
 | |
| sub i_bpduguard_enabled {
 | |
|     my $rapidcity    = shift;
 | |
|     my $partial = shift;
 | |
| 
 | |
|     return $rapidcity->rcPortBpduFilteringOperEnabled();
 | |
| }
 | |
| 
 | |
| sub i_stp_state {
 | |
|     my $rapidcity = shift;
 | |
|     my $partial   = shift;
 | |
| 
 | |
|     my $bp_index    = $rapidcity->bp_index($partial);
 | |
|     my $stp_p_state = $rapidcity->dot1dStpPortState($partial);
 | |
| 
 | |
|     my %i_stp_state;
 | |
| 
 | |
|     foreach my $index ( keys %$stp_p_state ) {
 | |
|         my $state = $stp_p_state->{$index};
 | |
|         my $iid   = $bp_index->{$index};
 | |
|         next unless defined $iid;
 | |
|         next unless defined $state;
 | |
|         $i_stp_state{$iid} = $state;
 | |
|     }
 | |
| 
 | |
|     return \%i_stp_state;
 | |
| }
 | |
| 
 | |
| 1;
 | |
| 
 | |
| __END__
 | |
| 
 | |
| =head1 NAME
 | |
| 
 | |
| SNMP::Info::RapidCity - SNMP Interface to the Avaya/Nortel RapidCity MIB
 | |
| 
 | |
| =head1 AUTHOR
 | |
| 
 | |
| Eric Miller
 | |
| 
 | |
| =head1 SYNOPSIS
 | |
| 
 | |
|  # Let SNMP::Info determine the correct subclass for you.
 | |
|  my $rapidcity = new SNMP::Info(
 | |
|                         AutoSpecify => 1,
 | |
|                         Debug       => 1,
 | |
|                         # These arguments are passed directly to SNMP::Session
 | |
|                         DestHost    => 'myswitch',
 | |
|                         Community   => 'public',
 | |
|                         Version     => 2
 | |
|                         )
 | |
|     or die "Can't connect to DestHost.\n";
 | |
| 
 | |
|  my $class = $rapidcity->class();
 | |
|  print "SNMP::Info determined this device to fall under subclass : $class\n";
 | |
| 
 | |
| =head1 DESCRIPTION
 | |
| 
 | |
| SNMP::Info::RapidCity is a subclass of SNMP::Info that provides an interface
 | |
| to the C<RAPID-CITY> MIB.  This MIB is used across the Avaya/Nortel Ethernet
 | |
| Routing Switch and Ethernet Switch product lines (Formerly known as Passport,
 | |
| BayStack, and Accelar), as well as, the VSP 9000 and 7000 series.
 | |
| 
 | |
| Use or create in a subclass of SNMP::Info.  Do not use directly.
 | |
| 
 | |
| =head2 Inherited Classes
 | |
| 
 | |
| None.
 | |
| 
 | |
| =head2 Required MIBs
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item F<RAPID-CITY>
 | |
| 
 | |
| =item F<NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB>
 | |
| 
 | |
| =item F<NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB>
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 GLOBALS
 | |
| 
 | |
| These are methods that return scalar values from SNMP
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item  $rapidcity->rc_base_mac()
 | |
| 
 | |
| (C<rc2kChassisBaseMacAddr>)
 | |
| 
 | |
| =item  $rapidcity->rc_serial()
 | |
| 
 | |
| (C<rcChasSerialNumber>)
 | |
| 
 | |
| =item  $rapidcity->rc_ch_rev()
 | |
| 
 | |
| (C<rcChasHardwareRevision>)
 | |
| 
 | |
| =item  $rapidcity->chassis()
 | |
| 
 | |
| (C<rcChasType>)
 | |
| 
 | |
| =item  $rapidcity->slots()
 | |
| 
 | |
| (C<rcChasNumSlots>)
 | |
| 
 | |
| =item  $rapidcity->rc_virt_ip()
 | |
| 
 | |
| (C<rcSysVirtualIpAddr>)
 | |
| 
 | |
| =item  $rapidcity->rc_virt_mask()
 | |
| 
 | |
| (C<rcSysVirtualNetMask>)
 | |
| 
 | |
| =item  $rapidcity->tftp_host()
 | |
| 
 | |
| (C<rcTftpHost>)
 | |
| 
 | |
| =item  $rapidcity->tftp_file()
 | |
| 
 | |
| (C<rcTftpFile>)
 | |
| 
 | |
| =item  $rapidcity->tftp_action()
 | |
| 
 | |
| (C<rcTftpAction>)
 | |
| 
 | |
| =item  $rapidcity->tftp_result()
 | |
| 
 | |
| (C<rcTftpResult>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Overrides
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item  $rapidcity->serial()
 | |
| 
 | |
| Returns serial number of the chassis
 | |
| 
 | |
| =item $rapidcity->stp_ver()
 | |
| 
 | |
| Returns the particular STP version running on this device.
 | |
| 
 | |
| Values: C<nortelStpg>, C<pvst>, C<rstp>, C<mstp>, C<ieee8021d>
 | |
| 
 | |
| (C<rcSysSpanningTreeOperMode>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 TABLE METHODS
 | |
| 
 | |
| These are methods that return tables of information in the form of a reference
 | |
| to a hash.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->i_duplex()
 | |
| 
 | |
| Returns reference to map of IIDs to current link duplex.
 | |
| 
 | |
| =item $rapidcity->i_duplex_admin()
 | |
| 
 | |
| Returns reference to hash of IIDs to admin duplex setting.
 | |
| 
 | |
| =item $rapidcity->i_vlan()
 | |
| 
 | |
| Returns a mapping between C<ifIndex> and the PVID or default VLAN.
 | |
| 
 | |
| =item $rapidcity->i_vlan_membership()
 | |
| 
 | |
| Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
 | |
| IDs.  These are the VLANs which are members of the egress list for the port.
 | |
| 
 | |
|   Example:
 | |
|   my $interfaces = $rapidcity->interfaces();
 | |
|   my $vlans      = $rapidcity->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 $rapidcity->i_vlan_membership_untagged()
 | |
| 
 | |
| Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
 | |
| IDs.  These are the VLANs which are members of the untagged egress list for
 | |
| the port.
 | |
| 
 | |
| =item $rapidcity->v_index()
 | |
| 
 | |
| Returns VLAN IDs
 | |
| 
 | |
| (C<rcVlanId>)
 | |
| 
 | |
| =item $rapidcity->agg_ports()
 | |
| 
 | |
| Returns a HASH reference mapping from slave to master port for each member of
 | |
| a port bundle (MLT) on the device. Keys are ifIndex of the slave ports,
 | |
| Values are ifIndex of the corresponding master ports.
 | |
| 
 | |
| =item $rapidcity->i_stp_state()
 | |
| 
 | |
| Returns the mapping of (C<dot1dStpPortState>) to the interface
 | |
| index (iid).
 | |
| 
 | |
| =item $rapidcity->mst_vlan2instance()
 | |
| 
 | |
| Returns the mapping of VLAN to Spanning Tree Group (STG) instance in the
 | |
| form of a hash reference with key = VLAN id, value = STG instance
 | |
| 
 | |
| (C<rcVlanStgId>)
 | |
| 
 | |
| =item $rapidcity->i_bpduguard_enabled()
 | |
| 
 | |
| Returns true or false depending on whether C<BpduGuard> is enabled on a given
 | |
| port.  Format is a hash reference with key = C<ifIndex>, value = [true|false]
 | |
| 
 | |
| (C<rcPortBpduFilteringOperEnabled>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Port Table (C<rcPortTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_index()
 | |
| 
 | |
| (C<rcPortIndex>)
 | |
| 
 | |
| =item $rapidcity->rc_duplex()
 | |
| 
 | |
| (C<rcPortOperDuplex>)
 | |
| 
 | |
| =item $rapidcity->rc_duplex_admin()
 | |
| 
 | |
| (C<rcPortAdminDuplex>)
 | |
| 
 | |
| =item $rapidcity->rc_speed_admin()
 | |
| 
 | |
| (C<rcPortAdminSpeed>)
 | |
| 
 | |
| =item $rapidcity->rc_auto()
 | |
| 
 | |
| (C<rcPortAutoNegotiate>)
 | |
| 
 | |
| =item $rapidcity->rc_alias()
 | |
| 
 | |
| (C<rcPortName>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY CPU Ethernet Port Table (C<rc2kCpuEthernetPortTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_cpu_ifindex()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortIfIndex>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_admin()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortAdminStatus>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_oper()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortOperStatus>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_ip()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortAddr>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_mask()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortMask>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_auto()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortAutoNegotiate>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_duplex_admin()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortAdminDuplex>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_duplex()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortOperDuplex>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_speed_admin()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortAdminSpeed>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_speed_oper()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortOperSpeed>)
 | |
| 
 | |
| =item $rapidcity->rc_cpu_mac()
 | |
| 
 | |
| (C<rc2kCpuEthernetPortMgmtMacAddr>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY VLAN Port Table (C<rcVlanPortTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan_if()
 | |
| 
 | |
| (C<rcVlanPortIndex>)
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan_num()
 | |
| 
 | |
| (C<rcVlanPortNumVlanIds>)
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan()
 | |
| 
 | |
| (C<rcVlanPortVlanIds>)
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan_type()
 | |
| 
 | |
| (C<rcVlanPortType>)
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan_pvid()
 | |
| 
 | |
| (C<rcVlanPortDefaultVlanId>)
 | |
| 
 | |
| =item $rapidcity->rc_i_vlan_tag()
 | |
| 
 | |
| (C<rcVlanPortPerformTagging>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY VLAN Table (C<rcVlanTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_vlan_id()
 | |
| 
 | |
| (C<rcVlanId>)
 | |
| 
 | |
| =item $rapidcity->v_name()
 | |
| 
 | |
| (C<rcVlanName>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_color()
 | |
| 
 | |
| (C<rcVlanColor>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_if()
 | |
| 
 | |
| (C<rcVlanIfIndex>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_stg()
 | |
| 
 | |
| (C<rcVlanStgId>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_type()
 | |
| 
 | |
| (C<rcVlanType>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_members()
 | |
| 
 | |
| (C<rcVlanPortMembers>)
 | |
| 
 | |
| =item $rapidcity->rc_vlan_mac()
 | |
| 
 | |
| (C<rcVlanMacAddress>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY IP Address Table (C<rcIpAddrTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_ip_index()
 | |
| 
 | |
| (C<rcIpAdEntIfIndex>)
 | |
| 
 | |
| =item $rapidcity->rc_ip_addr()
 | |
| 
 | |
| (C<rcIpAdEntAddr>)
 | |
| 
 | |
| =item $rapidcity->rc_ip_type()
 | |
| 
 | |
| (C<rcIpAdEntIfType>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Chassis Fan Table (C<rcChasFanTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_fan_op()
 | |
| 
 | |
| (C<rcChasFanOperStatus>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Power Supply Table (C<rcChasPowerSupplyTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_ps_op()
 | |
| 
 | |
| (C<rcChasPowerSupplyOperStatus>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Power Supply Detail Table (C<rcChasPowerSupplyDetailTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_ps_type()
 | |
| 
 | |
| (C<rcChasPowerSupplyDetailType>)
 | |
| 
 | |
| =item $rapidcity->rc_ps_serial()
 | |
| 
 | |
| (C<rcChasPowerSupplyDetailSerialNumber>)
 | |
| 
 | |
| =item $rapidcity->rc_ps_rev()
 | |
| 
 | |
| (C<rcChasPowerSupplyDetailHardwareRevision>)
 | |
| 
 | |
| =item $rapidcity->rc_ps_part()
 | |
| 
 | |
| (C<rcChasPowerSupplyDetailPartNumber>)
 | |
| 
 | |
| =item $rapidcity->rc_ps_detail()
 | |
| 
 | |
| (C<rcChasPowerSupplyDetailDescription>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Card Table (C<rcCardTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_c_type()
 | |
| 
 | |
| (C<rcCardType>)
 | |
| 
 | |
| =item $rapidcity->rc_c_serial()
 | |
| 
 | |
| (C<rcCardSerialNumber>)
 | |
| 
 | |
| =item $rapidcity->rc_c_rev()
 | |
| 
 | |
| (C<rcCardHardwareRevision>)
 | |
| 
 | |
| =item $rapidcity->rc_c_part()
 | |
| 
 | |
| (C<rcCardPartNumber>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY 2k Card Table (C<rc2kCardTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc2k_c_ftype()
 | |
| 
 | |
| (C<rc2kCardFrontType>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_fdesc()
 | |
| 
 | |
| (C<rc2kCardFrontDescription>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_fserial()
 | |
| 
 | |
| (C<rc2kCardFrontSerialNum>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_frev()
 | |
| 
 | |
| (C<rc2kCardFrontHwVersion>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_fpart()
 | |
| 
 | |
| (C<rc2kCardFrontPartNumber>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_fdate()
 | |
| 
 | |
| (C<rc2kCardFrontDateCode>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_fdev()
 | |
| 
 | |
| (C<rc2kCardFrontDeviations>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_btype()
 | |
| 
 | |
| (C<rc2kCardBackType>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_bdesc()
 | |
| 
 | |
| (C<rc2kCardBackDescription>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_bserial()
 | |
| 
 | |
| (C<rc2kCardBackSerialNum>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_brev()
 | |
| 
 | |
| (C<rc2kCardBackHwVersion>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_bpart()
 | |
| 
 | |
| (C<rc2kCardBackPartNumber>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_bdate()
 | |
| 
 | |
| (C<rc2kCardBackDateCode>)
 | |
| 
 | |
| =item $rapidcity->rc2k_c_bdev()
 | |
| 
 | |
| (C<rc2kCardBackDeviations>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY MDA Card Table (C<rc2kMdaCardTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_type()
 | |
| 
 | |
| (C<rc2kMdaCardType>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_desc()
 | |
| 
 | |
| (C<rc2kMdaCardDescription>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_serial()
 | |
| 
 | |
| (C<rc2kMdaCardSerialNum>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_rev()
 | |
| 
 | |
| (C<rc2kMdaCardHwVersion>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_part()
 | |
| 
 | |
| (C<rc2kMdaCardPartNumber>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_date()
 | |
| 
 | |
| (C<rc2kMdaCardDateCode>)
 | |
| 
 | |
| =item $rapidcity->rc2k_mda_dev()
 | |
| 
 | |
| (C<rc2kMdaCardDeviations>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 RAPID-CITY Bridge SPBM MAC Table (C<rcBridgeSpbmMacTable>)
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->rc_spbm_fw_mac()
 | |
| 
 | |
| Returns reference to hash of forwarding table MAC Addresses
 | |
| 
 | |
| (C<rcBridgeSpbmMacAddr>)
 | |
| 
 | |
| =item $rapidcity->rc_spbm_fw_port()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries port interface
 | |
| identifier (iid)
 | |
| 
 | |
| (C<rcBridgeSpbmMacCPort>)
 | |
| 
 | |
| =item $rapidcity->rc_spbm_fw_status()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries status
 | |
| 
 | |
| (C<rcBridgeSpbmMacStatus>)
 | |
| 
 | |
| =item $rapidcity->rc_spbm_fw_vlan()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries Customer VLAN ID
 | |
| 
 | |
| (C<rcBridgeSpbmMacCVlanId>)
 | |
| 
 | |
| =item $rapidcity->rc_spbm_fw_isid()
 | |
| 
 | |
| Returns reference to hash of forwarding table entries ISID
 | |
| 
 | |
| (C<rcBridgeSpbmMacIsid>)
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Spanning Tree Instance Globals
 | |
| 
 | |
| C<RSTP> and C<ieee8021d> operating modes do not populate the
 | |
| C<RAPID-CITY::rcStgTable> but do populate F<BRIDGE-MIB>.  These methods check
 | |
| F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->stp_i_mac()
 | |
| 
 | |
| Returns the bridge address
 | |
| 
 | |
| =item $rapidcity->stp_i_time()
 | |
| 
 | |
| Returns time since last topology change detected. (100ths/second)
 | |
| 
 | |
| =item $rapidcity->stp_i_ntop()
 | |
| 
 | |
| Returns the total number of topology changes detected.
 | |
| 
 | |
| =item $rapidcity->stp_i_root()
 | |
| 
 | |
| Returns root of STP.
 | |
| 
 | |
| =item $rapidcity->stp_i_root_port()
 | |
| 
 | |
| Returns the port number of the port that offers the lowest cost path
 | |
| to the root bridge.
 | |
| 
 | |
| =item $rapidcity->stp_i_priority()
 | |
| 
 | |
| Returns the port number of the port that offers the lowest cost path
 | |
| to the root bridge.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head2 Spanning Tree Protocol Port Table
 | |
| 
 | |
| C<RSTP> and C<ieee8021d> operating modes do not populate the
 | |
| C<RAPID-CITY::rcStgPortTable> but do populate F<BRIDGE-MIB>.  These methods
 | |
| check F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->stp_p_id()
 | |
| 
 | |
| "The port number of the port for which this entry contains Spanning Tree
 | |
| Protocol management information."
 | |
| 
 | |
| =item $rapidcity->stp_p_priority()
 | |
| 
 | |
| "The value of the priority field which is contained in the first
 | |
| (in network byte order) octet of the (2 octet long) Port ID.  The other octet
 | |
| of the Port ID is given by the value of C<dot1dStpPort>."
 | |
| 
 | |
| =item $rapidcity->stp_p_state()
 | |
| 
 | |
| "The port's current state as defined by application of the Spanning Tree
 | |
| Protocol."
 | |
| 
 | |
| =item $rapidcity->stp_p_cost()
 | |
| 
 | |
| "The contribution of this port to the path cost of paths towards the spanning
 | |
| tree root which include this port."
 | |
| 
 | |
| =item $rapidcity->stp_p_root()
 | |
| 
 | |
| "The unique Bridge Identifier of the Bridge recorded as the Root in the
 | |
| Configuration BPDUs transmitted by the Designated Bridge for the segment to
 | |
| which the port is attached."
 | |
| 
 | |
| =item $rapidcity->stp_p_bridge()
 | |
| 
 | |
| "The Bridge Identifier of the bridge which this port considers to be the
 | |
| Designated Bridge for this port's segment."
 | |
| 
 | |
| =item $rapidcity->stp_p_port()
 | |
| 
 | |
| "The Port Identifier of the port on the Designated Bridge for this port's
 | |
| segment."
 | |
| 
 | |
| =back
 | |
| 
 | |
| =head1 SET METHODS
 | |
| 
 | |
| These are methods that provide SNMP set functionality for overridden methods
 | |
| or provide a simpler interface to complex set operations.  See
 | |
| L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set
 | |
| operations.
 | |
| 
 | |
| =over
 | |
| 
 | |
| =item $rapidcity->set_i_speed_admin(speed, ifIndex)
 | |
| 
 | |
| Sets port speed, must be supplied with speed and port C<ifIndex>.  Speed
 | |
| choices are 'auto', '10', '100', '1000'.
 | |
| 
 | |
|  Example:
 | |
|  my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|  $rapidcity->set_i_speed_admin('auto', $if_map{'1.1'})
 | |
|     or die "Couldn't change port speed. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_i_duplex_admin(duplex, ifIndex)
 | |
| 
 | |
| Sets port duplex, must be supplied with duplex and port C<ifIndex>.  Speed
 | |
| choices are 'auto', 'half', 'full'.
 | |
| 
 | |
|   Example:
 | |
|   my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|   $rapidcity->set_i_duplex_admin('auto', $if_map{'1.1'})
 | |
|     or die "Couldn't change port duplex. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_i_vlan(vlan, ifIndex)
 | |
| 
 | |
| Changes an access (untagged) port VLAN, must be supplied with the numeric
 | |
| VLAN ID and port C<ifIndex>.  This method will modify the port's VLAN
 | |
| membership and PVID (default VLAN).  This method should only be used on end
 | |
| station (non-trunk) ports.
 | |
| 
 | |
|   Example:
 | |
|   my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|   $rapidcity->set_i_vlan('2', $if_map{'1.1'})
 | |
|     or die "Couldn't change port VLAN. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_i_pvid(pvid, ifIndex)
 | |
| 
 | |
| Sets port PVID or default VLAN, must be supplied with the numeric VLAN ID and
 | |
| port C<ifIndex>.  This method only changes the PVID, to modify an access
 | |
| (untagged) port use set_i_vlan() instead.
 | |
| 
 | |
|   Example:
 | |
|   my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|   $rapidcity->set_i_pvid('2', $if_map{'1.1'})
 | |
|     or die "Couldn't change port PVID. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_add_i_vlan_tagged(vlan, ifIndex)
 | |
| 
 | |
| Adds the port to the egress list of the VLAN, must be supplied with the
 | |
| numeric VLAN ID and port C<ifIndex>.
 | |
| 
 | |
|   Example:
 | |
|   my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|   $rapidcity->set_add_i_vlan_tagged('2', $if_map{'1.1'})
 | |
|     or die "Couldn't add port to egress list. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_remove_i_vlan_tagged(vlan, ifIndex)
 | |
| 
 | |
| Removes the port from the egress list of the VLAN, must be supplied with the
 | |
| numeric VLAN ID and port C<ifIndex>.
 | |
| 
 | |
|   Example:
 | |
|   my %if_map = reverse %{$rapidcity->interfaces()};
 | |
|   $rapidcity->set_remove_i_vlan_tagged('2', $if_map{'1.1'})
 | |
|     or die "Couldn't add port to egress list. ",$rapidcity->error(1);
 | |
| 
 | |
| =item $rapidcity->set_delete_vlan(vlan)
 | |
| 
 | |
| Deletes the specified VLAN from the device.
 | |
| 
 | |
| =item $rapidcity->set_create_vlan(name, vlan)
 | |
| 
 | |
| Creates the specified VLAN on the device.
 | |
| 
 | |
| Note:  This method only allows creation of Port type VLANs and does not allow
 | |
| for the setting of the Spanning Tree Group (STG) which defaults to 1.
 | |
| 
 | |
| =back
 | |
| 
 | |
| =cut
 |