1*d6b92ffaSHans Petter Selasky /*
2*d6b92ffaSHans Petter Selasky * Copyright (c) 2004-2009 Voltaire Inc. All rights reserved.
3*d6b92ffaSHans Petter Selasky * Copyright (c) 2007 Xsigo Systems Inc. All rights reserved.
4*d6b92ffaSHans Petter Selasky * Copyright (c) 2008 Lawrence Livermore National Lab. All rights reserved.
5*d6b92ffaSHans Petter Selasky * Copyright (c) 2010,2011 Mellanox Technologies LTD. All rights reserved.
6*d6b92ffaSHans Petter Selasky *
7*d6b92ffaSHans Petter Selasky * This software is available to you under a choice of one of two
8*d6b92ffaSHans Petter Selasky * licenses. You may choose to be licensed under the terms of the GNU
9*d6b92ffaSHans Petter Selasky * General Public License (GPL) Version 2, available from the file
10*d6b92ffaSHans Petter Selasky * COPYING in the main directory of this source tree, or the
11*d6b92ffaSHans Petter Selasky * OpenIB.org BSD license below:
12*d6b92ffaSHans Petter Selasky *
13*d6b92ffaSHans Petter Selasky * Redistribution and use in source and binary forms, with or
14*d6b92ffaSHans Petter Selasky * without modification, are permitted provided that the following
15*d6b92ffaSHans Petter Selasky * conditions are met:
16*d6b92ffaSHans Petter Selasky *
17*d6b92ffaSHans Petter Selasky * - Redistributions of source code must retain the above
18*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
19*d6b92ffaSHans Petter Selasky * disclaimer.
20*d6b92ffaSHans Petter Selasky *
21*d6b92ffaSHans Petter Selasky * - Redistributions in binary form must reproduce the above
22*d6b92ffaSHans Petter Selasky * copyright notice, this list of conditions and the following
23*d6b92ffaSHans Petter Selasky * disclaimer in the documentation and/or other materials
24*d6b92ffaSHans Petter Selasky * provided with the distribution.
25*d6b92ffaSHans Petter Selasky *
26*d6b92ffaSHans Petter Selasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27*d6b92ffaSHans Petter Selasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28*d6b92ffaSHans Petter Selasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29*d6b92ffaSHans Petter Selasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
30*d6b92ffaSHans Petter Selasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
31*d6b92ffaSHans Petter Selasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
32*d6b92ffaSHans Petter Selasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33*d6b92ffaSHans Petter Selasky * SOFTWARE.
34*d6b92ffaSHans Petter Selasky *
35*d6b92ffaSHans Petter Selasky */
36*d6b92ffaSHans Petter Selasky
37*d6b92ffaSHans Petter Selasky #if HAVE_CONFIG_H
38*d6b92ffaSHans Petter Selasky #include <config.h>
39*d6b92ffaSHans Petter Selasky #endif /* HAVE_CONFIG_H */
40*d6b92ffaSHans Petter Selasky
41*d6b92ffaSHans Petter Selasky #define _GNU_SOURCE
42*d6b92ffaSHans Petter Selasky #include <stdio.h>
43*d6b92ffaSHans Petter Selasky #include <stdlib.h>
44*d6b92ffaSHans Petter Selasky #include <unistd.h>
45*d6b92ffaSHans Petter Selasky #include <time.h>
46*d6b92ffaSHans Petter Selasky #include <string.h>
47*d6b92ffaSHans Petter Selasky #include <getopt.h>
48*d6b92ffaSHans Petter Selasky #include <inttypes.h>
49*d6b92ffaSHans Petter Selasky
50*d6b92ffaSHans Petter Selasky #include <infiniband/umad.h>
51*d6b92ffaSHans Petter Selasky #include <infiniband/mad.h>
52*d6b92ffaSHans Petter Selasky #include <complib/cl_nodenamemap.h>
53*d6b92ffaSHans Petter Selasky #include <infiniband/ibnetdisc.h>
54*d6b92ffaSHans Petter Selasky
55*d6b92ffaSHans Petter Selasky #include "ibdiag_common.h"
56*d6b92ffaSHans Petter Selasky
57*d6b92ffaSHans Petter Selasky #define LIST_CA_NODE (1 << IB_NODE_CA)
58*d6b92ffaSHans Petter Selasky #define LIST_SWITCH_NODE (1 << IB_NODE_SWITCH)
59*d6b92ffaSHans Petter Selasky #define LIST_ROUTER_NODE (1 << IB_NODE_ROUTER)
60*d6b92ffaSHans Petter Selasky
61*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_SWITCH 0x01
62*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_CA 0x02
63*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_ROUTER 0x04
64*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_PORT_CONNECTION 0x08
65*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_LID 0x10
66*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_NODE_DESCRIPTION 0x20
67*d6b92ffaSHans Petter Selasky
68*d6b92ffaSHans Petter Selasky #define DIFF_FLAG_DEFAULT (DIFF_FLAG_SWITCH | DIFF_FLAG_CA | DIFF_FLAG_ROUTER \
69*d6b92ffaSHans Petter Selasky | DIFF_FLAG_PORT_CONNECTION)
70*d6b92ffaSHans Petter Selasky
71*d6b92ffaSHans Petter Selasky static FILE *f;
72*d6b92ffaSHans Petter Selasky
73*d6b92ffaSHans Petter Selasky static char *node_name_map_file = NULL;
74*d6b92ffaSHans Petter Selasky static nn_map_t *node_name_map = NULL;
75*d6b92ffaSHans Petter Selasky static char *cache_file = NULL;
76*d6b92ffaSHans Petter Selasky static char *load_cache_file = NULL;
77*d6b92ffaSHans Petter Selasky static char *diff_cache_file = NULL;
78*d6b92ffaSHans Petter Selasky static unsigned diffcheck_flags = DIFF_FLAG_DEFAULT;
79*d6b92ffaSHans Petter Selasky
80*d6b92ffaSHans Petter Selasky static int report_max_hops = 0;
81*d6b92ffaSHans Petter Selasky static int full_info;
82*d6b92ffaSHans Petter Selasky
83*d6b92ffaSHans Petter Selasky /**
84*d6b92ffaSHans Petter Selasky * Define our own conversion functions to maintain compatibility with the old
85*d6b92ffaSHans Petter Selasky * ibnetdiscover which did not use the ibmad conversion functions.
86*d6b92ffaSHans Petter Selasky */
dump_linkspeed_compat(uint32_t speed)87*d6b92ffaSHans Petter Selasky char *dump_linkspeed_compat(uint32_t speed)
88*d6b92ffaSHans Petter Selasky {
89*d6b92ffaSHans Petter Selasky switch (speed) {
90*d6b92ffaSHans Petter Selasky case 1:
91*d6b92ffaSHans Petter Selasky return ("SDR");
92*d6b92ffaSHans Petter Selasky break;
93*d6b92ffaSHans Petter Selasky case 2:
94*d6b92ffaSHans Petter Selasky return ("DDR");
95*d6b92ffaSHans Petter Selasky break;
96*d6b92ffaSHans Petter Selasky case 4:
97*d6b92ffaSHans Petter Selasky return ("QDR");
98*d6b92ffaSHans Petter Selasky break;
99*d6b92ffaSHans Petter Selasky }
100*d6b92ffaSHans Petter Selasky return ("???");
101*d6b92ffaSHans Petter Selasky }
102*d6b92ffaSHans Petter Selasky
dump_linkspeedext_compat(uint32_t espeed,uint32_t speed,uint32_t fdr10)103*d6b92ffaSHans Petter Selasky char *dump_linkspeedext_compat(uint32_t espeed, uint32_t speed, uint32_t fdr10)
104*d6b92ffaSHans Petter Selasky {
105*d6b92ffaSHans Petter Selasky switch (espeed) {
106*d6b92ffaSHans Petter Selasky case 0:
107*d6b92ffaSHans Petter Selasky if (fdr10 & FDR10)
108*d6b92ffaSHans Petter Selasky return ("FDR10");
109*d6b92ffaSHans Petter Selasky else
110*d6b92ffaSHans Petter Selasky return dump_linkspeed_compat(speed);
111*d6b92ffaSHans Petter Selasky break;
112*d6b92ffaSHans Petter Selasky case 1:
113*d6b92ffaSHans Petter Selasky return ("FDR");
114*d6b92ffaSHans Petter Selasky break;
115*d6b92ffaSHans Petter Selasky case 2:
116*d6b92ffaSHans Petter Selasky return ("EDR");
117*d6b92ffaSHans Petter Selasky break;
118*d6b92ffaSHans Petter Selasky }
119*d6b92ffaSHans Petter Selasky return ("???");
120*d6b92ffaSHans Petter Selasky }
121*d6b92ffaSHans Petter Selasky
dump_linkwidth_compat(uint32_t width)122*d6b92ffaSHans Petter Selasky char *dump_linkwidth_compat(uint32_t width)
123*d6b92ffaSHans Petter Selasky {
124*d6b92ffaSHans Petter Selasky switch (width) {
125*d6b92ffaSHans Petter Selasky case 1:
126*d6b92ffaSHans Petter Selasky return ("1x");
127*d6b92ffaSHans Petter Selasky break;
128*d6b92ffaSHans Petter Selasky case 2:
129*d6b92ffaSHans Petter Selasky return ("4x");
130*d6b92ffaSHans Petter Selasky break;
131*d6b92ffaSHans Petter Selasky case 4:
132*d6b92ffaSHans Petter Selasky return ("8x");
133*d6b92ffaSHans Petter Selasky break;
134*d6b92ffaSHans Petter Selasky case 8:
135*d6b92ffaSHans Petter Selasky return ("12x");
136*d6b92ffaSHans Petter Selasky break;
137*d6b92ffaSHans Petter Selasky case 16:
138*d6b92ffaSHans Petter Selasky return ("2x");
139*d6b92ffaSHans Petter Selasky break;
140*d6b92ffaSHans Petter Selasky }
141*d6b92ffaSHans Petter Selasky return ("??");
142*d6b92ffaSHans Petter Selasky }
143*d6b92ffaSHans Petter Selasky
ports_nt_str_compat(ibnd_node_t * node)144*d6b92ffaSHans Petter Selasky static inline const char *ports_nt_str_compat(ibnd_node_t * node)
145*d6b92ffaSHans Petter Selasky {
146*d6b92ffaSHans Petter Selasky switch (node->type) {
147*d6b92ffaSHans Petter Selasky case IB_NODE_SWITCH:
148*d6b92ffaSHans Petter Selasky return "SW";
149*d6b92ffaSHans Petter Selasky case IB_NODE_CA:
150*d6b92ffaSHans Petter Selasky return "CA";
151*d6b92ffaSHans Petter Selasky case IB_NODE_ROUTER:
152*d6b92ffaSHans Petter Selasky return "RT";
153*d6b92ffaSHans Petter Selasky }
154*d6b92ffaSHans Petter Selasky return "??";
155*d6b92ffaSHans Petter Selasky }
156*d6b92ffaSHans Petter Selasky
node_name(ibnd_node_t * node)157*d6b92ffaSHans Petter Selasky char *node_name(ibnd_node_t * node)
158*d6b92ffaSHans Petter Selasky {
159*d6b92ffaSHans Petter Selasky static char buf[256];
160*d6b92ffaSHans Petter Selasky
161*d6b92ffaSHans Petter Selasky switch (node->type) {
162*d6b92ffaSHans Petter Selasky case IB_NODE_SWITCH:
163*d6b92ffaSHans Petter Selasky sprintf(buf, "\"%s", "S");
164*d6b92ffaSHans Petter Selasky break;
165*d6b92ffaSHans Petter Selasky case IB_NODE_CA:
166*d6b92ffaSHans Petter Selasky sprintf(buf, "\"%s", "H");
167*d6b92ffaSHans Petter Selasky break;
168*d6b92ffaSHans Petter Selasky case IB_NODE_ROUTER:
169*d6b92ffaSHans Petter Selasky sprintf(buf, "\"%s", "R");
170*d6b92ffaSHans Petter Selasky break;
171*d6b92ffaSHans Petter Selasky default:
172*d6b92ffaSHans Petter Selasky sprintf(buf, "\"%s", "?");
173*d6b92ffaSHans Petter Selasky break;
174*d6b92ffaSHans Petter Selasky }
175*d6b92ffaSHans Petter Selasky sprintf(buf + 2, "-%016" PRIx64 "\"", node->guid);
176*d6b92ffaSHans Petter Selasky
177*d6b92ffaSHans Petter Selasky return buf;
178*d6b92ffaSHans Petter Selasky }
179*d6b92ffaSHans Petter Selasky
list_node(ibnd_node_t * node,void * user_data)180*d6b92ffaSHans Petter Selasky void list_node(ibnd_node_t * node, void *user_data)
181*d6b92ffaSHans Petter Selasky {
182*d6b92ffaSHans Petter Selasky char *node_type;
183*d6b92ffaSHans Petter Selasky char *nodename = remap_node_name(node_name_map, node->guid,
184*d6b92ffaSHans Petter Selasky node->nodedesc);
185*d6b92ffaSHans Petter Selasky
186*d6b92ffaSHans Petter Selasky switch (node->type) {
187*d6b92ffaSHans Petter Selasky case IB_NODE_SWITCH:
188*d6b92ffaSHans Petter Selasky node_type = "Switch";
189*d6b92ffaSHans Petter Selasky break;
190*d6b92ffaSHans Petter Selasky case IB_NODE_CA:
191*d6b92ffaSHans Petter Selasky node_type = "Ca";
192*d6b92ffaSHans Petter Selasky break;
193*d6b92ffaSHans Petter Selasky case IB_NODE_ROUTER:
194*d6b92ffaSHans Petter Selasky node_type = "Router";
195*d6b92ffaSHans Petter Selasky break;
196*d6b92ffaSHans Petter Selasky default:
197*d6b92ffaSHans Petter Selasky node_type = "???";
198*d6b92ffaSHans Petter Selasky break;
199*d6b92ffaSHans Petter Selasky }
200*d6b92ffaSHans Petter Selasky fprintf(f,
201*d6b92ffaSHans Petter Selasky "%s\t : 0x%016" PRIx64
202*d6b92ffaSHans Petter Selasky " ports %d devid 0x%x vendid 0x%x \"%s\"\n", node_type,
203*d6b92ffaSHans Petter Selasky node->guid, node->numports, mad_get_field(node->info, 0,
204*d6b92ffaSHans Petter Selasky IB_NODE_DEVID_F),
205*d6b92ffaSHans Petter Selasky mad_get_field(node->info, 0, IB_NODE_VENDORID_F), nodename);
206*d6b92ffaSHans Petter Selasky
207*d6b92ffaSHans Petter Selasky free(nodename);
208*d6b92ffaSHans Petter Selasky }
209*d6b92ffaSHans Petter Selasky
list_nodes(ibnd_fabric_t * fabric,int list)210*d6b92ffaSHans Petter Selasky void list_nodes(ibnd_fabric_t * fabric, int list)
211*d6b92ffaSHans Petter Selasky {
212*d6b92ffaSHans Petter Selasky if (list & LIST_CA_NODE)
213*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, list_node, IB_NODE_CA, NULL);
214*d6b92ffaSHans Petter Selasky if (list & LIST_SWITCH_NODE)
215*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, list_node, IB_NODE_SWITCH, NULL);
216*d6b92ffaSHans Petter Selasky if (list & LIST_ROUTER_NODE)
217*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, list_node, IB_NODE_ROUTER, NULL);
218*d6b92ffaSHans Petter Selasky }
219*d6b92ffaSHans Petter Selasky
out_ids(ibnd_node_t * node,int group,char * chname,char * out_prefix)220*d6b92ffaSHans Petter Selasky void out_ids(ibnd_node_t * node, int group, char *chname, char *out_prefix)
221*d6b92ffaSHans Petter Selasky {
222*d6b92ffaSHans Petter Selasky uint64_t sysimgguid =
223*d6b92ffaSHans Petter Selasky mad_get_field64(node->info, 0, IB_NODE_SYSTEM_GUID_F);
224*d6b92ffaSHans Petter Selasky
225*d6b92ffaSHans Petter Selasky fprintf(f, "\n%svendid=0x%x\n", out_prefix ? out_prefix : "",
226*d6b92ffaSHans Petter Selasky mad_get_field(node->info, 0, IB_NODE_VENDORID_F));
227*d6b92ffaSHans Petter Selasky fprintf(f, "%sdevid=0x%x\n", out_prefix ? out_prefix : "",
228*d6b92ffaSHans Petter Selasky mad_get_field(node->info, 0, IB_NODE_DEVID_F));
229*d6b92ffaSHans Petter Selasky if (sysimgguid)
230*d6b92ffaSHans Petter Selasky fprintf(f, "%ssysimgguid=0x%" PRIx64,
231*d6b92ffaSHans Petter Selasky out_prefix ? out_prefix : "", sysimgguid);
232*d6b92ffaSHans Petter Selasky if (group && node->chassis && node->chassis->chassisnum) {
233*d6b92ffaSHans Petter Selasky fprintf(f, "\t\t# Chassis %d", node->chassis->chassisnum);
234*d6b92ffaSHans Petter Selasky if (chname)
235*d6b92ffaSHans Petter Selasky fprintf(f, " (%s)", clean_nodedesc(chname));
236*d6b92ffaSHans Petter Selasky if (ibnd_is_xsigo_tca(node->guid) && node->ports[1] &&
237*d6b92ffaSHans Petter Selasky node->ports[1]->remoteport)
238*d6b92ffaSHans Petter Selasky fprintf(f, " slot %d",
239*d6b92ffaSHans Petter Selasky node->ports[1]->remoteport->portnum);
240*d6b92ffaSHans Petter Selasky }
241*d6b92ffaSHans Petter Selasky if (sysimgguid ||
242*d6b92ffaSHans Petter Selasky (group && node->chassis && node->chassis->chassisnum))
243*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
244*d6b92ffaSHans Petter Selasky }
245*d6b92ffaSHans Petter Selasky
out_chassis(ibnd_fabric_t * fabric,unsigned char chassisnum)246*d6b92ffaSHans Petter Selasky uint64_t out_chassis(ibnd_fabric_t * fabric, unsigned char chassisnum)
247*d6b92ffaSHans Petter Selasky {
248*d6b92ffaSHans Petter Selasky uint64_t guid;
249*d6b92ffaSHans Petter Selasky
250*d6b92ffaSHans Petter Selasky fprintf(f, "\nChassis %u", chassisnum);
251*d6b92ffaSHans Petter Selasky guid = ibnd_get_chassis_guid(fabric, chassisnum);
252*d6b92ffaSHans Petter Selasky if (guid)
253*d6b92ffaSHans Petter Selasky fprintf(f, " (guid 0x%" PRIx64 ")", guid);
254*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
255*d6b92ffaSHans Petter Selasky return guid;
256*d6b92ffaSHans Petter Selasky }
257*d6b92ffaSHans Petter Selasky
out_switch_detail(ibnd_node_t * node,char * sw_prefix)258*d6b92ffaSHans Petter Selasky void out_switch_detail(ibnd_node_t * node, char *sw_prefix)
259*d6b92ffaSHans Petter Selasky {
260*d6b92ffaSHans Petter Selasky char *nodename = NULL;
261*d6b92ffaSHans Petter Selasky
262*d6b92ffaSHans Petter Selasky nodename = remap_node_name(node_name_map, node->guid, node->nodedesc);
263*d6b92ffaSHans Petter Selasky
264*d6b92ffaSHans Petter Selasky fprintf(f, "%sSwitch\t%d %s\t\t# \"%s\" %s port 0 lid %d lmc %d",
265*d6b92ffaSHans Petter Selasky sw_prefix ? sw_prefix : "", node->numports, node_name(node),
266*d6b92ffaSHans Petter Selasky nodename, node->smaenhsp0 ? "enhanced" : "base",
267*d6b92ffaSHans Petter Selasky node->smalid, node->smalmc);
268*d6b92ffaSHans Petter Selasky
269*d6b92ffaSHans Petter Selasky free(nodename);
270*d6b92ffaSHans Petter Selasky }
271*d6b92ffaSHans Petter Selasky
out_switch(ibnd_node_t * node,int group,char * chname,char * id_prefix,char * sw_prefix)272*d6b92ffaSHans Petter Selasky void out_switch(ibnd_node_t * node, int group, char *chname, char *id_prefix,
273*d6b92ffaSHans Petter Selasky char *sw_prefix)
274*d6b92ffaSHans Petter Selasky {
275*d6b92ffaSHans Petter Selasky char *str;
276*d6b92ffaSHans Petter Selasky char str2[256];
277*d6b92ffaSHans Petter Selasky
278*d6b92ffaSHans Petter Selasky out_ids(node, group, chname, id_prefix);
279*d6b92ffaSHans Petter Selasky fprintf(f, "%sswitchguid=0x%" PRIx64,
280*d6b92ffaSHans Petter Selasky id_prefix ? id_prefix : "", node->guid);
281*d6b92ffaSHans Petter Selasky fprintf(f, "(%" PRIx64 ")",
282*d6b92ffaSHans Petter Selasky mad_get_field64(node->info, 0, IB_NODE_PORT_GUID_F));
283*d6b92ffaSHans Petter Selasky if (group) {
284*d6b92ffaSHans Petter Selasky fprintf(f, "\t# ");
285*d6b92ffaSHans Petter Selasky str = ibnd_get_chassis_type(node);
286*d6b92ffaSHans Petter Selasky if (str)
287*d6b92ffaSHans Petter Selasky fprintf(f, "%s ", str);
288*d6b92ffaSHans Petter Selasky str = ibnd_get_chassis_slot_str(node, str2, 256);
289*d6b92ffaSHans Petter Selasky if (str)
290*d6b92ffaSHans Petter Selasky fprintf(f, "%s", str);
291*d6b92ffaSHans Petter Selasky }
292*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
293*d6b92ffaSHans Petter Selasky
294*d6b92ffaSHans Petter Selasky out_switch_detail(node, sw_prefix);
295*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
296*d6b92ffaSHans Petter Selasky }
297*d6b92ffaSHans Petter Selasky
out_ca_detail(ibnd_node_t * node,char * ca_prefix)298*d6b92ffaSHans Petter Selasky void out_ca_detail(ibnd_node_t * node, char *ca_prefix)
299*d6b92ffaSHans Petter Selasky {
300*d6b92ffaSHans Petter Selasky char *node_type;
301*d6b92ffaSHans Petter Selasky
302*d6b92ffaSHans Petter Selasky switch (node->type) {
303*d6b92ffaSHans Petter Selasky case IB_NODE_CA:
304*d6b92ffaSHans Petter Selasky node_type = "Ca";
305*d6b92ffaSHans Petter Selasky break;
306*d6b92ffaSHans Petter Selasky case IB_NODE_ROUTER:
307*d6b92ffaSHans Petter Selasky node_type = "Rt";
308*d6b92ffaSHans Petter Selasky break;
309*d6b92ffaSHans Petter Selasky default:
310*d6b92ffaSHans Petter Selasky node_type = "???";
311*d6b92ffaSHans Petter Selasky break;
312*d6b92ffaSHans Petter Selasky }
313*d6b92ffaSHans Petter Selasky
314*d6b92ffaSHans Petter Selasky fprintf(f, "%s%s\t%d %s\t\t# \"%s\"", ca_prefix ? ca_prefix : "",
315*d6b92ffaSHans Petter Selasky node_type, node->numports, node_name(node),
316*d6b92ffaSHans Petter Selasky clean_nodedesc(node->nodedesc));
317*d6b92ffaSHans Petter Selasky }
318*d6b92ffaSHans Petter Selasky
out_ca(ibnd_node_t * node,int group,char * chname,char * id_prefix,char * ca_prefix)319*d6b92ffaSHans Petter Selasky void out_ca(ibnd_node_t * node, int group, char *chname, char *id_prefix,
320*d6b92ffaSHans Petter Selasky char *ca_prefix)
321*d6b92ffaSHans Petter Selasky {
322*d6b92ffaSHans Petter Selasky char *node_type;
323*d6b92ffaSHans Petter Selasky
324*d6b92ffaSHans Petter Selasky out_ids(node, group, chname, id_prefix);
325*d6b92ffaSHans Petter Selasky switch (node->type) {
326*d6b92ffaSHans Petter Selasky case IB_NODE_CA:
327*d6b92ffaSHans Petter Selasky node_type = "ca";
328*d6b92ffaSHans Petter Selasky break;
329*d6b92ffaSHans Petter Selasky case IB_NODE_ROUTER:
330*d6b92ffaSHans Petter Selasky node_type = "rt";
331*d6b92ffaSHans Petter Selasky break;
332*d6b92ffaSHans Petter Selasky default:
333*d6b92ffaSHans Petter Selasky node_type = "???";
334*d6b92ffaSHans Petter Selasky break;
335*d6b92ffaSHans Petter Selasky }
336*d6b92ffaSHans Petter Selasky
337*d6b92ffaSHans Petter Selasky fprintf(f, "%s%sguid=0x%" PRIx64 "\n",
338*d6b92ffaSHans Petter Selasky id_prefix ? id_prefix : "", node_type, node->guid);
339*d6b92ffaSHans Petter Selasky out_ca_detail(node, ca_prefix);
340*d6b92ffaSHans Petter Selasky if (group && ibnd_is_xsigo_hca(node->guid))
341*d6b92ffaSHans Petter Selasky fprintf(f, " (scp)");
342*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
343*d6b92ffaSHans Petter Selasky }
344*d6b92ffaSHans Petter Selasky
345*d6b92ffaSHans Petter Selasky #define OUT_BUFFER_SIZE 16
out_ext_port(ibnd_port_t * port,int group)346*d6b92ffaSHans Petter Selasky static char *out_ext_port(ibnd_port_t * port, int group)
347*d6b92ffaSHans Petter Selasky {
348*d6b92ffaSHans Petter Selasky static char mapping[OUT_BUFFER_SIZE];
349*d6b92ffaSHans Petter Selasky
350*d6b92ffaSHans Petter Selasky if (group && port->ext_portnum != 0) {
351*d6b92ffaSHans Petter Selasky snprintf(mapping, OUT_BUFFER_SIZE,
352*d6b92ffaSHans Petter Selasky "[ext %d]", port->ext_portnum);
353*d6b92ffaSHans Petter Selasky return (mapping);
354*d6b92ffaSHans Petter Selasky }
355*d6b92ffaSHans Petter Selasky
356*d6b92ffaSHans Petter Selasky return (NULL);
357*d6b92ffaSHans Petter Selasky }
358*d6b92ffaSHans Petter Selasky
out_switch_port(ibnd_port_t * port,int group,char * out_prefix)359*d6b92ffaSHans Petter Selasky void out_switch_port(ibnd_port_t * port, int group, char *out_prefix)
360*d6b92ffaSHans Petter Selasky {
361*d6b92ffaSHans Petter Selasky char *ext_port_str = NULL;
362*d6b92ffaSHans Petter Selasky char *rem_nodename = NULL;
363*d6b92ffaSHans Petter Selasky uint32_t iwidth = mad_get_field(port->info, 0,
364*d6b92ffaSHans Petter Selasky IB_PORT_LINK_WIDTH_ACTIVE_F);
365*d6b92ffaSHans Petter Selasky uint32_t ispeed = mad_get_field(port->info, 0,
366*d6b92ffaSHans Petter Selasky IB_PORT_LINK_SPEED_ACTIVE_F);
367*d6b92ffaSHans Petter Selasky uint32_t vlcap = mad_get_field(port->info, 0,
368*d6b92ffaSHans Petter Selasky IB_PORT_VL_CAP_F);
369*d6b92ffaSHans Petter Selasky uint32_t fdr10 = mad_get_field(port->ext_info, 0,
370*d6b92ffaSHans Petter Selasky IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
371*d6b92ffaSHans Petter Selasky uint32_t cap_mask, espeed;
372*d6b92ffaSHans Petter Selasky
373*d6b92ffaSHans Petter Selasky DEBUG("port %p:%d remoteport %p\n", port, port->portnum,
374*d6b92ffaSHans Petter Selasky port->remoteport);
375*d6b92ffaSHans Petter Selasky fprintf(f, "%s[%d]", out_prefix ? out_prefix : "", port->portnum);
376*d6b92ffaSHans Petter Selasky
377*d6b92ffaSHans Petter Selasky ext_port_str = out_ext_port(port, group);
378*d6b92ffaSHans Petter Selasky if (ext_port_str)
379*d6b92ffaSHans Petter Selasky fprintf(f, "%s", ext_port_str);
380*d6b92ffaSHans Petter Selasky
381*d6b92ffaSHans Petter Selasky rem_nodename = remap_node_name(node_name_map,
382*d6b92ffaSHans Petter Selasky port->remoteport->node->guid,
383*d6b92ffaSHans Petter Selasky port->remoteport->node->nodedesc);
384*d6b92ffaSHans Petter Selasky
385*d6b92ffaSHans Petter Selasky ext_port_str = out_ext_port(port->remoteport, group);
386*d6b92ffaSHans Petter Selasky
387*d6b92ffaSHans Petter Selasky if (!port->node->ports[0]) {
388*d6b92ffaSHans Petter Selasky cap_mask = 0;
389*d6b92ffaSHans Petter Selasky ispeed = 0;
390*d6b92ffaSHans Petter Selasky espeed = 0;
391*d6b92ffaSHans Petter Selasky } else {
392*d6b92ffaSHans Petter Selasky cap_mask = mad_get_field(port->node->ports[0]->info, 0,
393*d6b92ffaSHans Petter Selasky IB_PORT_CAPMASK_F);
394*d6b92ffaSHans Petter Selasky if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS))
395*d6b92ffaSHans Petter Selasky espeed = mad_get_field(port->info, 0,
396*d6b92ffaSHans Petter Selasky IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
397*d6b92ffaSHans Petter Selasky else
398*d6b92ffaSHans Petter Selasky espeed = 0;
399*d6b92ffaSHans Petter Selasky }
400*d6b92ffaSHans Petter Selasky fprintf(f, "\t%s[%d]%s",
401*d6b92ffaSHans Petter Selasky node_name(port->remoteport->node), port->remoteport->portnum,
402*d6b92ffaSHans Petter Selasky ext_port_str ? ext_port_str : "");
403*d6b92ffaSHans Petter Selasky if (port->remoteport->node->type != IB_NODE_SWITCH)
404*d6b92ffaSHans Petter Selasky fprintf(f, "(%" PRIx64 ") ", port->remoteport->guid);
405*d6b92ffaSHans Petter Selasky fprintf(f, "\t\t# \"%s\" lid %d %s%s",
406*d6b92ffaSHans Petter Selasky rem_nodename,
407*d6b92ffaSHans Petter Selasky port->remoteport->node->type == IB_NODE_SWITCH ?
408*d6b92ffaSHans Petter Selasky port->remoteport->node->smalid :
409*d6b92ffaSHans Petter Selasky port->remoteport->base_lid,
410*d6b92ffaSHans Petter Selasky dump_linkwidth_compat(iwidth),
411*d6b92ffaSHans Petter Selasky (ispeed != 4 && !espeed) ?
412*d6b92ffaSHans Petter Selasky dump_linkspeed_compat(ispeed) :
413*d6b92ffaSHans Petter Selasky dump_linkspeedext_compat(espeed, ispeed, fdr10));
414*d6b92ffaSHans Petter Selasky
415*d6b92ffaSHans Petter Selasky if (full_info) {
416*d6b92ffaSHans Petter Selasky fprintf(f, " s=%d w=%d v=%d", ispeed, iwidth, vlcap);
417*d6b92ffaSHans Petter Selasky if (espeed)
418*d6b92ffaSHans Petter Selasky fprintf(f, " e=%d", espeed);
419*d6b92ffaSHans Petter Selasky }
420*d6b92ffaSHans Petter Selasky
421*d6b92ffaSHans Petter Selasky if (ibnd_is_xsigo_tca(port->remoteport->guid))
422*d6b92ffaSHans Petter Selasky fprintf(f, " slot %d", port->portnum);
423*d6b92ffaSHans Petter Selasky else if (ibnd_is_xsigo_hca(port->remoteport->guid))
424*d6b92ffaSHans Petter Selasky fprintf(f, " (scp)");
425*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
426*d6b92ffaSHans Petter Selasky
427*d6b92ffaSHans Petter Selasky free(rem_nodename);
428*d6b92ffaSHans Petter Selasky }
429*d6b92ffaSHans Petter Selasky
out_ca_port(ibnd_port_t * port,int group,char * out_prefix)430*d6b92ffaSHans Petter Selasky void out_ca_port(ibnd_port_t * port, int group, char *out_prefix)
431*d6b92ffaSHans Petter Selasky {
432*d6b92ffaSHans Petter Selasky char *str = NULL;
433*d6b92ffaSHans Petter Selasky char *rem_nodename = NULL;
434*d6b92ffaSHans Petter Selasky uint32_t iwidth = mad_get_field(port->info, 0,
435*d6b92ffaSHans Petter Selasky IB_PORT_LINK_WIDTH_ACTIVE_F);
436*d6b92ffaSHans Petter Selasky uint32_t ispeed = mad_get_field(port->info, 0,
437*d6b92ffaSHans Petter Selasky IB_PORT_LINK_SPEED_ACTIVE_F);
438*d6b92ffaSHans Petter Selasky uint32_t vlcap = mad_get_field(port->info, 0,
439*d6b92ffaSHans Petter Selasky IB_PORT_VL_CAP_F);
440*d6b92ffaSHans Petter Selasky uint32_t fdr10 = mad_get_field(port->ext_info, 0,
441*d6b92ffaSHans Petter Selasky IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
442*d6b92ffaSHans Petter Selasky uint32_t cap_mask, espeed;
443*d6b92ffaSHans Petter Selasky
444*d6b92ffaSHans Petter Selasky fprintf(f, "%s[%d]", out_prefix ? out_prefix : "", port->portnum);
445*d6b92ffaSHans Petter Selasky if (port->node->type != IB_NODE_SWITCH)
446*d6b92ffaSHans Petter Selasky fprintf(f, "(%" PRIx64 ") ", port->guid);
447*d6b92ffaSHans Petter Selasky fprintf(f, "\t%s[%d]",
448*d6b92ffaSHans Petter Selasky node_name(port->remoteport->node), port->remoteport->portnum);
449*d6b92ffaSHans Petter Selasky str = out_ext_port(port->remoteport, group);
450*d6b92ffaSHans Petter Selasky if (str)
451*d6b92ffaSHans Petter Selasky fprintf(f, "%s", str);
452*d6b92ffaSHans Petter Selasky if (port->remoteport->node->type != IB_NODE_SWITCH)
453*d6b92ffaSHans Petter Selasky fprintf(f, " (%" PRIx64 ") ", port->remoteport->guid);
454*d6b92ffaSHans Petter Selasky
455*d6b92ffaSHans Petter Selasky rem_nodename = remap_node_name(node_name_map,
456*d6b92ffaSHans Petter Selasky port->remoteport->node->guid,
457*d6b92ffaSHans Petter Selasky port->remoteport->node->nodedesc);
458*d6b92ffaSHans Petter Selasky
459*d6b92ffaSHans Petter Selasky cap_mask = mad_get_field(port->info, 0, IB_PORT_CAPMASK_F);
460*d6b92ffaSHans Petter Selasky if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS))
461*d6b92ffaSHans Petter Selasky espeed = mad_get_field(port->info, 0,
462*d6b92ffaSHans Petter Selasky IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
463*d6b92ffaSHans Petter Selasky else
464*d6b92ffaSHans Petter Selasky espeed = 0;
465*d6b92ffaSHans Petter Selasky
466*d6b92ffaSHans Petter Selasky fprintf(f, "\t\t# lid %d lmc %d \"%s\" lid %d %s%s",
467*d6b92ffaSHans Petter Selasky port->base_lid, port->lmc, rem_nodename,
468*d6b92ffaSHans Petter Selasky port->remoteport->node->type == IB_NODE_SWITCH ?
469*d6b92ffaSHans Petter Selasky port->remoteport->node->smalid :
470*d6b92ffaSHans Petter Selasky port->remoteport->base_lid,
471*d6b92ffaSHans Petter Selasky dump_linkwidth_compat(iwidth),
472*d6b92ffaSHans Petter Selasky (ispeed != 4 && !espeed) ?
473*d6b92ffaSHans Petter Selasky dump_linkspeed_compat(ispeed) :
474*d6b92ffaSHans Petter Selasky dump_linkspeedext_compat(espeed, ispeed, fdr10));
475*d6b92ffaSHans Petter Selasky
476*d6b92ffaSHans Petter Selasky if (full_info) {
477*d6b92ffaSHans Petter Selasky fprintf(f, " s=%d w=%d v=%d", ispeed, iwidth, vlcap);
478*d6b92ffaSHans Petter Selasky if (espeed)
479*d6b92ffaSHans Petter Selasky fprintf(f, " e=%d", espeed);
480*d6b92ffaSHans Petter Selasky }
481*d6b92ffaSHans Petter Selasky
482*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
483*d6b92ffaSHans Petter Selasky
484*d6b92ffaSHans Petter Selasky free(rem_nodename);
485*d6b92ffaSHans Petter Selasky }
486*d6b92ffaSHans Petter Selasky
487*d6b92ffaSHans Petter Selasky struct iter_user_data {
488*d6b92ffaSHans Petter Selasky int group;
489*d6b92ffaSHans Petter Selasky int skip_chassis_nodes;
490*d6b92ffaSHans Petter Selasky };
491*d6b92ffaSHans Petter Selasky
switch_iter_func(ibnd_node_t * node,void * iter_user_data)492*d6b92ffaSHans Petter Selasky static void switch_iter_func(ibnd_node_t * node, void *iter_user_data)
493*d6b92ffaSHans Petter Selasky {
494*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
495*d6b92ffaSHans Petter Selasky int p = 0;
496*d6b92ffaSHans Petter Selasky struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
497*d6b92ffaSHans Petter Selasky
498*d6b92ffaSHans Petter Selasky DEBUG("SWITCH: node %p\n", node);
499*d6b92ffaSHans Petter Selasky
500*d6b92ffaSHans Petter Selasky /* skip chassis based switches if flagged */
501*d6b92ffaSHans Petter Selasky if (data->skip_chassis_nodes && node->chassis
502*d6b92ffaSHans Petter Selasky && node->chassis->chassisnum)
503*d6b92ffaSHans Petter Selasky return;
504*d6b92ffaSHans Petter Selasky
505*d6b92ffaSHans Petter Selasky out_switch(node, data->group, NULL, NULL, NULL);
506*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
507*d6b92ffaSHans Petter Selasky port = node->ports[p];
508*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
509*d6b92ffaSHans Petter Selasky out_switch_port(port, data->group, NULL);
510*d6b92ffaSHans Petter Selasky }
511*d6b92ffaSHans Petter Selasky }
512*d6b92ffaSHans Petter Selasky
ca_iter_func(ibnd_node_t * node,void * iter_user_data)513*d6b92ffaSHans Petter Selasky static void ca_iter_func(ibnd_node_t * node, void *iter_user_data)
514*d6b92ffaSHans Petter Selasky {
515*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
516*d6b92ffaSHans Petter Selasky int p = 0;
517*d6b92ffaSHans Petter Selasky struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
518*d6b92ffaSHans Petter Selasky
519*d6b92ffaSHans Petter Selasky DEBUG("CA: node %p\n", node);
520*d6b92ffaSHans Petter Selasky /* Now, skip chassis based CAs */
521*d6b92ffaSHans Petter Selasky if (data->group && node->chassis && node->chassis->chassisnum)
522*d6b92ffaSHans Petter Selasky return;
523*d6b92ffaSHans Petter Selasky out_ca(node, data->group, NULL, NULL, NULL);
524*d6b92ffaSHans Petter Selasky
525*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
526*d6b92ffaSHans Petter Selasky port = node->ports[p];
527*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
528*d6b92ffaSHans Petter Selasky out_ca_port(port, data->group, NULL);
529*d6b92ffaSHans Petter Selasky }
530*d6b92ffaSHans Petter Selasky }
531*d6b92ffaSHans Petter Selasky
router_iter_func(ibnd_node_t * node,void * iter_user_data)532*d6b92ffaSHans Petter Selasky static void router_iter_func(ibnd_node_t * node, void *iter_user_data)
533*d6b92ffaSHans Petter Selasky {
534*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
535*d6b92ffaSHans Petter Selasky int p = 0;
536*d6b92ffaSHans Petter Selasky struct iter_user_data *data = (struct iter_user_data *)iter_user_data;
537*d6b92ffaSHans Petter Selasky
538*d6b92ffaSHans Petter Selasky DEBUG("RT: node %p\n", node);
539*d6b92ffaSHans Petter Selasky /* Now, skip chassis based RTs */
540*d6b92ffaSHans Petter Selasky if (data->group && node->chassis && node->chassis->chassisnum)
541*d6b92ffaSHans Petter Selasky return;
542*d6b92ffaSHans Petter Selasky out_ca(node, data->group, NULL, NULL, NULL);
543*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
544*d6b92ffaSHans Petter Selasky port = node->ports[p];
545*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
546*d6b92ffaSHans Petter Selasky out_ca_port(port, data->group, NULL);
547*d6b92ffaSHans Petter Selasky }
548*d6b92ffaSHans Petter Selasky }
549*d6b92ffaSHans Petter Selasky
dump_topology(int group,ibnd_fabric_t * fabric)550*d6b92ffaSHans Petter Selasky int dump_topology(int group, ibnd_fabric_t * fabric)
551*d6b92ffaSHans Petter Selasky {
552*d6b92ffaSHans Petter Selasky ibnd_node_t *node;
553*d6b92ffaSHans Petter Selasky ibnd_port_t *port;
554*d6b92ffaSHans Petter Selasky int i = 0, p = 0;
555*d6b92ffaSHans Petter Selasky time_t t = time(0);
556*d6b92ffaSHans Petter Selasky uint64_t chguid;
557*d6b92ffaSHans Petter Selasky char *chname = NULL;
558*d6b92ffaSHans Petter Selasky struct iter_user_data iter_user_data;
559*d6b92ffaSHans Petter Selasky
560*d6b92ffaSHans Petter Selasky fprintf(f, "#\n# Topology file: generated on %s#\n", ctime(&t));
561*d6b92ffaSHans Petter Selasky if (report_max_hops)
562*d6b92ffaSHans Petter Selasky fprintf(f, "# Reported max hops discovered: %u\n"
563*d6b92ffaSHans Petter Selasky "# Total MADs used: %u\n",
564*d6b92ffaSHans Petter Selasky fabric->maxhops_discovered, fabric->total_mads_used);
565*d6b92ffaSHans Petter Selasky fprintf(f, "# Initiated from node %016" PRIx64 " port %016" PRIx64 "\n",
566*d6b92ffaSHans Petter Selasky fabric->from_node->guid,
567*d6b92ffaSHans Petter Selasky mad_get_field64(fabric->from_node->info, 0,
568*d6b92ffaSHans Petter Selasky IB_NODE_PORT_GUID_F));
569*d6b92ffaSHans Petter Selasky
570*d6b92ffaSHans Petter Selasky /* Make pass on switches */
571*d6b92ffaSHans Petter Selasky if (group) {
572*d6b92ffaSHans Petter Selasky ibnd_chassis_t *ch = NULL;
573*d6b92ffaSHans Petter Selasky
574*d6b92ffaSHans Petter Selasky /* Chassis based switches first */
575*d6b92ffaSHans Petter Selasky for (ch = fabric->chassis; ch; ch = ch->next) {
576*d6b92ffaSHans Petter Selasky int n = 0;
577*d6b92ffaSHans Petter Selasky
578*d6b92ffaSHans Petter Selasky if (!ch->chassisnum)
579*d6b92ffaSHans Petter Selasky continue;
580*d6b92ffaSHans Petter Selasky chguid = out_chassis(fabric, ch->chassisnum);
581*d6b92ffaSHans Petter Selasky chname = NULL;
582*d6b92ffaSHans Petter Selasky if (ibnd_is_xsigo_guid(chguid)) {
583*d6b92ffaSHans Petter Selasky for (node = ch->nodes; node;
584*d6b92ffaSHans Petter Selasky node = node->next_chassis_node) {
585*d6b92ffaSHans Petter Selasky if (ibnd_is_xsigo_hca(node->guid)) {
586*d6b92ffaSHans Petter Selasky chname = node->nodedesc;
587*d6b92ffaSHans Petter Selasky fprintf(f, "Hostname: %s\n",
588*d6b92ffaSHans Petter Selasky clean_nodedesc
589*d6b92ffaSHans Petter Selasky (node->nodedesc));
590*d6b92ffaSHans Petter Selasky }
591*d6b92ffaSHans Petter Selasky }
592*d6b92ffaSHans Petter Selasky }
593*d6b92ffaSHans Petter Selasky
594*d6b92ffaSHans Petter Selasky fprintf(f, "\n# Spine Nodes");
595*d6b92ffaSHans Petter Selasky for (n = 1; n <= SPINES_MAX_NUM; n++) {
596*d6b92ffaSHans Petter Selasky if (ch->spinenode[n]) {
597*d6b92ffaSHans Petter Selasky out_switch(ch->spinenode[n], group,
598*d6b92ffaSHans Petter Selasky chname, NULL, NULL);
599*d6b92ffaSHans Petter Selasky for (p = 1;
600*d6b92ffaSHans Petter Selasky p <= ch->spinenode[n]->numports;
601*d6b92ffaSHans Petter Selasky p++) {
602*d6b92ffaSHans Petter Selasky port =
603*d6b92ffaSHans Petter Selasky ch->spinenode[n]->ports[p];
604*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
605*d6b92ffaSHans Petter Selasky out_switch_port(port,
606*d6b92ffaSHans Petter Selasky group,
607*d6b92ffaSHans Petter Selasky NULL);
608*d6b92ffaSHans Petter Selasky }
609*d6b92ffaSHans Petter Selasky }
610*d6b92ffaSHans Petter Selasky }
611*d6b92ffaSHans Petter Selasky fprintf(f, "\n# Line Nodes");
612*d6b92ffaSHans Petter Selasky for (n = 1; n <= LINES_MAX_NUM; n++) {
613*d6b92ffaSHans Petter Selasky if (ch->linenode[n]) {
614*d6b92ffaSHans Petter Selasky out_switch(ch->linenode[n], group,
615*d6b92ffaSHans Petter Selasky chname, NULL, NULL);
616*d6b92ffaSHans Petter Selasky for (p = 1;
617*d6b92ffaSHans Petter Selasky p <= ch->linenode[n]->numports;
618*d6b92ffaSHans Petter Selasky p++) {
619*d6b92ffaSHans Petter Selasky port =
620*d6b92ffaSHans Petter Selasky ch->linenode[n]->ports[p];
621*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
622*d6b92ffaSHans Petter Selasky out_switch_port(port,
623*d6b92ffaSHans Petter Selasky group,
624*d6b92ffaSHans Petter Selasky NULL);
625*d6b92ffaSHans Petter Selasky }
626*d6b92ffaSHans Petter Selasky }
627*d6b92ffaSHans Petter Selasky }
628*d6b92ffaSHans Petter Selasky
629*d6b92ffaSHans Petter Selasky fprintf(f, "\n# Chassis Switches");
630*d6b92ffaSHans Petter Selasky for (node = ch->nodes; node;
631*d6b92ffaSHans Petter Selasky node = node->next_chassis_node) {
632*d6b92ffaSHans Petter Selasky if (node->type == IB_NODE_SWITCH) {
633*d6b92ffaSHans Petter Selasky out_switch(node, group, chname, NULL,
634*d6b92ffaSHans Petter Selasky NULL);
635*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
636*d6b92ffaSHans Petter Selasky port = node->ports[p];
637*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
638*d6b92ffaSHans Petter Selasky out_switch_port(port,
639*d6b92ffaSHans Petter Selasky group,
640*d6b92ffaSHans Petter Selasky NULL);
641*d6b92ffaSHans Petter Selasky }
642*d6b92ffaSHans Petter Selasky }
643*d6b92ffaSHans Petter Selasky
644*d6b92ffaSHans Petter Selasky }
645*d6b92ffaSHans Petter Selasky
646*d6b92ffaSHans Petter Selasky fprintf(f, "\n# Chassis CAs");
647*d6b92ffaSHans Petter Selasky for (node = ch->nodes; node;
648*d6b92ffaSHans Petter Selasky node = node->next_chassis_node) {
649*d6b92ffaSHans Petter Selasky if (node->type == IB_NODE_CA) {
650*d6b92ffaSHans Petter Selasky out_ca(node, group, chname, NULL, NULL);
651*d6b92ffaSHans Petter Selasky for (p = 1; p <= node->numports; p++) {
652*d6b92ffaSHans Petter Selasky port = node->ports[p];
653*d6b92ffaSHans Petter Selasky if (port && port->remoteport)
654*d6b92ffaSHans Petter Selasky out_ca_port(port, group,
655*d6b92ffaSHans Petter Selasky NULL);
656*d6b92ffaSHans Petter Selasky }
657*d6b92ffaSHans Petter Selasky }
658*d6b92ffaSHans Petter Selasky }
659*d6b92ffaSHans Petter Selasky
660*d6b92ffaSHans Petter Selasky }
661*d6b92ffaSHans Petter Selasky
662*d6b92ffaSHans Petter Selasky } else { /* !group */
663*d6b92ffaSHans Petter Selasky iter_user_data.group = group;
664*d6b92ffaSHans Petter Selasky iter_user_data.skip_chassis_nodes = 0;
665*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, switch_iter_func, IB_NODE_SWITCH,
666*d6b92ffaSHans Petter Selasky &iter_user_data);
667*d6b92ffaSHans Petter Selasky }
668*d6b92ffaSHans Petter Selasky
669*d6b92ffaSHans Petter Selasky chname = NULL;
670*d6b92ffaSHans Petter Selasky if (group) {
671*d6b92ffaSHans Petter Selasky iter_user_data.group = group;
672*d6b92ffaSHans Petter Selasky iter_user_data.skip_chassis_nodes = 1;
673*d6b92ffaSHans Petter Selasky
674*d6b92ffaSHans Petter Selasky fprintf(f, "\nNon-Chassis Nodes\n");
675*d6b92ffaSHans Petter Selasky
676*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, switch_iter_func, IB_NODE_SWITCH,
677*d6b92ffaSHans Petter Selasky &iter_user_data);
678*d6b92ffaSHans Petter Selasky }
679*d6b92ffaSHans Petter Selasky
680*d6b92ffaSHans Petter Selasky iter_user_data.group = group;
681*d6b92ffaSHans Petter Selasky iter_user_data.skip_chassis_nodes = 0;
682*d6b92ffaSHans Petter Selasky /* Make pass on CAs */
683*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, ca_iter_func, IB_NODE_CA, &iter_user_data);
684*d6b92ffaSHans Petter Selasky
685*d6b92ffaSHans Petter Selasky /* Make pass on routers */
686*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(fabric, router_iter_func, IB_NODE_ROUTER,
687*d6b92ffaSHans Petter Selasky &iter_user_data);
688*d6b92ffaSHans Petter Selasky
689*d6b92ffaSHans Petter Selasky return i;
690*d6b92ffaSHans Petter Selasky }
691*d6b92ffaSHans Petter Selasky
dump_ports_report(ibnd_node_t * node,void * user_data)692*d6b92ffaSHans Petter Selasky void dump_ports_report(ibnd_node_t * node, void *user_data)
693*d6b92ffaSHans Petter Selasky {
694*d6b92ffaSHans Petter Selasky int p = 0;
695*d6b92ffaSHans Petter Selasky ibnd_port_t *port = NULL;
696*d6b92ffaSHans Petter Selasky char *nodename = NULL;
697*d6b92ffaSHans Petter Selasky char *rem_nodename = NULL;
698*d6b92ffaSHans Petter Selasky
699*d6b92ffaSHans Petter Selasky /* for each port */
700*d6b92ffaSHans Petter Selasky for (p = node->numports, port = node->ports[p]; p > 0;
701*d6b92ffaSHans Petter Selasky port = node->ports[--p]) {
702*d6b92ffaSHans Petter Selasky uint32_t iwidth, ispeed, fdr10, espeed, cap_mask;
703*d6b92ffaSHans Petter Selasky uint8_t *info = NULL;
704*d6b92ffaSHans Petter Selasky if (port == NULL)
705*d6b92ffaSHans Petter Selasky continue;
706*d6b92ffaSHans Petter Selasky iwidth =
707*d6b92ffaSHans Petter Selasky mad_get_field(port->info, 0, IB_PORT_LINK_WIDTH_ACTIVE_F);
708*d6b92ffaSHans Petter Selasky ispeed =
709*d6b92ffaSHans Petter Selasky mad_get_field(port->info, 0, IB_PORT_LINK_SPEED_ACTIVE_F);
710*d6b92ffaSHans Petter Selasky if (port->node->type == IB_NODE_SWITCH) {
711*d6b92ffaSHans Petter Selasky if (port->node->ports[0])
712*d6b92ffaSHans Petter Selasky info = (uint8_t *)&port->node->ports[0]->info;
713*d6b92ffaSHans Petter Selasky }
714*d6b92ffaSHans Petter Selasky else
715*d6b92ffaSHans Petter Selasky info = (uint8_t *)&port->info;
716*d6b92ffaSHans Petter Selasky if (info) {
717*d6b92ffaSHans Petter Selasky cap_mask = mad_get_field(info, 0, IB_PORT_CAPMASK_F);
718*d6b92ffaSHans Petter Selasky if (cap_mask & CL_NTOH32(IB_PORT_CAP_HAS_EXT_SPEEDS))
719*d6b92ffaSHans Petter Selasky espeed = mad_get_field(port->info, 0,
720*d6b92ffaSHans Petter Selasky IB_PORT_LINK_SPEED_EXT_ACTIVE_F);
721*d6b92ffaSHans Petter Selasky else
722*d6b92ffaSHans Petter Selasky espeed = 0;
723*d6b92ffaSHans Petter Selasky } else {
724*d6b92ffaSHans Petter Selasky ispeed = 0;
725*d6b92ffaSHans Petter Selasky iwidth = 0;
726*d6b92ffaSHans Petter Selasky espeed = 0;
727*d6b92ffaSHans Petter Selasky }
728*d6b92ffaSHans Petter Selasky fdr10 = mad_get_field(port->ext_info, 0,
729*d6b92ffaSHans Petter Selasky IB_MLNX_EXT_PORT_LINK_SPEED_ACTIVE_F);
730*d6b92ffaSHans Petter Selasky nodename = remap_node_name(node_name_map,
731*d6b92ffaSHans Petter Selasky port->node->guid,
732*d6b92ffaSHans Petter Selasky port->node->nodedesc);
733*d6b92ffaSHans Petter Selasky fprintf(stdout, "%2s %5d %2d 0x%016" PRIx64 " %s %s",
734*d6b92ffaSHans Petter Selasky ports_nt_str_compat(node),
735*d6b92ffaSHans Petter Selasky node->type ==
736*d6b92ffaSHans Petter Selasky IB_NODE_SWITCH ? node->smalid : port->base_lid,
737*d6b92ffaSHans Petter Selasky port->portnum, port->guid,
738*d6b92ffaSHans Petter Selasky dump_linkwidth_compat(iwidth),
739*d6b92ffaSHans Petter Selasky (ispeed != 4 && !espeed) ?
740*d6b92ffaSHans Petter Selasky dump_linkspeed_compat(ispeed) :
741*d6b92ffaSHans Petter Selasky dump_linkspeedext_compat(espeed, ispeed, fdr10));
742*d6b92ffaSHans Petter Selasky if (port->remoteport) {
743*d6b92ffaSHans Petter Selasky rem_nodename = remap_node_name(node_name_map,
744*d6b92ffaSHans Petter Selasky port->remoteport->node->guid,
745*d6b92ffaSHans Petter Selasky port->remoteport->node->nodedesc);
746*d6b92ffaSHans Petter Selasky fprintf(stdout,
747*d6b92ffaSHans Petter Selasky " - %2s %5d %2d 0x%016" PRIx64
748*d6b92ffaSHans Petter Selasky " ( '%s' - '%s' )\n",
749*d6b92ffaSHans Petter Selasky ports_nt_str_compat(port->remoteport->node),
750*d6b92ffaSHans Petter Selasky port->remoteport->node->type == IB_NODE_SWITCH ?
751*d6b92ffaSHans Petter Selasky port->remoteport->node->smalid :
752*d6b92ffaSHans Petter Selasky port->remoteport->base_lid,
753*d6b92ffaSHans Petter Selasky port->remoteport->portnum,
754*d6b92ffaSHans Petter Selasky port->remoteport->guid, nodename, rem_nodename);
755*d6b92ffaSHans Petter Selasky free(rem_nodename);
756*d6b92ffaSHans Petter Selasky } else
757*d6b92ffaSHans Petter Selasky fprintf(stdout, "%36s'%s'\n", "", nodename);
758*d6b92ffaSHans Petter Selasky
759*d6b92ffaSHans Petter Selasky free(nodename);
760*d6b92ffaSHans Petter Selasky }
761*d6b92ffaSHans Petter Selasky }
762*d6b92ffaSHans Petter Selasky
763*d6b92ffaSHans Petter Selasky struct iter_diff_data {
764*d6b92ffaSHans Petter Selasky uint32_t diff_flags;
765*d6b92ffaSHans Petter Selasky ibnd_fabric_t *fabric1;
766*d6b92ffaSHans Petter Selasky ibnd_fabric_t *fabric2;
767*d6b92ffaSHans Petter Selasky char *fabric1_prefix;
768*d6b92ffaSHans Petter Selasky char *fabric2_prefix;
769*d6b92ffaSHans Petter Selasky void (*out_header) (ibnd_node_t *, int, char *, char *, char *);
770*d6b92ffaSHans Petter Selasky void (*out_header_detail) (ibnd_node_t *, char *);
771*d6b92ffaSHans Petter Selasky void (*out_port) (ibnd_port_t *, int, char *);
772*d6b92ffaSHans Petter Selasky };
773*d6b92ffaSHans Petter Selasky
diff_iter_out_header(ibnd_node_t * node,struct iter_diff_data * data,int * out_header_flag)774*d6b92ffaSHans Petter Selasky static void diff_iter_out_header(ibnd_node_t * node,
775*d6b92ffaSHans Petter Selasky struct iter_diff_data *data,
776*d6b92ffaSHans Petter Selasky int *out_header_flag)
777*d6b92ffaSHans Petter Selasky {
778*d6b92ffaSHans Petter Selasky if (!(*out_header_flag)) {
779*d6b92ffaSHans Petter Selasky (*data->out_header) (node, 0, NULL, NULL, NULL);
780*d6b92ffaSHans Petter Selasky (*out_header_flag)++;
781*d6b92ffaSHans Petter Selasky }
782*d6b92ffaSHans Petter Selasky }
783*d6b92ffaSHans Petter Selasky
diff_ports(ibnd_node_t * fabric1_node,ibnd_node_t * fabric2_node,int * out_header_flag,struct iter_diff_data * data)784*d6b92ffaSHans Petter Selasky static void diff_ports(ibnd_node_t * fabric1_node, ibnd_node_t * fabric2_node,
785*d6b92ffaSHans Petter Selasky int *out_header_flag, struct iter_diff_data *data)
786*d6b92ffaSHans Petter Selasky {
787*d6b92ffaSHans Petter Selasky ibnd_port_t *fabric1_port;
788*d6b92ffaSHans Petter Selasky ibnd_port_t *fabric2_port;
789*d6b92ffaSHans Petter Selasky int p;
790*d6b92ffaSHans Petter Selasky
791*d6b92ffaSHans Petter Selasky for (p = 1; p <= fabric1_node->numports; p++) {
792*d6b92ffaSHans Petter Selasky int fabric1_out = 0, fabric2_out = 0;
793*d6b92ffaSHans Petter Selasky
794*d6b92ffaSHans Petter Selasky fabric1_port = fabric1_node->ports[p];
795*d6b92ffaSHans Petter Selasky fabric2_port = fabric2_node->ports[p];
796*d6b92ffaSHans Petter Selasky
797*d6b92ffaSHans Petter Selasky if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION) {
798*d6b92ffaSHans Petter Selasky if ((fabric1_port && !fabric2_port)
799*d6b92ffaSHans Petter Selasky || ((fabric1_port && fabric2_port)
800*d6b92ffaSHans Petter Selasky && (fabric1_port->remoteport
801*d6b92ffaSHans Petter Selasky && !fabric2_port->remoteport)))
802*d6b92ffaSHans Petter Selasky fabric1_out++;
803*d6b92ffaSHans Petter Selasky else if ((!fabric1_port && fabric2_port)
804*d6b92ffaSHans Petter Selasky || ((fabric1_port && fabric2_port)
805*d6b92ffaSHans Petter Selasky && (!fabric1_port->remoteport
806*d6b92ffaSHans Petter Selasky && fabric2_port->remoteport)))
807*d6b92ffaSHans Petter Selasky fabric2_out++;
808*d6b92ffaSHans Petter Selasky else if ((fabric1_port && fabric2_port)
809*d6b92ffaSHans Petter Selasky && ((fabric1_port->guid != fabric2_port->guid)
810*d6b92ffaSHans Petter Selasky ||
811*d6b92ffaSHans Petter Selasky ((fabric1_port->remoteport
812*d6b92ffaSHans Petter Selasky && fabric2_port->remoteport)
813*d6b92ffaSHans Petter Selasky && (fabric1_port->remoteport->guid !=
814*d6b92ffaSHans Petter Selasky fabric2_port->remoteport->guid)))) {
815*d6b92ffaSHans Petter Selasky fabric1_out++;
816*d6b92ffaSHans Petter Selasky fabric2_out++;
817*d6b92ffaSHans Petter Selasky }
818*d6b92ffaSHans Petter Selasky }
819*d6b92ffaSHans Petter Selasky
820*d6b92ffaSHans Petter Selasky if ((data->diff_flags & DIFF_FLAG_LID)
821*d6b92ffaSHans Petter Selasky && fabric1_port && fabric2_port
822*d6b92ffaSHans Petter Selasky && fabric1_port->base_lid != fabric2_port->base_lid) {
823*d6b92ffaSHans Petter Selasky fabric1_out++;
824*d6b92ffaSHans Petter Selasky fabric2_out++;
825*d6b92ffaSHans Petter Selasky }
826*d6b92ffaSHans Petter Selasky
827*d6b92ffaSHans Petter Selasky if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
828*d6b92ffaSHans Petter Selasky && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
829*d6b92ffaSHans Petter Selasky && fabric1_port && fabric2_port
830*d6b92ffaSHans Petter Selasky && fabric1_port->remoteport && fabric2_port->remoteport
831*d6b92ffaSHans Petter Selasky && memcmp(fabric1_port->remoteport->node->nodedesc,
832*d6b92ffaSHans Petter Selasky fabric2_port->remoteport->node->nodedesc,
833*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE)) {
834*d6b92ffaSHans Petter Selasky fabric1_out++;
835*d6b92ffaSHans Petter Selasky fabric2_out++;
836*d6b92ffaSHans Petter Selasky }
837*d6b92ffaSHans Petter Selasky
838*d6b92ffaSHans Petter Selasky if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
839*d6b92ffaSHans Petter Selasky && data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
840*d6b92ffaSHans Petter Selasky && fabric1_port && fabric2_port
841*d6b92ffaSHans Petter Selasky && fabric1_port->remoteport && fabric2_port->remoteport
842*d6b92ffaSHans Petter Selasky && memcmp(fabric1_port->remoteport->node->nodedesc,
843*d6b92ffaSHans Petter Selasky fabric2_port->remoteport->node->nodedesc,
844*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE)) {
845*d6b92ffaSHans Petter Selasky fabric1_out++;
846*d6b92ffaSHans Petter Selasky fabric2_out++;
847*d6b92ffaSHans Petter Selasky }
848*d6b92ffaSHans Petter Selasky
849*d6b92ffaSHans Petter Selasky if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
850*d6b92ffaSHans Petter Selasky && data->diff_flags & DIFF_FLAG_LID
851*d6b92ffaSHans Petter Selasky && fabric1_port && fabric2_port
852*d6b92ffaSHans Petter Selasky && fabric1_port->remoteport && fabric2_port->remoteport
853*d6b92ffaSHans Petter Selasky && fabric1_port->remoteport->base_lid != fabric2_port->remoteport->base_lid) {
854*d6b92ffaSHans Petter Selasky fabric1_out++;
855*d6b92ffaSHans Petter Selasky fabric2_out++;
856*d6b92ffaSHans Petter Selasky }
857*d6b92ffaSHans Petter Selasky
858*d6b92ffaSHans Petter Selasky if (fabric1_out) {
859*d6b92ffaSHans Petter Selasky diff_iter_out_header(fabric1_node, data,
860*d6b92ffaSHans Petter Selasky out_header_flag);
861*d6b92ffaSHans Petter Selasky (*data->out_port) (fabric1_port, 0,
862*d6b92ffaSHans Petter Selasky data->fabric1_prefix);
863*d6b92ffaSHans Petter Selasky }
864*d6b92ffaSHans Petter Selasky if (fabric2_out) {
865*d6b92ffaSHans Petter Selasky diff_iter_out_header(fabric1_node, data,
866*d6b92ffaSHans Petter Selasky out_header_flag);
867*d6b92ffaSHans Petter Selasky (*data->out_port) (fabric2_port, 0,
868*d6b92ffaSHans Petter Selasky data->fabric2_prefix);
869*d6b92ffaSHans Petter Selasky }
870*d6b92ffaSHans Petter Selasky }
871*d6b92ffaSHans Petter Selasky }
872*d6b92ffaSHans Petter Selasky
diff_iter_func(ibnd_node_t * fabric1_node,void * iter_user_data)873*d6b92ffaSHans Petter Selasky static void diff_iter_func(ibnd_node_t * fabric1_node, void *iter_user_data)
874*d6b92ffaSHans Petter Selasky {
875*d6b92ffaSHans Petter Selasky struct iter_diff_data *data = iter_user_data;
876*d6b92ffaSHans Petter Selasky ibnd_node_t *fabric2_node;
877*d6b92ffaSHans Petter Selasky ibnd_port_t *fabric1_port;
878*d6b92ffaSHans Petter Selasky int p;
879*d6b92ffaSHans Petter Selasky
880*d6b92ffaSHans Petter Selasky DEBUG("DEBUG: fabric1_node %p\n", fabric1_node);
881*d6b92ffaSHans Petter Selasky
882*d6b92ffaSHans Petter Selasky fabric2_node = ibnd_find_node_guid(data->fabric2, fabric1_node->guid);
883*d6b92ffaSHans Petter Selasky if (!fabric2_node) {
884*d6b92ffaSHans Petter Selasky (*data->out_header) (fabric1_node, 0, NULL,
885*d6b92ffaSHans Petter Selasky data->fabric1_prefix,
886*d6b92ffaSHans Petter Selasky data->fabric1_prefix);
887*d6b92ffaSHans Petter Selasky for (p = 1; p <= fabric1_node->numports; p++) {
888*d6b92ffaSHans Petter Selasky fabric1_port = fabric1_node->ports[p];
889*d6b92ffaSHans Petter Selasky if (fabric1_port && fabric1_port->remoteport)
890*d6b92ffaSHans Petter Selasky (*data->out_port) (fabric1_port, 0,
891*d6b92ffaSHans Petter Selasky data->fabric1_prefix);
892*d6b92ffaSHans Petter Selasky }
893*d6b92ffaSHans Petter Selasky } else if (data->diff_flags &
894*d6b92ffaSHans Petter Selasky (DIFF_FLAG_PORT_CONNECTION | DIFF_FLAG_LID
895*d6b92ffaSHans Petter Selasky | DIFF_FLAG_NODE_DESCRIPTION)) {
896*d6b92ffaSHans Petter Selasky int out_header_flag = 0;
897*d6b92ffaSHans Petter Selasky
898*d6b92ffaSHans Petter Selasky if ((data->diff_flags & DIFF_FLAG_LID
899*d6b92ffaSHans Petter Selasky && fabric1_node->smalid != fabric2_node->smalid) ||
900*d6b92ffaSHans Petter Selasky (data->diff_flags & DIFF_FLAG_NODE_DESCRIPTION
901*d6b92ffaSHans Petter Selasky && memcmp(fabric1_node->nodedesc, fabric2_node->nodedesc,
902*d6b92ffaSHans Petter Selasky IB_SMP_DATA_SIZE))) {
903*d6b92ffaSHans Petter Selasky (*data->out_header) (fabric1_node, 0, NULL, NULL,
904*d6b92ffaSHans Petter Selasky data->fabric1_prefix);
905*d6b92ffaSHans Petter Selasky (*data->out_header_detail) (fabric2_node,
906*d6b92ffaSHans Petter Selasky data->fabric2_prefix);
907*d6b92ffaSHans Petter Selasky fprintf(f, "\n");
908*d6b92ffaSHans Petter Selasky out_header_flag++;
909*d6b92ffaSHans Petter Selasky }
910*d6b92ffaSHans Petter Selasky
911*d6b92ffaSHans Petter Selasky if (fabric1_node->numports != fabric2_node->numports) {
912*d6b92ffaSHans Petter Selasky diff_iter_out_header(fabric1_node, data,
913*d6b92ffaSHans Petter Selasky &out_header_flag);
914*d6b92ffaSHans Petter Selasky fprintf(f, "%snumports = %d\n", data->fabric1_prefix,
915*d6b92ffaSHans Petter Selasky fabric1_node->numports);
916*d6b92ffaSHans Petter Selasky fprintf(f, "%snumports = %d\n", data->fabric2_prefix,
917*d6b92ffaSHans Petter Selasky fabric2_node->numports);
918*d6b92ffaSHans Petter Selasky return;
919*d6b92ffaSHans Petter Selasky }
920*d6b92ffaSHans Petter Selasky
921*d6b92ffaSHans Petter Selasky if (data->diff_flags & DIFF_FLAG_PORT_CONNECTION
922*d6b92ffaSHans Petter Selasky || data->diff_flags & DIFF_FLAG_LID)
923*d6b92ffaSHans Petter Selasky diff_ports(fabric1_node, fabric2_node, &out_header_flag,
924*d6b92ffaSHans Petter Selasky data);
925*d6b92ffaSHans Petter Selasky }
926*d6b92ffaSHans Petter Selasky }
927*d6b92ffaSHans Petter Selasky
diff_common(ibnd_fabric_t * orig_fabric,ibnd_fabric_t * new_fabric,int node_type,uint32_t diff_flags,void (* out_header)(ibnd_node_t *,int,char *,char *,char *),void (* out_header_detail)(ibnd_node_t *,char *),void (* out_port)(ibnd_port_t *,int,char *))928*d6b92ffaSHans Petter Selasky static int diff_common(ibnd_fabric_t * orig_fabric, ibnd_fabric_t * new_fabric,
929*d6b92ffaSHans Petter Selasky int node_type, uint32_t diff_flags,
930*d6b92ffaSHans Petter Selasky void (*out_header) (ibnd_node_t *, int, char *, char *,
931*d6b92ffaSHans Petter Selasky char *),
932*d6b92ffaSHans Petter Selasky void (*out_header_detail) (ibnd_node_t *, char *),
933*d6b92ffaSHans Petter Selasky void (*out_port) (ibnd_port_t *, int, char *))
934*d6b92ffaSHans Petter Selasky {
935*d6b92ffaSHans Petter Selasky struct iter_diff_data iter_diff_data;
936*d6b92ffaSHans Petter Selasky
937*d6b92ffaSHans Petter Selasky iter_diff_data.diff_flags = diff_flags;
938*d6b92ffaSHans Petter Selasky iter_diff_data.fabric1 = orig_fabric;
939*d6b92ffaSHans Petter Selasky iter_diff_data.fabric2 = new_fabric;
940*d6b92ffaSHans Petter Selasky iter_diff_data.fabric1_prefix = "< ";
941*d6b92ffaSHans Petter Selasky iter_diff_data.fabric2_prefix = "> ";
942*d6b92ffaSHans Petter Selasky iter_diff_data.out_header = out_header;
943*d6b92ffaSHans Petter Selasky iter_diff_data.out_header_detail = out_header_detail;
944*d6b92ffaSHans Petter Selasky iter_diff_data.out_port = out_port;
945*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(orig_fabric, diff_iter_func, node_type,
946*d6b92ffaSHans Petter Selasky &iter_diff_data);
947*d6b92ffaSHans Petter Selasky
948*d6b92ffaSHans Petter Selasky /* Do opposite diff to find existence of node types
949*d6b92ffaSHans Petter Selasky * in new_fabric but not in orig_fabric.
950*d6b92ffaSHans Petter Selasky *
951*d6b92ffaSHans Petter Selasky * In this diff, we don't need to check port connections,
952*d6b92ffaSHans Petter Selasky * lids, or node descriptions since it has already been
953*d6b92ffaSHans Petter Selasky * done (i.e. checks are only done when guid exists on both
954*d6b92ffaSHans Petter Selasky * orig and new).
955*d6b92ffaSHans Petter Selasky */
956*d6b92ffaSHans Petter Selasky iter_diff_data.diff_flags = diff_flags & ~DIFF_FLAG_PORT_CONNECTION;
957*d6b92ffaSHans Petter Selasky iter_diff_data.diff_flags &= ~DIFF_FLAG_LID;
958*d6b92ffaSHans Petter Selasky iter_diff_data.diff_flags &= ~DIFF_FLAG_NODE_DESCRIPTION;
959*d6b92ffaSHans Petter Selasky iter_diff_data.fabric1 = new_fabric;
960*d6b92ffaSHans Petter Selasky iter_diff_data.fabric2 = orig_fabric;
961*d6b92ffaSHans Petter Selasky iter_diff_data.fabric1_prefix = "> ";
962*d6b92ffaSHans Petter Selasky iter_diff_data.fabric2_prefix = "< ";
963*d6b92ffaSHans Petter Selasky iter_diff_data.out_header = out_header;
964*d6b92ffaSHans Petter Selasky iter_diff_data.out_header_detail = out_header_detail;
965*d6b92ffaSHans Petter Selasky iter_diff_data.out_port = out_port;
966*d6b92ffaSHans Petter Selasky ibnd_iter_nodes_type(new_fabric, diff_iter_func, node_type,
967*d6b92ffaSHans Petter Selasky &iter_diff_data);
968*d6b92ffaSHans Petter Selasky
969*d6b92ffaSHans Petter Selasky return 0;
970*d6b92ffaSHans Petter Selasky }
971*d6b92ffaSHans Petter Selasky
diff(ibnd_fabric_t * orig_fabric,ibnd_fabric_t * new_fabric)972*d6b92ffaSHans Petter Selasky int diff(ibnd_fabric_t * orig_fabric, ibnd_fabric_t * new_fabric)
973*d6b92ffaSHans Petter Selasky {
974*d6b92ffaSHans Petter Selasky if (diffcheck_flags & DIFF_FLAG_SWITCH)
975*d6b92ffaSHans Petter Selasky diff_common(orig_fabric, new_fabric, IB_NODE_SWITCH,
976*d6b92ffaSHans Petter Selasky diffcheck_flags, out_switch, out_switch_detail,
977*d6b92ffaSHans Petter Selasky out_switch_port);
978*d6b92ffaSHans Petter Selasky
979*d6b92ffaSHans Petter Selasky if (diffcheck_flags & DIFF_FLAG_CA)
980*d6b92ffaSHans Petter Selasky diff_common(orig_fabric, new_fabric, IB_NODE_CA,
981*d6b92ffaSHans Petter Selasky diffcheck_flags, out_ca, out_ca_detail,
982*d6b92ffaSHans Petter Selasky out_ca_port);
983*d6b92ffaSHans Petter Selasky
984*d6b92ffaSHans Petter Selasky if (diffcheck_flags & DIFF_FLAG_ROUTER)
985*d6b92ffaSHans Petter Selasky diff_common(orig_fabric, new_fabric, IB_NODE_ROUTER,
986*d6b92ffaSHans Petter Selasky diffcheck_flags, out_ca, out_ca_detail,
987*d6b92ffaSHans Petter Selasky out_ca_port);
988*d6b92ffaSHans Petter Selasky
989*d6b92ffaSHans Petter Selasky return 0;
990*d6b92ffaSHans Petter Selasky }
991*d6b92ffaSHans Petter Selasky
992*d6b92ffaSHans Petter Selasky static int list, group, ports_report;
993*d6b92ffaSHans Petter Selasky
process_opt(void * context,int ch,char * optarg)994*d6b92ffaSHans Petter Selasky static int process_opt(void *context, int ch, char *optarg)
995*d6b92ffaSHans Petter Selasky {
996*d6b92ffaSHans Petter Selasky struct ibnd_config *cfg = context;
997*d6b92ffaSHans Petter Selasky char *p;
998*d6b92ffaSHans Petter Selasky
999*d6b92ffaSHans Petter Selasky switch (ch) {
1000*d6b92ffaSHans Petter Selasky case 1:
1001*d6b92ffaSHans Petter Selasky node_name_map_file = strdup(optarg);
1002*d6b92ffaSHans Petter Selasky break;
1003*d6b92ffaSHans Petter Selasky case 2:
1004*d6b92ffaSHans Petter Selasky cache_file = strdup(optarg);
1005*d6b92ffaSHans Petter Selasky break;
1006*d6b92ffaSHans Petter Selasky case 3:
1007*d6b92ffaSHans Petter Selasky load_cache_file = strdup(optarg);
1008*d6b92ffaSHans Petter Selasky break;
1009*d6b92ffaSHans Petter Selasky case 4:
1010*d6b92ffaSHans Petter Selasky diff_cache_file = strdup(optarg);
1011*d6b92ffaSHans Petter Selasky break;
1012*d6b92ffaSHans Petter Selasky case 5:
1013*d6b92ffaSHans Petter Selasky diffcheck_flags = 0;
1014*d6b92ffaSHans Petter Selasky p = strtok(optarg, ",");
1015*d6b92ffaSHans Petter Selasky while (p) {
1016*d6b92ffaSHans Petter Selasky if (!strcasecmp(p, "sw"))
1017*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_SWITCH;
1018*d6b92ffaSHans Petter Selasky else if (!strcasecmp(p, "ca"))
1019*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_CA;
1020*d6b92ffaSHans Petter Selasky else if (!strcasecmp(p, "router"))
1021*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_ROUTER;
1022*d6b92ffaSHans Petter Selasky else if (!strcasecmp(p, "port"))
1023*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_PORT_CONNECTION;
1024*d6b92ffaSHans Petter Selasky else if (!strcasecmp(p, "lid"))
1025*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_LID;
1026*d6b92ffaSHans Petter Selasky else if (!strcasecmp(p, "nodedesc"))
1027*d6b92ffaSHans Petter Selasky diffcheck_flags |= DIFF_FLAG_NODE_DESCRIPTION;
1028*d6b92ffaSHans Petter Selasky else {
1029*d6b92ffaSHans Petter Selasky fprintf(stderr, "invalid diff check key: %s\n",
1030*d6b92ffaSHans Petter Selasky p);
1031*d6b92ffaSHans Petter Selasky return -1;
1032*d6b92ffaSHans Petter Selasky }
1033*d6b92ffaSHans Petter Selasky p = strtok(NULL, ",");
1034*d6b92ffaSHans Petter Selasky }
1035*d6b92ffaSHans Petter Selasky break;
1036*d6b92ffaSHans Petter Selasky case 's':
1037*d6b92ffaSHans Petter Selasky cfg->show_progress = 1;
1038*d6b92ffaSHans Petter Selasky break;
1039*d6b92ffaSHans Petter Selasky case 'f':
1040*d6b92ffaSHans Petter Selasky full_info = 1;
1041*d6b92ffaSHans Petter Selasky break;
1042*d6b92ffaSHans Petter Selasky case 'l':
1043*d6b92ffaSHans Petter Selasky list = LIST_CA_NODE | LIST_SWITCH_NODE | LIST_ROUTER_NODE;
1044*d6b92ffaSHans Petter Selasky break;
1045*d6b92ffaSHans Petter Selasky case 'g':
1046*d6b92ffaSHans Petter Selasky group = 1;
1047*d6b92ffaSHans Petter Selasky break;
1048*d6b92ffaSHans Petter Selasky case 'S':
1049*d6b92ffaSHans Petter Selasky list = LIST_SWITCH_NODE;
1050*d6b92ffaSHans Petter Selasky break;
1051*d6b92ffaSHans Petter Selasky case 'H':
1052*d6b92ffaSHans Petter Selasky list = LIST_CA_NODE;
1053*d6b92ffaSHans Petter Selasky break;
1054*d6b92ffaSHans Petter Selasky case 'R':
1055*d6b92ffaSHans Petter Selasky list = LIST_ROUTER_NODE;
1056*d6b92ffaSHans Petter Selasky break;
1057*d6b92ffaSHans Petter Selasky case 'p':
1058*d6b92ffaSHans Petter Selasky ports_report = 1;
1059*d6b92ffaSHans Petter Selasky break;
1060*d6b92ffaSHans Petter Selasky case 'm':
1061*d6b92ffaSHans Petter Selasky report_max_hops = 1;
1062*d6b92ffaSHans Petter Selasky break;
1063*d6b92ffaSHans Petter Selasky case 'o':
1064*d6b92ffaSHans Petter Selasky cfg->max_smps = strtoul(optarg, NULL, 0);
1065*d6b92ffaSHans Petter Selasky break;
1066*d6b92ffaSHans Petter Selasky default:
1067*d6b92ffaSHans Petter Selasky return -1;
1068*d6b92ffaSHans Petter Selasky }
1069*d6b92ffaSHans Petter Selasky
1070*d6b92ffaSHans Petter Selasky return 0;
1071*d6b92ffaSHans Petter Selasky }
1072*d6b92ffaSHans Petter Selasky
main(int argc,char ** argv)1073*d6b92ffaSHans Petter Selasky int main(int argc, char **argv)
1074*d6b92ffaSHans Petter Selasky {
1075*d6b92ffaSHans Petter Selasky struct ibnd_config config = { 0 };
1076*d6b92ffaSHans Petter Selasky ibnd_fabric_t *fabric = NULL;
1077*d6b92ffaSHans Petter Selasky ibnd_fabric_t *diff_fabric = NULL;
1078*d6b92ffaSHans Petter Selasky
1079*d6b92ffaSHans Petter Selasky const struct ibdiag_opt opts[] = {
1080*d6b92ffaSHans Petter Selasky {"full", 'f', 0, NULL, "show full information (ports' speed and width, vlcap)"},
1081*d6b92ffaSHans Petter Selasky {"show", 's', 0, NULL, "show more information"},
1082*d6b92ffaSHans Petter Selasky {"list", 'l', 0, NULL, "list of connected nodes"},
1083*d6b92ffaSHans Petter Selasky {"grouping", 'g', 0, NULL, "show grouping"},
1084*d6b92ffaSHans Petter Selasky {"Hca_list", 'H', 0, NULL, "list of connected CAs"},
1085*d6b92ffaSHans Petter Selasky {"Switch_list", 'S', 0, NULL, "list of connected switches"},
1086*d6b92ffaSHans Petter Selasky {"Router_list", 'R', 0, NULL, "list of connected routers"},
1087*d6b92ffaSHans Petter Selasky {"node-name-map", 1, 1, "<file>", "node name map file"},
1088*d6b92ffaSHans Petter Selasky {"cache", 2, 1, "<file>",
1089*d6b92ffaSHans Petter Selasky "filename to cache ibnetdiscover data to"},
1090*d6b92ffaSHans Petter Selasky {"load-cache", 3, 1, "<file>",
1091*d6b92ffaSHans Petter Selasky "filename of ibnetdiscover cache to load"},
1092*d6b92ffaSHans Petter Selasky {"diff", 4, 1, "<file>",
1093*d6b92ffaSHans Petter Selasky "filename of ibnetdiscover cache to diff"},
1094*d6b92ffaSHans Petter Selasky {"diffcheck", 5, 1, "<key(s)>",
1095*d6b92ffaSHans Petter Selasky "specify checks to execute for --diff"},
1096*d6b92ffaSHans Petter Selasky {"ports", 'p', 0, NULL, "obtain a ports report"},
1097*d6b92ffaSHans Petter Selasky {"max_hops", 'm', 0, NULL,
1098*d6b92ffaSHans Petter Selasky "report max hops discovered by the library"},
1099*d6b92ffaSHans Petter Selasky {"outstanding_smps", 'o', 1, NULL,
1100*d6b92ffaSHans Petter Selasky "specify the number of outstanding SMP's which should be "
1101*d6b92ffaSHans Petter Selasky "issued during the scan"},
1102*d6b92ffaSHans Petter Selasky {0}
1103*d6b92ffaSHans Petter Selasky };
1104*d6b92ffaSHans Petter Selasky char usage_args[] = "[topology-file]";
1105*d6b92ffaSHans Petter Selasky
1106*d6b92ffaSHans Petter Selasky ibdiag_process_opts(argc, argv, &config, "DGKLs", opts, process_opt,
1107*d6b92ffaSHans Petter Selasky usage_args, NULL);
1108*d6b92ffaSHans Petter Selasky
1109*d6b92ffaSHans Petter Selasky f = stdout;
1110*d6b92ffaSHans Petter Selasky
1111*d6b92ffaSHans Petter Selasky argc -= optind;
1112*d6b92ffaSHans Petter Selasky argv += optind;
1113*d6b92ffaSHans Petter Selasky
1114*d6b92ffaSHans Petter Selasky if (ibd_timeout)
1115*d6b92ffaSHans Petter Selasky config.timeout_ms = ibd_timeout;
1116*d6b92ffaSHans Petter Selasky
1117*d6b92ffaSHans Petter Selasky config.flags = ibd_ibnetdisc_flags;
1118*d6b92ffaSHans Petter Selasky
1119*d6b92ffaSHans Petter Selasky if (argc && !(f = fopen(argv[0], "w")))
1120*d6b92ffaSHans Petter Selasky IBEXIT("can't open file %s for writing", argv[0]);
1121*d6b92ffaSHans Petter Selasky
1122*d6b92ffaSHans Petter Selasky config.mkey = ibd_mkey;
1123*d6b92ffaSHans Petter Selasky
1124*d6b92ffaSHans Petter Selasky node_name_map = open_node_name_map(node_name_map_file);
1125*d6b92ffaSHans Petter Selasky
1126*d6b92ffaSHans Petter Selasky if (diff_cache_file &&
1127*d6b92ffaSHans Petter Selasky !(diff_fabric = ibnd_load_fabric(diff_cache_file, 0)))
1128*d6b92ffaSHans Petter Selasky IBEXIT("loading cached fabric for diff failed\n");
1129*d6b92ffaSHans Petter Selasky
1130*d6b92ffaSHans Petter Selasky if (load_cache_file) {
1131*d6b92ffaSHans Petter Selasky if ((fabric = ibnd_load_fabric(load_cache_file, 0)) == NULL)
1132*d6b92ffaSHans Petter Selasky IBEXIT("loading cached fabric failed\n");
1133*d6b92ffaSHans Petter Selasky } else {
1134*d6b92ffaSHans Petter Selasky if ((fabric =
1135*d6b92ffaSHans Petter Selasky ibnd_discover_fabric(ibd_ca, ibd_ca_port, NULL, &config)) == NULL)
1136*d6b92ffaSHans Petter Selasky IBEXIT("discover failed\n");
1137*d6b92ffaSHans Petter Selasky }
1138*d6b92ffaSHans Petter Selasky
1139*d6b92ffaSHans Petter Selasky if (ports_report)
1140*d6b92ffaSHans Petter Selasky ibnd_iter_nodes(fabric, dump_ports_report, NULL);
1141*d6b92ffaSHans Petter Selasky else if (list)
1142*d6b92ffaSHans Petter Selasky list_nodes(fabric, list);
1143*d6b92ffaSHans Petter Selasky else if (diff_fabric)
1144*d6b92ffaSHans Petter Selasky diff(diff_fabric, fabric);
1145*d6b92ffaSHans Petter Selasky else
1146*d6b92ffaSHans Petter Selasky dump_topology(group, fabric);
1147*d6b92ffaSHans Petter Selasky
1148*d6b92ffaSHans Petter Selasky if (cache_file)
1149*d6b92ffaSHans Petter Selasky if (ibnd_cache_fabric(fabric, cache_file, 0) < 0)
1150*d6b92ffaSHans Petter Selasky IBEXIT("caching ibnetdiscover data failed\n");
1151*d6b92ffaSHans Petter Selasky
1152*d6b92ffaSHans Petter Selasky ibnd_destroy_fabric(fabric);
1153*d6b92ffaSHans Petter Selasky if (diff_fabric)
1154*d6b92ffaSHans Petter Selasky ibnd_destroy_fabric(diff_fabric);
1155*d6b92ffaSHans Petter Selasky close_node_name_map(node_name_map);
1156*d6b92ffaSHans Petter Selasky exit(0);
1157*d6b92ffaSHans Petter Selasky }
1158