1# SNMP::Info::RapidCity
2#
3# Copyright (c) 2014 Eric Miller
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8#
9#     * Redistributions of source code must retain the above copyright notice,
10#       this list of conditions and the following disclaimer.
11#     * Redistributions in binary form must reproduce the above copyright
12#       notice, this list of conditions and the following disclaimer in the
13#       documentation and/or other materials provided with the distribution.
14#     * Neither the name of the University of California, Santa Cruz nor the
15#       names of its contributors may be used to endorse or promote products
16#       derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22# LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29
30package SNMP::Info::RapidCity;
31
32use strict;
33use warnings;
34use Exporter;
35use SNMP::Info;
36
37@SNMP::Info::RapidCity::ISA       = qw/SNMP::Info Exporter/;
38@SNMP::Info::RapidCity::EXPORT_OK = qw//;
39
40our ($VERSION, %FUNCS, %GLOBALS, %MIBS, %MUNGE);
41
42$VERSION = '3.81';
43
44%MIBS = (
45    'RAPID-CITY' => 'rapidCity',
46    # These are distinct from RAPID-CITY but are potentially used by
47    # classes which inherit the RAPID-CITY class
48    'NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB'    => 'nnRstDot1dStpVersion',
49    'NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB' => 'nnMstBrgAddress',
50);
51
52%GLOBALS = (
53    'rc_serial'    => 'rcChasSerialNumber',
54    'chassis'      => 'rcChasType',
55    'slots'        => 'rcChasNumSlots',
56    'tftp_host'    => 'rcTftpHost',
57    'tftp_file'    => 'rcTftpFile',
58    'tftp_action'  => 'rcTftpAction',
59    'tftp_result'  => 'rcTftpResult',
60    'rc_ch_rev'    => 'rcChasHardwareRevision',
61    'rc_base_mac'  => 'rc2kChassisBaseMacAddr',
62    'rc_virt_ip'   => 'rcSysVirtualIpAddr',
63    'rc_virt_mask' => 'rcSysVirtualNetMask',
64);
65
66%FUNCS = (
67
68    # From RAPID-CITY::rcPortTable
69    'rc_index'        => 'rcPortIndex',
70    'rc_duplex'       => 'rcPortOperDuplex',
71    'rc_duplex_admin' => 'rcPortAdminDuplex',
72    'rc_speed_admin'  => 'rcPortAdminSpeed',
73    'rc_auto'         => 'rcPortAutoNegotiate',
74    'rc_alias'        => 'rcPortName',
75
76    # From RAPID-CITY::rc2kCpuEthernetPortTable
77    'rc_cpu_ifindex'      => 'rc2kCpuEthernetPortIfIndex',
78    'rc_cpu_admin'        => 'rc2kCpuEthernetPortAdminStatus',
79    'rc_cpu_oper'         => 'rc2kCpuEthernetPortOperStatus',
80    'rc_cpu_ip'           => 'rc2kCpuEthernetPortAddr',
81    'rc_cpu_mask'         => 'rc2kCpuEthernetPortMask',
82    'rc_cpu_auto'         => 'rc2kCpuEthernetPortAutoNegotiate',
83    'rc_cpu_duplex_admin' => 'rc2kCpuEthernetPortAdminDuplex',
84    'rc_cpu_duplex'       => 'rc2kCpuEthernetPortOperDuplex',
85    'rc_cpu_speed_admin'  => 'rc2kCpuEthernetPortAdminSpeed',
86    'rc_cpu_speed_oper'   => 'rc2kCpuEthernetPortOperSpeed',
87    'rc_cpu_mac'          => 'rc2kCpuEthernetPortMgmtMacAddr',
88
89    # From RAPID-CITY::rcVlanPortTable
90    'rc_i_vlan_if'   => 'rcVlanPortIndex',
91    'rc_i_vlan_num'  => 'rcVlanPortNumVlanIds',
92    'rc_i_vlan'      => 'rcVlanPortVlanIds',
93    'rc_i_vlan_type' => 'rcVlanPortType',
94    'rc_i_vlan_pvid' => 'rcVlanPortDefaultVlanId',
95    'rc_i_vlan_tag'  => 'rcVlanPortPerformTagging',
96
97    # From RAPID-CITY::rcVlanTable
98    'rc_vlan_id'      => 'rcVlanId',
99    'v_name'          => 'rcVlanName',
100    'rc_vlan_color'   => 'rcVlanColor',
101    'rc_vlan_if'      => 'rcVlanIfIndex',
102    'rc_vlan_stg'     => 'rcVlanStgId',
103    'rc_vlan_type'    => 'rcVlanType',
104    'rc_vlan_members' => 'rcVlanPortMembers',
105    'rc_vlan_no_join' => 'rcVlanNotAllowToJoin',
106    'rc_vlan_mac'     => 'rcVlanMacAddress',
107    'rc_vlan_rstatus' => 'rcVlanRowStatus',
108
109    # From RAPID-CITY::rcIpAddrTable
110    'rc_ip_index' => 'rcIpAdEntIfIndex',
111    'rc_ip_addr'  => 'rcIpAdEntAddr',
112    'rc_ip_type'  => 'rcIpAdEntIfType',
113
114    # From RAPID-CITY::rcChasFanTable
115    'rc_fan_op' => 'rcChasFanOperStatus',
116
117    # From RAPID-CITY::rcChasPowerSupplyTable
118    'rc_ps_op' => 'rcChasPowerSupplyOperStatus',
119
120    # From RAPID-CITY::rcChasPowerSupplyDetailTable
121    'rc_ps_type'   => 'rcChasPowerSupplyDetailType',
122    'rc_ps_serial' => 'rcChasPowerSupplyDetailSerialNumber',
123    'rc_ps_rev'    => 'rcChasPowerSupplyDetailHardwareRevision',
124    'rc_ps_part'   => 'rcChasPowerSupplyDetailPartNumber',
125    'rc_ps_detail' => 'rcChasPowerSupplyDetailDescription',
126
127    # From RAPID-CITY::rcCardTable
128    'rc_c_type'   => 'rcCardType',
129    'rc_c_serial' => 'rcCardSerialNumber',
130    'rc_c_rev'    => 'rcCardHardwareRevision',
131    'rc_c_part'   => 'rcCardPartNumber',
132
133    # From RAPID-CITY::rc2kCardTable
134    'rc2k_c_ftype'   => 'rc2kCardFrontType',
135    'rc2k_c_fdesc'   => 'rc2kCardFrontDescription',
136    'rc2k_c_fserial' => 'rc2kCardFrontSerialNum',
137    'rc2k_c_frev'    => 'rc2kCardFrontHwVersion',
138    'rc2k_c_fpart'   => 'rc2kCardFrontPartNumber',
139    'rc2k_c_fdate'   => 'rc2kCardFrontDateCode',
140    'rc2k_c_fdev'    => 'rc2kCardFrontDeviations',
141    'rc2k_c_btype'   => 'rc2kCardBackType',
142    'rc2k_c_bdesc'   => 'rc2kCardBackDescription',
143    'rc2k_c_bserial' => 'rc2kCardBackSerialNum',
144    'rc2k_c_brev'    => 'rc2kCardBackHwVersion',
145    'rc2k_c_bpart'   => 'rc2kCardBackPartNumber',
146    'rc2k_c_bdate'   => 'rc2kCardBackDateCode',
147    'rc2k_c_bdev'    => 'rc2kCardBackDeviations',
148
149    # From RAPID-CITY::rc2kMdaCardTable
150    'rc2k_mda_type'   => 'rc2kMdaCardType',
151    'rc2k_mda_desc'   => 'rc2kMdaCardDescription',
152    'rc2k_mda_serial' => 'rc2kMdaCardSerialNum',
153    'rc2k_mda_rev'    => 'rc2kMdaCardHwVersion',
154    'rc2k_mda_part'   => 'rc2kMdaCardPartNumber',
155    'rc2k_mda_date'   => 'rc2kMdaCardDateCode',
156    'rc2k_mda_dev'    => 'rc2kMdaCardDeviations',
157
158    # From RAPID-CITY::rcMltTable
159    'rc_mlt_ports'    => 'rcMltPortMembers',
160    'rc_mlt_index'    => 'rcMltIfIndex',
161    'rc_mlt_dp'       => 'rcMltDesignatedPort',
162
163    # From RAPID-CITY::rcBridgeSpbmMacTable
164    'rc_spbm_fw_port'   => 'rcBridgeSpbmMacCPort',
165    'rc_spbm_fw_status' => 'rcBridgeSpbmMacStatus',
166    'rc_spbm_fw_vlan'   => 'rcBridgeSpbmMacCVlanId',
167
168    # From RAPID-CITY::rcStgTable
169    'stp_i_id'           => 'rcStgId',
170    'rc_stp_i_mac'       => 'rcStgBridgeAddress',
171    'rc_stp_i_time'      => 'rcStgTimeSinceTopologyChange',
172    'rc_stp_i_ntop'      => 'rcStgTopChanges',
173    'rc_stp_i_root'      => 'rcStgDesignatedRoot',
174    'rc_stp_i_root_port' => 'rcStgRootPort',
175    'rc_stp_i_priority'  => 'rcStgPriority',
176
177    # From RAPID-CITY::rcStgPortTable
178    'rc_stp_p_id'       => 'rcStgPort',
179    'stp_p_stg_id'      => 'rcStgPortStgId',
180    'rc_stp_p_priority' => 'rcStgPortPriority',
181    'rc_stp_p_state'    => 'rcStgPortState',
182    'rc_stp_p_cost'     => 'rcStgPortPathCost',
183    'rc_stp_p_root'     => 'rcStgPortDesignatedRoot',
184    'rc_stp_p_bridge'   => 'rcStgPortDesignatedBridge',
185    'rc_stp_p_port'     => 'rcStgPortDesignatedPort',
186);
187
188%MUNGE = (
189    'rc_base_mac'     => \&SNMP::Info::munge_mac,
190    'rc_vlan_mac'     => \&SNMP::Info::munge_mac,
191    'rc_cpu_mac'      => \&SNMP::Info::munge_mac,
192    'rc_vlan_members' => \&SNMP::Info::munge_port_list,
193    'rc_vlan_no_join' => \&SNMP::Info::munge_port_list,
194    'rc_mlt_ports'    => \&SNMP::Info::munge_port_list,
195    'rc_stp_i_mac'       => \&SNMP::Info::munge_mac,
196    'rc_stp_i_root'      => \&SNMP::Info::munge_prio_mac,
197    'rc_stp_p_root'      => \&SNMP::Info::munge_prio_mac,
198    'rc_stp_p_bridge'    => \&SNMP::Info::munge_prio_mac,
199    'rc_stp_p_port'      => \&SNMP::Info::munge_prio_port,
200);
201
202# Need to override here since overridden in Layer2 and Layer3 classes
203sub serial {
204    my $rapidcity = shift;
205
206    my $ver = $rapidcity->rc_serial();
207    return $ver unless !defined $ver;
208
209    return;
210}
211
212sub i_duplex {
213    my $rapidcity = shift;
214    my $partial   = shift;
215
216    my $rc_duplex     = $rapidcity->rc_duplex($partial)     || {};
217    my $rc_cpu_duplex = $rapidcity->rc_cpu_duplex($partial) || {};
218
219    my %i_duplex;
220    foreach my $if ( keys %$rc_duplex ) {
221        my $duplex = $rc_duplex->{$if};
222        next unless defined $duplex;
223
224        $duplex = 'half' if $duplex =~ /half/i;
225        $duplex = 'full' if $duplex =~ /full/i;
226        $i_duplex{$if} = $duplex;
227    }
228
229    # Get CPU Ethernet Interfaces for 8600 Series
230    foreach my $iid ( keys %$rc_cpu_duplex ) {
231        my $c_duplex = $rc_cpu_duplex->{$iid};
232        next unless defined $c_duplex;
233
234        $i_duplex{$iid} = $c_duplex;
235    }
236
237    return \%i_duplex;
238}
239
240sub i_duplex_admin {
241    my $rapidcity = shift;
242    my $partial   = shift;
243
244    my $rc_duplex_admin     = $rapidcity->rc_duplex_admin()             || {};
245    my $rc_auto             = $rapidcity->rc_auto($partial)             || {};
246    my $rc_cpu_auto         = $rapidcity->rc_cpu_auto($partial)         || {};
247    my $rc_cpu_duplex_admin = $rapidcity->rc_cpu_duplex_admin($partial) || {};
248
249    my %i_duplex_admin;
250    foreach my $if ( keys %$rc_duplex_admin ) {
251        my $duplex = $rc_duplex_admin->{$if};
252        next unless defined $duplex;
253        my $auto = $rc_auto->{$if} || 'false';
254
255        my $string = 'other';
256        $string = 'half' if ( $duplex =~ /half/i and $auto =~ /false/i );
257        $string = 'full' if ( $duplex =~ /full/i and $auto =~ /false/i );
258        $string = 'auto' if $auto =~ /true/i;
259
260        $i_duplex_admin{$if} = $string;
261    }
262
263    # Get CPU Ethernet Interfaces for 8600 Series
264    foreach my $iid ( keys %$rc_cpu_duplex_admin ) {
265        my $c_duplex = $rc_cpu_duplex_admin->{$iid};
266        next unless defined $c_duplex;
267        my $c_auto = $rc_cpu_auto->{$iid};
268
269        my $string = 'other';
270        $string = 'half' if ( $c_duplex =~ /half/i and $c_auto =~ /false/i );
271        $string = 'full' if ( $c_duplex =~ /full/i and $c_auto =~ /false/i );
272        $string = 'auto' if $c_auto =~ /true/i;
273
274        $i_duplex_admin{$iid} = $string;
275    }
276
277    return \%i_duplex_admin;
278}
279
280sub set_i_duplex_admin {
281    my $rapidcity = shift;
282    my ( $duplex, $iid ) = @_;
283
284    $duplex = lc($duplex);
285    return unless ( $duplex =~ /(half|full|auto)/ and $iid =~ /\d+/ );
286
287    # map a textual duplex to an integer one the switch understands
288    my %duplexes = qw/full 2 half 1/;
289    my $i_auto   = $rapidcity->rc_auto($iid);
290
291    if ( $duplex eq "auto" ) {
292        return $rapidcity->set_rc_auto( '1', $iid );
293    }
294    elsif ( ( $duplex ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) {
295        return unless ( $rapidcity->set_rc_auto( '2', $iid ) );
296        return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid );
297    }
298    else {
299        return $rapidcity->set_rc_duplex_admin( $duplexes{$duplex}, $iid );
300    }
301}
302
303sub set_i_speed_admin {
304    my $rapidcity = shift;
305    my ( $speed, $iid ) = @_;
306
307    return unless ( $speed =~ /(10|100|1000|auto)/i and $iid =~ /\d+/ );
308
309    # map a textual duplex to an integer one the switch understands
310    my %speeds = qw/10 1 100 2 1000 3/;
311    my $i_auto = $rapidcity->rc_auto($iid);
312
313    if ( $speed eq "auto" ) {
314        return $rapidcity->set_rc_auto( '1', $iid );
315    }
316    elsif ( ( $speed ne "auto" ) and ( $i_auto->{$iid} eq "1" ) ) {
317        return unless ( $rapidcity->set_rc_auto( '2', $iid ) );
318        return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid );
319    }
320    else {
321        return $rapidcity->set_rc_speed_admin( $speeds{$speed}, $iid );
322    }
323}
324
325sub v_index {
326    my $rapidcity = shift;
327    my $partial   = shift;
328
329    return $rapidcity->rc_vlan_id($partial);
330}
331
332sub i_vlan {
333    my $rapidcity = shift;
334    my $partial   = shift;
335
336    my $i_pvid = $rapidcity->rc_i_vlan_pvid($partial) || {};
337
338    return $i_pvid;
339}
340
341sub i_vlan_membership {
342    my $rapidcity = shift;
343
344    my $rc_v_ports = $rapidcity->rc_vlan_members();
345
346    my $i_vlan_membership = {};
347    foreach my $vlan ( keys %$rc_v_ports ) {
348        my $portlist = $rc_v_ports->{$vlan};
349        my $ret      = [];
350
351        # Convert portlist bit array to ifIndex array
352        for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) {
353            push( @{$ret}, $i ) if ( @$portlist[$i] );
354        }
355
356        #Create HoA ifIndex -> VLAN array
357        foreach my $port ( @{$ret} ) {
358            push( @{ $i_vlan_membership->{$port} }, $vlan );
359        }
360    }
361    return $i_vlan_membership;
362}
363
364sub i_vlan_membership_untagged {
365    my $rapidcity = shift;
366
367    # Traditionally access ports have one VLAN untagged and trunk ports have
368    # one or more VLANs all tagged
369    # Newer VOSS device trunks have PerformTagging true or false and also can
370    # UntagDefaultVlan
371    # Newer BOSS device trunks have four PerformTagging options true, false,
372    # tagPvidOnly, and untagPvidOnly
373
374    my $p_members = $rapidcity->i_vlan_membership();
375    my $i_vlan = $rapidcity->i_vlan();
376    my $p_tag_opt = $rapidcity->rcVlanPortPerformTagging() || {};
377    my $p_untag_def = $rapidcity->rcVlanPortUntagDefaultVlan() || {};
378    my $p_type = $rapidcity->rcVlanPortType() || {};
379
380    my $members_untagged = {};
381    foreach my $port ( keys %$p_type ) {
382        my $type = $p_type->{$port};
383        next unless $type;
384
385        # Easiest case first access ports
386        if ($type eq 'access') {
387            # Access ports should only have one VLAN and it should be
388            # untagged
389            $members_untagged->{$port} = $p_members->{$port};
390        }
391        else {
392            # If PerformTagging has a value do all checks otherwise we're
393            # just a trunk and everything is tagged
394            if ($p_tag_opt->{$port}) {
395                if ($p_tag_opt->{$port} eq 'untagPvidOnly') {
396                    my $vlan = $i_vlan->{$port};
397                    push( @{ $members_untagged->{$port} }, $vlan );
398                }
399                elsif (($p_tag_opt->{$port} eq 'true') and
400                       ($p_untag_def->{$port} and $p_untag_def->{$port} eq 'true'))
401                {
402                    my $vlan = $i_vlan->{$port};
403                    push( @{ $members_untagged->{$port} }, $vlan );
404                }
405                elsif ($p_tag_opt->{$port} eq 'tagPvidOnly') {
406                    my $vlan = $i_vlan->{$port};
407                    my @arr = $p_members->{$port};
408                    my $index = 0;
409                    my $count = scalar @arr;
410                    $index++ until $arr[$index] eq $vlan or $index==$count;
411                    splice(@arr, $index, 1);
412                    $members_untagged->{$port} = @arr;
413                }
414                # Don't know if this is a legal configuration, but included
415                # for completeness
416                elsif ($p_tag_opt->{$port} eq 'false') {
417                    $members_untagged->{$port} = $p_members->{$port};
418                }
419                else {
420                    next;
421                }
422            }
423        }
424    }
425
426    return $members_untagged;
427}
428
429sub set_i_pvid {
430    my $rapidcity = shift;
431    my ( $vlan_id, $ifindex ) = @_;
432
433    return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
434
435    unless ( $rapidcity->set_rc_i_vlan_pvid( $vlan_id, $ifindex ) ) {
436        $rapidcity->error_throw(
437            "Unable to change PVID to $vlan_id on IfIndex: $ifindex");
438        return;
439    }
440    return 1;
441}
442
443sub set_i_vlan {
444    my $rapidcity = shift;
445    my ( $new_vlan_id, $ifindex ) = @_;
446
447    return
448        unless ( $rapidcity->_validate_vlan_param( $new_vlan_id, $ifindex ) );
449
450    my $vlan_p_type = $rapidcity->rc_i_vlan_type($ifindex);
451    unless ( $vlan_p_type->{$ifindex} =~ /access/ ) {
452        $rapidcity->error_throw("Not an access port");
453        return;
454    }
455
456    my $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex);
457
458    # Store current untagged VLAN to remove it from the port list later
459    my $old_vlan_id = $i_pvid->{$ifindex};
460
461    # Check that haven't been given the same VLAN we are currently using
462    if ( $old_vlan_id eq $new_vlan_id ) {
463        $rapidcity->error_throw(
464            "Current PVID: $old_vlan_id and New VLAN: $new_vlan_id the same, no change."
465        );
466        return;
467    }
468
469    print "Changing VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n"
470        if $rapidcity->debug();
471
472    # Check if port in forbidden list for the VLAN, haven't seen this used,
473    # but we'll check anyway
474    return
475        unless (
476        $rapidcity->_check_forbidden_ports( $new_vlan_id, $ifindex ) );
477
478    my $old_vlan_members = $rapidcity->rc_vlan_members($old_vlan_id);
479    my $new_vlan_members = $rapidcity->rc_vlan_members($new_vlan_id);
480
481    print "Modifying egress list for VLAN: $new_vlan_id \n"
482        if $rapidcity->debug();
483    my $new_egress
484        = $rapidcity->modify_port_list( $new_vlan_members->{$new_vlan_id},
485        $ifindex, '1' );
486
487    print "Modifying egress list for VLAN: $old_vlan_id \n"
488        if $rapidcity->debug();
489    my $old_egress
490        = $rapidcity->modify_port_list( $old_vlan_members->{$old_vlan_id},
491        $ifindex, '0' );
492
493    my $vlan_set = [
494        [ 'rc_vlan_members', "$new_vlan_id", "$new_egress" ],
495
496        #        ['rc_vlan_members',"$old_vlan_id","$old_egress"],
497    ];
498
499    return
500        unless ( $rapidcity->set_multi($vlan_set) );
501
502    my $vlan_set2 = [ [ 'rc_vlan_members', "$old_vlan_id", "$old_egress" ], ];
503
504    return
505        unless ( $rapidcity->set_multi($vlan_set2) );
506
507 # Set new untagged / native VLAN
508 # Some models/versions do this for us also, so check to see if we need to set
509    $i_pvid = $rapidcity->rc_i_vlan_pvid($ifindex);
510
511    my $cur_i_pvid = $i_pvid->{$ifindex};
512    print "Current PVID: $cur_i_pvid\n" if $rapidcity->debug();
513    unless ( $cur_i_pvid eq $new_vlan_id ) {
514        return unless ( $rapidcity->set_i_pvid( $new_vlan_id, $ifindex ) );
515    }
516
517    print
518        "Successfully changed VLAN: $old_vlan_id to $new_vlan_id on IfIndex: $ifindex\n"
519        if $rapidcity->debug();
520    return 1;
521}
522
523sub set_add_i_vlan_tagged {
524    my $rapidcity = shift;
525    my ( $vlan_id, $ifindex ) = @_;
526
527    return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
528
529    print "Adding VLAN: $vlan_id to IfIndex: $ifindex\n"
530        if $rapidcity->debug();
531
532# Check if port in forbidden list for the VLAN, haven't seen this used, but we'll check anyway
533    return
534        unless ( $rapidcity->_check_forbidden_ports( $vlan_id, $ifindex ) );
535
536    my $iv_members = $rapidcity->rc_vlan_members($vlan_id);
537
538    print "Modifying egress list for VLAN: $vlan_id \n"
539        if $rapidcity->debug();
540    my $new_egress
541        = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex,
542        '1' );
543
544    unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) {
545        print
546            "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n"
547            if $rapidcity->debug();
548        return;
549    }
550
551    print
552        "Successfully added IfIndex: $ifindex to VLAN: $vlan_id egress list\n"
553        if $rapidcity->debug();
554    return 1;
555}
556
557sub set_remove_i_vlan_tagged {
558    my $rapidcity = shift;
559    my ( $vlan_id, $ifindex ) = @_;
560
561    return unless ( $rapidcity->_validate_vlan_param( $vlan_id, $ifindex ) );
562
563    print "Removing VLAN: $vlan_id from IfIndex: $ifindex\n"
564        if $rapidcity->debug();
565
566    my $iv_members = $rapidcity->rc_vlan_members($vlan_id);
567
568    print "Modifying egress list for VLAN: $vlan_id \n"
569        if $rapidcity->debug();
570    my $new_egress
571        = $rapidcity->modify_port_list( $iv_members->{$vlan_id}, $ifindex,
572        '0' );
573
574    unless ( $rapidcity->set_qb_v_egress( $new_egress, $vlan_id ) ) {
575        print
576            "Error: Unable to add VLAN: $vlan_id to Index: $ifindex egress list.\n"
577            if $rapidcity->debug();
578        return;
579    }
580
581    print
582        "Successfully removed IfIndex: $ifindex from VLAN: $vlan_id egress list\n"
583        if $rapidcity->debug();
584    return 1;
585}
586
587sub set_create_vlan {
588    my $rapidcity = shift;
589    my ( $name, $vlan_id ) = @_;
590    return unless ( $vlan_id =~ /\d+/ );
591
592    my $vlan_set = [
593        [ 'v_name',          "$vlan_id", "$name" ],
594        [ 'rc_vlan_rstatus', "$vlan_id", 4 ],
595    ];
596
597    unless ( $rapidcity->set_multi($vlan_set) ) {
598        print "Error: Unable to create VLAN: $vlan_id\n"
599            if $rapidcity->debug();
600        return;
601    }
602
603    return 1;
604}
605
606sub set_delete_vlan {
607    my $rapidcity = shift;
608    my ($vlan_id) = shift;
609    return unless ( $vlan_id =~ /^\d+$/ );
610
611    unless ( $rapidcity->set_rc_vlan_rstatus( '6', $vlan_id ) ) {
612        $rapidcity->error_throw("Unable to delete VLAN: $vlan_id");
613        return;
614    }
615    return 1;
616}
617
618#
619# These are internal methods and are not documented.  Do not use directly.
620#
621sub _check_forbidden_ports {
622    my $rapidcity = shift;
623    my ( $vlan_id, $ifindex ) = @_;
624
625    my $iv_forbidden = $rapidcity->rc_vlan_no_join($vlan_id);
626
627    my @forbidden_ports
628        = split( //, unpack( "B*", $iv_forbidden->{$vlan_id} ) );
629    print "Forbidden ports: @forbidden_ports\n" if $rapidcity->debug();
630    if ( defined( $forbidden_ports[$ifindex] )
631        and ( $forbidden_ports[$ifindex] eq "1" ) )
632    {
633        $rapidcity->error_throw(
634            "IfIndex: $ifindex in forbidden list for VLAN: $vlan_id unable to add"
635        );
636        return;
637    }
638    return 1;
639}
640
641sub _validate_vlan_param {
642    my $rapidcity = shift;
643    my ( $vlan_id, $ifindex ) = @_;
644
645    # VID and ifIndex should both be numeric
646    unless (defined $vlan_id
647        and defined $ifindex
648        and $vlan_id =~ /^\d+$/
649        and $ifindex =~ /^\d+$/ )
650    {
651        $rapidcity->error_throw("Invalid parameter");
652        return;
653    }
654
655    # Check that ifIndex exists on device
656    my $index = $rapidcity->interfaces($ifindex);
657
658    unless ( exists $index->{$ifindex} ) {
659        $rapidcity->error_throw("ifIndex $ifindex does not exist");
660        return;
661    }
662
663    #Check that VLAN exists on device
664    unless ( $rapidcity->rc_vlan_id($vlan_id) ) {
665        $rapidcity->error_throw(
666            "VLAN $vlan_id does not exist or is not operational");
667        return;
668    }
669
670    return 1;
671}
672
673sub agg_ports {
674    my $rapidcity = shift;
675
676    # TODO: implement partial
677    my $ports  = $rapidcity->rc_mlt_ports;
678    my $trunks = $rapidcity->rc_mlt_index;
679    my $dps    = $rapidcity->rc_mlt_dp || {};
680
681    return {}
682        unless ref {} eq ref $trunks
683            and scalar keys %$trunks
684            and ref {} eq ref $ports
685            and scalar keys %$ports;
686
687    my $ret = {};
688    foreach my $m ( keys %$trunks ) {
689        my $idx = $trunks->{$m};
690        next unless $idx;
691        $idx = $dps->{$m} ? $dps->{$m} : $idx;
692        my $portlist = $ports->{$m};
693        next unless $portlist;
694        for ( my $i = 0; $i <= scalar(@$portlist); $i++ ) {
695            $ret->{$i} = $idx if ( @$portlist[$i] );
696        }
697    }
698
699    return $ret;
700}
701
702# break up the rcBridgeSpbmMacEntry INDEX into ISID and MAC Address.
703sub _spbm_fdbtable_index {
704    my $idx    = shift;
705    my @values = split( /\./, $idx );
706    my $isid = shift(@values);
707    return ( $isid, join( ':', map { sprintf "%02x", $_ } @values ) );
708}
709
710sub rc_spbm_fw_mac {
711    my $rapidcity  = shift;
712    my $partial = shift;
713
714    my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
715    my $spbm_fw_mac  = {};
716    foreach my $idx ( keys %$spbm_fw_ports ) {
717        my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
718        $spbm_fw_mac->{$idx} = $mac;
719    }
720    return $spbm_fw_mac;
721}
722
723sub rc_spbm_fw_isid {
724    my $rapidcity  = shift;
725    my $partial = shift;
726
727    my $spbm_fw_ports = $rapidcity->rc_spbm_fw_port($partial);
728    my $spbm_fw_isid  = {};
729    foreach my $idx ( keys %$spbm_fw_ports ) {
730        my ( $isid, $mac ) = _spbm_fdbtable_index($idx);
731        $spbm_fw_isid->{$idx} = $isid;
732    }
733    return $spbm_fw_isid;
734}
735
736sub stp_ver {
737    my $rapidcity = shift;
738
739    return $rapidcity->rcSysSpanningTreeOperMode()
740      || $rapidcity->SUPER::stp_ver();
741}
742
743# RSTP and ieee8021d operating modes do not populate RAPID-CITY::rcStgTable
744# or RAPID-CITY::rcStgPortTable but do populate BRIDGE-MIB so check both
745sub stp_i_mac {
746    my $rapidcity = shift;
747
748    return $rapidcity->rc_stp_i_mac()
749      || $rapidcity->SUPER::stp_i_mac();
750}
751
752sub stp_i_time {
753    my $rapidcity = shift;
754
755    return $rapidcity->rc_stp_i_time()
756      || $rapidcity->SUPER::stp_i_time();
757}
758
759sub stp_i_ntop {
760    my $rapidcity = shift;
761
762    return $rapidcity->rc_stp_i_ntop()
763      || $rapidcity->SUPER::stp_i_ntop();
764}
765
766sub stp_i_root {
767    my $rapidcity = shift;
768
769    return $rapidcity->rc_stp_i_root()
770      || $rapidcity->SUPER::stp_i_root();
771}
772
773sub stp_i_root_port {
774    my $rapidcity = shift;
775
776    return $rapidcity->rc_stp_i_root_port()
777      || $rapidcity->SUPER::stp_i_root_port();
778}
779
780sub stp_i_priority {
781    my $rapidcity = shift;
782
783    return $rapidcity->rc_stp_i_priority()
784      || $rapidcity->SUPER::stp_i_priority();
785}
786
787sub stp_p_id {
788    my $rapidcity = shift;
789
790    return $rapidcity->rc_stp_p_id()
791      || $rapidcity->SUPER::stp_p_id();
792}
793
794sub stp_p_priority {
795    my $rapidcity = shift;
796
797    return $rapidcity->rc_stp_p_priority()
798      || $rapidcity->SUPER::stp_p_priority();
799}
800
801sub stp_p_state {
802    my $rapidcity = shift;
803
804    return $rapidcity->rc_stp_p_state()
805      || $rapidcity->SUPER::stp_p_state();
806}
807
808sub stp_p_cost {
809    my $rapidcity = shift;
810
811    return $rapidcity->rc_stp_p_cost()
812      || $rapidcity->SUPER::stp_p_cost();
813}
814
815sub stp_p_root {
816    my $rapidcity = shift;
817
818    return $rapidcity->rc_stp_p_root()
819      || $rapidcity->SUPER::stp_p_root();
820}
821
822sub stp_p_bridge {
823    my $rapidcity = shift;
824
825    return $rapidcity->rc_stp_p_bridge()
826      || $rapidcity->SUPER::stp_p_bridge();
827}
828
829sub stp_p_port {
830    my $rapidcity = shift;
831
832    return $rapidcity->rc_stp_p_port()
833      || $rapidcity->SUPER::stp_p_port();
834}
835
836sub mst_vlan2instance {
837    my $rapidcity = shift;
838    my $partial   = shift;
839
840    return $rapidcity->rcVlanStgId($partial);
841}
842
843sub i_bpduguard_enabled {
844    my $rapidcity    = shift;
845    my $partial = shift;
846
847    return $rapidcity->rcPortBpduFilteringOperEnabled();
848}
849
850sub i_stp_state {
851    my $rapidcity = shift;
852    my $partial   = shift;
853
854    my $bp_index    = $rapidcity->bp_index($partial);
855    my $stp_p_state = $rapidcity->dot1dStpPortState($partial);
856
857    my %i_stp_state;
858
859    foreach my $index ( keys %$stp_p_state ) {
860        my $state = $stp_p_state->{$index};
861        my $iid   = $bp_index->{$index};
862        next unless defined $iid;
863        next unless defined $state;
864        $i_stp_state{$iid} = $state;
865    }
866
867    return \%i_stp_state;
868}
869
8701;
871
872__END__
873
874=head1 NAME
875
876SNMP::Info::RapidCity - SNMP Interface to the Avaya/Nortel RapidCity MIB
877
878=head1 AUTHOR
879
880Eric Miller
881
882=head1 SYNOPSIS
883
884 # Let SNMP::Info determine the correct subclass for you.
885 my $rapidcity = new SNMP::Info(
886                        AutoSpecify => 1,
887                        Debug       => 1,
888                        # These arguments are passed directly to SNMP::Session
889                        DestHost    => 'myswitch',
890                        Community   => 'public',
891                        Version     => 2
892                        )
893    or die "Can't connect to DestHost.\n";
894
895 my $class = $rapidcity->class();
896 print "SNMP::Info determined this device to fall under subclass : $class\n";
897
898=head1 DESCRIPTION
899
900SNMP::Info::RapidCity is a subclass of SNMP::Info that provides an interface
901to the C<RAPID-CITY> MIB.  This MIB is used across the Avaya/Nortel Ethernet
902Routing Switch and Ethernet Switch product lines (Formerly known as Passport,
903BayStack, and Accelar), as well as, the VSP 9000 and 7000 series.
904
905Use or create in a subclass of SNMP::Info.  Do not use directly.
906
907=head2 Inherited Classes
908
909None.
910
911=head2 Required MIBs
912
913=over
914
915=item F<RAPID-CITY>
916
917=item F<NORTEL-NETWORKS-RAPID-SPANNING-TREE-MIB>
918
919=item F<NORTEL-NETWORKS-MULTIPLE-SPANNING-TREE-MIB>
920
921=back
922
923=head1 GLOBALS
924
925These are methods that return scalar values from SNMP
926
927=over
928
929=item  $rapidcity->rc_base_mac()
930
931(C<rc2kChassisBaseMacAddr>)
932
933=item  $rapidcity->rc_serial()
934
935(C<rcChasSerialNumber>)
936
937=item  $rapidcity->rc_ch_rev()
938
939(C<rcChasHardwareRevision>)
940
941=item  $rapidcity->chassis()
942
943(C<rcChasType>)
944
945=item  $rapidcity->slots()
946
947(C<rcChasNumSlots>)
948
949=item  $rapidcity->rc_virt_ip()
950
951(C<rcSysVirtualIpAddr>)
952
953=item  $rapidcity->rc_virt_mask()
954
955(C<rcSysVirtualNetMask>)
956
957=item  $rapidcity->tftp_host()
958
959(C<rcTftpHost>)
960
961=item  $rapidcity->tftp_file()
962
963(C<rcTftpFile>)
964
965=item  $rapidcity->tftp_action()
966
967(C<rcTftpAction>)
968
969=item  $rapidcity->tftp_result()
970
971(C<rcTftpResult>)
972
973=back
974
975=head2 Overrides
976
977=over
978
979=item  $rapidcity->serial()
980
981Returns serial number of the chassis
982
983=item $rapidcity->stp_ver()
984
985Returns the particular STP version running on this device.
986
987Values: C<nortelStpg>, C<pvst>, C<rstp>, C<mstp>, C<ieee8021d>
988
989(C<rcSysSpanningTreeOperMode>)
990
991=back
992
993=head1 TABLE METHODS
994
995These are methods that return tables of information in the form of a reference
996to a hash.
997
998=over
999
1000=item $rapidcity->i_duplex()
1001
1002Returns reference to map of IIDs to current link duplex.
1003
1004=item $rapidcity->i_duplex_admin()
1005
1006Returns reference to hash of IIDs to admin duplex setting.
1007
1008=item $rapidcity->i_vlan()
1009
1010Returns a mapping between C<ifIndex> and the PVID or default VLAN.
1011
1012=item $rapidcity->i_vlan_membership()
1013
1014Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
1015IDs.  These are the VLANs which are members of the egress list for the port.
1016
1017  Example:
1018  my $interfaces = $rapidcity->interfaces();
1019  my $vlans      = $rapidcity->i_vlan_membership();
1020
1021  foreach my $iid (sort keys %$interfaces) {
1022    my $port = $interfaces->{$iid};
1023    my $vlan = join(',', sort(@{$vlans->{$iid}}));
1024    print "Port: $port VLAN: $vlan\n";
1025  }
1026
1027=item $rapidcity->i_vlan_membership_untagged()
1028
1029Returns reference to hash of arrays: key = C<ifIndex>, value = array of VLAN
1030IDs.  These are the VLANs which are members of the untagged egress list for
1031the port.
1032
1033=item $rapidcity->v_index()
1034
1035Returns VLAN IDs
1036
1037(C<rcVlanId>)
1038
1039=item $rapidcity->agg_ports()
1040
1041Returns a HASH reference mapping from slave to master port for each member of
1042a port bundle (MLT) on the device. Keys are ifIndex of the slave ports,
1043Values are ifIndex of the corresponding master ports.
1044
1045=item $rapidcity->i_stp_state()
1046
1047Returns the mapping of (C<dot1dStpPortState>) to the interface
1048index (iid).
1049
1050=item $rapidcity->mst_vlan2instance()
1051
1052Returns the mapping of VLAN to Spanning Tree Group (STG) instance in the
1053form of a hash reference with key = VLAN id, value = STG instance
1054
1055(C<rcVlanStgId>)
1056
1057=item $rapidcity->i_bpduguard_enabled()
1058
1059Returns true or false depending on whether C<BpduGuard> is enabled on a given
1060port.  Format is a hash reference with key = C<ifIndex>, value = [true|false]
1061
1062(C<rcPortBpduFilteringOperEnabled>)
1063
1064=back
1065
1066=head2 RAPID-CITY Port Table (C<rcPortTable>)
1067
1068=over
1069
1070=item $rapidcity->rc_index()
1071
1072(C<rcPortIndex>)
1073
1074=item $rapidcity->rc_duplex()
1075
1076(C<rcPortOperDuplex>)
1077
1078=item $rapidcity->rc_duplex_admin()
1079
1080(C<rcPortAdminDuplex>)
1081
1082=item $rapidcity->rc_speed_admin()
1083
1084(C<rcPortAdminSpeed>)
1085
1086=item $rapidcity->rc_auto()
1087
1088(C<rcPortAutoNegotiate>)
1089
1090=item $rapidcity->rc_alias()
1091
1092(C<rcPortName>)
1093
1094=back
1095
1096=head2 RAPID-CITY CPU Ethernet Port Table (C<rc2kCpuEthernetPortTable>)
1097
1098=over
1099
1100=item $rapidcity->rc_cpu_ifindex()
1101
1102(C<rc2kCpuEthernetPortIfIndex>)
1103
1104=item $rapidcity->rc_cpu_admin()
1105
1106(C<rc2kCpuEthernetPortAdminStatus>)
1107
1108=item $rapidcity->rc_cpu_oper()
1109
1110(C<rc2kCpuEthernetPortOperStatus>)
1111
1112=item $rapidcity->rc_cpu_ip()
1113
1114(C<rc2kCpuEthernetPortAddr>)
1115
1116=item $rapidcity->rc_cpu_mask()
1117
1118(C<rc2kCpuEthernetPortMask>)
1119
1120=item $rapidcity->rc_cpu_auto()
1121
1122(C<rc2kCpuEthernetPortAutoNegotiate>)
1123
1124=item $rapidcity->rc_cpu_duplex_admin()
1125
1126(C<rc2kCpuEthernetPortAdminDuplex>)
1127
1128=item $rapidcity->rc_cpu_duplex()
1129
1130(C<rc2kCpuEthernetPortOperDuplex>)
1131
1132=item $rapidcity->rc_cpu_speed_admin()
1133
1134(C<rc2kCpuEthernetPortAdminSpeed>)
1135
1136=item $rapidcity->rc_cpu_speed_oper()
1137
1138(C<rc2kCpuEthernetPortOperSpeed>)
1139
1140=item $rapidcity->rc_cpu_mac()
1141
1142(C<rc2kCpuEthernetPortMgmtMacAddr>)
1143
1144=back
1145
1146=head2 RAPID-CITY VLAN Port Table (C<rcVlanPortTable>)
1147
1148=over
1149
1150=item $rapidcity->rc_i_vlan_if()
1151
1152(C<rcVlanPortIndex>)
1153
1154=item $rapidcity->rc_i_vlan_num()
1155
1156(C<rcVlanPortNumVlanIds>)
1157
1158=item $rapidcity->rc_i_vlan()
1159
1160(C<rcVlanPortVlanIds>)
1161
1162=item $rapidcity->rc_i_vlan_type()
1163
1164(C<rcVlanPortType>)
1165
1166=item $rapidcity->rc_i_vlan_pvid()
1167
1168(C<rcVlanPortDefaultVlanId>)
1169
1170=item $rapidcity->rc_i_vlan_tag()
1171
1172(C<rcVlanPortPerformTagging>)
1173
1174=back
1175
1176=head2 RAPID-CITY VLAN Table (C<rcVlanTable>)
1177
1178=over
1179
1180=item $rapidcity->rc_vlan_id()
1181
1182(C<rcVlanId>)
1183
1184=item $rapidcity->v_name()
1185
1186(C<rcVlanName>)
1187
1188=item $rapidcity->rc_vlan_color()
1189
1190(C<rcVlanColor>)
1191
1192=item $rapidcity->rc_vlan_if()
1193
1194(C<rcVlanIfIndex>)
1195
1196=item $rapidcity->rc_vlan_stg()
1197
1198(C<rcVlanStgId>)
1199
1200=item $rapidcity->rc_vlan_type()
1201
1202(C<rcVlanType>)
1203
1204=item $rapidcity->rc_vlan_members()
1205
1206(C<rcVlanPortMembers>)
1207
1208=item $rapidcity->rc_vlan_mac()
1209
1210(C<rcVlanMacAddress>)
1211
1212=back
1213
1214=head2 RAPID-CITY IP Address Table (C<rcIpAddrTable>)
1215
1216=over
1217
1218=item $rapidcity->rc_ip_index()
1219
1220(C<rcIpAdEntIfIndex>)
1221
1222=item $rapidcity->rc_ip_addr()
1223
1224(C<rcIpAdEntAddr>)
1225
1226=item $rapidcity->rc_ip_type()
1227
1228(C<rcIpAdEntIfType>)
1229
1230=back
1231
1232=head2 RAPID-CITY Chassis Fan Table (C<rcChasFanTable>)
1233
1234=over
1235
1236=item $rapidcity->rc_fan_op()
1237
1238(C<rcChasFanOperStatus>)
1239
1240=back
1241
1242=head2 RAPID-CITY Power Supply Table (C<rcChasPowerSupplyTable>)
1243
1244=over
1245
1246=item $rapidcity->rc_ps_op()
1247
1248(C<rcChasPowerSupplyOperStatus>)
1249
1250=back
1251
1252=head2 RAPID-CITY Power Supply Detail Table (C<rcChasPowerSupplyDetailTable>)
1253
1254=over
1255
1256=item $rapidcity->rc_ps_type()
1257
1258(C<rcChasPowerSupplyDetailType>)
1259
1260=item $rapidcity->rc_ps_serial()
1261
1262(C<rcChasPowerSupplyDetailSerialNumber>)
1263
1264=item $rapidcity->rc_ps_rev()
1265
1266(C<rcChasPowerSupplyDetailHardwareRevision>)
1267
1268=item $rapidcity->rc_ps_part()
1269
1270(C<rcChasPowerSupplyDetailPartNumber>)
1271
1272=item $rapidcity->rc_ps_detail()
1273
1274(C<rcChasPowerSupplyDetailDescription>)
1275
1276=back
1277
1278=head2 RAPID-CITY Card Table (C<rcCardTable>)
1279
1280=over
1281
1282=item $rapidcity->rc_c_type()
1283
1284(C<rcCardType>)
1285
1286=item $rapidcity->rc_c_serial()
1287
1288(C<rcCardSerialNumber>)
1289
1290=item $rapidcity->rc_c_rev()
1291
1292(C<rcCardHardwareRevision>)
1293
1294=item $rapidcity->rc_c_part()
1295
1296(C<rcCardPartNumber>)
1297
1298=back
1299
1300=head2 RAPID-CITY 2k Card Table (C<rc2kCardTable>)
1301
1302=over
1303
1304=item $rapidcity->rc2k_c_ftype()
1305
1306(C<rc2kCardFrontType>)
1307
1308=item $rapidcity->rc2k_c_fdesc()
1309
1310(C<rc2kCardFrontDescription>)
1311
1312=item $rapidcity->rc2k_c_fserial()
1313
1314(C<rc2kCardFrontSerialNum>)
1315
1316=item $rapidcity->rc2k_c_frev()
1317
1318(C<rc2kCardFrontHwVersion>)
1319
1320=item $rapidcity->rc2k_c_fpart()
1321
1322(C<rc2kCardFrontPartNumber>)
1323
1324=item $rapidcity->rc2k_c_fdate()
1325
1326(C<rc2kCardFrontDateCode>)
1327
1328=item $rapidcity->rc2k_c_fdev()
1329
1330(C<rc2kCardFrontDeviations>)
1331
1332=item $rapidcity->rc2k_c_btype()
1333
1334(C<rc2kCardBackType>)
1335
1336=item $rapidcity->rc2k_c_bdesc()
1337
1338(C<rc2kCardBackDescription>)
1339
1340=item $rapidcity->rc2k_c_bserial()
1341
1342(C<rc2kCardBackSerialNum>)
1343
1344=item $rapidcity->rc2k_c_brev()
1345
1346(C<rc2kCardBackHwVersion>)
1347
1348=item $rapidcity->rc2k_c_bpart()
1349
1350(C<rc2kCardBackPartNumber>)
1351
1352=item $rapidcity->rc2k_c_bdate()
1353
1354(C<rc2kCardBackDateCode>)
1355
1356=item $rapidcity->rc2k_c_bdev()
1357
1358(C<rc2kCardBackDeviations>)
1359
1360=back
1361
1362=head2 RAPID-CITY MDA Card Table (C<rc2kMdaCardTable>)
1363
1364=over
1365
1366=item $rapidcity->rc2k_mda_type()
1367
1368(C<rc2kMdaCardType>)
1369
1370=item $rapidcity->rc2k_mda_desc()
1371
1372(C<rc2kMdaCardDescription>)
1373
1374=item $rapidcity->rc2k_mda_serial()
1375
1376(C<rc2kMdaCardSerialNum>)
1377
1378=item $rapidcity->rc2k_mda_rev()
1379
1380(C<rc2kMdaCardHwVersion>)
1381
1382=item $rapidcity->rc2k_mda_part()
1383
1384(C<rc2kMdaCardPartNumber>)
1385
1386=item $rapidcity->rc2k_mda_date()
1387
1388(C<rc2kMdaCardDateCode>)
1389
1390=item $rapidcity->rc2k_mda_dev()
1391
1392(C<rc2kMdaCardDeviations>)
1393
1394=back
1395
1396=head2 RAPID-CITY Bridge SPBM MAC Table (C<rcBridgeSpbmMacTable>)
1397
1398=over
1399
1400=item $rapidcity->rc_spbm_fw_mac()
1401
1402Returns reference to hash of forwarding table MAC Addresses
1403
1404(C<rcBridgeSpbmMacAddr>)
1405
1406=item $rapidcity->rc_spbm_fw_port()
1407
1408Returns reference to hash of forwarding table entries port interface
1409identifier (iid)
1410
1411(C<rcBridgeSpbmMacCPort>)
1412
1413=item $rapidcity->rc_spbm_fw_status()
1414
1415Returns reference to hash of forwarding table entries status
1416
1417(C<rcBridgeSpbmMacStatus>)
1418
1419=item $rapidcity->rc_spbm_fw_vlan()
1420
1421Returns reference to hash of forwarding table entries Customer VLAN ID
1422
1423(C<rcBridgeSpbmMacCVlanId>)
1424
1425=item $rapidcity->rc_spbm_fw_isid()
1426
1427Returns reference to hash of forwarding table entries ISID
1428
1429(C<rcBridgeSpbmMacIsid>)
1430
1431=back
1432
1433=head2 Spanning Tree Instance Globals
1434
1435C<RSTP> and C<ieee8021d> operating modes do not populate the
1436C<RAPID-CITY::rcStgTable> but do populate F<BRIDGE-MIB>.  These methods check
1437F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
1438
1439=over
1440
1441=item $rapidcity->stp_i_mac()
1442
1443Returns the bridge address
1444
1445=item $rapidcity->stp_i_time()
1446
1447Returns time since last topology change detected. (100ths/second)
1448
1449=item $rapidcity->stp_i_ntop()
1450
1451Returns the total number of topology changes detected.
1452
1453=item $rapidcity->stp_i_root()
1454
1455Returns root of STP.
1456
1457=item $rapidcity->stp_i_root_port()
1458
1459Returns the port number of the port that offers the lowest cost path
1460to the root bridge.
1461
1462=item $rapidcity->stp_i_priority()
1463
1464Returns the port number of the port that offers the lowest cost path
1465to the root bridge.
1466
1467=back
1468
1469=head2 Spanning Tree Protocol Port Table
1470
1471C<RSTP> and C<ieee8021d> operating modes do not populate the
1472C<RAPID-CITY::rcStgPortTable> but do populate F<BRIDGE-MIB>.  These methods
1473check F<RAPID-CITY> first and fall back to F<BRIDGE-MIB>.
1474
1475=over
1476
1477=item $rapidcity->stp_p_id()
1478
1479"The port number of the port for which this entry contains Spanning Tree
1480Protocol management information."
1481
1482=item $rapidcity->stp_p_priority()
1483
1484"The value of the priority field which is contained in the first
1485(in network byte order) octet of the (2 octet long) Port ID.  The other octet
1486of the Port ID is given by the value of C<dot1dStpPort>."
1487
1488=item $rapidcity->stp_p_state()
1489
1490"The port's current state as defined by application of the Spanning Tree
1491Protocol."
1492
1493=item $rapidcity->stp_p_cost()
1494
1495"The contribution of this port to the path cost of paths towards the spanning
1496tree root which include this port."
1497
1498=item $rapidcity->stp_p_root()
1499
1500"The unique Bridge Identifier of the Bridge recorded as the Root in the
1501Configuration BPDUs transmitted by the Designated Bridge for the segment to
1502which the port is attached."
1503
1504=item $rapidcity->stp_p_bridge()
1505
1506"The Bridge Identifier of the bridge which this port considers to be the
1507Designated Bridge for this port's segment."
1508
1509=item $rapidcity->stp_p_port()
1510
1511"The Port Identifier of the port on the Designated Bridge for this port's
1512segment."
1513
1514=back
1515
1516=head1 SET METHODS
1517
1518These are methods that provide SNMP set functionality for overridden methods
1519or provide a simpler interface to complex set operations.  See
1520L<SNMP::Info/"SETTING DATA VIA SNMP"> for general information on set
1521operations.
1522
1523=over
1524
1525=item $rapidcity->set_i_speed_admin(speed, ifIndex)
1526
1527Sets port speed, must be supplied with speed and port C<ifIndex>.  Speed
1528choices are 'auto', '10', '100', '1000'.
1529
1530 Example:
1531 my %if_map = reverse %{$rapidcity->interfaces()};
1532 $rapidcity->set_i_speed_admin('auto', $if_map{'1.1'})
1533    or die "Couldn't change port speed. ",$rapidcity->error(1);
1534
1535=item $rapidcity->set_i_duplex_admin(duplex, ifIndex)
1536
1537Sets port duplex, must be supplied with duplex and port C<ifIndex>.  Speed
1538choices are 'auto', 'half', 'full'.
1539
1540  Example:
1541  my %if_map = reverse %{$rapidcity->interfaces()};
1542  $rapidcity->set_i_duplex_admin('auto', $if_map{'1.1'})
1543    or die "Couldn't change port duplex. ",$rapidcity->error(1);
1544
1545=item $rapidcity->set_i_vlan(vlan, ifIndex)
1546
1547Changes an access (untagged) port VLAN, must be supplied with the numeric
1548VLAN ID and port C<ifIndex>.  This method will modify the port's VLAN
1549membership and PVID (default VLAN).  This method should only be used on end
1550station (non-trunk) ports.
1551
1552  Example:
1553  my %if_map = reverse %{$rapidcity->interfaces()};
1554  $rapidcity->set_i_vlan('2', $if_map{'1.1'})
1555    or die "Couldn't change port VLAN. ",$rapidcity->error(1);
1556
1557=item $rapidcity->set_i_pvid(pvid, ifIndex)
1558
1559Sets port PVID or default VLAN, must be supplied with the numeric VLAN ID and
1560port C<ifIndex>.  This method only changes the PVID, to modify an access
1561(untagged) port use set_i_vlan() instead.
1562
1563  Example:
1564  my %if_map = reverse %{$rapidcity->interfaces()};
1565  $rapidcity->set_i_pvid('2', $if_map{'1.1'})
1566    or die "Couldn't change port PVID. ",$rapidcity->error(1);
1567
1568=item $rapidcity->set_add_i_vlan_tagged(vlan, ifIndex)
1569
1570Adds the port to the egress list of the VLAN, must be supplied with the
1571numeric VLAN ID and port C<ifIndex>.
1572
1573  Example:
1574  my %if_map = reverse %{$rapidcity->interfaces()};
1575  $rapidcity->set_add_i_vlan_tagged('2', $if_map{'1.1'})
1576    or die "Couldn't add port to egress list. ",$rapidcity->error(1);
1577
1578=item $rapidcity->set_remove_i_vlan_tagged(vlan, ifIndex)
1579
1580Removes the port from the egress list of the VLAN, must be supplied with the
1581numeric VLAN ID and port C<ifIndex>.
1582
1583  Example:
1584  my %if_map = reverse %{$rapidcity->interfaces()};
1585  $rapidcity->set_remove_i_vlan_tagged('2', $if_map{'1.1'})
1586    or die "Couldn't add port to egress list. ",$rapidcity->error(1);
1587
1588=item $rapidcity->set_delete_vlan(vlan)
1589
1590Deletes the specified VLAN from the device.
1591
1592=item $rapidcity->set_create_vlan(name, vlan)
1593
1594Creates the specified VLAN on the device.
1595
1596Note:  This method only allows creation of Port type VLANs and does not allow
1597for the setting of the Spanning Tree Group (STG) which defaults to 1.
1598
1599=back
1600
1601=cut
1602