SUCCESS: smb-d negotiate request and response
authorRalph Boehme <slow@samba.org>
Sat, 1 Oct 2016 04:05:07 +0000 (21:05 -0700)
committerStefan Metzmacher <metze@samba.org>
Fri, 1 Jun 2018 12:35:14 +0000 (14:35 +0200)
Commit: bfa44ad4bc1078713ce8c7685bf880f7fdcb6e2a

Trace: smb-d-step2.pcap

libcli/smb/smb_direct.c

index 60b7021efc9a875eec1db0f71a6b4e081b58678e..6cdfe16b45e9ceaa61ef31023b8fafc78e98550f 100644 (file)
@@ -261,7 +261,7 @@ struct smb_direct_connection *smb_direct_connection_create(TALLOC_CTX *mem_ctx)
        c->state.max_send_size       = 1364;
        c->state.max_receive_size    = SMB_DIRECT_IO_MAX_DATA;
        c->state.max_fragmented_size = 1048576;
-       c->state.max_read_write_size = 0;
+       c->state.max_read_write_size = 1048576;
        c->state.receive_credit_max  = 10;//255;
        c->state.send_credit_target  = 255;
        c->state.keep_alive_internal = 5;
@@ -1588,7 +1588,7 @@ static struct tevent_req *smb_direct_connection_negotiate_accept_send(
                return tevent_req_post(req, ev);
        }
 
-       return NULL;
+       return req;
 }
 
 static void smb_direct_connection_negotiate_accept_rdma_handler(
@@ -1630,6 +1630,11 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        }
 
        switch (c->rdma.cm_event->event) {
+       case RDMA_CM_EVENT_ESTABLISHED:
+               DEBUG(0,("RDMA conn established [%p]\n", c));
+               rdma_ack_cm_event(c->rdma.cm_event);
+               c->rdma.cm_event = NULL;
+               return;
        case RDMA_CM_EVENT_DISCONNECTED:
                status = NT_STATUS_CONNECTION_DISCONNECTED;
                DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -1639,7 +1644,6 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        case RDMA_CM_EVENT_ADDR_RESOLVED:
        case RDMA_CM_EVENT_ADDR_ERROR:
        case RDMA_CM_EVENT_ROUTE_RESOLVED:
-       case RDMA_CM_EVENT_ESTABLISHED:
        case RDMA_CM_EVENT_ROUTE_ERROR:
        case RDMA_CM_EVENT_CONNECT_REQUEST:
        case RDMA_CM_EVENT_CONNECT_RESPONSE:
@@ -1652,8 +1656,10 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
        case RDMA_CM_EVENT_ADDR_CHANGE:
        case RDMA_CM_EVENT_TIMEWAIT_EXIT:
                status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-               DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                       __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+               DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s] event [%d] "
+                        "RDMA_CM_EVENT_REJECTED [%d]\n",
+                        __location__, __FUNCTION__, ret, errno, nt_errstr(status),
+                        c->rdma.cm_event->event, RDMA_CM_EVENT_REJECTED));
                tevent_req_nterror(req, status);
                return;
        }
@@ -1684,12 +1690,13 @@ static void smb_direct_connection_negotiate_accept_ibv_handler(
        int ret;
        uint16_t credits_requested;
        uint16_t credits_granted;
-       uint32_t max_read_write_size;
        uint32_t preferred_send_size;
        uint32_t max_receive_size;
        uint32_t max_fragmented_size;
        uint32_t tmp;
        struct smb_direct_io *io = NULL;
+       struct smb_direct_io *neg_send = NULL;
+       struct ibv_send_wr *bad_send_wr = NULL;
 
 DEBUG(0,("%s:%s: here...\n", __location__, __func__));
 
@@ -1774,7 +1781,7 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                DEBUG(0,("%s:%s: GOT RECV[%p] next[%p] ret[%d] errno[%d]\n",
                        __location__, __FUNCTION__, io, io->recv_wr.next, ret, errno));
                //dump_data(0, io->data, wc.byte_len);
-               if (wc.byte_len < 0x20) {
+               if (wc.byte_len < 0x14) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                        DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
                                __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
@@ -1795,14 +1802,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        return;
                }
-               if (SVAL(io->data, 0x04) != 0x0100) {
-                       status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
-                       tevent_req_nterror(req, status);
-                       return;
-               }
-               credits_requested = SVAL(io->data, 0x08);
+
+               credits_requested = SVAL(io->data, 0x06);
                if (credits_requested == 0) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                        DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -1810,23 +1811,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        return;
                }
-               credits_granted = SVAL(io->data, 0x0A);
-               if (credits_granted == 0) {
-                       status = NT_STATUS_INVALID_NETWORK_RESPONSE;
-                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
-                       tevent_req_nterror(req, status);
-                       return;
-               }
-               status = NT_STATUS(IVAL(io->data, 0x0C));
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
-                               __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
-                       tevent_req_nterror(req, status);
-                       return;
-               }
-               max_read_write_size = IVAL(io->data, 0x10);
-               preferred_send_size = IVAL(io->data, 0x14);
+
+               preferred_send_size = IVAL(io->data, 0x08);
                if (preferred_send_size > c->state.max_receive_size) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                        DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -1834,7 +1820,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        return;
                }
-               max_receive_size = IVAL(io->data, 0x18);
+
+               max_receive_size = IVAL(io->data, 0x0c);
                if (max_receive_size < 0x80) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                        DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -1842,7 +1829,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        tevent_req_nterror(req, status);
                        return;
                }
-               max_fragmented_size = IVAL(io->data, 0x1C);
+
+               max_fragmented_size = IVAL(io->data, 0x10);
                if (max_fragmented_size < 0x20000) {
                        status = NT_STATUS_INVALID_NETWORK_RESPONSE;
                        DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
@@ -1851,6 +1839,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        return;
                }
 
+               credits_granted = 1;
+
                c->state.receive_credit_target = credits_requested;
 
                tmp = c->state.max_receive_size;
@@ -1862,13 +1852,6 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                tmp = MIN(tmp, max_receive_size);
                c->state.max_send_size = tmp;
 
-               tmp = MIN(1048576, max_read_write_size);
-               c->state.max_read_write_size = tmp;
-
-               tmp = c->state.max_fragmented_size;
-               tmp = MIN(tmp, max_fragmented_size);
-               c->state.max_fragmented_size = tmp;
-
                c->state.send_credits = credits_granted;
 
                TALLOC_FREE(c->ibv.fde_channel);
@@ -1877,6 +1860,8 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
                        __location__, __FUNCTION__, ret, errno));
 
+               smb_direct_connection_debug_credits(c, __location__, __FUNCTION__);
+
                TALLOC_FREE(io);
 
                errno = 0;
@@ -1889,6 +1874,42 @@ DEBUG(0,("%s:%s: here...\n", __location__, __func__));
                        return;
                }
 
+               neg_send = c->s2r.idle;
+               DLIST_REMOVE(c->s2r.idle, neg_send);
+
+               SSVAL(neg_send->data, 0x00, 0x0100);
+               SSVAL(neg_send->data, 0x02, 0x0100);
+               SSVAL(neg_send->data, 0x04, 0x0100);
+               SSVAL(neg_send->data, 0x06, 0x0000);
+
+               credits_granted = c->state.receive_credit_max;
+               credits_granted -= c->state.receive_credits;
+               credits_granted = MIN(credits_granted, c->state.receive_credit_target);
+
+               SSVAL(neg_send->data, 0x08, c->state.send_credit_target);
+               SSVAL(neg_send->data, 0x0a, credits_granted);
+               SIVAL(neg_send->data, 0x0c, NT_STATUS_V(NT_STATUS_OK));
+               SIVAL(neg_send->data, 0x10, c->state.max_read_write_size);
+               SIVAL(neg_send->data, 0x14, c->state.max_send_size);
+               SIVAL(neg_send->data, 0x18, c->state.max_receive_size);
+               SIVAL(neg_send->data, 0x1c, c->state.max_fragmented_size);
+
+               neg_send->sge[0].addr = (uint64_t) (uintptr_t) neg_send->data;
+               neg_send->sge[0].length = 0x20;
+               neg_send->sge[0].lkey = neg_send->data_mr->lkey;
+               neg_send->send_wr.opcode = IBV_WR_SEND;
+               neg_send->send_wr.send_flags = IBV_SEND_SIGNALED;
+               neg_send->send_wr.sg_list = neg_send->sge;
+               neg_send->send_wr.num_sge = 1;
+
+               ret = ibv_post_send(c->ibv.qp, &neg_send->send_wr, &bad_send_wr);
+               if (ret != 0) {
+                       status = map_nt_error_from_unix_common(errno);
+                       DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
+                                __location__, __FUNCTION__, ret, errno, nt_errstr(status)));
+                       tevent_req_nterror(req, status);
+                       return;
+               }
                tevent_req_done(req);
                return;