Пример #1
0
static int send_144_node_desc_update(void)
{
	ib_portid_t sm_port;
	ib_portid_t selfportid;
	int selfport;
	ib_rpc_t trap_rpc;
	ib_mad_notice_attr_t notice;

	if (ib_resolve_self(&selfportid, &selfport, NULL))
		IBERROR("can't resolve self");

	if (ib_resolve_smlid(&sm_port, 0))
		IBERROR("can't resolve SM destination port");

	memset(&trap_rpc, 0, sizeof(trap_rpc));
	trap_rpc.mgtclass = IB_SMI_CLASS;
	trap_rpc.method = IB_MAD_METHOD_TRAP;
	trap_rpc.trid = mad_trid();
	trap_rpc.attr.id = NOTICE;
	trap_rpc.datasz = IB_SMP_DATA_SIZE;
	trap_rpc.dataoffs = IB_SMP_DATA_OFFS;

	memset(&notice, 0, sizeof(notice));
	notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
	notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA);
	notice.g_or_v.generic.trap_num = cl_hton16(144);
	notice.issuer_lid = cl_hton16(selfportid.lid);
	notice.data_details.ntc_144.lid = cl_hton16(selfportid.lid);
	notice.data_details.ntc_144.local_changes =
	    TRAP_144_MASK_OTHER_LOCAL_CHANGES;
	notice.data_details.ntc_144.change_flgs =
	    TRAP_144_MASK_NODE_DESCRIPTION_CHANGE;

	return (mad_send(&trap_rpc, &sm_port, NULL, &notice));
}
Пример #2
0
static void build_trap145(ib_mad_notice_attr_t * n, ib_portid_t * port)
{
	n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
	n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
	n->g_or_v.generic.trap_num = cl_hton16(145);
	n->issuer_lid = cl_hton16((uint16_t) port->lid);
	n->data_details.ntc_145.new_sys_guid = cl_hton64(0x1234567812345678);
}
Пример #3
0
static void build_trap129(ib_mad_notice_attr_t * n, ib_portid_t * port)
{
	n->generic_type = 0x80 | IB_NOTICE_TYPE_URGENT;
	n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
	n->g_or_v.generic.trap_num = cl_hton16(129);
	n->issuer_lid = cl_hton16((uint16_t) port->lid);
	n->data_details.ntc_129_131.lid = n->issuer_lid;
	n->data_details.ntc_129_131.pad = 0;
	n->data_details.ntc_129_131.port_num = (uint8_t) error_port;
}
Пример #4
0
static void build_trap144_local(ib_mad_notice_attr_t * n, ib_portid_t * port)
{
	n->generic_type = 0x80 | IB_NOTICE_TYPE_INFO;
	n->g_or_v.generic.prod_type_lsb = cl_hton16(get_node_type(port));
	n->g_or_v.generic.trap_num = cl_hton16(144);
	n->issuer_lid = cl_hton16((uint16_t) port->lid);
	n->data_details.ntc_144.lid = n->issuer_lid;
	n->data_details.ntc_144.new_cap_mask = cl_hton32(get_cap_mask(port));
	n->data_details.ntc_144.local_changes =
	    TRAP_144_MASK_OTHER_LOCAL_CHANGES;
}
Пример #5
0
static int partition_create(unsigned lineno, struct part_conf *conf,
			    char *name, char *id, char *flag, char *flag_val)
{
	ib_net16_t pkey;

	if (!id && name && isdigit(*name)) {
		id = name;
		name = NULL;
	}

	if (id) {
		char *end;

		pkey = cl_hton16((uint16_t)strtoul(id, &end, 0));
		if (end == id || *end)
			return -1;
	} else
		pkey = 0;

	conf->p_prtn = osm_prtn_make_new(conf->p_log, conf->p_subn,
					 name, pkey);
	if (!conf->p_prtn)
		return -1;

	if (!conf->p_subn->opt.qos && conf->flags.sl != OSM_DEFAULT_SL) {
		OSM_LOG(conf->p_log, OSM_LOG_DEBUG, "Overriding SL %d"
			" to default SL %d on partition %s"
			" as QoS is not enabled.\n",
			conf->flags.sl, OSM_DEFAULT_SL, name);
		conf->flags.sl = OSM_DEFAULT_SL;
	}
	conf->p_prtn->sl = (uint8_t) conf->flags.sl;

	if (conf->is_ipoib) {
		struct precreate_mgroup broadcast_mgroup;
		memset(&broadcast_mgroup, 0, sizeof(broadcast_mgroup));
		broadcast_mgroup.mgid = osm_ipoib_broadcast_mgid;
		pkey |= cl_hton16(0x8000);
		memcpy(&broadcast_mgroup.mgid.raw[4], &pkey , sizeof(pkey));
		broadcast_mgroup.flags.mtu = conf->flags.mtu;
		broadcast_mgroup.flags.rate = conf->flags.rate;
		broadcast_mgroup.flags.sl = conf->flags.sl;
		broadcast_mgroup.flags.Q_Key = conf->flags.Q_Key ?
						conf->flags.Q_Key :
						OSM_IPOIB_BROADCAST_MGRP_QKEY;
		broadcast_mgroup.flags.TClass = conf->flags.TClass;
		broadcast_mgroup.flags.FlowLabel = conf->flags.FlowLabel;
		__create_mgrp(conf, &broadcast_mgroup);
	}

	return 0;
}
Пример #6
0
osm_prtn_t *osm_prtn_make_new(osm_log_t * p_log, osm_subn_t * p_subn,
			      const char *name, uint16_t pkey)
{
	osm_prtn_t *p = NULL, *p_check;

	pkey &= cl_hton16((uint16_t) ~ 0x8000);
	if (!pkey) {
		if (name && (p = osm_prtn_find_by_name(p_subn, name)))
			return p;
		if (!(pkey = generate_pkey(p_subn)))
			return NULL;
	}

	p = osm_prtn_new(name, pkey);
	if (!p) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "Unable to create"
			" partition \'%s\' (0x%04x)\n", name, cl_ntoh16(pkey));
		return NULL;
	}

	p_check = (osm_prtn_t *) cl_qmap_insert(&p_subn->prtn_pkey_tbl,
						p->pkey, &p->map_item);
	if (p != p_check) {
		OSM_LOG(p_log, OSM_LOG_VERBOSE, "Duplicated partition"
			" definition: \'%s\' (0x%04x) prev name \'%s\'"
			".  Will use it\n",
			name, cl_ntoh16(pkey), p_check->name);
		osm_prtn_delete(p_subn, &p);
		p = p_check;
	}

	return p;
}
Пример #7
0
void osm_prtn_delete(IN osm_subn_t * p_subn, IN OUT osm_prtn_t ** pp_prtn)
{
	char gid_str[INET6_ADDRSTRLEN];
	int i = 0;
	osm_prtn_t *p = *pp_prtn;

	cl_map_remove_all(&p->full_guid_tbl);
	cl_map_destroy(&p->full_guid_tbl);
	cl_map_remove_all(&p->part_guid_tbl);
	cl_map_destroy(&p->part_guid_tbl);

	if (p->mgrps) {
		/* Clean up mgrps */
		for (i = 0; i < p->nmgrps; i++) {
			/* osm_mgrp_cleanup will not delete
			 * "well_known" groups */
			p->mgrps[i]->well_known = FALSE;
			OSM_LOG(&p_subn->p_osm->log, OSM_LOG_DEBUG,
				"removing mgroup %s from partition (0x%x)\n",
				inet_ntop(AF_INET6,
					  p->mgrps[i]->mcmember_rec.mgid.raw,
					  gid_str, sizeof gid_str),
				cl_hton16(p->pkey));
			osm_mgrp_cleanup(p_subn, p->mgrps[i]);
		}

		free(p->mgrps);
	}

	free(p);
	*pp_prtn = NULL;
}
Пример #8
0
static void mpr_rcv_build_pr(IN osm_sa_t * sa,
			     IN const osm_alias_guid_t * p_src_alias_guid,
			     IN const osm_alias_guid_t * p_dest_alias_guid,
			     IN uint16_t src_lid_ho, IN uint16_t dest_lid_ho,
			     IN uint8_t preference,
			     IN const osm_path_parms_t * p_parms,
			     OUT ib_path_rec_t * p_pr)
{
	const osm_physp_t *p_src_physp, *p_dest_physp;

	OSM_LOG_ENTER(sa->p_log);

	p_src_physp = p_src_alias_guid->p_base_port->p_physp;
	p_dest_physp = p_dest_alias_guid->p_base_port->p_physp;

	p_pr->dgid.unicast.prefix = osm_physp_get_subnet_prefix(p_dest_physp);
	p_pr->dgid.unicast.interface_id = osm_physp_get_port_guid(p_dest_physp);

	p_pr->sgid.unicast.prefix = osm_physp_get_subnet_prefix(p_src_physp);
	p_pr->sgid.unicast.interface_id = osm_physp_get_port_guid(p_src_physp);

	p_pr->dlid = cl_hton16(dest_lid_ho);
	p_pr->slid = cl_hton16(src_lid_ho);

	p_pr->hop_flow_raw &= cl_hton32(1 << 31);

	p_pr->pkey = p_parms->pkey;
	ib_path_rec_set_qos_class(p_pr, 0);
	ib_path_rec_set_sl(p_pr, p_parms->sl);
	p_pr->mtu = (uint8_t) (p_parms->mtu | 0x80);
	p_pr->rate = (uint8_t) (p_parms->rate | 0x80);

	/* According to 1.2 spec definition Table 205 PacketLifeTime description,
	   for loopback paths, packetLifeTime shall be zero. */
	if (p_src_alias_guid->p_base_port == p_dest_alias_guid->p_base_port)
		p_pr->pkt_life = 0x80;	/* loopback */
	else
		p_pr->pkt_life = (uint8_t) (p_parms->pkt_life | 0x80);

	p_pr->preference = preference;

	/* always return num_path = 0 so this is only the reversible component */
	if (p_parms->reversible)
		p_pr->num_path = 0x80;

	OSM_LOG_EXIT(sa->p_log);
}
Пример #9
0
void osm_pkey_tbl_set_indx0_pkey(IN osm_log_t * p_log, IN ib_net16_t pkey,
				 IN boolean_t full,
				 OUT osm_pkey_tbl_t * p_pkey_tbl)
{
	p_pkey_tbl->indx0_pkey = (full == TRUE) ?
				 pkey | cl_hton16(0x8000) : pkey;
	OSM_LOG(p_log, OSM_LOG_DEBUG, "pkey 0x%04x set at indx0\n",
		cl_ntoh16(p_pkey_tbl->indx0_pkey));
}
Пример #10
0
static void
__osmv_ibms_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend,
				 IN struct _ibms_mad_addr *p_ibms_addr,
				 IN uint8_t is_smi,
				 OUT osm_mad_addr_t * p_osm_addr)
{
	memset(p_osm_addr, 0, sizeof(osm_mad_addr_t));
	p_osm_addr->dest_lid = cl_hton16(p_ibms_addr->slid);
	p_osm_addr->static_rate = 0;
	p_osm_addr->path_bits = 0;
	if (is_smi) {
		/* SMI */
		p_osm_addr->addr_type.smi.source_lid =
		    cl_hton16(p_ibms_addr->slid);
		p_osm_addr->addr_type.smi.port_num = 1;	/* TODO add if required p_ibms_addr->port; */
	} else {
		/* GSI */
		p_osm_addr->addr_type.gsi.remote_qp =
		    cl_ntoh32(p_ibms_addr->sqpn);
		p_osm_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
		p_osm_addr->addr_type.gsi.pkey_ix = p_ibms_addr->pkey_index;
		p_osm_addr->addr_type.gsi.service_level = p_ibms_addr->sl;

		p_osm_addr->addr_type.gsi.global_route = FALSE;
		/* copy the GRH data if relevant - TopSpin imp doesnt relate to GRH!!! */
		/*
		   if (p_osm_addr->addr_type.gsi.global_route)
		   {
		   p_osm_addr->addr_type.gsi.grh_info.ver_class_flow =
		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
		   p_rcv_desc->grh.traffic_class,
		   p_rcv_desc->grh.flow_label);
		   p_osm_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
		   memcpy(&p_osm_addr->addr_type.gsi.grh_info.src_gid.raw,
		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
		   memcpy(&p_osm_addr->addr_type.gsi.grh_info.dest_gid.raw,
		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
		   }
		 */
	}
}
Пример #11
0
static void
__osmv_TOPSPIN_mad_addr_to_osm_addr(IN osm_vendor_t const *p_vend,
				    IN struct ib_mad *p_mad,
				    IN uint8_t is_smi,
				    OUT osm_mad_addr_t * p_mad_addr)
{
	p_mad_addr->dest_lid = cl_hton16(p_mad->slid);
	p_mad_addr->static_rate = 0;
	p_mad_addr->path_bits = 0;
	if (is_smi) {
		/* SMI */
		p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid);
		p_mad_addr->addr_type.smi.port_num = p_mad->port;
	} else {
		/* GSI */
		p_mad_addr->addr_type.gsi.remote_qp = cl_ntoh32(p_mad->sqpn);
		p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
		/*  There is a TAVOR limitation that only one P_KEY is supported per */
		/*  QP - so QP1 must use IB_DEFAULT_PKEY */
		p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index;
		p_mad_addr->addr_type.gsi.service_level = p_mad->sl;

		p_mad_addr->addr_type.gsi.global_route = FALSE;
		/* copy the GRH data if relevant - TopSpin imp doesnt relate to GRH!!! */
		/*
		   if (p_mad_addr->addr_type.gsi.global_route)
		   {
		   p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
		   p_rcv_desc->grh.traffic_class,
		   p_rcv_desc->grh.flow_label);
		   p_mad_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
		   }
		 */
	}
}
Пример #12
0
static int mgroup_create(char *p, char *mgid, unsigned lineno, struct part_conf *conf)
{
	int ret = 0;
	struct precreate_mgroup mgroup;

	memset(&mgroup, 0, sizeof(mgroup));

	if (inet_pton(AF_INET6, mgid, &mgroup.mgid) != 1
	    || mgroup.mgid.raw[0] != 0xff) {
		OSM_LOG(conf->p_log, OSM_LOG_ERROR,
			"PARSE ERROR partition conf file line %d: "
			"mgid \"%s\": gid is not multicast\n", lineno, mgid);
		return 0;
	}

	/* inherit partition flags */
	mgroup.flags.mtu = conf->flags.mtu;
	mgroup.flags.rate = conf->flags.rate;
	mgroup.flags.sl = conf->flags.sl;
	mgroup.flags.Q_Key = conf->flags.Q_Key;
	mgroup.flags.FlowLabel = conf->flags.FlowLabel;
	mgroup.flags.scope_mask = conf->flags.scope_mask;

	/* override with user specified flags */
	ret = parse_mgroup_flags(conf->p_log, &mgroup, p, lineno);

	/* check/verify special IP group parameters */
	if (mgid_is_ip(&mgroup.mgid)) {
		ib_net16_t pkey = conf->p_prtn->pkey | cl_hton16(0x8000);

		if (!ip_mgroup_pkey_ok(conf, &mgroup)
		    || !ip_mgroup_rate_ok(conf, &mgroup)
		    || !ip_mgroup_mtu_ok(conf, &mgroup))
			goto error;

		/* set special IP settings */
		memcpy(&mgroup.mgid.raw[4], &pkey, sizeof(pkey));

		if (mgroup.flags.Q_Key == 0)
			mgroup.flags.Q_Key = OSM_IPOIB_BROADCAST_MGRP_QKEY;
	}

	/* don't create multiple copies of the group */
	if (osm_get_mgrp_by_mgid(conf->p_subn, &mgroup.mgid))
		goto error;

	/* create the group */
	__create_mgrp(conf, &mgroup);

error:
	return ret;
}
Пример #13
0
static uint16_t generate_pkey(osm_subn_t * p_subn)
{
	uint16_t pkey;

	cl_qmap_t *m = &p_subn->prtn_pkey_tbl;
	while (global_pkey_counter < cl_ntoh16(IB_DEFAULT_PARTIAL_PKEY) - 1) {
		pkey = ++global_pkey_counter;
		pkey = cl_hton16(pkey);
		if (cl_qmap_get(m, pkey) == cl_qmap_end(m))
			return pkey;
	}
	return 0;
}
Пример #14
0
/**********************************************************************
 * TS MAD to OSM ADDRESS VECTOR
 **********************************************************************/
void
__osm_ts_conv_mad_rcv_desc_to_osm_addr(IN osm_vendor_t * const p_vend,
				       IN struct ib_mad *p_mad,
				       IN uint8_t is_smi,
				       OUT osm_mad_addr_t * p_mad_addr)
{
	p_mad_addr->dest_lid = cl_hton16(p_mad->slid);
	p_mad_addr->static_rate = 0;	/*  HACK - we do not know the rate ! */
	p_mad_addr->path_bits = 0;	/*  HACK - no way to know in TS */
	if (is_smi) {
		/* SMI */
		p_mad_addr->addr_type.smi.source_lid = cl_hton16(p_mad->slid);
		p_mad_addr->addr_type.smi.port_num = p_mad->port;
	} else {
		/* GSI */
		p_mad_addr->addr_type.gsi.remote_qp = p_mad->sqpn;
		p_mad_addr->addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
		p_mad_addr->addr_type.gsi.pkey_ix = p_mad->pkey_index;
		p_mad_addr->addr_type.gsi.service_level = 0;	/*  HACK no way to know */

		p_mad_addr->addr_type.gsi.global_route = FALSE;	/*  HACK no way to know */
		/* copy the GRH data if relevant */
		/*
		   if (p_mad_addr->addr_type.gsi.global_route)
		   {
		   p_mad_addr->addr_type.gsi.grh_info.ver_class_flow =
		   ib_grh_set_ver_class_flow(p_rcv_desc->grh.IP_version,
		   p_rcv_desc->grh.traffic_class,
		   p_rcv_desc->grh.flow_label);
		   p_mad_addr->addr_type.gsi.grh_info.hop_limit =  p_rcv_desc->grh.hop_limit;
		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.src_gid.raw,
		   &p_rcv_desc->grh.sgid, sizeof(ib_net64_t));
		   memcpy(&p_mad_addr->addr_type.gsi.grh_info.dest_gid.raw,
		   p_rcv_desc->grh.dgid,  sizeof(ib_net64_t));
		   }
		 */
	}
}
Пример #15
0
ib_api_status_t osm_prtn_add_mcgroup(osm_log_t * p_log, osm_subn_t * p_subn,
				     osm_prtn_t * p, uint8_t rate, uint8_t mtu,
				     uint8_t sl, uint8_t scope, uint32_t Q_Key,
				     uint8_t tclass, uint32_t FlowLabel,
				     const ib_gid_t *mgid)
{
	char gid_str[INET6_ADDRSTRLEN];
	ib_member_rec_t mc_rec;
	ib_net64_t comp_mask;
	ib_net16_t pkey;
	osm_mgrp_t *mgrp;
	osm_sa_t *p_sa = &p_subn->p_osm->sa;
	uint8_t hop_limit;

	pkey = p->pkey | cl_hton16(0x8000);
	if (!scope)
		scope = OSM_DEFAULT_MGRP_SCOPE;
	hop_limit = (scope == IB_MC_SCOPE_LINK_LOCAL) ? 0 : IB_HOPLIMIT_MAX;

	memset(&mc_rec, 0, sizeof(mc_rec));

	mc_rec.mgid = *mgid;

	mc_rec.qkey = CL_HTON32(Q_Key);
	mc_rec.mtu = mtu | (IB_PATH_SELECTOR_EXACTLY << 6);
	mc_rec.tclass = tclass;
	mc_rec.pkey = pkey;
	mc_rec.rate = rate | (IB_PATH_SELECTOR_EXACTLY << 6);
	mc_rec.pkt_life = p_subn->opt.subnet_timeout;
	mc_rec.sl_flow_hop = ib_member_set_sl_flow_hop(sl, FlowLabel, hop_limit);
	/* Scope in MCMemberRecord (if present) needs to be consistent with MGID */
	mc_rec.scope_state =
	    ib_member_set_scope_state(scope, IB_MC_REC_STATE_FULL_MEMBER);
	ib_mgid_set_scope(&mc_rec.mgid, scope);

	/* don't update rate, mtu */
	comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL |
	    IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
	mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(p_sa, comp_mask, &mc_rec);
	if (!mgrp) {
		OSM_LOG(p_log, OSM_LOG_ERROR,
			"Failed to create MC group (%s) with pkey 0x%04x\n",
			inet_ntop(AF_INET6, mgid->raw, gid_str, sizeof gid_str),
			cl_ntoh16(pkey));
		return IB_ERROR;
	}

	return (track_mgrp_w_partition(p_log, p, mgrp, p_subn, mgid, pkey));
}
Пример #16
0
bool IBConnection::_writeKeys( const struct IBDest *myDest )
{
    char msg[KEY_MSG_SIZE];

    sprintf( msg,
             KEY_PRINT_FMT,
             cl_hton16(myDest->lid),
             cl_hton32(myDest->qpn),
             cl_hton32(myDest->psn),
             cl_hton32(myDest->rkey),
             myDest->vaddr);

    _socketConnection->send( msg, KEY_MSG_SIZE );
    return true;
}
Пример #17
0
/*
 * Initialize an inform info attribute:
 * Catch all traps in the lid range of the p_osmt
 *
 */
ib_api_status_t
osmt_init_inform_info(IN osmtest_t * const p_osmt, OUT ib_inform_info_t * p_ii)
{

	memset(p_ii, 0, sizeof(ib_inform_info_t));
	/*  p_ii->lid_range_begin = cl_hton16(1); */
	p_ii->lid_range_begin = 0xFFFF;
	p_ii->lid_range_end = cl_hton16(p_osmt->max_lid);
	p_ii->is_generic = 1;	/*  have to choose */
	p_ii->trap_type = 0xFFFF;	/*  ALL */
	p_ii->g_or_v.generic.trap_num = 0xFFFF;	/*  ALL */
	p_ii->g_or_v.generic.node_type_lsb = 0xFFFF;	/*  ALL */
	p_ii->g_or_v.generic.node_type_msb = 0xFF;	/*  ALL */
	return IB_SUCCESS;
}
Пример #18
0
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);
}
Пример #19
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);
}
Пример #20
0
/* handle a mad message */
int
IBMSServer::handleMadMsg(int clientSock,
        ibms_mad_msg_t &madMsg)
{
    MSG_ENTER_FUNC;
    int status;
    MSGREG(err1, 'E', "Socket $ was not previously connected.", "server");

    pthread_mutex_lock(&lock);

    /* find the client conn for the given sock */
    map_sock_client::iterator sI = sockToClientMap.find(clientSock);

    /* if none then fail */
    if (sI == sockToClientMap.end()) {
        MSGSND(err1, clientSock);
        pthread_mutex_unlock(&lock);
        MSG_EXIT_FUNC;
        return 1;
    }

    IBMSClientConn *pClientConn = (*sI).second;

    /* we need to replace the source lid with the lid of the port */
    madMsg.addr.slid =
            cl_hton16(pClientConn->getSimNode()->nodePortsInfo[pClientConn->getIbPortNum()].base_lid);

    status = pSim->getDispatcher()->dispatchMad(
            pClientConn->getSimNode(),
            pClientConn->getIbPortNum(),
            madMsg);

    pthread_mutex_unlock(&lock);
    MSG_EXIT_FUNC;
    return status;
}
Пример #21
0
static ib_api_status_t mpr_rcv_get_path_parms(IN osm_sa_t * sa,
					      IN const ib_multipath_rec_t *
					      p_mpr,
					      IN const osm_alias_guid_t * p_src_alias_guid,
					      IN const osm_alias_guid_t * p_dest_alias_guid,
					      IN const uint16_t dest_lid_ho,
					      IN const ib_net64_t comp_mask,
					      OUT osm_path_parms_t * p_parms)
{
	const osm_node_t *p_node;
	const osm_physp_t *p_physp, *p_physp0;
	const osm_physp_t *p_src_physp;
	const osm_physp_t *p_dest_physp;
	const osm_prtn_t *p_prtn = NULL;
	const ib_port_info_t *p_pi, *p_pi0;
	ib_slvl_table_t *p_slvl_tbl;
	ib_api_status_t status = IB_SUCCESS;
	uint8_t mtu;
	uint8_t rate;
	uint8_t pkt_life;
	uint8_t required_mtu;
	uint8_t required_rate;
	ib_net16_t required_pkey;
	uint8_t required_sl;
	uint8_t required_pkt_life;
	ib_net16_t dest_lid;
	int hops = 0;
	int in_port_num = 0;
	uint8_t i;
	osm_qos_level_t *p_qos_level = NULL;
	uint16_t valid_sl_mask = 0xffff;

	OSM_LOG_ENTER(sa->p_log);

	dest_lid = cl_hton16(dest_lid_ho);

	p_dest_physp = p_dest_alias_guid->p_base_port->p_physp;
	p_physp = p_src_alias_guid->p_base_port->p_physp;
	p_src_physp = p_physp;
	p_pi = &p_physp->port_info;

	mtu = ib_port_info_get_mtu_cap(p_pi);
	rate = ib_port_info_compute_rate(p_pi,
					 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);

	/*
	   Mellanox Tavor device performance is better using 1K MTU.
	   If required MTU and MTU selector are such that 1K is OK
	   and at least one end of the path is Tavor we override the
	   port MTU with 1K.
	 */
	if (sa->p_subn->opt.enable_quirks &&
	    sa_multipath_rec_apply_tavor_mtu_limit(p_mpr,
						   p_src_alias_guid->p_base_port,
						   p_dest_alias_guid->p_base_port,
						   comp_mask))
		if (mtu > IB_MTU_LEN_1024) {
			mtu = IB_MTU_LEN_1024;
			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
				"Optimized Path MTU to 1K for Mellanox Tavor device\n");
		}

	/*
	   Walk the subnet object from source to destination,
	   tracking the most restrictive rate and mtu values along the way...

	   If source port node is a switch, then p_physp should
	   point to the port that routes the destination lid
	 */

	p_node = osm_physp_get_node_ptr(p_physp);

	if (p_node->sw) {
		/*
		 * Source node is a switch.
		 * Make sure that p_physp points to the out port of the
		 * switch that routes to the destination lid (dest_lid_ho)
		 */
		p_physp = osm_switch_get_route_by_lid(p_node->sw, dest_lid);
		if (p_physp == 0) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4514: "
				"Can't find routing to LID %u on switch %s "
				"(GUID 0x%016"PRIx64")\n", dest_lid_ho,
				p_node->print_desc,
				cl_ntoh64(osm_node_get_node_guid(p_node)));
			status = IB_NOT_FOUND;
			goto Exit;
		}
	}

	if (sa->p_subn->opt.qos) {

		/*
		 * Whether this node is switch or CA, the IN port for
		 * the sl2vl table is 0, because this is a source node.
		 */
		p_slvl_tbl = osm_physp_get_slvl_tbl(p_physp, 0);

		/* update valid SLs that still exist on this route */
		for (i = 0; i < IB_MAX_NUM_VLS; i++) {
			if (valid_sl_mask & (1 << i) &&
			    ib_slvl_table_get(p_slvl_tbl, i) == IB_DROP_VL)
				valid_sl_mask &= ~(1 << i);
		}
		if (!valid_sl_mask) {
			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
				"All the SLs lead to VL15 on this path\n");
			status = IB_NOT_FOUND;
			goto Exit;
		}
	}

	/*
	 * Same as above
	 */
	p_node = osm_physp_get_node_ptr(p_dest_physp);

	if (p_node->sw) {
		/*
		 * if destination is switch, we want p_dest_physp to point to port 0
		 */
		p_dest_physp =
		    osm_switch_get_route_by_lid(p_node->sw, dest_lid);

		if (p_dest_physp == 0) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4515: "
				"Can't find routing to LID %u on switch %s "
				"(GUID 0x%016"PRIx64")\n", dest_lid_ho,
				p_node->print_desc,
				cl_ntoh64(osm_node_get_node_guid(p_node)));
			status = IB_NOT_FOUND;
			goto Exit;
		}

	}

	/*
	 * Now go through the path step by step
	 */

	while (p_physp != p_dest_physp) {

		int tmp_pnum = p_physp->port_num;
		p_node = osm_physp_get_node_ptr(p_physp);
		p_physp = osm_physp_get_remote(p_physp);

		if (p_physp == 0) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4505: "
				"Can't find remote phys port of %s (GUID "
				"0x%016"PRIx64") port %d "
				"while routing to LID %u",
				p_node->print_desc,
				cl_ntoh64(osm_node_get_node_guid(p_node)),
				tmp_pnum,
				dest_lid_ho);
			status = IB_ERROR;
			goto Exit;
		}

		/* update number of hops traversed */
		hops++;
		if (hops > MAX_HOPS) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4520: "
				"Path from GUID 0x%016" PRIx64 " (%s) to"
				" lid %u GUID 0x%016" PRIx64 " (%s) needs"
				" more than %d hops, max %d hops allowed\n",
				cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
				p_src_physp->p_node->print_desc, dest_lid_ho,
				cl_ntoh64(osm_physp_get_port_guid
					  (p_dest_physp)),
				p_dest_physp->p_node->print_desc, hops,
				MAX_HOPS);
			status = IB_NOT_FOUND;
			goto Exit;
		}

		in_port_num = osm_physp_get_port_num(p_physp);

		/*
		   This is point to point case (no switch in between)
		 */
		if (p_physp == p_dest_physp)
			break;

		p_node = osm_physp_get_node_ptr(p_physp);

		if (!p_node->sw) {
			/*
			   There is some sort of problem in the subnet object!
			   If this isn't a switch, we should have reached
			   the destination by now!
			 */
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4503: "
				"Internal error, bad path while routing "
				"from %s (GUID: 0x%016"PRIx64") port %d "
				"to %s (GUID: 0x%016"PRIx64") port %d; "
				"ended at %s port %d\n",
				p_src_alias_guid->p_base_port->p_node->print_desc,
				cl_ntoh64(p_src_alias_guid->p_base_port->p_node->node_info.node_guid),
				p_src_alias_guid->p_base_port->p_physp->port_num,
				p_dest_alias_guid->p_base_port->p_node->print_desc,
				cl_ntoh64(p_dest_alias_guid->p_base_port->p_node->node_info.node_guid),
				p_dest_alias_guid->p_base_port->p_physp->port_num,
				p_node->print_desc,
				p_physp->port_num);
			status = IB_ERROR;
			goto Exit;
		}

		/*
		   Check parameters for the ingress port in this switch.
		 */
		p_pi = &p_physp->port_info;

		if (mtu > ib_port_info_get_mtu_cap(p_pi))
			mtu = ib_port_info_get_mtu_cap(p_pi);

		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
		p_pi0 = &p_physp0->port_info;
		if (ib_path_compare_rates(rate,
					  ib_port_info_compute_rate(p_pi,
								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
			rate = ib_port_info_compute_rate(p_pi,
							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);

		/*
		   Continue with the egress port on this switch.
		 */
		p_physp = osm_switch_get_route_by_lid(p_node->sw, dest_lid);
		if (p_physp == 0) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4516: "
				"Dead end path on switch "
				"%s (GUID: 0x%016"PRIx64") to LID %u\n",
				p_node->print_desc,
				cl_ntoh64(osm_node_get_node_guid(p_node)),
				dest_lid_ho);
			status = IB_ERROR;
			goto Exit;
		}

		p_pi = &p_physp->port_info;

		if (mtu > ib_port_info_get_mtu_cap(p_pi))
			mtu = ib_port_info_get_mtu_cap(p_pi);

		p_physp0 = osm_node_get_physp_ptr((osm_node_t *)p_node, 0);
		p_pi0 = &p_physp0->port_info;
		if (ib_path_compare_rates(rate,
					  ib_port_info_compute_rate(p_pi,
								    p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
			rate = ib_port_info_compute_rate(p_pi,
							 p_pi0->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);

		if (sa->p_subn->opt.qos) {
			/*
			 * Check SL2VL table of the switch and update valid SLs
			 */
			p_slvl_tbl =
			    osm_physp_get_slvl_tbl(p_physp, in_port_num);
			for (i = 0; i < IB_MAX_NUM_VLS; i++) {
				if (valid_sl_mask & (1 << i) &&
				    ib_slvl_table_get(p_slvl_tbl,
						      i) == IB_DROP_VL)
					valid_sl_mask &= ~(1 << i);
			}
			if (!valid_sl_mask) {
				OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
					"All the SLs lead to VL15 "
					"on this path\n");
				status = IB_NOT_FOUND;
				goto Exit;
			}
		}
	}

	/*
	   p_physp now points to the destination
	 */
	p_pi = &p_physp->port_info;

	if (mtu > ib_port_info_get_mtu_cap(p_pi))
		mtu = ib_port_info_get_mtu_cap(p_pi);

	if (ib_path_compare_rates(rate,
				  ib_port_info_compute_rate(p_pi,
							    p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS)) > 0)
		rate = ib_port_info_compute_rate(p_pi,
						 p_pi->capability_mask & IB_PORT_CAP_HAS_EXT_SPEEDS);

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
		"Path min MTU = %u, min rate = %u\n", mtu, rate);

	/*
	 * Get QoS Level object according to the MultiPath request
	 * and adjust MultiPath parameters according to QoS settings
	 */
	if (sa->p_subn->opt.qos && sa->p_subn->p_qos_policy &&
	    (p_qos_level =
	     osm_qos_policy_get_qos_level_by_mpr(sa->p_subn->p_qos_policy,
						 p_mpr, p_src_physp,
						 p_dest_physp, comp_mask))) {

		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"MultiPathRecord request matches QoS Level '%s' (%s)\n",
			p_qos_level->name,
			p_qos_level->use ? p_qos_level->use : "no description");

		if (p_qos_level->mtu_limit_set
		    && (mtu > p_qos_level->mtu_limit))
			mtu = p_qos_level->mtu_limit;

		if (p_qos_level->rate_limit_set
		    && (ib_path_compare_rates(rate, p_qos_level->rate_limit) > 0))
			rate = p_qos_level->rate_limit;

		if (p_qos_level->sl_set) {
			required_sl = p_qos_level->sl;
			if (!(valid_sl_mask & (1 << required_sl))) {
				status = IB_NOT_FOUND;
				goto Exit;
			}
		}
	}

	/*
	   Determine if these values meet the user criteria
	 */

	/* we silently ignore cases where only the MTU selector is defined */
	if ((comp_mask & IB_MPR_COMPMASK_MTUSELEC) &&
	    (comp_mask & IB_MPR_COMPMASK_MTU)) {
		required_mtu = ib_multipath_rec_mtu(p_mpr);
		switch (ib_multipath_rec_mtu_sel(p_mpr)) {
		case 0:	/* must be greater than */
			if (mtu <= required_mtu)
				status = IB_NOT_FOUND;
			break;

		case 1:	/* must be less than */
			if (mtu >= required_mtu) {
				/* adjust to use the highest mtu
				   lower then the required one */
				if (required_mtu > 1)
					mtu = required_mtu - 1;
				else
					status = IB_NOT_FOUND;
			}
			break;

		case 2:	/* exact match */
			if (mtu < required_mtu)
				status = IB_NOT_FOUND;
			else
				mtu = required_mtu;
			break;

		case 3:	/* largest available */
			/* can't be disqualified by this one */
			break;

		default:
			/* if we're here, there's a bug in ib_multipath_rec_mtu_sel() */
			CL_ASSERT(FALSE);
			status = IB_ERROR;
			break;
		}
	}
	if (status != IB_SUCCESS)
		goto Exit;

	/* we silently ignore cases where only the Rate selector is defined */
	if ((comp_mask & IB_MPR_COMPMASK_RATESELEC) &&
	    (comp_mask & IB_MPR_COMPMASK_RATE)) {
		required_rate = ib_multipath_rec_rate(p_mpr);
		switch (ib_multipath_rec_rate_sel(p_mpr)) {
		case 0:	/* must be greater than */
			if (ib_path_compare_rates(rate, required_rate) <= 0)
				status = IB_NOT_FOUND;
			break;

		case 1:	/* must be less than */
			if (ib_path_compare_rates(rate, required_rate) >= 0) {
				/* adjust the rate to use the highest rate
				   lower then the required one */
				rate = ib_path_rate_get_prev(required_rate);
				if (!rate)
					status = IB_NOT_FOUND;
			}
			break;

		case 2:	/* exact match */
			if (ib_path_compare_rates(rate, required_rate))
				status = IB_NOT_FOUND;
			else
				rate = required_rate;
			break;

		case 3:	/* largest available */
			/* can't be disqualified by this one */
			break;

		default:
			/* if we're here, there's a bug in ib_multipath_rec_mtu_sel() */
			CL_ASSERT(FALSE);
			status = IB_ERROR;
			break;
		}
	}
	if (status != IB_SUCCESS)
		goto Exit;

	/* Verify the pkt_life_time */
	/* According to spec definition IBA 1.2 Table 205 PacketLifeTime description,
	   for loopback paths, packetLifeTime shall be zero. */
	if (p_src_alias_guid->p_base_port == p_dest_alias_guid->p_base_port)
		pkt_life = 0;	/* loopback */
	else if (p_qos_level && p_qos_level->pkt_life_set)
		pkt_life = p_qos_level->pkt_life;
	else
		pkt_life = sa->p_subn->opt.subnet_timeout;

	/* we silently ignore cases where only the PktLife selector is defined */
	if ((comp_mask & IB_MPR_COMPMASK_PKTLIFETIMESELEC) &&
	    (comp_mask & IB_MPR_COMPMASK_PKTLIFETIME)) {
		required_pkt_life = ib_multipath_rec_pkt_life(p_mpr);
		switch (ib_multipath_rec_pkt_life_sel(p_mpr)) {
		case 0:	/* must be greater than */
			if (pkt_life <= required_pkt_life)
				status = IB_NOT_FOUND;
			break;

		case 1:	/* must be less than */
			if (pkt_life >= required_pkt_life) {
				/* adjust the lifetime to use the highest possible
				   lower then the required one */
				if (required_pkt_life > 1)
					pkt_life = required_pkt_life - 1;
				else
					status = IB_NOT_FOUND;
			}
			break;

		case 2:	/* exact match */
			if (pkt_life < required_pkt_life)
				status = IB_NOT_FOUND;
			else
				pkt_life = required_pkt_life;
			break;

		case 3:	/* smallest available */
			/* can't be disqualified by this one */
			break;

		default:
			/* if we're here, there's a bug in ib_path_rec_pkt_life_sel() */
			CL_ASSERT(FALSE);
			status = IB_ERROR;
			break;
		}
	}

	if (status != IB_SUCCESS)
		goto Exit;

	/*
	 * set Pkey for this MultiPath record request
	 */

	if (comp_mask & IB_MPR_COMPMASK_RAWTRAFFIC &&
	    cl_ntoh32(p_mpr->hop_flow_raw) & (1 << 31))
		required_pkey =
		    osm_physp_find_common_pkey(p_src_physp, p_dest_physp,
					       sa->p_subn->opt.allow_both_pkeys);

	else if (comp_mask & IB_MPR_COMPMASK_PKEY) {
		/*
		 * MPR request has a specific pkey:
		 * Check that source and destination share this pkey.
		 * If QoS level has pkeys, check that this pkey exists
		 * in the QoS level pkeys.
		 * MPR returned pkey is the requested pkey.
		 */
		required_pkey = p_mpr->pkey;
		if (!osm_physp_share_this_pkey
		    (p_src_physp, p_dest_physp, required_pkey,
		     sa->p_subn->opt.allow_both_pkeys)) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4518: "
				"Ports src 0x%016"PRIx64" (%s port %d) "
				"and dst 0x%016"PRIx64" (%s port %d) "
				"do not share the specified PKey 0x%04x\n",
				cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
				p_src_physp->p_node->print_desc,
				p_src_physp->port_num,
				cl_ntoh64(osm_physp_get_port_guid
					  (p_dest_physp)),
				p_dest_physp->p_node->print_desc,
				p_dest_physp->port_num,
				cl_ntoh16(required_pkey));
			status = IB_NOT_FOUND;
			goto Exit;
		}
		if (p_qos_level && p_qos_level->pkey_range_len &&
		    !osm_qos_level_has_pkey(p_qos_level, required_pkey)) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 451C: "
				"Ports src 0x%016"PRIx64" (%s port %d) "
				"and dst 0x%016"PRIx64" (%s port %d) "
				"do not share specified PKey (0x%04x) as "
				"defined by QoS level \"%s\"\n",
				cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
				p_src_physp->p_node->print_desc,
				p_src_physp->port_num,
				cl_ntoh64(osm_physp_get_port_guid
					  (p_dest_physp)),
				p_dest_physp->p_node->print_desc,
				p_dest_physp->port_num,
				cl_ntoh16(required_pkey),
				p_qos_level->name);
			status = IB_NOT_FOUND;
			goto Exit;
		}

	} else if (p_qos_level && p_qos_level->pkey_range_len) {
		/*
		 * MPR request doesn't have a specific pkey, but QoS level
		 * has pkeys - get shared pkey from QoS level pkeys
		 */
		required_pkey = osm_qos_level_get_shared_pkey(p_qos_level,
							      p_src_physp,
							      p_dest_physp,
							      sa->p_subn->opt.allow_both_pkeys);
		if (!required_pkey) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 451D: "
				"Ports src 0x%016"PRIx64" (%s port %d) "
				"and dst 0x%016"PRIx64" (%s port %d) "
				"do not share a PKey as defined by QoS "
				"level \"%s\"\n",
				cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
				p_src_physp->p_node->print_desc,
				p_src_physp->port_num,
				cl_ntoh64(osm_physp_get_port_guid
					  (p_dest_physp)),
				p_dest_physp->p_node->print_desc,
				p_dest_physp->port_num,
				p_qos_level->name);
			status = IB_NOT_FOUND;
			goto Exit;
		}

	} else {
		/*
		 * Neither MPR request nor QoS level have pkey.
		 * Just get any shared pkey.
		 */
		required_pkey =
		    osm_physp_find_common_pkey(p_src_physp, p_dest_physp,
					       sa->p_subn->opt.allow_both_pkeys);
		if (!required_pkey) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4519: "
				"Ports src 0x%016"PRIx64" (%s port %d) "
				"and dst 0x%016"PRIx64" (%s port %d) "
				"do not have any shared PKeys\n",
				cl_ntoh64(osm_physp_get_port_guid(p_src_physp)),
				p_src_physp->p_node->print_desc,
				p_src_physp->port_num,
				cl_ntoh64(osm_physp_get_port_guid
					  (p_dest_physp)),
				p_dest_physp->p_node->print_desc,
				p_dest_physp->port_num);
			status = IB_NOT_FOUND;
			goto Exit;
		}
	}

	if (required_pkey) {
		p_prtn =
		    (osm_prtn_t *) cl_qmap_get(&sa->p_subn->prtn_pkey_tbl,
					       required_pkey &
					       cl_ntoh16((uint16_t) ~ 0x8000));
		if (p_prtn ==
		    (osm_prtn_t *) cl_qmap_end(&sa->p_subn->prtn_pkey_tbl))
			p_prtn = NULL;
	}

	/*
	 * Set MultiPathRecord SL.
	 */

	if (comp_mask & IB_MPR_COMPMASK_SL) {
		/*
		 * Specific SL was requested
		 */
		required_sl = ib_multipath_rec_sl(p_mpr);

		if (p_qos_level && p_qos_level->sl_set &&
		    p_qos_level->sl != required_sl) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 451E: "
				"QoS constraints: required MultiPathRecord SL "
				"(%u) doesn't match QoS policy \"%s\" SL (%u) "
				"[%s port %d <-> %s port %d]\n", required_sl,
				p_qos_level->name,
				p_qos_level->sl,
				p_src_alias_guid->p_base_port->p_node->print_desc,
				p_src_alias_guid->p_base_port->p_physp->port_num,
				p_dest_alias_guid->p_base_port->p_node->print_desc,
				p_dest_alias_guid->p_base_port->p_physp->port_num);
			status = IB_NOT_FOUND;
			goto Exit;
		}

	} else if (p_qos_level && p_qos_level->sl_set) {
		/*
		 * No specific SL was requested,
		 * but there is an SL in QoS level.
		 */
		required_sl = p_qos_level->sl;

		if (required_pkey && p_prtn && p_prtn->sl != p_qos_level->sl)
			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
				"QoS level SL (%u) overrides partition SL (%u)\n",
				p_qos_level->sl, p_prtn->sl);

	} else if (required_pkey) {
		/*
		 * No specific SL in request or in QoS level - use partition SL
		 */
		p_prtn =
		    (osm_prtn_t *) cl_qmap_get(&sa->p_subn->prtn_pkey_tbl,
					       required_pkey &
					       cl_ntoh16((uint16_t) ~ 0x8000));
		if (!p_prtn) {
			required_sl = OSM_DEFAULT_SL;
			/* this may be possible when pkey tables are created somehow in
			   previous runs or things are going wrong here */
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 451A: "
				"No partition found for PKey 0x%04x - "
				"using default SL %d "
				"[%s port %d <-> %s port %d]\n",
				cl_ntoh16(required_pkey), required_sl,
				p_src_alias_guid->p_base_port->p_node->print_desc,
				p_src_alias_guid->p_base_port->p_physp->port_num,
				p_dest_alias_guid->p_base_port->p_node->print_desc,
				p_dest_alias_guid->p_base_port->p_physp->port_num);
		} else
			required_sl = p_prtn->sl;

	} else if (sa->p_subn->opt.qos) {
		if (valid_sl_mask & (1 << OSM_DEFAULT_SL))
			required_sl = OSM_DEFAULT_SL;
		else {
			for (i = 0; i < IB_MAX_NUM_VLS; i++)
				if (valid_sl_mask & (1 << i))
					break;
			required_sl = i;
		}
	} else
		required_sl = OSM_DEFAULT_SL;

	if (sa->p_subn->opt.qos && !(valid_sl_mask & (1 << required_sl))) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 451F: "
			"Selected SL (%u) leads to VL15 "
			"[%s port %d <-> %s port %d]\n",
			required_sl,
			p_src_alias_guid->p_base_port->p_node->print_desc,
			p_src_alias_guid->p_base_port->p_physp->port_num,
			p_dest_alias_guid->p_base_port->p_node->print_desc,
			p_dest_alias_guid->p_base_port->p_physp->port_num);
		status = IB_NOT_FOUND;
		goto Exit;
	}

	/* reset pkey when raw traffic */
	if (comp_mask & IB_MPR_COMPMASK_RAWTRAFFIC &&
	    cl_ntoh32(p_mpr->hop_flow_raw) & (1 << 31))
		required_pkey = 0;

	p_parms->mtu = mtu;
	p_parms->rate = rate;
	p_parms->pkey = required_pkey;
	p_parms->pkt_life = pkt_life;
	p_parms->sl = required_sl;
	p_parms->hops = hops;

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "MultiPath params:"
		" mtu = %u, rate = %u, packet lifetime = %u,"
		" pkey = 0x%04X, sl = %u, hops = %u\n", mtu, rate,
		pkt_life, cl_ntoh16(required_pkey), required_sl, hops);

Exit:
	OSM_LOG_EXIT(sa->p_log);
	return status;
}
Пример #22
0
/* Send a MAD out on the GSI interface */
static ib_api_status_t
__osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
		   IN const osmv_sa_mad_data_t * const p_sa_mad_data,
		   IN const osmv_query_req_t * const p_query_req)
{
	ib_api_status_t status;
	ib_mad_t *p_mad_hdr;
	ib_sa_mad_t *p_sa_mad;
	osm_madw_t *p_madw;
	osm_log_t *p_log = p_bind->p_log;
	static atomic32_t trans_id;
	boolean_t sync;
	osmv_query_req_t *p_query_req_copy;

	OSM_LOG_ENTER(p_log);

	/*
	   since the sm_lid might change we obtain it every send
	   (actually it is cached in the bind object and refreshed
	   every 30sec by this proc)
	 */
	if (time(NULL) > p_bind->last_lids_update_sec + 30) {
		status = update_umad_port(p_bind->p_vendor);
		if (status != IB_SUCCESS) {
			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5509: "
				"Failed to obtain the SM lid\n");
			goto Exit;
		}
		p_bind->last_lids_update_sec = time(NULL);
	}

	/* Get a MAD wrapper for the send */
	p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
				  p_bind->h_bind, MAD_BLOCK_SIZE, NULL);

	if (p_madw == NULL) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 5510: "
			"Unable to acquire MAD\n");
		status = IB_INSUFFICIENT_RESOURCES;
		goto Exit;
	}

	/* Initialize the Sent MAD: */

	/* Initialize the MAD buffer for the send operation. */
	p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);

	/* Get a new transaction Id */
	cl_atomic_inc(&trans_id);

	/* Cleanup the MAD from any residue */
	memset(p_sa_mad, 0, MAD_BLOCK_SIZE);

	/* Initialize the standard MAD header. */
	ib_mad_init_new(p_mad_hdr,	/* mad pointer */
			IB_MCLASS_SUBN_ADM,	/* class */
			(uint8_t) 2,	/* version */
			p_sa_mad_data->method,	/* method */
			cl_hton64((uint64_t) trans_id),	/* tid */
			p_sa_mad_data->attr_id,	/* attr id */
			p_sa_mad_data->attr_mod	/* attr mod */);

	/* Set the query information. */
	p_sa_mad->sm_key = p_query_req->sm_key;
	p_sa_mad->attr_offset = 0;
	p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
#ifdef DUAL_SIDED_RMPP
	if (p_sa_mad->method == IB_MAD_METHOD_GETMULTI)
		p_sa_mad->rmpp_flags = IB_RMPP_FLAG_ACTIVE;
#endif
	if (p_sa_mad->comp_mask) {
		memcpy(p_sa_mad->data, p_sa_mad_data->p_attr,
		       ib_get_attr_size(p_sa_mad_data->attr_offset));
	}

	/*
	   Provide the address to send to
	 */
	p_madw->mad_addr.dest_lid =
	    cl_hton16(p_bind->p_vendor->umad_port.sm_lid);
	p_madw->mad_addr.addr_type.smi.source_lid =
	    cl_hton16(p_bind->p_vendor->umad_port.base_lid);
	p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
	p_madw->resp_expected = TRUE;
	p_madw->fail_msg = CL_DISP_MSGID_NONE;

	/*
	   Provide MAD context such that the call back will know what to do.
	   We have to keep the entire request structure so we know the CB.
	   Since we can not rely on the client to keep it around until
	   the response - we duplicate it and will later dispose it (in CB).
	   To store on the MADW we cast it into what opensm has:
	   p_madw->context.ni_context.node_guid
	 */
	p_query_req_copy = malloc(sizeof(*p_query_req_copy));
	*p_query_req_copy = *p_query_req;
	p_madw->context.ni_context.node_guid =
	    (ib_net64_t) (long)p_query_req_copy;

	/* we can support async as well as sync calls */
	sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);

	/* send the mad asynchronously */
	status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
				 p_madw, p_madw->resp_expected);

	/* if synchronous - wait on the event */
	if (sync) {
		OSM_LOG(p_log, OSM_LOG_DEBUG, "Waiting for async event\n");
		cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
		cl_event_reset(&p_bind->sync_event);
		status = p_madw->status;
	}

Exit:
	OSM_LOG_EXIT(p_log);
	return status;
}
Пример #23
0
static void lr_rcv_get_physp_link(IN osm_sa_t * sa,
				  IN const ib_link_record_t * p_lr,
				  IN const osm_physp_t * p_src_physp,
				  IN const osm_physp_t * p_dest_physp,
				  IN const ib_net64_t comp_mask,
				  IN cl_qlist_t * p_list,
				  IN const osm_physp_t * p_req_physp)
{
	uint8_t src_port_num;
	uint8_t dest_port_num;
	ib_net16_t from_base_lid;
	ib_net16_t to_base_lid;
	ib_net16_t lmc_mask;

	OSM_LOG_ENTER(sa->p_log);

	/*
	   If only one end of the link is specified, determine
	   the other side.
	 */
	if (p_src_physp) {
		if (p_dest_physp) {
			/*
			   Ensure the two physp's are actually connected.
			   If not, bail out.
			 */
			if (osm_physp_get_remote(p_src_physp) != p_dest_physp)
				goto Exit;
		} else {
			p_dest_physp = osm_physp_get_remote(p_src_physp);
			if (p_dest_physp == NULL)
				goto Exit;
		}
	} else {
		if (p_dest_physp) {
			p_src_physp = osm_physp_get_remote(p_dest_physp);
			if (p_src_physp == NULL)
				goto Exit;
		} else
			goto Exit;	/* no physp's, so nothing to do */
	}

	/* Check that the p_src_physp, p_dest_physp and p_req_physp
	   all share a pkey (doesn't have to be the same p_key). */
	if (!osm_physp_share_pkey(sa->p_log, p_src_physp, p_dest_physp,
				  sa->p_subn->opt.allow_both_pkeys)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Source and Dest PhysPorts do not share PKey\n");
		goto Exit;
	}
	if (!osm_physp_share_pkey(sa->p_log, p_src_physp, p_req_physp,
				  sa->p_subn->opt.allow_both_pkeys)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Source and Requester PhysPorts do not share PKey\n");
		goto Exit;
	}
	if (!osm_physp_share_pkey(sa->p_log, p_req_physp, p_dest_physp,
				  sa->p_subn->opt.allow_both_pkeys)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Requester and Dest PhysPorts do not share PKey\n");
		goto Exit;
	}

	src_port_num = osm_physp_get_port_num(p_src_physp);
	dest_port_num = osm_physp_get_port_num(p_dest_physp);

	if (comp_mask & IB_LR_COMPMASK_FROM_PORT)
		if (src_port_num != p_lr->from_port_num)
			goto Exit;

	if (comp_mask & IB_LR_COMPMASK_TO_PORT)
		if (dest_port_num != p_lr->to_port_num)
			goto Exit;

	from_base_lid = get_base_lid(p_src_physp);
	to_base_lid = get_base_lid(p_dest_physp);

	lmc_mask = ~((1 << sa->p_subn->opt.lmc) - 1);
	lmc_mask = cl_hton16(lmc_mask);

	if (comp_mask & IB_LR_COMPMASK_FROM_LID)
		if (from_base_lid != (p_lr->from_lid & lmc_mask))
			goto Exit;

	if (comp_mask & IB_LR_COMPMASK_TO_LID)
		if (to_base_lid != (p_lr->to_lid & lmc_mask))
			goto Exit;

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG, "Acquiring link record\n"
		"\t\t\t\tsrc port 0x%" PRIx64 " (port %u)"
		", dest port 0x%" PRIx64 " (port %u)\n",
		cl_ntoh64(osm_physp_get_port_guid(p_src_physp)), src_port_num,
		cl_ntoh64(osm_physp_get_port_guid(p_dest_physp)),
		dest_port_num);

	lr_rcv_build_physp_link(sa, from_base_lid, to_base_lid, src_port_num,
				dest_port_num, p_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #24
0
static void ucast_mgr_set_fwd_top(IN cl_map_item_t * p_map_item,
				  IN void *cxt)
{
	osm_ucast_mgr_t *p_mgr = cxt;
	osm_switch_t * p_sw = (osm_switch_t *) p_map_item;
	osm_node_t *p_node;
	osm_physp_t *p_physp;
	osm_dr_path_t *p_path;
	osm_madw_context_t context;
	ib_api_status_t status;
	ib_switch_info_t si;
	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_sw->max_lid_ho);

	p_node = p_sw->p_node;

	CL_ASSERT(p_node);

	if (p_mgr->max_lid < p_sw->max_lid_ho)
		p_mgr->max_lid = p_sw->max_lid_ho;

	p_physp = osm_node_get_physp_ptr(p_node, 0);

	CL_ASSERT(p_physp);

	p_path = osm_physp_get_dr_path_ptr(p_physp);

	/*
	   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;
		context.si_context.lft_top_change = TRUE;
	} else
		context.si_context.lft_top_change = FALSE;

	life_state = si.life_state;
	ib_switch_info_set_life_time(&si, p_mgr->p_subn->opt.packet_life_time);

	if (life_state != si.life_state)
		set_swinfo_require = TRUE;

	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, FALSE,
				     ib_port_info_get_m_key(&p_physp->port_info),
				     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));
	}

	OSM_LOG_EXIT(p_mgr->p_log);
}
static void cpi_rcv_respond(IN osm_sa_t * sa, IN const osm_madw_t * p_madw)
{
	osm_madw_t *p_resp_madw;
	const ib_sa_mad_t *p_sa_mad;
	ib_sa_mad_t *p_resp_sa_mad;
	ib_class_port_info_t *p_resp_cpi;
	ib_gid_t zero_gid;
	uint32_t cap_mask2;
	uint8_t rtv;

	OSM_LOG_ENTER(sa->p_log);

	memset(&zero_gid, 0, sizeof(ib_gid_t));

	/*
	   Get a MAD to reply. Address of Mad is in the received mad_wrapper
	 */
	p_resp_madw = osm_mad_pool_get(sa->p_mad_pool, p_madw->h_bind,
				       MAD_BLOCK_SIZE, &p_madw->mad_addr);
	if (!p_resp_madw) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1408: "
			"Unable to allocate MAD\n");
		goto Exit;
	}

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_resp_sa_mad = osm_madw_get_sa_mad_ptr(p_resp_madw);

	memcpy(p_resp_sa_mad, p_sa_mad, IB_SA_MAD_HDR_SIZE);
	p_resp_sa_mad->method |= IB_MAD_METHOD_RESP_MASK;
	/* C15-0.1.5 - always return SM_Key = 0 (table 185 p 884) */
	p_resp_sa_mad->sm_key = 0;

	p_resp_cpi =
	    (ib_class_port_info_t *) ib_sa_mad_get_payload_ptr(p_resp_sa_mad);

	/* finally do it (the job) man ! */
	p_resp_cpi->base_ver = 1;
	p_resp_cpi->class_ver = 2;
	/* Calculate encoded response time value */
	/* transaction timeout is in msec */
	if (sa->p_subn->opt.transaction_timeout >
	    msecs_to_rtv_table[MAX_MSECS_TO_RTV - 1])
		rtv = MAX_MSECS_TO_RTV - 1;
	else {
		for (rtv = 0; rtv < MAX_MSECS_TO_RTV; rtv++) {
			if (sa->p_subn->opt.transaction_timeout <=
			    msecs_to_rtv_table[rtv])
				break;
		}
	}
	rtv += 8;
	ib_class_set_resp_time_val(p_resp_cpi, rtv);
	p_resp_cpi->redir_gid = zero_gid;
	p_resp_cpi->redir_tc_sl_fl = 0;
	p_resp_cpi->redir_lid = 0;
	p_resp_cpi->redir_pkey = 0;
	p_resp_cpi->redir_qp = CL_NTOH32(1);
	p_resp_cpi->redir_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
	p_resp_cpi->trap_gid = zero_gid;
	p_resp_cpi->trap_tc_sl_fl = 0;
	p_resp_cpi->trap_lid = 0;
	p_resp_cpi->trap_pkey = 0;
	p_resp_cpi->trap_hop_qp = 0;
	p_resp_cpi->trap_qkey = IB_QP1_WELL_KNOWN_Q_KEY;

	/* set specific capability mask bits */
	/* we do not support the following options/optional records:
	   OSM_CAP_IS_SUBN_OPT_RECS_SUP :
	   RandomForwardingTableRecord,
	   ServiceAssociationRecord
	   other optional records supported "under the table"

	   OSM_CAP_IS_MULTIPATH_SUP:
	   TraceRecord

	   OSM_CAP_IS_REINIT_SUP:
	   For reinitialization functionality.

	   So not sending traps, but supporting Get(Notice) and Set(Notice).
	 */

	/* Note host notation replaced later */
#if defined (VENDOR_RMPP_SUPPORT) && defined (DUAL_SIDED_RMPP)
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED |
	    OSM_CAP_IS_MULTIPATH_SUP;
#else
	p_resp_cpi->cap_mask = OSM_CAP_IS_SUBN_GET_SET_NOTICE_SUP |
	    OSM_CAP_IS_PORT_INFO_CAPMASK_MATCH_SUPPORTED;
#endif
	cap_mask2 = OSM_CAP2_IS_FULL_PORTINFO_REC_SUPPORTED |
		    OSM_CAP2_IS_EXTENDED_SPEEDS_SUPPORTED |
		    OSM_CAP2_IS_ALIAS_GUIDS_SUPPORTED |
		    OSM_CAP2_IS_MULTICAST_SERVICE_RECS_SUPPORTED |
		    OSM_CAP2_IS_PORT_INFO_CAPMASK2_MATCH_SUPPORTED |
		    OSM_CAP2_IS_LINK_WIDTH_2X_SUPPORTED;
	if (sa->p_subn->opt.use_mfttop)
		cap_mask2 |= OSM_CAP2_IS_MCAST_TOP_SUPPORTED;
	if (sa->p_subn->opt.qos)
		cap_mask2 |= OSM_CAP2_IS_QOS_SUPPORTED;
	ib_class_set_cap_mask2(p_resp_cpi, cap_mask2);

	if (!sa->p_subn->opt.disable_multicast)
		p_resp_cpi->cap_mask |= OSM_CAP_IS_UD_MCAST_SUP;
	p_resp_cpi->cap_mask = cl_hton16(p_resp_cpi->cap_mask);

	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_FRAMES))
		osm_dump_sa_mad_v2(sa->p_log, p_resp_sa_mad, FILE_ID, OSM_LOG_FRAMES);

	osm_sa_send(sa, p_resp_madw, FALSE);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #26
0
/* Send a MAD out on the GSI interface */
ib_api_status_t
__osmv_send_sa_req(IN osmv_sa_bind_info_t * p_bind,
		   IN const osmv_sa_mad_data_t * const p_sa_mad_data,
		   IN const osmv_query_req_t * const p_query_req)
{
	ib_api_status_t status;
	ib_mad_t *p_mad_hdr;
	ib_sa_mad_t *p_sa_mad;
	osm_madw_t *p_madw;
	osm_log_t *p_log = p_bind->p_log;
	static atomic32_t trans_id;
	boolean_t sync;
	osmv_query_req_t *p_query_req_copy;

	OSM_LOG_ENTER(p_log);

	/*
	   since the sm_lid might change we obtain it every send
	   (actually it is cached in the bind object and refreshed
	   every 30sec by this proc )
	 */
	status =
	    __osmv_get_lid_and_sm_lid_by_port_guid(p_bind->p_vendor,
						   p_bind->port_guid,
						   &p_bind->
						   last_lids_update_sec,
						   &p_bind->lid,
						   &p_bind->sm_lid);
	if (status != IB_SUCCESS) {
		osm_log(p_log, OSM_LOG_ERROR,
			"__osmv_send_sa_req: ERR 0509: "
			"Fail to obtain the sm lid.\n");
		goto Exit;
	}

	/* Get a MAD wrapper for the send */
	p_madw = osm_mad_pool_get(p_bind->p_mad_pool,
				  p_bind->h_bind, MAD_BLOCK_SIZE, NULL);

	if (p_madw == NULL) {
		osm_log(p_log, OSM_LOG_ERROR,
			"__osmv_send_sa_req: ERR 0510: "
			"Unable to acquire MAD.\n");
		status = IB_INSUFFICIENT_RESOURCES;
		goto Exit;
	}

	/* Initialize the Sent MAD: */

	/* Initialize the MAD buffer for the send operation. */
	p_mad_hdr = osm_madw_get_mad_ptr(p_madw);
	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);

	/* Get a new transaction Id */
	cl_atomic_inc(&trans_id);

	/* Cleanup the MAD from any residue */
	memset(p_sa_mad, 0, MAD_BLOCK_SIZE);

	/* Initialize the standard MAD header. */
	ib_mad_init_new(p_mad_hdr,	/* mad pointer */
			IB_MCLASS_SUBN_ADM,	/* class */
			(uint8_t) 2,	/* version */
			p_sa_mad_data->method,	/* method */
			cl_hton64((uint64_t) trans_id),	/* tid */
			p_sa_mad_data->attr_id,	/* attr id */
			p_sa_mad_data->attr_mod	/* attr mod */
	    );

	/* Set the query information. */
	p_sa_mad->sm_key = p_query_req->sm_key;
	p_sa_mad->attr_offset = 0;
	p_sa_mad->comp_mask = p_sa_mad_data->comp_mask;
	if (p_sa_mad->comp_mask) {
		memcpy(p_sa_mad->data, p_sa_mad_data->p_attr,
		       ib_get_attr_size(p_sa_mad_data->attr_offset));
	}

	/*
	   Provide the address to send to
	 */
	/* Patch to handle IBAL - host order , where it should take destination lid in network order */
#ifdef OSM_VENDOR_INTF_AL
	p_madw->mad_addr.dest_lid = p_bind->sm_lid;
#else
	p_madw->mad_addr.dest_lid = cl_hton16(p_bind->sm_lid);
#endif
	p_madw->mad_addr.addr_type.smi.source_lid = cl_hton16(p_bind->lid);
	p_madw->mad_addr.addr_type.gsi.remote_qp = CL_HTON32(1);
	p_madw->mad_addr.addr_type.gsi.remote_qkey = IB_QP1_WELL_KNOWN_Q_KEY;
	p_madw->mad_addr.addr_type.gsi.pkey_ix = 0;
	p_madw->resp_expected = TRUE;
	p_madw->fail_msg = CL_DISP_MSGID_NONE;

	/*
	   Provide MAD context such that the call back will know what to do.
	   We have to keep the entire request structure so we know the CB.
	   Since we can not rely on the client to keep it arroud until
	   the response - we duplicate it and will later dispose it (in CB).
	   To store on the MADW we cast it into what opensm has:
	   p_madw->context.arb_context.context1
	 */
	p_query_req_copy = malloc(sizeof(*p_query_req_copy));
	*p_query_req_copy = *p_query_req;
	p_madw->context.arb_context.context1 = p_query_req_copy;

	/* we can support async as well as sync calls */
	sync = ((p_query_req->flags & OSM_SA_FLAGS_SYNC) == OSM_SA_FLAGS_SYNC);

	/* send the mad asynchronously */
	status = osm_vendor_send(osm_madw_get_bind_handle(p_madw),
				 p_madw, p_madw->resp_expected);

	/* if synchronous - wait on the event */
	if (sync) {
		osm_log(p_log, OSM_LOG_DEBUG,
			"__osmv_send_sa_req: " "Waiting for async event.\n");
		cl_event_wait_on(&p_bind->sync_event, EVENT_NO_TIMEOUT, FALSE);
		cl_event_reset(&p_bind->sync_event);
		status = p_madw->status;
	}

Exit:
	OSM_LOG_EXIT(p_log);
	return status;
}
Пример #27
0
/*
 * Send a trap (Subn LID Route) Trap(Notice) through the regular
 * connection QP connection (targeted at QP0)
 *
 * Wait for the trap repress
 */
ib_api_status_t
osmt_send_trap_wait_for_forward(IN osmtest_t * const p_osmt,
				IN osmt_qp_ctx_t * p_qp_ctx)
{
	ib_smp_t *p_smp = (ib_smp_t *) (p_qp_ctx->p_send_buf);
	ib_mad_notice_attr_t *p_ntc = ib_smp_get_payload_ptr(p_smp);
	ib_sa_mad_t *p_sa_mad;
	IB_MGT_ret_t mgt_res;
	VAPI_ret_t vapi_ret;
	VAPI_wc_desc_t wc_desc;
	VAPI_ud_av_hndl_t avh;
	IB_ud_av_t av;
	static VAPI_wr_id_t wrid = 2222;
	osm_log_t *p_log = &p_osmt->log;
	ib_api_status_t status = IB_SUCCESS;

	OSM_LOG_ENTER(p_log);

	OSM_LOG(p_log, OSM_LOG_INFO,
		"Sending Traps to QP0 of SA LID:0x%X\n",
		p_osmt->local_port.sm_lid);

	/* init the MAD */
	memset(p_smp, 0, sizeof(ib_smp_t));
	ib_mad_init_new((ib_mad_t *) p_smp,
			IB_MCLASS_SUBN_LID,
			(uint8_t) 2,
			IB_MAD_METHOD_TRAP, cl_hton64(wrid), (ib_net16_t) 0, 0);

	wrid++;
	p_smp->attr_id = IB_MAD_ATTR_NOTICE;

	/* prepare the notice */
	p_ntc->generic_type = 0x82;	/*  generic, type = 2 */
	ib_notice_set_prod_type_ho(p_ntc, 1);
	p_ntc->g_or_v.generic.trap_num = cl_hton16(0x26);
	p_ntc->issuer_lid = cl_hton16(2);

	/* --------------------- PREP ------------------------- */
	if (osmt_mtl_mad_post_recv_bufs(&p_qp_ctx->qp_bind_hndl, p_qp_ctx->p_recv_buf, 1,	/*  we need to receive both trap repress and report */
					GRH_LEN + MAD_BLOCK_SIZE, wrid) != 1) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0127: "
			"Error posting recv bufs\n");
		status = IB_ERROR;
		goto Exit;
	}
	OSM_LOG(p_log, OSM_LOG_DEBUG, "Posted recv bufs\n");

	av.dlid = p_osmt->local_port.sm_lid;
	av.grh_flag = FALSE;

	/*  EZ: returned in HACK: use constants */
	av.static_rate = 0;	/*  p_mad_addr->static_rate; */
	av.src_path_bits = 1;	/*  p_mad_addr->path_bits; */
	av.sl = 0;		/*  p_mad_addr->addr_type.gsi.service_level; */

	OSM_LOG(p_log, OSM_LOG_DEBUG,
		"av.dlid 0x%X, av.static_rate %d, av.path_bits %d\n",
		cl_ntoh16(av.dlid), av.static_rate, av.src_path_bits);

	/* send it */
	mgt_res = IB_MGT_send_mad(p_qp_ctx->ib_mgt_qp0_handle, p_smp,	/*  actual payload */
				  &av,	/*  address vector */
				  wrid,	/*  casting the mad wrapper pointer for err cb */
				  p_osmt->opt.transaction_timeout);
	if (mgt_res != IB_MGT_OK) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0128: "
			"Error sending mad (%d)\n", mgt_res);
		status = IB_ERROR;
		goto Exit;
	}

	vapi_ret =
	    osmt_mtl_create_av(&p_qp_ctx->qp_bind_hndl,
			       p_osmt->local_port.sm_lid, &avh);
	if (vapi_ret != VAPI_OK) {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0129: "
			"Error Preparing AVH (%s)\n",
			VAPI_strerror_sym(vapi_ret));
		status = IB_ERROR;
		goto Exit;
	}
	OSM_LOG(p_log, OSM_LOG_DEBUG, "Prepared AVH\n");

	OSM_LOG(p_log, OSM_LOG_DEBUG, "Trap MAD Sent\n");

	/* --------------------- RECV ------------------------- */
	vapi_ret = osmt_mtl_mad_poll4cqe(p_qp_ctx->qp_bind_hndl.hca_hndl,
					 p_qp_ctx->qp_bind_hndl.rq_cq_hndl,
					 &wc_desc, 200, 10000, &avh);
	if (vapi_ret != VAPI_SUCCESS) {
		if (vapi_ret == VAPI_CQ_EMPTY) {
			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0130: "
				"Timeout receiving mad (%s)\n",
				VAPI_strerror_sym(vapi_ret));
			status = IB_TIMEOUT;
		} else {
			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 0131: "
				"Error receiving mad (%s)\n",
				VAPI_strerror_sym(vapi_ret));
			status = IB_ERROR;
		}
		goto Exit;
	}

	/* check to see if successful - by examination of the subscribe bit */
	p_sa_mad = (ib_sa_mad_t *) (p_qp_ctx->p_recv_buf + GRH_LEN);

	if (p_sa_mad->method == IB_MAD_METHOD_REPORT) {
		if (p_sa_mad->attr_id == IB_MAD_ATTR_NOTICE) {
			OSM_LOG(p_log, OSM_LOG_INFO, "Received the Report!\n");
			status = IB_SUCCESS;
		} else {
			OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020"
				"Did not receive a Report(Notice) but attr:%d\n",
				cl_ntoh16(p_sa_mad->attr_id));
			status = IB_ERROR;
		}
	} else {
		OSM_LOG(p_log, OSM_LOG_ERROR, "ERR 1020"
			"Received an Unexpected Method:%d\n", p_smp->method);
		status = IB_ERROR;
	}

Exit:
	OSM_LOG_EXIT(p_log);
	return status;
}
Пример #28
0
/*
 * Run a complete inform info test flow:
 * - try to unregister inform info (should fail)
 * - register an inform info
 * - try to unregister inform info (should succeed)
 * - register an inform info
 * - send a trap - sleep
 * - check that a Report(Notice) arrived that match the sent one
 *
 */
ib_api_status_t osmt_run_trap64_65_flow(IN osmtest_t * const p_osmt)
{
	ib_inform_info_t inform_info;
	ib_api_status_t status;
	osmt_qp_ctx_t qp_ctx;

	OSM_LOG_ENTER(&p_osmt->log);

	/* bind the QP */
	status = osmt_bind_inform_qp(p_osmt, &qp_ctx);
	if (status != IB_SUCCESS) {
		goto Exit;
	}

	/* init the inform info */
	osmt_init_inform_info_by_trap(p_osmt, cl_hton16(64), &inform_info);

	/* send the inform info registration */
	status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1);
	if (status != IB_SUCCESS) {
		goto Exit;
	}

  /*--------------------- PREP -------------------------*/
	if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1,	/* we need to receive the report */
					GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) {
		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: "
			"Error posting recv bufs for trap 64\n");
		status = IB_ERROR;
		goto Exit;
	}

	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 64\n");

	/* init the inform info */
	osmt_init_inform_info_by_trap(p_osmt, cl_hton16(65), &inform_info);

	/* send the inform info registration */
	status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 1);
	if (status != IB_SUCCESS) {
		goto Exit;
	}

  /*--------------------- PREP -------------------------*/
	if (osmt_mtl_mad_post_recv_bufs(&qp_ctx.qp_bind_hndl, qp_ctx.p_recv_buf, 1,	/* we need to receive the report */
					GRH_LEN + MAD_BLOCK_SIZE, 1) != 1) {
		OSM_LOG(&p_osmt->log, OSM_LOG_ERROR, "ERR 0127: "
			"Error posting recv bufs for trap 65\n");
		status = IB_ERROR;
		goto Exit;
	}
	OSM_LOG(&p_osmt->log, OSM_LOG_DEBUG, "Posted recv bufs for trap 65\n");

	/* Sleep for x seconds in order to allow external script trap generation */
#if 0
	sleep(p_osmt->opt.wait_time);
#endif

	/* wait for a trap on QPN */
	status = osmt_trap_wait(p_osmt, &qp_ctx);
	if (status != IB_SUCCESS) {
		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
			"Error during Send Trap and Wait For Report: (%s)\n",
			ib_get_err_str(status));
		goto Exit;
	}

	/* try to unsubscribe for cleanup */
	status = osmt_reg_unreg_inform_info(p_osmt, &qp_ctx, &inform_info, 0);

	if (status != IB_SUCCESS) {
		OSM_LOG(&p_osmt->log, OSM_LOG_INFO,
			"Error during UnSubscribe: (%s)\n",
			ib_get_err_str(status));
		goto Exit;
	}

Exit:
	osmt_unbind_inform_qp(p_osmt, &qp_ctx);
	OSM_LOG_EXIT(&p_osmt->log);
	return status;
}
Пример #29
0
static inline boolean_t mgid_is_ip(const ib_gid_t *mgid)
{
	ib_net16_t ipsig = *(ib_net16_t *)&mgid->raw[2];
	return (ipsig == cl_hton16(0x401b) || ipsig == cl_hton16(0x601b));
}
Пример #30
0
static void ucast_mgr_set_fwd_top(IN cl_map_item_t * p_map_item,
				  IN void *cxt)
{
	osm_ucast_mgr_t *p_mgr = cxt;
	osm_switch_t * p_sw = (osm_switch_t *) p_map_item;
	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;
	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);

	if (p_mgr->max_lid < p_sw->max_lid_ho)
		p_mgr->max_lid = p_sw->max_lid_ho;

	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));
	}

	OSM_LOG_EXIT(p_mgr->p_log);
}