boolean_t osm_node_link_exists(IN osm_node_t * p_node, IN uint8_t port_num, IN osm_node_t * p_remote_node, IN uint8_t remote_port_num) { osm_physp_t *p_physp; osm_physp_t *p_remote_physp; CL_ASSERT(port_num < p_node->physp_tbl_size); CL_ASSERT(remote_port_num < p_remote_node->physp_tbl_size); p_physp = osm_node_get_physp_ptr(p_node, port_num); p_remote_physp = osm_node_get_physp_ptr(p_remote_node, remote_port_num); return osm_physp_link_exists(p_physp, p_remote_physp); }
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); }
static struct osm_remote_node * osm_switch_find_guid_common(IN const osm_switch_t * const p_sw, IN struct osm_remote_guids_count *r, IN uint8_t port_num, IN int find_sys_guid, IN int find_node_guid) { struct osm_remote_node *p_remote_guid = NULL; osm_physp_t *p_physp; osm_physp_t *p_rem_physp; osm_node_t *p_rem_node; uint64_t sys_guid; uint64_t node_guid; int i; CL_ASSERT(p_sw); p_physp = osm_node_get_physp_ptr(p_sw->p_node, port_num); p_rem_physp = osm_physp_get_remote(p_physp); p_rem_node = osm_physp_get_node_ptr(p_rem_physp); sys_guid = p_rem_node->node_info.sys_guid; node_guid = p_rem_node->node_info.node_guid; for (i = 0; i < r->count; i++) { if ((!find_sys_guid || r->guids[i].node->node_info.sys_guid == sys_guid) && (!find_node_guid || r->guids[i].node->node_info.node_guid == node_guid)) { p_remote_guid = &r->guids[i]; break; } } return p_remote_guid; }
void osm_node_link(IN osm_node_t * p_node, IN uint8_t port_num, IN osm_node_t * p_remote_node, IN uint8_t remote_port_num) { osm_physp_t *p_physp; osm_physp_t *p_remote_physp; p_physp = osm_node_get_physp_ptr(p_node, port_num); p_remote_physp = osm_node_get_physp_ptr(p_remote_node, remote_port_num); if (p_physp->p_remote_physp) p_physp->p_remote_physp->p_remote_physp = NULL; if (p_remote_physp->p_remote_physp) p_remote_physp->p_remote_physp->p_remote_physp = NULL; osm_physp_link(p_physp, p_remote_physp); }
boolean_t osm_node_has_any_link(IN osm_node_t * p_node, IN uint8_t port_num) { osm_physp_t *p_physp; CL_ASSERT(port_num < p_node->physp_tbl_size); p_physp = osm_node_get_physp_ptr(p_node, port_num); return osm_physp_has_any_link(p_physp); }
/********************************************************************** 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 report_duplicated_guid(IN osm_sm_t * sm, osm_physp_t * p_physp, osm_node_t * p_neighbor_node, const uint8_t port_num) { osm_physp_t *p_old, *p_new; osm_dr_path_t path; p_old = p_physp->p_remote_physp; p_new = osm_node_get_physp_ptr(p_neighbor_node, port_num); OSM_LOG(sm->p_log, OSM_LOG_SYS | OSM_LOG_ERROR, "ERR 0D01: " "Found duplicated node GUID.\n" "Node 0x%" PRIx64 " port %u is reachable from remote node " "0x%" PRIx64 " port %u and remote node 0x%" PRIx64 " port %u.\n" "Paths are:\n", cl_ntoh64(p_physp->p_node->node_info.node_guid), p_physp->port_num, p_old ? cl_ntoh64(p_old->p_node->node_info.node_guid) : 0, p_old ? p_old->port_num : 0, p_new ? cl_ntoh64(p_new->p_node->node_info.node_guid) : 0, p_new ? p_new->port_num : 0); osm_dump_dr_path_v2(sm->p_log, osm_physp_get_dr_path_ptr(p_physp), FILE_ID, OSM_LOG_ERROR); path = *osm_physp_get_dr_path_ptr(p_new); if (osm_dr_path_extend(&path, port_num)) OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 0D05: " "DR path with hop count %d couldn't be extended\n", path.hop_count); osm_dump_dr_path_v2(sm->p_log, &path, FILE_ID, OSM_LOG_ERROR); }
static int mark_ignored_port(void *ctx, uint64_t guid, char *p) { osm_ucast_mgr_t *m = ctx; osm_node_t *node = osm_get_node_by_guid(m->p_subn, cl_hton64(guid)); osm_physp_t *physp; unsigned port; if (!node || !node->sw) { OSM_LOG(m->p_log, OSM_LOG_DEBUG, "switch with guid 0x%016" PRIx64 " is not found\n", guid); return 0; } if (!p || !*p || !(port = strtoul(p, NULL, 0)) || port >= node->sw->num_ports) { OSM_LOG(m->p_log, OSM_LOG_DEBUG, "bad port specified for guid 0x%016" PRIx64 "\n", guid); return 0; } physp = osm_node_get_physp_ptr(node, port); if (!physp) return 0; physp->is_prof_ignored = 1; return 0; }
/** ========================================================================= */ void ep_port_tbl_rec_init(osm_physp_t *p_physp, struct ep_port_tbl_rec *p_rec) { const ib_port_info_t *p_pi; const osm_physp_t *p_physp0; uint8_t is_fdr10_active; uint8_t is_switch; if (osm_node_get_type(p_physp->p_node) == IB_NODE_TYPE_SWITCH && osm_physp_get_port_num(p_physp) > 0) { /* for SW external ports, port 0 Capability Mask is used */ p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_physp->p_node, 0); p_pi = &p_physp0->port_info; } else { p_pi = &p_physp->port_info; } is_fdr10_active = ((p_physp->ext_port_info.link_speed_active & FDR10) ? 0xff : 0) & SSA_DB_PORT_IS_FDR10_ACTIVE_MASK; is_switch = ((osm_node_get_type(p_physp->p_node) == IB_NODE_TYPE_SWITCH) ? 0xff : 0) & SSA_DB_PORT_IS_SWITCH_MASK; p_rec->pkey_tbl_offset = 0; p_rec->pkey_tbl_size = 0; p_rec->port_lid = osm_physp_get_base_lid(p_physp); p_rec->port_num = osm_physp_get_port_num(p_physp); p_rec->neighbor_mtu = ib_port_info_get_neighbor_mtu(&p_physp->port_info); p_rec->rate = ib_port_info_compute_rate(&p_physp->port_info, p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS) & SSA_DB_PORT_RATE_MASK; p_rec->vl_enforce = p_physp->port_info.vl_enforce; p_rec->rate = (uint8_t) (p_rec->rate | is_fdr10_active | is_switch); }
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 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); }
void osm_node_unlink(IN osm_node_t * p_node, IN uint8_t port_num, IN osm_node_t * p_remote_node, IN uint8_t remote_port_num) { osm_physp_t *p_physp; osm_physp_t *p_remote_physp; CL_ASSERT(port_num < p_node->physp_tbl_size); CL_ASSERT(remote_port_num < p_remote_node->physp_tbl_size); if (osm_node_link_exists(p_node, port_num, p_remote_node, remote_port_num)) { p_physp = osm_node_get_physp_ptr(p_node, port_num); p_remote_physp = osm_node_get_physp_ptr(p_remote_node, remote_port_num); osm_physp_unlink(p_physp, p_remote_physp); } }
static void set_default_hop_wf(cl_map_item_t * p_map_item, void *ctx) { osm_switch_t *sw = (osm_switch_t *) p_map_item; int i; for (i = 1; i < sw->num_ports; i++) { osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, i); if (p) p->hop_wf = 1; } }
static void clear_prof_ignore_flag(cl_map_item_t * p_map_item, void *ctx) { osm_switch_t *sw = (osm_switch_t *) p_map_item; int i; for (i = 1; i < sw->num_ports; i++) { osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, i); if (p) p->is_prof_ignored = 0; } }
static void sw_count_endport_links(osm_switch_t * sw) { osm_physp_t *p; int i; sw->endport_links = 0; for (i = 1; i < sw->num_ports; i++) { p = osm_node_get_physp_ptr(sw->p_node, i); if (p && p->p_remote_physp && !p->p_remote_physp->p_node->sw) sw->endport_links++; } }
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 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 void dump_sl2vl_tbl(cl_map_item_t * item, FILE * file, void *cxt) { osm_port_t *p_port = (osm_port_t *) item; osm_node_t *p_node = p_port->p_node; uint32_t in_port, out_port, num_ports = p_node->node_info.num_ports; ib_net16_t base_lid = osm_port_get_base_lid(p_port); osm_physp_t *p_physp; ib_slvl_table_t *p_tbl; int i, n; char buf[1024]; const char * header_line = "#in out : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"; const char * separator_line = "#--------------------------------------------------------"; if (!num_ports) return; fprintf(file, "%s 0x%016" PRIx64 ", base LID %d, " "\"%s\"\n%s\n%s\n", ib_get_node_type_str(p_node->node_info.node_type), cl_ntoh64(p_port->guid), cl_ntoh16(base_lid), p_node->print_desc, header_line, separator_line); if (p_node->node_info.node_type == IB_NODE_TYPE_SWITCH) { for (out_port = 0; out_port <= num_ports; out_port++){ p_physp = osm_node_get_physp_ptr(p_node, out_port); /* no need to print SL2VL table for port that is down */ if (!p_physp || !p_physp->p_remote_physp) continue; for (in_port = 0; in_port <= num_ports; in_port++) { p_tbl = osm_physp_get_slvl_tbl(p_physp, in_port); for (i = 0, n = 0; i < 16; i++) n += sprintf(buf + n, " %-2d", ib_slvl_table_get(p_tbl, i)); fprintf(file, "%-3d %-3d :%s\n", in_port, out_port, buf); } } } else { p_physp = p_port->p_physp; p_tbl = osm_physp_get_slvl_tbl(p_physp, 0); for (i = 0, n = 0; i < 16; i++) n += sprintf(buf + n, " %-2d", ib_slvl_table_get(p_tbl, i)); fprintf(file, "%-3d %-3d :%s\n", 0, 0, buf); } fprintf(file, "%s\n\n", separator_line); }
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; }
/********************************************************************** The lock must be held before calling this function. **********************************************************************/ ib_net16_t osm_node_get_remote_base_lid(IN osm_node_t * p_node, IN uint32_t port_num) { osm_physp_t *p_physp; osm_physp_t *p_remote_physp; CL_ASSERT(port_num < p_node->physp_tbl_size); p_physp = osm_node_get_physp_ptr(p_node, port_num); if (p_physp) { p_remote_physp = osm_physp_get_remote(p_physp); return osm_physp_get_base_lid(p_remote_physp); } return 0; }
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 struct osm_remote_node * find_and_add_remote_sys(osm_switch_t *sw, uint8_t port, struct osm_remote_guids_count *r) { unsigned i; osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, port); osm_node_t *node = p->p_remote_physp->p_node; for (i = 0; i < r->count; i++) if (r->guids[i].node == node) return &r->guids[i]; r->guids[i].node = node; r->guids[i].forwarded_to = 0; r->count++; return &r->guids[i]; }
static void osm_lash_process_switch(lash_t * p_lash, osm_switch_t * p_sw) { osm_log_t *p_log = &p_lash->p_osm->log; int i, port_count; osm_physp_t *p_current_physp, *p_remote_physp; unsigned switch_a_lash_id, switch_b_lash_id; OSM_LOG_ENTER(p_log); switch_a_lash_id = get_lash_id(p_sw); port_count = osm_node_get_num_physp(p_sw->p_node); /* starting at port 1, ignoring management port on switch */ for (i = 1; i < port_count; i++) { p_current_physp = osm_node_get_physp_ptr(p_sw->p_node, i); if (p_current_physp) { p_remote_physp = p_current_physp->p_remote_physp; if (p_remote_physp && p_remote_physp->p_node->sw) { int physical_port_a_num = osm_physp_get_port_num(p_current_physp); int physical_port_b_num = osm_physp_get_port_num(p_remote_physp); switch_b_lash_id = get_lash_id(p_remote_physp->p_node->sw); connect_switches(p_lash, switch_a_lash_id, switch_b_lash_id, physical_port_a_num); OSM_LOG(p_log, OSM_LOG_VERBOSE, "LASH SUCCESS connected G 0x%016" PRIx64 " , lash_id(%u), P(%u) " " to G 0x%016" PRIx64 " , lash_id(%u) , P(%u)\n", cl_ntoh64(osm_physp_get_port_guid (p_current_physp)), switch_a_lash_id, physical_port_a_num, cl_ntoh64(osm_physp_get_port_guid (p_remote_physp)), switch_b_lash_id, physical_port_b_num); } } } OSM_LOG_EXIT(p_log); }
osm_node_t *osm_node_get_remote_node(IN osm_node_t * p_node, IN uint8_t port_num, OUT uint8_t * p_remote_port_num) { osm_physp_t *p_physp; osm_physp_t *p_remote_physp; p_physp = osm_node_get_physp_ptr(p_node, port_num); if (!p_physp || !osm_physp_has_any_link(p_physp)) return NULL; p_remote_physp = osm_physp_get_remote(p_physp); if (p_remote_port_num) *p_remote_port_num = osm_physp_get_port_num(p_remote_physp); return osm_physp_get_node_ptr(p_remote_physp); }
/********************************************************************** 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); }
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); }
static void add_sw_endports_to_order_list(osm_switch_t * sw, osm_ucast_mgr_t * m) { osm_port_t *port; osm_physp_t *p; int i; for (i = 1; i < sw->num_ports; i++) { p = osm_node_get_physp_ptr(sw->p_node, i); if (p && p->p_remote_physp && !p->p_remote_physp->p_node->sw) { port = osm_get_port_by_guid(m->p_subn, p->p_remote_physp-> port_guid); if (!port) continue; cl_qlist_insert_tail(&m->port_order_list, &port->list_item); port->flag = 1; } } }
static struct osm_remote_node *find_and_add_remote_sys(osm_switch_t * sw, uint8_t port, boolean_t dor, struct osm_remote_guids_count *r) { unsigned i; osm_physp_t *p = osm_node_get_physp_ptr(sw->p_node, port); osm_node_t *node = p->p_remote_physp->p_node; uint8_t rem_port = osm_physp_get_port_num(p->p_remote_physp); for (i = 0; i < r->count; i++) if (r->guids[i].node == node) if (!dor || (r->guids[i].port == rem_port)) return &r->guids[i]; r->guids[i].node = node; r->guids[i].forwarded_to = 0; r->guids[i].port = rem_port; r->count++; return &r->guids[i]; }
static int set_hop_wf(void *ctx, uint64_t guid, char *p) { osm_ucast_mgr_t *m = ctx; osm_node_t *node = osm_get_node_by_guid(m->p_subn, cl_hton64(guid)); osm_physp_t *physp; unsigned port, hop_wf; char *e; if (!node || !node->sw) { OSM_LOG(m->p_log, OSM_LOG_DEBUG, "switch with guid 0x%016" PRIx64 " is not found\n", guid); return 0; } if (!p || !*p || !(port = strtoul(p, &e, 0)) || (p == e) || port >= node->sw->num_ports) { OSM_LOG(m->p_log, OSM_LOG_DEBUG, "bad port specified for guid 0x%016" PRIx64 "\n", guid); return 0; } p = e + 1; if (!*p || !(hop_wf = strtoul(p, &e, 0)) || p == e || hop_wf >= 0x100) { OSM_LOG(m->p_log, OSM_LOG_DEBUG, "bad hop weight factor specified for guid 0x%016" PRIx64 "port %u\n", guid, port); return 0; } physp = osm_node_get_physp_ptr(node, port); if (!physp) return 0; physp->hop_wf = hop_wf; return 0; }