summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/iscsi_if.h3
-rw-r--r--usr/initiator.c5
-rw-r--r--usr/initiator.h8
-rw-r--r--usr/login.c80
4 files changed, 86 insertions, 10 deletions
diff --git a/include/iscsi_if.h b/include/iscsi_if.h
index 1033e7c..8777bd6 100644
--- a/include/iscsi_if.h
+++ b/include/iscsi_if.h
@@ -160,8 +160,9 @@ enum iscsi_param {
ISCSI_PARAM_ERL = 11,
ISCSI_PARAM_IFMARKER_EN = 12,
ISCSI_PARAM_OFMARKER_EN = 13,
+ ISCSI_PARAM_RDMAEXTENSIONS = 14,
};
-#define ISCSI_PARAM_MAX 14
+#define ISCSI_PARAM_MAX 15
typedef uint64_t iscsi_sessionh_t; /* iSCSI Data-Path session handle */
typedef uint64_t iscsi_connh_t; /* iSCSI Data-Path connection handle */
diff --git a/usr/initiator.c b/usr/initiator.c
index 9cdd69c..aa9bb1a 100644
--- a/usr/initiator.c
+++ b/usr/initiator.c
@@ -501,6 +501,7 @@ __session_create(node_rec_t *rec, iscsi_provider_t *provider)
session->initiator_alias = dconfig->initiator_alias;
strncpy(session->target_name, rec->name, TARGET_NAME_MAXLEN);
session->vendor_specific_keys = 1;
+ session->rdma_ext = RDMA_EXT_NOT_NEGOTIATED;
/* session's misc parameters */
session->reopen_cnt = rec->session.reopen_max;
@@ -856,6 +857,10 @@ __session_conn_recv_pdu(queue_item_t *item)
.param = ISCSI_PARAM_OFMARKER_EN,
.value = &zero,/* FIXME: session->ofmarker_en */
.conn_only = 0,
+ }, {
+ .param = ISCSI_PARAM_RDMAEXTENSIONS,
+ .value = &session->rdma_ext,
+ .conn_only = 0,
}
/*
diff --git a/usr/initiator.h b/usr/initiator.h
index 246ef0a..0ac3b7b 100644
--- a/usr/initiator.h
+++ b/usr/initiator.h
@@ -65,6 +65,12 @@ enum iscsi_login_status {
LOGIN_REDIRECT = 9,
};
+enum iscsi_rdma_ext {
+ RDMA_EXT_NO = 0,
+ RDMA_EXT_YES = 1,
+ RDMA_EXT_NOT_NEGOTIATED = 2,
+};
+
typedef enum iscsi_conn_state_e {
STATE_FREE = 0,
STATE_XPT_WAIT = 1,
@@ -288,6 +294,8 @@ typedef struct iscsi_session {
/* session's processing */
actor_t mainloop;
queue_t *queue;
+
+ enum iscsi_rdma_ext rdma_ext;
} iscsi_session_t;
/* iscsid.c */
diff --git a/usr/login.c b/usr/login.c
index 25b2487..a42e30e 100644
--- a/usr/login.c
+++ b/usr/login.c
@@ -535,6 +535,24 @@ get_op_params_text_keys(iscsi_session_t *session, int cid,
return LOGIN_NEGOTIATION_FAILED;
}
text = value_end;
+ } else if (iscsi_find_key_value("RDMAExtensions", text, end,
+ &value, &value_end)) {
+ if (session->provider->rdma) {
+ if (strcmp(value, "Yes") == 0)
+ session->rdma_ext = RDMA_EXT_YES;
+ else
+ session->rdma_ext = RDMA_EXT_NO;
+ } else if (strcmp(value, "Yes") == 0) {
+ log_error("Login negotiation failed, "
+ "can't support RDMAExtensions");
+ return LOGIN_NEGOTIATION_FAILED;
+ }
+ text = value_end;
+ } else if (iscsi_find_key_value("TargetRecvDataSegmentLength", text,
+ end, &value, &value_end)) {
+ if (session->provider->rdma)
+ conn->max_xmit_dlength = strtoul(value, NULL, 0);
+ text = value_end;
} else if (iscsi_find_key_value ("X-com.cisco.protocol", text, end,
&value, &value_end)) {
if (strcmp(value, "NotUnderstood") &&
@@ -778,7 +796,33 @@ add_params_normal_session(iscsi_session_t *session, struct iscsi_hdr *pdu,
if (!iscsi_add_text(pdu, data, max_data_length,
"DataSequenceInOrder", "Yes"))
return 0;
+ return 1;
+}
+
+static int
+add_params_provider_specific(iscsi_session_t *session, int cid,
+ struct iscsi_hdr *pdu, char *data,
+ int max_data_length)
+{
+ char value[AUTH_STR_MAX_LEN];
+ iscsi_conn_t *conn = &session->conn[cid];
+ if (!session->provider->rdma) {
+ sprintf(value, "%d", conn->max_recv_dlength);
+ if (!iscsi_add_text(pdu, data, max_data_length,
+ "MaxRecvDataSegmentLength", value))
+ return 0;
+ session->rdma_ext = RDMA_EXT_NO;
+ } else {
+ sprintf(value, "%d", conn->max_recv_dlength);
+ if (!iscsi_add_text(pdu, data, max_data_length,
+ "InitiatorRecvDataSegmentLength",
+ value))
+ return 0;
+ if (!iscsi_add_text(pdu, data, max_data_length,
+ "RDMAExtensions", "Yes"))
+ return 0;
+ }
return 1;
}
@@ -948,6 +992,11 @@ fill_op_params_text(iscsi_session_t *session, int cid, struct iscsi_hdr *pdu,
conn->current_stage = ISCSI_OP_PARMS_NEGOTIATION_STAGE;
conn->next_stage = ISCSI_FULL_FEATURE_PHASE;
*transit = 1;
+ /* For RDMA transport stage switched after RDMAExtensions negotiated */
+ if (session->provider->rdma &&
+ session->type == ISCSI_SESSION_TYPE_NORMAL &&
+ session->rdma_ext != RDMA_EXT_NOT_NEGOTIATED)
+ *transit = 0;
/*
* If we haven't gotten a partial response, then either we shouldn't be
@@ -959,12 +1008,8 @@ fill_op_params_text(iscsi_session_t *session, int cid, struct iscsi_hdr *pdu,
* request the desired settings the first time
* we are in this stage
*/
- if (!fill_crc_digest_text(conn, pdu, data, max_data_length))
- return 0;
-
- sprintf(value, "%d", conn->max_recv_dlength);
- if (!iscsi_add_text(pdu, data, max_data_length,
- "MaxRecvDataSegmentLength", value))
+ if (!session->provider->rdma &&
+ !fill_crc_digest_text(conn, pdu, data, max_data_length))
return 0;
sprintf(value, "%d", session->def_time2wait);
@@ -989,11 +1034,22 @@ fill_op_params_text(iscsi_session_t *session, int cid, struct iscsi_hdr *pdu,
"ErrorRecoveryLevel", "0"))
return 0;
- if (session->type == ISCSI_SESSION_TYPE_NORMAL)
+ if (session->type == ISCSI_SESSION_TYPE_NORMAL) {
if (!add_params_normal_session(session, pdu, data,
max_data_length))
return 0;
+ if (!add_params_provider_specific(session, cid,
+ pdu, data,
+ max_data_length))
+ return 0;
+ } else {
+ sprintf(value, "%d", conn->max_recv_dlength);
+ if (!iscsi_add_text(pdu, data, max_data_length,
+ "MaxRecvDataSegmentLength", value))
+ return 0;
+ }
+
/*
* Note: 12.22 forbids vendor-specific keys on discovery
* sessions, so the caller is violating the spec if it asks for
@@ -1003,8 +1059,14 @@ fill_op_params_text(iscsi_session_t *session, int cid, struct iscsi_hdr *pdu,
if (!add_vendor_specific_text(session, cid, pdu, data,
max_data_length))
return 0;
- } else if (!check_irrelevant_keys(session, pdu, data, max_data_length))
- return 0;
+ } else {
+ if (!check_irrelevant_keys(session, pdu, data, max_data_length))
+ return 0;
+
+ if (session->provider->rdma &&
+ !fill_crc_digest_text(conn, pdu, data, max_data_length))
+ return 0;
+ }
return 1;
}