Ejemplo n.º 1
0
void osm_pkey_tbl_init_new_blocks(IN const osm_pkey_tbl_t * p_pkey_tbl)
{
	ib_pkey_table_t *p_block;
	size_t b, num_blocks = cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks);

	for (b = 0; b < num_blocks; b++)
		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, b)))
			memset(p_block, 0, sizeof(*p_block));
}
Ejemplo n.º 2
0
cl_status_t
cl_ptr_vector_at(IN const cl_ptr_vector_t * const p_vector,
		 IN const size_t index, OUT void **const p_element)
{
	CL_ASSERT(p_vector);
	CL_ASSERT(p_vector->state == CL_INITIALIZED);

	/* Range check */
	if (index >= p_vector->size)
		return (CL_INVALID_PARAMETER);

	*p_element = cl_ptr_vector_get(p_vector, index);
	return (CL_SUCCESS);
}
Ejemplo n.º 3
0
void osm_pkey_tbl_destroy(IN osm_pkey_tbl_t * p_pkey_tbl)
{
	ib_pkey_table_t *p_block;
	uint16_t num_blocks, i;

	num_blocks = (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->blocks));
	for (i = 0; i < num_blocks; i++)
		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, i)))
			free(p_block);
	cl_ptr_vector_destroy(&p_pkey_tbl->blocks);

	num_blocks =
	    (uint16_t) (cl_ptr_vector_get_size(&p_pkey_tbl->new_blocks));
	for (i = 0; i < num_blocks; i++)
		if ((p_block = cl_ptr_vector_get(&p_pkey_tbl->new_blocks, i)))
			free(p_block);
	cl_ptr_vector_destroy(&p_pkey_tbl->new_blocks);

	cl_map_remove_all(&p_pkey_tbl->accum_pkeys);
	cl_map_destroy(&p_pkey_tbl->accum_pkeys);

	cl_map_remove_all(&p_pkey_tbl->keys);
	cl_map_destroy(&p_pkey_tbl->keys);
}
Ejemplo n.º 4
0
/**********************************************************************
o13-14.1.1: Except for Set(InformInfo) requests with Inform-
Info:LIDRangeBegin=0xFFFF, managers that support event forwarding
shall, upon receiving a Set(InformInfo), verify that the requester
originating the Set(InformInfo) and a Trap() source identified by Inform-
can access each other - can use path record to verify that.
**********************************************************************/
static boolean_t
__validate_ports_access_rights(IN osm_sa_t * sa,
			       IN osm_infr_t * p_infr_rec)
{
	boolean_t valid = TRUE;
	osm_physp_t *p_requester_physp;
	osm_port_t *p_port;
	osm_physp_t *p_physp;
	ib_net64_t portguid;
	ib_net16_t lid_range_begin;
	ib_net16_t lid_range_end;
	ib_net16_t lid;
	const cl_ptr_vector_t *p_tbl;
	ib_gid_t zero_gid;

	OSM_LOG_ENTER(sa->p_log);

	/* get the requester physp from the request address */
	p_requester_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						      &p_infr_rec->report_addr);

	memset(&zero_gid, 0, sizeof(zero_gid));
	if (memcmp(&(p_infr_rec->inform_record.inform_info.gid),
		   &zero_gid, sizeof(ib_gid_t))) {
		/* a gid is defined */
		portguid =
		    p_infr_rec->inform_record.inform_info.gid.unicast.
		    interface_id;

		p_port = osm_get_port_by_guid(sa->p_subn, portguid);

		if (p_port == NULL) {
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4301: "
				"Invalid port guid: 0x%016" PRIx64 "\n",
				cl_ntoh64(portguid));
			valid = FALSE;
			goto Exit;
		}

		/* get the destination InformInfo physical port */
		p_physp = p_port->p_physp;

		/* make sure that the requester and destination port can access each other
		   according to the current partitioning. */
		if (!osm_physp_share_pkey
		    (sa->p_log, p_physp, p_requester_physp)) {
			OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
				"port and requester don't share pkey\n");
			valid = FALSE;
			goto Exit;
		}
	} else {
		/* gid is zero - check if LID range is defined */
		lid_range_begin =
		    cl_ntoh16(p_infr_rec->inform_record.inform_info.
			      lid_range_begin);
		/* if lid is 0xFFFF - meaning all endports managed by the manager */
		if (lid_range_begin == 0xFFFF)
			goto Exit;

		lid_range_end =
		    cl_ntoh16(p_infr_rec->inform_record.inform_info.
			      lid_range_end);

		/* lid_range_end is set to zero if no range desired. In this case -
		   just make it equal to the lid_range_begin. */
		if (lid_range_end == 0)
			lid_range_end = lid_range_begin;

		/* go over all defined lids within the range and make sure that the
		   requester port can access them according to current partitioning. */
		for (lid = lid_range_begin; lid <= lid_range_end; lid++) {
			p_tbl = &sa->p_subn->port_lid_tbl;
			if (cl_ptr_vector_get_size(p_tbl) > lid)
				p_port = cl_ptr_vector_get(p_tbl, lid);
			else {
				/* lid requested is out of range */
				OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4302: "
					"Given LID (%u) is out of range:%u\n",
					lid, cl_ptr_vector_get_size(p_tbl));
				valid = FALSE;
				goto Exit;
			}
			if (p_port == NULL)
				continue;

			p_physp = p_port->p_physp;
			/* make sure that the requester and destination port can access
			   each other according to the current partitioning. */
			if (!osm_physp_share_pkey
			    (sa->p_log, p_physp, p_requester_physp)) {
				OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
					"port and requester don't share pkey\n");
				valid = FALSE;
				goto Exit;
			}
		}
	}

Exit:
	OSM_LOG_EXIT(sa->p_log);
	return valid;
}
Ejemplo n.º 5
0
ib_api_status_t osm_pkey_tbl_set(IN osm_pkey_tbl_t * p_pkey_tbl,
				 IN uint16_t block, IN ib_pkey_table_t * p_tbl,
				 IN boolean_t allow_both_pkeys)
{
	uint16_t b, i;
	ib_pkey_table_t *p_pkey_block;
	uint16_t *p_prev_pkey;
	ib_net16_t pkey, pkey_base;

	/* make sure the block is allocated */
	if (cl_ptr_vector_get_size(&p_pkey_tbl->blocks) > block)
		p_pkey_block =
		    (ib_pkey_table_t *) cl_ptr_vector_get(&p_pkey_tbl->blocks,
							  block);
	else
		p_pkey_block = NULL;

	if (!p_pkey_block) {
		p_pkey_block =
		    (ib_pkey_table_t *) malloc(sizeof(ib_pkey_table_t));
		if (!p_pkey_block)
			return IB_ERROR;
		memset(p_pkey_block, 0, sizeof(ib_pkey_table_t));
		cl_ptr_vector_set(&p_pkey_tbl->blocks, block, p_pkey_block);
	}

	/* sets the block values */
	memcpy(p_pkey_block, p_tbl, sizeof(ib_pkey_table_t));

	/*
	   NOTE: as the spec does not require uniqueness of PKeys in
	   tables there is no other way but to refresh the entire keys map.

	   Moreover, if the same key exists but with full membership it should
	   have precedence over the key with limited membership !
	 */
	cl_map_remove_all(&p_pkey_tbl->keys);

	for (b = 0; b < cl_ptr_vector_get_size(&p_pkey_tbl->blocks); b++) {

		p_pkey_block = cl_ptr_vector_get(&p_pkey_tbl->blocks, b);
		if (!p_pkey_block)
			continue;

		for (i = 0; i < IB_NUM_PKEY_ELEMENTS_IN_BLOCK; i++) {
			pkey = p_pkey_block->pkey_entry[i];
			if (ib_pkey_is_invalid(pkey))
				continue;

			if (allow_both_pkeys)
				pkey_base = pkey;
			else
				pkey_base = ib_pkey_get_base(pkey);

			/*
			   If allow_both_pkeys is FALSE,
			   ignore the PKey Full Member bit in the key but store
			   the pointer to the table element as the map value
			 */
			p_prev_pkey = cl_map_get(&p_pkey_tbl->keys, pkey_base);

			/* we only insert if no previous or it is not full member and allow_both_pkeys is FALSE */
			if ((p_prev_pkey == NULL) ||
			    (allow_both_pkeys == FALSE &&
			     cl_ntoh16(*p_prev_pkey) < cl_ntoh16(pkey)))
				cl_map_insert(&p_pkey_tbl->keys, pkey_base,
					      &(p_pkey_block->pkey_entry[i])
				    );
		}
	}
	return IB_SUCCESS;
}