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 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); }
int osm_ucast_mgr_set_fwd_table(IN osm_ucast_mgr_t * const p_mgr, IN osm_switch_t * const p_sw) { osm_node_t *p_node; osm_dr_path_t *p_path; osm_madw_context_t context; ib_api_status_t status; ib_switch_info_t si; uint16_t block_id_ho = 0; uint8_t block[IB_SMP_DATA_SIZE]; boolean_t set_swinfo_require = FALSE; uint16_t lin_top; uint8_t life_state; CL_ASSERT(p_mgr); OSM_LOG_ENTER(p_mgr->p_log); CL_ASSERT(p_sw); p_node = p_sw->p_node; CL_ASSERT(p_node); p_path = osm_physp_get_dr_path_ptr(osm_node_get_physp_ptr(p_node, 0)); /* Set the top of the unicast forwarding table. */ si = p_sw->switch_info; lin_top = cl_hton16(p_sw->max_lid_ho); if (lin_top != si.lin_top) { set_swinfo_require = TRUE; si.lin_top = lin_top; } /* check to see if the change state bit is on. If it is - then we need to clear it. */ if (ib_switch_info_get_state_change(&si)) life_state = ((p_mgr->p_subn->opt.packet_life_time << 3) | (si.life_state & IB_SWITCH_PSC)) & 0xfc; else life_state = (p_mgr->p_subn->opt.packet_life_time << 3) & 0xf8; if ((life_state != si.life_state) || ib_switch_info_get_state_change(&si)) { set_swinfo_require = TRUE; si.life_state = life_state; } if (set_swinfo_require) { OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Setting switch FT top to LID %u\n", p_sw->max_lid_ho); context.si_context.light_sweep = FALSE; context.si_context.node_guid = osm_node_get_node_guid(p_node); context.si_context.set_method = TRUE; status = osm_req_set(p_mgr->sm, p_path, (uint8_t *) & si, sizeof(si), IB_MAD_ATTR_SWITCH_INFO, 0, CL_DISP_MSGID_NONE, &context); if (status != IB_SUCCESS) OSM_LOG(p_mgr->p_log, OSM_LOG_ERROR, "ERR 3A06: " "Sending SwitchInfo attribute failed (%s)\n", ib_get_err_str(status)); } /* Send linear forwarding table blocks to the switch as long as the switch indicates it has blocks needing configuration. */ context.lft_context.node_guid = osm_node_get_node_guid(p_node); context.lft_context.set_method = TRUE; 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); goto Exit; } for (block_id_ho = 0; osm_switch_get_lft_block(p_sw, block_id_ho, block); block_id_ho++) { if (!p_sw->need_update && !memcmp(block, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, IB_SMP_DATA_SIZE)) continue; OSM_LOG(p_mgr->p_log, OSM_LOG_DEBUG, "Writing FT block %u\n", block_id_ho); status = osm_req_set(p_mgr->sm, p_path, p_sw->new_lft + block_id_ho * IB_SMP_DATA_SIZE, sizeof(block), 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)); } Exit: OSM_LOG_EXIT(p_mgr->p_log); return 0; }