static void nd_rcv_process_nd(IN osm_sm_t * sm, IN osm_node_t * p_node, IN const ib_node_desc_t * p_nd) { char *tmp_desc; char print_desc[IB_NODE_DESCRIPTION_SIZE + 1]; OSM_LOG_ENTER(sm->p_log); memcpy(&p_node->node_desc.description, p_nd, sizeof(*p_nd)); /* also set up a printable version */ memcpy(print_desc, p_nd, sizeof(*p_nd)); print_desc[IB_NODE_DESCRIPTION_SIZE] = '\0'; tmp_desc = remap_node_name(sm->p_subn->p_osm->node_name_map, cl_ntoh64(osm_node_get_node_guid(p_node)), print_desc); /* make a copy for this node to "own" */ if (p_node->print_desc) free(p_node->print_desc); p_node->print_desc = tmp_desc; OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, "Node 0x%" PRIx64 "\n\t\t\t\tDescription = %s\n", cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc); OSM_LOG_EXIT(sm->p_log); }
static void add_path(osm_opensm_t * p_osm, osm_switch_t * p_sw, uint16_t lid, uint8_t port_num, ib_net64_t port_guid) { uint16_t new_lid; uint8_t old_port; new_lid = port_guid ? remap_lid(p_osm, lid, port_guid) : lid; old_port = osm_switch_get_port_by_lid(p_sw, new_lid); if (old_port != OSM_NO_PATH && old_port != port_num) { OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE, "LID collision is detected on switch " "0x016%" PRIx64 ", will overwrite LID %u entry\n", cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)), new_lid); } p_sw->new_lft[new_lid] = port_num; if (!(p_osm->subn.opt.port_profile_switch_nodes && port_guid && osm_get_switch_by_guid(&p_osm->subn, port_guid))) osm_switch_count_path(p_sw, port_num); OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "route 0x%04x(was 0x%04x) %u 0x%016" PRIx64 " is added to switch 0x%016" PRIx64 "\n", new_lid, lid, port_num, cl_ntoh64(port_guid), cl_ntoh64(osm_node_get_node_guid(p_sw->p_node))); }
static void nd_rcv_process_nd(IN osm_sm_t * sm, IN osm_node_t * p_node, IN const ib_node_desc_t * p_nd) { char *tmp_desc; char print_desc[IB_NODE_DESCRIPTION_SIZE + 1]; OSM_LOG_ENTER(sm->p_log); memcpy(&p_node->node_desc.description, p_nd, sizeof(*p_nd)); /* also set up a printable version */ memcpy(print_desc, p_nd, sizeof(*p_nd)); print_desc[IB_NODE_DESCRIPTION_SIZE] = '\0'; tmp_desc = remap_node_name(sm->p_subn->p_osm->node_name_map, cl_ntoh64(osm_node_get_node_guid(p_node)), print_desc); /* make a copy for this node to "own" */ if (p_node->print_desc) free(p_node->print_desc); p_node->print_desc = tmp_desc; #ifdef ENABLE_OSM_PERF_MGR /* update the perfmgr entry if available */ osm_perfmgr_update_nodename(&sm->p_subn->p_osm->perfmgr, cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc); #endif /* ENABLE_OSM_PERF_MGR */ OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, "Node 0x%" PRIx64 ", Description = %s\n", cl_ntoh64(osm_node_get_node_guid(p_node)), p_node->print_desc); OSM_LOG_EXIT(sm->p_log); }
/** =========================================================================== */ static void extract_node(osm_node_t *p_node, uint64_t *p_offset, struct ssa_db_extract *p_ssa_db) { struct ep_map_rec *p_map_rec; #ifdef SSA_PLUGIN_VERBOSE_LOGGING char buffer[64]; if (osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH) sprintf(buffer, " with %s Switch Port 0\n", ib_switch_info_is_enhanced_port0( &p_node->sw->switch_info) ? "Enhanced" : "Base"); else sprintf(buffer, "\n"); ssa_log(SSA_LOG_VERBOSE, "Node GUID 0x%" PRIx64 " Type %d%s", ntohll(osm_node_get_node_guid(p_node)), osm_node_get_type(p_node), buffer); #endif smdb_node_init(p_node, &p_ssa_db->p_node_tbl[*p_offset]); p_map_rec = ep_map_rec_init(*p_offset); if (!p_map_rec) { /* add memory allocation failure handling */ ssa_log(SSA_LOG_VERBOSE, "Quick MAP rec memory allocation failed\n"); } cl_qmap_insert(&p_ssa_db->ep_node_tbl, osm_node_get_node_guid(p_node), &p_map_rec->map_item); *p_offset = *p_offset + 1; }
static void osm_pi_rcv_process_set(IN osm_sm_t * sm, IN osm_node_t * const p_node, IN const uint8_t port_num, IN osm_madw_t * const p_madw) { osm_physp_t *p_physp; ib_net64_t port_guid; ib_smp_t *p_smp; ib_port_info_t *p_pi; osm_pi_context_t *p_context; osm_log_level_t level; OSM_LOG_ENTER(sm->p_log); p_context = osm_madw_get_pi_context_ptr(p_madw); CL_ASSERT(p_node); p_physp = osm_node_get_physp_ptr(p_node, port_num); CL_ASSERT(p_physp); port_guid = osm_physp_get_port_guid(p_physp); p_smp = osm_madw_get_smp_ptr(p_madw); p_pi = (ib_port_info_t *) ib_smp_get_payload_ptr(p_smp); /* check for error */ if (cl_ntoh16(p_smp->status) & 0x7fff) { /* If port already ACTIVE, don't treat status 7 as error */ if (p_context->active_transition && (cl_ntoh16(p_smp->status) & 0x7fff) == 0x1c) { level = OSM_LOG_INFO; OSM_LOG(sm->p_log, OSM_LOG_INFO, "Received error status 0x%x for SetResp() during ACTIVE transition\n", cl_ntoh16(p_smp->status) & 0x7fff); /* Should there be a subsequent Get to validate that port is ACTIVE ? */ } else { level = OSM_LOG_ERROR; OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F10: " "Received error status for SetResp()\n"); } osm_dump_port_info(sm->p_log, osm_node_get_node_guid(p_node), port_guid, port_num, p_pi, level); } OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Received logical SetResp() for GUID 0x%" PRIx64 ", port num %u" "\n\t\t\t\tfor parent node GUID 0x%" PRIx64 " TID 0x%" PRIx64 "\n", cl_ntoh64(port_guid), port_num, cl_ntoh64(osm_node_get_node_guid(p_node)), cl_ntoh64(p_smp->trans_id)); osm_physp_set_port_info(p_physp, p_pi); OSM_LOG_EXIT(sm->p_log); }
static void dump_ucast_path_distribution(cl_map_item_t * item, FILE * file, void *cxt) { osm_node_t *p_node; osm_node_t *p_remote_node; uint8_t i; uint8_t num_ports; uint32_t num_paths; ib_net64_t remote_guid_ho; osm_switch_t *p_sw = (osm_switch_t *) item; p_node = p_sw->p_node; num_ports = p_sw->num_ports; fprintf(file, "dump_ucast_path_distribution: Switch 0x%" PRIx64 "\n" "Port : Path Count Through Port", cl_ntoh64(osm_node_get_node_guid(p_node))); for (i = 0; i < num_ports; i++) { num_paths = osm_switch_path_count_get(p_sw, i); fprintf(file, "\n %03u : %u", i, num_paths); if (i == 0) { fprintf(file, " (switch management port)"); continue; } p_remote_node = osm_node_get_remote_node(p_node, i, NULL); if (p_remote_node == NULL) continue; remote_guid_ho = cl_ntoh64(osm_node_get_node_guid(p_remote_node)); switch (osm_node_get_type(p_remote_node)) { case IB_NODE_TYPE_SWITCH: fprintf(file, " (link to switch"); break; case IB_NODE_TYPE_ROUTER: fprintf(file, " (link to router"); break; case IB_NODE_TYPE_CA: fprintf(file, " (link to CA"); break; default: fprintf(file, " (link to unknown node type"); break; } fprintf(file, " 0x%" PRIx64 ")", remote_guid_ho); } fprintf(file, "\n"); }
static void ni_rcv_get_port_info(IN osm_sm_t * sm, IN osm_node_t * node, IN const osm_madw_t * madw) { osm_madw_context_t context; osm_physp_t *physp; ib_node_info_t *ni; unsigned port; ib_api_status_t status; int mlnx_epi_supported = 0; ni = ib_smp_get_payload_ptr(osm_madw_get_smp_ptr(madw)); port = ib_node_info_get_local_port_num(ni); if (sm->p_subn->opt.fdr10) mlnx_epi_supported = is_mlnx_ext_port_info_supported(ni->device_id); physp = osm_node_get_physp_ptr(node, port); if (!physp) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1E: " "Failed to find physp for port %d of Node GUID 0x%" PRIx64 "\n", port, cl_ntoh64(osm_node_get_node_guid(node))); return; } context.pi_context.node_guid = osm_node_get_node_guid(node); context.pi_context.port_guid = osm_physp_get_port_guid(physp); context.pi_context.set_method = FALSE; context.pi_context.light_sweep = FALSE; context.pi_context.active_transition = FALSE; context.pi_context.client_rereg = FALSE; status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp), IB_MAD_ATTR_PORT_INFO, cl_hton32(port), TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD02: " "Failure initiating PortInfo request (%s)\n", ib_get_err_str(status)); if (mlnx_epi_supported) { status = osm_req_get(sm, osm_physp_get_dr_path_ptr(physp), IB_MAD_ATTR_MLNX_EXTENDED_PORT_INFO, cl_hton32(port), TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D0B: " "Failure initiating MLNX ExtPortInfo request (%s)\n", ib_get_err_str(status)); } }
static qos_mad_item_t *osm_qos_mad_create(IN osm_sm_t * sm, IN osm_physp_t * p, IN uint32_t data_size, IN uint8_t * p_data, IN ib_net16_t attr_id, IN uint32_t attr_mod) { qos_mad_item_t *p_mad; osm_madw_context_t context; osm_madw_t *p_madw; osm_node_t *p_node; p_node = osm_physp_get_node_ptr(p); switch (attr_id){ case IB_MAD_ATTR_SLVL_TABLE: context.slvl_context.node_guid = osm_node_get_node_guid(p_node); context.slvl_context.port_guid = osm_physp_get_port_guid(p); context.slvl_context.set_method = TRUE; break; case IB_MAD_ATTR_VL_ARBITRATION: context.vla_context.node_guid = osm_node_get_node_guid(p_node); context.vla_context.port_guid = osm_physp_get_port_guid(p); context.vla_context.set_method = TRUE; break; default: return NULL; } p_mad = (qos_mad_item_t *) malloc(sizeof(*p_mad)); if (!p_mad) return NULL; memset(p_mad, 0, sizeof(*p_mad)); p_madw = osm_prepare_req_set(sm, osm_physp_get_dr_path_ptr(p), p_data, data_size, attr_id, cl_hton32(attr_mod), CL_DISP_MSGID_NONE, &context); if (p_madw == NULL) { free(p_mad); return NULL; } p_mad->p_madw = p_madw; return p_mad; }
static void dump_roots(cl_map_item_t *item, FILE *file, void *cxt) { osm_switch_t *sw = (osm_switch_t *)item; if (!((struct updn_node *)sw->priv)->rank) fprintf(file, "0x%" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(sw->p_node))); }
static void state_mgr_get_sw_info(IN cl_map_item_t * p_object, IN void *context) { osm_node_t *p_node; osm_dr_path_t *p_dr_path; osm_madw_context_t mad_context; osm_switch_t *const p_sw = (osm_switch_t *) p_object; osm_sm_t *sm = context; ib_api_status_t status; OSM_LOG_ENTER(sm->p_log); p_node = p_sw->p_node; p_dr_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_node, 0)); memset(&mad_context, 0, sizeof(mad_context)); mad_context.si_context.node_guid = osm_node_get_node_guid(p_node); mad_context.si_context.set_method = FALSE; mad_context.si_context.light_sweep = TRUE; status = osm_req_get(sm, p_dr_path, IB_MAD_ATTR_SWITCH_INFO, 0, OSM_MSG_LIGHT_SWEEP_FAIL, &mad_context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3304: " "Request for SwitchInfo failed (%s)\n", ib_get_err_str(status)); OSM_LOG_EXIT(sm->p_log); }
/********************************************************************** The plock must be held before calling this function. **********************************************************************/ static void ni_rcv_get_node_desc(IN osm_sm_t * sm, IN osm_node_t * p_node, IN const osm_madw_t * p_madw) { ib_node_info_t *p_ni; ib_smp_t *p_smp; uint8_t port_num; osm_physp_t *p_physp = NULL; OSM_LOG_ENTER(sm->p_log); p_smp = osm_madw_get_smp_ptr(p_madw); p_ni = ib_smp_get_payload_ptr(p_smp); port_num = ib_node_info_get_local_port_num(p_ni); /* Request PortInfo & NodeDescription attributes for the port that responded to the NodeInfo attribute. Because this is a channel adapter or router, we are not allowed to request PortInfo for the other ports. Set the context union properly, so the recipient knows which node & port are relevant. */ p_physp = osm_node_get_physp_ptr(p_node, port_num); if (!p_physp) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR OD1F: " "Failed to find physp for port %d of Node GUID 0x%" PRIx64 "\n", port_num, cl_ntoh64(osm_node_get_node_guid(p_node))); return; } osm_req_get_node_desc(sm, p_physp); OSM_LOG_EXIT(sm->p_log); }
static void ni_rcv_process_switch(IN osm_sm_t * sm, IN osm_node_t * p_node, IN const osm_madw_t * p_madw) { ib_api_status_t status = IB_SUCCESS; osm_physp_t *p_physp; osm_madw_context_t context; osm_dr_path_t *path; ib_smp_t *p_smp; OSM_LOG_ENTER(sm->p_log); p_smp = osm_madw_get_smp_ptr(p_madw); p_physp = osm_node_get_physp_ptr(p_node, 0); /* update DR path of already initialized switch port 0 */ path = osm_physp_get_dr_path_ptr(p_physp); osm_dr_path_init(path, p_smp->hop_count, p_smp->initial_path); context.si_context.node_guid = osm_node_get_node_guid(p_node); context.si_context.set_method = FALSE; context.si_context.light_sweep = FALSE; context.si_context.lft_top_change = FALSE; /* Request a SwitchInfo attribute */ status = osm_req_get(sm, path, IB_MAD_ATTR_SWITCH_INFO, 0, TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) /* continue despite error */ OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D06: " "Failure initiating SwitchInfo request (%s)\n", ib_get_err_str(status)); OSM_LOG_EXIT(sm->p_log); }
static void dump_lid_matrix(cl_map_item_t * item, FILE * file, void *cxt) { osm_switch_t *p_sw = (osm_switch_t *) item; osm_opensm_t *p_osm = cxt; osm_node_t *p_node = p_sw->p_node; unsigned max_lid = p_sw->max_lid_ho; unsigned max_port = p_sw->num_ports; uint16_t lid; uint8_t port; fprintf(file, "Switch: guid 0x%016" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(p_node))); for (lid = 1; lid <= max_lid; lid++) { osm_port_t *p_port; if (osm_switch_get_least_hops(p_sw, lid) == OSM_NO_PATH) continue; fprintf(file, "0x%04x:", lid); for (port = 0; port < max_port; port++) fprintf(file, " %02x", osm_switch_get_hop_count(p_sw, lid, port)); p_port = osm_get_port_by_lid_ho(&p_osm->subn, lid); if (p_port) fprintf(file, " # portguid 0x%016" PRIx64, cl_ntoh64(osm_port_get_guid(p_port))); fprintf(file, "\n"); } }
static void ucast_mgr_process_neighbor(IN osm_ucast_mgr_t * p_mgr, IN osm_switch_t * p_this_sw, IN osm_switch_t * p_remote_sw, IN uint8_t port_num, IN uint8_t remote_port_num) { osm_switch_t *p_sw; cl_map_item_t *item; uint16_t lid_ho; uint16_t hops; osm_physp_t *p; OSM_LOG_ENTER(p_mgr->p_log); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Node 0x%" PRIx64 ", remote node 0x%" PRIx64 ", port %u, remote port %u\n", cl_ntoh64(osm_node_get_node_guid(p_this_sw->p_node)), cl_ntoh64(osm_node_get_node_guid(p_remote_sw->p_node)), port_num, remote_port_num); p = osm_node_get_physp_ptr(p_this_sw->p_node, port_num); for (item = cl_qmap_head(&p_mgr->p_subn->sw_guid_tbl); item != cl_qmap_end(&p_mgr->p_subn->sw_guid_tbl); item = cl_qmap_next(item)) { p_sw = (osm_switch_t *) item; lid_ho = cl_ntoh16(osm_node_get_base_lid(p_sw->p_node, 0)); hops = osm_switch_get_least_hops(p_remote_sw, lid_ho); if (hops == OSM_NO_PATH) continue; hops += p->hop_wf; if (hops < osm_switch_get_hop_count(p_this_sw, lid_ho, port_num)) { if (osm_switch_set_hops (p_this_sw, lid_ho, port_num, (uint8_t) hops) != 0) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A03: " "cannot set hops for lid %u at switch 0x%" PRIx64 "\n", lid_ho, cl_ntoh64(osm_node_get_node_guid (p_this_sw->p_node))); p_mgr->some_hop_count_set = TRUE; } } OSM_LOG_EXIT(p_mgr->p_log); }
static void __osm_ucast_mgr_process_neighbor(IN osm_ucast_mgr_t * const p_mgr, IN osm_switch_t * const p_this_sw, IN osm_switch_t * const p_remote_sw, IN const uint8_t port_num, IN const uint8_t remote_port_num) { osm_switch_t *p_sw, *p_next_sw; uint16_t lid_ho; uint8_t hops; OSM_LOG_ENTER(p_mgr->p_log); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Node 0x%" PRIx64 ", remote node 0x%" PRIx64 ", port %u, remote port %u\n", cl_ntoh64(osm_node_get_node_guid(p_this_sw->p_node)), cl_ntoh64(osm_node_get_node_guid(p_remote_sw->p_node)), port_num, remote_port_num); p_next_sw = (osm_switch_t *) cl_qmap_head(&p_mgr->p_subn->sw_guid_tbl); while (p_next_sw != (osm_switch_t *) cl_qmap_end(&p_mgr->p_subn->sw_guid_tbl)) { p_sw = p_next_sw; p_next_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item); lid_ho = osm_node_get_base_lid(p_sw->p_node, 0); lid_ho = cl_ntoh16(lid_ho); hops = osm_switch_get_least_hops(p_remote_sw, lid_ho); if (hops == OSM_NO_PATH) continue; hops++; if (hops < osm_switch_get_hop_count(p_this_sw, lid_ho, port_num)) { if (osm_switch_set_hops (p_this_sw, lid_ho, port_num, hops) != 0) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "cannot set hops for lid %u at switch 0x%" PRIx64 "\n", lid_ho, cl_ntoh64(osm_node_get_node_guid (p_this_sw->p_node))); p_mgr->some_hop_count_set = TRUE; } } OSM_LOG_EXIT(p_mgr->p_log); }
static osm_signal_t __osm_link_mgr_process_node(osm_sm_t * sm, IN osm_node_t * const p_node, IN const uint8_t link_state) { uint32_t i; uint32_t num_physp; osm_physp_t *p_physp; uint8_t current_state; osm_signal_t signal = OSM_SIGNAL_DONE; OSM_LOG_ENTER(sm->p_log); OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Node 0x%" PRIx64 " going to %s\n", cl_ntoh64(osm_node_get_node_guid(p_node)), ib_get_port_state_str(link_state)); /* Set the PortInfo for every Physical Port associated with this Port. Start iterating with port 1, since the linkstate is not applicable to the management port on switches. */ num_physp = osm_node_get_num_physp(p_node); for (i = 0; i < num_physp; i++) { /* Don't bother doing anything if this Physical Port is not valid. or if the state of the port is already better then the specified state. */ p_physp = osm_node_get_physp_ptr(p_node, (uint8_t) i); if (!p_physp) continue; current_state = osm_physp_get_port_state(p_physp); if (current_state == IB_LINK_DOWN) continue; /* Normally we only send state update if state is lower then required state. However, we need to send update if no state change required. */ if (link_state != IB_LINK_NO_CHANGE && link_state <= current_state) OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Physical port %u already %s. Skipping\n", p_physp->port_num, ib_get_port_state_str(current_state)); else if (__osm_link_mgr_set_physp_pi(sm, p_physp, link_state)) signal = OSM_SIGNAL_DONE_PENDING; } OSM_LOG_EXIT(sm->p_log); return (signal); }
static void state_mgr_update_node_desc(IN cl_map_item_t * obj, IN void *context) { osm_madw_context_t mad_context; osm_node_t *p_node = (osm_node_t *) obj; osm_sm_t *sm = context; osm_physp_t *p_physp = NULL; unsigned i, num_ports; ib_api_status_t status; OSM_LOG_ENTER(sm->p_log); CL_ASSERT(p_node); OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Updating NodeDesc for 0x%016" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(p_node))); /* get a physp to request from. */ num_ports = osm_node_get_num_physp(p_node); for (i = 0; i < num_ports; i++) if ((p_physp = osm_node_get_physp_ptr(p_node, i))) break; if (!p_physp) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 331C: " "Failed to find any valid physical port object.\n"); goto exit; } mad_context.nd_context.node_guid = osm_node_get_node_guid(p_node); status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp), IB_MAD_ATTR_NODE_DESC, 0, CL_DISP_MSGID_NONE, &mad_context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 331B: Failure initiating NodeDescription request " "(%s)\n", ib_get_err_str(status)); exit: OSM_LOG_EXIT(sm->p_log); }
/** ========================================================================= */ void ep_node_tbl_rec_init(osm_node_t *p_node, struct ep_node_tbl_rec *p_rec) { p_rec->node_guid = osm_node_get_node_guid(p_node); if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH) p_rec->is_enhanced_sp0 = ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info); else p_rec->is_enhanced_sp0 = 0; p_rec->node_type = p_node->node_info.node_type; memcpy(p_rec->description, p_node->node_desc.description, sizeof(p_rec->description)); memset(&p_rec->pad, 0, sizeof(p_rec->pad)); }
static void __osm_ucast_mgr_process_neighbors(IN cl_map_item_t * const p_map_item, IN void *context) { osm_switch_t *const p_sw = (osm_switch_t *) p_map_item; osm_ucast_mgr_t *const p_mgr = (osm_ucast_mgr_t *) context; osm_node_t *p_node; osm_node_t *p_remote_node; uint32_t port_num; uint8_t remote_port_num; uint32_t num_ports; osm_physp_t *p_physp; OSM_LOG_ENTER(p_mgr->p_log); p_node = p_sw->p_node; CL_ASSERT(p_node); CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Processing switch with GUID 0x%" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(p_node))); num_ports = osm_node_get_num_physp(p_node); /* Start with port 1 to skip the switch's management port. */ for (port_num = 1; port_num < num_ports; port_num++) { p_remote_node = osm_node_get_remote_node(p_node, (uint8_t) port_num, &remote_port_num); if (p_remote_node && p_remote_node->sw && (p_remote_node != p_node)) { /* make sure the link is healthy. If it is not - don't propagate through it. */ p_physp = osm_node_get_physp_ptr(p_node, port_num); if (!p_physp || !osm_link_is_healthy(p_physp)) continue; __osm_ucast_mgr_process_neighbor(p_mgr, p_sw, p_remote_node->sw, (uint8_t) port_num, remote_port_num); } } OSM_LOG_EXIT(p_mgr->p_log); }
static struct updn_node *create_updn_node(osm_switch_t * sw) { struct updn_node *u; u = malloc(sizeof(*u)); if (!u) return NULL; memset(u, 0, sizeof(*u)); u->sw = sw; u->id = cl_ntoh64(osm_node_get_node_guid(sw->p_node)); u->rank = 0xffffffff; return u; }
/********************************************************************** The plock must be held before calling this function. **********************************************************************/ static void pi_rcv_process_switch_port0(IN osm_sm_t * sm, IN osm_node_t * p_node, IN osm_physp_t * p_physp, IN ib_port_info_t * p_pi) { ib_api_status_t status; osm_madw_context_t context; uint8_t port, num_ports; OSM_LOG_ENTER(sm->p_log); if (p_physp->need_update) sm->p_subn->ignore_existing_lfts = TRUE; pi_rcv_check_and_fix_lid(sm->p_log, p_pi, p_physp); /* Update the PortInfo attribute */ osm_physp_set_port_info(p_physp, p_pi, sm); /* Determine if base switch port 0 */ if (p_node->sw && !ib_switch_info_is_enhanced_port0(&p_node->sw->switch_info)) /* PortState is not used on BSP0 but just in case it is DOWN */ p_physp->port_info = *p_pi; /* Now, query PortInfo for the switch external ports */ num_ports = osm_node_get_num_physp(p_node); context.pi_context.node_guid = osm_node_get_node_guid(p_node); context.pi_context.port_guid = osm_physp_get_port_guid(p_physp); context.pi_context.set_method = FALSE; context.pi_context.light_sweep = FALSE; context.pi_context.active_transition = FALSE; context.pi_context.client_rereg = FALSE; for (port = 1; port < num_ports; port++) { status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp), IB_MAD_ATTR_PORT_INFO, cl_hton32(port), FALSE, ib_port_info_get_m_key(&p_physp->port_info), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0F16: " "Failure initiating PortInfo request (%s)\n", ib_get_err_str(status)); } pi_rcv_process_endport(sm, p_physp, p_pi); OSM_LOG_EXIT(sm->p_log); }
static int set_lft_block(IN osm_switch_t *p_sw, IN osm_ucast_mgr_t *p_mgr, IN uint16_t block_id_ho) { uint8_t block[IB_SMP_DATA_SIZE]; osm_madw_context_t context; osm_dr_path_t *p_path; ib_api_status_t status; /* Send linear forwarding table blocks to the switch as long as the switch indicates it has blocks needing configuration. */ if (!p_sw->new_lft) { /* any routing should provide the new_lft */ CL_ASSERT(p_mgr->p_subn->opt.use_ucast_cache && p_mgr->cache_valid && !p_sw->need_update); return -1; } p_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_sw->p_node, 0)); context.lft_context.node_guid = osm_node_get_node_guid(p_sw->p_node); context.lft_context.set_method = TRUE; if (!osm_switch_get_lft_block(p_sw, block_id_ho, block) || (!p_sw->need_update && !p_mgr->p_subn->need_update && !memcmp(block, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE))) return 0; OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Writing FT block %u to switch 0x%" PRIx64 "\n", block_id_ho, cl_ntoh64(context.lft_context.node_guid)); status = osm_req_set(p_mgr->sm, p_path, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE, IB_MAD_ATTR_LIN_FWD_TBL, cl_hton32(block_id_ho), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) { OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A05: " "Sending linear fwd. tbl. block failed (%s)\n", ib_get_err_str(status)); return -1; } return 0; }
static void __osm_ucast_mgr_process_tbl(IN cl_map_item_t * const p_map_item, IN void *context) { osm_ucast_mgr_t *p_mgr = context; osm_switch_t *const p_sw = (osm_switch_t *) p_map_item; unsigned i, lids_per_port; OSM_LOG_ENTER(p_mgr->p_log); CL_ASSERT(p_sw && p_sw->p_node); OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Processing switch 0x%" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid(p_sw->p_node))); /* Initialize LIDs in buffer to invalid port number. */ memset(p_sw->new_lft, OSM_NO_PATH, IB_LID_UCAST_END_HO + 1); if (p_mgr->p_subn->opt.lmc) alloc_ports_priv(p_mgr); /* Iterate through every port setting LID routes for each port based on base LID and LMC value. */ lids_per_port = 1 << p_mgr->p_subn->opt.lmc; for (i = 0; i < lids_per_port; i++) { cl_qlist_t *list = &p_mgr->port_order_list; cl_list_item_t *item; for (item = cl_qlist_head(list); item != cl_qlist_end(list); item = cl_qlist_next(item)) { osm_port_t *port = cl_item_obj(item, port, list_item); __osm_ucast_mgr_process_port(p_mgr, p_sw, port, i); } } osm_ucast_mgr_set_fwd_table(p_mgr, p_sw); if (p_mgr->p_subn->opt.lmc) free_ports_priv(p_mgr); OSM_LOG_EXIT(p_mgr->p_log); }
static ib_api_status_t __osm_mftr_rcv_new_mftr(IN osm_sa_t * sa, IN osm_switch_t * const p_sw, IN cl_qlist_t * const p_list, IN ib_net16_t const lid, IN uint16_t const block, IN uint8_t const position) { osm_mftr_item_t *p_rec_item; ib_api_status_t status = IB_SUCCESS; uint16_t position_block_num; OSM_LOG_ENTER(sa->p_log); p_rec_item = malloc(sizeof(*p_rec_item)); if (p_rec_item == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4A02: " "rec_item alloc failed\n"); status = IB_INSUFFICIENT_RESOURCES; goto Exit; } OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "New MulticastForwardingTable: sw 0x%016" PRIx64 "\n\t\t\t\tblock %u position %u lid %u\n", cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)), block, position, cl_ntoh16(lid)); position_block_num = ((uint16_t) position << 12) | (block & IB_MCAST_BLOCK_ID_MASK_HO); memset(p_rec_item, 0, sizeof(*p_rec_item)); p_rec_item->rec.lid = lid; p_rec_item->rec.position_block_num = cl_hton16(position_block_num); /* copy the mft block */ osm_switch_get_mft_block(p_sw, block, position, p_rec_item->rec.mft); cl_qlist_insert_tail(p_list, &p_rec_item->list_item); Exit: OSM_LOG_EXIT(sa->p_log); return (status); }
/********************************************************************** The plock must be held before calling this function. **********************************************************************/ static void si_rcv_get_fwd_tbl(IN osm_sm_t * sm, IN osm_switch_t * p_sw) { osm_madw_context_t context; osm_dr_path_t *p_dr_path; osm_physp_t *p_physp; osm_node_t *p_node; uint32_t block_id_ho; uint32_t max_block_id_ho; ib_api_status_t status = IB_SUCCESS; OSM_LOG_ENTER(sm->p_log); CL_ASSERT(p_sw); p_node = p_sw->p_node; CL_ASSERT(osm_node_get_type(p_node) == IB_NODE_TYPE_SWITCH); context.lft_context.node_guid = osm_node_get_node_guid(p_node); context.lft_context.set_method = FALSE; max_block_id_ho = osm_switch_get_max_block_id_in_use(p_sw); p_physp = osm_node_get_physp_ptr(p_node, 0); p_dr_path = osm_physp_get_dr_path_ptr(p_physp); for (block_id_ho = 0; block_id_ho <= max_block_id_ho; block_id_ho++) { OSM_LOG(sm->p_log, OSM_LOG_DEBUG, "Retrieving FT block %u\n", block_id_ho); status = osm_req_get(sm, p_dr_path, IB_MAD_ATTR_LIN_FWD_TBL, cl_hton32(block_id_ho), CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) /* continue the loop despite the error */ OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3603: " "Failure initiating PortInfo request (%s)\n", ib_get_err_str(status)); } OSM_LOG_EXIT(sm->p_log); }
/********************************************************************** Initiate a remote port info request for the given physical port **********************************************************************/ static void state_mgr_get_remote_port_info(IN osm_sm_t * sm, IN osm_physp_t * p_physp) { osm_dr_path_t *p_dr_path; osm_dr_path_t rem_node_dr_path; osm_madw_context_t mad_context; ib_api_status_t status; OSM_LOG_ENTER(sm->p_log); /* generate a dr path leaving on the physp to the remote node */ p_dr_path = osm_physp_get_dr_path_ptr(p_physp); memcpy(&rem_node_dr_path, p_dr_path, sizeof(osm_dr_path_t)); if (osm_dr_path_extend(&rem_node_dr_path, osm_physp_get_port_num(p_physp))) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 332D: " "DR path with hop count %d couldn't be extended " "so skipping PortInfo query\n", p_dr_path->hop_count); goto Exit; } memset(&mad_context, 0, sizeof(mad_context)); mad_context.pi_context.node_guid = osm_node_get_node_guid(osm_physp_get_node_ptr(p_physp)); mad_context.pi_context.port_guid = p_physp->port_guid; mad_context.pi_context.set_method = FALSE; mad_context.pi_context.light_sweep = TRUE; mad_context.pi_context.active_transition = FALSE; /* note that with some negative logic - if the query failed it means * that there is no point in going to heavy sweep */ status = osm_req_get(sm, &rem_node_dr_path, IB_MAD_ATTR_PORT_INFO, 0, CL_DISP_MSGID_NONE, &mad_context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 332E: " "Request for PortInfo failed (%s)\n", ib_get_err_str(status)); Exit: OSM_LOG_EXIT(sm->p_log); }
/********************************************************************** The plock must be held before calling this function. **********************************************************************/ void osm_req_get_node_desc(IN osm_sm_t * sm, osm_physp_t * p_physp) { ib_api_status_t status = IB_SUCCESS; osm_madw_context_t context; OSM_LOG_ENTER(sm->p_log); context.nd_context.node_guid = osm_node_get_node_guid(osm_physp_get_node_ptr(p_physp)); status = osm_req_get(sm, osm_physp_get_dr_path_ptr(p_physp), IB_MAD_ATTR_NODE_DESC, 0, TRUE, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D03: " "Failure initiating NodeDescription request (%s)\n", ib_get_err_str(status)); OSM_LOG_EXIT(sm->p_log); }
static int ucast_mgr_setup_all_switches(osm_subn_t * p_subn) { osm_switch_t *p_sw; uint16_t lids; lids = (uint16_t) cl_ptr_vector_get_size(&p_subn->port_lid_tbl); lids = lids ? lids - 1 : 0; for (p_sw = (osm_switch_t *) cl_qmap_head(&p_subn->sw_guid_tbl); p_sw != (osm_switch_t *) cl_qmap_end(&p_subn->sw_guid_tbl); p_sw = (osm_switch_t *) cl_qmap_next(&p_sw->map_item)) if (osm_switch_prepare_path_rebuild(p_sw, lids)) { OSM_LOG(&p_subn->p_osm->log, OSM_LOG_ERROR, "ERR 3A0B: " "cannot setup switch 0x%016" PRIx64 "\n", cl_ntoh64(osm_node_get_node_guid (p_sw->p_node))); return -1; } return 0; }
static ib_api_status_t __osm_lftr_rcv_new_lftr(IN osm_sa_t * sa, IN const osm_switch_t * const p_sw, IN cl_qlist_t * const p_list, IN ib_net16_t const lid, IN uint16_t const block) { osm_lftr_item_t *p_rec_item; ib_api_status_t status = IB_SUCCESS; OSM_LOG_ENTER(sa->p_log); p_rec_item = malloc(sizeof(*p_rec_item)); if (p_rec_item == NULL) { OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4402: " "rec_item alloc failed\n"); status = IB_INSUFFICIENT_RESOURCES; goto Exit; } OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "New LinearForwardingTable: sw 0x%016" PRIx64 "\n\t\t\t\tblock 0x%02X lid %u\n", cl_ntoh64(osm_node_get_node_guid(p_sw->p_node)), block, cl_ntoh16(lid)); memset(p_rec_item, 0, sizeof(*p_rec_item)); p_rec_item->rec.lid = lid; p_rec_item->rec.block_num = cl_hton16(block); /* copy the lft block */ osm_switch_get_lft_block(p_sw, block, p_rec_item->rec.lft); cl_qlist_insert_tail(p_list, &p_rec_item->list_item); Exit: OSM_LOG_EXIT(sa->p_log); return (status); }
static ib_api_status_t sl2vl_update_table(osm_sm_t * sm, osm_physp_t * p, uint8_t in_port, uint8_t out_port, unsigned force_update, const ib_slvl_table_t * sl2vl_table) { osm_madw_context_t context; ib_slvl_table_t tbl, *p_tbl; osm_node_t *p_node = osm_physp_get_node_ptr(p); uint32_t attr_mod; unsigned vl_mask; uint8_t vl1, vl2; int i; vl_mask = (1 << (ib_port_info_get_op_vls(&p->port_info) - 1)) - 1; for (i = 0; i < IB_MAX_NUM_VLS / 2; i++) { vl1 = sl2vl_table->raw_vl_by_sl[i] >> 4; vl2 = sl2vl_table->raw_vl_by_sl[i] & 0xf; if (vl1 != 15) vl1 &= vl_mask; if (vl2 != 15) vl2 &= vl_mask; tbl.raw_vl_by_sl[i] = (vl1 << 4) | vl2; } if (!force_update && (p_tbl = osm_physp_get_slvl_tbl(p, in_port)) && !memcmp(p_tbl, &tbl, sizeof(tbl))) return IB_SUCCESS; context.slvl_context.node_guid = osm_node_get_node_guid(p_node); context.slvl_context.port_guid = osm_physp_get_port_guid(p); context.slvl_context.set_method = TRUE; attr_mod = in_port << 8 | out_port; return osm_req_set(sm, osm_physp_get_dr_path_ptr(p), (uint8_t *) & tbl, sizeof(tbl), IB_MAD_ATTR_SLVL_TABLE, cl_hton32(attr_mod), CL_DISP_MSGID_NONE, &context); }