void * mad_rpc_rmpp(const void *port_id, ib_rpc_t *rpc, ib_portid_t *dport, ib_rmpp_hdr_t *rmpp, void *data) { const struct ibmad_port *p = port_id; int status, len; uint8_t sndbuf[1024], rcvbuf[1024], *mad; memset(sndbuf, 0, umad_size() + IB_MAD_SIZE); DEBUG("rmpp %p data %p", rmpp, data); if ((len = mad_build_pkt(sndbuf, rpc, dport, rmpp, data)) < 0) return 0; if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf, p->class_agents[rpc->mgtclass], len, rpc->timeout)) < 0) { IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport)); return 0; } mad = umad_get_mad(rcvbuf); if ((status = mad_get_field(mad, 0, IB_MAD_STATUS_F)) != 0) { ERRS("MAD completed with error status 0x%x; dport (%s)", status, portid2str(dport)); return 0; } if (ibdebug) { IBWARN("data offs %d sz %d", rpc->dataoffs, rpc->datasz); xdump(stderr, "rmpp mad data\n", mad + rpc->dataoffs, rpc->datasz); } if (rmpp) { rmpp->flags = mad_get_field(mad, 0, IB_SA_RMPP_FLAGS_F); if ((rmpp->flags & 0x3) && mad_get_field(mad, 0, IB_SA_RMPP_VERS_F) != 1) { IBWARN("bad rmpp version"); return 0; } rmpp->type = mad_get_field(mad, 0, IB_SA_RMPP_TYPE_F); rmpp->status = mad_get_field(mad, 0, IB_SA_RMPP_STATUS_F); DEBUG("rmpp type %d status %d", rmpp->type, rmpp->status); rmpp->d1.u = mad_get_field(mad, 0, IB_SA_RMPP_D1_F); rmpp->d2.u = mad_get_field(mad, 0, IB_SA_RMPP_D2_F); } if (data) memcpy(data, mad + rpc->dataoffs, rpc->datasz); rpc->recsz = mad_get_field(mad, 0, IB_SA_ATTROFFS_F); return data; }
static int server_respond(void *umad, int size) { ib_rpc_t rpc = { 0 }; ib_rmpp_hdr_t rmpp = { 0 }; ib_portid_t rport; uint8_t *mad = umad_get_mad(umad); ib_mad_addr_t *mad_addr; if (!(mad_addr = umad_get_mad_addr(umad))) return -1; memset(&rport, 0, sizeof(rport)); rport.lid = ntohs(mad_addr->lid); rport.qp = ntohl(mad_addr->qpn); rport.qkey = ntohl(mad_addr->qkey); rport.sl = mad_addr->sl; if (!rport.qkey && rport.qp == 1) rport.qkey = IB_DEFAULT_QP1_QKEY; rpc.mgtclass = mad_get_field(mad, 0, IB_MAD_MGMTCLASS_F); rpc.method = IB_MAD_METHOD_GET | IB_MAD_RESPONSE; rpc.attr.id = mad_get_field(mad, 0, IB_MAD_ATTRID_F); rpc.attr.mod = mad_get_field(mad, 0, IB_MAD_ATTRMOD_F); rpc.oui = mad_get_field(mad, 0, IB_VEND2_OUI_F); rpc.trid = mad_get_field64(mad, 0, IB_MAD_TRID_F); if (size > IB_MAD_SIZE) rmpp.flags = IB_RMPP_FLAG_ACTIVE; DEBUG("responding %d bytes to %s, attr 0x%x mod 0x%x qkey %x", size, portid2str(&rport), rpc.attr.id, rpc.attr.mod, rport.qkey); if (mad_build_pkt(umad, &rpc, &rport, &rmpp, 0) < 0) return -1; if (ibdebug > 1) xdump(stderr, "mad respond pkt\n", mad, IB_MAD_SIZE); if (umad_send(mad_rpc_portid(srcport), mad_rpc_class_agent(srcport, rpc.mgtclass), umad, size, rpc.timeout, 0) < 0) { DEBUG("send failed; %m"); return -1; } return 0; }
static void build_mcm_rec_umad(void *umad, ib_portid_t * dport, int method, uint64_t comp_mask, uint8_t * data) { ib_rpc_t rpc; memset(&rpc, 0, sizeof(rpc)); rpc.mgtclass = IB_SA_CLASS; rpc.method = method; rpc.attr.id = IB_SA_ATTR_MCRECORD; rpc.attr.mod = 0; // ??? rpc.mask = comp_mask; rpc.datasz = IB_SA_DATA_SIZE; rpc.dataoffs = IB_SA_DATA_OFFS; mad_build_pkt(umad, &rpc, dport, NULL, data); }
static char *ibsystat(ib_portid_t * portid, int attr) { ib_rpc_t rpc = { 0 }; int fd, agent, timeout, len; void *data = (uint8_t *) umad_get_mad(buf) + IB_VENDOR_RANGE2_DATA_OFFS; DEBUG("Sysstat ping.."); rpc.mgtclass = IB_VENDOR_OPENIB_SYSSTAT_CLASS; rpc.method = IB_MAD_METHOD_GET; rpc.attr.id = attr; rpc.attr.mod = 0; rpc.oui = oui; rpc.timeout = 0; rpc.datasz = IB_VENDOR_RANGE2_DATA_SIZE; rpc.dataoffs = IB_VENDOR_RANGE2_DATA_OFFS; portid->qp = 1; if (!portid->qkey) portid->qkey = IB_DEFAULT_QP1_QKEY; if ((len = mad_build_pkt(buf, &rpc, portid, NULL, NULL)) < 0) IBPANIC("cannot build packet."); fd = mad_rpc_portid(srcport); agent = mad_rpc_class_agent(srcport, rpc.mgtclass); timeout = ibd_timeout ? ibd_timeout : MAD_DEF_TIMEOUT_MS; if (umad_send(fd, agent, buf, len, timeout, 0) < 0) IBPANIC("umad_send failed."); len = sizeof(buf) - umad_size(); if (umad_recv(fd, buf, &len, timeout) < 0) IBPANIC("umad_recv failed."); if (umad_status(buf)) return strerror(umad_status(buf)); DEBUG("Got sysstat pong.."); if (attr != IB_PING_ATTR) puts(data); else printf("sysstat ping succeeded\n"); return 0; }
void * mad_rpc(const void *port_id, ib_rpc_t *rpc, ib_portid_t *dport, void *payload, void *rcvdata) { const struct ibmad_port *p = port_id; int status, len; uint8_t sndbuf[1024], rcvbuf[1024], *mad; len = 0; memset(sndbuf, 0, umad_size() + IB_MAD_SIZE); if ((len = mad_build_pkt(sndbuf, rpc, dport, 0, payload)) < 0) return 0; if ((len = _do_madrpc(p->port_id, sndbuf, rcvbuf, p->class_agents[rpc->mgtclass], len, rpc->timeout)) < 0) { IBWARN("_do_madrpc failed; dport (%s)", portid2str(dport)); return 0; } mad = umad_get_mad(rcvbuf); if ((status = mad_get_field(mad, 0, IB_DRSMP_STATUS_F)) != 0) { ERRS("MAD completed with error status 0x%x; dport (%s)", status, portid2str(dport)); return 0; } if (ibdebug) { IBWARN("data offs %d sz %d", rpc->dataoffs, rpc->datasz); xdump(stderr, "mad data\n", mad + rpc->dataoffs, rpc->datasz); } if (rcvdata) memcpy(rcvdata, mad + rpc->dataoffs, rpc->datasz); return rcvdata; }