1/* 2 * Copyright (c) 2004-2008 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2002-2005 Mellanox Technologies LTD. All rights reserved. 4 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved. 5 * Copyright (c) 2008 Xsigo Systems Inc. All rights reserved. 6 * 7 * This software is available to you under a choice of one of two 8 * licenses. You may choose to be licensed under the terms of the GNU 9 * General Public License (GPL) Version 2, available from the file 10 * COPYING in the main directory of this source tree, or the 11 * OpenIB.org BSD license below: 12 * 13 * Redistribution and use in source and binary forms, with or 14 * without modification, are permitted provided that the following 15 * conditions are met: 16 * 17 * - Redistributions of source code must retain the above 18 * copyright notice, this list of conditions and the following 19 * disclaimer. 20 * 21 * - Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials 24 * provided with the distribution. 25 * 26 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 27 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 28 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 29 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 30 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 31 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 32 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 33 * SOFTWARE. 34 * 35 */ 36 37/* 38 * Abstract: 39 * Implementation of osm_sa_t. 40 * This object represents the Subnet Administration object. 41 * This object is part of the opensm family of objects. 42 */ 43 44#if HAVE_CONFIG_H 45# include <config.h> 46#endif /* HAVE_CONFIG_H */ 47 48#include <string.h> 49#include <ctype.h> 50#include <errno.h> 51#include <stdlib.h> 52#include <sys/types.h> 53#include <sys/stat.h> 54#include <complib/cl_qmap.h> 55#include <complib/cl_passivelock.h> 56#include <complib/cl_debug.h> 57#include <iba/ib_types.h> 58#include <opensm/osm_sa.h> 59#include <opensm/osm_madw.h> 60#include <opensm/osm_log.h> 61#include <opensm/osm_subnet.h> 62#include <opensm/osm_mad_pool.h> 63#include <opensm/osm_msgdef.h> 64#include <opensm/osm_opensm.h> 65#include <opensm/osm_multicast.h> 66#include <opensm/osm_inform.h> 67#include <opensm/osm_service.h> 68#include <opensm/osm_helper.h> 69#include <vendor/osm_vendor_api.h> 70 71#define OSM_SA_INITIAL_TID_VALUE 0xabc 72 73extern void osm_cpi_rcv_process(IN void *context, IN void *data); 74extern void osm_gir_rcv_process(IN void *context, IN void *data); 75extern void osm_infr_rcv_process(IN void *context, IN void *data); 76extern void osm_infir_rcv_process(IN void *context, IN void *data); 77extern void osm_lftr_rcv_process(IN void *context, IN void *data); 78extern void osm_lr_rcv_process(IN void *context, IN void *data); 79extern void osm_mcmr_rcv_process(IN void *context, IN void *data); 80extern void osm_mftr_rcv_process(IN void *context, IN void *data); 81extern void osm_mpr_rcv_process(IN void *context, IN void *data); 82extern void osm_nr_rcv_process(IN void *context, IN void *data); 83extern void osm_pr_rcv_process(IN void *context, IN void *data); 84extern void osm_pkey_rec_rcv_process(IN void *context, IN void *data); 85extern void osm_pir_rcv_process(IN void *context, IN void *data); 86extern void osm_sr_rcv_process(IN void *context, IN void *data); 87extern void osm_slvl_rec_rcv_process(IN void *context, IN void *data); 88extern void osm_smir_rcv_process(IN void *context, IN void *data); 89extern void osm_sir_rcv_process(IN void *context, IN void *data); 90extern void osm_vlarb_rec_rcv_process(IN void *context, IN void *data); 91extern void osm_sr_rcv_lease_cb(IN void *context); 92 93/********************************************************************** 94 **********************************************************************/ 95void osm_sa_construct(IN osm_sa_t * const p_sa) 96{ 97 memset(p_sa, 0, sizeof(*p_sa)); 98 p_sa->state = OSM_SA_STATE_INIT; 99 p_sa->sa_trans_id = OSM_SA_INITIAL_TID_VALUE; 100 101 cl_timer_construct(&p_sa->sr_timer); 102} 103 104/********************************************************************** 105 **********************************************************************/ 106void osm_sa_shutdown(IN osm_sa_t * const p_sa) 107{ 108 ib_api_status_t status; 109 OSM_LOG_ENTER(p_sa->p_log); 110 111 cl_timer_stop(&p_sa->sr_timer); 112 113 /* unbind from the mad service */ 114 status = osm_sa_mad_ctrl_unbind(&p_sa->mad_ctrl); 115 116 /* remove any registered dispatcher message */ 117 cl_disp_unregister(p_sa->nr_disp_h); 118 cl_disp_unregister(p_sa->pir_disp_h); 119 cl_disp_unregister(p_sa->gir_disp_h); 120 cl_disp_unregister(p_sa->lr_disp_h); 121 cl_disp_unregister(p_sa->pr_disp_h); 122#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP) 123 cl_disp_unregister(p_sa->mpr_disp_h); 124#endif 125 cl_disp_unregister(p_sa->smir_disp_h); 126 cl_disp_unregister(p_sa->mcmr_disp_h); 127 cl_disp_unregister(p_sa->sr_disp_h); 128 cl_disp_unregister(p_sa->infr_disp_h); 129 cl_disp_unregister(p_sa->infir_disp_h); 130 cl_disp_unregister(p_sa->vlarb_disp_h); 131 cl_disp_unregister(p_sa->slvl_disp_h); 132 cl_disp_unregister(p_sa->pkey_disp_h); 133 cl_disp_unregister(p_sa->lft_disp_h); 134 cl_disp_unregister(p_sa->sir_disp_h); 135 cl_disp_unregister(p_sa->mft_disp_h); 136 osm_sa_mad_ctrl_destroy(&p_sa->mad_ctrl); 137 138 OSM_LOG_EXIT(p_sa->p_log); 139} 140 141/********************************************************************** 142 **********************************************************************/ 143void osm_sa_destroy(IN osm_sa_t * const p_sa) 144{ 145 OSM_LOG_ENTER(p_sa->p_log); 146 147 p_sa->state = OSM_SA_STATE_INIT; 148 149 cl_timer_destroy(&p_sa->sr_timer); 150 151 OSM_LOG_EXIT(p_sa->p_log); 152} 153 154/********************************************************************** 155 **********************************************************************/ 156ib_api_status_t 157osm_sa_init(IN osm_sm_t * const p_sm, 158 IN osm_sa_t * const p_sa, 159 IN osm_subn_t * const p_subn, 160 IN osm_vendor_t * const p_vendor, 161 IN osm_mad_pool_t * const p_mad_pool, 162 IN osm_log_t * const p_log, 163 IN osm_stats_t * const p_stats, 164 IN cl_dispatcher_t * const p_disp, IN cl_plock_t * const p_lock) 165{ 166 ib_api_status_t status = IB_SUCCESS; 167 168 OSM_LOG_ENTER(p_log); 169 170 p_sa->sm = p_sm; 171 p_sa->p_subn = p_subn; 172 p_sa->p_vendor = p_vendor; 173 p_sa->p_mad_pool = p_mad_pool; 174 p_sa->p_log = p_log; 175 p_sa->p_disp = p_disp; 176 p_sa->p_lock = p_lock; 177 178 p_sa->state = OSM_SA_STATE_READY; 179 180 status = osm_sa_mad_ctrl_init(&p_sa->mad_ctrl, 181 p_sa, 182 p_sa->p_mad_pool, 183 p_sa->p_vendor, 184 p_subn, p_log, p_stats, p_disp); 185 if (status != IB_SUCCESS) 186 goto Exit; 187 188 status = cl_timer_init(&p_sa->sr_timer, osm_sr_rcv_lease_cb, p_sa); 189 if (status != IB_SUCCESS) 190 goto Exit; 191 192 p_sa->cpi_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_CLASS_PORT_INFO, 193 osm_cpi_rcv_process, p_sa); 194 if (p_sa->cpi_disp_h == CL_DISP_INVALID_HANDLE) 195 goto Exit; 196 197 p_sa->nr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_NODE_RECORD, 198 osm_nr_rcv_process, p_sa); 199 if (p_sa->nr_disp_h == CL_DISP_INVALID_HANDLE) 200 goto Exit; 201 202 p_sa->pir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PORTINFO_RECORD, 203 osm_pir_rcv_process, p_sa); 204 if (p_sa->pir_disp_h == CL_DISP_INVALID_HANDLE) 205 goto Exit; 206 207 p_sa->gir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_GUIDINFO_RECORD, 208 osm_gir_rcv_process, p_sa); 209 if (p_sa->gir_disp_h == CL_DISP_INVALID_HANDLE) 210 goto Exit; 211 212 p_sa->lr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LINK_RECORD, 213 osm_lr_rcv_process, p_sa); 214 if (p_sa->lr_disp_h == CL_DISP_INVALID_HANDLE) 215 goto Exit; 216 217 p_sa->pr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_PATH_RECORD, 218 osm_pr_rcv_process, p_sa); 219 if (p_sa->pr_disp_h == CL_DISP_INVALID_HANDLE) 220 goto Exit; 221 222#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP) 223 p_sa->mpr_disp_h = 224 cl_disp_register(p_disp, OSM_MSG_MAD_MULTIPATH_RECORD, 225 osm_mpr_rcv_process, p_sa); 226 if (p_sa->mpr_disp_h == CL_DISP_INVALID_HANDLE) 227 goto Exit; 228#endif 229 230 p_sa->smir_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SMINFO_RECORD, 231 osm_smir_rcv_process, p_sa); 232 if (p_sa->smir_disp_h == CL_DISP_INVALID_HANDLE) 233 goto Exit; 234 235 p_sa->mcmr_disp_h = 236 cl_disp_register(p_disp, OSM_MSG_MAD_MCMEMBER_RECORD, 237 osm_mcmr_rcv_process, p_sa); 238 if (p_sa->mcmr_disp_h == CL_DISP_INVALID_HANDLE) 239 goto Exit; 240 241 p_sa->sr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_SERVICE_RECORD, 242 osm_sr_rcv_process, p_sa); 243 if (p_sa->sr_disp_h == CL_DISP_INVALID_HANDLE) 244 goto Exit; 245 246 p_sa->infr_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO, 247 osm_infr_rcv_process, p_sa); 248 if (p_sa->infr_disp_h == CL_DISP_INVALID_HANDLE) 249 goto Exit; 250 251 p_sa->infir_disp_h = 252 cl_disp_register(p_disp, OSM_MSG_MAD_INFORM_INFO_RECORD, 253 osm_infir_rcv_process, p_sa); 254 if (p_sa->infir_disp_h == CL_DISP_INVALID_HANDLE) 255 goto Exit; 256 257 p_sa->vlarb_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_VL_ARB_RECORD, 258 osm_vlarb_rec_rcv_process, p_sa); 259 if (p_sa->vlarb_disp_h == CL_DISP_INVALID_HANDLE) 260 goto Exit; 261 262 p_sa->slvl_disp_h = 263 cl_disp_register(p_disp, OSM_MSG_MAD_SLVL_TBL_RECORD, 264 osm_slvl_rec_rcv_process, p_sa); 265 if (p_sa->slvl_disp_h == CL_DISP_INVALID_HANDLE) 266 goto Exit; 267 268 p_sa->pkey_disp_h = 269 cl_disp_register(p_disp, OSM_MSG_MAD_PKEY_TBL_RECORD, 270 osm_pkey_rec_rcv_process, p_sa); 271 if (p_sa->pkey_disp_h == CL_DISP_INVALID_HANDLE) 272 goto Exit; 273 274 p_sa->lft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_LFT_RECORD, 275 osm_lftr_rcv_process, p_sa); 276 if (p_sa->lft_disp_h == CL_DISP_INVALID_HANDLE) 277 goto Exit; 278 279 p_sa->sir_disp_h = 280 cl_disp_register(p_disp, OSM_MSG_MAD_SWITCH_INFO_RECORD, 281 osm_sir_rcv_process, p_sa); 282 if (p_sa->sir_disp_h == CL_DISP_INVALID_HANDLE) 283 goto Exit; 284 285 p_sa->mft_disp_h = cl_disp_register(p_disp, OSM_MSG_MAD_MFT_RECORD, 286 osm_mftr_rcv_process, p_sa); 287 if (p_sa->mft_disp_h == CL_DISP_INVALID_HANDLE) 288 goto Exit; 289 290Exit: 291 OSM_LOG_EXIT(p_log); 292 return (status); 293} 294 295/********************************************************************** 296 **********************************************************************/ 297ib_api_status_t 298osm_sa_bind(IN osm_sa_t * const p_sa, IN const ib_net64_t port_guid) 299{ 300 ib_api_status_t status; 301 302 OSM_LOG_ENTER(p_sa->p_log); 303 304 status = osm_sa_mad_ctrl_bind(&p_sa->mad_ctrl, port_guid); 305 306 if (status != IB_SUCCESS) { 307 OSM_LOG(p_sa->p_log, OSM_LOG_ERROR, "ERR 4C03: " 308 "SA MAD Controller bind failed (%s)\n", 309 ib_get_err_str(status)); 310 goto Exit; 311 } 312 313Exit: 314 OSM_LOG_EXIT(p_sa->p_log); 315 return (status); 316} 317 318ib_api_status_t osm_sa_send(osm_sa_t *sa, 319 IN osm_madw_t * const p_madw, 320 IN boolean_t const resp_expected) 321{ 322 ib_api_status_t status; 323 324 cl_atomic_inc(&sa->p_subn->p_osm->stats.sa_mads_sent); 325 status = osm_vendor_send(p_madw->h_bind, p_madw, resp_expected); 326 if (status != IB_SUCCESS) { 327 cl_atomic_dec(&sa->p_subn->p_osm->stats.sa_mads_sent); 328 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C04: " 329 "osm_vendor_send failed, status = %s\n", 330 ib_get_err_str(status)); 331 } 332 return status; 333} 334 335void 336osm_sa_send_error(IN osm_sa_t * sa, 337 IN const osm_madw_t * const p_madw, 338 IN const ib_net16_t sa_status) 339{ 340 osm_madw_t *p_resp_madw; 341 ib_sa_mad_t *p_resp_sa_mad; 342 ib_sa_mad_t *p_sa_mad; 343 344 OSM_LOG_ENTER(sa->p_log); 345 346 /* avoid races - if we are exiting - exit */ 347 if (osm_exit_flag) { 348 OSM_LOG(sa->p_log, OSM_LOG_DEBUG, 349 "Ignoring requested send after exit\n"); 350 goto Exit; 351 } 352 353 p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, 354 p_madw->h_bind, MAD_BLOCK_SIZE, 355 &p_madw->mad_addr); 356 357 if (p_resp_madw == NULL) { 358 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C07: " 359 "Unable to acquire response MAD\n"); 360 goto Exit; 361 } 362 363 p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw); 364 p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw); 365 366 /* Copy the MAD header back into the response mad */ 367 *p_resp_sa_mad = *p_sa_mad; 368 p_resp_sa_mad->status = sa_status; 369 370 if (p_resp_sa_mad->method == IB_MAD_METHOD_SET) 371 p_resp_sa_mad->method = IB_MAD_METHOD_GET; 372 else if (p_resp_sa_mad->method == IB_MAD_METHOD_GETTABLE) 373 p_resp_sa_mad->attr_offset = 0; 374 375 p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK; 376 377 /* 378 * C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) 379 */ 380 p_resp_sa_mad->sm_key = 0; 381 382 /* 383 * o15-0.2.7 - The PathRecord Attribute ID shall be used in 384 * the response (to a SubnAdmGetMulti(MultiPathRecord) 385 */ 386 if (p_resp_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD) 387 p_resp_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD; 388 389 if (osm_log_is_active(sa->p_log, OSM_LOG_FRAMES)) 390 osm_dump_sa_mad(sa->p_log, p_resp_sa_mad, OSM_LOG_FRAMES); 391 392 osm_sa_send(sa, p_resp_madw, FALSE); 393 394Exit: 395 OSM_LOG_EXIT(sa->p_log); 396} 397 398void osm_sa_respond(osm_sa_t *sa, osm_madw_t *madw, size_t attr_size, 399 cl_qlist_t *list) 400{ 401 struct item_data { 402 cl_list_item_t list; 403 char data[0]; 404 }; 405 cl_list_item_t *item; 406 osm_madw_t *resp_madw; 407 ib_sa_mad_t *sa_mad, *resp_sa_mad; 408 unsigned num_rec, i; 409#ifndef VENDOR_RMPP_SUPPORT 410 unsigned trim_num_rec; 411#endif 412 void *p; 413 414 sa_mad = osm_madw_get_sa_mad_ptr(madw); 415 num_rec = cl_qlist_count(list); 416 417 /* 418 * C15-0.1.30: 419 * If we do a SubnAdmGet and got more than one record it is an error! 420 */ 421 if (sa_mad->method == IB_MAD_METHOD_GET && num_rec > 1) { 422 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C05: " 423 "Got more than one record for SubnAdmGet (%u)\n", 424 num_rec); 425 osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_TOO_MANY_RECORDS); 426 goto Exit; 427 } 428 429#ifndef VENDOR_RMPP_SUPPORT 430 trim_num_rec = (MAD_BLOCK_SIZE - IB_SA_MAD_HDR_SIZE) / attr_size; 431 if (trim_num_rec < num_rec) { 432 OSM_LOG(sa->p_log, OSM_LOG_VERBOSE, 433 "Number of records:%u trimmed to:%u to fit in one MAD\n", 434 num_rec, trim_num_rec); 435 num_rec = trim_num_rec; 436 } 437#endif 438 439 OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Returning %u records\n", num_rec); 440 441 if (sa_mad->method == IB_MAD_METHOD_GET && num_rec == 0) { 442 osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RECORDS); 443 goto Exit; 444 } 445 446 /* 447 * Get a MAD to reply. Address of Mad is in the received mad_wrapper 448 */ 449 resp_madw = osm_mad_pool_get(sa->p_mad_pool, madw->h_bind, 450 num_rec * attr_size + IB_SA_MAD_HDR_SIZE, 451 &madw->mad_addr); 452 if (!resp_madw) { 453 OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4C06: " 454 "osm_mad_pool_get failed\n"); 455 osm_sa_send_error(sa, madw, IB_SA_MAD_STATUS_NO_RESOURCES); 456 goto Exit; 457 } 458 459 resp_sa_mad = osm_madw_get_sa_mad_ptr(resp_madw); 460 461 /* 462 Copy the MAD header back into the response mad. 463 Set the 'R' bit and the payload length, 464 Then copy all records from the list into the response payload. 465 */ 466 467 memcpy(resp_sa_mad, sa_mad, IB_SA_MAD_HDR_SIZE); 468 if (resp_sa_mad->method == IB_MAD_METHOD_SET) 469 resp_sa_mad->method = IB_MAD_METHOD_GET; 470 resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK; 471 /* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */ 472 resp_sa_mad->sm_key = 0; 473 474 /* Fill in the offset (paylen will be done by the rmpp SAR) */ 475 resp_sa_mad->attr_offset = num_rec ? ib_get_attr_offset(attr_size) : 0; 476 477 p = ib_sa_mad_get_payload_ptr(resp_sa_mad); 478 479#ifndef VENDOR_RMPP_SUPPORT 480 /* we support only one packet RMPP - so we will set the first and 481 last flags for gettable */ 482 if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) { 483 resp_sa_mad->rmpp_type = IB_RMPP_TYPE_DATA; 484 resp_sa_mad->rmpp_flags = 485 IB_RMPP_FLAG_FIRST | IB_RMPP_FLAG_LAST | 486 IB_RMPP_FLAG_ACTIVE; 487 } 488#else 489 /* forcefully define the packet as RMPP one */ 490 if (resp_sa_mad->method == IB_MAD_METHOD_GETTABLE_RESP) 491 resp_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE; 492#endif 493 494 for (i = 0; i < num_rec; i++) { 495 item = cl_qlist_remove_head(list); 496 memcpy(p, ((struct item_data *)item)->data, attr_size); 497 p += attr_size; 498 free(item); 499 } 500 501 osm_sa_send(sa, resp_madw, FALSE); 502 503 osm_dump_sa_mad(sa->p_log, resp_sa_mad, OSM_LOG_FRAMES); 504Exit: 505 /* need to set the mem free ... */ 506 item = cl_qlist_remove_head(list); 507 while (item != cl_qlist_end(list)) { 508 free(item); 509 item = cl_qlist_remove_head(list); 510 } 511} 512 513/********************************************************************** 514 **********************************************************************/ 515/* 516 * SA DB Dumper 517 * 518 */ 519 520struct opensm_dump_context { 521 osm_opensm_t *p_osm; 522 FILE *file; 523}; 524 525static int 526opensm_dump_to_file(osm_opensm_t * p_osm, const char *file_name, 527 void (*dump_func) (osm_opensm_t * p_osm, FILE * file)) 528{ 529 char path[1024]; 530 FILE *file; 531 532 snprintf(path, sizeof(path), "%s/%s", 533 p_osm->subn.opt.dump_files_dir, file_name); 534 535 file = fopen(path, "w"); 536 if (!file) { 537 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, "ERR 4C01: " 538 "cannot open file \'%s\': %s\n", 539 file_name, strerror(errno)); 540 return -1; 541 } 542 543 chmod(path, S_IRUSR | S_IWUSR); 544 545 dump_func(p_osm, file); 546 547 fclose(file); 548 return 0; 549} 550 551static void mcast_mgr_dump_one_port(cl_map_item_t * p_map_item, void *cxt) 552{ 553 FILE *file = ((struct opensm_dump_context *)cxt)->file; 554 osm_mcm_port_t *p_mcm_port = (osm_mcm_port_t *) p_map_item; 555 556 fprintf(file, "mcm_port: " 557 "port_gid=0x%016" PRIx64 ":0x%016" PRIx64 " " 558 "scope_state=0x%02x proxy_join=0x%x" "\n\n", 559 cl_ntoh64(p_mcm_port->port_gid.unicast.prefix), 560 cl_ntoh64(p_mcm_port->port_gid.unicast.interface_id), 561 p_mcm_port->scope_state, p_mcm_port->proxy_join); 562} 563 564static void sa_dump_one_mgrp(osm_mgrp_t *p_mgrp, void *cxt) 565{ 566 struct opensm_dump_context dump_context; 567 osm_opensm_t *p_osm = ((struct opensm_dump_context *)cxt)->p_osm; 568 FILE *file = ((struct opensm_dump_context *)cxt)->file; 569 570 fprintf(file, "MC Group 0x%04x %s:" 571 " mgid=0x%016" PRIx64 ":0x%016" PRIx64 572 " port_gid=0x%016" PRIx64 ":0x%016" PRIx64 573 " qkey=0x%08x mlid=0x%04x mtu=0x%02x tclass=0x%02x" 574 " pkey=0x%04x rate=0x%02x pkt_life=0x%02x sl_flow_hop=0x%08x" 575 " scope_state=0x%02x proxy_join=0x%x" "\n\n", 576 cl_ntoh16(p_mgrp->mlid), 577 p_mgrp->well_known ? " (well known)" : "", 578 cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.prefix), 579 cl_ntoh64(p_mgrp->mcmember_rec.mgid.unicast.interface_id), 580 cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.prefix), 581 cl_ntoh64(p_mgrp->mcmember_rec.port_gid.unicast.interface_id), 582 cl_ntoh32(p_mgrp->mcmember_rec.qkey), 583 cl_ntoh16(p_mgrp->mcmember_rec.mlid), 584 p_mgrp->mcmember_rec.mtu, 585 p_mgrp->mcmember_rec.tclass, 586 cl_ntoh16(p_mgrp->mcmember_rec.pkey), 587 p_mgrp->mcmember_rec.rate, 588 p_mgrp->mcmember_rec.pkt_life, 589 cl_ntoh32(p_mgrp->mcmember_rec.sl_flow_hop), 590 p_mgrp->mcmember_rec.scope_state, 591 p_mgrp->mcmember_rec.proxy_join); 592 593 dump_context.p_osm = p_osm; 594 dump_context.file = file; 595 596 cl_qmap_apply_func(&p_mgrp->mcm_port_tbl, 597 mcast_mgr_dump_one_port, &dump_context); 598} 599 600static void sa_dump_one_inform(cl_list_item_t * p_list_item, void *cxt) 601{ 602 FILE *file = ((struct opensm_dump_context *)cxt)->file; 603 osm_infr_t *p_infr = (osm_infr_t *) p_list_item; 604 ib_inform_info_record_t *p_iir = &p_infr->inform_record; 605 606 fprintf(file, "InformInfo Record:" 607 " subscriber_gid=0x%016" PRIx64 ":0x%016" PRIx64 608 " subscriber_enum=0x%x" 609 " InformInfo:" 610 " gid=0x%016" PRIx64 ":0x%016" PRIx64 611 " lid_range_begin=0x%x" 612 " lid_range_end=0x%x" 613 " is_generic=0x%x" 614 " subscribe=0x%x" 615 " trap_type=0x%x" 616 " trap_num=0x%x" 617 " qpn_resp_time_val=0x%x" 618 " node_type=0x%06x" 619 " rep_addr: lid=0x%04x path_bits=0x%02x static_rate=0x%02x" 620 " remote_qp=0x%08x remote_qkey=0x%08x pkey_ix=0x%04x sl=0x%02x" 621 "\n\n", 622 cl_ntoh64(p_iir->subscriber_gid.unicast.prefix), 623 cl_ntoh64(p_iir->subscriber_gid.unicast.interface_id), 624 cl_ntoh16(p_iir->subscriber_enum), 625 cl_ntoh64(p_iir->inform_info.gid.unicast.prefix), 626 cl_ntoh64(p_iir->inform_info.gid.unicast.interface_id), 627 cl_ntoh16(p_iir->inform_info.lid_range_begin), 628 cl_ntoh16(p_iir->inform_info.lid_range_end), 629 p_iir->inform_info.is_generic, 630 p_iir->inform_info.subscribe, 631 cl_ntoh16(p_iir->inform_info.trap_type), 632 cl_ntoh16(p_iir->inform_info.g_or_v.generic.trap_num), 633 cl_ntoh32(p_iir->inform_info.g_or_v.generic.qpn_resp_time_val), 634 cl_ntoh32(ib_inform_info_get_prod_type(&p_iir->inform_info)), 635 cl_ntoh16(p_infr->report_addr.dest_lid), 636 p_infr->report_addr.path_bits, 637 p_infr->report_addr.static_rate, 638 cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qp), 639 cl_ntoh32(p_infr->report_addr.addr_type.gsi.remote_qkey), 640 p_infr->report_addr.addr_type.gsi.pkey_ix, 641 p_infr->report_addr.addr_type.gsi.service_level); 642} 643 644static void sa_dump_one_service(cl_list_item_t * p_list_item, void *cxt) 645{ 646 FILE *file = ((struct opensm_dump_context *)cxt)->file; 647 osm_svcr_t *p_svcr = (osm_svcr_t *) p_list_item; 648 ib_service_record_t *p_sr = &p_svcr->service_record; 649 650 fprintf(file, "Service Record: id=0x%016" PRIx64 651 " gid=0x%016" PRIx64 ":0x%016" PRIx64 652 " pkey=0x%x" 653 " lease=0x%x" 654 " key=0x%02x%02x%02x%02x%02x%02x%02x%02x" 655 ":0x%02x%02x%02x%02x%02x%02x%02x%02x" 656 " name=\'%s\'" 657 " data8=0x%02x%02x%02x%02x%02x%02x%02x%02x" 658 ":0x%02x%02x%02x%02x%02x%02x%02x%02x" 659 " data16=0x%04x%04x%04x%04x:0x%04x%04x%04x%04x" 660 " data32=0x%08x%08x:0x%08x%08x" 661 " data64=0x%016" PRIx64 ":0x%016" PRIx64 662 " modified_time=0x%x lease_period=0x%x\n\n", 663 cl_ntoh64(p_sr->service_id), 664 cl_ntoh64(p_sr->service_gid.unicast.prefix), 665 cl_ntoh64(p_sr->service_gid.unicast.interface_id), 666 cl_ntoh16(p_sr->service_pkey), 667 cl_ntoh32(p_sr->service_lease), 668 p_sr->service_key[0], p_sr->service_key[1], 669 p_sr->service_key[2], p_sr->service_key[3], 670 p_sr->service_key[4], p_sr->service_key[5], 671 p_sr->service_key[6], p_sr->service_key[7], 672 p_sr->service_key[8], p_sr->service_key[9], 673 p_sr->service_key[10], p_sr->service_key[11], 674 p_sr->service_key[12], p_sr->service_key[13], 675 p_sr->service_key[14], p_sr->service_key[15], 676 p_sr->service_name, 677 p_sr->service_data8[0], p_sr->service_data8[1], 678 p_sr->service_data8[2], p_sr->service_data8[3], 679 p_sr->service_data8[4], p_sr->service_data8[5], 680 p_sr->service_data8[6], p_sr->service_data8[7], 681 p_sr->service_data8[8], p_sr->service_data8[9], 682 p_sr->service_data8[10], p_sr->service_data8[11], 683 p_sr->service_data8[12], p_sr->service_data8[13], 684 p_sr->service_data8[14], p_sr->service_data8[15], 685 cl_ntoh16(p_sr->service_data16[0]), 686 cl_ntoh16(p_sr->service_data16[1]), 687 cl_ntoh16(p_sr->service_data16[2]), 688 cl_ntoh16(p_sr->service_data16[3]), 689 cl_ntoh16(p_sr->service_data16[4]), 690 cl_ntoh16(p_sr->service_data16[5]), 691 cl_ntoh16(p_sr->service_data16[6]), 692 cl_ntoh16(p_sr->service_data16[7]), 693 cl_ntoh32(p_sr->service_data32[0]), 694 cl_ntoh32(p_sr->service_data32[1]), 695 cl_ntoh32(p_sr->service_data32[2]), 696 cl_ntoh32(p_sr->service_data32[3]), 697 cl_ntoh64(p_sr->service_data64[0]), 698 cl_ntoh64(p_sr->service_data64[1]), 699 p_svcr->modified_time, p_svcr->lease_period); 700} 701 702static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file) 703{ 704 struct opensm_dump_context dump_context; 705 osm_mgrp_t *p_mgrp; 706 int i; 707 708 dump_context.p_osm = p_osm; 709 dump_context.file = file; 710 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast:\n"); 711 cl_plock_acquire(&p_osm->lock); 712 for (i = 0; i <= p_osm->subn.max_mcast_lid_ho - IB_LID_MCAST_START_HO; 713 i++) { 714 p_mgrp = p_osm->subn.mgroups[i]; 715 if (p_mgrp) 716 sa_dump_one_mgrp(p_mgrp, &dump_context); 717 } 718 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform:\n"); 719 cl_qlist_apply_func(&p_osm->subn.sa_infr_list, 720 sa_dump_one_inform, &dump_context); 721 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services:\n"); 722 cl_qlist_apply_func(&p_osm->subn.sa_sr_list, 723 sa_dump_one_service, &dump_context); 724 cl_plock_release(&p_osm->lock); 725} 726 727int osm_sa_db_file_dump(osm_opensm_t * p_osm) 728{ 729 return opensm_dump_to_file(p_osm, "opensm-sa.dump", sa_dump_all_sa); 730} 731 732/* 733 * SA DB Loader 734 */ 735static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid, 736 ib_member_rec_t * p_mcm_rec, 737 unsigned well_known) 738{ 739 ib_net64_t comp_mask; 740 osm_mgrp_t *p_mgrp; 741 742 cl_plock_excl_acquire(&p_osm->lock); 743 744 p_mgrp = osm_get_mgrp_by_mlid(&p_osm->subn, mlid); 745 if (p_mgrp) { 746 if (!memcmp(&p_mgrp->mcmember_rec.mgid, &p_mcm_rec->mgid, 747 sizeof(ib_gid_t))) { 748 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, 749 "mgrp %04x is already here.", cl_ntoh16(mlid)); 750 goto _out; 751 } 752 OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, 753 "mlid %04x is already used by another MC group. Will " 754 "request clients reregistration.\n", cl_ntoh16(mlid)); 755 p_mgrp = NULL; 756 goto _out; 757 } 758 759 comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL 760 | IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL; 761 if (osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa, 762 comp_mask, p_mcm_rec, 763 &p_mgrp) != IB_SUCCESS || 764 !p_mgrp || p_mgrp->mlid != mlid) { 765 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, 766 "cannot create MC group with mlid 0x%04x and mgid " 767 "0x%016" PRIx64 ":0x%016" PRIx64 "\n", cl_ntoh16(mlid), 768 cl_ntoh64(p_mcm_rec->mgid.unicast.prefix), 769 cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id)); 770 p_mgrp = NULL; 771 } else if (well_known) 772 p_mgrp->well_known = TRUE; 773 774_out: 775 cl_plock_release(&p_osm->lock); 776 777 return p_mgrp; 778} 779 780static int load_svcr(osm_opensm_t * p_osm, ib_service_record_t * sr, 781 uint32_t modified_time, uint32_t lease_period) 782{ 783 osm_svcr_t *p_svcr; 784 int ret = 0; 785 786 cl_plock_excl_acquire(&p_osm->lock); 787 788 if (osm_svcr_get_by_rid(&p_osm->subn, &p_osm->log, sr)) { 789 OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, 790 "ServiceRecord already exists\n"); 791 goto _out; 792 } 793 794 if (!(p_svcr = osm_svcr_new(sr))) { 795 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, 796 "cannot allocate new service struct\n"); 797 ret = -1; 798 goto _out; 799 } 800 801 p_svcr->modified_time = modified_time; 802 p_svcr->lease_period = lease_period; 803 804 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding ServiceRecord...\n"); 805 806 osm_svcr_insert_to_db(&p_osm->subn, &p_osm->log, p_svcr); 807 808 if (lease_period != 0xffffffff) 809 cl_timer_trim(&p_osm->sa.sr_timer, 1000); 810 811_out: 812 cl_plock_release(&p_osm->lock); 813 814 return ret; 815} 816 817static int load_infr(osm_opensm_t * p_osm, ib_inform_info_record_t * iir, 818 osm_mad_addr_t * addr) 819{ 820 osm_infr_t infr, *p_infr; 821 int ret = 0; 822 823 infr.h_bind = p_osm->sa.mad_ctrl.h_bind; 824 infr.sa = &p_osm->sa; 825 /* other possible way to restore mad_addr partially is 826 to extract qpn from InformInfo and to find lid by gid */ 827 infr.report_addr = *addr; 828 infr.inform_record = *iir; 829 830 cl_plock_excl_acquire(&p_osm->lock); 831 if (osm_infr_get_by_rec(&p_osm->subn, &p_osm->log, &infr)) { 832 OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, 833 "InformInfo Record already exists\n"); 834 goto _out; 835 } 836 837 if (!(p_infr = osm_infr_new(&infr))) { 838 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, 839 "cannot allocate new infr struct\n"); 840 ret = -1; 841 goto _out; 842 } 843 844 OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding InformInfo Record...\n"); 845 846 osm_infr_insert_to_db(&p_osm->subn, &p_osm->log, p_infr); 847 848_out: 849 cl_plock_release(&p_osm->lock); 850 851 return ret; 852} 853 854#define UNPACK_FUNC(name,x) \ 855static int unpack_##name##x(char *p, uint##x##_t *val_ptr) \ 856{ \ 857 char *q; \ 858 unsigned long long num; \ 859 num = strtoull(p, &q, 16); \ 860 if (num > ~((uint##x##_t)0x0) \ 861 || q == p || (!isspace(*q) && *q != ':')) { \ 862 *val_ptr = 0; \ 863 return -1; \ 864 } \ 865 *val_ptr = cl_hton##x((uint##x##_t)num); \ 866 return (int)(q - p); \ 867} 868 869#define cl_hton8(x) (x) 870 871UNPACK_FUNC(net, 8); 872UNPACK_FUNC(net, 16); 873UNPACK_FUNC(net, 32); 874UNPACK_FUNC(net, 64); 875 876static int unpack_string(char *p, uint8_t * buf, unsigned len) 877{ 878 char *q = p; 879 char delim = ' '; 880 881 if (*q == '\'' || *q == '\"') 882 delim = *q++; 883 while (--len && *q && *q != delim) 884 *buf++ = *q++; 885 *buf = '\0'; 886 if (*q == delim && delim != ' ') 887 q++; 888 return (int)(q - p); 889} 890 891static int unpack_string64(char *p, uint8_t * buf) 892{ 893 return unpack_string(p, buf, 64); 894} 895 896#define PARSE_AHEAD(p, x, name, val_ptr) { int _ret; \ 897 p = strstr(p, name); \ 898 if (!p) { \ 899 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \ 900 "PARSE ERROR: %s:%u: cannot find \"%s\" string\n", \ 901 file_name, lineno, (name)); \ 902 ret = -2; \ 903 goto _error; \ 904 } \ 905 p += strlen(name); \ 906 _ret = unpack_##x(p, (val_ptr)); \ 907 if (_ret < 0) { \ 908 OSM_LOG(&p_osm->log, OSM_LOG_ERROR, \ 909 "PARSE ERROR: %s:%u: cannot parse "#x" value " \ 910 "after \"%s\"\n", file_name, lineno, (name)); \ 911 ret = _ret; \ 912 goto _error; \ 913 } \ 914 p += _ret; \ 915} 916 917int osm_sa_db_file_load(osm_opensm_t * p_osm) 918{ 919 char line[1024]; 920 char *file_name; 921 FILE *file; 922 int ret = 0; 923 osm_mgrp_t *p_mgrp = NULL; 924 unsigned rereg_clients = 0; 925 unsigned lineno; 926 927 file_name = p_osm->subn.opt.sa_db_file; 928 if (!file_name) { 929 OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, 930 "sa db file name is not specifed. Skip restore\n"); 931 return 0; 932 } 933 934 file = fopen(file_name, "r"); 935 if (!file) { 936 OSM_LOG(&p_osm->log, OSM_LOG_ERROR | OSM_LOG_SYS, "ERR 4C02: " 937 "cannot open sa db file \'%s\'. Skip restoring\n", 938 file_name); 939 return -1; 940 } 941 942 lineno = 0; 943 944 while (fgets(line, sizeof(line) - 1, file) != NULL) { 945 char *p; 946 uint8_t val; 947 948 lineno++; 949 950 p = line; 951 while (isspace(*p)) 952 p++; 953 954 if (*p == '#') 955 continue; 956 957 if (!strncmp(p, "MC Group", 8)) { 958 ib_member_rec_t mcm_rec; 959 ib_net16_t mlid; 960 unsigned well_known = 0; 961 962 p_mgrp = NULL; 963 memset(&mcm_rec, 0, sizeof(mcm_rec)); 964 965 PARSE_AHEAD(p, net16, " 0x", &mlid); 966 if (strstr(p, "well known")) 967 well_known = 1; 968 PARSE_AHEAD(p, net64, " mgid=0x", 969 &mcm_rec.mgid.unicast.prefix); 970 PARSE_AHEAD(p, net64, ":0x", 971 &mcm_rec.mgid.unicast.interface_id); 972 PARSE_AHEAD(p, net64, " port_gid=0x", 973 &mcm_rec.port_gid.unicast.prefix); 974 PARSE_AHEAD(p, net64, ":0x", 975 &mcm_rec.port_gid.unicast.interface_id); 976 PARSE_AHEAD(p, net32, " qkey=0x", &mcm_rec.qkey); 977 PARSE_AHEAD(p, net16, " mlid=0x", &mcm_rec.mlid); 978 PARSE_AHEAD(p, net8, " mtu=0x", &mcm_rec.mtu); 979 PARSE_AHEAD(p, net8, " tclass=0x", &mcm_rec.tclass); 980 PARSE_AHEAD(p, net16, " pkey=0x", &mcm_rec.pkey); 981 PARSE_AHEAD(p, net8, " rate=0x", &mcm_rec.rate); 982 PARSE_AHEAD(p, net8, " pkt_life=0x", &mcm_rec.pkt_life); 983 PARSE_AHEAD(p, net32, " sl_flow_hop=0x", 984 &mcm_rec.sl_flow_hop); 985 PARSE_AHEAD(p, net8, " scope_state=0x", 986 &mcm_rec.scope_state); 987 PARSE_AHEAD(p, net8, " proxy_join=0x", &val); 988 mcm_rec.proxy_join = val; 989 990 p_mgrp = load_mcgroup(p_osm, mlid, &mcm_rec, 991 well_known); 992 if (!p_mgrp) 993 rereg_clients = 1; 994 } else if (p_mgrp && !strncmp(p, "mcm_port", 8)) { 995 ib_gid_t port_gid; 996 ib_net64_t guid; 997 uint8_t scope_state; 998 boolean_t proxy_join; 999 1000 PARSE_AHEAD(p, net64, " port_gid=0x", 1001 &port_gid.unicast.prefix); 1002 PARSE_AHEAD(p, net64, ":0x", 1003 &port_gid.unicast.interface_id); 1004 PARSE_AHEAD(p, net8, " scope_state=0x", &scope_state); 1005 PARSE_AHEAD(p, net8, " proxy_join=0x", &val); 1006 proxy_join = val; 1007 1008 guid = port_gid.unicast.interface_id; 1009 if (cl_qmap_get(&p_mgrp->mcm_port_tbl, 1010 port_gid.unicast.interface_id) == 1011 cl_qmap_end(&p_mgrp->mcm_port_tbl)) 1012 osm_mgrp_add_port(&p_osm->subn, &p_osm->log, 1013 p_mgrp, &port_gid, 1014 scope_state, proxy_join); 1015 } else if (!strncmp(p, "Service Record:", 15)) { 1016 ib_service_record_t s_rec; 1017 uint32_t modified_time, lease_period; 1018 1019 p_mgrp = NULL; 1020 memset(&s_rec, 0, sizeof(s_rec)); 1021 1022 PARSE_AHEAD(p, net64, " id=0x", &s_rec.service_id); 1023 PARSE_AHEAD(p, net64, " gid=0x", 1024 &s_rec.service_gid.unicast.prefix); 1025 PARSE_AHEAD(p, net64, ":0x", 1026 &s_rec.service_gid.unicast.interface_id); 1027 PARSE_AHEAD(p, net16, " pkey=0x", &s_rec.service_pkey); 1028 PARSE_AHEAD(p, net32, " lease=0x", 1029 &s_rec.service_lease); 1030 PARSE_AHEAD(p, net64, " key=0x", 1031 (ib_net64_t *) (&s_rec.service_key[0])); 1032 PARSE_AHEAD(p, net64, ":0x", 1033 (ib_net64_t *) (&s_rec.service_key[8])); 1034 PARSE_AHEAD(p, string64, " name=", s_rec.service_name); 1035 PARSE_AHEAD(p, net64, " data8=0x", 1036 (ib_net64_t *) (&s_rec.service_data8[0])); 1037 PARSE_AHEAD(p, net64, ":0x", 1038 (ib_net64_t *) (&s_rec.service_data8[8])); 1039 PARSE_AHEAD(p, net64, " data16=0x", 1040 (ib_net64_t *) (&s_rec.service_data16[0])); 1041 PARSE_AHEAD(p, net64, ":0x", 1042 (ib_net64_t *) (&s_rec.service_data16[4])); 1043 PARSE_AHEAD(p, net64, " data32=0x", 1044 (ib_net64_t *) (&s_rec.service_data32[0])); 1045 PARSE_AHEAD(p, net64, ":0x", 1046 (ib_net64_t *) (&s_rec.service_data32[2])); 1047 PARSE_AHEAD(p, net64, " data64=0x", 1048 &s_rec.service_data64[0]); 1049 PARSE_AHEAD(p, net64, ":0x", &s_rec.service_data64[1]); 1050 PARSE_AHEAD(p, net32, " modified_time=0x", 1051 &modified_time); 1052 PARSE_AHEAD(p, net32, " lease_period=0x", 1053 &lease_period); 1054 1055 if (load_svcr(p_osm, &s_rec, cl_ntoh32(modified_time), 1056 cl_ntoh32(lease_period))) 1057 rereg_clients = 1; 1058 } else if (!strncmp(p, "InformInfo Record:", 18)) { 1059 ib_inform_info_record_t i_rec; 1060 osm_mad_addr_t rep_addr; 1061 ib_net16_t val16; 1062 1063 p_mgrp = NULL; 1064 memset(&i_rec, 0, sizeof(i_rec)); 1065 memset(&rep_addr, 0, sizeof(rep_addr)); 1066 1067 PARSE_AHEAD(p, net64, " subscriber_gid=0x", 1068 &i_rec.subscriber_gid.unicast.prefix); 1069 PARSE_AHEAD(p, net64, ":0x", 1070 &i_rec.subscriber_gid.unicast.interface_id); 1071 PARSE_AHEAD(p, net16, " subscriber_enum=0x", 1072 &i_rec.subscriber_enum); 1073 PARSE_AHEAD(p, net64, " gid=0x", 1074 &i_rec.inform_info.gid.unicast.prefix); 1075 PARSE_AHEAD(p, net64, ":0x", 1076 &i_rec.inform_info.gid.unicast. 1077 interface_id); 1078 PARSE_AHEAD(p, net16, " lid_range_begin=0x", 1079 &i_rec.inform_info.lid_range_begin); 1080 PARSE_AHEAD(p, net16, " lid_range_end=0x", 1081 &i_rec.inform_info.lid_range_end); 1082 PARSE_AHEAD(p, net8, " is_generic=0x", 1083 &i_rec.inform_info.is_generic); 1084 PARSE_AHEAD(p, net8, " subscribe=0x", 1085 &i_rec.inform_info.subscribe); 1086 PARSE_AHEAD(p, net16, " trap_type=0x", 1087 &i_rec.inform_info.trap_type); 1088 PARSE_AHEAD(p, net16, " trap_num=0x", 1089 &i_rec.inform_info.g_or_v.generic.trap_num); 1090 PARSE_AHEAD(p, net32, " qpn_resp_time_val=0x", 1091 &i_rec.inform_info.g_or_v.generic. 1092 qpn_resp_time_val); 1093 PARSE_AHEAD(p, net32, " node_type=0x", 1094 (uint32_t *) & i_rec.inform_info.g_or_v. 1095 generic.reserved2); 1096 1097 PARSE_AHEAD(p, net16, " rep_addr: lid=0x", 1098 &rep_addr.dest_lid); 1099 PARSE_AHEAD(p, net8, " path_bits=0x", 1100 &rep_addr.path_bits); 1101 PARSE_AHEAD(p, net8, " static_rate=0x", 1102 &rep_addr.static_rate); 1103 PARSE_AHEAD(p, net32, " remote_qp=0x", 1104 &rep_addr.addr_type.gsi.remote_qp); 1105 PARSE_AHEAD(p, net32, " remote_qkey=0x", 1106 &rep_addr.addr_type.gsi.remote_qkey); 1107 PARSE_AHEAD(p, net16, " pkey_ix=0x", &val16); 1108 rep_addr.addr_type.gsi.pkey_ix = cl_ntoh16(val16); 1109 PARSE_AHEAD(p, net8, " sl=0x", 1110 &rep_addr.addr_type.gsi.service_level); 1111 1112 if (load_infr(p_osm, &i_rec, &rep_addr)) 1113 rereg_clients = 1; 1114 } 1115 } 1116 1117 if (!rereg_clients) 1118 p_osm->subn.opt.no_clients_rereg = TRUE; 1119 1120_error: 1121 fclose(file); 1122 return ret; 1123} 1124