const struct sockaddr_storage *addr,
struct tsocket_address *local_addr,
struct tsocket_address *remote_addr);
-NTSTATUS smb_transport_direct_rdma_connect_recv(struct tevent_req *req);
+NTSTATUS smb_direct_rdma_connect_recv(struct tevent_req *req);
static void smb_direct_rdma_connect_handler(struct tevent_context *ev,
struct tevent_fd *fde,
DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
__location__, __FUNCTION__, ret, errno));
+ state->t->rdma.expected_event = RDMA_CM_EVENT_DISCONNECTED;
break;
case RDMA_CM_EVENT_ROUTE_ERROR:
}
}
-NTSTATUS smb_transport_direct_rdma_connect_recv(struct tevent_req *req)
+NTSTATUS smb_direct_rdma_connect_recv(struct tevent_req *req)
{
struct smb_direct_rdma_connect_state *state =
tevent_req_data(req,
return NT_STATUS_OK;
}
+struct smb_direct_negotiate_state {
+ struct smb_direct_transport *t;
+};
+
+struct tevent_req *smb_direct_negotiate_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smb_direct_transport *transport);
+NTSTATUS smb_direct_negotiate_recv(struct tevent_req *req);
+
+static void smb_direct_negotiate_rdma_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+static void smb_direct_negotiate_ibv_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
+struct tevent_req *smb_direct_negotiate_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct smb_direct_transport *transport)
+{
+ struct tevent_req *req;
+ struct smb_direct_negotiate_state *state;
+
+ req = tevent_req_create(mem_ctx, &state,
+ struct smb_direct_negotiate_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->t = transport;
+
+ transport->ibv.fde_channel = tevent_add_fd(ev, transport,
+ transport->ibv.comp_channel->fd,
+ TEVENT_FD_READ,
+ smb_direct_negotiate_ibv_handler,
+ req);
+ if (tevent_req_nomem(transport->ibv.fde_channel, req)) {
+ return tevent_req_post(req, ev);
+ }
+ transport->rdma.fde_channel = tevent_add_fd(ev, transport,
+ transport->rdma.cm_channel->fd,
+ TEVENT_FD_READ,
+ smb_direct_negotiate_rdma_handler,
+ req);
+ if (tevent_req_nomem(transport->rdma.fde_channel, req)) {
+ return tevent_req_post(req, ev);
+ }
+#if 0
+ cb->recv_mr = ibv_reg_mr(cb->pd, &cb->recv_buf, sizeof cb->recv_buf,
+ IBV_ACCESS_LOCAL_WRITE);
+ if (!cb->recv_mr) {
+ fprintf(stderr, "recv_buf reg_mr failed\n");
+ return errno;
+ }
+
+ cb->send_mr = ibv_reg_mr(cb->pd, &cb->send_buf, sizeof cb->send_buf, 0);
+ if (!cb->send_mr) {
+ fprintf(stderr, "send_buf reg_mr failed\n");
+ ret = errno;
+ goto err1;
+ }
+
+ cb->rdma_buf = malloc(cb->size);
+ if (!cb->rdma_buf) {
+ fprintf(stderr, "rdma_buf malloc failed\n");
+ ret = -ENOMEM;
+ goto err2;
+ }
+#endif
+ return req;
+}
+
+static void smb_direct_negotiate_ibv_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ struct tevent_req *req =
+ talloc_get_type_abort(private_data,
+ struct tevent_req);
+ struct smb_direct_negotiate_state *state =
+ tevent_req_data(req,
+ struct smb_direct_negotiate_state);
+ struct ibv_cq *cq = NULL;
+ void *cq_context = NULL;
+ struct ibv_wc wc;
+ struct ibv_recv_wr *bad_wr;
+ int ret;
+
+ errno = 0;
+
+ ret = ibv_get_cq_event(state->t->ibv.comp_channel,
+ &cq, &cq_context);
+ if (ret != 0) {
+ DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, ret, errno));
+ }
+
+ if (cq != state->t->ibv.cq) {
+ }
+ if (cq_context != state->t) {
+ }
+
+ ret = ibv_req_notify_cq(state->t->ibv.cq, 0);
+ if (ret != 0) {
+ DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, ret, errno));
+ }
+
+ ret = ibv_poll_cq(state->t->ibv.cq, 1, &wc);
+ if (ret != 1) {
+ }
+
+ ret = 0;
+
+ if (wc.status != IBV_WC_SUCCESS) {
+ }
+
+ switch (wc.opcode) {
+ case IBV_WC_SEND:
+ break;
+ case IBV_WC_RDMA_WRITE:
+ break;
+ case IBV_WC_RDMA_READ:
+ break;
+ case IBV_WC_RECV:
+ //ret = ibv_post_recv(cb->qp, &cb->rq_wr, &bad_wr);
+ break;
+ default:
+ break;
+ }
+
+ ibv_ack_cq_events(state->t->ibv.cq, 1);
+}
+
+static void smb_direct_negotiate_rdma_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
+{
+ struct tevent_req *req =
+ talloc_get_type_abort(private_data,
+ struct tevent_req);
+ struct smb_direct_negotiate_state *state =
+ tevent_req_data(req,
+ struct smb_direct_negotiate_state);
+ int ret;
+
+ errno = 0;
+
+ ret = rdma_get_cm_event(state->t->rdma.cm_channel,
+ &state->t->rdma.cm_event);
+ if (ret != 0) {
+ DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, ret, errno));
+ }
+
+ if (state->t->rdma.cm_event->status != 0) {
+ DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, ret, errno));
+
+ }
+
+ if (state->t->rdma.cm_event->event != state->t->rdma.expected_event) {
+ DEBUG(0,("%s:%s: ret[%d] errno[%d]\n",
+ __location__, __FUNCTION__, ret, errno));
+
+ }
+
+ switch (state->t->rdma.cm_event->event) {
+ 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:
+ case RDMA_CM_EVENT_CONNECT_ERROR:
+ case RDMA_CM_EVENT_UNREACHABLE:
+ case RDMA_CM_EVENT_REJECTED:
+ case RDMA_CM_EVENT_DISCONNECTED:
+ case RDMA_CM_EVENT_DEVICE_REMOVAL:
+ case RDMA_CM_EVENT_MULTICAST_JOIN:
+ case RDMA_CM_EVENT_MULTICAST_ERROR:
+ case RDMA_CM_EVENT_ADDR_CHANGE:
+ case RDMA_CM_EVENT_TIMEWAIT_EXIT:
+ //error
+ break;
+ }
+
+ if (state->t->rdma.cm_event != NULL) {
+ rdma_ack_cm_event(state->t->rdma.cm_event);
+ state->t->rdma.cm_event = NULL;
+ }
+}
+
+NTSTATUS smb_direct_rdma_connect_recv(struct tevent_req *req)
+{
+ struct smb_direct_negotiate_state *state =
+ tevent_req_data(req,
+ struct smb_direct_negotiate_state);
+ NTSTATUS status;
+
+ TALLOC_FREE(state->t->ibv.fde_channel);
+ TALLOC_FREE(state->t->rdma.fde_channel);
+
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ tevent_req_received(req);
+ return NT_STATUS_OK;
+}
#endif /* SMB_TRANSPORT_ENABLE_RDMA */