+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- Infrastructure for SMB-Direct RDMA as transport
- Copyright (C) Stefan Metzmacher 2012
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "system/network.h"
-#include <tevent.h>
-#include "../util/tevent_ntstatus.h"
-#include "../lib/tsocket/tsocket.h"
-
-#ifdef SMB_TRANSPORT_ENABLE_RDMA
-#include <rdma/rdma_cma_abi.h>
-#include <rdma/rdma_cma.h>
-#include <infiniband/verbs.h>
-
-struct smb_direct_transport {
- struct {
- struct rdma_cm_id *cm_id;
- struct rdma_event_channel *cm_channel;
- struct tevent_fd *fde_channel;
- enum rdma_cm_event_type expected_event;
- struct rdma_cm_event *cm_event;
- } rdma;
-};
-
-static int smb_direct_transport_destructor(struct smb_direct_transport *t);
-
-static struct smb_direct_transport *smb_direct_transport_create(TALLOC_CTX *mem_ctx)
-{
- struct smb_direct_transport *t;
- int ret;
-
- t = talloc_zero(mem_ctx, struct smb_direct_transport);
- if (t == NULL) {
- return NULL;
- }
- talloc_set_destructor(t, smb_direct_transport_destructor);
-
- t->rdma.cm_channel = rdma_create_event_channel();
- if (t->rdma.cm_channel == NULL) {
- talloc_free(t);
- return NULL;
- }
-
-#if RDMA_USER_CM_MAX_ABI_VERSION >= 2
- ret = rdma_create_id(t->rdma.cm_channel,
- &t->rdma.cm_id,
- t, RDMA_PS_TCP);
-#else
- ret = rdma_create_id(t->rdma.cm_channel,
- &t->rdma.cm_id,
- t);
-#endif
- if (ret != 0) {
- talloc_free(t);
- return NULL;
- }
-
- return t;
-}
-
-static int smb_direct_transport_destructor(struct smb_direct_transport *t)
-{
- TALLOC_FREE(t->rdma.fde_channel);
-
- if (t->rdma.cm_event != NULL) {
- rdma_ack_cm_event(t->rdma.cm_event);
- t->rdma.cm_event = NULL;
- }
-
- if (t->rdma.cm_id != NULL) {
- rdma_destroy_id(t->rdma.cm_id);
- t->rdma.cm_id = NULL;
- }
-
- if (t->rdma.cm_channel != NULL) {
- rdma_destroy_event_channel(t->rdma.cm_channel);
- t->rdma.cm_channel = NULL;
- }
-
- return 0;
-}
-
-struct smb_direct_rdma_connect_state {
- struct smb_direct_transport *t;
-};
-
-static struct tevent_req *smb_direct_rdma_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct smb_direct_transport *transport,
- struct tsocket_address *local_addr,
- struct tsocket_address *remote_addr)
-{
- struct tevent_req *req;
- struct smb_direct_rdma_connect_state *state;
- int ret;
- struct sockaddr *src_addr, *dst_addr;
-
- req = tevent_req_create(mem_ctx, &state,
- struct smb_direct_rdma_connect_state);
- if (!req) {
- return NULL;
- }
- state->t = transport;
-
-/*
- * ret = smb_direct_transport_setup_ev(transport, ev);
- if (ret != 0) {
-
- }
-*/
- ret = rdma_resolve_addr(state->t->rdma.cm_id,
- src_addr, dst_addr,
- 5000);
- if (ret != 0) {
- }
- state->t->rdma.expected_event = RDMA_CM_EVENT_ADDR_RESOLVED;
-
- return req;
-}
-
-static void smb_direct_rdma_connect_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_rdma_connect_state *state =
- tevent_req_data(req,
- struct smb_direct_rdma_connect_state);
- int ret;
-
- ret = rdma_get_cm_event(state->t->rdma.cm_channel,
- &state->t->rdma.cm_event);
- if (ret != 0) {
-
- }
-
- if (state->t->rdma.cm_event->status != 0) {
-
- }
-
- if (state->t->rdma.cm_event->event != state->t->rdma.expected_event) {
-
- }
-
- switch (state->t->rdma.cm_event->event) {
- case RDMA_CM_EVENT_ADDR_RESOLVED:
- ret = rdma_resolve_route(state->t->rdma.cm_id, 5000);
- if (ret != 0) {
-
- }
- break;
- case RDMA_CM_EVENT_ADDR_ERROR:
- break;
- case RDMA_CM_EVENT_ROUTE_RESOLVED:
-
- 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_ESTABLISHED:
- 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;
- }
-}
-
-static NTSTATUS smb_transport_direct_rdma_connect_recv(struct tevent_req *req)
-{
- struct smb_direct_rdma_connect_state *state =
- tevent_req_data(req,
- struct smb_direct_rdma_connect_state);
- NTSTATUS status;
-
- if (tevent_req_is_nterror(req, &status)) {
- tevent_req_received(req);
- return status;
- }
-
- tevent_req_received(req);
- return NT_STATUS_NOT_IMPLEMENTED;
-}
-
-#endif /* SMB_TRANSPORT_ENABLE_RDMA */