2 # Discovery module for Arbor|e Series devices
3 # Formerly Ellacoya Networks
5 # Copyright (C) 2008 Jon Nistor
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21 # $Id: Arbor_E.pm,v 1.2 2011-12-16 22:43:52 ivan Exp $
22 # Jon Nistor <nistor at snickers.org>
24 # NOTE: This module has been tested against v7.5.x, v7.6.x, v9.0.x, v9.1.x
27 # Arbor_E::disable-bundle-offer
28 # Arbor_E::disable-bundle-offer-deny
29 # Arbor_E::disable-bundle-offer-pktsize
30 # Arbor_E::disable-bundle-offer-rate
31 # Arbor_E::disable-bundle-offer-subcount
32 # Arbor_E::enable-bundle-name-rrd
33 # Arbor_E::disable-flowdev
36 # Arbor_E::disable-e30-buffers
37 # Arbor_E::disable-e30-bundle
38 # Arbor_E::disable-e30-cpu
39 # Arbor_E::disable-e30-fwdTable
40 # Arbor_E::disable-e30-fwdTable-login
41 # Arbor_E::disable-e30-hdd
42 # Arbor_E::enable-e30-hdd-errors
43 # Arbor_E::disable-e30-hdd-logs
44 # Arbor_E::disable-e30-l2tp
45 # Arbor_E::disable-e30-mem
46 # Arbor_E::enable-e30-mempool
47 # Arbor_E::disable-e30-bundle
48 # Arbor_E::disable-e30-bundle-deny
49 # Arbor_E::disable-e30-bundle-rate
50 # Arbor_E::disable-e30-slowpath
53 # Arbor_E::disable-e100-cpu
54 # Arbor_E::disable-e100-hdd
55 # Arbor_E::disable-e100-mem
56 # Arbor_E::disable-e100-policymgmt
57 # Arbor_E::disable-e100-submgmt
60 # Arbor_E devices discovery
61 package Torrus::DevDiscover::Arbor_E;
67 $Torrus::DevDiscover::registry{'Arbor_E'} = {
69 'checkdevtype' => \&checkdevtype,
70 'discover' => \&discover,
71 'buildConfig' => \&buildConfig
77 'eProducts' => '1.3.6.1.4.1.3813.2',
78 'codeVer' => '1.3.6.1.4.1.3813.1.4.1.1.0',
79 'sysIdSerialNum' => '1.3.6.1.4.1.3813.1.4.1.5.2.0',
80 'memPoolNameIndex' => '1.3.6.1.4.1.3813.1.4.2.5.1.1',
81 'hDriveErrModel' => '1.3.6.1.4.1.3813.1.4.2.10.16.0',
82 'hDriveErrSerialNum' => '1.3.6.1.4.1.3813.1.4.2.10.17.0',
83 'partitionName' => '1.3.6.1.4.1.3813.1.4.2.11.1.2', # e100
84 'cpuSdramIndex' => '1.3.6.1.4.1.3813.1.4.2.12.1.1', # e100
85 'hDriveDailyLogSize' => '1.3.6.1.4.1.3813.1.4.2.13.0',
86 'cpuUtilization' => '1.3.6.1.4.1.3813.1.4.4.1.0',
87 'cpuUtilTable' => '1.3.6.1.4.1.3813.1.4.4.2', # e100
88 'cpuIndex' => '1.3.6.1.4.1.3813.1.4.4.2.1.1', # e100
89 'cpuName' => '1.3.6.1.4.1.3813.1.4.4.2.1.2', # e100
90 'loginRespOkStatsIndex' => '1.3.6.1.4.1.3813.1.4.3.15.1.1',
92 # ELLACOYA-MIB::cpuCounters, e30 (available in 7.5.x -- slowpath counters)
93 'cpuCounters' => '1.3.6.1.4.1.3813.1.4.4.10',
94 'slowpathCounters' => '1.3.6.1.4.1.3813.1.4.4.10.1',
95 'sigCounters' => '1.3.6.1.4.1.3813.1.4.4.10.2',
98 'flowPoolNameD1' => '1.3.6.1.4.1.3813.1.4.5.1.1.1.2',
99 'flowPoolNameD2' => '1.3.6.1.4.1.3813.1.4.5.2.1.1.2',
101 # ELLACOYA-MIB::bundleStatsTable
102 'bundleName' => '1.3.6.1.4.1.3813.1.4.12.1.1.2',
103 'bundleBytesSentDenyPolicyDrop' => '1.3.6.1.4.1.3813.1.4.12.1.1.6',
104 'bundleBytesSentRateLimitDrop' => '1.3.6.1.4.1.3813.1.4.12.1.1.8',
105 'boBundleID' => '1.3.6.1.4.1.3813.1.4.12.2.1.1',
106 'boBundleName' => '1.3.6.1.4.1.3813.1.4.12.2.1.3',
107 'boOfferName' => '1.3.6.1.4.1.3813.1.4.12.2.1.4',
108 'boBundleSubCount' => '1.3.6.1.4.1.3813.1.4.12.2.1.7',
109 'boPacketsSent64' => '1.3.6.1.4.1.3813.1.4.12.2.1.8',
110 'boBundleBytesSentDenyPolicyDrop' => '1.3.6.1.4.1.3813.1.4.12.2.1.22',
111 'boBundleBytesSentRateLimitDrop' => '1.3.6.1.4.1.3813.1.4.12.2.1.24',
113 # ELLACOYA-MIB::policyMgmt, e100
114 'policyMgmt' => '1.3.6.1.4.1.3813.1.4.16',
116 # ELLACOYA-MIB::subscriberMgmt, e100
117 'subscriberMgmt' => '1.3.6.1.4.1.3813.1.4.17',
118 'subscriberStateName' => '1.3.6.1.4.1.3813.1.4.17.7.1.2',
120 # ELLACOYA-MIB::l2tp, e30 (available in 7.5.x)
121 'l2tpConfigEnabled' => '1.3.6.1.4.1.3813.1.4.18.1.1.0',
122 'l2tpSecureEndpointIpAddress' => '1.3.6.1.4.1.3813.1.4.18.3.2.1.1.1',
123 'l2tpSecureEndpointOverlapping' => '1.3.6.1.4.1.3813.1.4.18.3.2.1.1.3',
131 '3' => 'e30 Revision: R',
132 '4' => 'e30 Revision: S',
133 '5' => 'e30 Revision: T',
134 '6' => 'e30 Revision: U',
135 '7' => 'e30 Revision: V',
136 '8' => 'Ellacoya e100',
142 '1' => 'Control Module',
143 '3' => 'DPI Module 1 CPU 1',
144 '4' => 'DPI Module 1 CPU 2',
145 '5' => 'DPI Module 2 CPU 1',
146 '6' => 'DPI Module 2 CPU 2',
153 my $devdetails = shift;
155 if( not $dd->oidBaseMatch
156 ( 'eProducts', $devdetails->snmpVar( $dd->oiddef('sysObjectID') ) ) )
161 $devdetails->setCap('interfaceIndexingPersistent');
170 my $devdetails = shift;
172 my $session = $dd->session();
173 my $data = $devdetails->data();
175 # PROG: Grab versions, serials and type of chassis.
176 my $eInfo = $dd->retrieveSnmpOIDs
177 ( 'codeVer', 'sysIdSerialNum', 'sysObjectID' );
178 $eInfo->{'modelNum'} = $eInfo->{'sysObjectID'};
179 $eInfo->{'modelNum'} =~ s/.*(\d)$/$1/; # Last digit
181 # SNMP: System comment
182 $data->{'param'}{'comment'} =
183 "Arbor " . $eChassisName{$eInfo->{'modelNum'}} .
184 ", Hw Serial#: " . $eInfo->{'sysIdSerialNum'} .
185 ", Version: " . $eInfo->{'codeVer'};
187 # ------------------------------------------------------------------------
188 # Arbor_E e30 related material here
189 if( $eInfo->{'modelNum'} < 8 )
191 Debug("Arbor_E: Found " . $eChassisName{$eInfo->{'modelNum'}} );
193 # PROG: Set Capability to be the e30 device
194 $devdetails->setCap('e30');
196 # PROG: Check status oids
197 if( $devdetails->param('Arbor_E::disable-e30-buffers') ne 'yes' )
199 $devdetails->setCap('e30-buffers');
202 if( $devdetails->param('Arbor_E::disable-e30-cpu') ne 'yes' )
204 $devdetails->setCap('e30-cpu');
207 if( $devdetails->param('Arbor_E::disable-e30-fwdTable') ne 'yes' )
209 $devdetails->setCap('e30-fwdTable');
211 if( $devdetails->param('Arbor_E::disable-e30-fwdTable-login')
214 my $loginTable = $session->get_table(
215 -baseoid => $dd->oiddef('loginRespOkStatsIndex') );
216 $devdetails->storeSnmpVars( $loginTable );
218 if( defined( $loginTable ) )
220 $devdetails->setCap('e30-fwdTable-login');
222 foreach my $statsIdx ( $devdetails->getSnmpIndices(
223 $dd->oiddef('loginRespOkStatsIndex') ) )
225 push(@{$data->{'e30'}{'loginResp'}}, $statsIdx);
228 } # END hasCap disable-e30-fwdTable-login
231 if( $devdetails->param('Arbor_E::disable-e30-hdd') ne 'yes' )
233 $devdetails->setCap('e30-hdd');
235 # SNMP: Add harddrive comment information
236 $eInfo = $dd->retrieveSnmpOIDs( 'hDriveErrModel',
237 'hDriveErrSerialNum' );
239 $data->{'e30'}{'hddModel'} = $eInfo->{'hDriveErrModel'};
240 $data->{'e30'}{'hddSerial'} = $eInfo->{'hDriveErrSerialNum'};
242 # PROG: Do we want errors as well?
243 if( $devdetails->param('Arbor_E::enable-e30-hdd-errors') eq 'yes' )
245 $devdetails->setCap('e30-hdd-errors');
248 # PROG: Do we want to look at daily log files? (New in 7.6)
249 if( $devdetails->param('Arbor_E::disable-e30-hdd-logs') ne 'yes' )
251 $eInfo = $dd->retrieveSnmpOIDs( 'hDriveDailyLogSize' );
253 if( $eInfo->{'hDriveDailyLogSize'} )
255 $devdetails->setCap('e30-hdd-logs');
258 } # END: if disable-e30-hdd
260 if( $devdetails->param('Arbor_E::disable-e30-l2tp') ne 'yes' )
262 # 1 - disabled, 2 - enabled, 3 - session aware
263 $eInfo = $dd->retrieveSnmpOIDs('l2tpConfigEnabled');
265 if( $eInfo->{'l2tpConfigEnabled'} > 1 )
267 $devdetails->setCap('e30-l2tp');
269 my $l2tpSecEndTable = $session->get_table(
270 -baseoid => $dd->oiddef('l2tpSecureEndpointIpAddress') );
271 $devdetails->storeSnmpVars( $l2tpSecEndTable );
273 Debug("e30: L2TP secure endpoints found:");
274 foreach my $SEP ( $devdetails->getSnmpIndices(
275 $dd->oiddef('l2tpSecureEndpointIpAddress') ) )
278 $data->{'e30'}{'l2tpSEP'}{$SEP} = 0;
281 } # END: if l2tpConfigEnabled
284 # Memory usage on system
285 if( $devdetails->param('Arbor_E::disable-e30-mem') ne 'yes' )
287 $devdetails->setCap('e30-mem');
290 # Memory usage / individual blocks
291 if( $devdetails->param('Arbor_E::enable-e30-mempool') eq 'yes' )
293 my $mempoolTable = $session->get_table(
294 -baseoid => $dd->oiddef('memPoolNameIndex') );
295 $devdetails->storeSnmpVars( $mempoolTable );
297 if( defined( $mempoolTable ) )
299 $devdetails->setCap('e30-mempool');
302 $devdetails->getSnmpIndices(
303 $dd->oiddef('memPoolNameIndex') ) )
305 my $memName = $mempoolTable->{
306 $dd->oiddef('memPoolNameIndex') . '.' . $memOID};
308 Debug("e30: Mempool: $memName");
309 $data->{'e30'}{'mempool'}{$memOID} = $memName;
314 # Traffic statistics per Bundle
315 if( $devdetails->param('Arbor_E::disable-e30-bundle') ne 'yes' )
318 $devdetails->setCap('e30-bundle');
320 # Pull table information
321 my $bundleTable = $session->get_table(
322 -baseoid => $dd->oiddef('bundleName') );
323 $devdetails->storeSnmpVars( $bundleTable );
325 Debug("e30: Bundle Information id:name");
326 foreach my $bundleID (
327 $devdetails->getSnmpIndices( $dd->oiddef('bundleName') ))
329 my $bundleName = $bundleTable->{$dd->oiddef('bundleName') .
331 $data->{'e30'}{'bundleID'}{$bundleID} = $bundleName;
333 Debug("e30: $bundleID $bundleName");
334 } # END foreache my $bundleID
336 if( $devdetails->param('Arbor_E::disable-e30-bundle-deny') ne 'yes')
338 my $bundleDenyTable = $session->get_table(
339 -baseoid => $dd->oiddef('bundleBytesSentDenyPolicyDrop') );
340 $devdetails->storeSnmpVars( $bundleDenyTable );
342 if( $bundleDenyTable )
344 $devdetails->setCap('e30-bundle-denyStats');
348 if( $devdetails->param('Arbor_E::disable-e30-bundle-rate') ne 'yes')
350 my $bundleRateLimitTable = $session->get_table(
351 -baseoid => $dd->oiddef('bundleBytesSentRateLimitDrop') );
352 $devdetails->storeSnmpVars( $bundleRateLimitTable );
354 if( $bundleRateLimitTable )
356 $devdetails->setCap('e30-bundle-rateLimitStats');
360 } # END if Arbor_E::disable-e30-bundle
363 if( $devdetails->param('Arbor_E::disable-e30-slowpath') ne 'yes' )
365 # Slowpath counters are available as of 7.5.x
366 my $counters = $session->get_table(
367 -baseoid => $dd->oiddef('slowpathCounters') );
368 $devdetails->storeSnmpVars( $counters );
370 if( defined( $counters ) )
372 $devdetails->setCap('e30-slowpath');
378 # ------------------------------------------------------------------------
380 # Arbor E100 related material here
382 if( $eInfo->{'modelNum'} >= 8 )
384 Debug("Arbor_E: Found " . $eChassisName{$eInfo->{'modelNum'}} );
386 # PROG: Set Capability to be the e100 device
387 $devdetails->setCap('e100');
390 if( $devdetails->param('Arbor_E::disable-e100-cpu') ne 'yes' )
392 my $cpuNameTable = $session->get_table(
393 -baseoid => $dd->oiddef('cpuName') );
394 $devdetails->storeSnmpVars( $cpuNameTable );
396 if( defined( $cpuNameTable ) )
398 $devdetails->setCap('e100-cpu');
400 # PROG: Find all the CPU's ..
401 foreach my $cpuIndex ( $devdetails->getSnmpIndices(
402 $dd->oiddef('cpuName') ) )
404 my $cpuName = $cpuNameTable->{$dd->oiddef('cpuName') .
407 Debug(" CPU found: $cpuIndex, $cpuName");
408 $data->{'e100'}{'cpu'}{$cpuIndex} = $cpuName;
414 if( $devdetails->param('Arbor_E::disable-e100-hdd') ne 'yes' )
416 my $hddTable = $session->get_table(
417 -baseoid => $dd->oiddef('partitionName') );
418 $devdetails->storeSnmpVars( $hddTable );
420 if( defined( $hddTable ) )
422 $devdetails->setCap('e100-hdd');
424 # PROG: Find all the paritions and names ..
425 foreach my $hddIndex ( $devdetails->getSnmpIndices(
426 $dd->oiddef('partitionName') ) )
428 my $partitionName = $hddTable->{$dd->oiddef('partitionName') .
430 Debug("HDD Partition: $hddIndex, $partitionName");
431 $data->{'e100'}{'hdd'}{$hddIndex} = $partitionName;
437 if( $devdetails->param('Arbor_E::disable-e100-mem') ne 'yes' )
439 my $cpuSdramTable = $session->get_table(
440 -baseoid => $dd->oiddef('cpuSdramIndex') );
441 $devdetails->storeSnmpVars( $cpuSdramTable );
443 if( defined( $cpuSdramTable ) )
445 $devdetails->setCap('e100-mem');
447 # PROG: Find all memory indexes
448 foreach my $memIndex ( $devdetails->getSnmpIndices(
449 $dd->oiddef('cpuSdramIndex') ) )
451 my $memName = $data->{'e100'}{'cpu'}{$memIndex};
452 Debug("MEM found: $memIndex, $memName");
453 $data->{'e100'}{'mem'}{$memIndex} = $memName;
458 # Policy Mgmt parameters
459 if( $devdetails->param('Arbor_E::disable-e100-policymgmt') ne 'yes' )
461 my $policyTable = $session->get_table(
462 -baseoid => $dd->oiddef('policyMgmt')
464 $devdetails->storeSnmpVars( $policyTable );
466 if( defined( $policyTable ) )
468 $devdetails->setCap('e100-policymgmt');
472 # Subscriber Mgmt parameters
473 if( $devdetails->param('Arbor_E::disable-e100-submgmt') ne 'yes' )
475 my $subTable = $session->get_table(
476 -baseoid => $dd->oiddef('subscriberStateName')
478 $devdetails->storeSnmpVars( $subTable );
480 if( defined( $subTable ) )
482 $devdetails->setCap('e100-submgmt');
484 # Sub: Find state name entries
485 foreach my $stateIDX ( $devdetails->getSnmpIndices( $dd->oiddef(
486 'subscriberStateName') ) )
488 my $state = $subTable->{
489 $dd->oiddef('subscriberStateName') .
493 Debug(" State index: $stateIDX, name: $state");
494 $data->{'e100'}{'submgmt'}{$stateIDX} = $state;
501 # ------------------------------------------------------------------------
503 # Common information between e30 and e100
505 if( $devdetails->param('Arbor_E::disable-flowdev') ne 'yes' )
507 $devdetails->setCap('arbor-flowLookup');
509 # Flow Lookup Device information
510 # Figure out what pools exist for the 2 flow switching modules
511 # ------------------------------------------------------------
512 my $switchingModules = 2;
514 foreach my $flowModule (1 .. $switchingModules) {
515 Debug("common: Flow Lookup Device " . $flowModule);
517 my $flowPoolOid = 'flowPoolNameD' . $flowModule;
518 my $flowModTable = $session->get_table (
519 -baseoid => $dd->oiddef($flowPoolOid) );
520 $devdetails->storeSnmpVars ( $flowModTable );
522 # PROG: Look for pool names and indexes and store them.
523 if( $flowModTable ) {
524 foreach my $flowPoolIDX ( $devdetails->getSnmpIndices(
525 $dd->oiddef($flowPoolOid) ) )
527 my $flowPoolName = $flowModTable->{
528 $dd->oiddef($flowPoolOid) . '.' . $flowPoolIDX};
530 $data->{'arbor_e'}{'flowModule'}{$flowModule}{$flowPoolIDX}
533 Debug("common: IDX: $flowPoolIDX Pool: $flowPoolName");
535 } # END: foreach my $flowPoolIDX
536 } # END: if $flowModTable
537 } # END: foreach my $flowModule
541 if( $devdetails->param('Arbor_E::disable-bundle-offer') ne 'yes' )
543 my $boOfferNameTable = $session->get_table(
544 -baseoid => $dd->oiddef('boOfferName') );
545 $devdetails->storeSnmpVars( $boOfferNameTable );
547 my $boBundleNameTable = $session->get_table(
548 -baseoid => $dd->oiddef('boBundleName') );
549 $devdetails->storeSnmpVars( $boBundleNameTable );
551 if( defined( $boOfferNameTable ) )
553 $devdetails->setCap('arbor-bundle');
555 foreach my $boOfferNameID ( $devdetails->getSnmpIndices(
556 $dd->oiddef('boOfferName') ) )
558 my ($bundleID,$offerNameID) = split( /\./, $boOfferNameID );
560 my $offerName = $boOfferNameTable->{
561 $dd->oiddef('boOfferName')
562 . '.' . $boOfferNameID };
563 my $bundleName = $boBundleNameTable->{
564 $dd->oiddef('boBundleName')
565 . '.' . $boOfferNameID };
567 $data->{'arbor_e'}{'offerName'}{$offerNameID} = $offerName;
568 $data->{'arbor_e'}{'bundleName'}{$bundleID} = $bundleName;
570 push( @{$data->{'arbor_e'}{'boOfferBundle'}{$offerNameID}},
575 # PROG: Subscribers using the bundle
576 if( $devdetails->param('Arbor_E::disable-bundle-offer-subcount')
579 my $oidSubcount = $dd->oiddef('boBundleSubCount');
581 if( defined $session->get_table( -baseoid => $oidSubcount ) )
583 $devdetails->setCap('arbor-bundle-subcount');
587 # PROG: Packets sent on this bundle with a size
588 if( $devdetails->param('Arbor_E::disable-bundle-offer-pktsize')
591 my $oidPktsize = $dd->oiddef('boPacketsSent64');
593 if( defined $session->get_table( -baseoid => $oidPktsize ) )
595 $devdetails->setCap('arbor-bundle-pktsize');
599 # PROG: Bytes sent on this bundle for deny policy drop
600 if( $devdetails->param('Arbor_E::disable-bundle-offer-deny')
603 my $oidDenypolicy = $dd->oiddef('boBundleBytesSentDenyPolicyDrop');
605 if( defined $session->get_table( -baseoid => $oidDenypolicy ) )
607 $devdetails->setCap('arbor-bundle-deny');
611 # PROG: Bytes sent on this bundle for rate limit drop
612 if( $devdetails->param('Arbor_E::disable-bundle-offer-rate')
615 my $oidRatelimit = $dd->oiddef('boBundleBytesSentRateLimitDrop');
617 if( defined $session->get_table( -baseoid => $oidRatelimit ) )
619 $devdetails->setCap('arbor-bundle-ratelimit');
630 my $devdetails = shift;
633 my $data = $devdetails->data();
635 # PROG: Lets do e30 first ...
636 if( $devdetails->hasCap('e30') )
638 # e30 buffer information
639 if( $devdetails->hasCap('e30-buffers') )
641 $cb->addTemplateApplication($devNode, 'Arbor_E::e30-buffers');
644 if( $devdetails->hasCap('e30-bundle') )
646 # Create topLevel subtree
647 my $bundleNode = $cb->addSubtree( $devNode, 'Bundle_Stats',
648 { 'comment' => 'Bundle statistics' },
649 [ 'Arbor_E::e30-bundle-subtree' ] );
652 ( sort {$a <=> $b} keys %{$data->{'e30'}{'bundleID'} } )
654 my $srvName = $data->{'e30'}{'bundleID'}{$bundleID};
655 my $subtreeName = $srvName;
656 $subtreeName =~ s/\W/_/g;
657 my $bundleRRD = $bundleID;
658 my @templates = ( 'Arbor_E::e30-bundle' );
660 if( $devdetails->param('Arbor_E::enable-e30-bundle-name-rrd')
663 # Filenames written out as the bundle name
664 $bundleRRD = lc($srvName);
665 $bundleRRD =~ s/\W/_/g;
668 if( $devdetails->hasCap('e30-bundle-denyStats') )
670 push( @templates, 'Arbor_E::e30-bundle-deny' );
673 if( $devdetails->hasCap('e30-bundle-rateLimitStats') )
675 push( @templates, 'Arbor_E::e30-bundle-ratelimit' );
678 $cb->addSubtree( $bundleNode, $subtreeName,
679 { 'comment' => $srvName,
680 'e30-bundle-index' => $bundleID,
681 'e30-bundle-name' => $srvName,
682 'e30-bundle-rrd' => $bundleRRD,
683 'precedence' => 1000 - $bundleID },
685 } # END foreach my $bundleID
689 if( $devdetails->hasCap('e30-cpu') )
691 $cb->addTemplateApplication($devNode, 'Arbor_E::e30-cpu');
694 # e30 forwarding table
695 if( $devdetails->hasCap('e30-fwdTable') )
697 $cb->addTemplateApplication($devNode, 'Arbor_E::e30-fwdTable');
699 if( $devdetails->hasCap('e30-fwdTable-login') )
701 my $subtree = "Forwarding_Table_Login_Stats";
702 my $comment = "Discovery attempts statistics";
703 my $nodeTree = $cb->addSubtree( $devNode, $subtree,
704 { 'comment' => $comment },
708 ('##one', '##two', '##three', '##four', '##five',
709 '##six', '##seven', '##eight', '##nine', '##ten'
713 'precedence' => 1000,
714 'comment' => 'Summary of login attempt responses',
715 'graph-lower-limit' => 0,
716 'graph-title' => 'Summary of login attempt responses',
717 'rrd-hwpredict' => 'disabled',
718 'vertical-label' => 'Responses',
719 'ds-type' => 'rrd-multigraph'
723 foreach my $sindex ( sort { $a <=> $b }
724 @{$data->{'e30'}{'loginResp'}} )
727 $cb->addLeaf( $nodeTree, 'Login_' . $sindex,
728 { 'comment' => 'Login attempt #' . $sindex,
729 'login-idx' => $sindex,
730 'precedence' => 100 - $sindex },
731 [ 'Arbor_E::e30-fwdTable-login' ] );
733 # Addition for multi-graph
734 my $dsName = "Login_$sindex";
735 my $color = shift @colors;
736 $dsList .= $dsName . ',';
738 $multiParam->{"ds-expr-$dsName"} = "{$dsName}";
739 $multiParam->{"graph-legend-$dsName"} = "Attempt $sindex";
740 $multiParam->{"line-style-$dsName"} = "LINE1";
741 $multiParam->{"line-color-$dsName"} = $color;
742 $multiParam->{"line-order-$dsName"} = $sindex;
744 Debug(" loginReps: $sindex, color: $color");
745 } # END: foreach $sindex
747 $dsList =~ s/,$//o; # Remove final comma
748 $multiParam->{'ds-names'} = $dsList;
750 $cb->addLeaf($nodeTree, 'Summary', $multiParam, undef );
752 } # END: hasCap e30-fwdTable-login
753 } # END: hasCap e30-fwdTable
756 if( $devdetails->hasCap('e30-hdd') )
758 my $comment = "Model: " . $data->{'e30'}{'hddModel'} . ", " .
759 "Serial: " . $data->{'e30'}{'hddSerial'};
760 my $subtree = "Hard_Drive";
762 push( @templates, 'Arbor_E::e30-hdd-subtree' );
763 push( @templates, 'Arbor_E::e30-hdd' );
765 # PROG: Process hdd errors
766 if( $devdetails->hasCap('e30-hdd-errors') )
768 push( @templates, 'Arbor_E::e30-hdd-errors' );
771 # PROG: Process hdd daily logs
772 if( $devdetails->hasCap('e30-hdd-logs') )
774 push( @templates, 'Arbor_E::e30-hdd-logs' );
777 my $hdNode = $cb->addSubtree($devNode, $subtree,
778 { 'comment' => $comment },
782 # e30 L2TP tunnel information
783 if( $devdetails->hasCap('e30-l2tp') )
785 # PROG: First add the appropriate template
786 my $l2tpNode = $cb->addSubtree( $devNode, 'L2TP', undef,
787 [ 'Arbor_E::e30-l2tp-subtree' ]);
789 # PROG: Cycle through the SECURE EndPoint devices
790 if( $data->{'e30'}{'l2tpSEP'} )
792 # PROG: Add the assisting template first
793 my $l2tpEndNode = $cb->addSubtree( $l2tpNode, 'Secure_Endpoint',
794 { 'comment' => 'Secure endpoint parties' },
795 [ 'Arbor_E::e30-l2tp-secure-endpoints-subtree' ] );
797 foreach my $SEP ( keys %{$data->{'e30'}{'l2tpSEP'}} )
800 $endPoint =~ s/\W/_/g;
802 $cb->addSubtree($l2tpEndNode, $endPoint,
803 { 'e30-l2tp-ep' => $SEP,
804 'e30-l2tp-file' => $endPoint },
805 [ 'Arbor_E::e30-l2tp-secure-endpoints-leaf' ]);
811 if( $devdetails->hasCap('e30-mem') )
813 $cb->addTemplateApplication($devNode, 'Arbor_E::e30-mem');
817 if( $devdetails->hasCap('e30-mempool') )
819 my $subtreeName = "Memory_Pool";
820 my $param = { 'comment' => 'Memory Pool Statistics' };
821 my $templates = [ 'Arbor_E::e30-mempool-subtree' ];
822 my $memIndex = $data->{'e30'}{'mempool'};
824 my $nodeTop = $cb->addSubtree( $devNode, $subtreeName,
825 $param, $templates );
827 foreach my $memIDX ( keys %{$memIndex} )
829 my $leafName = $memIndex->{$memIDX};
830 my $dataFile = "%snmp-host%_mempool_" . $leafName . '.rrd';
832 my $nodeMem = $cb->addSubtree( $nodeTop, $leafName,
833 { 'data-file' => $dataFile,
834 'e30-mempool-index' => $memIDX,
835 'e30-mempool-name' => $leafName
837 [ 'Arbor_E::e30-mempool' ] );
841 # e30 slowpath counters
842 if( $devdetails->hasCap('e30-slowpath') )
844 my $slowNode = $cb->addSubtree( $devNode, 'SlowPath', undef,
845 [ 'Arbor_E::e30-slowpath' ] );
847 } # END: if e30 device
850 # -----------------------------------------------------
854 if( $devdetails->hasCap('e100') )
856 # CPU: per-cpu information
857 if( $devdetails->hasCap('e100-cpu') )
859 my @colors = ( '##one', '##two', '##three', '##four', '##five',
860 '##six', '##seven', '##eight', '##nine', '##ten'
862 my $subtree = "CPU_Usage";
863 my $cpuTree = $cb->addSubtree( $devNode, $subtree, undef,
864 [ 'Arbor_E::e100-cpu-subtree' ] );
866 'precedence' => 1000,
867 'comment' => 'Summary of all CPU utilization',
868 'graph-lower-limit' => 0,
869 'graph-title' => 'Summary of all CPU utilization',
870 'rrd-hwpredict' => 'disabled',
871 'vertical-label' => 'Percent',
872 'ds-type' => 'rrd-multigraph'
876 foreach my $cpuIndex ( sort keys %{$data->{'e100'}{'cpu'}} )
878 my $cpuName = $data->{'e100'}{'cpu'}{$cpuIndex};
880 # Is there proper desc for the CPU index?
882 if( $eCpuName{$cpuIndex} )
884 $comment = $eCpuName{$cpuIndex};
886 $comment = "CPU: $cpuName";
889 $cb->addLeaf( $cpuTree, $cpuName,
890 { 'comment' => $comment,
891 'cpu-index' => $cpuIndex,
892 'cpu-name' => $cpuName,
893 'precedence' => 1000 - $cpuIndex },
894 [ 'Arbor_E::e100-cpu' ] );
896 # Multi-graph additions
897 my $color = shift @colors;
898 $dsList .= $cpuName . ',';
899 $multiParam->{"ds-expr-$cpuName"} = "{$cpuName}";
900 $multiParam->{"graph-legend-$cpuName"} = "$cpuName";
901 $multiParam->{"line-style-$cpuName"} = "LINE1";
902 $multiParam->{"line-color-$cpuName"} = $color;
903 $multiParam->{"line-order-$cpuName"} = $cpuIndex;
904 } # END: foreach $cpuIndex
906 $dsList =~ s/,$//o; # Remove final comma
907 $multiParam->{'ds-names'} = $dsList;
908 $cb->addLeaf($cpuTree, 'Summary', $multiParam, undef );
910 } # END: hasCap e100-cpu
912 # HDD: Partition sizes / usage
913 if( $devdetails->hasCap('e100-hdd') )
915 my $subtree = "HDD_Usage";
916 my $hddTree = $cb->addSubtree( $devNode, $subtree, undef,
917 [ 'Arbor_E::e100-hdd-subtree' ] );
919 foreach my $hddIndex ( sort keys %{$data->{'e100'}{'hdd'}} )
921 my $hddName = $data->{'e100'}{'hdd'}{$hddIndex};
922 $cb->addSubtree( $hddTree, $hddName,
923 { 'comment' => 'HDD: ' . $hddName,
924 'hdd-index' => $hddIndex,
925 'hdd-name' => $hddName,
926 'precedence' => 1000 - $hddIndex },
927 [ 'Arbor_E::e100-hdd' ] );
931 # MEM: per-cpu memory usage
932 if( $devdetails->hasCap('e100-mem') )
934 my $subtree = "Memory_Usage";
935 my $memTree = $cb->addSubtree( $devNode, $subtree, undef,
936 [ 'Arbor_E::e100-mem-subtree' ] );
937 foreach my $memIndex ( sort keys %{$data->{'e100'}{'mem'}} )
939 my $memName = $data->{'e100'}{'cpu'}{$memIndex};
941 my $comment = "Memory for $memName CPU";
942 $cb->addSubtree( $memTree, $memName,
943 { 'comment' => $comment,
944 'mem-index' => $memIndex,
945 'mem-name' => $memName,
946 'precedence' => 1000 - $memIndex },
947 [ 'Arbor_E::e100-mem' ] );
951 # PolicyMmgt: Information regarding delta, service bundles, subnets
952 if( $devdetails->hasCap('e100-policymgmt') )
954 $cb->addTemplateApplication($devNode, 'Arbor_E::e100-policymgmt');
957 # SubscriberMgmt: Information regarding subscriber counts, states, etc.
958 if( $devdetails->hasCap('e100-submgmt') )
960 my $subMgmtTree = $cb->addSubtree( $devNode, 'Subscribers', undef,
961 [ 'Arbor_E::e100-submgmt-subtree' ]
964 my $stateTree = $cb->addSubtree( $subMgmtTree, 'Subscriber_State',
966 [ 'Arbor_E::e100-submgmt-state-subtree' ]
969 # State: Multigraph display
971 ('##one', '##two', '##three', '##four', '##five',
972 '##six', '##seven', '##eight', '##nine', '##ten'
975 'precedence' => 1000,
976 'graph-lower-limit' => 0,
977 'graph-title' => 'Summary of subscriber states',
978 'rrd-hwpredict' => 'disabled',
979 'vertical-label' => 'Subscribers',
980 'comment' => 'Summary of all states',
981 'ds-type' => 'rrd-multigraph'
985 foreach my $stateIDX ( sort keys %{$data->{'e100'}{'submgmt'}} )
987 my $color = shift @colors;
988 my $stateName = $data->{'e100'}{'submgmt'}{$stateIDX};
989 my $stateNameRRD = $stateName;
990 $stateNameRRD =~ s/[^a-zA-Z_]/_/o;
992 my $stateNode = $cb->addLeaf( $stateTree, $stateName,
993 { 'comment' => "State: $stateName",
994 'state-idx' => $stateIDX,
995 'state-name' => $stateName,
996 'state-rrd' => $stateNameRRD,
997 'precedence' => 100 - $stateIDX },
998 [ 'Arbor_E::e100-submgmt-state' ] );
999 $dsList .= $stateName . ',';
1001 $multiParam->{"ds-expr-$stateName"} = "{$stateName}";
1002 $multiParam->{"graph-legend-$stateName"} = "$stateName";
1003 $multiParam->{"line-style-$stateName"} = "LINE1";
1004 $multiParam->{"line-color-$stateName"} = $color,
1005 $multiParam->{"line-order-$stateName"} = $stateIDX;
1008 $multiParam->{'ds-names'} = $dsList;
1010 $cb->addLeaf($stateTree, 'Summary', $multiParam, undef );
1015 # -------------------------------------------------------------------------
1017 # Common information between e30 and e100
1019 if( $devdetails->hasCap('arbor-bundle') )
1021 my $subtreeName = "Bundle_Offer_Stats";
1022 my $param = { 'comment' => 'Byte counts for each bundle ' .
1024 my $templates = [ ];
1025 my $nodeTop = $cb->addSubtree( $devNode, $subtreeName,
1026 $param, $templates );
1028 foreach my $offerNameID ( keys %{$data->{'arbor_e'}{'offerName'}} )
1030 my $offerName = $data->{'arbor_e'}{'offerName'}{$offerNameID};
1031 $offerName =~ s/\W/_/g;
1032 my $offerBundle = $data->{'arbor_e'}{'boOfferBundle'};
1033 my $offerRRD = $offerNameID;
1035 if( $devdetails->param('Arbor_E::enable-bundle-name-rrd')
1038 # Filename will now be written as offer name
1039 $offerRRD = lc($offerName);
1043 my $oparam = { 'comment' => 'Offer: ' . $offerName,
1044 'offer-id' => $offerNameID,
1045 'offer-rrd' => $offerRRD };
1046 my $otemplates = [ 'Arbor_E::arbor-bundle-subtree' ];
1047 my $offerTop = $cb->addSubtree( $nodeTop, $offerName, $oparam,
1050 Debug(" Offer: $offerName");
1052 foreach my $bundleID ( @{$offerBundle->{$offerNameID}} )
1055 my $bundleName = $data->{'arbor_e'}{'bundleName'}{$bundleID};
1056 $bundleName =~ s/\W/_/g;
1057 my $bundleRRD = $bundleID;
1059 Debug(" $bundleID: $bundleName");
1061 if( $devdetails->param('Arbor_E::enable-bundle-name-rrd')
1064 # Filename will now be written as bundle name
1065 $bundleRRD = lc($bundleName);
1068 my $bparam = { 'comment' => 'Bundle ID: ' . $bundleID,
1069 'data-file' => '%system-id%_bo_' .
1072 'bundle-id' => $bundleID,
1073 'bundle-name' => $bundleName,
1074 'bundle-rrd' => $bundleRRD };
1075 push( @btemplates, 'Arbor_E::arbor-bundle' );
1077 # PROG: Subscribers using the bundle
1078 if( $devdetails->hasCap('arbor-bundle-subcount') )
1080 push( @btemplates, 'Arbor_E::arbor-bundle-subcount' );
1083 # PROG: Packets sent on this bundle per size
1084 if( $devdetails->hasCap('arbor-bundle-pktsize') )
1086 push( @btemplates, 'Arbor_E::arbor-bundle-pktsize' );
1089 # PROG: Bytes sent on this bundle for deny policy drop
1090 if( $devdetails->hasCap('arbor-bundle-deny') )
1092 push( @btemplates, 'Arbor_E::arbor-bundle-deny' );
1095 # PROG: Bytes sent on this bundle for rate limit drop
1096 if( $devdetails->hasCap('arbor-bundle-ratelimit') )
1098 push( @btemplates, 'Arbor_E::arbor-bundle-ratelimit' );
1102 $cb->addSubtree( $offerTop, $bundleName,
1103 $bparam, \@btemplates );
1104 } # END: foreach $bundleID
1105 } # END: foreach $offerNameID
1106 } # END: hasCap arbor-bundle
1108 # Flow device lookups
1109 if( $devdetails->hasCap('arbor-flowLookup') )
1111 # PROG: Flow Lookup Device (pool names)
1112 my $flowNode = $cb->addSubtree( $devNode, 'Flow_Lookup',
1113 { 'comment' => 'Switching modules' },
1116 my $flowLookup = $data->{'arbor_e'}{'flowModule'};
1118 foreach my $flowDevIdx ( keys %{$flowLookup} )
1120 my $flowNodeDev = $cb->addSubtree( $flowNode,
1121 'Flow_Lookup_' . $flowDevIdx,
1122 { 'comment' => 'Switching module '
1124 [ 'Arbor_E::arbor-flowlkup-subtree' ] );
1126 # PROG: Find all the pool names and add Subtree
1127 foreach my $flowPoolIdx ( keys %{$flowLookup->{$flowDevIdx}} )
1129 my $poolName = $flowLookup->{$flowDevIdx}{$flowPoolIdx};
1131 my $poolNode = $cb->addSubtree( $flowNodeDev, $poolName,
1132 { 'comment' => 'Flow Pool: ' . $poolName,
1133 'flowdev-index' => $flowDevIdx,
1134 'flowpool-index' => $flowPoolIdx,
1135 'flowpool-name' => $poolName,
1136 'precedence' => 1000 - $flowPoolIdx},
1137 [ 'Arbor_E::arbor-flowlkup-leaf' ] );
1138 } # END: foreach my $flowPoolIdx
1139 } # END: foreach my $flowDevIdx
1140 } # END: hasCap arbor-flowLookup
1148 # indent-tabs-mode: nil
1149 # perl-indent-level: 4