Missed two merges
[torrus-plus.git] / src / lib / Torrus / DevDiscover / CiscoIOS.pm
blobaf6b28911d00b52376dd1c1f88473eacb4c8aab2
1 # Copyright (C) 2002 Stanislav Sinyagin
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17 # $Id$
18 # Stanislav Sinyagin <ssinyagin@yahoo.com>
20 # Cisco IOS devices discovery
22 package Torrus::DevDiscover::CiscoIOS;
24 use strict;
25 use warnings;
27 use Torrus::Log;
29 our $VERSION = 1.0;
31 $Torrus::DevDiscover::registry{'CiscoIOS'} = {
32 'sequence' => 500,
33 'checkdevtype' => \&checkdevtype,
34 'discover' => \&discover,
35 'buildConfig' => \&buildConfig
39 our %oiddef =
41 # CISCO-SMI
42 'ciscoProducts' => '1.3.6.1.4.1.9.1',
43 # CISCO-PRODUCTS-MIB
44 'ciscoLS1010' => '1.3.6.1.4.1.9.1.107',
45 # CISCO-IMAGE-MIB
46 'ciscoImageTable' => '1.3.6.1.4.1.9.9.25.1.1',
47 # CISCO-ENHANCED-IMAGE-MIB
48 'ceImageTable' => '1.3.6.1.4.1.9.9.249.1.1.1',
49 # OLD-CISCO-MEMORY-MIB
50 'bufferElFree' => '1.3.6.1.4.1.9.2.1.9.0',
51 # CISCO-IPSEC-FLOW-MONITOR-MIB
52 'cipSecGlobalHcInOctets' => '1.3.6.1.4.1.9.9.171.1.3.1.4.0',
53 # CISCO-BGP4-MIB
54 'cbgpPeerAddrFamilyName' => '1.3.6.1.4.1.9.9.187.1.2.3.1.3',
55 'cbgpPeerAcceptedPrefixes' => '1.3.6.1.4.1.9.9.187.1.2.4.1.1',
56 'cbgpPeerPrefixAdminLimit' => '1.3.6.1.4.1.9.9.187.1.2.4.1.3',
57 # CISCO-CAR-MIB
58 'ccarConfigTable' => '1.3.6.1.4.1.9.9.113.1.1.1',
59 'ccarConfigType' => '1.3.6.1.4.1.9.9.113.1.1.1.1.3',
60 'ccarConfigAccIdx' => '1.3.6.1.4.1.9.9.113.1.1.1.1.4',
61 'ccarConfigRate' => '1.3.6.1.4.1.9.9.113.1.1.1.1.5',
62 'ccarConfigLimit' => '1.3.6.1.4.1.9.9.113.1.1.1.1.6',
63 'ccarConfigExtLimit' => '1.3.6.1.4.1.9.9.113.1.1.1.1.7',
64 'ccarConfigConformAction' => '1.3.6.1.4.1.9.9.113.1.1.1.1.8',
65 'ccarConfigExceedAction' => '1.3.6.1.4.1.9.9.113.1.1.1.1.9',
66 # CISCO-VPDN-MGMT-MIB
67 'cvpdnSystemTunnelTotal' => '1.3.6.1.4.1.9.10.24.1.1.4.1.2',
68 # CISCO-WAN-3G-MIB
69 'c3gStandard' => '1.3.6.1.4.1.9.9.661.1.1.1.1',
70 # CISCO-PORT-QOS-MIB
71 'cportQosDropPkts' => '1.3.6.1.4.1.9.9.189.1.3.2.1.7',
75 # Not all interfaces are normally needed to monitor.
76 # You may override the interface filtering in devdiscover-siteconfig.pl:
77 # redefine $Torrus::DevDiscover::CiscoIOS::interfaceFilter
78 # or define $Torrus::DevDiscover::CiscoIOS::interfaceFilterOverlay
80 our $interfaceFilter;
81 our $interfaceFilterOverlay;
82 my %ciscoInterfaceFilter;
84 if( not defined( $interfaceFilter ) )
86 $interfaceFilter = \%ciscoInterfaceFilter;
90 # Key is some unique symbolic name, does not mean anything
91 # ifType is the number to match the interface type
92 # ifDescr is the regexp to match the interface description
93 %ciscoInterfaceFilter =
95 'Null0' => {
96 'ifType' => 1, # other
97 'ifDescr' => '^Null'
100 'E1 N/N/N' => {
101 'ifType' => 18, # ds1
102 'ifDescr' => '^E1'
105 'Virtual-AccessN' => {
106 'ifType' => 23, # ppp
107 'ifDescr' => '^Virtual-Access'
110 'LoopbackN' => {
111 'ifType' => 24, # softwareLoopback
112 'ifDescr' => '^Loopback'
115 'SerialN:N-Bearer Channel' => {
116 'ifType' => 81, # ds0, Digital Signal Level 0
117 'ifDescr' => '^Serial.*Bearer\s+Channel'
120 'Voice Encapsulation (POTS) Peer: N' => {
121 'ifType' => 103 # voiceEncap
124 'Voice Over IP Peer: N' => {
125 'ifType' => 104 # voiceOverIp
128 'ATMN/N/N.N-atm subif' => {
129 'ifType' => 134, # atmSubInterface
130 'ifDescr' => '^ATM[0-9\/]+\.[0-9]+\s+subif'
133 'BundleN' => {
134 'ifType' => 127, # docsCableMaclayer
135 'ifDescr' => '^Bundle'
138 'EOBCN/N' => {
139 'ifType' => 53, # propVirtual
140 'ifDescr' => '^EOBC'
143 'FIFON/N' => {
144 'ifType' => 53, # propVirtual
145 'ifDescr' => '^FIFO'
148 'vfc' => {
149 'ifType' => 56, # virtualFibreChannel
150 'ifDescr' => '^vfc'
154 our %tunnelType =
156 # CISCO-VPDN-MGMT-MIB Tunnel Types
157 '1' => 'L2F',
158 '2' => 'L2TP',
159 '3' => 'PPTP'
163 sub checkdevtype
165 my $dd = shift;
166 my $devdetails = shift;
168 if( not $dd->oidBaseMatch
169 ( 'ciscoProducts',
170 $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
172 return 0;
175 my $session = $dd->session();
176 if( not $dd->checkSnmpTable('ciscoImageTable') )
178 if( $dd->checkSnmpTable('ceImageTable') )
180 # IOS XR has a new MIB for software image management
181 $devdetails->setCap('CiscoIOSXR');
183 else
185 return 0;
189 # On some Layer3 switching devices, VlanXXX interfaces give some
190 # useful stats, while on others the stats are not relevant at all
192 if( $devdetails->paramDisabled('CiscoIOS::enable-vlan-interfaces') )
194 $interfaceFilter->{'VlanN'} = {
195 'ifType' => 53, # propVirtual
196 'ifDescr' => '^Vlan\d+'
200 # same thing with unrouted VLAN interfaces
201 if( $devdetails->paramDisabled('CiscoIOS::enable-unrouted-vlan-interfaces'))
203 $interfaceFilter->{'unrouted VLAN N'} = {
204 'ifType' => 53, # propVirtual
205 'ifDescr' => '^unrouted\s+VLAN\s+\d+'
209 # sometimes we want Dialer interface stats
210 if( $devdetails->paramDisabled('CiscoIOS::enable-dialer-interfaces') )
212 $interfaceFilter->{'DialerN'} = {
213 'ifType' => 23, # ppp
214 'ifDescr' => '^Dialer'
216 $interfaceFilter->{'DialerN_ML'} = {
217 'ifType' => 108, # pppMultilinkBundle
218 'ifDescr' => '^Dialer'
222 &Torrus::DevDiscover::RFC2863_IF_MIB::addInterfaceFilter
223 ($devdetails, $interfaceFilter);
225 if( defined( $interfaceFilterOverlay ) )
227 &Torrus::DevDiscover::RFC2863_IF_MIB::addInterfaceFilter
228 ($devdetails, $interfaceFilterOverlay);
231 $devdetails->setCap('interfaceIndexingManaged');
233 return 1;
237 my %ccarConfigType =
238 ( 1 => 'all',
239 2 => 'quickAcc',
240 3 => 'standardAcc' );
242 my %ccarAction =
243 ( 1 => 'drop',
244 2 => 'xmit',
245 3 => 'continue',
246 4 => 'precedXmit',
247 5 => 'precedCont' );
251 sub discover
253 my $dd = shift;
254 my $devdetails = shift;
256 my $session = $dd->session();
257 my $data = $devdetails->data();
259 # Old mkroutercfg used cisco-interface-counters
260 if( $Torrus::DevDiscover::CiscoIOS::useCiscoInterfaceCounters )
262 for my $interface ( values %{$data->{'interfaces'}} )
264 $interface->{'hasHCOctets'} = 0;
265 $interface->{'hasOctets'} = 0;
266 push( @{$interface->{'templates'}},
267 'CiscoIOS::cisco-interface-counters' );
270 else
272 # This is a well-known bug in IOS: HC counters are implemented,
273 # but always zero. We can catch this only for active interfaces.
275 for my $ifIndex ( sort {$a<=>$b} keys %{$data->{'interfaces'}} )
277 my $interface = $data->{'interfaces'}{$ifIndex};
279 if( $interface->{'hasHCOctets'} and
281 $devdetails->snmpVar( $dd->oiddef('ifHCInOctets')
282 . '.' . $ifIndex ) == 0 and
283 $devdetails->snmpVar( $dd->oiddef('ifInOctets')
284 . '.' . $ifIndex ) > 0
288 $devdetails->snmpVar( $dd->oiddef('ifHCOutOctets')
289 . '.' . $ifIndex ) == 0 and
290 $devdetails->snmpVar( $dd->oiddef('ifOutOctets')
291 . '.' . $ifIndex ) > 0
292 ) ) )
294 Debug('Disabling HC octets for ' . $ifIndex . ': ' .
295 $interface->{'ifDescr'});
297 $interface->{'hasHCOctets'} = 0;
298 $interface->{'hasHCUcastPkts'} = 0;
303 if( $devdetails->paramEnabled('CiscoIOS::enable-membuf-stats') )
305 # Old Memory Buffers, if we have bufferElFree we assume
306 # the rest as they are "required"
308 if( $dd->checkSnmpOID('bufferElFree') )
310 $devdetails->setCap('old-ciscoMemoryBuffers');
311 push( @{$data->{'templates'}},
312 'CiscoIOS::old-cisco-memory-buffers' );
316 if( $devdetails->paramDisabled('CiscoIOS::disable-ipsec-stats') )
318 if( $dd->checkSnmpOID('cipSecGlobalHcInOctets') )
320 $devdetails->setCap('ciscoIPSecGlobalStats');
321 push( @{$data->{'templates'}},
322 'CiscoIOS::cisco-ipsec-flow-globals' );
325 if( $dd->oidBaseMatch
326 ( 'ciscoLS1010',
327 $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
329 $data->{'param'}{'snmp-oids-per-pdu'} = 10;
333 if( $devdetails->paramDisabled('CiscoIOS::disable-bgp-stats') )
335 my $peerTable =
336 $session->get_table( -baseoid =>
337 $dd->oiddef('cbgpPeerAcceptedPrefixes') );
338 if( defined($peerTable) and scalar(keys %{$peerTable}) > 0 )
340 $devdetails->storeSnmpVars( $peerTable );
341 $devdetails->setCap('CiscoBGP');
343 my $limitsTable =
344 $session->get_table( -baseoid =>
345 $dd->oiddef('cbgpPeerPrefixAdminLimit') );
346 $limitsTable = {} if not defined( $limitsTable );
348 $data->{'cbgpPeers'} = {};
350 # retrieve AS numbers for neighbor peers
351 Torrus::DevDiscover::RFC1657_BGP4_MIB::discover($dd, $devdetails);
353 # list of indices for peers that are not IPv4 Unicast
354 my @nonV4Unicast;
356 # Number of peers for each AS
357 my %asNumbers;
359 for my $INDEX
360 ( $devdetails->
361 getSnmpIndices( $dd->oiddef('cbgpPeerAcceptedPrefixes') ) )
363 my ($a1, $a2, $a3, $a4, $afi, $safi) = split(/\./, $INDEX);
364 my $peerIP = join('.', $a1, $a2, $a3, $a4);
366 my $peer = {
367 'peerIP' => $peerIP,
368 'addrFamily' => 'IPv4 Unicast'
371 if( $afi != 1 and $safi != 1 )
373 push( @nonV4Unicast, $INDEX );
376 my $desc =
377 $devdetails->paramString
378 ('peer-ipaddr-description-' .
379 join('_', split('\.', $peerIP)));
380 if( $desc ne '' )
382 $peer->{'description'} = $desc;
385 my $peerAS = $data->{'bgpPeerAS'}{$peerIP};
386 if( defined( $peerAS ) )
388 $peer->{'peerAS'} = $data->{'bgpPeerAS'}{$peerIP};
389 $asNumbers{$peer->{'peerAS'}}++;
391 my $desc =
392 $devdetails->paramString
393 ('bgp-as-description-' . $peerAS);
394 if( $desc ne '' )
396 if( defined( $peer->{'description'} ) )
398 Warn('Conflicting descriptions for peer ' .
399 $peerIP);
401 $peer->{'description'} = $desc;
404 else
406 Error('Cannot find AS number for BGP peer ' . $peerIP);
407 next;
410 if( defined( $peer->{'description'} ) )
412 $peer->{'description'} .= ' ';
414 $peer->{'description'} .= '[' . $peerIP . ']';
416 $peer->{'prefixLimit'} =
417 $limitsTable->{$dd->oiddef('cbgpPeerPrefixAdminLimit') .
418 '.' . $INDEX};
420 $data->{'cbgpPeers'}{$INDEX} = $peer;
423 if( scalar( @nonV4Unicast ) > 0 )
425 my $addrFamTable =
426 $session->get_table
427 ( -baseoid => $dd->oiddef('cbgpPeerAddrFamilyName') );
429 for my $INDEX ( @nonV4Unicast )
431 my $peer = $data->{'cbgpPeers'}{$INDEX};
433 my $fam = $addrFamTable->{
434 $dd->oiddef('cbgpPeerAddrFamilyName') .
435 '.' . $INDEX};
437 $peer->{'addrFamily'} = $fam;
438 $peer->{'otherAddrFamily'} = 1;
439 $peer->{'description'} .= ' ' . $fam;
443 # Construct the subtree names from AS, peer IP, and address
444 # family
445 for my $INDEX ( keys %{$data->{'cbgpPeers'}} )
447 my $peer = $data->{'cbgpPeers'}{$INDEX};
449 my $subtreeName = 'AS' . $peer->{'peerAS'};
450 if( $asNumbers{$peer->{'peerAS'}} > 1 )
452 $subtreeName .= '_' . $peer->{'peerIP'};
455 if( $peer->{'otherAddrFamily'} )
457 my $fam = $data->{'cbgpPeers'}{$INDEX}{'addrFamily'};
458 $fam =~ s/\W/_/g;
459 $subtreeName .= '_' . $fam;
462 $peer->{'subtreeName'} = $subtreeName;
468 if( $devdetails->paramDisabled('CiscoIOS::disable-car-stats') )
470 my $carTable =
471 $session->get_table( -baseoid =>
472 $dd->oiddef('ccarConfigTable') );
473 if( defined($carTable) and scalar(keys %{$carTable}) > 0 )
475 $devdetails->storeSnmpVars( $carTable );
476 $devdetails->setCap('CiscoCAR');
478 $data->{'ccar'} = {};
480 for my $INDEX
481 ( $devdetails->
482 getSnmpIndices( $dd->oiddef('ccarConfigType') ) )
484 my ($ifIndex, $dir, $carIndex) = split(/\./, $INDEX);
485 my $interface = $data->{'interfaces'}{$ifIndex};
487 my $car = {
488 'ifIndex' => $ifIndex,
489 'direction' => $dir,
490 'carIndex' => $carIndex };
492 $car->{'configType'} =
493 $ccarConfigType{ $carTable->{$dd->oiddef
494 ('ccarConfigType') .
495 '.' . $INDEX} };
497 $car->{'accIdx'} = $carTable->{$dd->oiddef
498 ('ccarConfigAccIdx') .
499 '.' . $INDEX};
501 $car->{'rate'} = $carTable->{$dd->oiddef
502 ('ccarConfigRate') .
503 '.' . $INDEX};
506 $car->{'limit'} = $carTable->{$dd->oiddef
507 ('ccarConfigLimit') .
508 '.' . $INDEX};
510 $car->{'extLimit'} = $carTable->{$dd->oiddef
511 ('ccarConfigExtLimit') .
512 '.' . $INDEX};
513 $car->{'conformAction'} =
514 $ccarAction{ $carTable->{$dd->oiddef
515 ('ccarConfigConformAction') .
516 '.' . $INDEX} };
518 $car->{'exceedAction'} =
519 $ccarAction{ $carTable->{$dd->oiddef
520 ('ccarConfigExceedAction') .
521 '.' . $INDEX} };
523 $data->{'ccar'}{$INDEX} = $car;
528 if( $devdetails->paramDisabled('CiscoIOS::disable-vpdn-stats') )
530 if( $dd->checkSnmpTable( 'cvpdnSystemTunnelTotal' ) )
532 # Find the Tunnel type
533 my $tableTun = $session->get_table(
534 -baseoid => $dd->oiddef('cvpdnSystemTunnelTotal') );
536 if( $tableTun )
538 $devdetails->setCap('ciscoVPDN');
540 $devdetails->storeSnmpVars( $tableTun );
542 # VPDN indexing: 1: l2f, 2: l2tp, 3: pptp
543 for my $typeIndex (
544 $devdetails->getSnmpIndices(
545 $dd->oiddef('cvpdnSystemTunnelTotal') ) )
547 Debug("CISCO-VPDN-MGMT-MIB: found Tunnel type " .
548 $tunnelType{$typeIndex} );
550 $data->{'ciscoVPDN'}{$typeIndex} = $tunnelType{$typeIndex};
556 if( $devdetails->paramDisabled('CiscoIOS::disable-3g-stats') )
558 my $base = $dd->oiddef('c3gStandard');
559 my $table = $session->get_table( -baseoid => $base );
560 my $prefixLen = length( $base ) + 1;
562 if( defined($table) )
564 while( my( $oid, $val ) = each %{$table} )
566 if( $val == 2 )
568 $devdetails->setCap('Cisco3G');
569 my $phy = substr( $oid, $prefixLen );
570 my $phyName = $data->{'entityPhysical'}{$phy}{'name'};
571 if( not defined( $phyName ) )
573 $phyName = 'Cellular Modem';
576 $data->{'cisco3G'}{$phy} = {
577 'name' => $phyName,
578 'standard' => 'gsm',
581 else
583 Warn('CISCO-WAN-3G-MIB: CDMA statistics are ' .
584 'not yet implemented');
589 my $tokenset = $devdetails->paramString('CiscoIOS::3g-stats-tokenset');
590 if( $tokenset ne '')
592 $data->{'cisco3G_tokenset'} = $tokenset;
597 if( $devdetails->paramDisabled('CiscoIOS::disable-port-qos-stats') )
599 my $base = $dd->oiddef('cportQosDropPkts');
600 my $table = $session->get_table( -baseoid => $base );
601 my $prefixLen = length( $base ) + 1;
603 if( defined($table) and scalar(keys %{$table}) > 0 )
605 $devdetails->setCap('CiscoPortQos');
606 $data->{'ciscoPortQos'} = {};
608 while( my( $oid, $val ) = each %{$table} )
610 my $qos_entry = substr( $oid, $prefixLen );
611 my($ifIndex, $direction, $qos_index) =
612 split(/\./o, $qos_entry);
614 $data->{'ciscoPortQos'}{$qos_entry} = {
615 'ifIndex' => $ifIndex,
616 'direction' => ($direction==1)?'ingress':'egress',
617 'qosidx' => $qos_index,
624 if( $devdetails->paramEnabled('CiscoIOS::short-device-comment') )
626 # Remove serials from device comment
627 # 1841 chassis, Hw Serial#: 3625140487, Hw Revision: 6.0
629 $data->{'param'}{'comment'} =~ s/, Hw.*//o;
632 return 1;
636 sub buildConfig
638 my $devdetails = shift;
639 my $cb = shift;
640 my $devNode = shift;
642 my $data = $devdetails->data();
644 if( $devdetails->hasCap('CiscoBGP') )
646 my $countersNode =
647 $cb->addSubtree( $devNode, 'BGP_Prefixes',
649 'node-display-name' => 'BGP Prefixes',
650 'comment' => 'Accepted prefixes',
651 } );
653 for my $INDEX ( sort
654 { $data->{'cbgpPeers'}{$a}{'subtreeName'} cmp
655 $data->{'cbgpPeers'}{$b}{'subtreeName'} }
656 keys %{$data->{'cbgpPeers'}} )
658 my $peer = $data->{'cbgpPeers'}{$INDEX};
660 my $param = {
661 'peer-index' => $INDEX,
662 'peer-ipaddr' => $peer->{'peerIP'},
663 'comment' => $peer->{'description'},
664 'descriptive-nickname' => $peer->{'subtreeName'},
665 'precedence' => 65000 - $peer->{'peerAS'}
668 if( defined( $peer->{'prefixLimit'} ) and
669 $peer->{'prefixLimit'} > 0 )
671 $param->{'upper-limit'} = $peer->{'prefixLimit'};
672 $param->{'graph-upper-limit'} = $peer->{'prefixLimit'} * 1.03;
675 $cb->addLeaf
676 ( $countersNode, $peer->{'subtreeName'}, $param,
677 ['CiscoIOS::cisco-bgp'] );
682 if( $devdetails->hasCap('CiscoCAR') )
684 my $countersNode =
685 $cb->addSubtree( $devNode, 'CAR_Stats', {
686 'comment' => 'Committed Access Rate statistics',
687 'node-display-name' => 'CAR', },
688 ['CiscoIOS::cisco-car-subtree']);
690 for my $INDEX ( sort keys %{$data->{'ccar'}} )
692 my $car = $data->{'ccar'}{$INDEX};
693 my $interface = $data->{'interfaces'}{$car->{'ifIndex'}};
695 my $subtreeName =
696 $interface->{$data->{'nameref'}{'ifSubtreeName'}};
698 $subtreeName .= ($car->{'direction'} == 1) ? '_IN':'_OUT';
699 if( $car->{'carIndex'} > 1 )
701 $subtreeName .= '_' . $car->{'carIndex'};
704 my $param = {
705 'searchable' => 'yes',
706 'car-direction' => $car->{'direction'},
707 'car-index' => $car->{'carIndex'} };
709 $param->{'interface-name'} =
710 $interface->{'param'}{'interface-name'};
711 $param->{'interface-nick'} =
712 $interface->{'param'}{'interface-nick'};
713 $param->{'comment'} =
714 $interface->{'param'}{'comment'};
716 my $legend = sprintf("Type: %s;", $car->{'configType'});
717 if( $car->{'accIdx'} > 0 )
719 $legend .= sprintf("Access list: %d;", $car->{'accIdx'});
722 $legend .=
723 sprintf("Rate: %d bps; Limit: %d bytes; Ext limit: %d bytes;" .
724 "Conform action: %s; Exceed action: %s",
725 $car->{'rate'},
726 $car->{'limit'},
727 $car->{'extLimit'},
728 $car->{'conformAction'},
729 $car->{'exceedAction'});
731 $param->{'legend'} = $legend;
733 $cb->addSubtree
734 ( $countersNode,
735 $subtreeName,
736 $param,
737 ['CiscoIOS::cisco-car']);
742 if( $devdetails->hasCap('ciscoVPDN') )
744 my $tunnelNode = $cb->addSubtree
745 ( $devNode, 'VPDN_Statistics',
746 {'node-display-name' => 'VPDN Statistics'},
747 [ 'CiscoIOS::cisco-vpdn-subtree' ] );
749 for my $INDEX ( sort keys %{$data->{'ciscoVPDN'}} )
751 my $tunnelProtocol = $data->{'ciscoVPDN'}{$INDEX};
753 $cb->addSubtree( $tunnelNode, $tunnelProtocol,
754 { 'comment' => $tunnelProtocol . ' information',
755 'tunIndex' => $INDEX,
756 'tunFile' => lc($tunnelProtocol) },
757 [ 'CiscoIOS::cisco-vpdn-leaf' ] );
761 if( $devdetails->hasCap('Cisco3G') )
763 for my $phy ( sort keys %{$data->{'cisco3G'}} )
765 my @templates;
766 my $summary_leaf;
767 if( $data->{'cisco3G'}{$phy}{'standard'} eq 'gsm' )
769 push(@templates, 'CiscoIOS::cisco-3g-gsm-stats');
770 $summary_leaf = 'RSSI';
773 my $phyName = $data->{'cisco3G'}{$phy}{'name'};
775 my $subtreeName = $phyName;
776 $subtreeName =~ s/\W/_/go;
778 my $subtree = $cb->addSubtree
779 ( $devNode, $subtreeName,
781 'node-display-name' => $phyName,
782 'comment' => '3G cellular statistics',
783 'cisco-3g-phy' => $phy,
784 'cisco-3g-phyname' => $phyName,
785 '3gcell-nodeid' => 'cell//%nodeid-device%//' . $phy,
786 'nodeid' => '%3gcell-nodeid%',
788 \@templates );
790 if( defined($data->{'cisco3G_tokenset'}) )
792 $cb->addLeaf
793 ($subtree, $summary_leaf,
794 {'tokenset-member' => $data->{'cisco3G_tokenset'}});
799 if( $devdetails->hasCap('CiscoPortQos') )
801 my $subtreeNode = $cb->addSubtree
802 ( $devNode, 'Port_QoS',
803 {'node-display-name' => 'QoS drop statistics'} );
805 my $precedence = 1000;
806 for my $qos_entry (sort keys %{$data->{'ciscoPortQos'}})
808 my $entry = $data->{'ciscoPortQos'}{$qos_entry};
810 my $interface = $data->{'interfaces'}{$entry->{'ifIndex'}};
811 next unless defined($interface);
812 next if $interface->{'excluded'};
814 my $leafName =
815 $interface->{$data->{'nameref'}{'ifSubtreeName'}} . '_' .
816 $entry->{'direction'} . '_drops';
818 my $intfName =
819 $interface->{$data->{'nameref'}{'ifReferenceName'}};
821 my $intfNick = $interface->{$data->{'nameref'}{'ifNick'}};
823 my $params = {
824 'cisco-pqos-entry' => $qos_entry,
825 'cisco-pqos-ifnick' => $intfNick,
826 'cisco-pqos-direction' => $entry->{'direction'},
827 'graph-legend' => 'Dropped packets',
828 'precedence' => $precedence--,
831 $params->{'node-display-name'} =
832 $intfName . ' ' . $entry->{'direction'} . ' drops';
834 $params->{'graph-title'} =
835 $params->{'descriptive-nickname'} =
836 '%system-id% ' . $intfName . ' ' .
837 $entry->{'direction'} . ' drops';
839 $cb->addLeaf($subtreeNode, $leafName, $params,
840 ['CiscoIOS::cisco-port-qos-packets']);
851 # Local Variables:
852 # mode: perl
853 # indent-tabs-mode: nil
854 # perl-indent-level: 4
855 # End: