2
* Copyright (c) 2004 Mellanox Technologies LTD. All rights reserved.
4
* This software is available to you under a choice of one of two
5
* licenses. You may choose to be licensed under the terms of the GNU
6
* General Public License (GPL) Version 2, available from the file
7
* COPYING in the main directory of this source tree, or the
8
* OpenIB.org BSD license below:
10
* Redistribution and use in source and binary forms, with or
11
* without modification, are permitted provided that the following
14
* - Redistributions of source code must retain the above
15
* copyright notice, this list of conditions and the following
18
* - Redistributions in binary form must reproduce the above
19
* copyright notice, this list of conditions and the following
20
* disclaimer in the documentation and/or other materials
21
* provided with the distribution.
23
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
* IB Fabric Data Model (and Utilities)
39
* Data Model Interface File for TCL SWIG
43
%title "IB Fabric Data Model - TCL Extention"
54
#include "CredLoops.h"
55
#include "TraceRoute.h"
56
#include "TopoMatch.h"
57
#include "Congestion.h"
60
# define __PRI64_PREFIX "l"
61
# define __PRIPTR_PREFIX "l"
63
# define __PRI64_PREFIX "ll"
64
# define __PRIPTR_PREFIX
67
# define PRIx64 __PRI64_PREFIX "x"
73
static char ibdm_tcl_error_msg[1024];
74
static int ibdm_tcl_error;
75
static vector< IBFabric *> ibdm_fabrics;
76
static IBLinkWidth UnknownLinkWidth = IB_UNKNOWN_LINK_WIDTH;
77
static IBLinkSpeed UnknownLinkSpeed = IB_UNKNOWN_LINK_SPEED;
78
static IBLinkWidth DefaultLinkWidth = IB_LINK_WIDTH_4X;
79
static IBLinkSpeed DefaultLinkSpeed = IB_LINK_SPEED_2_5;
82
MAPPING IBDM OBJECTS TO TCL and BACK:
83
The idea is that we have specifc rules for naming
84
Node, Port, System and SystemPort for a specific Fabric.
86
All Fabrics are stored by id in a global vector.
88
So the object names will follow:
89
<type>:<fabricIdx>/<name>
93
/* Given a fabric pointer return its idx (starting w 1) or 0 */
94
int ibdmGetFabricIdxByPtr(IBFabric *p_fabric) {
95
/* go over all fabrics and find it's index: */
96
for (unsigned int i = 0; i < ibdm_fabrics.size(); i++) {
97
if (ibdm_fabrics[i] == p_fabric) {
104
/* Given a fabric idx return it's pointer */
105
/* Note the index is 1-N and thus we need to -1 it before access */
106
IBFabric *ibdmGetFabricPtrByIdx(unsigned int idx) {
107
if ((idx > ibdm_fabrics.size()) || (idx < 1)) {
110
return ibdm_fabrics[idx - 1];
114
we provide our own constructor such that all IBFabrics are
115
registered in the global vector;
117
IBFabric *new_IBFabric(void) {
118
IBFabric *p_fabric = new IBFabric();
121
/* look for an open index in the vector of fabrics */
122
for (i = 0; i < ibdm_fabrics.size(); i++)
124
if (ibdm_fabrics[i] == NULL)
126
ibdm_fabrics[i] = p_fabric;
130
ibdm_fabrics.push_back(p_fabric);
136
we provide our own destructor such that the deleted fabric is
137
de-registered from the global fabrics vector
139
void delete_IBFabric(IBFabric *p_fabric) {
140
int idx = ibdmGetFabricIdxByPtr(p_fabric);
142
printf("ERROR: Fabric idx:%p does not exist in the global vector!\n",
145
ibdm_fabrics[idx-1] = NULL;
150
/* Given the Object Pointer and Type provide it's TCL name */
151
int ibdmGetObjTclNameByPtr(Tcl_Obj *objPtr, void *ptr, char *type) {
157
if (!strcmp(type, "IBNode *")) {
158
IBNode *p_node = (IBNode *)ptr;
159
p_fabric = p_node->p_fabric;
160
sprintf(name, ":%s", p_node->name.c_str());
162
} else if (!strcmp(type, "IBPort *")) {
163
IBPort *p_port = (IBPort *)ptr;
164
sprintf(name,":%s/%u", p_port->p_node->name.c_str(), p_port->num);
165
p_fabric = p_port->p_node->p_fabric;
167
} else if (!strcmp(type, "IBSystem *")) {
168
IBSystem *p_system = (IBSystem *)ptr;
169
sprintf(name, ":%s", p_system->name.c_str());
171
p_fabric = p_system->p_fabric;
172
} else if (!strcmp(type, "IBSysPort *")) {
173
IBSysPort *p_sysPort = (IBSysPort *)ptr;
174
sprintf(name, ":%s:%s", p_sysPort->p_system->name.c_str(),
175
p_sysPort->name.c_str());
177
p_fabric = p_sysPort->p_system->p_fabric;
178
} else if (!strcmp(type, "IBFabric *")) {
179
p_fabric = (IBFabric *)ptr;
183
sprintf(tclName, "-E- Unrecognized Object Type:%s", type);
184
Tcl_SetStringObj(objPtr, tclName, -1);
188
/* get the fabric index */
189
int idx = ibdmGetFabricIdxByPtr(p_fabric);
191
Tcl_SetStringObj(objPtr, "-E- Fail to find fabric by ptr", -1);
195
sprintf(tclName, "%s:%u%s", uiType.c_str(), idx, name);
196
Tcl_SetStringObj(objPtr, tclName, -1);
200
/* Given the Object TCL Name Get it's pointer */
201
int ibdmGetObjPtrByTclName(Tcl_Obj *objPtr, void **ptr) {
202
/* we need to parse the name and get the type etc. */
204
char *type, *name=0, *fabIdxStr;
205
char *colonIdx, *slashIdx;
209
strcpy(buf, Tcl_GetStringFromObj(objPtr,0));
211
/* the format is always: <type>:<idx>[:<name>] */
213
/* first separate the type */
214
colonIdx = index(buf,':');
216
printf("-E- Bad formatted (no :) ibdm object:%s\n", buf);
222
fabIdxStr = ++colonIdx;
224
/* now separate the fabric section if tyep is not fabric */
225
if (strcmp(type, "fabric")) {
226
slashIdx = index(fabIdxStr,':');
228
printf( "-E- Bad formatted ibdm fabric object:%s\n",
229
Tcl_GetStringFromObj(objPtr,0));
236
/* Ok so now get the fabic pointer */
237
fabricIdx = atoi(fabIdxStr);
239
IBFabric *p_fabric = ibdmGetFabricPtrByIdx(fabricIdx);
245
if (!strcmp(type, "fabric")) {
247
} else if (!strcmp(type, "node")) {
248
IBNode *p_node = p_fabric->getNode(string(name));
250
printf("-E- Fail to get node:%s\n", name);
254
} else if (!strcmp(type, "port")) {
255
slashIdx = rindex(name,'/');
257
printf("-E- Bad formatted ibdm node object:%s\n",
258
Tcl_GetStringFromObj(objPtr,0));
262
int portNum = atoi(++slashIdx);
263
IBNode *p_node = p_fabric->getNode(string(name));
265
printf("-E- Fail to get node:%s\n", name);
268
IBPort *p_port = p_node->getPort(portNum);
270
printf("-E- Fail to get node:%s port:%u\n",
275
} else if (!strcmp(type, "system")) {
276
IBSystem *p_system = p_fabric->getSystem(string(name));
278
printf("-E- Fail to get system:%s\n", name);
282
} else if (!strcmp(type, "sysport")) {
283
/* the format of system port is: <type>:<idx>:<sys>:<port> */
284
colonIdx = index(name,':');
286
printf("-E- Bad formatted ibdm sysport object:%s\n",
287
Tcl_GetStringFromObj(objPtr,0) );
291
IBSystem *p_system = p_fabric->getSystem(string(name));
293
printf("-E- Fail to get system:%s\n", name);
296
IBSysPort *p_sysPort = p_system->getSysPort(string(++colonIdx));
298
printf("-E- Fail to get system:%s port:%s\n", name, colonIdx);
303
printf("-E- Unrecognized Object Type:%s\n", type);
309
int ibdmReportNonUpDownCa2CaPaths(IBFabric *p_fabric, list_pnode rootNodes) {
310
map_pnode_int nodesRank;
311
if (SubnRankFabricNodesByRootNodes(p_fabric, rootNodes, nodesRank))
313
printf("-E- fail to rank the fabric by the given root nodes.\n");
316
return( SubnReportNonUpDownCa2CaPaths(p_fabric, nodesRank));
319
int ibdmFatTreeRoute(IBFabric *p_fabric, list_pnode rootNodes) {
320
map_pnode_int nodesRank;
321
if (SubnRankFabricNodesByRootNodes(p_fabric, rootNodes, nodesRank))
323
printf("-E- fail to rank the fabric by the given root nodes.\n");
326
return( SubnMgtFatTreeRoute(p_fabric));
329
int ibdmCheckFabricMCGrpsForCreditLoopPotential(IBFabric *p_fabric, list_pnode rootNodes) {
330
map_pnode_int nodesRank;
331
if (SubnRankFabricNodesByRootNodes(p_fabric, rootNodes, nodesRank))
333
printf("-E- fail to rank the fabric by the given root nodes.\n");
336
return( SubnMgtCheckFabricMCGrpsForCreditLoopPotential(p_fabric, nodesRank));
339
int ibdmRankFabricByRoots(IBFabric *p_fabric, list_pnode rootNodes) {
340
map_pnode_int nodesRank;
341
if (SubnRankFabricNodesByRootNodes(p_fabric, rootNodes, nodesRank))
343
printf("-E- fail to rank the fabric by the given root nodes.\n");
353
// exception handling wrapper based on the MsgMgr interfaces
356
// it assumes we do not send the messages to stderr
360
if (ibdm_tcl_error) {
361
Tcl_SetStringObj(Tcl_GetObjResult(interp), ibdm_tcl_error_msg, -1);
371
// Convert a TCL Object to C++ world.
372
%typemap(tcl8,in) IBFabric *, IBNode *, IBSystem *, IBPort *, IBSysPort * {
375
if (ibdmGetObjPtrByTclName($source, &ptr) != TCL_OK) {
377
sprintf(err, "-E- fail to find ibdm obj by id:%s",Tcl_GetString($source) );
378
// Tcl_SetStringObj(tcl_result, err, strlen(err));
382
$target = ($type)ptr;
385
// Convert C++ pointer to TCL
386
%typemap(tcl8,out) IBFabric *, IBNode *, IBSystem *, IBPort *, IBSysPort * {
388
ibdmGetObjTclNameByPtr($target, $source, "$type");
391
%typemap(tcl8,check) IBFabric *, IBNode *, IBSystem *, IBPort *, IBSysPort * {
392
/* the format is always: <type>:<idx>[:<name>] */
394
// get the type from the given source
396
strcpy(buf, Tcl_GetStringFromObj($source,0));
397
char *colonIdx = index(buf,':');
400
sprintf(err, "-E- Bad formatted ibdm object:%s", buf);
401
Tcl_SetStringObj(tcl_result, err, strlen(err));
406
if (!strcmp("$basetype", "IBFabric ")) {
407
if (strcmp(buf, "fabric")) {
409
sprintf(err, "-E- basetype is $basetype but received obj of type %s", buf);
410
Tcl_SetStringObj(tcl_result, err, strlen(err));
413
} else if (!strcmp("$basetype", "IBSystem ")) {
414
if (strcmp(buf, "system")) {
416
sprintf(err, "-E- basetype is $basetype but received obj of type %s", buf);
417
Tcl_SetStringObj(tcl_result, err, strlen(err));
420
} else if (!strcmp("$basetype", "IBSysPort ")) {
421
if (strcmp(buf, "sysport")) {
423
sprintf(err, "-E- basetype is $basetype but received obj of type %s", buf);
424
Tcl_SetStringObj(tcl_result, err, strlen(err));
427
} else if (!strcmp("$basetype", "IBNode ")) {
428
if (strcmp(buf, "node")) {
430
sprintf(err, "-E- basetype is $basetype but received obj of type %s", buf);
431
Tcl_SetStringObj(tcl_result, err, strlen(err));
434
} else if (!strcmp("$basetype", "IBPort ")) {
435
if (strcmp(buf, "port")) {
437
sprintf(err, "-E- basetype is $basetype but received obj of type %s", buf);
438
Tcl_SetStringObj(tcl_result, err, strlen(err));
443
sprintf(err, "-E- basetype '$basetype' is unknown");
444
Tcl_SetStringObj(tcl_result, err, strlen(err));
449
// representing vec_pport in TCL
450
%typemap(tcl8, out) vec_pport * {
453
for (unsigned int i = 0; i < $source->size(); i++) {
454
IBPort *p_port = (*$source)[i];
456
p_tclObj = Tcl_NewObj();
457
if (ibdmGetObjTclNameByPtr(p_tclObj, p_port, "IBPort *")
459
printf("-E- Fail to map Port Object (a Vector element)\n");
461
Tcl_AppendElement(interp, Tcl_GetString(p_tclObj));
463
Tcl_DecrRefCount(p_tclObj);
468
%typemap(tcl8, out) vec_vec_byte * {
469
for (unsigned int i = 0; i < $source->size(); i++) {
470
Tcl_AppendResult(interp,"{", NULL);
471
for (unsigned int j = 0; j < (*$source)[i].size(); j++) {
473
sprintf(buf,"%u ", (*$source)[i][j]);
474
Tcl_AppendResult(interp, buf, NULL);
476
Tcl_AppendResult(interp,"} ", NULL);
480
%typemap(tcl8, out) vec_byte * {
481
for (unsigned int i = 0; i < $source->size(); i++) {
483
sprintf(buf,"%u ", (*$source)[i]);
484
Tcl_AppendResult(interp, buf, NULL);
488
// representing map_str_psysport in TCL
489
%typemap(tcl8, out) map_str_psysport * {
490
// build a TCL list out of the Objec ID's of the ibdm objects in it.
491
map_str_psysport::const_iterator I = $source->begin();
494
while (I != $source->end()) {
495
p_tclObj = Tcl_NewObj();
496
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBSysPort *") != TCL_OK) {
497
printf("-E- Fail to map SysPort Object (a Vector element)\n");
500
sprintf(buf, "%s %s", (*I).first.c_str(), Tcl_GetString(p_tclObj));
501
Tcl_AppendElement(interp, buf);
503
Tcl_DecrRefCount(p_tclObj);
508
// representing map_str_psys in TCL
509
%typemap(tcl8, out) map_str_psys * {
510
// build a TCL list out of the Objec ID's of the ibdm objects in it.
511
map_str_psys::const_iterator I = $source->begin();
514
while (I != $source->end()) {
515
p_tclObj = Tcl_NewObj();
516
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBSystem *") != TCL_OK) {
517
printf("-E- Fail to map System Object (a Vector element)\n");
520
sprintf(buf, "%s %s", (*I).first.c_str(), Tcl_GetString(p_tclObj));
521
Tcl_AppendElement(interp, buf);
523
Tcl_DecrRefCount(p_tclObj);
528
// representing map_str_pnode in TCL
529
%typemap(tcl8, out) map_str_pnode * {
530
// build a TCL list out of the Objec ID's of the ibdm objects in it.
531
map_str_pnode::const_iterator I = $source->begin();
534
while (I != $source->end()) {
535
p_tclObj = Tcl_NewObj();
536
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBNode *") != TCL_OK) {
537
printf("-E- Fail to map Node Object (a Vector element)\n");
540
sprintf(buf, "%s %s", (*I).first.c_str(), Tcl_GetString(p_tclObj));
541
Tcl_AppendElement(interp, buf);
543
Tcl_DecrRefCount(p_tclObj);
548
// representing map_guid_pport in TCL
549
%typemap(tcl8, out) map_guid_pport * {
550
// build a TCL list out of the Objec ID's of the ibdm objects in it.
551
map_guid_pport::const_iterator I = $source->begin();
554
while (I != $source->end()) {
555
p_tclObj = Tcl_NewObj();
556
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBPort *") != TCL_OK) {
557
printf("-E- Fail to map Port Object (a guid map element)\n");
560
sprintf(buf, "0x%016" PRIx64 " %s",
561
(*I).first, Tcl_GetString(p_tclObj));
562
Tcl_AppendElement(interp, buf);
564
Tcl_DecrRefCount(p_tclObj);
569
// representing map_guid_pnode in TCL
570
%typemap(tcl8, out) map_guid_pnode * {
571
// build a TCL list out of the Objec ID's of the ibdm objects in it.
572
map_guid_pnode::const_iterator I = $source->begin();
575
while (I != $source->end()) {
576
p_tclObj = Tcl_NewObj();
577
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBNode *") != TCL_OK) {
578
printf("-E- Fail to map Node Object (a guid map element)\n");
581
sprintf(buf, "0x%016" PRIx64 " %s",
582
(*I).first, Tcl_GetString(p_tclObj));
583
Tcl_AppendElement(interp, buf);
585
Tcl_DecrRefCount(p_tclObj);
590
// representing map_guid_psystem in TCL
591
%typemap(tcl8, out) map_guid_psys * {
592
// build a TCL list out of the Objec ID's of the ibdm objects in it.
593
map_guid_psys::const_iterator I = $source->begin();
596
while (I != $source->end()) {
597
p_tclObj = Tcl_NewObj();
598
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I).second, "IBSystem *") != TCL_OK) {
599
printf("-E- Fail to map System Object (a guid map element)\n");
602
sprintf(buf, "0x%016" PRIx64 " %s",
603
(*I).first, Tcl_GetString(p_tclObj));
604
Tcl_AppendElement(interp, buf);
606
Tcl_DecrRefCount(p_tclObj);
611
// cast a Tcl String object to string
612
%typemap(tcl8,in) string * {
614
static string $target_tmp;
615
$target_tmp = string(Tcl_GetStringFromObj($source,&len));
616
$target = &$target_tmp;
619
// NOTE FOR SOME REASON THE RETURN TYPE IS TAKEN NOT AS A POINTER
620
// BUT PASSED AS ONE ?????
622
// return a char * from a string:
623
%typemap(tcl8,out) string, string * {
625
strcpy(ezTmp, $source->c_str());
626
Tcl_SetStringObj(tcl_result, ezTmp, strlen(ezTmp));
629
#define new_string string
631
// return a char * from a string that was allocated previously
632
// so we need to delete it
633
%typemap(tcl8,out) new_string, new_string * {
635
strcpy(ezTmp, $source->c_str());
636
Tcl_SetStringObj(tcl_result, ezTmp, strlen(ezTmp));
640
%typemap (tcl8, ignore) char **p_out_str (char *p_c) {
644
%typemap (tcl8, argout) char **p_out_str {
646
Tcl_SetStringObj($target,*$source,strlen(*$source));
649
Tcl_SetStringObj($target,"",-1);
654
TCL Type Maps for Standard Integer Types
657
%typemap(tcl8,in) uint64_t *(uint64_t temp) {
658
temp = strtoull(Tcl_GetStringFromObj($source,NULL), NULL,16);
662
%typemap(tcl8,out) uint64_t {
664
sprintf(buff, "0x%016" PRIx64, *$source);
665
Tcl_SetStringObj($target,buff,strlen(buff));
668
%typemap(tcl8,out) uint64_t * {
670
sprintf(buff, "0x%016" PRIx64, *$source);
671
Tcl_SetStringObj($target,buff,strlen(buff));
675
#define new_uint64_t uint64_t
677
%typemap(tcl8,out) new_uint64_t *, new_uint64_t {
679
/* new_uint64_t tcl8 out */
680
sprintf(buff, "0x%016" PRIx64, *$source);
681
Tcl_SetStringObj($target,buff,strlen(buff));
685
%typemap(tcl8,in) uint32_t * (uint32_t temp){
686
temp = strtoul(Tcl_GetStringFromObj($source,NULL), NULL, 0);
690
%typemap(tcl8,out) uint32_t * {
692
sprintf(buff, "%u", *$source);
693
Tcl_SetStringObj($target,buff,strlen(buff));
696
%typemap(tcl8,in) uint16_t * (uint16_t temp) {
697
temp = strtoul(Tcl_GetStringFromObj($source,NULL), NULL, 0);
701
%typemap(tcl8,out) uint16_t * {
703
sprintf(buff, "%u", *$source);
704
Tcl_SetStringObj($target,buff,strlen(buff));
707
%typemap(tcl8,in) uint8_t * (uint8_t temp) {
708
temp = strtoul(Tcl_GetStringFromObj($source,NULL), NULL, 0);
712
%typemap(tcl8,out) uint8_t * {
714
sprintf(buff, "%u", *$source);
715
Tcl_SetStringObj($target,buff,strlen(buff));
718
%typemap(tcl8,in) ib_net64_t *(uint64_t temp) {
719
temp = cl_hton64(strtoull(Tcl_GetStringFromObj($source,NULL), NULL, 16));
723
%typemap(tcl8,out) ib_net64_t * {
725
sprintf(buff, "0x%016" PRIx64, cl_ntoh64(*$source));
726
Tcl_SetStringObj($target,buff,strlen(buff));
729
%typemap(tcl8,in) ib_net32_t *(ib_net32_t temp) {
730
temp = cl_hton32(strtoul(Tcl_GetStringFromObj($source,NULL), NULL, 0));
734
%typemap(tcl8,out) ib_net32_t * {
736
sprintf(buff, "%u", cl_ntoh32(*$source));
737
Tcl_SetStringObj($target,buff,strlen(buff));
740
%typemap(tcl8,in) ib_net16_t * (ib_net16_t temp) {
741
temp = cl_hton16(strtoul(Tcl_GetStringFromObj($source,NULL), NULL, 0));
745
%typemap(tcl8,out) ib_net16_t * {
747
sprintf(buff, "%u", cl_hton16(*$source));
748
Tcl_SetStringObj($target,buff,strlen(buff));
751
%typemap(tcl8,argout) uint64_t *OUTPUT {
753
sprintf(buff, "0x%016" PRIx64, *$source);
754
Tcl_SetStringObj($target,buff,strlen(buff));
757
%typemap(tcl8,ignore) uint64_t *OUTPUT(uint64_t temp) {
762
%typemap(tcl8,argout) ostringstream & {
763
Tcl_SetStringObj($target, (char*)$source->str().c_str(),
764
$source->str().size() + 1);
767
%typemap(tcl8,ignore) ostringstream &(ostringstream tempStream) {
768
$target = &tempStream;
771
%typemap(tcl8,out) boolean_t * {
773
Tcl_SetStringObj($target,"TRUE", 4);
775
Tcl_SetStringObj($target,"FALSE", 5);
779
%typemap(tcl8,in) boolean_t *(boolean_t temp) {
780
if (strcmp(Tcl_GetStringFromObj($source,NULL), "TRUE")) {
788
%typemap(tcl8,out) IBLinkWidth * {
789
Tcl_SetStringObj($target,width2char(*$source), -1);
792
%typemap(tcl8,in) IBLinkWidth * (IBLinkWidth temp1) {
793
temp1 = char2width(Tcl_GetStringFromObj($source,NULL));
797
%typemap(tcl8,out) IBLinkSpeed * {
798
Tcl_SetStringObj($target,speed2char(*$source), -1);
801
%typemap(tcl8,in) IBLinkSpeed * (IBLinkSpeed temp2) {
802
temp2 = char2speed(Tcl_GetStringFromObj($source,NULL));
807
%typemap(tcl8,out) list_pnode *, list_pnode {
808
// build a TCL list out of the Objec ID's of the ibdm objects in it.
809
list_pnode::const_iterator I = $source->begin();
812
while (I != $source->end()) {
813
p_tclObj = Tcl_NewObj();
814
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I), "IBNode *") != TCL_OK) {
815
printf("-E- Fail to map Node Object (a guid map element)\n");
818
sprintf(buf, "%s", Tcl_GetString(p_tclObj));
819
Tcl_AppendElement(interp, buf);
821
Tcl_DecrRefCount(p_tclObj);
826
// given a list of node names - generate the list of nodes
827
%typemap(tcl8,in) list_pnode * (list_pnode tmpNodeList) {
828
#if TCL_MINOR_VERSION > 3
829
const char **sub_lists;
836
/* we will use the TCL split list to split into elements */
837
if (Tcl_SplitList(interp,
838
Tcl_GetStringFromObj($source,0),
839
&num_sub_lists, &sub_lists) != TCL_OK) {
840
printf("-E- Bad formatted list :%s\n",
841
Tcl_GetStringFromObj($source,0));
845
for (idx = 0; (idx < num_sub_lists); idx++)
847
/* we need to double copy since TCL 8.4 requires split res to be const */
851
strcpy(buf, sub_lists[idx]);
853
if (strncmp("node:", buf, 5)) {
854
printf("-E- Bad formatted node (%u) object:%s\n", idx, buf);
858
p_tclObj = Tcl_NewObj();
859
Tcl_SetStringObj(p_tclObj, buf, -1);
860
if (ibdmGetObjPtrByTclName(p_tclObj, &ptr) != TCL_OK) {
861
printf("-E- fail to find ibdm obj by id:%s", buf );
862
Tcl_DecrRefCount(p_tclObj);
865
Tcl_DecrRefCount(p_tclObj);
866
tmpNodeList.push_back((IBNode *)ptr);
869
$target = &tmpNodeList;
873
// INTERFACE DEFINITION (~copy of h file)
876
%section "IBDM Constants"
877
/* These constants are provided by IBDM: */
879
typedef enum {IB_UNKNOWN_NODE_TYPE, IB_SW_NODE, IB_CA_NODE} IBNodeType;
882
%subsection "Log Verbosity Flags",before,pre
883
/* To be or'ed and used as the value of FabricUtilsVerboseLevel */
885
#define FABU_LOG_NONE 0x0
886
#define FABU_LOG_ERROR 0x1
887
#define FABU_LOG_INFO 0x2
888
#define FABU_LOG_VERBOSE 0x4
891
%section "IBDM Globals"
892
int FabricUtilsVerboseLevel;
893
/* Log level: set to FABU_LOG* values */
895
int ibdmUseInternalLog();
896
/* instruct ibdm to use intrernal buffer for log */
897
int ibdmUseCoutLog();
898
/* use stdout for log */
899
%new char *ibdmGetAndClearInternalLog();
900
/* obtain log messages from internal log and clear it */
902
%section "IBDM Objects",pre
903
/* This section decribes the various object types exposed by IBDM. */
906
IBDM exposes some of its internal objects. The objects
907
identifiers returned by the various function calls are formatted
908
according to the following rules:
910
System: system:<fab idx>:<sys name>
911
SysPort: sysport:<fab idx>:<sys name>:<port name>
912
Node: node:<fab idx>:<node name>
913
Port: port:<fab idx>:<node name>/<port num>
915
IBDM Objects are standard Swig-Tcl objects.
916
As such they have two flavors for their usage: Variables, Objects.
919
For each object attribute a "get" and "set" methods are provided.
920
The format of the methods is: <class>_<attribute>_<get|set>.
921
The "set" method is only available for read/write attributes.
924
set nodes [ibdm_get_nodes]
925
set node [lindex $nodes 0]
926
IBNode_numPorts_get $node
929
Given an object pointer one can convert it to a Tcl "Object"
930
using the following command:
931
<class> <obj_name> -this <obj pointer>
933
Once declared the <obj-name> can be used in conjunction to
934
with the standard "configure" and "cget" commands.
936
Example (following the previous one):
937
IBFabric VaTech -this $fabric
938
VaTech cget -NodeByName
940
To delete an object symbol (and enable its mapping to another
949
// This is not the "End Node" but the physical port of
954
IBPort * p_remotePort; // Port connected on the other side of link
955
IBSysPort * p_sysPort; // The system port (if any) connected to
956
IBNode * p_node; // The node the port is part of.
957
int num; // Physical ports are identified by number.
958
unsigned int base_lid; // The base lid assigned to the port.
959
IBLinkWidth width; // The link width of the port
960
IBLinkSpeed speed; // The link speed of the port
961
unsigned int counter1; // a generic value to be used by various algorithms
963
IBPort(IBNode *p_nodePtr, int number);
966
new_uint64_t guid_get();
967
void guid_set(uint64_t guid);
969
new_string getName();
971
void connect (IBPort *p_otherPort,
972
IBLinkWidth w = DefaultLinkWidth,
973
IBLinkSpeed s = DefaultLinkSpeed);
974
// connect the port to another node port
977
// disconnect the port. Return 0 if successful
986
string name; // Name of the node (instance name of the chip)
987
IBNodeType type; // Either a CA or SW
988
uint32_t devId; // The device ID of the node
989
uint32_t revId; // The device revision Id.
990
uint32_t vendId; // The device Vendor ID.
991
string attributes;// Comma-sep string of arbitrary attributes k=v
992
uint8_t rank; // The rank of the node in the tree
994
IBSystem *p_system; // What system we belong to
995
IBFabric *p_fabric; // What fabric we belong to.
996
unsigned int numPorts; // Number of physical ports
997
vec_pport Ports; // Vector of all the ports
998
vec_vec_byte MinHopsTable; // Table describing minimal hop count through
999
// each port to each target lid
1000
vec_byte LFT; // The LFT of this node (for switches only)
1002
// void *p_appData1; // Application Private Data #1
1003
// void *p_appData2; // Application Private Data #2
1005
new_uint64_t guid_get();
1006
void guid_set(uint64_t guid);
1011
IBNodeType t, int np);
1016
inline IBPort *makePort (unsigned int num);
1017
// create a new port by name if required to
1019
inline IBPort *getPort(unsigned int num);
1020
// get a port by number num = 1..N:
1022
void setHops (IBPort *p_port, unsigned int lid, int hops);
1023
// Set the min hop for the given port (* is all) lid pair
1025
int getHops (IBPort *p_port, unsigned int lid);
1026
// Get the min number of hops defined for the given port or all
1028
IBPort *getFirstMinHopPort(unsigned int lid);
1029
// Scan the node ports and find the first port
1030
// with min hop to the lid
1032
void setLFTPortForLid (unsigned int lid, unsigned int portNum);
1033
// Set the Linear Forwarding Table:
1035
int getLFTPortForLid (unsigned int lid);
1036
// Get the LFT for a given lid
1039
// dump out the min hop table of the node
1044
// System Port Class
1045
// The System Port is a front pannel entity.
1049
string name; // The front pannel name of the port
1050
IBSysPort *p_remoteSysPort; // If connected the other side sys port
1051
IBSystem *p_system; // System it benongs to
1052
IBPort *p_nodePort; // The node port it connects to.
1054
IBSysPort(string n, IBSystem *p_sys);
1059
void connect (IBSysPort *p_otherSysPort,
1060
IBLinkWidth width = UnknownLinkWidth,
1061
IBLinkSpeed speed = UnknownLinkSpeed);
1062
// connect two SysPorts
1065
// disconnect the SysPort (and ports). Return 0 if successful
1071
// This is normally derived into a system specific class
1075
string name; // the "host" name of the system
1076
string type; // what is the type i.e. Cougar, Buffalo etc
1077
IBFabric *p_fabric; // fabric belongs to
1079
map_str_pnode NodeByName; // Provide the node pointer by its name
1080
map_str_psysport PortByName;// A map provising pointer to the SysPort by name
1083
IBSystem(string n, IBFabric *p_fab, string t);
1088
new_uint64_t guid_get();
1089
void guid_set(uint64_t guid);
1091
IBSysPort *makeSysPort (string pName);
1092
// make sure we got the port defined (so define it if not)
1094
IBPort *getSysPortNodePortByName (string sysPortName);
1095
// get the node port for the given sys port by name
1097
IBSysPort *getSysPort(string name);
1098
// Get a Sys Port by name
1103
// The entire fabric
1108
map_str_pnode NodeByName; // Provide the node pointer by its name
1109
map_str_psys SystemByName; // Provide the system pointer by its name
1110
vec_pport PortByLid; // Pointer to the Port by its lid
1111
map_guid_pnode NodeByGuid; // Provides the node by guid
1112
map_guid_psys SystemByGuid; // Provides the system by guid
1113
map_guid_pport PortByGuid; // Provides the port by guid
1115
unsigned int minLid; // Track min lid used.
1116
unsigned int maxLid; // Track max lid used.
1117
unsigned int lmc; // LMC value used
1119
// IBFabric() {maxLid = 0;};
1121
// we need to have our own destructor to take care of the
1122
// fabrics vector cleanup
1126
IBNode *makeNode (string n,
1129
unsigned int numPorts);
1130
// get the node by its name (create one of does not exist)
1132
IBNode *getNode (string name);
1133
// get the node by its name
1135
list_pnode *getNodesByType (IBNodeType type);
1136
// return the list of node pointers matching the required type
1138
IBSystem *makeGenericSystem (string name);
1139
// crate a new generic system - basically an empty contaner for nodes...
1141
IBSystem *makeSystem (string name, string type);
1142
// crate a new system - the type must have a registed factory.
1144
IBSystem *getSystem(string name);
1145
// Get system by name
1147
IBSystem *getSystemByGuid(uint64_t guid);
1148
// get the system by its guid
1149
IBNode *getNodeByGuid(uint64_t guid);
1150
// get the node by its guid
1151
IBPort *getPortByGuid(uint64_t guid);
1152
// get the port by its guid
1154
void addCable (string t1, string n1, string p1,
1155
string t2, string n2, string p2,
1156
IBLinkWidth width = DefaultLinkWidth,
1157
IBLinkSpeed speed = DefaultLinkSpeed
1160
// Add a cable connection
1162
int parseCables (string fn);
1163
// Parse the cables file and build the fabric
1165
int parseTopology (string fn);
1166
// Parse Topology File
1168
int addLink(string type1, int numPorts1, uint64_t sysGuid1,
1169
uint64_t nodeGuid1, uint64_t portGuid1,
1170
int vend1, int devId1, int rev1, string desc1,
1171
int hcaIdx1, int lid1, int portNum1,
1172
string type2, int numPorts2, uint64_t sysGuid2,
1173
uint64_t nodeGuid2, uint64_t portGuid2,
1174
int vend2, int devId2, int rev2, string desc2,
1175
int hcaIdx2, int lid2, int portNum2,
1176
IBLinkWidth width = DefaultLinkWidth,
1177
IBLinkSpeed speed = DefaultLinkSpeed);
1178
// Add a link into the fabric - this will create system
1179
// and nodes as required.
1181
int parseSubnetLinks (string fn);
1182
// Parse the OpenSM subnet.lst file and build the fabric from it.
1184
int parseFdbFile(string fn);
1185
// Parse OpenSM FDB dump file
1187
int parseMCFdbFile(string fn);
1188
// Parse an OpenSM MCFDBs file and set the MFT table accordingly
1190
inline void setLidPort (unsigned int lid, IBPort *p_port);
1193
inline IBPort *getPortByLid (unsigned int lid);
1194
// get a port by lid
1196
int dumpTopology(char *fileName, char *ibnlDir);
1197
// write out a topology file and IBNLs into given directory
1200
/* we use our own version of the constructor */
1201
IBFabric* new_IBFabric();
1202
/* we use our own version of the destructor */
1203
void delete_IBFabric(IBFabric *p_fabric);
1205
%section "IBDM Functions",pre
1206
/* IBDM functions */
1208
This section provide the details about the functions IBDM exposes.
1209
The order follows the expected order in a regular IBDM flow.
1210
They all return 0 on succes.
1213
%subsection "Subnet Utilities",before,pre
1218
The file holds a set of utilities to be run on the subnet to mimic OpenSM
1219
initialization and analyze the results:
1221
Assign Lids: SubnMgtAssignLids
1222
Init min hop tables: SubnMgtCalcMinHopTables
1223
Perform Enhanced LMC aware routing: SubnMgtOsmEnhancedRoute
1224
Perform standard routing: SubnMgtOsmRoute
1225
Perform Fat Tree specialized routing: SubnMgtFatTreeRoute
1226
Verify all CA to CA routes: SubnMgtVerifyAllCaToCaRoutes
1230
%name(ibdmAssignLids)
1231
int SubnMgtAssignLids (IBPort *p_smNodePort, unsigned int lmc = 0);
1234
%name(ibdmCalcMinHopTables)
1235
int SubnMgtCalcMinHopTables (IBFabric *p_fabric);
1236
// Calculate the minhop table for the switches
1238
%name(ibdmCalcUpDnMinHopTbls)
1239
int SubnMgtCalcUpDnMinHopTblsByRootNodesRex(IBFabric *p_fabric, char *rootNodesNameRex);
1240
// Fill in the FDB tables in a Up Down routing.
1241
// Start the tree from the given nodes by regular expression
1243
%name (ibdmOsmRoute)
1244
int SubnMgtOsmRoute(IBFabric *p_fabric);
1245
// Fill in the FDB tables in an OpesnSM style routing
1246
// which is switch based, uses number of routes per port
1247
// profiling and treat LMC assigned lids sequentialy
1248
// Rely on running the SubnMgtCalcMinHopTables beforehand
1250
%name(ibdmEnhancedRoute)
1251
int SubnMgtOsmEnhancedRoute(IBFabric *p_fabric);
1252
// Fill in the FDB tables in an OpesnSM style routing
1253
// which is switch based, uses number of routes per port
1254
// profiling and treat LMC assigned lids sequentialy.
1255
// Also it will favor runing through a new system or node
1256
// on top of the port profile.
1257
// Rely on running the SubnMgtCalcMinHopTables beforehand
1259
int ibdmFatTreeRoute(IBFabric *p_fabric, list_pnode rootNodes);
1260
// Perform Fat Tree specific routing by assigning a single LID to
1261
// each root node port a single LID to route through.
1263
%name(ibdmFatTreeAnalysis) int FatTreeAnalysis(IBFabric *p_fabric);
1264
// Performs FatTree structural analysis
1266
%name(ibdmFatTreeRouteByPermutation) int FatTreeRouteByPermutation(IBFabric *p_fabric, char* srcs, char* dsts);
1267
// Performs optimal permutation routing in FatTree
1269
%name(ibdmVerifyCAtoCARoutes)
1270
int SubnMgtVerifyAllCaToCaRoutes(IBFabric *p_fabric);
1271
// Verify point to point connectivity
1273
%name(ibdmVerifyAllPaths)
1274
int SubnMgtVerifyAllRoutes(IBFabric *p_fabric);
1277
%name(ibdmAnalyzeLoops)
1278
int CrdLoopAnalyze(IBFabric *p_fabric);
1279
// Analyze the Fabric for Credit Loops
1281
%name(ibdmFindSymmetricalTreeRoots)
1282
list_pnode SubnMgtFindTreeRootNodes(IBFabric *p_fabric);
1283
// Analyze the fabric to find its root nodes assuming it is
1284
// a pure tree (keeping all levels in place).
1286
%name(ibdmFindRootNodesByMinHop)
1287
list_pnode SubnMgtFindRootNodesByMinHop(IBFabric *p_fabric);
1288
// Analyze the fabric to find its root nodes using statistical methods
1289
// on the profiles of min hops to CAs
1291
int ibdmRankFabricByRoots(IBFabric *p_fabric, list_pnode rootNodes);
1292
// Just rank the fabric according to the given nodes list
1294
int ibdmReportNonUpDownCa2CaPaths(IBFabric *p_fabric, list_pnode rootNodes);
1295
// Find any routes that exist in the FDB's from CA to CA and do not adhare to
1296
// the up/down rules. Report any crossing of the path. Use the given list fo nodes
1297
// as roots of the tree.
1299
%name(ibdmCheckMulticastGroups)
1300
int SubnMgtCheckFabricMCGrps(IBFabric *p_fabric);
1301
// Check all multicast groups :
1302
// 1. all switches holding it are connected
1303
// 2. No loops (i.e. a single BFS with no returns).
1305
int ibdmCheckFabricMCGrpsForCreditLoopPotential(
1306
IBFabric *p_fabric, list_pnode rootNodes);
1307
// Check all multicast groups do not have credit loop potential
1309
%name(ibdmLinkCoverageAnalysis)
1310
int LinkCoverageAnalysis(IBFabric *p_fabric, list_pnode rootNodes);
1311
// Provide sets of port pairs to run BW check from in a way that is
1312
// full bandwidth. Reide in LinkCover.cpp
1314
%subsection "Tracing Utilities",before,pre
1316
%name(ibdmTraceDRPathRoute)
1317
int TraceDRPathRoute (IBPort *p_smNodePort, list_int drPathPortNums);
1318
// Trace a direct route from the given SM node port
1320
%name(ibdmTraceRouteByMinHops)
1321
int TraceRouteByMinHops (IBFabric *p_fabric,
1322
unsigned int slid , unsigned int dlid);
1323
// Trace a route from slid to dlid by Min Hop
1325
%typemap(tcl8,in) list_pnode_arg_name*(list_pnode tmp) {
1329
%typemap(tcl8,argout) list_pnode_arg_name* {
1330
// build a TCL list out of the Objec ID's of the ibdm objects in it.
1331
list_pnode::const_iterator I = $source->begin();
1333
Tcl_SetVar(interp, Tcl_GetString($arg),"",0);
1334
while (I != $source->end()) {
1335
p_tclObj = Tcl_NewObj();
1336
if (ibdmGetObjTclNameByPtr(p_tclObj, (*I), "IBNode *") != TCL_OK) {
1337
printf("-E- Fail to map Node Object (a guid map element)\n");
1340
sprintf(buf, "%s", Tcl_GetString(p_tclObj));
1341
Tcl_SetVar(interp, Tcl_GetString($arg), buf,
1342
TCL_LIST_ELEMENT|TCL_APPEND_VALUE);
1344
Tcl_DecrRefCount(p_tclObj);
1349
#define list_pnode_arg_name list_pnode
1352
%typemap(tcl8,in) unsigned_int_arg_name*(unsigned int tmp) {
1356
%typemap(tcl8,argout) unsigned_int_arg_name* {
1358
sprintf(buf, "%u", tmp);
1359
Tcl_SetVar(interp, Tcl_GetString($arg), buf, 0);
1362
#define unsigned_int_arg_name unsigned int
1365
%name(ibdmTraceRouteByLFT)
1366
int TraceRouteByLFT (IBFabric *p_fabric,
1367
unsigned int slid , unsigned int dlid,
1368
unsigned_int_arg_name *hops,
1369
list_pnode_arg_name *p_nodesList);
1370
// Trace a route from slid to dlid by LFT
1372
%subsection "Topology Matching Utilities",before,pre
1374
%apply char **p_out_str {char **p_report_str};
1376
%name(ibdmMatchFabrics)
1377
int TopoMatchFabrics(
1378
IBFabric *p_spec_fabric, // The specification fabric
1379
IBFabric *p_discovered_fabric, // The discovered fabric
1380
char *anchorNodeName, // The system to be the anchor point
1381
int anchorPortNum, // The port number of the anchor port
1382
uint64_t anchorPortGuid, // Discovered Guid of the anchor port
1383
char **p_report_str // Diagnostic output.
1385
// Error if fabrics deffer. And provide it as result.
1387
%name(ibdmBuildMergedFabric)
1389
TopoMergeDiscAndSpecFabrics(
1390
IBFabric *p_spec_fabric, // The specification fabric
1391
IBFabric *p_discovered_fabric, // The discovered fabric
1392
IBFabric *p_merged_fabric); // Output merged fabric (allocated internaly)
1393
// Build a merged fabric from a matched discovered and spec fabrics.
1394
// NOTE: you have to run ibdmMatchFabrics before calling this routine.
1396
%subsection "Congestion Analysis Utilities",before,pre
1398
%name(ibdmCongInit) int CongInit(IBFabric *p_fabric);
1399
// Initialize a fabric for congestion analysis
1401
%name(ibdmCongCleanup) int CongCleanup(IBFabric *p_fabric);
1402
// Cleanup congestion analysis data and free memory
1404
%name(ibdmCongClear) int CongZero(IBFabric *p_fabric);
1405
// Clear the congestion analysis path trace. Does not affect max paths
1407
%name(ibdmCongTrace)
1408
int CongTrackPath(IBFabric *p_fabric, uint16_t srcLid, uint16_t dstLid);
1409
// Trace the path from source to destination tracking the visited links
1411
%name(ibdmCongReport) int CongReport(IBFabric *p_fabric, ostringstream &out);
1412
// Report the max path count and histogram
1414
%name(ibdmCongDump) int CongDump(IBFabric *p_fabric, ostringstream &out);
1415
// provide detailed dump of the link usage
1418
// FIX OF SWIG TO SUPPORT NAME ALTERNATE MANGLING
1421
#include "swig_alternate_mangling.cpp"
1424
///////////////////////////////////////////////////////////////////////////////
1425
extern char * ibdmSourceVersion;
1432
/* mixing declarations .... */
1434
// Register the objects for alternate mangling
1435
SWIG_AlternateObjMangling["_IBFabric_p"] = &ibdmGetObjTclNameByPtr;
1436
SWIG_AlternateNameToObj ["_IBFabric_p"] = &ibdmGetObjPtrByTclName;
1438
SWIG_AlternateObjMangling["_IBSystem_p"] = &ibdmGetObjTclNameByPtr;
1439
SWIG_AlternateNameToObj ["_IBSystem_p"] = &ibdmGetObjPtrByTclName;
1441
SWIG_AlternateObjMangling["_IBSysPort_p"] = &ibdmGetObjTclNameByPtr;
1442
SWIG_AlternateNameToObj ["_IBSysPort_p"] = &ibdmGetObjPtrByTclName;
1444
SWIG_AlternateObjMangling["_IBNode_p"] = &ibdmGetObjTclNameByPtr;
1445
SWIG_AlternateNameToObj ["_IBNode_p"] = &ibdmGetObjPtrByTclName;
1447
SWIG_AlternateObjMangling["_IBPort_p"] = &ibdmGetObjTclNameByPtr;
1448
SWIG_AlternateNameToObj ["_IBPort_p"] = &ibdmGetObjPtrByTclName;