Пример #1
0
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);
}
Пример #2
0
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);
}
Пример #3
0
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;
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
/**********************************************************************
 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);
}
Пример #7
0
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);
}
Пример #8
0
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);
}
Пример #9
0
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;
}
Пример #10
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);
}
Пример #11
0
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);
}
Пример #12
0
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);
}
Пример #13
0
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);
	}
}
Пример #14
0
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;
	}
}
Пример #15
0
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;
	}
}
Пример #16
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++;
	}
}
Пример #17
0
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);
}
Пример #18
0
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));
	}
}
Пример #19
0
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);
}
Пример #20
0
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;
}
Пример #21
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;
}
Пример #22
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);
}
Пример #23
0
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];
}
Пример #24
0
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);
}
Пример #25
0
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);
}
Пример #26
0
/**********************************************************************
 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);
}
Пример #27
0
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);
}
Пример #28
0
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;
		}
	}
}
Пример #29
0
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];
}
Пример #30
0
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;
}