2 # Discovery module for Alcatel-Lucent ESS and SR routers
4 # Copyright (C) 2009 Stanislav Sinyagin
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20 # $Id: ALU_Timetra.pm,v 1.1 2010-12-27 00:03:49 ivan Exp $
21 # Stanislav Sinyagin <ssinyagin@yahoo.com>
24 # Currently tested with following Alcatel-Lucent devices:
28 package Torrus::DevDiscover::ALU_Timetra;
34 $Torrus::DevDiscover::registry{'ALU_Timetra'} = {
36 'checkdevtype' => \&checkdevtype,
37 'discover' => \&discover,
38 'buildConfig' => \&buildConfig
46 'tmnxChassisTotalNumber' => '1.3.6.1.4.1.6527.3.1.2.2.1.1.0',
49 'timetraReg' => '1.3.6.1.4.1.6527.1',
50 'timetraServiceRouters' => '1.3.6.1.4.1.6527.1.3',
51 'timetraServiceSwitches' => '1.3.6.1.4.1.6527.1.6',
52 'alcatel7710ServiceRouters' => '1.3.6.1.4.1.6527.1.9',
55 'custDescription' => '1.3.6.1.4.1.6527.3.1.2.4.1.3.1.3',
56 'svcCustId' => '1.3.6.1.4.1.6527.3.1.2.4.2.2.1.4',
57 'svcDescription' => '1.3.6.1.4.1.6527.3.1.2.4.2.2.1.6',
58 'sapDescription' => '1.3.6.1.4.1.6527.3.1.2.4.3.2.1.5',
60 # TIMETRA-PORT-MIB (chassis ID hardcoded to 1)
61 'tmnxPortDescription' => '1.3.6.1.4.1.6527.3.1.2.2.4.2.1.5.1',
62 'tmnxPortEncapType' => '1.3.6.1.4.1.6527.3.1.2.2.4.2.1.12.1',
66 my %essInterfaceFilter =
69 'ifType' => 24, # softwareLoopback
79 my $devdetails = shift;
81 my $objectID = $devdetails->snmpVar( $dd->oiddef('sysObjectID') );
83 if( $dd->oidBaseMatch( 'timetraReg', $objectID ) )
85 my $session = $dd->session();
86 my $oid = $dd->oiddef('tmnxChassisTotalNumber');
87 my $result = $session->get_request( $oid );
88 if( $result->{$oid} != 1 )
90 Error('Multi-chassis ALU 7x50 equipment is not yet supported');
94 if( $dd->oidBaseMatch( 'timetraServiceSwitches', $objectID ) )
96 $devdetails->setCap('ALU_ESS7450');
98 $devdetails->setCap('interfaceIndexingManaged');
99 $devdetails->setCap('interfaceIndexingPersistent');
101 &Torrus::DevDiscover::RFC2863_IF_MIB::addInterfaceFilter
102 ($devdetails, \%essInterfaceFilter);
104 $dd->setMaxMsgSize($devdetails, 65535, {'only_v1_and_v2' => 1});
110 # placeholder for future developments
111 Error('This model of Alcatel-Lucent equipment ' .
112 'is not yet supported');
126 my $devdetails = shift;
128 my $session = $dd->session();
129 my $data = $devdetails->data();
131 # WARNING: This code is tested only with ESS7450
133 # Get port descriptions
135 my $oid = $dd->oiddef('tmnxPortDescription');
137 my $portDescrTable = $session->get_table( -baseoid => $oid );
138 my $prefixLen = length( $oid ) + 1;
140 while( my( $oid, $descr ) = each %{$portDescrTable} )
142 my $ifIndex = substr( $oid, $prefixLen );
143 if( defined( $data->{'interfaces'}{$ifIndex} ) )
145 $data->{'interfaces'}{$ifIndex}{'tmnxPortDescription'} =
151 # Amend RFC2863_IF_MIB references
152 $data->{'nameref'}{'ifSubtreeName'} = 'ifNameT';
153 $data->{'nameref'}{'ifReferenceName'} = 'ifName';
154 $data->{'nameref'}{'ifNick'} = 'ifNameT';
155 $data->{'nameref'}{'ifComment'} = 'tmnxPortDescription';
159 my $oid = $dd->oiddef('custDescription');
160 my $custDescrTable = $session->get_table( -baseoid => $oid );
161 my $prefixLen = length( $oid ) + 1;
163 while( my( $oid, $descr ) = each %{$custDescrTable} )
165 my $custId = substr( $oid, $prefixLen );
166 $data->{'timetraCustDescr'}{$custId} = $descr;
171 # Get Service Descriptions
173 my $oid = $dd->oiddef('svcDescription');
174 my $svcDescrTable = $session->get_table( -baseoid => $oid );
175 my $prefixLen = length( $oid ) + 1;
177 while( my( $oid, $descr ) = each %{$svcDescrTable} )
179 my $svcId = substr( $oid, $prefixLen );
180 $data->{'timetraSvc'}{$svcId} = {
181 'description' => $descr,
187 # Get mapping of Services to Customers
189 my $oid = $dd->oiddef('svcCustId');
190 my $svcCustIdTable = $session->get_table( -baseoid => $oid );
191 my $prefixLen = length( $oid ) + 1;
193 while( my( $oid, $custId ) = each %{$svcCustIdTable} )
195 my $svcId = substr( $oid, $prefixLen );
197 $data->{'timetraCustSvc'}{$custId}{$svcId} = 1;
198 $data->{'timetraSvcCust'}{$svcId} = $custId;
203 # Get port encapsulations
205 my $oid = $dd->oiddef('tmnxPortEncapType');
207 my $portEncapTable = $session->get_table( -baseoid => $oid );
208 my $prefixLen = length( $oid ) + 1;
210 while( my( $oid, $encap ) = each %{$portEncapTable} )
212 my $ifIndex = substr( $oid, $prefixLen );
213 if( defined( $data->{'interfaces'}{$ifIndex} ) )
215 $data->{'interfaces'}{$ifIndex}{'tmnxPortEncapType'} = $encap;
221 # Get SAP information
223 my $oid = $dd->oiddef('sapDescription');
225 my $sapDescrTable = $session->get_table( -baseoid => $oid );
226 my $prefixLen = length( $oid ) + 1;
228 while( my( $oid, $descr ) = each %{$sapDescrTable} )
230 my $sapFullID = substr( $oid, $prefixLen );
232 my ($svcId, $ifIndex, $sapEncapValue) =
233 split(/\./o, $sapFullID);
235 my $svcSaps = $data->{'timetraSvc'}{$svcId}{'sap'};
236 if( not defined( $svcSaps ) )
238 Error('Cannot find Service ID ' . $svcId);
242 if( not defined( $data->{'interfaces'}{$ifIndex} ) )
244 Warn('IfIndex ' . $ifIndex . ' is not in interfaces table, ' .
249 my $encap = $data->{'interfaces'}{$ifIndex}{'tmnxPortEncapType'};
251 # Compose the SAP name depending on port encapsulation.
253 my $sapName = $data->{'interfaces'}{$ifIndex}{'ifName'};
255 if( $encap == 1 ) # nullEncap
259 elsif( $encap == 2 ) # qEncap
261 # sapEncapValue is equal to VLAN ID
262 $sapName .= ':' . $sapEncapValue;
264 elsif( $encap == 10 ) # qinqEncap
266 # sapEncapValue contains inner and outer VLAN IDs
268 my $outer = $sapEncapValue & 0xffff;
269 my $inner = $sapEncapValue >> 16;
276 $sapName .= ':' . $outer . '.' . $inner;
278 elsif( $encap == 3 ) # mplsEncap
280 # sapEncapValue contains the 20-bit LSP ID
281 # we should probably do something more here
282 $sapName .= ':' . $sapEncapValue;
286 Warn('Encapsulation type ' . $encap . ' is not supported yet');
287 $sapName .= ':' . $sapEncapValue;
290 $data->{'timetraSap'}{$sapFullID} = {
291 'description' => $descr,
294 'encval' => $sapEncapValue,
298 push( @{$svcSaps}, $sapFullID );
308 my $devdetails = shift;
311 my $data = $devdetails->data();
314 if( defined( $data->{'timetraSvc'} ) )
316 my $customersNode = $cb->addSubtree( $devNode, 'Customers' );
318 foreach my $custId (sort {$a <=> $b} keys %{$data->{'timetraCustSvc'}})
320 # count the number of SAPs
322 foreach my $svcId ( keys %{$data->{'timetraCustSvc'}{$custId}} )
324 my $svcSaps = $data->{'timetraSvc'}{$svcId}{'sap'};
325 if( defined( $svcSaps ) )
327 foreach my $sapID ( @{$svcSaps} )
329 if( not $data->{'timetraSap'}{$sapID}{'excluded'} )
343 'precedence' => 100000 - $custId,
344 'comment' => $data->{'timetraCustDescr'}{$custId},
345 'timetra-customer-id' => $custId,
349 $cb->addSubtree( $customersNode, $custId, $param,
350 ['ALU_Timetra::alu-timetra-customer']);
352 my $precedence = 10000;
355 ( keys %{$data->{'timetraCustSvc'}{$custId}} )
357 my $svcSaps = $data->{'timetraSvc'}{$svcId}{'sap'};
359 if( defined($svcSaps ) )
362 ( sort {sapCompare($data->{'timetraSap'}{$a},
363 $data->{'timetraSap'}{$b})}
366 my $sap = $data->{'timetraSap'}{$sapID};
368 if( $sap->{'excluded'} )
373 my $sapDescr = $sap->{'description'};
374 if( length( $sapDescr ) == 0 )
376 $sapDescr = $data->{'timetraSvc'}{$svcId}->{
380 my $subtreeName = $sap->{'name'};
381 $subtreeName =~ s/\W/_/go;
384 if( length( $sapDescr ) > 0 )
386 $comment = $sapDescr;
391 if( length($data->{'timetraCustDescr'}{$custId}) > 0 )
393 $legend .= 'Customer:' .
394 $devdetails->screenSpecialChars
395 ( $data->{'timetraCustDescr'}{$custId} ) . ';';
398 if( length($data->{'timetraSvc'}{$svcId}->{
399 'description'}) > 0 )
401 $legend .= 'Service:' .
402 $devdetails->screenSpecialChars
403 ( $data->{'timetraSvc'}{$svcId}->{
404 'description'} ) . ';';
408 $devdetails->screenSpecialChars( $sap->{'name'} );
412 'comment' => $comment,
413 'timetra-sap-id' => $sapID,
414 'timetra-sap-name' => $sap->{'name'},
415 'node-display-name' => $sap->{'name'},
416 'precedence' => $precedence--,
420 $cb->addSubtree( $custNode, $subtreeName, $param,
421 ['ALU_Timetra::alu-timetra-sap']);
435 if( $a->{'port'} == $b->{'port'} )
437 return ( $a->{'encval'} <=> $b->{'encval'} );
441 return ( $a->{'port'} <=> $b->{'port'} );
447 #######################################
448 # Selectors interface
452 $Torrus::DevDiscover::selectorsRegistry{'ALU_SAP'} = {
453 'getObjects' => \&getSelectorObjects,
454 'getObjectName' => \&getSelectorObjectName,
455 'checkAttribute' => \&checkSelectorAttribute,
456 'applyAction' => \&applySelectorAction,
459 ## Objects are full SAP indexes: svcId.sapPortId.sapEncapValue
461 sub getSelectorObjects
463 my $devdetails = shift;
466 my $data = $devdetails->data();
467 my @ret = keys %{$data->{'timetraSap'}};
469 return( sort {$a<=>$b} @ret );
473 sub checkSelectorAttribute
475 my $devdetails = shift;
479 my $checkval = shift;
481 my $data = $devdetails->data();
486 my $sap = $data->{'timetraSap'}{$object};
488 if( $attr eq 'sapDescr' )
490 $value = $sap->{'description'};
492 elsif( $attr eq 'custDescr' )
494 my $svcId = $sap->{'svc'};
495 my $custId = $data->{'timetraSvcCust'}{$svcId};
496 $value = $data->{'timetraCustDescr'}{$custId};
498 elsif( $attr eq 'sapName' )
500 $value = $sap->{'name'};
503 elsif( $attr eq 'sapPort' )
505 my $ifIndex = $sap->{'port'};
506 $value = $data->{'interfaces'}{$ifIndex}{'ifName'};
511 Error('Unknown ALU_SAP selector attribute: ' . $attr);
516 return eval( '$value' . ' ' . $operator . '$checkval' ) ? 1:0;
520 sub getSelectorObjectName
522 my $devdetails = shift;
526 my $data = $devdetails->data();
528 return $data->{'timetraSap'}{$object}{'name'};
532 my %knownSelectorActions =
538 sub applySelectorAction
540 my $devdetails = shift;
546 my $data = $devdetails->data();
549 if( not $knownSelectorActions{$action} )
551 Error('Unknown ALU_SAP selector action: ' . $action);
555 if( $action eq 'RemoveSAP' )
557 $data->{'timetraSap'}{$object}{'excluded'} = 1;
565 # indent-tabs-mode: nil
566 # perl-indent-level: 4