ibsim: Support for short RMPP packets (up thru 256 bytes total)

Changes from v1:
- Added length to simulation header (by reducing context size so as not
to break ABI) and encoded length on sends and decoded and checked
lengths on receive
- Restored short/partial packet read check in umad2sim_read
- In umad2sim_write, fixed setting of umad->length
- Eliminated sim_req256 typedef

Signed-off-by: Hal Rosenstock <[EMAIL PROTECTED]>

diff --git a/TODO b/TODO
index 616ed71..b385ade 100644
--- a/TODO
+++ b/TODO
@@ -1,7 +1,7 @@
 * transaction management
   - multiple transactions per client
   - hops simulation
-  - RMPP
+  - long RMPP
 * more attributes handled
 * MKey support
 * cleaner (less) debug/warning messages
diff --git a/ibsim/ibsim.c b/ibsim/ibsim.c
index e4ab6bc..cde9ac5 100644
--- a/ibsim/ibsim.c
+++ b/ibsim/ibsim.c
@@ -492,9 +492,9 @@ static int sim_read_pkt(int fd, int client)
                if (!dcl)
                        continue;
 
-               VERB("%s %d bytes (%zu) to client %d fd %d",
+               VERB("%s %d bytes to client %d fd %d",
                     dcl == cl ? "replying" : "forwarding",
-                    size, sizeof(struct sim_request), dcl->id, dcl->fd);
+                    size, dcl->id, dcl->fd);
 
                // reply
                ret = write(dcl->fd, buf, size);
diff --git a/ibsim/sim_mad.c b/ibsim/sim_mad.c
index 675d95b..28fdd52
--- a/ibsim/sim_mad.c
+++ b/ibsim/sim_mad.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2004-2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  *
  * This file is part of ibsim.
  *
@@ -1128,14 +1129,14 @@ Smpfn *get_handle_fn(ib_rpc_t rpc, int response)
                return fn;
        }
 
-       return 0;               // No MGTCLASS matched .
+       return 0;               // No MGTCLASS matched.
 }
 
 int process_packet(Client * cl, void *p, int size, Client ** dcl)
 {
        struct sim_request *r = p;
        Port *port;
-       uint8_t data[256];
+       uint8_t data[MAD_BLOCK_SIZE];
        int status, tlid, tqp;
        int response;
        Smpfn *fn;
@@ -1144,9 +1145,10 @@ int process_packet(Client * cl, void *p, int size, 
Client ** dcl)
 
        *dcl = cl;
 
-       DEBUG("client %d, size %d", cl->id, size);
-       if (size != sizeof(*r)) {
-               IBWARN("bad packet size %d (!= %zu)", size, sizeof(*r));
+       DEBUG("client %d size %d", cl->id, size);
+       if (size > sizeof(*r) + MAD_BLOCK_SIZE) {
+               IBWARN("unsupported packet size %d (> %zu)", size,
+                      sizeof(*r) + MAD_BLOCK_SIZE);
                return -1;
        }
 
@@ -1183,7 +1185,7 @@ int process_packet(Client * cl, void *p, int size, Client 
** dcl)
                VERB("forward pkt to client %d pid %d attr %d",
                     (*dcl)->id, (*dcl)->pid, rpc.attr.id);
                forward_MAD(r->mad, &rpc, &path);
-               return sizeof(*r);      // forward only
+               return size;            // forward only
        }
 
        if (port->errrate && (random() % 100) < port->errrate) {
@@ -1214,12 +1216,12 @@ int process_packet(Client * cl, void *p, int size, 
Client ** dcl)
                VERB("PKT roll back did not succeed");
                goto _dropped;
        }
-       return sizeof(*r);
+       return sizeof(*r) + MAD_BLOCK_SIZE;
 
   _dropped:
        r->status = htonl(110);
        *dcl = cl;
-       return sizeof(*r);
+       return sizeof(*r) + MAD_BLOCK_SIZE;
 }
 
 static int encode_trap128(Port * port, char *data)
@@ -1279,48 +1281,60 @@ static int encode_trap_header(char *buf)
 
 int send_trap(Port * port, int trapnum)
 {
-       struct sim_request req;
+       struct sim_request *req;
        Client *cl;
        int ret, lid = port->lid;
-       char *data = req.mad + 64;      /* data offset */
        EncodeTrapfn *encode_trapfn = encodetrap[trapnum];
        Port *destport;
 
        if (!encode_trapfn) {
-               IBWARN("trap number %d not upported", trapnum);
+               IBWARN("trap number %d not supported", trapnum);
                return -1;
        }
 
-       memset(req.mad, 0, sizeof(req.mad));
-       encode_trap_header(req.mad);
-       if (encode_trapfn(port, data) < 0)
+       req = malloc(sizeof(*req) + MAD_BLOCK_SIZE);
+       if (!req) {
+               IBWARN("no mem for trap MAD: %m");
                return -1;
+       }
+
+       memset(req->mad, 0, MAD_BLOCK_SIZE);
+       encode_trap_header(req->mad);
+       if (encode_trapfn(port, req->mad + 64) < 0) {
+               free(req);
+               return -1;
+       }
 
        if (!(destport = lid_route_MAD(port, port->smlid))) {
+               free(req);
                IBWARN("routing failed: no route to dest lid %d", port->smlid);
                return -1;
        }
 
-       req.dlid = htons(port->smlid);
-       req.slid = htons(lid);
-       req.sqp = 0;
-       req.dqp = 0;
-       req.status = 0;
-       req.context = 0;
+       req->dlid = htons(port->smlid);
+       req->slid = htons(lid);
+       req->sqp = 0;
+       req->dqp = 0;
+       req->status = 0;
+       req->length = MAD_BLOCK_SIZE;
+       req->context = 0;
 
        // find SM client
        cl = find_client(destport, 0, 1, 0);
 
-       if (!cl)
+       if (!cl) {
+               free(req);
                return 0;
+       }
 
        if (simverb > 2) {
                xdump(stdout, "--- packet ---\n", &req, 256);
                fflush(stdout);
        }
 
-       ret = write(cl->fd, &req, sizeof(req));
-       if (ret == sizeof(req))
+       ret = write(cl->fd, req, sizeof(*req) + MAD_BLOCK_SIZE);
+       free(req);
+       if (ret == sizeof(*req) + MAD_BLOCK_SIZE)
                return 0;
 
        if (ret < 0 && (errno == ECONNREFUSED || errno == ENOTCONN)) {
diff --git a/include/ibsim.h b/include/ibsim.h
index 84568e6..2c6a841 100644
--- a/include/ibsim.h
+++ b/include/ibsim.h
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2006,2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  *
  * This file is part of ibsim.
  *
@@ -61,14 +62,17 @@ struct sim_port {
 #define SIM_MAGIC      0xdeadbeef
 #define SIM_CTL_MAX_DATA       64
 
+#define MAD_BLOCK_SIZE         256
+
 struct sim_request {
        uint32_t dlid;
        uint32_t slid;
        uint32_t dqp;
        uint32_t sqp;
        uint32_t status;
-       uint64_t context;
-       char mad[256];
+       uint32_t length;
+       uint32_t context;
+       char mad[0];
 };
 
 enum SIM_CTL_TYPES {
diff --git a/umad2sim/umad2sim.c b/umad2sim/umad2sim.c
index 4cbf8da..6f0fbad 100644
--- a/umad2sim/umad2sim.c
+++ b/umad2sim/umad2sim.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2006,2007 Voltaire, Inc. All rights reserved.
+ * Copyright (c) 2008 Xsigo Systems Inc.  All rights reserved.
  *
  * This file is part of ibsim.
  *
@@ -376,30 +377,46 @@ static int dev_sysfs_create(struct umad2sim_dev *dev)
 
 static ssize_t umad2sim_read(struct umad2sim_dev *dev, void *buf, size_t count)
 {
-       struct sim_request req;
+       struct sim_request *req;
        ib_user_mad_t *umad = (ib_user_mad_t *) buf;
        unsigned mgmt_class;
        int cnt;
 
        DEBUG("umad2sim_read: %zu...\n", count);
+       req = malloc(sizeof(*req) + MAD_BLOCK_SIZE);
+       if (!req) {
+               ERROR("umad2sim_read: no mem: %m\n");
+               return 0; /* ???? */
+       }
 
-       cnt = real_read(dev->sim_client.fd_pktin, &req, sizeof(req));
+       cnt = real_read(dev->sim_client.fd_pktin, req,
+                       sizeof(*req) + MAD_BLOCK_SIZE);
        DEBUG("umad2sim_read: got %d...\n", cnt);
-       if (cnt < sizeof(req)) {
-               ERROR("umad2sim_read: partial request - skip.\n");
+       if (cnt < sizeof(*req)) {
+               free(req);
+               ERROR("umad2sim_read: sim header incomplete - skip.\n");
+               umad->status = EAGAIN;
+               return umad_size();
+       }
+
+       if (cnt != sizeof(*req) + req->length) {
+               free(req);
+               ERROR("umad2sim_read: partial request - got %d length "
+                     "in sim header %d - skip.\n",
+                     cnt, sizeof(*req) + req->length);
                umad->status = EAGAIN;
                return umad_size();
        }
 
-       mgmt_class = mad_get_field(req.mad, 0, IB_MAD_MGMTCLASS_F);
+       mgmt_class = mad_get_field(req->mad, 0, IB_MAD_MGMTCLASS_F);
 
        DEBUG("umad2sim_read: mad: method=%x, response=%x, mgmtclass=%x, "
              "attrid=%x, attrmod=%x\n",
-             mad_get_field(req.mad, 0, IB_MAD_METHOD_F),
-             mad_get_field(req.mad, 0, IB_MAD_RESPONSE_F),
+             mad_get_field(req->mad, 0, IB_MAD_METHOD_F),
+             mad_get_field(req->mad, 0, IB_MAD_RESPONSE_F),
              mgmt_class,
-             mad_get_field(req.mad, 0, IB_MAD_ATTRID_F),
-             mad_get_field(req.mad, 0, IB_MAD_ATTRMOD_F)
+             mad_get_field(req->mad, 0, IB_MAD_ATTRID_F),
+             mad_get_field(req->mad, 0, IB_MAD_ATTRMOD_F)
            );
 
        if (mgmt_class >= arrsize(dev->agent_idx)) {
@@ -407,23 +424,24 @@ static ssize_t umad2sim_read(struct umad2sim_dev *dev, 
void *buf, size_t count)
                mgmt_class = 0;
        }
 
+       cnt -= sizeof(*req);
        umad->agent_id = dev->agent_idx[mgmt_class];
-       umad->status = ntohl(req.status);
+       umad->status = ntohl(req->status);
        umad->timeout_ms = 0;
        umad->retries = 0;
-       umad->length = umad_size() + sizeof(req.mad);
+       umad->length = umad_size() + cnt;
 
-       umad->addr.qpn = req.sqp;
+       umad->addr.qpn = req->sqp;
        umad->addr.qkey = 0;    // agent->qkey;
-       umad->addr.lid = req.slid;
+       umad->addr.lid = req->slid;
        umad->addr.sl = 0;      // agent->sl;
        umad->addr.path_bits = 0;
        umad->addr.grh_present = 0;
 
-       cnt -= sizeof(req) - sizeof(req.mad);
        if (cnt > count - umad_size())
                cnt = count - umad_size();
-       memcpy(umad_get_mad(umad), req.mad, cnt);
+       memcpy(umad_get_mad(umad), req->mad, cnt);
+       free(req);
 
        return cnt + umad_size();
 }
@@ -431,9 +449,9 @@ static ssize_t umad2sim_read(struct umad2sim_dev *dev, void 
*buf, size_t count)
 static ssize_t umad2sim_write(struct umad2sim_dev *dev,
                              const void *buf, size_t count)
 {
-       struct sim_request req;
+       struct sim_request *req;
        ib_user_mad_t *umad = (ib_user_mad_t *) buf;
-       int cnt;
+       int cnt, ocnt;
 
 #ifdef SIMULATE_SEND_ERRORS
        { static int err_count;
@@ -464,25 +482,33 @@ static ssize_t umad2sim_write(struct umad2sim_dev *dev,
              mad_get_field(umad_get_mad(umad), 0, IB_MAD_ATTRMOD_F)
            );
 
-       req.dlid = umad->addr.lid;
-       req.slid = req.dlid == 0xffff ? 0xffff : 0;     /* 0 - means auto
+       cnt = count - umad_size();
+       if (cnt > MAD_BLOCK_SIZE)
+               cnt = MAD_BLOCK_SIZE;
+       req = malloc(sizeof(*req) + cnt);
+       if (!req) {
+               ERROR("umad2sim_write: no mem for sim req: %m");
+               return -1;
+       }
+
+       req->dlid = umad->addr.lid;
+       req->slid = req->dlid == 0xffff ? 0xffff : 0;   /* 0 - means auto
                                                           (supported by ibsim) 
*/ ;
-       req.dqp = umad->addr.qpn;
-       req.sqp = htonl(dev->agents[umad->agent_id].qpn);
-       req.status = 0;
-       req.context = 0;
+       req->dqp = umad->addr.qpn;
+       req->sqp = htonl(dev->agents[umad->agent_id].qpn);
+       req->status = 0;
+       req->length = cnt;
+       req->context = 0;
 
-       cnt = count - umad_size();
-       if (cnt > sizeof(req.mad))
-               cnt = sizeof(req.mad);
-       memcpy(req.mad, umad_get_mad(umad), cnt);
+       memcpy(req->mad, umad_get_mad(umad), cnt);
 
-       cnt = write(dev->sim_client.fd_pktout, (void *)&req, sizeof(req));
-       if (cnt < 0) {
+       ocnt = write(dev->sim_client.fd_pktout, req, sizeof(*req) + cnt);
+       free(req);
+       if (ocnt < 0) {
                ERROR("umad2sim_write: cannot write\n");
                return -1;
        }
-       if (cnt < sizeof(req)) {
+       if (ocnt < sizeof(*req) + cnt) {
                ERROR("umad2sim_write: partial write\n");
        }
 


_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to