File Coverage

blib/lib/Net/SNMP/Mixin/NXOSDot1qFdb.pm
Criterion Covered Total %
statement 40 60 66.6
branch 10 16 62.5
condition 3 9 33.3
subroutine 12 12 100.0
pod 1 1 100.0
total 66 98 67.3


line stmt bran cond sub pod time code
1             package Net::SNMP::Mixin::NXOSDot1qFdb;
2              
3 4     4   395219 use strict;
  4         13  
  4         130  
4 4     4   23 use warnings;
  4         8  
  4         160  
5              
6             #
7             # store this package name in a handy variable,
8             # used for unambiguous prefix of mixin attributes
9             # storage in object hash
10             #
11             my $prefix = __PACKAGE__;
12              
13             #
14             # this module import config
15             #
16 4     4   23 use Carp ();
  4         9  
  4         110  
17 4     4   546 use Net::SNMP::Mixin::Util qw/idx2val normalize_mac get_init_slot/;
  4         92968  
  4         33  
18              
19             #
20             # this module export config
21             #
22             my @mixin_methods;
23              
24             BEGIN {
25 4     4   2072 @mixin_methods = ( qw/ get_dot1q_fdb_entries /);
26             }
27              
28 4         38 use Sub::Exporter -setup => {
29             exports => [@mixin_methods],
30             groups => { default => [@mixin_methods], },
31 4     4   33 };
  4         9  
32              
33             #
34             # SNMP oid constants used in this module
35             #
36             use constant {
37 4         1644 DOT1Q_TP_FDB_TABLE => '1.3.6.1.2.1.17.7.1.2.2',
38             DOT1Q_TP_FDB_PORT => '1.3.6.1.2.1.17.7.1.2.2.1.2',
39             DOT1Q_TP_FDB_STATUS => '1.3.6.1.2.1.17.7.1.2.2.1.3',
40              
41 4     4   2050 };
  4         8  
42              
43             =head1 NAME
44              
45             Net::SNMP::Mixin::NXOSDot1qFdb - mixin class for 802.1-Q switch forwarding databases
46              
47             =head1 VERSION
48              
49             Version 0.01
50              
51             =cut
52              
53             our $VERSION = '0.01';
54              
55             =head1 SYNOPSIS
56              
57             use Net::SNMP;
58             use Net::SNMP::Mixin;
59              
60             my $session = Net::SNMP->session( -hostname => 'foo.bar.com' );
61             $session->mixer('Net::SNMP::Mixin::NXOSDot1qFdb');
62             $session->init_mixins();
63             snmp_dispatcher() if $session->nonblocking;
64             $session->init_ok();
65             die $session->errors if $session->errors;
66              
67             foreach my $fdb_entry ( $session->get_dot1q_fdb_entries() ) {
68             my $mac = $fdb_entry->{MacAddress};
69             my $vlan_id = $fdb_entry->{vlanId};
70             my $port = $fdb_entry->{dot1dBasePort};
71             my $status = $fdb_entry->{fdbStatus};
72              
73             print "$mac, $vlan_id, $port, $status\n";
74             }
75              
76             =head1 DESCRIPTION
77              
78             A Net::SNMP mixin class for forwarding database info of NXOS 802.1-Q limited MIBs.
79              
80             =head1 MIXIN METHODS
81              
82             =head2 B<< @fdb = OBJ->get_dot1q_fdb_entries() >>
83              
84             Returns a list of fdb entries. Every list element is a reference to a hash with the following fields and values:
85              
86             {
87             MacAddress => 'XX:XX:XX:XX:XX:XX',
88             dot1dBasePort => Integer,
89             vlanId => Integer,
90             fdbStatus => Integer,
91             fdbStatusString => String,
92             }
93              
94             =over
95              
96             =item MacAddress
97              
98             MacAddress received, in normalized IEEE form XX:XX:XX:XX:XX:XX.
99              
100             =item dot1dBasePort
101              
102             The receiving bride-port for the MAC address.
103              
104             =item vlanId
105              
106             Every MacAdress is related to a distinct vlanId.
107              
108             =item fdbStatus
109              
110             The status of this entry. The meanings of the values are:
111              
112             1 = other
113             2 = invalid
114             3 = learned
115             4 = self
116             5 = mgmt
117              
118             For more information please see the corresponding Q-BRIDGE-MIB.
119              
120             =item fdbStatusString
121              
122             The status of this entry in string form, see above.
123              
124             =back
125              
126             =cut
127              
128             sub get_dot1q_fdb_entries {
129 1     1 1 32207 my $session = shift;
130 1         6 my $agent = $session->hostname;
131              
132 1 50       11 Carp::croak "$agent: '$prefix' not initialized,"
133             unless $session->init_ok($prefix);
134              
135             #
136             # the port's current state translation table
137             #
138 0         0 my %fdp_entry_status_enum = (
139             1 => 'other',
140             2 => 'invalid',
141             3 => 'learned',
142             4 => 'self',
143             5 => 'mgmt',
144             );
145              
146             # stash for return values
147 0         0 my @fdb_entries = ();
148              
149 0         0 my ( @digits, $vlan_id, $mac, $mac_string, $port, $status, $status_string );
150              
151             # index is VlanId.MacAddress
152 0         0 foreach my $idx ( keys %{ $session->{$prefix}{dot1qTpFdbPort} } ) {
  0         0  
153 0         0 $port = $session->{$prefix}{dot1qTpFdbPort}{$idx};
154 0         0 $status = $session->{$prefix}{dot1qTpFdbStatus}{$idx};
155              
156             # the snmp get_table() isn't a snapshot, it can be, that
157             # the MAC has already timeout in the FDB when the
158             # status is fetched
159 0 0 0     0 next unless defined $port && defined $status;
160              
161 0         0 $status_string = $fdp_entry_status_enum{$status};
162              
163             # split the idx to vlan_id and mac address
164             # index is VlanId.MacAddress, value is the bridge port
165 0         0 @digits = split /\./, $idx;
166              
167 0         0 $vlan_id = $digits[0];
168              
169 0         0 $mac = pack( 'C6', @digits[ 1 .. 6 ] );
170 0         0 $mac_string = normalize_mac($mac);
171              
172 0         0 push @fdb_entries,
173             {
174             dot1dBasePort => $port,
175             MacAddress => $mac_string,
176             vlanId => $vlan_id,
177             fdbStatus => $status,
178             fdbStatusString => $status_string,
179             };
180             }
181              
182 0         0 return @fdb_entries;
183             }
184              
185             =head1 INITIALIZATION
186              
187             =cut
188              
189             =head2 B<< OBJ->_init($reload) >>
190              
191             Fetch the fdb related snmp values from the host. Don't call this method direct!
192              
193             =cut
194              
195             #
196             # due to the asynchron nature, we don't know what init job is really the last, we decrement
197             # the value after each callback
198             #
199 4     4   35 use constant THIS_INIT_JOBS => 1;
  4         9  
  4         1862  
200              
201             sub _init {
202 4     4   9067 my ( $session, $reload ) = @_;
203 4         16 my $agent = $session->hostname;
204              
205             die "$agent: $prefix already initialized and reload not forced.\n"
206             if exists get_init_slot($session)->{$prefix}
207 4 50 66     46 && get_init_slot($session)->{$prefix} == 0
      33        
208             && not $reload;
209              
210             # set number of async init jobs for proper initialization
211 4         116 get_init_slot($session)->{$prefix} = THIS_INIT_JOBS;
212              
213 4         45 _fetch_dot1q_tp_fdb_entries($session);
214 4 100       33 return if $session->error;
215              
216 2         13 return 1;
217             }
218              
219             =head1 PRIVATE METHODS
220              
221             Only for developers or maintainers.
222              
223             =head2 B<< _fetch_dot1q_tp_fdb_table() >>
224              
225             Fetch the forwarding databases from the dot1qTpFdbTable once during object initialization.
226              
227             =cut
228              
229             sub _fetch_dot1q_tp_fdb_entries() {
230 4     4   10 my $session = shift;
231 4         19 my $result;
232              
233             # fetch the forwarding databases from dot1qTpFdbTable
234 4 100       26 $result = $session->get_entries(
235             -columns => [ DOT1Q_TP_FDB_PORT, DOT1Q_TP_FDB_STATUS ],
236              
237             # define callback if in nonblocking mode
238             $session->nonblocking
239             ? ( -callback => \&_dot1q_tp_fdb_entries_cb )
240             : (),
241             );
242              
243 4 100       2010984 return unless defined $result;
244 2 50       21 return 1 if $session->nonblocking;
245              
246             # call the callback function in blocking mode by hand
247 0         0 _dot1q_tp_fdb_entries_cb($session);
248              
249             }
250              
251             sub _dot1q_tp_fdb_entries_cb {
252 2     2   2005224 my $session = shift;
253 2         8 my $vbl = $session->var_bind_list;
254              
255 2 50       23 return unless defined $vbl;
256              
257             # mangle result table to get plain idx->value
258             # index is fdbId.MacAddress, value is the bridge port
259 0           $session->{$prefix}{dot1qTpFdbPort} = idx2val( $vbl, DOT1Q_TP_FDB_PORT );
260              
261             # mangle result table to get plain idx->value
262             # index is fdbId.MacAddress, value is the entry status
263 0           $session->{$prefix}{dot1qTpFdbStatus} = idx2val( $vbl, DOT1Q_TP_FDB_STATUS );
264              
265             # this init job is finished
266 0           get_init_slot($session)->{$prefix}--;
267              
268 0           return 1;
269             }
270              
271             =head1 SEE ALSO
272              
273             L<< Net::SNMP::Mixin::Dot1dBase >> for a mapping between ifIndexes and dot1dBasePorts.
274              
275             =head1 REQUIREMENTS
276              
277             L<< Net::SNMP >>, L<< Net::SNMP::Mixin >>
278              
279             =head1 BUGS, PATCHES & FIXES
280              
281             There are no known bugs at the time of this release. However, if you spot a bug or are experiencing difficulties that are not explained within the POD documentation, please submit a bug to the RT system (see link below). However, it would help greatly if you are able to pinpoint problems or even supply a patch.
282              
283             Fixes are dependant upon their severity and my availablity. Should a fix not be forthcoming, please feel free to (politely) remind me by sending an email to gaissmai@cpan.org .
284              
285             RT: http://rt.cpan.org/Public/Dist/Display.html?Name=Net-SNMP-Mixin-NXOSDot1qFdb
286              
287             =head1 AUTHOR
288              
289             Karl Gaissmaier
290              
291             =head1 COPYRIGHT & LICENSE
292              
293             Copyright 2020 Karl Gaissmaier, all rights reserved.
294              
295             This program is free software; you can redistribute it and/or modify it
296             under the same terms as Perl itself.
297              
298             =cut
299              
300             unless ( caller() ) {
301             print "$prefix compiles and initializes successful.\n";
302             }
303              
304             1;
305              
306             # vim: sw=2