+ if (msg->kqm_version != QSWLND_PROTO_VERSION) {
+ /* Future protocol version compatibility support!
+ * The next qswlnd-specific protocol rev will first
+ * send an RPC to check version.
+ * 1.4.6 and 1.4.7.early reply with a status
+ * block containing its current version.
+ * Later versions send a failure (-ve) status +
+ * magic/version */
+
+ if (!krx->krx_rpc_reply_needed) {
+ CERROR("Unexpected version %d from %s\n",
+ msg->kqm_version, libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+ LASSERT (krx->krx_rpc_reply.msg.status == -EPROTO);
+ goto done;
+ }
+
+ switch (msg->kqm_type) {
+ default:
+ CERROR("Bad request type %x from %s\n",
+ msg->kqm_type, libcfs_nid2str(fromnid));
+ goto done;
+
+ case QSWLND_MSG_IMMEDIATE:
+ if (krx->krx_rpc_reply_needed) {
+ /* Should have been a simple message */
+ CERROR("IMMEDIATE sent as RPC from %s\n",
+ libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+ nob = offsetof(kqswnal_msg_t, kqm_u.immediate.kqim_payload);
+ if (krx->krx_nob < nob) {
+ CERROR("Short IMMEDIATE %d(%d) from %s\n",
+ krx->krx_nob, nob, libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+#if KQSW_CKSUM
+ if (csum0 != msg->kqm_cksum) {
+ CERROR("Bad IMMEDIATE checksum %08x(%08x) from %s\n",
+ csum0, msg->kqm_cksum, libcfs_nid2str(fromnid));
+ CERROR("nob %d (%d)\n", krx->krx_nob, msg->kqm_nob);
+ goto done;
+ }
+#endif
+ rc = lnet_parse(ni, &msg->kqm_u.immediate.kqim_hdr,
+ fromnid, krx, 0);
+ if (rc < 0)
+ goto done;
+ return;
+
+ case QSWLND_MSG_RDMA:
+ if (!krx->krx_rpc_reply_needed) {
+ /* Should have been a simple message */
+ CERROR("RDMA sent as simple message from %s\n",
+ libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+ nob = offsetof(kqswnal_msg_t,
+ kqm_u.rdma.kqrm_rmd.kqrmd_frag[0]);
+ if (krx->krx_nob < nob) {
+ CERROR("Short RDMA message %d(%d) from %s\n",
+ krx->krx_nob, nob, libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+ if (swab)
+ __swab32s(&msg->kqm_u.rdma.kqrm_rmd.kqrmd_nfrag);
+
+ n = msg->kqm_u.rdma.kqrm_rmd.kqrmd_nfrag;
+ nob = offsetof(kqswnal_msg_t,
+ kqm_u.rdma.kqrm_rmd.kqrmd_frag[n]);
+
+ if (krx->krx_nob < nob) {
+ CERROR("short RDMA message %d(%d) from %s\n",
+ krx->krx_nob, nob, libcfs_nid2str(fromnid));
+ goto done;
+ }
+
+ if (swab) {
+ for (i = 0; i < n; i++) {
+ EP_NMD *nmd = &msg->kqm_u.rdma.kqrm_rmd.kqrmd_frag[i];
+
+ __swab32s(&nmd->nmd_addr);
+ __swab32s(&nmd->nmd_len);
+ __swab32s(&nmd->nmd_attr);
+ }
+ }
+
+#if KQSW_CKSUM
+ krx->krx_cksum = csum0; /* stash checksum so far */
+#endif
+ rc = lnet_parse(ni, &msg->kqm_u.rdma.kqrm_hdr,
+ fromnid, krx, 1);
+ if (rc < 0)
+ goto done;
+ return;