#include <rdma/rdma_cma.h>
#include <infiniband/verbs.h>
+#define SMB_DIRECT_LISTENER_BACKLOG 100
+
+//#define SMB_DIRECT_IO_MAX_DATA 8192
+#define SMB_DIRECT_IO_MAX_DATA 1364
+#define SMB_DIRECT_DATA_MIN_HDR_SIZE 0x14
+#define SMB_DIRECT_DATA_OFFSET NDR_ROUND(SMB_DIRECT_DATA_MIN_HDR_SIZE, 8)
+
#define SMB_DIRECT_RESPONSE_REQUESTED 0x0001
+struct smb_direct_listener;
+struct smb_direct_connection;
struct smb_direct_io;
struct smb_direct_listener {
+ struct tevent_context *ev;
struct {
struct smb_direct_rdma_context context;
struct rdma_cm_id *cm_id;
enum rdma_cm_event_type expected_event;
struct rdma_cm_event *cm_event;
} rdma;
+ struct smb_direct_connection *ready;
};
struct smb_direct_connection {
+ struct smb_direct_connection *next, *prev; /* used in the listener ready list */
+ struct smb_direct_listener *l; /* only valid before fully accepted */
+
const void *last_ev;
struct {
uint32_t max_send_size;
struct smb_direct_connection *smb_direct_conn;
-//#define SMB_DIRECT_IO_MAX_DATA 8192
-#define SMB_DIRECT_IO_MAX_DATA 1364
-#define SMB_DIRECT_DATA_MIN_HDR_SIZE 0x14
-#define SMB_DIRECT_DATA_OFFSET NDR_ROUND(SMB_DIRECT_DATA_MIN_HDR_SIZE, 8)
struct smb_direct_io {
struct smb_direct_io *prev, *next;
return c;
}
-NTSTATUS smb_direct_connection_complete_alloc(struct smb_direct_connection *c)
+static NTSTATUS smb_direct_connection_complete_alloc(struct smb_direct_connection *c)
{
int ret;
uint16_t i;
static int smb_direct_connection_destructor(struct smb_direct_connection *c)
{
+ if (c->l != NULL) {
+ DLIST_REMOVE(c->l->ready, c);
+ c->l = NULL;
+ }
+
TALLOC_FREE(c->sock.fde);
if (c->sock.fd != -1) {
return tevent_req_post(req, ev);
}
- c->rdma.fde_channel = tevent_add_fd(ev, c,
+ c->rdma.fde_channel = tevent_add_fd(ev, state,
c->rdma.cm_channel->fd,
TEVENT_FD_READ,
smb_direct_connection_rdma_connect_handler,
// TODO: cleanup
talloc_set_destructor(state, smb_direct_connection_negotiate_connect_destructor);
- c->rdma.fde_channel = tevent_add_fd(ev, c, c->rdma.cm_channel->fd,
+ c->rdma.fde_channel = tevent_add_fd(ev, state,
+ c->rdma.cm_channel->fd,
TEVENT_FD_READ,
smb_direct_connection_negotiate_connect_rdma_handler,
req);
if (tevent_req_nomem(c->rdma.fde_channel, req)) {
return tevent_req_post(req, ev);
}
- c->ibv.fde_channel = tevent_add_fd(ev, c, c->ibv.comp_channel->fd,
+ c->ibv.fde_channel = tevent_add_fd(ev, state,
+ c->ibv.comp_channel->fd,
TEVENT_FD_READ,
smb_direct_connection_negotiate_connect_ibv_handler,
req);
return NT_STATUS_OK;
}
-struct smb_direct_connection *smb_direct_connection_listener(
- TALLOC_CTX *mem_ctx,
- struct rdma_cm_id *cm_id)
-{
- struct smb_direct_connection *c;
- int sfd[2];
- int ret;
- //uint16_t i;
-
- c = talloc_zero(mem_ctx, struct smb_direct_connection);
- if (c == NULL) {
- return NULL;
- }
- c->sock.fd = -1;
- c->sock.tmp_fd = -1;
-//DEBUG(0,("%s:%s: here...\n", __location__, __func__));
- talloc_set_destructor(c, smb_direct_connection_destructor);
-
- 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.receive_credit_max = 10;//255;
- c->state.send_credit_target = 255;
- c->state.keep_alive_internal = 5;
-
- ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sfd);
- if (ret == -1) {
- int saved_errno = errno;
- TALLOC_FREE(c);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
- errno = saved_errno;
- return NULL;
- }
- c->sock.tmp_fd = sfd[0];
- c->sock.fd = sfd[1];
-
-DEBUG(0,("%s:%s: sock.fd[%d] sock.tmp_fd[%d]\n",
- __location__, __func__, c->sock.fd, c->sock.tmp_fd));
-
- smb_set_close_on_exec(c->sock.tmp_fd);
- smb_set_close_on_exec(c->sock.fd);
- set_blocking(c->sock.fd, false);
-
- c->rdma.cm_channel = rdma_create_event_channel();
- if (c->rdma.cm_channel == NULL) {
- TALLOC_FREE(c);
-DEBUG(0,("%s:%s: here...\n", __location__, __func__));
- return NULL;
- }
- smb_set_close_on_exec(c->rdma.cm_channel->fd);
- set_blocking(c->rdma.cm_channel->fd, false);
-
- c->rdma.cm_id = cm_id;
-
- return c;
-}
-
uint32_t smb_direct_connection_max_fragmented_size(struct smb_direct_connection *c)
{
return c->state.max_fragmented_size;
NTSTATUS smbd_direct_listener_setup(TALLOC_CTX *mem_ctx,
const struct sockaddr_storage *addr,
- struct smb_direct_listener **_l);
+ struct smb_direct_listener **_l)
{
struct smb_direct_listener *l;
int ret;
struct sockaddr_storage _addr = *addr;
struct sockaddr *bind_addr = (struct sockaddr *)&_addr;
+ char addr_buf[INET6_ADDRSTRLEN] = { 0, };
set_sockaddr_port(bind_addr, 5445);
smb_set_close_on_exec(l->rdma.cm_channel->fd);
set_blocking(l->rdma.cm_channel->fd, false);
- l->rdma.context.c = l;
+ l->rdma.context.l = l;
#if RDMA_USER_CM_MAX_ABI_VERSION >= 2
ret = rdma_create_id(l->rdma.cm_channel,
&l->rdma.cm_id,
return status;
}
- ret = rdma_listen(l->rdma.cm_id, SMB_DIRECT_LISTEN_BACKLOG);
+ ret = rdma_listen(l->rdma.cm_id, SMB_DIRECT_LISTENER_BACKLOG);
if (ret != 0) {
NTSTATUS status;
status = map_nt_error_from_unix_common(errno);
DEBUG(0,("%s:%s: here...\n", __location__, __func__));
return status;
}
- c->rdma.expected_event = RDMA_CM_EVENT_ADDR_RESOLVED;
+ l->rdma.expected_event = RDMA_CM_EVENT_CONNECT_REQUEST;
+
+ DBG_ERR("SMB-D daemon started listening SMB-D connections on listener[%p]: %s\n",
+ l, print_sockaddr(addr_buf, sizeof(addr_buf), &_addr));
*_l = l;
return NT_STATUS_OK;
static int smb_direct_listener_destructor(struct smb_direct_listener *l)
{
- TALLOC_FREE(c->rdma.fde_channel);
+ TALLOC_FREE(l->rdma.fde_channel);
- if (c->rdma.cm_event != NULL) {
- rdma_ack_cm_event(c->rdma.cm_event);
- c->rdma.cm_event = NULL;
+ if (l->rdma.cm_event != NULL) {
+ rdma_ack_cm_event(l->rdma.cm_event);
+ l->rdma.cm_event = NULL;
}
- if (c->rdma.cm_id != NULL) {
- rdma_destroy_id(c->rdma.cm_id);
- c->rdma.cm_id = NULL;
+ if (l->rdma.cm_id != NULL) {
+ rdma_destroy_id(l->rdma.cm_id);
+ l->rdma.cm_id = NULL;
}
- if (c->rdma.cm_channel != NULL) {
- rdma_destroy_event_channel(c->rdma.cm_channel);
- c->rdma.cm_channel = NULL;
+ if (l->rdma.cm_channel != NULL) {
+ rdma_destroy_event_channel(l->rdma.cm_channel);
+ l->rdma.cm_channel = NULL;
}
return 0;
}
+struct smb_direct_listener_accept_state {
+ struct tevent_context *ev;
+ struct smb_direct_listener *l;
+};
+
+static int smb_direct_listener_accept_state_destructor(
+ struct smb_direct_listener_accept_state *state)
+{
+ TALLOC_FREE(state->l->rdma.fde_channel);
+
+ return 0;
+}
+
+static void smb_direct_listener_accept_rdma_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data);
+
struct tevent_req *smb_direct_listener_accept_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smb_direct_listener *l)
{
- struct tevent_req
+ struct tevent_req *req = NULL;
+ struct smb_direct_listener_accept_state *state = NULL;
-static void smb_direct_listener_rdma_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
+ req = tevent_req_create(mem_ctx, &state,
+ struct smb_direct_listener_accept_state);
+ if (req == NULL) {
+ return NULL;
+ }
+ state->ev = ev;
+ state->l = l;
+ talloc_set_destructor(state, smb_direct_listener_accept_state_destructor);
+
+ l->rdma.fde_channel = tevent_add_fd(ev, state,
+ l->rdma.cm_channel->fd,
+ TEVENT_FD_READ,
+ smb_direct_listener_accept_rdma_handler,
+ req);
+ if (tevent_req_nomem(l->rdma.fde_channel, req)) {
+ return tevent_req_post(req, ev);
+ }
+
+ DBG_ERR("SMB-D daemon started accepting SMB-D connections on listener[%p]\n", l);
+
+ return req;
+}
+
+static void smb_direct_listener_accept_rdma_handler(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags,
+ void *private_data)
{
- struct smb_direct_listener *l =
+ struct tevent_req *req =
talloc_get_type_abort(private_data,
- struct smb_direct_listener);
- struct rdma_cm_event *cm_ev = NULL;
- struct rdma_cm_event cm_ev_copy;
- int result;
+ struct tevent_req);
+ struct smb_direct_listener_accept_state *state =
+ tevent_req_data(req,
+ struct smb_direct_listener_accept_state);
+ struct smb_direct_listener *l = state->l;
NTSTATUS status;
+ int ret;
- DBG_ERR("SMB-D got connection event\n");
+ DBG_ERR("SMB-D got connection event listener[%p]\n", l);
ret = rdma_get_cm_event(l->rdma.cm_channel,
&l->rdma.cm_event);
DEBUG(0,("%s:%s: ret[%d] errno[%d] status[%s]\n",
__location__, __FUNCTION__, ret, errno, nt_errstr(status)));
smb_direct_listener_destructor(l); //TODO cleanup???
+ tevent_req_nterror(req, status);
return;
}
errno = 0;
- if (c->rdma.cm_event->status != 0) {
- errno = c->rdma.cm_event->status;
+ if (l->rdma.cm_event->status != 0) {
+ errno = l->rdma.cm_event->status;
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)));
smb_direct_listener_destructor(l); //TODO cleanup???
+ tevent_req_nterror(req, status);
return;
}
- if (c->rdma.cm_event->event != c->rdma.expected_event) {
- DEBUG(0,("%s:%s: c->rdma.cm_event->event[%u] != c->rdma.expected_event[%u]\n",
+ if (l->rdma.cm_event->event != l->rdma.expected_event) {
+ DEBUG(0,("%s:%s: l->rdma.cm_event->event[%u] != l->rdma.expected_event[%u]\n",
__location__, __FUNCTION__,
- c->rdma.cm_event->event, c->rdma.expected_event));
+ l->rdma.cm_event->event, l->rdma.expected_event));
}
- switch (c->rdma.cm_event->event) {
+ switch (l->rdma.cm_event->event) {
case RDMA_CM_EVENT_ADDR_RESOLVED:
DBG_DEBUG("RDMA_CM_EVENT_ADDR_RESOLVED\n");
errno = 0;
- ret = rdma_resolve_route(c->rdma.cm_id, 5000);
+ ret = rdma_resolve_route(l->rdma.cm_id, 5000);
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)));
smb_direct_listener_destructor(l); //TODO cleanup???
+ tevent_req_nterror(req, status);
return;
}
- c->rdma.expected_event = RDMA_CM_EVENT_ROUTE_RESOLVED;
- break;
- case RDMA_CM_EVENT_CONNECT_REQUEST:
+ l->rdma.expected_event = RDMA_CM_EVENT_ROUTE_RESOLVED;
+ smb_direct_listener_destructor(l); //TODO cleanup???
+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR);
+ return;
+
+ case RDMA_CM_EVENT_CONNECT_REQUEST: {
+ struct rdma_conn_param conn_param;
+ uint8_t ird_ord_hdr[8];
+ struct smb_direct_connection *c = NULL;
+
+ RSIVAL(ird_ord_hdr, 0, 0);
+ RSIVAL(ird_ord_hdr, 4, 16);
+
DBG_DEBUG("RDMA_CM_EVENT_CONNECT_REQUEST\n");
- result = rdma_accept(cm_ev_copy.id, NULL);
- if (result != 0) {
- DBG_ERR("rdma_accept failed [%s]\n", strerror(errno));
- goto fail;
+ conn_param = l->rdma.cm_event->param.conn;
+// ZERO_STRUCT(conn_param);
+ conn_param.private_data = ird_ord_hdr;
+ conn_param.private_data_len = sizeof(ird_ord_hdr);
+// conn_param.responder_resources = 1;
+// conn_param.initiator_depth = 1;
+// conn_param.retry_count = 10;
+
+ c = smb_direct_connection_create(l);
+ if (c == NULL) {
+ DBG_ERR("smb_direct_connection_create failed - ignoring\n");
+
+ rdma_reject(l->rdma.cm_event->id, NULL, 0);
+ /* wait for more */
+ break;
}
- sconn = smb_direct_connection_listener(daemon_state,
- cm_ev_copy.id);
- if (sconn == NULL) {
- DBG_ERR("smb_direct_connection_create failed\n");
- return;
+ c->rdma.cm_id = l->rdma.cm_event->id;
+ c->rdma.cm_id->context = &c->rdma.context;
+ c->rdma.cm_id->channel = c->rdma.cm_channel;
+
+ status = smb_direct_connection_complete_alloc(c);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("smb_direct_connection_complete_alloc failed - ignoring\n");
+ c->rdma.cm_id->context = NULL;
+ c->rdma.cm_id->channel = NULL;
+ c->rdma.cm_id = NULL;
+ TALLOC_FREE(c);
+
+ rdma_reject(l->rdma.cm_event->id, NULL, 0);
+ /* wait for more */
+ break;
+ }
+
+ ret = rdma_accept(c->rdma.cm_id, &conn_param);
+ if (ret != 0) {
+ DBG_ERR("rdma_accept failed [%s] result [%d]\n", strerror(errno), ret);
+ c->rdma.cm_id->context = NULL;
+ c->rdma.cm_id->channel = NULL;
+ c->rdma.cm_id = NULL;
+ TALLOC_FREE(c);
+
+ //??? rdma_reject(l->rdma.cm_event->id);
+ /* wait for more */
+ break;
}
- cm_ev_copy.id->context = sconn;
+ l->rdma.cm_event->id = NULL;
+
+ c->l = l;
+ DLIST_ADD_END(l->ready, c);
+
+ tevent_req_defer_callback(req, l->ev);
+ tevent_req_done(req);
+ }
break;
case RDMA_CM_EVENT_DISCONNECTED:
DBG_DEBUG("RDMA_CM_EVENT_DISCONNECTED\n");
-
- sconn = talloc_get_type(cm_ev_copy.id->context,
- struct smb_direct_connection);
- TALLOC_FREE(sconn);
break;
case RDMA_CM_EVENT_DEVICE_REMOVAL:
DBG_ERR("RDMA device removal\n");
- goto fail;
+ break;
default:
- DBG_ERR("event %d\n", cm_ev_copy.event);
- goto fail;
+ DBG_ERR("event %d\n", l->rdma.cm_event->event);
+ break;
}
+ rdma_ack_cm_event(l->rdma.cm_event);
+ l->rdma.cm_event = NULL;
return;
+}
-fail:
- if (cm_ev_copy.id == daemon_state->rdma.cm_id) {
- /* Listening conn is erroring out, shut it down and die */
- TALLOC_FREE(daemon_state->listening_conn);
+NTSTATUS smb_direct_listener_accept_recv(struct tevent_req *req,
+ TALLOC_CTX *mem_ctx,
+ struct smb_direct_connection **_c,
+ int *fd,
+ struct sockaddr_storage *laddr,
+ struct sockaddr_storage *raddr)
+{
+ struct smb_direct_listener_accept_state *state =
+ tevent_req_data(req,
+ struct smb_direct_listener_accept_state);
+ struct smb_direct_listener *l = state->l;
+ struct smb_direct_connection *c = NULL;
+ NTSTATUS status;
+
+ *_c = NULL;
+ *fd = -1;
+ if (laddr != NULL) {
+ ZERO_STRUCTP(laddr);
+ }
+ if (raddr != NULL) {
+ ZERO_STRUCTP(raddr);
}
- TALLOC_FREE(sconn);
- return;
+ if (tevent_req_is_nterror(req, &status)) {
+ tevent_req_received(req);
+ return status;
+ }
+
+ /*
+ * We don't call tevent_req_received()
+ * because the caller can lease this alive
+ * in order to consume more connections
+ */
+ if (l->ready == NULL) {
+ return NT_STATUS_NO_MORE_ENTRIES;
+ }
+
+ c = l->ready;
+ DLIST_REMOVE(l->ready, c);
+ c->l = NULL;
+
+ *fd = c->sock.tmp_fd;
+ c->sock.tmp_fd = -1;
+ if (laddr != NULL) {
+ ZERO_STRUCTP(laddr);
+ }
+ if (raddr != NULL) {
+ ZERO_STRUCTP(raddr);
+ }
+ *_c = talloc_move(mem_ctx, &c);
+ return NT_STATUS_OK;
+
}
#endif /* SMB_TRANSPORT_ENABLE_RDMA */
*/
state->listen_path = listen_path;
+#define SMB_DIRECT_LISTEN_BACKLOG 100
+
ret = listen(state->listen_fd, SMB_DIRECT_LISTEN_BACKLOG);
if (ret != 0) {
DBG_ERR("listen failed [%s]\n", strerror(errno));
return NT_STATUS_OK;
}
-static void rdma_cm_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data);
+static void smbd_direct_daemon_listen_accept_done(struct tevent_req *subreq);
static NTSTATUS smbd_direct_daemon_listen(
struct smb_direct_daemon_conn *conn,
struct sdd_packet_listen_response *listen_response)
{
struct smb_direct_daemon_state *daemon_state = conn->daemon_state;
- struct sockaddr_in inaddr;
- int result;
+ struct sockaddr_storage bind_addr;
+ struct smb_direct_listener *l = NULL;
+ NTSTATUS status;
+ struct tevent_req *subreq = NULL;
DBG_ERR("got listen request...\n");
return NT_STATUS_INVALID_PARAMETER;
}
- daemon_state->rdma.cm_channel = rdma_create_event_channel();
- if (daemon_state->rdma.cm_channel == NULL) {
- DBG_ERR("rdma_create_event_channel failed [%s]\n",
- strerror(errno));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- set_close_on_exec(daemon_state->rdma.cm_channel->fd);
- set_blocking(daemon_state->rdma.cm_channel->fd, false);
-
- daemon_state->rdma.context.d = daemon_state;
-#if RDMA_USER_CM_MAX_ABI_VERSION >= 2
- result = rdma_create_id(daemon_state->rdma.cm_channel,
- &daemon_state->rdma.cm_id,
- &daemon_state->rdma.context,
- RDMA_PS_TCP);
-#else
- result = rdma_create_id(daemon_state->rdma.cm_channel,
- &daemon_state->rdma.cm_id,
- &daemon_state->rdma.context);
-#endif
- if (result != 0) {
- DBG_ERR("rdma_create_id failed [%s]\n",
- strerror(errno));
- goto fail;
- }
+ ZERO_STRUCT(bind_addr);
- daemon_state->rdma.cm_channel_fde = tevent_add_fd(
- conn->ev,
- conn,
- daemon_state->rdma.cm_channel->fd,
- TEVENT_FD_READ,
- rdma_cm_handler,
- daemon_state);
- if (daemon_state->rdma.cm_channel_fde == NULL) {
- DBG_ERR("tevent_add_fd failed\n");
- goto fail;
+ status = smbd_direct_listener_setup(conn, &bind_addr, &l);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("smbd_direct_listener_setup() => %s\n",
+ nt_errstr(status));
+ return status;
}
- ZERO_STRUCT(inaddr);
- inaddr.sin_family = AF_INET;
- inaddr.sin_port = htons(5445);
- inaddr.sin_addr.s_addr = INADDR_ANY;
-
- result = rdma_bind_addr(daemon_state->rdma.cm_id,
- (struct sockaddr *)&inaddr);
- if (result != 0) {
- DBG_ERR("rdma_bind_addr failed\n");
- goto fail;
- }
+ // TODO: create an socketpair() with shutdown(SHUT_RD) or a pipe()
+ // and pass it allong, we'll to sendmsg() from our side
+ // and pass the metadata and the connection fd to the calling
+ // process. If the other end closes we need to free the
+ // listener.
- result = rdma_listen(daemon_state->rdma.cm_id,
- SMB_DIRECT_LISTEN_BACKLOG);
- if (result != 0) {
- DBG_ERR("rdma_bind_addr failed\n");
- goto fail;
+ subreq = smb_direct_listener_accept_send(l, daemon_state->ev, l);
+ if (subreq == NULL) {
+ TALLOC_FREE(l);
+ status = NT_STATUS_NO_MEMORY;
+ DBG_ERR("smbd_direct_listener_setup() => %s\n",
+ nt_errstr(status));
+ return status;
}
+ tevent_req_set_callback(subreq,
+ smbd_direct_daemon_listen_accept_done,
+ conn);
conn->listening = true;
DBG_ERR("SMB-D daemon started accepting SMB-D connections\n");
return NT_STATUS_OK;
+}
-fail:
- rdma_destroy_id(daemon_state->rdma.cm_id);
- daemon_state->rdma.cm_id = NULL;
- rdma_destroy_event_channel(daemon_state->rdma.cm_channel);
- daemon_state->rdma.cm_channel = NULL;
- return NT_STATUS_INTERNAL_ERROR;
+static void smbd_direct_daemon_listen_accept_done(struct tevent_req *subreq)
+{
+ struct smb_direct_daemon_conn *conn = tevent_req_callback_data(subreq,
+ struct smb_direct_daemon_conn);
+ struct smb_direct_daemon_state *daemon_state = conn->daemon_state;
+ struct smb_direct_connection *c = NULL;
+ int fd = -1;
+ struct sockaddr_storage laddr;
+ struct sockaddr_storage raddr;
+ NTSTATUS status;
+
+ ZERO_STRUCT(laddr);
+ ZERO_STRUCT(raddr);
+
+ status = smb_direct_listener_accept_recv(subreq, daemon_state,
+ &c, &fd, &laddr, &raddr);
+ /* no TALLOC_FREE(subreq)! we want to get more connections */
+ if (!NT_STATUS_IS_OK(status)) {
+ //TODO...
+ return;
+ }
+ subreq = NULL;
+
+ status = smb_direct_connection_setup_events(c, daemon_state->ev);
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(c);
+ close(fd);
+ //TODO...
+ return;
+ }
+
+ //TODO: pass the caller
+ TALLOC_FREE(c);
+ close(fd);
}
static NTSTATUS smbd_direct_daemon_dispatch(struct smb_direct_daemon_conn *conn,
return tevent_req_simple_recv_unix(req);
}
-static void rdma_cm_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- struct smb_direct_daemon_state *daemon_state = talloc_get_type_abort(
- private_data, struct smb_direct_daemon_state);
- struct smb_direct_connection *sconn = NULL;
- struct rdma_cm_event *cm_ev = NULL;
- int result;
- NTSTATUS status;
-
- DBG_ERR("SMB-D got connection event\n");
-
- result = rdma_get_cm_event(daemon_state->rdma.cm_channel, &cm_ev);
- if (result != 0) {
- DBG_ERR("rdma_get_cm_event failed [%s]\n", strerror(errno));
- return;
- }
-
- DBG_ERR("cm_event type [%d] cm_id [%p]\n",
- cm_ev->event, cm_ev->id);
-
- switch (cm_ev->event) {
- case RDMA_CM_EVENT_CONNECT_REQUEST: {
- struct rdma_conn_param conn_param;
- uint8_t ird_ord_hdr[8];
-
- RSIVAL(ird_ord_hdr, 0, 0);
- RSIVAL(ird_ord_hdr, 4, 16);
-
- DBG_DEBUG("RDMA_CM_EVENT_CONNECT_REQUEST\n");
-
- ZERO_STRUCT(conn_param);
-// conn_param.private_data = ird_ord_hdr;
-// conn_param.private_data_len = sizeof(ird_ord_hdr);
- conn_param.responder_resources = 1;
- conn_param.initiator_depth = 1;
-// conn_param.retry_count = 10;
-
- sconn = smb_direct_connection_listener(daemon_state,
- cm_ev->id);
- if (sconn == NULL) {
- DBG_ERR("smb_direct_connection_create failed\n");
- goto fail;
- }
-
- status = smb_direct_connection_complete_alloc(sconn);
- if (!NT_STATUS_IS_OK(status)) {
- DBG_ERR("smb_direct_connection_complete_alloc failed\n");
- goto fail;
- }
-
- cm_ev->id->context = sconn;
-
- result = rdma_accept(cm_ev->id, NULL);
- if (result != 0) {
- DBG_ERR("rdma_accept failed [%s] result [%d]\n", strerror(errno), result);
- goto fail;
- }
-
- break;
- }
-
- case RDMA_CM_EVENT_ESTABLISHED:
- DBG_DEBUG("RDMA_CM_EVENT_ESTABLISHED\n");
-
- sconn = talloc_get_type_abort(cm_ev->id->context,
- struct smb_direct_connection);
- /*
- * TODO: get things going...
- */
- break;
-
- case RDMA_CM_EVENT_DISCONNECTED:
- DBG_DEBUG("RDMA_CM_EVENT_DISCONNECTED\n");
-
- sconn = talloc_get_type(cm_ev->id->context,
- struct smb_direct_connection);
- TALLOC_FREE(sconn);
- break;
-
- case RDMA_CM_EVENT_DEVICE_REMOVAL:
- DBG_ERR("RDMA device removal\n");
- goto fail;
-
- default:
- DBG_ERR("event %d\n", cm_ev->event);
- goto fail;
- }
-
- result = rdma_ack_cm_event(cm_ev);
- if (result != 0) {
- DBG_ERR("rdma_ack_cm_event failed [%s]\n", strerror(errno));
- goto fail;
- }
-
- return;
-
-fail:
- rdma_ack_cm_event(cm_ev);
-
- if (cm_ev->id == daemon_state->rdma.cm_id) {
- /* Listening conn is erroring out, shut it down and die */
- TALLOC_FREE(daemon_state->listening_conn);
- // tevent_req_error(daemon_state->req, EPANIC);
- }
-
- TALLOC_FREE(sconn);
- return;
-}
-
#endif /* SMB_TRANSPORT_ENABLE_RDMA */