1 /* 2 * Copyright (c) 2006,2007 The Regents of the University of California. 3 * Copyright (c) 2004-2009 Voltaire, Inc. All rights reserved. 4 * Copyright (c) 2002-2013 Mellanox Technologies LTD. All rights reserved. 5 * Copyright (c) 1996-2013 Intel Corporation. All rights reserved. 6 * Copyright (c) 2009 HNR Consulting. All rights reserved. 7 * 8 * Produced at Lawrence Livermore National Laboratory. 9 * Written by Ira Weiny <weiny2@llnl.gov>. 10 * 11 * This software is available to you under a choice of one of two 12 * licenses. You may choose to be licensed under the terms of the GNU 13 * General Public License (GPL) Version 2, available from the file 14 * COPYING in the main directory of this source tree, or the 15 * OpenIB.org BSD license below: 16 * 17 * Redistribution and use in source and binary forms, with or 18 * without modification, are permitted provided that the following 19 * conditions are met: 20 * 21 * - Redistributions of source code must retain the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer. 24 * 25 * - Redistributions in binary form must reproduce the above 26 * copyright notice, this list of conditions and the following 27 * disclaimer in the documentation and/or other materials 28 * provided with the distribution. 29 * 30 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 34 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 35 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 36 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 37 * SOFTWARE. 38 * 39 */ 40 41 #if HAVE_CONFIG_H 42 # include <config.h> 43 #endif /* HAVE_CONFIG_H */ 44 45 #include <unistd.h> 46 #include <stdio.h> 47 #include <arpa/inet.h> 48 #include <ctype.h> 49 #include <string.h> 50 #include <errno.h> 51 52 #define _GNU_SOURCE 53 #include <getopt.h> 54 55 #include <infiniband/umad.h> 56 #include <infiniband/mad.h> 57 #include <iba/ib_types.h> 58 #include <complib/cl_nodenamemap.h> 59 60 #include "ibdiag_common.h" 61 #include "ibdiag_sa.h" 62 63 #ifndef IB_PR_COMPMASK_SERVICEID 64 #define IB_PR_COMPMASK_SERVICEID (IB_PR_COMPMASK_SERVICEID_MSB | \ 65 IB_PR_COMPMASK_SERVICEID_LSB) 66 #endif 67 68 #define UMAD_SA_CAP_MASK2_IS_MCAST_TOP_SUP (1 << 3) 69 70 struct query_params { 71 uint64_t service_id; 72 ib_gid_t sgid, dgid, gid, mgid; 73 uint16_t slid, dlid, mlid; 74 uint32_t flow_label; 75 int hop_limit; 76 uint8_t tclass; 77 int reversible, numb_path; 78 uint16_t pkey; 79 int qos_class, sl; 80 uint8_t mtu, rate, pkt_life; 81 uint32_t qkey; 82 uint8_t scope; 83 uint8_t join_state; 84 int proxy_join; 85 ib_class_port_info_t cpi; 86 uint8_t with_grh; 87 ibmad_gid_t sa_dgid; 88 }; 89 90 struct query_cmd { 91 const char *name, *alias; 92 uint16_t query_type; 93 const char *usage; 94 int (*handler) (const struct query_cmd * q, struct sa_handle * h, 95 struct query_params * p, int argc, char *argv[]); 96 }; 97 98 static char *node_name_map_file = NULL; 99 static nn_map_t *node_name_map = NULL; 100 101 /** 102 * Declare some globals because I don't want this to be too complex. 103 */ 104 #define MAX_PORTS (8) 105 #define DEFAULT_SA_TIMEOUT_MS (1000) 106 107 enum { 108 ALL, 109 LID_ONLY, 110 UNIQUE_LID_ONLY, 111 GUID_ONLY, 112 ALL_DESC, 113 NAME_OF_LID, 114 NAME_OF_GUID, 115 } node_print_desc = ALL; 116 117 char *requested_name = NULL; 118 uint16_t requested_lid = 0; 119 int requested_lid_flag = 0; 120 uint64_t requested_guid = 0; 121 int requested_guid_flag = 0; 122 123 static unsigned valid_gid(ib_gid_t * gid) 124 { 125 ib_gid_t zero_gid; 126 memset(&zero_gid, 0, sizeof zero_gid); 127 return memcmp(&zero_gid, gid, sizeof(*gid)); 128 } 129 130 static void print_node_desc(ib_node_record_t * node_record) 131 { 132 ib_node_info_t *p_ni = &(node_record->node_info); 133 ib_node_desc_t *p_nd = &(node_record->node_desc); 134 char *name; 135 136 if (p_ni->node_type == IB_NODE_TYPE_CA) { 137 name = remap_node_name(node_name_map, 138 node_record->node_info.node_guid, 139 (char *)p_nd->description); 140 printf("%6d \"%s\"\n", cl_ntoh16(node_record->lid), name); 141 free(name); 142 } 143 } 144 145 static void dump_node_record(void *data, struct query_params *p) 146 { 147 ib_node_record_t *nr = data; 148 ib_node_info_t *ni = &nr->node_info; 149 char *name = remap_node_name(node_name_map, 150 cl_ntoh64(ni->node_guid), 151 (char *)nr->node_desc.description); 152 153 printf("NodeRecord dump:\n" 154 "\t\tlid.....................%u\n" 155 "\t\treserved................0x%X\n" 156 "\t\tbase_version............0x%X\n" 157 "\t\tclass_version...........0x%X\n" 158 "\t\tnode_type...............%s\n" 159 "\t\tnum_ports...............%u\n" 160 "\t\tsys_guid................0x%016" PRIx64 "\n" 161 "\t\tnode_guid...............0x%016" PRIx64 "\n" 162 "\t\tport_guid...............0x%016" PRIx64 "\n" 163 "\t\tpartition_cap...........0x%X\n" 164 "\t\tdevice_id...............0x%X\n" 165 "\t\trevision................0x%X\n" 166 "\t\tport_num................%u\n" 167 "\t\tvendor_id...............0x%X\n" 168 "\t\tNodeDescription.........%s\n", 169 cl_ntoh16(nr->lid), cl_ntoh16(nr->resv), 170 ni->base_version, ni->class_version, 171 ib_get_node_type_str(ni->node_type), ni->num_ports, 172 cl_ntoh64(ni->sys_guid), cl_ntoh64(ni->node_guid), 173 cl_ntoh64(ni->port_guid), cl_ntoh16(ni->partition_cap), 174 cl_ntoh16(ni->device_id), cl_ntoh32(ni->revision), 175 ib_node_info_get_local_port_num(ni), 176 cl_ntoh32(ib_node_info_get_vendor_id(ni)), 177 name); 178 179 free(name); 180 } 181 182 static void print_node_record(ib_node_record_t * node_record) 183 { 184 ib_node_info_t *p_ni = &node_record->node_info; 185 ib_node_desc_t *p_nd = &node_record->node_desc; 186 char *name; 187 188 switch (node_print_desc) { 189 case LID_ONLY: 190 case UNIQUE_LID_ONLY: 191 printf("%u\n", cl_ntoh16(node_record->lid)); 192 return; 193 case GUID_ONLY: 194 printf("0x%016" PRIx64 "\n", cl_ntoh64(p_ni->port_guid)); 195 return; 196 case NAME_OF_LID: 197 case NAME_OF_GUID: 198 name = remap_node_name(node_name_map, 199 cl_ntoh64(p_ni->node_guid), 200 (char *)p_nd->description); 201 printf("%s\n", name); 202 free(name); 203 return; 204 case ALL: 205 default: 206 break; 207 } 208 209 dump_node_record(node_record, 0); 210 } 211 212 static void dump_path_record(void *data, struct query_params *p) 213 { 214 char gid_str[INET6_ADDRSTRLEN]; 215 char gid_str2[INET6_ADDRSTRLEN]; 216 ib_path_rec_t *p_pr = data; 217 printf("PathRecord dump:\n" 218 "\t\tservice_id..............0x%016" PRIx64 "\n" 219 "\t\tdgid....................%s\n" 220 "\t\tsgid....................%s\n" 221 "\t\tdlid....................%u\n" 222 "\t\tslid....................%u\n" 223 "\t\thop_flow_raw............0x%X\n" 224 "\t\ttclass..................0x%X\n" 225 "\t\tnum_path_revers.........0x%X\n" 226 "\t\tpkey....................0x%X\n" 227 "\t\tqos_class...............0x%X\n" 228 "\t\tsl......................0x%X\n" 229 "\t\tmtu.....................0x%X\n" 230 "\t\trate....................0x%X\n" 231 "\t\tpkt_life................0x%X\n" 232 "\t\tpreference..............0x%X\n" 233 "\t\tresv2...................0x%02X%02X%02X%02X%02X%02X\n", 234 cl_ntoh64(p_pr->service_id), 235 inet_ntop(AF_INET6, p_pr->dgid.raw, gid_str, sizeof gid_str), 236 inet_ntop(AF_INET6, p_pr->sgid.raw, gid_str2, sizeof gid_str2), 237 cl_ntoh16(p_pr->dlid), cl_ntoh16(p_pr->slid), 238 cl_ntoh32(p_pr->hop_flow_raw), p_pr->tclass, p_pr->num_path, 239 cl_ntoh16(p_pr->pkey), ib_path_rec_qos_class(p_pr), 240 ib_path_rec_sl(p_pr), p_pr->mtu, p_pr->rate, p_pr->pkt_life, 241 p_pr->preference, 242 p_pr->resv2[0], p_pr->resv2[1], p_pr->resv2[2], 243 p_pr->resv2[3], p_pr->resv2[4], p_pr->resv2[5]); 244 } 245 246 static void dump_class_port_info(ib_class_port_info_t *cpi) 247 { 248 char gid_str[INET6_ADDRSTRLEN]; 249 char gid_str2[INET6_ADDRSTRLEN]; 250 251 printf("SA ClassPortInfo:\n" 252 "\t\tBase version.............%d\n" 253 "\t\tClass version............%d\n" 254 "\t\tCapability mask..........0x%04X\n" 255 "\t\tCapability mask 2........0x%08X\n" 256 "\t\tResponse time value......0x%02X\n" 257 "\t\tRedirect GID.............%s\n" 258 "\t\tRedirect TC/SL/FL........0x%08X\n" 259 "\t\tRedirect LID.............%u\n" 260 "\t\tRedirect PKey............0x%04X\n" 261 "\t\tRedirect QP..............0x%08X\n" 262 "\t\tRedirect QKey............0x%08X\n" 263 "\t\tTrap GID.................%s\n" 264 "\t\tTrap TC/SL/FL............0x%08X\n" 265 "\t\tTrap LID.................%u\n" 266 "\t\tTrap PKey................0x%04X\n" 267 "\t\tTrap HL/QP...............0x%08X\n" 268 "\t\tTrap QKey................0x%08X\n", 269 cpi->base_ver, cpi->class_ver, cl_ntoh16(cpi->cap_mask), 270 ib_class_cap_mask2(cpi), ib_class_resp_time_val(cpi), 271 inet_ntop(AF_INET6, &(cpi->redir_gid), gid_str, sizeof gid_str), 272 cl_ntoh32(cpi->redir_tc_sl_fl), cl_ntoh16(cpi->redir_lid), 273 cl_ntoh16(cpi->redir_pkey), cl_ntoh32(cpi->redir_qp), 274 cl_ntoh32(cpi->redir_qkey), 275 inet_ntop(AF_INET6, &(cpi->trap_gid), gid_str2, sizeof gid_str2), 276 cl_ntoh32(cpi->trap_tc_sl_fl), cl_ntoh16(cpi->trap_lid), 277 cl_ntoh16(cpi->trap_pkey), cl_ntoh32(cpi->trap_hop_qp), 278 cl_ntoh32(cpi->trap_qkey)); 279 } 280 281 static void dump_portinfo_record(void *data, struct query_params *p) 282 { 283 ib_portinfo_record_t *p_pir = data; 284 const ib_port_info_t *const p_pi = &p_pir->port_info; 285 286 printf("PortInfoRecord dump:\n" 287 "\t\tEndPortLid..............%u\n" 288 "\t\tPortNum.................%u\n" 289 "\t\tbase_lid................%u\n" 290 "\t\tmaster_sm_base_lid......%u\n" 291 "\t\tcapability_mask.........0x%X\n", 292 cl_ntoh16(p_pir->lid), p_pir->port_num, 293 cl_ntoh16(p_pi->base_lid), cl_ntoh16(p_pi->master_sm_base_lid), 294 cl_ntoh32(p_pi->capability_mask)); 295 } 296 297 static void dump_one_portinfo_record(void *data, struct query_params *p) 298 { 299 ib_portinfo_record_t *pir = data; 300 ib_port_info_t *pi = &pir->port_info; 301 302 printf("PortInfoRecord dump:\n" 303 "\tRID\n" 304 "\t\tEndPortLid..............%u\n" 305 "\t\tPortNum.................%u\n" 306 "\t\tOptions.................0x%x\n" 307 "\tPortInfo dump:\n", 308 cl_ntoh16(pir->lid), pir->port_num, pir->options); 309 dump_portinfo(pi, 2); 310 } 311 312 static void dump_one_mcmember_record(void *data, struct query_params *p) 313 { 314 char mgid[INET6_ADDRSTRLEN], gid[INET6_ADDRSTRLEN]; 315 ib_member_rec_t *mr = data; 316 uint32_t flow; 317 uint8_t sl, hop, scope, join; 318 ib_member_get_sl_flow_hop(mr->sl_flow_hop, &sl, &flow, &hop); 319 ib_member_get_scope_state(mr->scope_state, &scope, &join); 320 printf("MCMember Record dump:\n" 321 "\t\tMGID....................%s\n" 322 "\t\tPortGid.................%s\n" 323 "\t\tqkey....................0x%x\n" 324 "\t\tmlid....................0x%x\n" 325 "\t\tmtu.....................0x%x\n" 326 "\t\tTClass..................0x%x\n" 327 "\t\tpkey....................0x%x\n" 328 "\t\trate....................0x%x\n" 329 "\t\tpkt_life................0x%x\n" 330 "\t\tSL......................0x%x\n" 331 "\t\tFlowLabel...............0x%x\n" 332 "\t\tHopLimit................0x%x\n" 333 "\t\tScope...................0x%x\n" 334 "\t\tJoinState...............0x%x\n" 335 "\t\tProxyJoin...............0x%x\n", 336 inet_ntop(AF_INET6, mr->mgid.raw, mgid, sizeof(mgid)), 337 inet_ntop(AF_INET6, mr->port_gid.raw, gid, sizeof(gid)), 338 cl_ntoh32(mr->qkey), cl_ntoh16(mr->mlid), mr->mtu, mr->tclass, 339 cl_ntoh16(mr->pkey), mr->rate, mr->pkt_life, sl, 340 flow, hop, scope, join, mr->proxy_join); 341 } 342 343 static void dump_multicast_group_record(void *data, struct query_params *p) 344 { 345 char gid_str[INET6_ADDRSTRLEN]; 346 ib_member_rec_t *p_mcmr = data; 347 uint8_t sl; 348 ib_member_get_sl_flow_hop(p_mcmr->sl_flow_hop, &sl, NULL, NULL); 349 printf("MCMemberRecord group dump:\n" 350 "\t\tMGID....................%s\n" 351 "\t\tMlid....................0x%X\n" 352 "\t\tMtu.....................0x%X\n" 353 "\t\tpkey....................0x%X\n" 354 "\t\tRate....................0x%X\n" 355 "\t\tSL......................0x%X\n", 356 inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, sizeof gid_str), 357 cl_ntoh16(p_mcmr->mlid), 358 p_mcmr->mtu, cl_ntoh16(p_mcmr->pkey), p_mcmr->rate, sl); 359 } 360 361 static void dump_multicast_member_record(ib_member_rec_t *p_mcmr, 362 struct sa_query_result *nr_result, 363 struct query_params *params) 364 { 365 char gid_str[INET6_ADDRSTRLEN]; 366 char gid_str2[INET6_ADDRSTRLEN]; 367 uint16_t mlid = cl_ntoh16(p_mcmr->mlid); 368 unsigned i = 0; 369 char *node_name = strdup("<unknown>"); 370 371 /* go through the node records searching for a port guid which matches 372 * this port gid interface id. 373 * This gives us a node name to print, if available. 374 */ 375 for (i = 0; i < nr_result->result_cnt; i++) { 376 ib_node_record_t *nr = sa_get_query_rec(nr_result->p_result_madw, i); 377 if (nr->node_info.port_guid == 378 p_mcmr->port_gid.unicast.interface_id) { 379 if(node_name != NULL) 380 free(node_name); 381 node_name = remap_node_name(node_name_map, 382 nr->node_info.node_guid, 383 (char *)nr->node_desc.description); 384 break; 385 } 386 } 387 388 if (requested_name) { 389 if (strtol(requested_name, NULL, 0) == mlid) 390 printf("\t\tPortGid.................%s (%s)\n", 391 inet_ntop(AF_INET6, p_mcmr->port_gid.raw, 392 gid_str, sizeof gid_str), node_name); 393 } else { 394 printf("MCMemberRecord member dump:\n" 395 "\t\tMGID....................%s\n" 396 "\t\tMlid....................0x%X\n" 397 "\t\tPortGid.................%s\n" 398 "\t\tScopeState..............0x%X\n" 399 "\t\tProxyJoin...............0x%X\n" 400 "\t\tNodeDescription.........%s\n", 401 inet_ntop(AF_INET6, p_mcmr->mgid.raw, gid_str, 402 sizeof gid_str), 403 cl_ntoh16(p_mcmr->mlid), 404 inet_ntop(AF_INET6, p_mcmr->port_gid.raw, 405 gid_str2, sizeof gid_str2), 406 p_mcmr->scope_state, p_mcmr->proxy_join, node_name); 407 } 408 free(node_name); 409 } 410 411 static void dump_service_record(void *data, struct query_params *p) 412 { 413 char gid[INET6_ADDRSTRLEN]; 414 char buf_service_key[35]; 415 char buf_service_name[65]; 416 ib_service_record_t *p_sr = data; 417 418 sprintf(buf_service_key, 419 "0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", 420 p_sr->service_key[0], p_sr->service_key[1], 421 p_sr->service_key[2], p_sr->service_key[3], 422 p_sr->service_key[4], p_sr->service_key[5], 423 p_sr->service_key[6], p_sr->service_key[7], 424 p_sr->service_key[8], p_sr->service_key[9], 425 p_sr->service_key[10], p_sr->service_key[11], 426 p_sr->service_key[12], p_sr->service_key[13], 427 p_sr->service_key[14], p_sr->service_key[15]); 428 strncpy(buf_service_name, (char *)p_sr->service_name, 64); 429 buf_service_name[64] = '\0'; 430 431 printf("ServiceRecord dump:\n" 432 "\t\tServiceID...............0x%016" PRIx64 "\n" 433 "\t\tServiceGID..............%s\n" 434 "\t\tServiceP_Key............0x%X\n" 435 "\t\tServiceLease............0x%X\n" 436 "\t\tServiceKey..............%s\n" 437 "\t\tServiceName.............%s\n" 438 "\t\tServiceData8.1..........0x%X\n" 439 "\t\tServiceData8.2..........0x%X\n" 440 "\t\tServiceData8.3..........0x%X\n" 441 "\t\tServiceData8.4..........0x%X\n" 442 "\t\tServiceData8.5..........0x%X\n" 443 "\t\tServiceData8.6..........0x%X\n" 444 "\t\tServiceData8.7..........0x%X\n" 445 "\t\tServiceData8.8..........0x%X\n" 446 "\t\tServiceData8.9..........0x%X\n" 447 "\t\tServiceData8.10.........0x%X\n" 448 "\t\tServiceData8.11.........0x%X\n" 449 "\t\tServiceData8.12.........0x%X\n" 450 "\t\tServiceData8.13.........0x%X\n" 451 "\t\tServiceData8.14.........0x%X\n" 452 "\t\tServiceData8.15.........0x%X\n" 453 "\t\tServiceData8.16.........0x%X\n" 454 "\t\tServiceData16.1.........0x%X\n" 455 "\t\tServiceData16.2.........0x%X\n" 456 "\t\tServiceData16.3.........0x%X\n" 457 "\t\tServiceData16.4.........0x%X\n" 458 "\t\tServiceData16.5.........0x%X\n" 459 "\t\tServiceData16.6.........0x%X\n" 460 "\t\tServiceData16.7.........0x%X\n" 461 "\t\tServiceData16.8.........0x%X\n" 462 "\t\tServiceData32.1.........0x%X\n" 463 "\t\tServiceData32.2.........0x%X\n" 464 "\t\tServiceData32.3.........0x%X\n" 465 "\t\tServiceData32.4.........0x%X\n" 466 "\t\tServiceData64.1.........0x%016" PRIx64 "\n" 467 "\t\tServiceData64.2.........0x%016" PRIx64 "\n", 468 cl_ntoh64(p_sr->service_id), 469 inet_ntop(AF_INET6, p_sr->service_gid.raw, gid, sizeof gid), 470 cl_ntoh16(p_sr->service_pkey), cl_ntoh32(p_sr->service_lease), 471 (show_keys ? buf_service_key : NOT_DISPLAYED_STR), 472 buf_service_name, 473 p_sr->service_data8[0], p_sr->service_data8[1], 474 p_sr->service_data8[2], p_sr->service_data8[3], 475 p_sr->service_data8[4], p_sr->service_data8[5], 476 p_sr->service_data8[6], p_sr->service_data8[7], 477 p_sr->service_data8[8], p_sr->service_data8[9], 478 p_sr->service_data8[10], p_sr->service_data8[11], 479 p_sr->service_data8[12], p_sr->service_data8[13], 480 p_sr->service_data8[14], p_sr->service_data8[15], 481 cl_ntoh16(p_sr->service_data16[0]), 482 cl_ntoh16(p_sr->service_data16[1]), 483 cl_ntoh16(p_sr->service_data16[2]), 484 cl_ntoh16(p_sr->service_data16[3]), 485 cl_ntoh16(p_sr->service_data16[4]), 486 cl_ntoh16(p_sr->service_data16[5]), 487 cl_ntoh16(p_sr->service_data16[6]), 488 cl_ntoh16(p_sr->service_data16[7]), 489 cl_ntoh32(p_sr->service_data32[0]), 490 cl_ntoh32(p_sr->service_data32[1]), 491 cl_ntoh32(p_sr->service_data32[2]), 492 cl_ntoh32(p_sr->service_data32[3]), 493 cl_ntoh64(p_sr->service_data64[0]), 494 cl_ntoh64(p_sr->service_data64[1])); 495 } 496 497 static void dump_sm_info_record(void *data, struct query_params *p) 498 { 499 ib_sminfo_record_t *p_smr = data; 500 const ib_sm_info_t *const p_smi = &p_smr->sm_info; 501 uint8_t priority, state; 502 priority = ib_sminfo_get_priority(p_smi); 503 state = ib_sminfo_get_state(p_smi); 504 505 printf("SMInfoRecord dump:\n" 506 "\t\tRID\n" 507 "\t\tLID...................%u\n" 508 "\t\tSMInfo dump:\n" 509 "\t\tGUID..................0x%016" PRIx64 "\n" 510 "\t\tSM_Key................0x%016" PRIx64 "\n" 511 "\t\tActCount..............%u\n" 512 "\t\tPriority..............%u\n" 513 "\t\tSMState...............%u\n", 514 cl_ntoh16(p_smr->lid), 515 cl_ntoh64(p_smr->sm_info.guid), 516 cl_ntoh64(p_smr->sm_info.sm_key), 517 cl_ntoh32(p_smr->sm_info.act_count), 518 priority, state); 519 } 520 521 static void dump_switch_info_record(void *data, struct query_params *p) 522 { 523 ib_switch_info_record_t *p_sir = data; 524 uint32_t sa_cap_mask2 = ib_class_cap_mask2(&p->cpi); 525 526 printf("SwitchInfoRecord dump:\n" 527 "\t\tRID\n" 528 "\t\tLID.....................................%u\n" 529 "\t\tSwitchInfo dump:\n" 530 "\t\tLinearFDBCap............................0x%X\n" 531 "\t\tRandomFDBCap............................0x%X\n" 532 "\t\tMulticastFDBCap.........................0x%X\n" 533 "\t\tLinearFDBTop............................0x%X\n" 534 "\t\tDefaultPort.............................%u\n" 535 "\t\tDefaultMulticastPrimaryPort.............%u\n" 536 "\t\tDefaultMulticastNotPrimaryPort..........%u\n" 537 "\t\tLifeTimeValue/PortStateChange/OpSL2VL...0x%X\n" 538 "\t\tLIDsPerPort.............................0x%X\n" 539 "\t\tPartitionEnforcementCap.................0x%X\n" 540 "\t\tflags...................................0x%X\n", 541 cl_ntoh16(p_sir->lid), 542 cl_ntoh16(p_sir->switch_info.lin_cap), 543 cl_ntoh16(p_sir->switch_info.rand_cap), 544 cl_ntoh16(p_sir->switch_info.mcast_cap), 545 cl_ntoh16(p_sir->switch_info.lin_top), 546 p_sir->switch_info.def_port, 547 p_sir->switch_info.def_mcast_pri_port, 548 p_sir->switch_info.def_mcast_not_port, 549 p_sir->switch_info.life_state, 550 cl_ntoh16(p_sir->switch_info.lids_per_port), 551 cl_ntoh16(p_sir->switch_info.enforce_cap), 552 p_sir->switch_info.flags); 553 if (sa_cap_mask2 & UMAD_SA_CAP_MASK2_IS_MCAST_TOP_SUP) 554 printf("\t\tMulticastFDBTop.........................0x%X\n", 555 cl_ntoh16(p_sir->switch_info.mcast_top)); 556 } 557 558 static void dump_inform_info_record(void *data, struct query_params *p) 559 { 560 char gid_str[INET6_ADDRSTRLEN]; 561 char gid_str2[INET6_ADDRSTRLEN]; 562 ib_inform_info_record_t *p_iir = data; 563 uint32_t qpn; 564 uint8_t resp_time_val; 565 566 ib_inform_info_get_qpn_resp_time(p_iir->inform_info.g_or_v. 567 generic.qpn_resp_time_val, &qpn, 568 &resp_time_val); 569 if (p_iir->inform_info.is_generic) { 570 printf("InformInfoRecord dump:\n" 571 "\t\tRID\n" 572 "\t\tSubscriberGID...........%s\n" 573 "\t\tSubscriberEnum..........0x%X\n" 574 "\t\tInformInfo dump:\n" 575 "\t\tgid.....................%s\n" 576 "\t\tlid_range_begin.........%u\n" 577 "\t\tlid_range_end...........%u\n" 578 "\t\tis_generic..............0x%X\n" 579 "\t\tsubscribe...............0x%X\n" 580 "\t\ttrap_type...............0x%X\n" 581 "\t\ttrap_num................%u\n", 582 inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str, 583 sizeof gid_str), 584 cl_ntoh16(p_iir->subscriber_enum), 585 inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, gid_str2, 586 sizeof gid_str2), 587 cl_ntoh16(p_iir->inform_info.lid_range_begin), 588 cl_ntoh16(p_iir->inform_info.lid_range_end), 589 p_iir->inform_info.is_generic, 590 p_iir->inform_info.subscribe, 591 cl_ntoh16(p_iir->inform_info.trap_type), 592 cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num)); 593 if (show_keys) { 594 printf("\t\tqpn.....................0x%06X\n", 595 cl_ntoh32(qpn)); 596 } else { 597 printf("\t\tqpn....................." 598 NOT_DISPLAYED_STR "\n"); 599 } 600 printf("\t\tresp_time_val...........0x%X\n" 601 "\t\tnode_type...............0x%06X\n", 602 resp_time_val, 603 cl_ntoh32(ib_inform_info_get_prod_type 604 (&p_iir->inform_info))); 605 } else { 606 printf("InformInfoRecord dump:\n" 607 "\t\tRID\n" 608 "\t\tSubscriberGID...........%s\n" 609 "\t\tSubscriberEnum..........0x%X\n" 610 "\t\tInformInfo dump:\n" 611 "\t\tgid.....................%s\n" 612 "\t\tlid_range_begin.........%u\n" 613 "\t\tlid_range_end...........%u\n" 614 "\t\tis_generic..............0x%X\n" 615 "\t\tsubscribe...............0x%X\n" 616 "\t\ttrap_type...............0x%X\n" 617 "\t\tdev_id..................0x%X\n", 618 inet_ntop(AF_INET6, p_iir->subscriber_gid.raw, gid_str, 619 sizeof gid_str), 620 cl_ntoh16(p_iir->subscriber_enum), 621 inet_ntop(AF_INET6, p_iir->inform_info.gid.raw, 622 gid_str2, sizeof gid_str2), 623 cl_ntoh16(p_iir->inform_info.lid_range_begin), 624 cl_ntoh16(p_iir->inform_info.lid_range_end), 625 p_iir->inform_info.is_generic, 626 p_iir->inform_info.subscribe, 627 cl_ntoh16(p_iir->inform_info.trap_type), 628 cl_ntoh16(p_iir->inform_info.g_or_v.vend.dev_id)); 629 if (show_keys) { 630 printf("\t\tqpn.....................0x%06X\n", 631 cl_ntoh32(qpn)); 632 } else { 633 printf("\t\tqpn....................." 634 NOT_DISPLAYED_STR "\n"); 635 } 636 printf("\t\tresp_time_val...........0x%X\n" 637 "\t\tvendor_id...............0x%06X\n", 638 resp_time_val, 639 cl_ntoh32(ib_inform_info_get_prod_type 640 (&p_iir->inform_info))); 641 } 642 } 643 644 static void dump_one_link_record(void *data, struct query_params *p) 645 { 646 ib_link_record_t *lr = data; 647 printf("LinkRecord dump:\n" 648 "\t\tFromLID....................%u\n" 649 "\t\tFromPort...................%u\n" 650 "\t\tToPort.....................%u\n" 651 "\t\tToLID......................%u\n", 652 cl_ntoh16(lr->from_lid), lr->from_port_num, 653 lr->to_port_num, cl_ntoh16(lr->to_lid)); 654 } 655 656 static void dump_one_slvl_record(void *data, struct query_params *p) 657 { 658 ib_slvl_table_record_t *slvl = data; 659 ib_slvl_table_t *t = &slvl->slvl_tbl; 660 printf("SL2VLTableRecord dump:\n" 661 "\t\tLID........................%u\n" 662 "\t\tInPort.....................%u\n" 663 "\t\tOutPort....................%u\n" 664 "\t\tSL: 0| 1| 2| 3| 4| 5| 6| 7| 8| 9|10|11|12|13|14|15|\n" 665 "\t\tVL:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u" 666 "|%2u|%2u|%2u|\n", 667 cl_ntoh16(slvl->lid), slvl->in_port_num, slvl->out_port_num, 668 ib_slvl_table_get(t, 0), ib_slvl_table_get(t, 1), 669 ib_slvl_table_get(t, 2), ib_slvl_table_get(t, 3), 670 ib_slvl_table_get(t, 4), ib_slvl_table_get(t, 5), 671 ib_slvl_table_get(t, 6), ib_slvl_table_get(t, 7), 672 ib_slvl_table_get(t, 8), ib_slvl_table_get(t, 9), 673 ib_slvl_table_get(t, 10), ib_slvl_table_get(t, 11), 674 ib_slvl_table_get(t, 12), ib_slvl_table_get(t, 13), 675 ib_slvl_table_get(t, 14), ib_slvl_table_get(t, 15)); 676 } 677 678 static void dump_one_vlarb_record(void *data, struct query_params *p) 679 { 680 ib_vl_arb_table_record_t *vlarb = data; 681 ib_vl_arb_element_t *e = vlarb->vl_arb_tbl.vl_entry; 682 int i; 683 printf("VLArbTableRecord dump:\n" 684 "\t\tLID........................%u\n" 685 "\t\tPort.......................%u\n" 686 "\t\tBlock......................%u\n", 687 cl_ntoh16(vlarb->lid), vlarb->port_num, vlarb->block_num); 688 for (i = 0; i < 32; i += 16) 689 printf("\t\tVL :%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|" 690 "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|\n" 691 "\t\tWeight:%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|" 692 "%2u|%2u|%2u|%2u|%2u|%2u|%2u|%2u|\n", 693 e[i + 0].vl, e[i + 1].vl, e[i + 2].vl, e[i + 3].vl, 694 e[i + 4].vl, e[i + 5].vl, e[i + 6].vl, e[i + 7].vl, 695 e[i + 8].vl, e[i + 9].vl, e[i + 10].vl, e[i + 11].vl, 696 e[i + 12].vl, e[i + 13].vl, e[i + 14].vl, e[i + 15].vl, 697 e[i + 0].weight, e[i + 1].weight, e[i + 2].weight, 698 e[i + 3].weight, e[i + 4].weight, e[i + 5].weight, 699 e[i + 6].weight, e[i + 7].weight, e[i + 8].weight, 700 e[i + 9].weight, e[i + 10].weight, e[i + 11].weight, 701 e[i + 12].weight, e[i + 13].weight, e[i + 14].weight, 702 e[i + 15].weight); 703 } 704 705 static void dump_one_pkey_tbl_record(void *data, struct query_params *params) 706 { 707 ib_pkey_table_record_t *pktr = data; 708 ib_net16_t *p = pktr->pkey_tbl.pkey_entry; 709 int i; 710 printf("PKeyTableRecord dump:\n" 711 "\t\tLID........................%u\n" 712 "\t\tPort.......................%u\n" 713 "\t\tBlock......................%u\n" 714 "\t\tPKey Table:\n", 715 cl_ntoh16(pktr->lid), pktr->port_num, pktr->block_num); 716 for (i = 0; i < 32; i += 8) 717 printf("\t\t0x%04x 0x%04x 0x%04x 0x%04x" 718 " 0x%04x 0x%04x 0x%04x 0x%04x\n", 719 cl_ntoh16(p[i + 0]), cl_ntoh16(p[i + 1]), 720 cl_ntoh16(p[i + 2]), cl_ntoh16(p[i + 3]), 721 cl_ntoh16(p[i + 4]), cl_ntoh16(p[i + 5]), 722 cl_ntoh16(p[i + 6]), cl_ntoh16(p[i + 7])); 723 printf("\n"); 724 } 725 726 static void dump_one_lft_record(void *data, struct query_params *p) 727 { 728 ib_lft_record_t *lftr = data; 729 unsigned block = cl_ntoh16(lftr->block_num); 730 int i; 731 printf("LFT Record dump:\n" 732 "\t\tLID........................%u\n" 733 "\t\tBlock......................%u\n" 734 "\t\tLFT:\n\t\tLID\tPort Number\n", cl_ntoh16(lftr->lid), block); 735 for (i = 0; i < 64; i++) 736 printf("\t\t%u\t%u\n", block * 64 + i, lftr->lft[i]); 737 printf("\n"); 738 } 739 740 static void dump_one_guidinfo_record(void *data, struct query_params *p) 741 { 742 ib_guidinfo_record_t *gir = data; 743 printf("GUIDInfo Record dump:\n" 744 "\t\tLID........................%u\n" 745 "\t\tBlock......................%u\n" 746 "\t\tGUID 0.....................0x%016" PRIx64 "\n" 747 "\t\tGUID 1.....................0x%016" PRIx64 "\n" 748 "\t\tGUID 2.....................0x%016" PRIx64 "\n" 749 "\t\tGUID 3.....................0x%016" PRIx64 "\n" 750 "\t\tGUID 4.....................0x%016" PRIx64 "\n" 751 "\t\tGUID 5.....................0x%016" PRIx64 "\n" 752 "\t\tGUID 6.....................0x%016" PRIx64 "\n" 753 "\t\tGUID 7.....................0x%016" PRIx64 "\n", 754 cl_ntoh16(gir->lid), gir->block_num, 755 cl_ntoh64(gir->guid_info.guid[0]), 756 cl_ntoh64(gir->guid_info.guid[1]), 757 cl_ntoh64(gir->guid_info.guid[2]), 758 cl_ntoh64(gir->guid_info.guid[3]), 759 cl_ntoh64(gir->guid_info.guid[4]), 760 cl_ntoh64(gir->guid_info.guid[5]), 761 cl_ntoh64(gir->guid_info.guid[6]), 762 cl_ntoh64(gir->guid_info.guid[7])); 763 } 764 765 static void dump_one_mft_record(void *data, struct query_params *p) 766 { 767 ib_mft_record_t *mftr = data; 768 unsigned position = cl_ntoh16(mftr->position_block_num) >> 12; 769 unsigned block = cl_ntoh16(mftr->position_block_num) & 770 IB_MCAST_BLOCK_ID_MASK_HO; 771 int i; 772 unsigned offset; 773 774 printf("MFT Record dump:\n" 775 "\t\tLID........................%u\n" 776 "\t\tPosition...................%u\n" 777 "\t\tBlock......................%u\n" 778 "\t\tMFT:\n\t\tMLID\tPort Mask\n", 779 cl_ntoh16(mftr->lid), position, block); 780 offset = IB_LID_MCAST_START_HO + block * 32; 781 for (i = 0; i < IB_MCAST_BLOCK_SIZE; i++) 782 printf("\t\t0x%04x\t0x%04x\n", 783 offset + i, cl_ntoh16(mftr->mft[i])); 784 printf("\n"); 785 } 786 787 static void dump_results(struct sa_query_result *r, 788 void (*dump_func) (void *, struct query_params *), 789 struct query_params *p) 790 { 791 unsigned i; 792 for (i = 0; i < r->result_cnt; i++) { 793 void *data = sa_get_query_rec(r->p_result_madw, i); 794 dump_func(data, p); 795 } 796 } 797 798 /** 799 * Get any record(s) 800 */ 801 static int get_any_records(struct sa_handle * h, 802 uint16_t attr_id, uint32_t attr_mod, 803 ib_net64_t comp_mask, void *attr, 804 size_t attr_size, 805 struct sa_query_result *result) 806 { 807 int ret = sa_query(h, IB_MAD_METHOD_GET_TABLE, attr_id, attr_mod, 808 cl_ntoh64(comp_mask), ibd_sakey, attr, attr_size, result); 809 if (ret) { 810 fprintf(stderr, "Query SA failed: %s\n", strerror(ret)); 811 return ret; 812 } 813 814 if (result->status != IB_SA_MAD_STATUS_SUCCESS) { 815 sa_report_err(result->status); 816 return EIO; 817 } 818 819 return ret; 820 } 821 822 static int get_and_dump_any_records(struct sa_handle * h, uint16_t attr_id, 823 uint32_t attr_mod, ib_net64_t comp_mask, 824 void *attr, 825 size_t attr_size, 826 void (*dump_func) (void *, 827 struct query_params *), 828 struct query_params *p) 829 { 830 struct sa_query_result result; 831 int ret = get_any_records(h, attr_id, attr_mod, comp_mask, attr, 832 attr_size, &result); 833 if (ret) 834 return ret; 835 836 dump_results(&result, dump_func, p); 837 sa_free_result_mad(&result); 838 return 0; 839 } 840 841 /** 842 * Get all the records available for requested query type. 843 */ 844 static int get_all_records(struct sa_handle * h, uint16_t attr_id, 845 struct sa_query_result *result) 846 { 847 return get_any_records(h, attr_id, 0, 0, NULL, 0, result); 848 } 849 850 static int get_and_dump_all_records(struct sa_handle * h, uint16_t attr_id, 851 void (*dump_func) (void *, 852 struct query_params *p), 853 struct query_params *p) 854 { 855 struct sa_query_result result; 856 int ret = get_all_records(h, attr_id, &result); 857 if (ret) 858 return ret; 859 860 dump_results(&result, dump_func, p); 861 sa_free_result_mad(&result); 862 return ret; 863 } 864 865 /** 866 * return the lid from the node descriptor (name) supplied 867 */ 868 static int get_lid_from_name(struct sa_handle * h, const char *name, uint16_t * lid) 869 { 870 ib_node_record_t *node_record = NULL; 871 unsigned i; 872 int ret; 873 struct sa_query_result result; 874 875 ret = get_all_records(h, IB_SA_ATTR_NODERECORD, &result); 876 if (ret) 877 return ret; 878 879 ret = EHOSTDOWN; 880 for (i = 0; i < result.result_cnt; i++) { 881 node_record = sa_get_query_rec(result.p_result_madw, i); 882 if (name 883 && strncmp(name, (char *)node_record->node_desc.description, 884 sizeof(node_record->node_desc.description)) == 885 0) { 886 *lid = cl_ntoh16(node_record->lid); 887 ret = 0; 888 break; 889 } 890 } 891 sa_free_result_mad(&result); 892 return ret; 893 } 894 895 static uint16_t get_lid(struct sa_handle * h, const char *name) 896 { 897 int rc = 0; 898 uint16_t rc_lid = 0; 899 900 if (!name) 901 return 0; 902 if (isalpha(name[0])) { 903 if ((rc = get_lid_from_name(h, name, &rc_lid)) != 0) { 904 fprintf(stderr, "Failed to find lid for \"%s\": %s\n", 905 name, strerror(rc)); 906 exit(rc); 907 } 908 } else { 909 long val; 910 errno = 0; 911 val = strtol(name, NULL, 0); 912 if (errno != 0 || val <= 0 || val > UINT16_MAX) { 913 fprintf(stderr, "Invalid lid specified: \"%s\"\n", name); 914 exit(EINVAL); 915 } 916 rc_lid = (uint16_t)val; 917 } 918 919 return rc_lid; 920 } 921 922 static int parse_iir_subscriber_gid(char *str, ib_inform_info_record_t *ir) 923 { 924 int rc = inet_pton(AF_INET6,str,&(ir->subscriber_gid.raw)); 925 if(rc < 1){ 926 fprintf(stderr, "Invalid SubscriberGID specified: \"%s\"\n",str); 927 exit(EINVAL); 928 } 929 return rc; 930 } 931 932 static int parse_lid_and_ports(struct sa_handle * h, 933 char *str, int *lid, int *port1, int *port2) 934 { 935 char *p, *e; 936 937 if (port1) 938 *port1 = -1; 939 if (port2) 940 *port2 = -1; 941 942 p = strchr(str, '/'); 943 if (p) 944 *p = '\0'; 945 if (lid) 946 *lid = get_lid(h, str); 947 948 if (!p) 949 return 0; 950 str = p + 1; 951 p = strchr(str, '/'); 952 if (p) 953 *p = '\0'; 954 if (port1) { 955 *port1 = strtoul(str, &e, 0); 956 if (e == str) 957 *port1 = -1; 958 } 959 960 if (!p) 961 return 0; 962 str = p + 1; 963 if (port2) { 964 *port2 = strtoul(str, &e, 0); 965 if (e == str) 966 *port2 = -1; 967 } 968 969 return 0; 970 } 971 972 /* 973 * Get the portinfo records available with IsSM or IsSMdisabled CapabilityMask bit on. 974 */ 975 static int get_issm_records(struct sa_handle * h, ib_net32_t capability_mask, 976 struct sa_query_result *result) 977 { 978 ib_portinfo_record_t attr; 979 980 memset(&attr, 0, sizeof(attr)); 981 attr.port_info.capability_mask = capability_mask; 982 983 return get_any_records(h, IB_SA_ATTR_PORTINFORECORD, 1 << 31, 984 IB_PIR_COMPMASK_CAPMASK, &attr, sizeof(attr), result); 985 } 986 987 static int print_node_records(struct sa_handle * h, struct query_params *p) 988 { 989 unsigned i; 990 int ret; 991 struct sa_query_result result; 992 993 ret = get_all_records(h, IB_SA_ATTR_NODERECORD, &result); 994 if (ret) 995 return ret; 996 997 if (node_print_desc == ALL_DESC) { 998 printf(" LID \"name\"\n"); 999 printf("================\n"); 1000 } 1001 for (i = 0; i < result.result_cnt; i++) { 1002 ib_node_record_t *node_record; 1003 node_record = sa_get_query_rec(result.p_result_madw, i); 1004 if (node_print_desc == ALL_DESC) { 1005 print_node_desc(node_record); 1006 } else if (node_print_desc == NAME_OF_LID) { 1007 if (requested_lid == cl_ntoh16(node_record->lid)) 1008 print_node_record(node_record); 1009 } else if (node_print_desc == NAME_OF_GUID) { 1010 ib_node_info_t *p_ni = &(node_record->node_info); 1011 1012 if (requested_guid == cl_ntoh64(p_ni->port_guid)) 1013 print_node_record(node_record); 1014 } else { 1015 ib_node_info_t *p_ni = &(node_record->node_info); 1016 ib_node_desc_t *p_nd = &(node_record->node_desc); 1017 char *name; 1018 1019 name = remap_node_name (node_name_map, 1020 cl_ntoh64(p_ni->node_guid), 1021 (char *)p_nd->description); 1022 1023 if (!requested_name || 1024 (strncmp(requested_name, 1025 (char *)node_record->node_desc.description, 1026 sizeof(node_record-> 1027 node_desc.description)) == 0) || 1028 (strncmp(requested_name, 1029 name, 1030 sizeof(node_record-> 1031 node_desc.description)) == 0)) { 1032 print_node_record(node_record); 1033 if (node_print_desc == UNIQUE_LID_ONLY) { 1034 sa_free_result_mad(&result); 1035 exit(0); 1036 } 1037 } 1038 1039 free(name); 1040 } 1041 } 1042 sa_free_result_mad(&result); 1043 return ret; 1044 } 1045 1046 static int sm_pr_query(struct sa_handle * h, ibmad_gid_t *gid, int srclid, int destlid) { 1047 1048 ib_path_rec_t pr; 1049 ib_net64_t comp_mask = 0; 1050 struct sa_query_result result; 1051 int ret; 1052 ib_path_rec_t *p_pr; 1053 1054 memset(&pr, 0, sizeof(pr)); 1055 CHECK_AND_SET_VAL(srclid, 16, 0, pr.slid, PR, SLID); 1056 CHECK_AND_SET_VAL(destlid, 16, 0, pr.dlid, PR, DLID); 1057 1058 ret = get_any_records(h, IB_SA_ATTR_PATHRECORD, 0, comp_mask, &pr, sizeof(pr), &result); 1059 if (ret) 1060 return ret; 1061 1062 p_pr = sa_get_query_rec(result.p_result_madw, 0); 1063 memcpy(gid, &p_pr->dgid, 16); 1064 sa_free_result_mad(&result); 1065 return ret; 1066 } 1067 1068 static int query_path_records(const struct query_cmd *q, struct sa_handle * h, 1069 struct query_params *p, int argc, char *argv[]) 1070 { 1071 ib_path_rec_t pr; 1072 ib_net64_t comp_mask = 0; 1073 uint32_t flow = 0; 1074 uint16_t qos_class = 0; 1075 uint8_t reversible = 0; 1076 1077 memset(&pr, 0, sizeof(pr)); 1078 CHECK_AND_SET_VAL(p->service_id, 64, 0, pr.service_id, PR, SERVICEID); 1079 CHECK_AND_SET_GID(p->sgid, pr.sgid, PR, SGID); 1080 CHECK_AND_SET_GID(p->dgid, pr.dgid, PR, DGID); 1081 CHECK_AND_SET_VAL(p->slid, 16, 0, pr.slid, PR, SLID); 1082 CHECK_AND_SET_VAL(p->dlid, 16, 0, pr.dlid, PR, DLID); 1083 CHECK_AND_SET_VAL(p->hop_limit, 32, -1, pr.hop_flow_raw, PR, HOPLIMIT); 1084 CHECK_AND_SET_VAL((p->flow_label << 8), 32, 0, flow, PR, FLOWLABEL); 1085 pr.hop_flow_raw = 1086 (pr.hop_flow_raw & cl_hton32(~0x0FFFFF00)) | flow; 1087 CHECK_AND_SET_VAL(p->tclass, 8, 0, pr.tclass, PR, TCLASS); 1088 CHECK_AND_SET_VAL(p->reversible, 8, -1, reversible, PR, REVERSIBLE); 1089 CHECK_AND_SET_VAL(p->numb_path, 8, -1, pr.num_path, PR, NUMBPATH); 1090 pr.num_path |= reversible << 7; 1091 CHECK_AND_SET_VAL(p->pkey, 16, 0, pr.pkey, PR, PKEY); 1092 CHECK_AND_SET_VAL(p->sl, 16, -1, pr.qos_class_sl, PR, SL); 1093 CHECK_AND_SET_VAL((p->qos_class << 4), 16, -1, qos_class, PR, QOS_CLASS); 1094 pr.qos_class_sl = (pr.qos_class_sl & CL_HTON16(IB_PATH_REC_SL_MASK)) | 1095 qos_class; 1096 CHECK_AND_SET_VAL_AND_SEL(p->mtu, pr.mtu, PR, MTU, SELEC); 1097 CHECK_AND_SET_VAL_AND_SEL(p->rate, pr.rate, PR, RATE, SELEC); 1098 CHECK_AND_SET_VAL_AND_SEL(p->pkt_life, pr.pkt_life, PR, PKTLIFETIME, 1099 SELEC); 1100 1101 return get_and_dump_any_records(h, IB_SA_ATTR_PATHRECORD, 0, comp_mask, 1102 &pr, sizeof(pr), dump_path_record, p); 1103 } 1104 1105 static int print_issm_records(struct sa_handle * h, struct query_params *p) 1106 { 1107 struct sa_query_result result; 1108 int ret = 0; 1109 1110 /* First, get IsSM records */ 1111 ret = get_issm_records(h, IB_PORT_CAP_IS_SM, &result); 1112 if (ret != 0) 1113 return (ret); 1114 1115 printf("IsSM ports\n"); 1116 dump_results(&result, dump_portinfo_record, p); 1117 sa_free_result_mad(&result); 1118 1119 /* Now, get IsSMdisabled records */ 1120 ret = get_issm_records(h, IB_PORT_CAP_SM_DISAB, &result); 1121 if (ret != 0) 1122 return (ret); 1123 1124 printf("\nIsSMdisabled ports\n"); 1125 dump_results(&result, dump_portinfo_record, p); 1126 sa_free_result_mad(&result); 1127 1128 return (ret); 1129 } 1130 1131 static int print_multicast_member_records(struct sa_handle * h, 1132 struct query_params *params) 1133 { 1134 struct sa_query_result mc_group_result; 1135 struct sa_query_result nr_result; 1136 int ret; 1137 unsigned i; 1138 1139 ret = get_all_records(h, IB_SA_ATTR_MCRECORD, &mc_group_result); 1140 if (ret) 1141 return ret; 1142 1143 ret = get_all_records(h, IB_SA_ATTR_NODERECORD, &nr_result); 1144 if (ret) 1145 goto return_mc; 1146 1147 for (i = 0; i < mc_group_result.result_cnt; i++) { 1148 ib_member_rec_t *rec = (ib_member_rec_t *) 1149 sa_get_query_rec(mc_group_result.p_result_madw, 1150 i); 1151 dump_multicast_member_record(rec, &nr_result, params); 1152 } 1153 1154 sa_free_result_mad(&nr_result); 1155 1156 return_mc: 1157 sa_free_result_mad(&mc_group_result); 1158 1159 return ret; 1160 } 1161 1162 static int print_multicast_group_records(struct sa_handle * h, 1163 struct query_params *p) 1164 { 1165 return get_and_dump_all_records(h, IB_SA_ATTR_MCRECORD, 1166 dump_multicast_group_record, p); 1167 } 1168 1169 static int query_class_port_info(const struct query_cmd *q, struct sa_handle * h, 1170 struct query_params *p, int argc, char *argv[]) 1171 { 1172 dump_class_port_info(&p->cpi); 1173 return (0); 1174 } 1175 1176 static int query_node_records(const struct query_cmd *q, struct sa_handle * h, 1177 struct query_params *p, int argc, char *argv[]) 1178 { 1179 ib_node_record_t nr; 1180 ib_net64_t comp_mask = 0; 1181 int lid = 0; 1182 1183 if (argc > 0) 1184 parse_lid_and_ports(h, argv[0], &lid, NULL, NULL); 1185 1186 memset(&nr, 0, sizeof(nr)); 1187 CHECK_AND_SET_VAL(lid, 16, 0, nr.lid, NR, LID); 1188 1189 return get_and_dump_any_records(h, IB_SA_ATTR_NODERECORD, 0, comp_mask, 1190 &nr, sizeof(nr), dump_node_record, p); 1191 } 1192 1193 static int query_portinfo_records(const struct query_cmd *q, 1194 struct sa_handle * h, struct query_params *p, 1195 int argc, char *argv[]) 1196 { 1197 ib_portinfo_record_t pir; 1198 ib_net64_t comp_mask = 0; 1199 int lid = 0, port = -1, options = -1; 1200 1201 if (argc > 0) 1202 parse_lid_and_ports(h, argv[0], &lid, &port, &options); 1203 1204 memset(&pir, 0, sizeof(pir)); 1205 CHECK_AND_SET_VAL(lid, 16, 0, pir.lid, PIR, LID); 1206 CHECK_AND_SET_VAL(port, 8, -1, pir.port_num, PIR, PORTNUM); 1207 CHECK_AND_SET_VAL(options, 8, -1, pir.options, PIR, OPTIONS); 1208 1209 return get_and_dump_any_records(h, IB_SA_ATTR_PORTINFORECORD, 0, 1210 comp_mask, &pir, sizeof(pir), 1211 dump_one_portinfo_record, p); 1212 } 1213 1214 static int query_mcmember_records(const struct query_cmd *q, 1215 struct sa_handle * h, struct query_params *p, 1216 int argc, char *argv[]) 1217 { 1218 ib_member_rec_t mr; 1219 ib_net64_t comp_mask = 0; 1220 uint32_t flow = 0; 1221 uint8_t sl = 0, hop = 0, scope = 0; 1222 1223 memset(&mr, 0, sizeof(mr)); 1224 CHECK_AND_SET_GID(p->mgid, mr.mgid, MCR, MGID); 1225 CHECK_AND_SET_GID(p->gid, mr.port_gid, MCR, PORT_GID); 1226 CHECK_AND_SET_VAL(p->mlid, 16, 0, mr.mlid, MCR, MLID); 1227 CHECK_AND_SET_VAL(p->qkey, 32, 0, mr.qkey, MCR, QKEY); 1228 CHECK_AND_SET_VAL_AND_SEL(p->mtu, mr.mtu, MCR, MTU, _SEL); 1229 CHECK_AND_SET_VAL_AND_SEL(p->rate, mr.rate, MCR, RATE, _SEL); 1230 CHECK_AND_SET_VAL_AND_SEL(p->pkt_life, mr.pkt_life, MCR, LIFE, _SEL); 1231 CHECK_AND_SET_VAL(p->tclass, 8, 0, mr.tclass, MCR, TCLASS); 1232 CHECK_AND_SET_VAL(p->pkey, 16, 0, mr.pkey, MCR, PKEY); 1233 CHECK_AND_SET_VAL(p->sl, 8, -1, sl, MCR, SL); 1234 CHECK_AND_SET_VAL(p->flow_label, 32, 0, flow, MCR, FLOW); 1235 CHECK_AND_SET_VAL(p->hop_limit, 8, 0, hop, MCR, HOP); 1236 /* pass flow in host order as expected by function */ 1237 mr.sl_flow_hop = ib_member_set_sl_flow_hop(sl, cl_ntoh32(flow), hop); 1238 CHECK_AND_SET_VAL(p->scope, 8, 0, scope, MCR, SCOPE); 1239 CHECK_AND_SET_VAL(p->join_state, 8, 0, mr.scope_state, MCR, JOIN_STATE); 1240 mr.scope_state |= scope << 4; 1241 CHECK_AND_SET_VAL(p->proxy_join, 8, -1, mr.proxy_join, MCR, PROXY); 1242 1243 return get_and_dump_any_records(h, IB_SA_ATTR_MCRECORD, 0, comp_mask, 1244 &mr, sizeof(mr), dump_one_mcmember_record, p); 1245 } 1246 1247 static int query_service_records(const struct query_cmd *q, struct sa_handle * h, 1248 struct query_params *p, int argc, char *argv[]) 1249 { 1250 return get_and_dump_all_records(h, IB_SA_ATTR_SERVICERECORD, 1251 dump_service_record, p); 1252 } 1253 1254 static int query_sm_info_records(const struct query_cmd *q, 1255 struct sa_handle * h, struct query_params *p, 1256 int argc, char *argv[]) 1257 { 1258 ib_sminfo_record_t smir; 1259 ib_net64_t comp_mask = 0; 1260 int lid = 0; 1261 1262 if (argc > 0) 1263 parse_lid_and_ports(h, argv[0], &lid, NULL, NULL); 1264 1265 memset(&smir, 0, sizeof(smir)); 1266 CHECK_AND_SET_VAL(lid, 16, 0, smir.lid, SMIR, LID); 1267 1268 return get_and_dump_any_records(h, IB_SA_ATTR_SMINFORECORD, 0, 1269 comp_mask, &smir, sizeof(smir), 1270 dump_sm_info_record, p); 1271 } 1272 1273 static int query_switchinfo_records(const struct query_cmd *q, 1274 struct sa_handle * h, struct query_params *p, 1275 int argc, char *argv[]) 1276 { 1277 ib_switch_info_record_t swir; 1278 ib_net64_t comp_mask = 0; 1279 int lid = 0; 1280 1281 if (argc > 0) 1282 parse_lid_and_ports(h, argv[0], &lid, NULL, NULL); 1283 1284 memset(&swir, 0, sizeof(swir)); 1285 CHECK_AND_SET_VAL(lid, 16, 0, swir.lid, SWIR, LID); 1286 1287 return get_and_dump_any_records(h, IB_SA_ATTR_SWITCHINFORECORD, 0, 1288 comp_mask, &swir, sizeof(swir), 1289 dump_switch_info_record, p); 1290 } 1291 1292 static int query_inform_info_records(const struct query_cmd *q, 1293 struct sa_handle * h, struct query_params *p, 1294 int argc, char *argv[]) 1295 { 1296 int rc = 0; 1297 ib_inform_info_record_t ir; 1298 ib_net64_t comp_mask = 0; 1299 memset(&ir, 0, sizeof(ir)); 1300 1301 if (argc > 0) { 1302 comp_mask = IB_IIR_COMPMASK_SUBSCRIBERGID; 1303 if((rc = parse_iir_subscriber_gid(argv[0], &ir)) < 1) 1304 return rc; 1305 } 1306 1307 return get_and_dump_any_records(h, IB_SA_ATTR_INFORMINFORECORD, 0, comp_mask, 1308 &ir, sizeof(ir), dump_inform_info_record, p); 1309 1310 } 1311 1312 static int query_link_records(const struct query_cmd *q, struct sa_handle * h, 1313 struct query_params *p, int argc, char *argv[]) 1314 { 1315 ib_link_record_t lr; 1316 ib_net64_t comp_mask = 0; 1317 int from_lid = 0, to_lid = 0, from_port = -1, to_port = -1; 1318 1319 if (argc > 0) 1320 parse_lid_and_ports(h, argv[0], &from_lid, &from_port, NULL); 1321 1322 if (argc > 1) 1323 parse_lid_and_ports(h, argv[1], &to_lid, &to_port, NULL); 1324 1325 memset(&lr, 0, sizeof(lr)); 1326 CHECK_AND_SET_VAL(from_lid, 16, 0, lr.from_lid, LR, FROM_LID); 1327 CHECK_AND_SET_VAL(from_port, 8, -1, lr.from_port_num, LR, FROM_PORT); 1328 CHECK_AND_SET_VAL(to_lid, 16, 0, lr.to_lid, LR, TO_LID); 1329 CHECK_AND_SET_VAL(to_port, 8, -1, lr.to_port_num, LR, TO_PORT); 1330 1331 return get_and_dump_any_records(h, IB_SA_ATTR_LINKRECORD, 0, comp_mask, 1332 &lr, sizeof(lr), dump_one_link_record, p); 1333 } 1334 1335 static int query_sl2vl_records(const struct query_cmd *q, struct sa_handle * h, 1336 struct query_params *p, int argc, char *argv[]) 1337 { 1338 ib_slvl_table_record_t slvl; 1339 ib_net64_t comp_mask = 0; 1340 int lid = 0, in_port = -1, out_port = -1; 1341 1342 if (argc > 0) 1343 parse_lid_and_ports(h, argv[0], &lid, &in_port, &out_port); 1344 1345 memset(&slvl, 0, sizeof(slvl)); 1346 CHECK_AND_SET_VAL(lid, 16, 0, slvl.lid, SLVL, LID); 1347 CHECK_AND_SET_VAL(in_port, 8, -1, slvl.in_port_num, SLVL, IN_PORT); 1348 CHECK_AND_SET_VAL(out_port, 8, -1, slvl.out_port_num, SLVL, OUT_PORT); 1349 1350 return get_and_dump_any_records(h, IB_SA_ATTR_SL2VLTABLERECORD, 0, 1351 comp_mask, &slvl, sizeof(slvl), 1352 dump_one_slvl_record, p); 1353 } 1354 1355 static int query_vlarb_records(const struct query_cmd *q, struct sa_handle * h, 1356 struct query_params *p, int argc, char *argv[]) 1357 { 1358 ib_vl_arb_table_record_t vlarb; 1359 ib_net64_t comp_mask = 0; 1360 int lid = 0, port = -1, block = -1; 1361 1362 if (argc > 0) 1363 parse_lid_and_ports(h, argv[0], &lid, &port, &block); 1364 1365 memset(&vlarb, 0, sizeof(vlarb)); 1366 CHECK_AND_SET_VAL(lid, 16, 0, vlarb.lid, VLA, LID); 1367 CHECK_AND_SET_VAL(port, 8, -1, vlarb.port_num, VLA, OUT_PORT); 1368 CHECK_AND_SET_VAL(block, 8, -1, vlarb.block_num, VLA, BLOCK); 1369 1370 return get_and_dump_any_records(h, IB_SA_ATTR_VLARBTABLERECORD, 0, 1371 comp_mask, &vlarb, sizeof(vlarb), 1372 dump_one_vlarb_record, p); 1373 } 1374 1375 static int query_pkey_tbl_records(const struct query_cmd *q, 1376 struct sa_handle * h, struct query_params *p, 1377 int argc, char *argv[]) 1378 { 1379 ib_pkey_table_record_t pktr; 1380 ib_net64_t comp_mask = 0; 1381 int lid = 0, port = -1, block = -1; 1382 1383 if (argc > 0) 1384 parse_lid_and_ports(h, argv[0], &lid, &port, &block); 1385 1386 memset(&pktr, 0, sizeof(pktr)); 1387 CHECK_AND_SET_VAL(lid, 16, 0, pktr.lid, PKEY, LID); 1388 CHECK_AND_SET_VAL(port, 8, -1, pktr.port_num, PKEY, PORT); 1389 CHECK_AND_SET_VAL(block, 16, -1, pktr.block_num, PKEY, BLOCK); 1390 1391 return get_and_dump_any_records(h, IB_SA_ATTR_PKEYTABLERECORD, 0, 1392 comp_mask, &pktr, sizeof(pktr), 1393 dump_one_pkey_tbl_record, p); 1394 } 1395 1396 static int query_lft_records(const struct query_cmd *q, struct sa_handle * h, 1397 struct query_params *p, int argc, char *argv[]) 1398 { 1399 ib_lft_record_t lftr; 1400 ib_net64_t comp_mask = 0; 1401 int lid = 0, block = -1; 1402 1403 if (argc > 0) 1404 parse_lid_and_ports(h, argv[0], &lid, &block, NULL); 1405 1406 memset(&lftr, 0, sizeof(lftr)); 1407 CHECK_AND_SET_VAL(lid, 16, 0, lftr.lid, LFTR, LID); 1408 CHECK_AND_SET_VAL(block, 16, -1, lftr.block_num, LFTR, BLOCK); 1409 1410 return get_and_dump_any_records(h, IB_SA_ATTR_LFTRECORD, 0, comp_mask, 1411 &lftr, sizeof(lftr), dump_one_lft_record, p); 1412 } 1413 1414 static int query_guidinfo_records(const struct query_cmd *q, struct sa_handle * h, 1415 struct query_params *p, int argc, char *argv[]) 1416 { 1417 ib_guidinfo_record_t gir; 1418 ib_net64_t comp_mask = 0; 1419 int lid = 0, block = -1; 1420 1421 if (argc > 0) 1422 parse_lid_and_ports(h, argv[0], &lid, &block, NULL); 1423 1424 memset(&gir, 0, sizeof(gir)); 1425 CHECK_AND_SET_VAL(lid, 16, 0, gir.lid, GIR, LID); 1426 CHECK_AND_SET_VAL(block, 8, -1, gir.block_num, GIR, BLOCKNUM); 1427 1428 return get_and_dump_any_records(h, IB_SA_ATTR_GUIDINFORECORD, 0, 1429 comp_mask, &gir, sizeof(gir), 1430 dump_one_guidinfo_record, p); 1431 } 1432 1433 static int query_mft_records(const struct query_cmd *q, struct sa_handle * h, 1434 struct query_params *p, int argc, char *argv[]) 1435 { 1436 ib_mft_record_t mftr; 1437 ib_net64_t comp_mask = 0; 1438 int lid = 0, block = -1, position = -1; 1439 uint16_t pos = 0; 1440 1441 if (argc > 0) 1442 parse_lid_and_ports(h, argv[0], &lid, &position, &block); 1443 1444 memset(&mftr, 0, sizeof(mftr)); 1445 CHECK_AND_SET_VAL(lid, 16, 0, mftr.lid, MFTR, LID); 1446 CHECK_AND_SET_VAL(block, 16, -1, mftr.position_block_num, MFTR, BLOCK); 1447 mftr.position_block_num &= cl_hton16(IB_MCAST_BLOCK_ID_MASK_HO); 1448 CHECK_AND_SET_VAL(position, 8, -1, pos, MFTR, POSITION); 1449 mftr.position_block_num |= cl_hton16(pos << 12); 1450 1451 return get_and_dump_any_records(h, IB_SA_ATTR_MFTRECORD, 0, comp_mask, 1452 &mftr, sizeof(mftr), dump_one_mft_record, p); 1453 } 1454 1455 static int query_sa_cpi(struct sa_handle *h, struct query_params *query_params) 1456 { 1457 ib_class_port_info_t *cpi; 1458 struct sa_query_result result; 1459 int ret = sa_query(h, IB_MAD_METHOD_GET, CLASS_PORT_INFO, 0, 0, 1460 ibd_sakey, NULL, 0, &result); 1461 if (ret) { 1462 fprintf(stderr, "Query SA failed: %s\n", strerror(ret)); 1463 return ret; 1464 } 1465 1466 if (result.status != IB_SA_MAD_STATUS_SUCCESS) { 1467 sa_report_err(result.status); 1468 ret = EIO; 1469 goto Exit; 1470 } 1471 cpi = sa_get_query_rec(result.p_result_madw, 0); 1472 memcpy(&query_params->cpi, cpi, sizeof(query_params->cpi)); 1473 Exit: 1474 sa_free_result_mad(&result); 1475 return (0); 1476 } 1477 1478 static const struct query_cmd query_cmds[] = { 1479 {"ClassPortInfo", "CPI", CLASS_PORT_INFO, 1480 NULL, query_class_port_info}, 1481 {"NodeRecord", "NR", IB_SA_ATTR_NODERECORD, 1482 "[lid]", query_node_records}, 1483 {"PortInfoRecord", "PIR", IB_SA_ATTR_PORTINFORECORD, 1484 "[[lid]/[port]/[options]]", query_portinfo_records}, 1485 {"SL2VLTableRecord", "SL2VL", IB_SA_ATTR_SL2VLTABLERECORD, 1486 "[[lid]/[in_port]/[out_port]]", query_sl2vl_records}, 1487 {"PKeyTableRecord", "PKTR", IB_SA_ATTR_PKEYTABLERECORD, 1488 "[[lid]/[port]/[block]]", query_pkey_tbl_records}, 1489 {"VLArbitrationTableRecord", "VLAR", IB_SA_ATTR_VLARBTABLERECORD, 1490 "[[lid]/[port]/[block]]", query_vlarb_records}, 1491 {"InformInfoRecord", "IIR", IB_SA_ATTR_INFORMINFORECORD, 1492 "[subscriber_gid]", query_inform_info_records}, 1493 {"LinkRecord", "LR", IB_SA_ATTR_LINKRECORD, 1494 "[[from_lid]/[from_port]] [[to_lid]/[to_port]]", query_link_records}, 1495 {"ServiceRecord", "SR", IB_SA_ATTR_SERVICERECORD, 1496 NULL, query_service_records}, 1497 {"PathRecord", "PR", IB_SA_ATTR_PATHRECORD, 1498 NULL, query_path_records}, 1499 {"MCMemberRecord", "MCMR", IB_SA_ATTR_MCRECORD, 1500 NULL, query_mcmember_records}, 1501 {"LFTRecord", "LFTR", IB_SA_ATTR_LFTRECORD, 1502 "[[lid]/[block]]", query_lft_records}, 1503 {"MFTRecord", "MFTR", IB_SA_ATTR_MFTRECORD, 1504 "[[mlid]/[position]/[block]]", query_mft_records}, 1505 {"GUIDInfoRecord", "GIR", IB_SA_ATTR_GUIDINFORECORD, 1506 "[[lid]/[block]]", query_guidinfo_records}, 1507 {"SwitchInfoRecord", "SWIR", IB_SA_ATTR_SWITCHINFORECORD, 1508 "[lid]", query_switchinfo_records}, 1509 {"SMInfoRecord", "SMIR", IB_SA_ATTR_SMINFORECORD, 1510 "[lid]", query_sm_info_records}, 1511 {0} 1512 }; 1513 1514 static const struct query_cmd *find_query(const char *name) 1515 { 1516 const struct query_cmd *q; 1517 1518 for (q = query_cmds; q->name; q++) 1519 if (!strcasecmp(name, q->name) || 1520 (q->alias && !strcasecmp(name, q->alias))) 1521 return q; 1522 1523 return NULL; 1524 } 1525 1526 static const struct query_cmd *find_query_by_type(uint16_t type) 1527 { 1528 const struct query_cmd *q; 1529 1530 for (q = query_cmds; q->name; q++) 1531 if (q->query_type == type) 1532 return q; 1533 1534 return NULL; 1535 } 1536 1537 enum saquery_command { 1538 SAQUERY_CMD_QUERY, 1539 SAQUERY_CMD_NODE_RECORD, 1540 SAQUERY_CMD_CLASS_PORT_INFO, 1541 SAQUERY_CMD_ISSM, 1542 SAQUERY_CMD_MCGROUPS, 1543 SAQUERY_CMD_MCMEMBERS, 1544 }; 1545 1546 static enum saquery_command command = SAQUERY_CMD_QUERY; 1547 static uint16_t query_type; 1548 static char *src_lid, *dst_lid; 1549 1550 static int process_opt(void *context, int ch, char *optarg) 1551 { 1552 struct query_params *p = context; 1553 1554 switch (ch) { 1555 case 1: 1556 { 1557 src_lid = strdup(optarg); 1558 dst_lid = strchr(src_lid, ':'); 1559 if (!dst_lid) 1560 ibdiag_show_usage(); 1561 *dst_lid++ = '\0'; 1562 } 1563 p->numb_path = 0x7f; 1564 query_type = IB_SA_ATTR_PATHRECORD; 1565 break; 1566 case 2: 1567 { 1568 char *src_addr = strdup(optarg); 1569 char *dst_addr = strchr(src_addr, '-'); 1570 if (!dst_addr) 1571 ibdiag_show_usage(); 1572 *dst_addr++ = '\0'; 1573 if (inet_pton(AF_INET6, src_addr, &p->sgid) <= 0) 1574 ibdiag_show_usage(); 1575 if (inet_pton(AF_INET6, dst_addr, &p->dgid) <= 0) 1576 ibdiag_show_usage(); 1577 free(src_addr); 1578 } 1579 p->numb_path = 0x7f; 1580 query_type = IB_SA_ATTR_PATHRECORD; 1581 break; 1582 case 3: 1583 node_name_map_file = strdup(optarg); 1584 break; 1585 case 4: 1586 if (!isxdigit(*optarg) && !(optarg = getpass("SM_Key: "))) { 1587 fprintf(stderr, "cannot get SM_Key\n"); 1588 ibdiag_show_usage(); 1589 } 1590 ibd_sakey = strtoull(optarg, NULL, 0); 1591 break; 1592 case 'p': 1593 query_type = IB_SA_ATTR_PATHRECORD; 1594 break; 1595 case 'D': 1596 node_print_desc = ALL_DESC; 1597 command = SAQUERY_CMD_NODE_RECORD; 1598 break; 1599 case 'c': 1600 command = SAQUERY_CMD_CLASS_PORT_INFO; 1601 break; 1602 case 'S': 1603 query_type = IB_SA_ATTR_SERVICERECORD; 1604 break; 1605 case 'I': 1606 query_type = IB_SA_ATTR_INFORMINFORECORD; 1607 break; 1608 case 'N': 1609 command = SAQUERY_CMD_NODE_RECORD; 1610 break; 1611 case 'L': 1612 node_print_desc = LID_ONLY; 1613 command = SAQUERY_CMD_NODE_RECORD; 1614 break; 1615 case 'l': 1616 node_print_desc = UNIQUE_LID_ONLY; 1617 command = SAQUERY_CMD_NODE_RECORD; 1618 break; 1619 case 'G': 1620 node_print_desc = GUID_ONLY; 1621 command = SAQUERY_CMD_NODE_RECORD; 1622 break; 1623 case 'O': 1624 node_print_desc = NAME_OF_LID; 1625 command = SAQUERY_CMD_NODE_RECORD; 1626 break; 1627 case 'U': 1628 node_print_desc = NAME_OF_GUID; 1629 command = SAQUERY_CMD_NODE_RECORD; 1630 break; 1631 case 's': 1632 command = SAQUERY_CMD_ISSM; 1633 break; 1634 case 'g': 1635 command = SAQUERY_CMD_MCGROUPS; 1636 break; 1637 case 'm': 1638 command = SAQUERY_CMD_MCMEMBERS; 1639 break; 1640 case 'x': 1641 query_type = IB_SA_ATTR_LINKRECORD; 1642 break; 1643 case 5: 1644 p->slid = (uint16_t) strtoul(optarg, NULL, 0); 1645 break; 1646 case 6: 1647 p->dlid = (uint16_t) strtoul(optarg, NULL, 0); 1648 break; 1649 case 7: 1650 p->mlid = (uint16_t) strtoul(optarg, NULL, 0); 1651 break; 1652 case 14: 1653 if (inet_pton(AF_INET6, optarg, &p->sgid) <= 0) 1654 ibdiag_show_usage(); 1655 break; 1656 case 15: 1657 if (inet_pton(AF_INET6, optarg, &p->dgid) <= 0) 1658 ibdiag_show_usage(); 1659 break; 1660 case 16: 1661 if (inet_pton(AF_INET6, optarg, &p->gid) <= 0) 1662 ibdiag_show_usage(); 1663 break; 1664 case 17: 1665 if (inet_pton(AF_INET6, optarg, &p->mgid) <= 0) 1666 ibdiag_show_usage(); 1667 break; 1668 case 'r': 1669 p->reversible = strtoul(optarg, NULL, 0); 1670 break; 1671 case 'n': 1672 p->numb_path = strtoul(optarg, NULL, 0); 1673 break; 1674 case 18: 1675 if (!isxdigit(*optarg) && !(optarg = getpass("P_Key: "))) { 1676 fprintf(stderr, "cannot get P_Key\n"); 1677 ibdiag_show_usage(); 1678 } 1679 p->pkey = (uint16_t) strtoul(optarg, NULL, 0); 1680 break; 1681 case 'Q': 1682 p->qos_class = strtoul(optarg, NULL, 0); 1683 break; 1684 case 19: 1685 p->sl = strtoul(optarg, NULL, 0); 1686 break; 1687 case 'M': 1688 p->mtu = (uint8_t) strtoul(optarg, NULL, 0); 1689 break; 1690 case 'R': 1691 p->rate = (uint8_t) strtoul(optarg, NULL, 0); 1692 break; 1693 case 20: 1694 p->pkt_life = (uint8_t) strtoul(optarg, NULL, 0); 1695 break; 1696 case 'q': 1697 if (!isxdigit(*optarg) && !(optarg = getpass("Q_Key: "))) { 1698 fprintf(stderr, "cannot get Q_Key\n"); 1699 ibdiag_show_usage(); 1700 } 1701 p->qkey = strtoul(optarg, NULL, 0); 1702 break; 1703 case 'T': 1704 p->tclass = (uint8_t) strtoul(optarg, NULL, 0); 1705 break; 1706 case 'F': 1707 p->flow_label = strtoul(optarg, NULL, 0); 1708 break; 1709 case 'H': 1710 p->hop_limit = strtoul(optarg, NULL, 0); 1711 break; 1712 case 21: 1713 p->scope = (uint8_t) strtoul(optarg, NULL, 0); 1714 break; 1715 case 'J': 1716 p->join_state = (uint8_t) strtoul(optarg, NULL, 0); 1717 break; 1718 case 'X': 1719 p->proxy_join = strtoul(optarg, NULL, 0); 1720 break; 1721 case 22: 1722 p->service_id = strtoull(optarg, NULL, 0); 1723 break; 1724 case 23: 1725 p->with_grh = TRUE; 1726 break; 1727 case 24: 1728 p->with_grh = TRUE; 1729 if (inet_pton(AF_INET6, optarg, &p->sa_dgid) <= 0) 1730 ibdiag_show_usage(); 1731 break; 1732 default: 1733 return -1; 1734 } 1735 return 0; 1736 } 1737 1738 int main(int argc, char **argv) 1739 { 1740 ib_portid_t portid = { 0 }; 1741 int port = 0; 1742 int sa_cpi_required = 0; 1743 char usage_args[1024]; 1744 struct sa_handle * h; 1745 struct query_params params; 1746 const struct query_cmd *q; 1747 int status; 1748 int n; 1749 1750 const struct ibdiag_opt opts[] = { 1751 {"p", 'p', 0, NULL, "get PathRecord info"}, 1752 {"N", 'N', 0, NULL, "get NodeRecord info"}, 1753 {"L", 'L', 0, NULL, "return the Lids of the name specified"}, 1754 {"l", 'l', 0, NULL, 1755 "return the unique Lid of the name specified"}, 1756 {"G", 'G', 0, NULL, "return the Guids of the name specified"}, 1757 {"O", 'O', 0, NULL, "return name for the Lid specified"}, 1758 {"U", 'U', 0, NULL, "return name for the Guid specified"}, 1759 {"s", 's', 0, NULL, "return the PortInfoRecords with isSM or" 1760 " isSMdisabled capability mask bit on"}, 1761 {"g", 'g', 0, NULL, "get multicast group info"}, 1762 {"m", 'm', 0, NULL, "get multicast member info (if multicast" 1763 " group specified, list member GIDs only for group specified," 1764 " for example 'saquery -m 0xC000')"}, 1765 {"x", 'x', 0, NULL, "get LinkRecord info"}, 1766 {"c", 'c', 0, NULL, "get the SA's class port info"}, 1767 {"S", 'S', 0, NULL, "get ServiceRecord info"}, 1768 {"I", 'I', 0, NULL, "get InformInfoRecord (subscription) info"}, 1769 {"list", 'D', 0, NULL, "the node desc of the CA's"}, 1770 {"with-grh", 23, 0, NULL, "add GRH to path record query"}, 1771 {"sa-dgid", 24, 1, "<gid>", 1772 "Set destination GID (in IPv6 format) in the GRH"}, 1773 {"src-to-dst", 1, 1, "<src:dst>", "get a PathRecord for" 1774 " <src:dst> where src and dst are either node names or LIDs"}, 1775 {"sgid-to-dgid", 2, 1, "<sgid-dgid>", "get a PathRecord for" 1776 " <sgid-dgid> where sgid and dgid are addresses in IPv6 format"}, 1777 {"node-name-map", 3, 1, "<file>", 1778 "specify a node name map file"}, 1779 {"smkey", 4, 1, "<val>", 1780 "SA SM_Key value for the query." 1781 " If non-numeric value (like 'x') is specified then" 1782 " saquery will prompt for a value. " 1783 " Default (when not specified here or in ibdiag.conf) is to " 1784 " use SM_Key == 0 (or \"untrusted\")"}, 1785 {"slid", 5, 1, "<lid>", "Source LID (PathRecord)"}, 1786 {"dlid", 6, 1, "<lid>", "Destination LID (PathRecord)"}, 1787 {"mlid", 7, 1, "<lid>", "Multicast LID (MCMemberRecord)"}, 1788 {"sgid", 14, 1, "<gid>", 1789 "Source GID (IPv6 format) (PathRecord)"}, 1790 {"dgid", 15, 1, "<gid>", 1791 "Destination GID (IPv6 format) (PathRecord)"}, 1792 {"gid", 16, 1, "<gid>", "Port GID (MCMemberRecord)"}, 1793 {"mgid", 17, 1, "<gid>", "Multicast GID (MCMemberRecord)"}, 1794 {"reversible", 'r', 1, NULL, "Reversible path (PathRecord)"}, 1795 {"numb_path", 'n', 1, NULL, "Number of paths (PathRecord)"}, 1796 {"pkey", 18, 1, NULL, "P_Key (PathRecord, MCMemberRecord)." 1797 " If non-numeric value (like 'x') is specified then" 1798 " saquery will prompt for a value"}, 1799 {"qos_class", 'Q', 1, NULL, "QoS Class (PathRecord)"}, 1800 {"sl", 19, 1, NULL, 1801 "Service level (PathRecord, MCMemberRecord)"}, 1802 {"mtu", 'M', 1, NULL, 1803 "MTU and selector (PathRecord, MCMemberRecord)"}, 1804 {"rate", 'R', 1, NULL, 1805 "Rate and selector (PathRecord, MCMemberRecord)"}, 1806 {"pkt_lifetime", 20, 1, NULL, 1807 "Packet lifetime and selector (PathRecord, MCMemberRecord)"}, 1808 {"qkey", 'q', 1, NULL, "Q_Key (MCMemberRecord)." 1809 " If non-numeric value (like 'x') is specified then" 1810 " saquery will prompt for a value"}, 1811 {"tclass", 'T', 1, NULL, 1812 "Traffic Class (PathRecord, MCMemberRecord)"}, 1813 {"flow_label", 'F', 1, NULL, 1814 "Flow Label (PathRecord, MCMemberRecord)"}, 1815 {"hop_limit", 'H', 1, NULL, 1816 "Hop limit (PathRecord, MCMemberRecord)"}, 1817 {"scope", 21, 1, NULL, "Scope (MCMemberRecord)"}, 1818 {"join_state", 'J', 1, NULL, "Join state (MCMemberRecord)"}, 1819 {"proxy_join", 'X', 1, NULL, "Proxy join (MCMemberRecord)"}, 1820 {"service_id", 22, 1, NULL, "ServiceID (PathRecord)"}, 1821 {0} 1822 }; 1823 1824 memset(¶ms, 0, sizeof params); 1825 params.hop_limit = 0; 1826 params.reversible = -1; 1827 params.numb_path = -1; 1828 params.qos_class = -1; 1829 params.sl = -1; 1830 params.proxy_join = -1; 1831 1832 n = sprintf(usage_args, "[query-name] [<name> | <lid> | <guid>]\n" 1833 "\nSupported query names (and aliases):\n"); 1834 for (q = query_cmds; q->name; q++) { 1835 n += snprintf(usage_args + n, sizeof(usage_args) - n, 1836 " %s (%s) %s\n", q->name, 1837 q->alias ? q->alias : "", 1838 q->usage ? q->usage : ""); 1839 if (n >= sizeof(usage_args)) 1840 exit(-1); 1841 } 1842 snprintf(usage_args + n, sizeof(usage_args) - n, 1843 "\n Queries node records by default."); 1844 1845 q = NULL; 1846 ibd_timeout = DEFAULT_SA_TIMEOUT_MS; 1847 1848 ibdiag_process_opts(argc, argv, ¶ms, "DGLsy", opts, process_opt, 1849 usage_args, NULL); 1850 1851 argc -= optind; 1852 argv += optind; 1853 1854 if (!query_type && command == SAQUERY_CMD_QUERY) { 1855 if (!argc || !(q = find_query(argv[0]))) 1856 query_type = IB_SA_ATTR_NODERECORD; 1857 else { 1858 query_type = q->query_type; 1859 argc--; 1860 argv++; 1861 } 1862 } 1863 1864 if (argc) { 1865 if (node_print_desc == NAME_OF_LID) { 1866 requested_lid = (uint16_t) strtoul(argv[0], NULL, 0); 1867 requested_lid_flag++; 1868 } else if (node_print_desc == NAME_OF_GUID) { 1869 requested_guid = strtoul(argv[0], NULL, 0); 1870 requested_guid_flag++; 1871 } else 1872 requested_name = argv[0]; 1873 } 1874 1875 if ((node_print_desc == LID_ONLY || 1876 node_print_desc == UNIQUE_LID_ONLY || 1877 node_print_desc == GUID_ONLY) && !requested_name) { 1878 fprintf(stderr, "ERROR: name not specified\n"); 1879 ibdiag_show_usage(); 1880 } 1881 1882 if (node_print_desc == NAME_OF_LID && !requested_lid_flag) { 1883 fprintf(stderr, "ERROR: lid not specified\n"); 1884 ibdiag_show_usage(); 1885 } 1886 1887 if (node_print_desc == NAME_OF_GUID && !requested_guid_flag) { 1888 fprintf(stderr, "ERROR: guid not specified\n"); 1889 ibdiag_show_usage(); 1890 } 1891 1892 /* Note: lid cannot be 0; see infiniband spec 4.1.3 */ 1893 if (node_print_desc == NAME_OF_LID && !requested_lid) { 1894 fprintf(stderr, "ERROR: lid invalid\n"); 1895 ibdiag_show_usage(); 1896 } 1897 1898 if (umad_init()) 1899 IBEXIT("Failed to initialized umad library"); 1900 h = sa_get_handle(); 1901 if (!h) 1902 IBPANIC("Failed to bind to the SA"); 1903 1904 if (params.with_grh) { 1905 ibmad_gid_t gid = { 0 }; 1906 /* 1907 * If GRH destination GID is not specified, try to get it by 1908 * querying the SA. 1909 */ 1910 if (!memcmp(&gid, ¶ms.sa_dgid, sizeof(ibmad_gid_t))) { 1911 if ((status = resolve_self(ibd_ca, ibd_ca_port, &portid, 1912 &port, 0)) < 0) { 1913 fprintf(stderr, "can't resolve self port %s\n", 1914 argv[0]); 1915 goto error; 1916 } 1917 if ((status = sm_pr_query(h, &gid, portid.lid, 1918 h->dport.lid)) > 0) { 1919 fprintf(stderr, 1920 "Failed to query SA:PathRecord\n"); 1921 goto error; 1922 } 1923 } else 1924 memcpy(&gid, ¶ms.sa_dgid, sizeof(ibmad_gid_t)); 1925 1926 if ((status = sa_set_handle(h, 1, &gid)) < 0) { 1927 fprintf(stderr, "Failed to set GRH\n"); 1928 goto error; 1929 } 1930 } 1931 1932 node_name_map = open_node_name_map(node_name_map_file); 1933 1934 if (src_lid && *src_lid) 1935 params.slid = get_lid(h, src_lid); 1936 if (dst_lid && *dst_lid) 1937 params.dlid = get_lid(h, dst_lid); 1938 1939 if (command == SAQUERY_CMD_CLASS_PORT_INFO || 1940 query_type == CLASS_PORT_INFO || 1941 query_type == IB_SA_ATTR_SWITCHINFORECORD) 1942 sa_cpi_required = 1; 1943 1944 if (sa_cpi_required && (status = query_sa_cpi(h, ¶ms)) != 0) { 1945 fprintf(stderr, "Failed to query SA:ClassPortInfo\n"); 1946 goto error; 1947 } 1948 1949 switch (command) { 1950 case SAQUERY_CMD_NODE_RECORD: 1951 status = print_node_records(h, ¶ms); 1952 break; 1953 case SAQUERY_CMD_CLASS_PORT_INFO: 1954 dump_class_port_info(¶ms.cpi); 1955 status = 0; 1956 break; 1957 case SAQUERY_CMD_ISSM: 1958 status = print_issm_records(h, ¶ms); 1959 break; 1960 case SAQUERY_CMD_MCGROUPS: 1961 status = print_multicast_group_records(h, ¶ms); 1962 break; 1963 case SAQUERY_CMD_MCMEMBERS: 1964 status = print_multicast_member_records(h, ¶ms); 1965 break; 1966 default: 1967 if ((!q && !(q = find_query_by_type(query_type))) 1968 || !q->handler) { 1969 fprintf(stderr, "Unknown query type %d\n", 1970 ntohs(query_type)); 1971 status = EINVAL; 1972 } else 1973 status = q->handler(q, h, ¶ms, argc, argv); 1974 break; 1975 } 1976 1977 error: 1978 if (src_lid) 1979 free(src_lid); 1980 sa_free_handle(h); 1981 umad_done(); 1982 close_node_name_map(node_name_map); 1983 return (status); 1984 } 1985