osm_switch_t *osm_switch_new(IN osm_node_t * p_node, IN const osm_madw_t * p_madw) { osm_switch_t *p_sw; ib_switch_info_t *p_si; ib_smp_t *p_smp; uint8_t num_ports; uint32_t port_num; CL_ASSERT(p_madw); CL_ASSERT(p_node); p_smp = osm_madw_get_smp_ptr(p_madw); p_si = ib_smp_get_payload_ptr(p_smp); num_ports = osm_node_get_num_physp(p_node); CL_ASSERT(p_smp->attr_id == IB_MAD_ATTR_SWITCH_INFO); if (!p_si->lin_cap) /* The switch doesn't support LFT */ return NULL; p_sw = malloc(sizeof(*p_sw)); if (!p_sw) return NULL; memset(p_sw, 0, sizeof(*p_sw)); p_sw->p_node = p_node; p_sw->switch_info = *p_si; p_sw->num_ports = num_ports; p_sw->need_update = 2; p_sw->p_prof = malloc(sizeof(*p_sw->p_prof) * num_ports); if (!p_sw->p_prof) goto err; memset(p_sw->p_prof, 0, sizeof(*p_sw->p_prof) * num_ports); osm_mcast_tbl_init(&p_sw->mcast_tbl, osm_node_get_num_physp(p_node), cl_ntoh16(p_si->mcast_cap)); for (port_num = 0; port_num < num_ports; port_num++) osm_port_prof_construct(&p_sw->p_prof[port_num]); return p_sw; err: osm_switch_delete(&p_sw); return NULL; }
osm_switch_t *osm_switch_new(IN osm_node_t * const p_node, IN const osm_madw_t * const p_madw) { ib_api_status_t status; osm_switch_t *p_sw; CL_ASSERT(p_madw); CL_ASSERT(p_node); p_sw = (osm_switch_t *) malloc(sizeof(*p_sw)); if (p_sw) { memset(p_sw, 0, sizeof(*p_sw)); status = osm_switch_init(p_sw, p_node, p_madw); if (status != IB_SUCCESS) osm_switch_delete(&p_sw); } return (p_sw); }
/********************************************************************** Lock must be held on entry to this function. **********************************************************************/ static void si_rcv_process_new(IN osm_sm_t * sm, IN osm_node_t * p_node, IN const osm_madw_t * p_madw) { osm_switch_t *p_sw; osm_switch_t *p_check; ib_switch_info_t *p_si; ib_smp_t *p_smp; cl_qmap_t *p_sw_guid_tbl; CL_ASSERT(sm); OSM_LOG_ENTER(sm->p_log); CL_ASSERT(p_madw); p_sw_guid_tbl = &sm->p_subn->sw_guid_tbl; p_smp = osm_madw_get_smp_ptr(p_madw); p_si = ib_smp_get_payload_ptr(p_smp); osm_dump_switch_info_v2(sm->p_log, p_si, FILE_ID, OSM_LOG_DEBUG); p_sw = osm_switch_new(p_node, p_madw); if (p_sw == NULL) { OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3608: " "Unable to allocate new switch object\n"); goto Exit; } /* set subnet max mlid to the minimum MulticastFDBCap of all switches */ if (cl_ntoh16(p_si->mcast_cap) + IB_LID_MCAST_START_HO - 1 < sm->p_subn->max_mcast_lid_ho) { sm->p_subn->max_mcast_lid_ho = cl_ntoh16(p_si->mcast_cap) + IB_LID_MCAST_START_HO - 1; OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, "Subnet max multicast lid is 0x%X\n", sm->p_subn->max_mcast_lid_ho); } /* set subnet max unicast lid to the minimum LinearFDBCap of all switches */ if (cl_ntoh16(p_si->lin_cap) < sm->p_subn->max_ucast_lid_ho) { sm->p_subn->max_ucast_lid_ho = cl_ntoh16(p_si->lin_cap); OSM_LOG(sm->p_log, OSM_LOG_VERBOSE, "Subnet max unicast lid is 0x%X\n", sm->p_subn->max_ucast_lid_ho); } p_check = (osm_switch_t *) cl_qmap_insert(p_sw_guid_tbl, osm_node_get_node_guid (p_node), &p_sw->map_item); if (p_check != p_sw) { /* This shouldn't happen since we hold the lock! */ OSM_LOG(sm->p_log, OSM_LOG_ERROR, "ERR 3605: " "Unable to add new switch object to database\n"); osm_switch_delete(&p_sw); goto Exit; } p_node->sw = p_sw; /* Update the switch info according to the info we just received. */ osm_switch_set_switch_info(p_sw, p_si); #if 0 /* Don't bother retrieving the current unicast and multicast tables from the switches. The current version of SM does not support silent take-over of an existing multicast configuration. Gathering the multicast tables can also generate large amounts of extra subnet-init traffic. The code to retrieve the tables was fully debugged. */ si_rcv_get_fwd_tbl(sm, p_sw); if (!sm->p_subn->opt.disable_multicast) si_rcv_get_mcast_fwd_tbl(sm, p_sw); #endif Exit: OSM_LOG_EXIT(sm->p_log); }