Example #1
0
static void fillMAD_Get_LFTRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt16 destLid, UInt64 trId)
{
	UInt64 mask;
	struct _LinearForwardingTableRecord lft;

	memset(umad, 0, len);
	umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY);
	/* Ignore GRH */

	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_GET_TABLE);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1);
	mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_LFTRECORD);

	if (destLid > 0) {
		memset(&lft, 0, sizeof(lft));
		lft.lid = hton16(destLid);

		mask = 0x1;	/* lid */
		memcpy((UInt8 *)umad_get_mad(umad) + IB_SA_DATA_OFFS, &lft, sizeof(lft));
	}
	mad_set_field64(umad_get_mad(umad), 0, IB_SA_COMPMASK_F, mask);
}
Example #2
0
static void fillMAD_Delete_MCMemberRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt64 guid, UInt64 trId, UInt8 *mgid, UInt8 *portGid)
{
	UInt64 mask = 0;
	struct _MCMemberRecord mr;

	memset(umad, 0, len);
	umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY);
	/* Ignore GRH */

	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_DELETE);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1);
	mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_MCRECORD);

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

	memcpy(mr.mgid, mgid, 16);
	mask |= (1 << 0);

	memcpy(mr.portGid, portGid, 16);
	mask |= (1 << 1);

	mr.scope_joinState = 0x1;
	/* Scope remains unset */
	mask |= (1 << 16);

	mask |= (1 << 17);

	memcpy((UInt8 *)umad_get_mad(umad) + IB_SA_DATA_OFFS, &mr, sizeof(mr));

	mad_set_field64(umad_get_mad(umad), 0, IB_SA_COMPMASK_F, mask);
}
Example #3
0
static void fillMAD_Get_MCMemberRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt64 guid, UInt64 trId)
{
	memset(umad, 0, len);
	umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY);
	/* Ignore GRH */

	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_GET_TABLE);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1);
	mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_MCRECORD);
}
Example #4
0
/* Returns 0 (invalid base version) on error */
static uint8_t get_base_version_from_ni(int fd, uint32_t aid, int pkey_index)
{
	uint8_t rc;
    void *umad_p = NULL;
	struct umad_smp *send_mad;
	size_t length;

    umad_p = umad_alloc(1, sizeof(*send_mad) + umad_size());
    if (!umad_p) {
        OUTPUT_ERROR ("can't alloc umad for OPA check; send_size %ld\n", sizeof(*send_mad));
        return 0;
    }
    memset(umad_p, 0, sizeof(*send_mad) + umad_size());
    umad_set_grh(umad_p, 0);

    send_mad = umad_get_mad(umad_p);
	send_mad->base_version = UMAD_BASE_VERSION;
	send_mad->mgmt_class = UMAD_CLASS_SUBN_DIRECTED_ROUTE;
	send_mad->class_version = 0x01;
	send_mad->method = UMAD_METHOD_GET;
	send_mad->tid = htonl(0xDEADBEEF);
	send_mad->attr_id = htons(UMAD_SM_ATTR_NODE_INFO);
	send_mad->dr_slid = 0xffff;
	send_mad->dr_dlid = 0xffff;

    umad_set_pkey(umad_p, pkey_index);
    umad_set_addr(umad_p, 0xffff, 0, 0, 0);

	rc = 0;
    if (umad_send(fd, aid, umad_p, sizeof(*send_mad), 100, 1) < 0)
		goto free_mad;

	length = sizeof(*send_mad);
	if (umad_recv(fd, umad_p, (int *)&length, 100) < 0)
		goto free_mad;

	if (length < sizeof(*send_mad))
		goto free_mad;

	if (umad_status(umad_p) != 0)
		goto free_mad;

	rc = ((NODE_INFO *)(send_mad->data))->BaseVersion;

free_mad:
	free(umad_p);
	return rc;
}
Example #5
0
static void fillMAD_Set_MCMemberRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt64 guid, UInt64 trId, UInt8 *mgid, UInt8 *portGid)
{
	UInt64 mask = 0;
	struct _MCMemberRecord mr;

	memset(umad, 0, len);
	umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY);
	/* Ignore GRH */

	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_SET);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1);
	mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_MCRECORD);

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

	memcpy(mr.mgid, mgid, 16);
	mask |= (1 << 0);

	memcpy(mr.portGid, portGid, 16);
	mask |= (1 << 1);

	mr.qkey = hton32(0x1);
	mask |= (1 << 2);

	mr.pkey = hton16(0xffff);
	mask |= (1 << 7);

	/* SL */
	mask |= (1 << 12);

	/* FlowLabel */
	mask |= (1 << 13);
	/* Traffic class */
	mask |= (1 << 6);

	mr.scope_joinState = (0x5 << 4) | 0x1;
	mask |= (1 << 15);
	mask |= (1 << 16);

	memcpy((UInt8 *)umad_get_mad(umad) + IB_SA_DATA_OFFS, &mr, sizeof(mr));

	mad_set_field64(umad_get_mad(umad), 0, IB_SA_COMPMASK_F, mask);
}
Example #6
0
static void fillMAD_Get_PathRecord(UInt8 *umad, SInt64 len, UInt16 smLid, UInt64 guid, UInt64 trId)
{
	UInt8 dgid[16];

	memset(umad, 0, len);
	umad_set_addr(umad, smLid, MAD_QP1, MAD_DEFAULT_SL, IB_DEFAULT_QP1_QKEY);
	/* Ignore GRH */

	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_METHOD_F, IB_MAD_METHOD_GET);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_CLASSVER_F, MAD_HEADER_CLASS_VERSION_SA);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_MGMTCLASS_F, IB_SA_CLASS);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_BASEVER_F, 1);
	mad_set_field64(umad_get_mad(umad), 0, IB_MAD_TRID_F, trId);
	mad_set_field  (umad_get_mad(umad), 0, IB_MAD_ATTRID_F, IB_SA_ATTR_PATHRECORD);
	mad_set_field64(umad_get_mad(umad), 0, IB_SA_COMPMASK_F, 0x4);

	mad_set_field64(dgid, 0, IB_GID_PREFIX_F, IB_DEFAULT_SUBN_PREFIX);
	mad_set_field64(dgid, 0, IB_GID_GUID_F  , guid);

	/* 128 bit data
	 */
	mad_encode_field((UInt8 *)umad_get_mad(umad) + IB_SA_DATA_OFFS, IB_SA_PR_DGID_F, dgid);
}
/****************************************************************************** 
 * join_multicast_group
 ******************************************************************************/
int join_multicast_group(subn_adm_method method,struct mcast_parameters *params) {

	int portid = -1;
	int agentid = -1;
	void *umad_buff = NULL;
	void *mad = NULL;
	int length = MAD_SIZE;
	int test_result = 0;

	// mlid will be assigned to the new LID after the join 
	if (umad_init() < 0) {
		fprintf(stderr, "failed to init the UMAD library\n");
		goto cleanup;
	}
	/* use casting to loose the "const char0 *" */
	portid = umad_open_port((char*)params->ib_devname,params->ib_port);
	if (portid < 0) {
		fprintf(stderr,"failed to open UMAD port %d\n",params->ib_port);
		goto cleanup;
	}

	agentid = umad_register(portid,MANAGMENT_CLASS_SUBN_ADM, 2, 0, 0);
	if (agentid < 0) {
		fprintf(stderr,"failed to register UMAD agent for MADs\n");
		goto cleanup;
	}

	umad_buff = umad_alloc(1, umad_size() + MAD_SIZE);
	if (!umad_buff) {
		fprintf(stderr, "failed to allocate MAD buffer\n");
		goto cleanup;
	}

	mad = umad_get_mad(umad_buff);
	prepare_mcast_mad(method,params,(struct sa_mad_packet_t *)mad);

	if (umad_set_addr(umad_buff,params->sm_lid,1,params->sm_sl,QP1_WELL_KNOWN_Q_KEY) < 0) {
		fprintf(stderr, "failed to set the destination address of the SMP\n");
		goto cleanup;
	}

	if (umad_send(portid,agentid,umad_buff,MAD_SIZE,100,5) < 0) {
		fprintf(stderr, "failed to send MAD\n");
		goto cleanup;
	}

	if (umad_recv(portid,umad_buff,&length,5000) < 0) {
		fprintf(stderr, "failed to receive MAD response\n");
		goto cleanup;
	}

	if (check_mad_status((struct sa_mad_packet_t*)mad)) {
		fprintf(stderr, "failed to get mlid from MAD\n");
		goto cleanup;
	}

	//  "Join multicast group" message was sent 
	if (method == SUBN_ADM_METHOD_SET) {
		get_mlid_from_mad((struct sa_mad_packet_t*)mad,&params->mlid);
		params->mcast_state |= MCAST_IS_JOINED;

	//  "Leave multicast group" message was sent 
	} else { 
		params->mcast_state &= ~MCAST_IS_JOINED;
	}

cleanup:
	if (umad_buff)
		umad_free(umad_buff);

	if (portid >= 0) {
		if (agentid >= 0) {
			if (umad_unregister(portid, agentid)) {
				fprintf(stderr, "failed to deregister UMAD agent for MADs\n");
				test_result = 1;
			}
		}

		if (umad_close_port(portid)) {
			fprintf(stderr, "failed to close UMAD portid\n");
			test_result = 1;
		}
	}

	return test_result;
}
Example #8
0
/** ========================================================================= */
FSTATUS oib_send_mad2(struct oib_port *port, uint8_t *send_mad, size_t send_size,
			struct oib_mad_addr *addr, int timeout_ms, int retries)
{
	FSTATUS          status = FSUCCESS;
    void            *umad_p = NULL;
    int              response;
	uint8_t          mclass, class_ver;
    int              aid;
    int              correctedTimeout;
    struct umad_hdr *mad_hdr = (struct umad_hdr *)send_mad;
	uint16_t         ib_lid;
    int              pkey_idx;
    size_t           padded_size;

	if (!port || !send_mad || !send_size || !addr)
		return FINVALID_PARAMETER;

    ib_lid = addr->lid & 0xffff;

    // Make sure we are registered for this class/version...
	mclass = mad_hdr->mgmt_class;
	class_ver = mad_hdr->class_version;
	response = (mad_hdr->method & 0x80)
				|| (mad_hdr->method == UMAD_METHOD_TRAP_REPRESS)
				|| (mclass == UMAD_CLASS_BM &&
					ntohl(mad_hdr->attr_mod) & BM_ATTRIB_MOD_RESPONSE);
    aid  = port->umad_agents[class_ver][mclass];
    DBGPRINT (" Management Class 0x%x method 0x%x attrId 0x%x attrM 0x%x\n",mclass, mad_hdr->method,
              ntohs(mad_hdr->attr_id), ntohl(mad_hdr->attr_mod));
    DBGPRINT (" base_version 0x%x class_version 0x%x\n",mad_hdr->base_version, mad_hdr->class_version);

    if (aid == OIB_INVALID_AGENTID) {
		// automatically register for "send" only
		int err = 0;
		struct oib_class_args mgmt_class[2];

		memset(mgmt_class, 0, sizeof(mgmt_class));

		mgmt_class[0].base_version = mad_hdr->base_version;
		mgmt_class[0].mgmt_class = mad_hdr->mgmt_class;
		mgmt_class[0].class_version = mad_hdr->class_version;
		mgmt_class[0].is_responding_client = 0;
		mgmt_class[0].is_trap_client = 0;
		mgmt_class[0].is_report_client = 0;
		mgmt_class[0].kernel_rmpp = 1;
		mgmt_class[0].use_methods = 0;

		DBGPRINT ("auto registering class 0x%02x; version 0x%x for send only\n",
				mclass, class_ver);
		if ((err = oib_bind_classes(port, mgmt_class)) != 0) {
        	OUTPUT_ERROR ("Failed to auto register for class 0x%02x: %s\n",
							mclass, strerror(err));
        	status = FERROR;
        	goto done;
		}
		aid = port->umad_agents[class_ver][mclass];
    }

    // Initialize the user mad.
    // umad has limititation that outgoing packets must be > 36 bytes.
    padded_size = ( MAX(send_size,36) + 7) & ~0x7;
    DBGPRINT ("dlid %d qpn %d qkey %x sl %d\n", ib_lid, addr->qpn, addr->qkey, addr->sl);
    umad_p = umad_alloc(1, padded_size + umad_size());
    if (!umad_p) {
        OUTPUT_ERROR ("can't alloc umad send_size %ld\n", padded_size);
        status = FINSUFFICIENT_MEMORY;
        goto done;
    }
    memset(umad_p, 0, padded_size + umad_size());
    memcpy (umad_get_mad(umad_p), send_mad, send_size); /* Copy mad to umad */
    umad_set_grh(umad_p, 0);   

    pkey_idx = oib_find_pkey(port, addr->pkey);
    if (pkey_idx < 0) {
        DBGPRINT("P_Key 0x%x not found in pkey table\n", addr->pkey);
        if (addr->pkey == 0xffff) {
            pkey_idx = oib_find_pkey(port, 0x7fff);
            if (pkey_idx < 0) {
                OUTPUT_ERROR("Failed to find 0x7fff pkey defaulting to index 1\n");
                pkey_idx = 1;
            } else {
               DBGPRINT("... using 0x7fff found at index %d\n", pkey_idx);
            }
        } else {
            // Previously, this code would try to find the limited management pkey 
            //   if it could not find the requested pkey, and use that pkey instead.
            // This would often "work" because all nodes should have the limited
            //   management pkey, but b/c it was a limited member, this would result
            //   in potential timeouts - especially where the full management pkey was
            //   required.
            // Changed this code fail immediately without retrying a new pkey.
            OUTPUT_ERROR("Failed to find requested pkey:0x%x, class 0x%x aid:0x%x \n",
                         addr->pkey, mclass, ntohs(mad_hdr->attr_id));
            status = FPROTECTION;
            goto done;
        }
    }
    umad_set_pkey(umad_p, pkey_idx);

    umad_set_addr(umad_p, ib_lid?ib_lid:0xffff, addr->qpn, addr->sl, addr->qkey);

    if (dbg_file) {
        DBGPRINT(">>> sending: len %ld pktsz %zu\n", send_size, umad_size() + padded_size);
		umad_dump(umad_p);
        oib_dump_mad(dbg_file, umad_get_mad(umad_p), send_size, "send mad\n");
    }

    correctedTimeout = (timeout_ms == OIB_SEND_TIMEOUT_DEFAULT)
                     ? OIB_UTILS_DEF_TIMEOUT_MS : timeout_ms;

    if (umad_send(port->umad_fd, aid, umad_p, padded_size, (response ? 0 : correctedTimeout), retries) < 0) {
        OUTPUT_ERROR("send failed; %s, agent id %u MClass 0x%x method 0x%x attrId 0x%x attrM 0x%x\n",
				strerror(errno), aid, mclass, mad_hdr->method, 
				ntohs(mad_hdr->attr_id), ntohl(mad_hdr->attr_mod)); 
        status = FNOT_DONE;
        goto done;
    }

done:
    // Free umad if allocated.
    if (umad_p != NULL) {
        umad_free(umad_p);
    }

    return status;
}