Add iSCSI parameters as defined in the iSER specification.
Handle special parameter cases for RDMA:

    - no digests
    - do not offer iSER parameters unless initiator requests them
    - do not offer MRDSL (use [IT]RDSL instead)

Except do not advertise MaxOutstandingUnexpectedPDUs just yet, as
the open-iscsi initiatior does not understand it.

Signed-off-by: Pete Wyckoff <[EMAIL PROTECTED]>
---
 usr/iscsi/iscsi_if.h |    5 +++++
 usr/iscsi/iscsid.c   |   21 ++++++++++++++++++++-
 usr/iscsi/param.c    |   38 ++++++++++++++++++++++++++++++++++++++
 usr/iscsi/target.c   |    4 ++++
 4 files changed, 67 insertions(+), 1 deletions(-)

diff --git a/usr/iscsi/iscsi_if.h b/usr/iscsi/iscsi_if.h
index 58a76a2..0e9c2eb 100644
--- a/usr/iscsi/iscsi_if.h
+++ b/usr/iscsi/iscsi_if.h
@@ -215,6 +215,11 @@ enum iscsi_param {
        ISCSI_PARAM_OFMARKINT,
        ISCSI_PARAM_IFMARKINT,
        ISCSI_PARAM_MAXCONNECTIONS,
+       /* iSCSI Extensions for RDMA (RFC5046) */
+       ISCSI_PARAM_RDMA_EXTENSIONS,
+       ISCSI_PARAM_TARGET_RDSL,
+       ISCSI_PARAM_INITIATOR_RDSL,
+       ISCSI_PARAM_MAX_OUTST_PDU,
        /* must always be last */
        ISCSI_PARAM_MAX,
 };
diff --git a/usr/iscsi/iscsid.c b/usr/iscsi/iscsid.c
index defe3a7..df0fec4 100644
--- a/usr/iscsi/iscsid.c
+++ b/usr/iscsi/iscsid.c
@@ -270,7 +270,7 @@ static void login_security_done(struct iscsi_connection 
*conn)
 static void text_scan_login(struct iscsi_connection *conn)
 {
        char *key, *value, *data;
-       int datasize, idx;
+       int datasize, idx, is_rdma = 0;
        struct iscsi_login_rsp *rsp = (struct iscsi_login_rsp *)&conn->rsp.bhs;
 
        data = conn->req.data;
@@ -289,6 +289,9 @@ static void text_scan_login(struct iscsi_connection *conn)
                        if (idx == ISCSI_PARAM_MAX_RECV_DLENGTH)
                                idx = ISCSI_PARAM_MAX_XMIT_DLENGTH;
 
+                       if (idx == ISCSI_PARAM_RDMA_EXTENSIONS)
+                               is_rdma = 1;
+
                        if (param_str_to_val(session_keys, idx, value, &val) < 
0) {
                                if (conn->session_param[idx].state
                                    == KEY_STATE_START) {
@@ -335,6 +338,15 @@ static void text_scan_login(struct iscsi_connection *conn)
                        text_key_add(conn, key, "NotUnderstood");
        }
 
+       if (is_rdma) {
+               /* do not try to do digests, not supported in iser */
+               conn->session_param[ISCSI_PARAM_HDRDGST_EN].val = DIGEST_NONE;
+               conn->session_param[ISCSI_PARAM_DATADGST_EN].val = DIGEST_NONE;
+       } else {
+               /* do not offer RDMA, initiator must explicitly request */
+               conn->session_param[ISCSI_PARAM_RDMA_EXTENSIONS].val = 0;
+       }
+
 out:
        return;
 }
@@ -354,6 +366,13 @@ static int text_check_param(struct iscsi_connection *conn)
                                        p[i].state = KEY_STATE_DONE;
                                        continue;
                                }
+                               if (p[ISCSI_PARAM_RDMA_EXTENSIONS].val == 1) {
+                                       if (i == ISCSI_PARAM_MAX_RECV_DLENGTH)
+                                               continue;
+                               } else {
+                                       if (i >= ISCSI_PARAM_RDMA_EXTENSIONS)
+                                               continue;
+                               }
                                memset(buf, 0, sizeof(buf));
                                param_val_to_str(session_keys, i, p[i].val,
                                                 buf);
diff --git a/usr/iscsi/param.c b/usr/iscsi/param.c
index 9eac62c..76236d1 100644
--- a/usr/iscsi/param.c
+++ b/usr/iscsi/param.c
@@ -118,6 +118,18 @@ static int minimum_check_val(struct iscsi_key *key, 
unsigned int *val)
        return 0;
 }
 
+static int min_or_zero_check_val(struct iscsi_key *key, unsigned int *val)
+{
+       int err = 0;
+
+       if (*val != 0 && (*val < key->min || key->max < *val)) {
+               *val = key->min;
+               err = -EINVAL;
+       }
+
+       return 0;
+}
+
 static int maximum_check_val(struct iscsi_key *key, unsigned int *val)
 {
        int err = 0;
@@ -140,6 +152,16 @@ static int minimum_set_val(struct param *param, int idx, 
unsigned int *val)
        return 0;
 }
 
+static int min_or_zero_set_val(struct param *param, int idx, unsigned int *val)
+{
+       if (*val > param[idx].val || *val == 0)
+               *val = param[idx].val;
+       else
+               param[idx].val = *val;
+
+       return 0;
+}
+
 static int maximum_set_val(struct param *param, int idx, unsigned int *val)
 {
        if (param[idx].val > *val)
@@ -265,6 +287,13 @@ static struct iscsi_key_ops minimum_ops = {
        .set_val = minimum_set_val,
 };
 
+static struct iscsi_key_ops min_or_zero_ops = {
+       .val_to_str = range_val_to_str,
+       .str_to_val = range_str_to_val,
+       .check_val = min_or_zero_check_val,
+       .set_val = min_or_zero_set_val,
+};
+
 static struct iscsi_key_ops maximum_ops = {
        .val_to_str = range_val_to_str,
        .str_to_val = range_str_to_val,
@@ -345,6 +374,15 @@ struct iscsi_key session_keys[] = {
        {"IFMarkInt", 2048, 1, 65535, &marker_ops},
        [ISCSI_PARAM_MAXCONNECTIONS] =
        {"MaxConnections", 1, 1, 65535, &minimum_ops},
+       /* iSER draft */
+       [ISCSI_PARAM_RDMA_EXTENSIONS] =
+       {"RDMAExtensions", 0, 0, 1, &and_ops},
+       [ISCSI_PARAM_TARGET_RDSL] =
+       {"TargetRecvDataSegmentLength", 8192, 512, 16777215, &minimum_ops},
+       [ISCSI_PARAM_INITIATOR_RDSL] =
+       {"InitiatorRecvDataSegmentLength", 8192, 512, 16777215, &minimum_ops},
+       [ISCSI_PARAM_MAX_OUTST_PDU] =
+       {"MaxOutstandingUnexpectedPDUs", 0, 2, 4294967295U, &min_or_zero_ops},
        [ISCSI_PARAM_MAX] =
        {NULL,},
 };
diff --git a/usr/iscsi/target.c b/usr/iscsi/target.c
index ab0685f..0471d15 100644
--- a/usr/iscsi/target.c
+++ b/usr/iscsi/target.c
@@ -283,6 +283,10 @@ int iscsi_target_create(struct target *t)
                [ISCSI_PARAM_OFMARKINT] = {0, 2048},
                [ISCSI_PARAM_IFMARKINT] = {0, 2048},
                [ISCSI_PARAM_MAXCONNECTIONS] = {0, 1},
+               [ISCSI_PARAM_RDMA_EXTENSIONS] = {0, 1},
+               [ISCSI_PARAM_TARGET_RDSL] = {0, 262144},
+               [ISCSI_PARAM_INITIATOR_RDSL] = {0, 262144},
+               [ISCSI_PARAM_MAX_OUTST_PDU] =  {0, 0},  /* not in open-iscsi */
        };
 
        target = malloc(sizeof(*target));
-- 
1.5.3.4

_______________________________________________
Stgt-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/stgt-devel

Reply via email to