source: src/linux/universal/linux-3.18/drivers/target/iscsi/iscsi_target_parameters.c @ 31885

Last change on this file since 31885 was 31885, checked in by brainslayer, 3 months ago

update

File size: 53.5 KB
Line 
1/*******************************************************************************
2 * This file contains main functions related to iSCSI Parameter negotiation.
3 *
4 * (c) Copyright 2007-2013 Datera, Inc.
5 *
6 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 ******************************************************************************/
18
19#include <linux/slab.h>
20
21#include "iscsi_target_core.h"
22#include "iscsi_target_util.h"
23#include "iscsi_target_parameters.h"
24
25int iscsi_login_rx_data(
26        struct iscsi_conn *conn,
27        char *buf,
28        int length)
29{
30        int rx_got;
31        struct kvec iov;
32
33        memset(&iov, 0, sizeof(struct kvec));
34        iov.iov_len     = length;
35        iov.iov_base    = buf;
36
37        /*
38         * Initial Marker-less Interval.
39         * Add the values regardless of IFMarker/OFMarker, considering
40         * it may not be negoitated yet.
41         */
42        conn->of_marker += length;
43
44        rx_got = rx_data(conn, &iov, 1, length);
45        if (rx_got != length) {
46                pr_err("rx_data returned %d, expecting %d.\n",
47                                rx_got, length);
48                return -1;
49        }
50
51        return 0 ;
52}
53
54int iscsi_login_tx_data(
55        struct iscsi_conn *conn,
56        char *pdu_buf,
57        char *text_buf,
58        int text_length)
59{
60        int length, tx_sent, iov_cnt = 1;
61        struct kvec iov[2];
62
63        length = (ISCSI_HDR_LEN + text_length);
64
65        memset(&iov[0], 0, 2 * sizeof(struct kvec));
66        iov[0].iov_len          = ISCSI_HDR_LEN;
67        iov[0].iov_base         = pdu_buf;
68
69        if (text_buf && text_length) {
70                iov[1].iov_len  = text_length;
71                iov[1].iov_base = text_buf;
72                iov_cnt++;
73        }
74
75        /*
76         * Initial Marker-less Interval.
77         * Add the values regardless of IFMarker/OFMarker, considering
78         * it may not be negoitated yet.
79         */
80        conn->if_marker += length;
81
82        tx_sent = tx_data(conn, &iov[0], iov_cnt, length);
83        if (tx_sent != length) {
84                pr_err("tx_data returned %d, expecting %d.\n",
85                                tx_sent, length);
86                return -1;
87        }
88
89        return 0;
90}
91
92void iscsi_dump_conn_ops(struct iscsi_conn_ops *conn_ops)
93{
94        pr_debug("HeaderDigest: %s\n", (conn_ops->HeaderDigest) ?
95                                "CRC32C" : "None");
96        pr_debug("DataDigest: %s\n", (conn_ops->DataDigest) ?
97                                "CRC32C" : "None");
98        pr_debug("MaxRecvDataSegmentLength: %u\n",
99                                conn_ops->MaxRecvDataSegmentLength);
100        pr_debug("OFMarker: %s\n", (conn_ops->OFMarker) ? "Yes" : "No");
101        pr_debug("IFMarker: %s\n", (conn_ops->IFMarker) ? "Yes" : "No");
102        if (conn_ops->OFMarker)
103                pr_debug("OFMarkInt: %u\n", conn_ops->OFMarkInt);
104        if (conn_ops->IFMarker)
105                pr_debug("IFMarkInt: %u\n", conn_ops->IFMarkInt);
106}
107
108void iscsi_dump_sess_ops(struct iscsi_sess_ops *sess_ops)
109{
110        pr_debug("InitiatorName: %s\n", sess_ops->InitiatorName);
111        pr_debug("InitiatorAlias: %s\n", sess_ops->InitiatorAlias);
112        pr_debug("TargetName: %s\n", sess_ops->TargetName);
113        pr_debug("TargetAlias: %s\n", sess_ops->TargetAlias);
114        pr_debug("TargetPortalGroupTag: %hu\n",
115                        sess_ops->TargetPortalGroupTag);
116        pr_debug("MaxConnections: %hu\n", sess_ops->MaxConnections);
117        pr_debug("InitialR2T: %s\n",
118                        (sess_ops->InitialR2T) ? "Yes" : "No");
119        pr_debug("ImmediateData: %s\n", (sess_ops->ImmediateData) ?
120                        "Yes" : "No");
121        pr_debug("MaxBurstLength: %u\n", sess_ops->MaxBurstLength);
122        pr_debug("FirstBurstLength: %u\n", sess_ops->FirstBurstLength);
123        pr_debug("DefaultTime2Wait: %hu\n", sess_ops->DefaultTime2Wait);
124        pr_debug("DefaultTime2Retain: %hu\n",
125                        sess_ops->DefaultTime2Retain);
126        pr_debug("MaxOutstandingR2T: %hu\n",
127                        sess_ops->MaxOutstandingR2T);
128        pr_debug("DataPDUInOrder: %s\n",
129                        (sess_ops->DataPDUInOrder) ? "Yes" : "No");
130        pr_debug("DataSequenceInOrder: %s\n",
131                        (sess_ops->DataSequenceInOrder) ? "Yes" : "No");
132        pr_debug("ErrorRecoveryLevel: %hu\n",
133                        sess_ops->ErrorRecoveryLevel);
134        pr_debug("SessionType: %s\n", (sess_ops->SessionType) ?
135                        "Discovery" : "Normal");
136}
137
138void iscsi_print_params(struct iscsi_param_list *param_list)
139{
140        struct iscsi_param *param;
141
142        list_for_each_entry(param, &param_list->param_list, p_list)
143                pr_debug("%s: %s\n", param->name, param->value);
144}
145
146static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *param_list,
147                char *name, char *value, u8 phase, u8 scope, u8 sender,
148                u16 type_range, u8 use)
149{
150        struct iscsi_param *param = NULL;
151
152        param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
153        if (!param) {
154                pr_err("Unable to allocate memory for parameter.\n");
155                goto out;
156        }
157        INIT_LIST_HEAD(&param->p_list);
158
159        param->name = kstrdup(name, GFP_KERNEL);
160        if (!param->name) {
161                pr_err("Unable to allocate memory for parameter name.\n");
162                goto out;
163        }
164
165        param->value = kstrdup(value, GFP_KERNEL);
166        if (!param->value) {
167                pr_err("Unable to allocate memory for parameter value.\n");
168                goto out;
169        }
170
171        param->phase            = phase;
172        param->scope            = scope;
173        param->sender           = sender;
174        param->use              = use;
175        param->type_range       = type_range;
176
177        switch (param->type_range) {
178        case TYPERANGE_BOOL_AND:
179                param->type = TYPE_BOOL_AND;
180                break;
181        case TYPERANGE_BOOL_OR:
182                param->type = TYPE_BOOL_OR;
183                break;
184        case TYPERANGE_0_TO_2:
185        case TYPERANGE_0_TO_3600:
186        case TYPERANGE_0_TO_32767:
187        case TYPERANGE_0_TO_65535:
188        case TYPERANGE_1_TO_65535:
189        case TYPERANGE_2_TO_3600:
190        case TYPERANGE_512_TO_16777215:
191                param->type = TYPE_NUMBER;
192                break;
193        case TYPERANGE_AUTH:
194        case TYPERANGE_DIGEST:
195                param->type = TYPE_VALUE_LIST | TYPE_STRING;
196                break;
197        case TYPERANGE_MARKINT:
198                param->type = TYPE_NUMBER_RANGE;
199                param->type_range |= TYPERANGE_1_TO_65535;
200                break;
201        case TYPERANGE_ISCSINAME:
202        case TYPERANGE_SESSIONTYPE:
203        case TYPERANGE_TARGETADDRESS:
204        case TYPERANGE_UTF8:
205                param->type = TYPE_STRING;
206                break;
207        default:
208                pr_err("Unknown type_range 0x%02x\n",
209                                param->type_range);
210                goto out;
211        }
212        list_add_tail(&param->p_list, &param_list->param_list);
213
214        return param;
215out:
216        if (param) {
217                kfree(param->value);
218                kfree(param->name);
219                kfree(param);
220        }
221
222        return NULL;
223}
224
225/* #warning Add extension keys */
226int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
227{
228        struct iscsi_param *param = NULL;
229        struct iscsi_param_list *pl;
230
231        pl = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
232        if (!pl) {
233                pr_err("Unable to allocate memory for"
234                                " struct iscsi_param_list.\n");
235                return -1 ;
236        }
237        INIT_LIST_HEAD(&pl->param_list);
238        INIT_LIST_HEAD(&pl->extra_response_list);
239
240        /*
241         * The format for setting the initial parameter definitions are:
242         *
243         * Parameter name:
244         * Initial value:
245         * Allowable phase:
246         * Scope:
247         * Allowable senders:
248         * Typerange:
249         * Use:
250         */
251        param = iscsi_set_default_param(pl, AUTHMETHOD, INITIAL_AUTHMETHOD,
252                        PHASE_SECURITY, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
253                        TYPERANGE_AUTH, USE_INITIAL_ONLY);
254        if (!param)
255                goto out;
256
257        param = iscsi_set_default_param(pl, HEADERDIGEST, INITIAL_HEADERDIGEST,
258                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
259                        TYPERANGE_DIGEST, USE_INITIAL_ONLY);
260        if (!param)
261                goto out;
262
263        param = iscsi_set_default_param(pl, DATADIGEST, INITIAL_DATADIGEST,
264                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
265                        TYPERANGE_DIGEST, USE_INITIAL_ONLY);
266        if (!param)
267                goto out;
268
269        param = iscsi_set_default_param(pl, MAXCONNECTIONS,
270                        INITIAL_MAXCONNECTIONS, PHASE_OPERATIONAL,
271                        SCOPE_SESSION_WIDE, SENDER_BOTH,
272                        TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
273        if (!param)
274                goto out;
275
276        param = iscsi_set_default_param(pl, SENDTARGETS, INITIAL_SENDTARGETS,
277                        PHASE_FFP0, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
278                        TYPERANGE_UTF8, 0);
279        if (!param)
280                goto out;
281
282        param = iscsi_set_default_param(pl, TARGETNAME, INITIAL_TARGETNAME,
283                        PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_BOTH,
284                        TYPERANGE_ISCSINAME, USE_ALL);
285        if (!param)
286                goto out;
287
288        param = iscsi_set_default_param(pl, INITIATORNAME,
289                        INITIAL_INITIATORNAME, PHASE_DECLARATIVE,
290                        SCOPE_SESSION_WIDE, SENDER_INITIATOR,
291                        TYPERANGE_ISCSINAME, USE_INITIAL_ONLY);
292        if (!param)
293                goto out;
294
295        param = iscsi_set_default_param(pl, TARGETALIAS, INITIAL_TARGETALIAS,
296                        PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
297                        TYPERANGE_UTF8, USE_ALL);
298        if (!param)
299                goto out;
300
301        param = iscsi_set_default_param(pl, INITIATORALIAS,
302                        INITIAL_INITIATORALIAS, PHASE_DECLARATIVE,
303                        SCOPE_SESSION_WIDE, SENDER_INITIATOR, TYPERANGE_UTF8,
304                        USE_ALL);
305        if (!param)
306                goto out;
307
308        param = iscsi_set_default_param(pl, TARGETADDRESS,
309                        INITIAL_TARGETADDRESS, PHASE_DECLARATIVE,
310                        SCOPE_SESSION_WIDE, SENDER_TARGET,
311                        TYPERANGE_TARGETADDRESS, USE_ALL);
312        if (!param)
313                goto out;
314
315        param = iscsi_set_default_param(pl, TARGETPORTALGROUPTAG,
316                        INITIAL_TARGETPORTALGROUPTAG,
317                        PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
318                        TYPERANGE_0_TO_65535, USE_INITIAL_ONLY);
319        if (!param)
320                goto out;
321
322        param = iscsi_set_default_param(pl, INITIALR2T, INITIAL_INITIALR2T,
323                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
324                        TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
325        if (!param)
326                goto out;
327
328        param = iscsi_set_default_param(pl, IMMEDIATEDATA,
329                        INITIAL_IMMEDIATEDATA, PHASE_OPERATIONAL,
330                        SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_AND,
331                        USE_LEADING_ONLY);
332        if (!param)
333                goto out;
334
335        param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
336                        INITIAL_MAXXMITDATASEGMENTLENGTH,
337                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
338                        TYPERANGE_512_TO_16777215, USE_ALL);
339        if (!param)
340                goto out;
341
342        param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
343                        INITIAL_MAXRECVDATASEGMENTLENGTH,
344                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
345                        TYPERANGE_512_TO_16777215, USE_ALL);
346        if (!param)
347                goto out;
348
349        param = iscsi_set_default_param(pl, MAXBURSTLENGTH,
350                        INITIAL_MAXBURSTLENGTH, PHASE_OPERATIONAL,
351                        SCOPE_SESSION_WIDE, SENDER_BOTH,
352                        TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
353        if (!param)
354                goto out;
355
356        param = iscsi_set_default_param(pl, FIRSTBURSTLENGTH,
357                        INITIAL_FIRSTBURSTLENGTH,
358                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
359                        TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
360        if (!param)
361                goto out;
362
363        param = iscsi_set_default_param(pl, DEFAULTTIME2WAIT,
364                        INITIAL_DEFAULTTIME2WAIT,
365                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
366                        TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
367        if (!param)
368                goto out;
369
370        param = iscsi_set_default_param(pl, DEFAULTTIME2RETAIN,
371                        INITIAL_DEFAULTTIME2RETAIN,
372                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
373                        TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
374        if (!param)
375                goto out;
376
377        param = iscsi_set_default_param(pl, MAXOUTSTANDINGR2T,
378                        INITIAL_MAXOUTSTANDINGR2T,
379                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
380                        TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
381        if (!param)
382                goto out;
383
384        param = iscsi_set_default_param(pl, DATAPDUINORDER,
385                        INITIAL_DATAPDUINORDER, PHASE_OPERATIONAL,
386                        SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_OR,
387                        USE_LEADING_ONLY);
388        if (!param)
389                goto out;
390
391        param = iscsi_set_default_param(pl, DATASEQUENCEINORDER,
392                        INITIAL_DATASEQUENCEINORDER,
393                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
394                        TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
395        if (!param)
396                goto out;
397
398        param = iscsi_set_default_param(pl, ERRORRECOVERYLEVEL,
399                        INITIAL_ERRORRECOVERYLEVEL,
400                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
401                        TYPERANGE_0_TO_2, USE_LEADING_ONLY);
402        if (!param)
403                goto out;
404
405        param = iscsi_set_default_param(pl, SESSIONTYPE, INITIAL_SESSIONTYPE,
406                        PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
407                        TYPERANGE_SESSIONTYPE, USE_LEADING_ONLY);
408        if (!param)
409                goto out;
410
411        param = iscsi_set_default_param(pl, IFMARKER, INITIAL_IFMARKER,
412                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
413                        TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
414        if (!param)
415                goto out;
416
417        param = iscsi_set_default_param(pl, OFMARKER, INITIAL_OFMARKER,
418                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
419                        TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
420        if (!param)
421                goto out;
422
423        param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT,
424                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
425                        TYPERANGE_MARKINT, USE_INITIAL_ONLY);
426        if (!param)
427                goto out;
428
429        param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT,
430                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
431                        TYPERANGE_MARKINT, USE_INITIAL_ONLY);
432        if (!param)
433                goto out;
434        /*
435         * Extra parameters for ISER from RFC-5046
436         */
437        param = iscsi_set_default_param(pl, RDMAEXTENSIONS, INITIAL_RDMAEXTENSIONS,
438                        PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
439                        TYPERANGE_BOOL_AND, USE_LEADING_ONLY);
440        if (!param)
441                goto out;
442
443        param = iscsi_set_default_param(pl, INITIATORRECVDATASEGMENTLENGTH,
444                        INITIAL_INITIATORRECVDATASEGMENTLENGTH,
445                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
446                        TYPERANGE_512_TO_16777215, USE_ALL);
447        if (!param)
448                goto out;
449
450        param = iscsi_set_default_param(pl, TARGETRECVDATASEGMENTLENGTH,
451                        INITIAL_TARGETRECVDATASEGMENTLENGTH,
452                        PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
453                        TYPERANGE_512_TO_16777215, USE_ALL);
454        if (!param)
455                goto out;
456
457        *param_list_ptr = pl;
458        return 0;
459out:
460        iscsi_release_param_list(pl);
461        return -1;
462}
463
464int iscsi_set_keys_to_negotiate(
465        struct iscsi_param_list *param_list,
466        bool iser)
467{
468        struct iscsi_param *param;
469
470        param_list->iser = iser;
471
472        list_for_each_entry(param, &param_list->param_list, p_list) {
473                param->state = 0;
474                if (!strcmp(param->name, AUTHMETHOD)) {
475                        SET_PSTATE_NEGOTIATE(param);
476                } else if (!strcmp(param->name, HEADERDIGEST)) {
477                        if (!iser)
478                                SET_PSTATE_NEGOTIATE(param);
479                } else if (!strcmp(param->name, DATADIGEST)) {
480                        if (!iser)
481                                SET_PSTATE_NEGOTIATE(param);
482                } else if (!strcmp(param->name, MAXCONNECTIONS)) {
483                        SET_PSTATE_NEGOTIATE(param);
484                } else if (!strcmp(param->name, TARGETNAME)) {
485                        continue;
486                } else if (!strcmp(param->name, INITIATORNAME)) {
487                        continue;
488                } else if (!strcmp(param->name, TARGETALIAS)) {
489                        if (param->value)
490                                SET_PSTATE_NEGOTIATE(param);
491                } else if (!strcmp(param->name, INITIATORALIAS)) {
492                        continue;
493                } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
494                        SET_PSTATE_NEGOTIATE(param);
495                } else if (!strcmp(param->name, INITIALR2T)) {
496                        SET_PSTATE_NEGOTIATE(param);
497                } else if (!strcmp(param->name, IMMEDIATEDATA)) {
498                        SET_PSTATE_NEGOTIATE(param);
499                } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
500                        if (!iser)
501                                SET_PSTATE_NEGOTIATE(param);
502                } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
503                        continue;
504                } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
505                        SET_PSTATE_NEGOTIATE(param);
506                } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
507                        SET_PSTATE_NEGOTIATE(param);
508                } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
509                        SET_PSTATE_NEGOTIATE(param);
510                } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
511                        SET_PSTATE_NEGOTIATE(param);
512                } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
513                        SET_PSTATE_NEGOTIATE(param);
514                } else if (!strcmp(param->name, DATAPDUINORDER)) {
515                        SET_PSTATE_NEGOTIATE(param);
516                } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
517                        SET_PSTATE_NEGOTIATE(param);
518                } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
519                        SET_PSTATE_NEGOTIATE(param);
520                } else if (!strcmp(param->name, SESSIONTYPE)) {
521                        SET_PSTATE_NEGOTIATE(param);
522                } else if (!strcmp(param->name, IFMARKER)) {
523                        SET_PSTATE_NEGOTIATE(param);
524                } else if (!strcmp(param->name, OFMARKER)) {
525                        SET_PSTATE_NEGOTIATE(param);
526                } else if (!strcmp(param->name, IFMARKINT)) {
527                        SET_PSTATE_NEGOTIATE(param);
528                } else if (!strcmp(param->name, OFMARKINT)) {
529                        SET_PSTATE_NEGOTIATE(param);
530                } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
531                        if (iser)
532                                SET_PSTATE_NEGOTIATE(param);
533                } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
534                        if (iser)
535                                SET_PSTATE_NEGOTIATE(param);
536                } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
537                        if (iser)
538                                SET_PSTATE_NEGOTIATE(param);
539                }
540        }
541
542        return 0;
543}
544
545int iscsi_set_keys_irrelevant_for_discovery(
546        struct iscsi_param_list *param_list)
547{
548        struct iscsi_param *param;
549
550        list_for_each_entry(param, &param_list->param_list, p_list) {
551                if (!strcmp(param->name, MAXCONNECTIONS))
552                        param->state &= ~PSTATE_NEGOTIATE;
553                else if (!strcmp(param->name, INITIALR2T))
554                        param->state &= ~PSTATE_NEGOTIATE;
555                else if (!strcmp(param->name, IMMEDIATEDATA))
556                        param->state &= ~PSTATE_NEGOTIATE;
557                else if (!strcmp(param->name, MAXBURSTLENGTH))
558                        param->state &= ~PSTATE_NEGOTIATE;
559                else if (!strcmp(param->name, FIRSTBURSTLENGTH))
560                        param->state &= ~PSTATE_NEGOTIATE;
561                else if (!strcmp(param->name, MAXOUTSTANDINGR2T))
562                        param->state &= ~PSTATE_NEGOTIATE;
563                else if (!strcmp(param->name, DATAPDUINORDER))
564                        param->state &= ~PSTATE_NEGOTIATE;
565                else if (!strcmp(param->name, DATASEQUENCEINORDER))
566                        param->state &= ~PSTATE_NEGOTIATE;
567                else if (!strcmp(param->name, ERRORRECOVERYLEVEL))
568                        param->state &= ~PSTATE_NEGOTIATE;
569                else if (!strcmp(param->name, DEFAULTTIME2WAIT))
570                        param->state &= ~PSTATE_NEGOTIATE;
571                else if (!strcmp(param->name, DEFAULTTIME2RETAIN))
572                        param->state &= ~PSTATE_NEGOTIATE;
573                else if (!strcmp(param->name, IFMARKER))
574                        param->state &= ~PSTATE_NEGOTIATE;
575                else if (!strcmp(param->name, OFMARKER))
576                        param->state &= ~PSTATE_NEGOTIATE;
577                else if (!strcmp(param->name, IFMARKINT))
578                        param->state &= ~PSTATE_NEGOTIATE;
579                else if (!strcmp(param->name, OFMARKINT))
580                        param->state &= ~PSTATE_NEGOTIATE;
581                else if (!strcmp(param->name, RDMAEXTENSIONS))
582                        param->state &= ~PSTATE_NEGOTIATE;
583                else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH))
584                        param->state &= ~PSTATE_NEGOTIATE;
585                else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH))
586                        param->state &= ~PSTATE_NEGOTIATE;
587        }
588
589        return 0;
590}
591
592int iscsi_copy_param_list(
593        struct iscsi_param_list **dst_param_list,
594        struct iscsi_param_list *src_param_list,
595        int leading)
596{
597        struct iscsi_param *param = NULL;
598        struct iscsi_param *new_param = NULL;
599        struct iscsi_param_list *param_list = NULL;
600
601        param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
602        if (!param_list) {
603                pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
604                return -1;
605        }
606        INIT_LIST_HEAD(&param_list->param_list);
607        INIT_LIST_HEAD(&param_list->extra_response_list);
608
609        list_for_each_entry(param, &src_param_list->param_list, p_list) {
610                if (!leading && (param->scope & SCOPE_SESSION_WIDE)) {
611                        if ((strcmp(param->name, "TargetName") != 0) &&
612                            (strcmp(param->name, "InitiatorName") != 0) &&
613                            (strcmp(param->name, "TargetPortalGroupTag") != 0))
614                                continue;
615                }
616
617                new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
618                if (!new_param) {
619                        pr_err("Unable to allocate memory for struct iscsi_param.\n");
620                        goto err_out;
621                }
622
623                new_param->name = kstrdup(param->name, GFP_KERNEL);
624                new_param->value = kstrdup(param->value, GFP_KERNEL);
625                if (!new_param->value || !new_param->name) {
626                        kfree(new_param->value);
627                        kfree(new_param->name);
628                        kfree(new_param);
629                        pr_err("Unable to allocate memory for parameter name/value.\n");
630                        goto err_out;
631                }
632
633                new_param->set_param = param->set_param;
634                new_param->phase = param->phase;
635                new_param->scope = param->scope;
636                new_param->sender = param->sender;
637                new_param->type = param->type;
638                new_param->use = param->use;
639                new_param->type_range = param->type_range;
640
641                list_add_tail(&new_param->p_list, &param_list->param_list);
642        }
643
644        if (!list_empty(&param_list->param_list)) {
645                *dst_param_list = param_list;
646        } else {
647                pr_err("No parameters allocated.\n");
648                goto err_out;
649        }
650
651        return 0;
652
653err_out:
654        iscsi_release_param_list(param_list);
655        return -1;
656}
657
658static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
659{
660        struct iscsi_extra_response *er, *er_tmp;
661
662        list_for_each_entry_safe(er, er_tmp, &param_list->extra_response_list,
663                        er_list) {
664                list_del(&er->er_list);
665                kfree(er);
666        }
667}
668
669void iscsi_release_param_list(struct iscsi_param_list *param_list)
670{
671        struct iscsi_param *param, *param_tmp;
672
673        list_for_each_entry_safe(param, param_tmp, &param_list->param_list,
674                        p_list) {
675                list_del(&param->p_list);
676
677                kfree(param->name);
678                kfree(param->value);
679                kfree(param);
680        }
681
682        iscsi_release_extra_responses(param_list);
683
684        kfree(param_list);
685}
686
687struct iscsi_param *iscsi_find_param_from_key(
688        char *key,
689        struct iscsi_param_list *param_list)
690{
691        struct iscsi_param *param;
692
693        if (!key || !param_list) {
694                pr_err("Key or parameter list pointer is NULL.\n");
695                return NULL;
696        }
697
698        list_for_each_entry(param, &param_list->param_list, p_list) {
699                if (!strcmp(key, param->name))
700                        return param;
701        }
702
703        pr_err("Unable to locate key \"%s\".\n", key);
704        return NULL;
705}
706
707int iscsi_extract_key_value(char *textbuf, char **key, char **value)
708{
709        *value = strchr(textbuf, '=');
710        if (!*value) {
711                pr_err("Unable to locate \"=\" separator for key,"
712                                " ignoring request.\n");
713                return -1;
714        }
715
716        *key = textbuf;
717        **value = '\0';
718        *value = *value + 1;
719
720        return 0;
721}
722
723int iscsi_update_param_value(struct iscsi_param *param, char *value)
724{
725        kfree(param->value);
726
727        param->value = kstrdup(value, GFP_KERNEL);
728        if (!param->value) {
729                pr_err("Unable to allocate memory for value.\n");
730                return -ENOMEM;
731        }
732
733        pr_debug("iSCSI Parameter updated to %s=%s\n",
734                        param->name, param->value);
735        return 0;
736}
737
738static int iscsi_add_notunderstood_response(
739        char *key,
740        char *value,
741        struct iscsi_param_list *param_list)
742{
743        struct iscsi_extra_response *extra_response;
744
745        if (strlen(value) > VALUE_MAXLEN) {
746                pr_err("Value for notunderstood key \"%s\" exceeds %d,"
747                        " protocol error.\n", key, VALUE_MAXLEN);
748                return -1;
749        }
750
751        extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL);
752        if (!extra_response) {
753                pr_err("Unable to allocate memory for"
754                        " struct iscsi_extra_response.\n");
755                return -1;
756        }
757        INIT_LIST_HEAD(&extra_response->er_list);
758
759        strlcpy(extra_response->key, key, sizeof(extra_response->key));
760        strlcpy(extra_response->value, NOTUNDERSTOOD,
761                sizeof(extra_response->value));
762
763        list_add_tail(&extra_response->er_list,
764                        &param_list->extra_response_list);
765        return 0;
766}
767
768static int iscsi_check_for_auth_key(char *key)
769{
770        /*
771         * RFC 1994
772         */
773        if (!strcmp(key, "CHAP_A") || !strcmp(key, "CHAP_I") ||
774            !strcmp(key, "CHAP_C") || !strcmp(key, "CHAP_N") ||
775            !strcmp(key, "CHAP_R"))
776                return 1;
777
778        /*
779         * RFC 2945
780         */
781        if (!strcmp(key, "SRP_U") || !strcmp(key, "SRP_N") ||
782            !strcmp(key, "SRP_g") || !strcmp(key, "SRP_s") ||
783            !strcmp(key, "SRP_A") || !strcmp(key, "SRP_B") ||
784            !strcmp(key, "SRP_M") || !strcmp(key, "SRP_HM"))
785                return 1;
786
787        return 0;
788}
789
790static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
791{
792        if (IS_TYPE_BOOL_AND(param)) {
793                if (!strcmp(param->value, NO))
794                        SET_PSTATE_REPLY_OPTIONAL(param);
795        } else if (IS_TYPE_BOOL_OR(param)) {
796                if (!strcmp(param->value, YES))
797                        SET_PSTATE_REPLY_OPTIONAL(param);
798                 /*
799                  * Required for gPXE iSCSI boot client
800                  */
801                if (!strcmp(param->name, IMMEDIATEDATA))
802                        SET_PSTATE_REPLY_OPTIONAL(param);
803        } else if (IS_TYPE_NUMBER(param)) {
804                if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
805                        SET_PSTATE_REPLY_OPTIONAL(param);
806                /*
807                 * Required for gPXE iSCSI boot client
808                 */
809                if (!strcmp(param->name, MAXCONNECTIONS))
810                        SET_PSTATE_REPLY_OPTIONAL(param);
811        } else if (IS_PHASE_DECLARATIVE(param))
812                SET_PSTATE_REPLY_OPTIONAL(param);
813}
814
815static int iscsi_check_boolean_value(struct iscsi_param *param, char *value)
816{
817        if (strcmp(value, YES) && strcmp(value, NO)) {
818                pr_err("Illegal value for \"%s\", must be either"
819                        " \"%s\" or \"%s\".\n", param->name, YES, NO);
820                return -1;
821        }
822
823        return 0;
824}
825
826static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_ptr)
827{
828        char *tmpptr;
829        int value = 0;
830
831        value = simple_strtoul(value_ptr, &tmpptr, 0);
832
833        if (IS_TYPERANGE_0_TO_2(param)) {
834                if ((value < 0) || (value > 2)) {
835                        pr_err("Illegal value for \"%s\", must be"
836                                " between 0 and 2.\n", param->name);
837                        return -1;
838                }
839                return 0;
840        }
841        if (IS_TYPERANGE_0_TO_3600(param)) {
842                if ((value < 0) || (value > 3600)) {
843                        pr_err("Illegal value for \"%s\", must be"
844                                " between 0 and 3600.\n", param->name);
845                        return -1;
846                }
847                return 0;
848        }
849        if (IS_TYPERANGE_0_TO_32767(param)) {
850                if ((value < 0) || (value > 32767)) {
851                        pr_err("Illegal value for \"%s\", must be"
852                                " between 0 and 32767.\n", param->name);
853                        return -1;
854                }
855                return 0;
856        }
857        if (IS_TYPERANGE_0_TO_65535(param)) {
858                if ((value < 0) || (value > 65535)) {
859                        pr_err("Illegal value for \"%s\", must be"
860                                " between 0 and 65535.\n", param->name);
861                        return -1;
862                }
863                return 0;
864        }
865        if (IS_TYPERANGE_1_TO_65535(param)) {
866                if ((value < 1) || (value > 65535)) {
867                        pr_err("Illegal value for \"%s\", must be"
868                                " between 1 and 65535.\n", param->name);
869                        return -1;
870                }
871                return 0;
872        }
873        if (IS_TYPERANGE_2_TO_3600(param)) {
874                if ((value < 2) || (value > 3600)) {
875                        pr_err("Illegal value for \"%s\", must be"
876                                " between 2 and 3600.\n", param->name);
877                        return -1;
878                }
879                return 0;
880        }
881        if (IS_TYPERANGE_512_TO_16777215(param)) {
882                if ((value < 512) || (value > 16777215)) {
883                        pr_err("Illegal value for \"%s\", must be"
884                                " between 512 and 16777215.\n", param->name);
885                        return -1;
886                }
887                return 0;
888        }
889
890        return 0;
891}
892
893static int iscsi_check_numerical_range_value(struct iscsi_param *param, char *value)
894{
895        char *left_val_ptr = NULL, *right_val_ptr = NULL;
896        char *tilde_ptr = NULL;
897        u32 left_val, right_val, local_left_val;
898
899        if (strcmp(param->name, IFMARKINT) &&
900            strcmp(param->name, OFMARKINT)) {
901                pr_err("Only parameters \"%s\" or \"%s\" may contain a"
902                       " numerical range value.\n", IFMARKINT, OFMARKINT);
903                return -1;
904        }
905
906        if (IS_PSTATE_PROPOSER(param))
907                return 0;
908
909        tilde_ptr = strchr(value, '~');
910        if (!tilde_ptr) {
911                pr_err("Unable to locate numerical range indicator"
912                        " \"~\" for \"%s\".\n", param->name);
913                return -1;
914        }
915        *tilde_ptr = '\0';
916
917        left_val_ptr = value;
918        right_val_ptr = value + strlen(left_val_ptr) + 1;
919
920        if (iscsi_check_numerical_value(param, left_val_ptr) < 0)
921                return -1;
922        if (iscsi_check_numerical_value(param, right_val_ptr) < 0)
923                return -1;
924
925        left_val = simple_strtoul(left_val_ptr, NULL, 0);
926        right_val = simple_strtoul(right_val_ptr, NULL, 0);
927        *tilde_ptr = '~';
928
929        if (right_val < left_val) {
930                pr_err("Numerical range for parameter \"%s\" contains"
931                        " a right value which is less than the left.\n",
932                                param->name);
933                return -1;
934        }
935
936        /*
937         * For now,  enforce reasonable defaults for [I,O]FMarkInt.
938         */
939        tilde_ptr = strchr(param->value, '~');
940        if (!tilde_ptr) {
941                pr_err("Unable to locate numerical range indicator"
942                        " \"~\" for \"%s\".\n", param->name);
943                return -1;
944        }
945        *tilde_ptr = '\0';
946
947        left_val_ptr = param->value;
948        right_val_ptr = param->value + strlen(left_val_ptr) + 1;
949
950        local_left_val = simple_strtoul(left_val_ptr, NULL, 0);
951        *tilde_ptr = '~';
952
953        if (param->set_param) {
954                if ((left_val < local_left_val) ||
955                    (right_val < local_left_val)) {
956                        pr_err("Passed value range \"%u~%u\" is below"
957                                " minimum left value \"%u\" for key \"%s\","
958                                " rejecting.\n", left_val, right_val,
959                                local_left_val, param->name);
960                        return -1;
961                }
962        } else {
963                if ((left_val < local_left_val) &&
964                    (right_val < local_left_val)) {
965                        pr_err("Received value range \"%u~%u\" is"
966                                " below minimum left value \"%u\" for key"
967                                " \"%s\", rejecting.\n", left_val, right_val,
968                                local_left_val, param->name);
969                        SET_PSTATE_REJECT(param);
970                        if (iscsi_update_param_value(param, REJECT) < 0)
971                                return -1;
972                }
973        }
974
975        return 0;
976}
977
978static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
979{
980        if (IS_PSTATE_PROPOSER(param))
981                return 0;
982
983        if (IS_TYPERANGE_AUTH_PARAM(param)) {
984                if (strcmp(value, KRB5) && strcmp(value, SPKM1) &&
985                    strcmp(value, SPKM2) && strcmp(value, SRP) &&
986                    strcmp(value, CHAP) && strcmp(value, NONE)) {
987                        pr_err("Illegal value for \"%s\", must be"
988                                " \"%s\", \"%s\", \"%s\", \"%s\", \"%s\""
989                                " or \"%s\".\n", param->name, KRB5,
990                                        SPKM1, SPKM2, SRP, CHAP, NONE);
991                        return -1;
992                }
993        }
994        if (IS_TYPERANGE_DIGEST_PARAM(param)) {
995                if (strcmp(value, CRC32C) && strcmp(value, NONE)) {
996                        pr_err("Illegal value for \"%s\", must be"
997                                " \"%s\" or \"%s\".\n", param->name,
998                                        CRC32C, NONE);
999                        return -1;
1000                }
1001        }
1002        if (IS_TYPERANGE_SESSIONTYPE(param)) {
1003                if (strcmp(value, DISCOVERY) && strcmp(value, NORMAL)) {
1004                        pr_err("Illegal value for \"%s\", must be"
1005                                " \"%s\" or \"%s\".\n", param->name,
1006                                        DISCOVERY, NORMAL);
1007                        return -1;
1008                }
1009        }
1010
1011        return 0;
1012}
1013
1014/*
1015 *      This function is used to pick a value range number,  currently just
1016 *      returns the lesser of both right values.
1017 */
1018static char *iscsi_get_value_from_number_range(
1019        struct iscsi_param *param,
1020        char *value)
1021{
1022        char *end_ptr, *tilde_ptr1 = NULL, *tilde_ptr2 = NULL;
1023        u32 acceptor_right_value, proposer_right_value;
1024
1025        tilde_ptr1 = strchr(value, '~');
1026        if (!tilde_ptr1)
1027                return NULL;
1028        *tilde_ptr1++ = '\0';
1029        proposer_right_value = simple_strtoul(tilde_ptr1, &end_ptr, 0);
1030
1031        tilde_ptr2 = strchr(param->value, '~');
1032        if (!tilde_ptr2)
1033                return NULL;
1034        *tilde_ptr2++ = '\0';
1035        acceptor_right_value = simple_strtoul(tilde_ptr2, &end_ptr, 0);
1036
1037        return (acceptor_right_value >= proposer_right_value) ?
1038                tilde_ptr1 : tilde_ptr2;
1039}
1040
1041static char *iscsi_check_valuelist_for_support(
1042        struct iscsi_param *param,
1043        char *value)
1044{
1045        char *tmp1 = NULL, *tmp2 = NULL;
1046        char *acceptor_values = NULL, *proposer_values = NULL;
1047
1048        acceptor_values = param->value;
1049        proposer_values = value;
1050
1051        do {
1052                if (!proposer_values)
1053                        return NULL;
1054                tmp1 = strchr(proposer_values, ',');
1055                if (tmp1)
1056                        *tmp1 = '\0';
1057                acceptor_values = param->value;
1058                do {
1059                        if (!acceptor_values) {
1060                                if (tmp1)
1061                                        *tmp1 = ',';
1062                                return NULL;
1063                        }
1064                        tmp2 = strchr(acceptor_values, ',');
1065                        if (tmp2)
1066                                *tmp2 = '\0';
1067                        if (!strcmp(acceptor_values, proposer_values)) {
1068                                if (tmp2)
1069                                        *tmp2 = ',';
1070                                goto out;
1071                        }
1072                        if (tmp2)
1073                                *tmp2++ = ',';
1074
1075                        acceptor_values = tmp2;
1076                } while (acceptor_values);
1077                if (tmp1)
1078                        *tmp1++ = ',';
1079                proposer_values = tmp1;
1080        } while (proposer_values);
1081
1082out:
1083        return proposer_values;
1084}
1085
1086static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
1087                                struct iscsi_conn *conn)
1088{
1089        u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
1090        char *negoitated_value = NULL;
1091
1092        if (IS_PSTATE_ACCEPTOR(param)) {
1093                pr_err("Received key \"%s\" twice, protocol error.\n",
1094                                param->name);
1095                return -1;
1096        }
1097
1098        if (IS_PSTATE_REJECT(param))
1099                return 0;
1100
1101        if (IS_TYPE_BOOL_AND(param)) {
1102                if (!strcmp(value, YES))
1103                        proposer_boolean_value = 1;
1104                if (!strcmp(param->value, YES))
1105                        acceptor_boolean_value = 1;
1106                if (acceptor_boolean_value && proposer_boolean_value)
1107                        do {} while (0);
1108                else {
1109                        if (iscsi_update_param_value(param, NO) < 0)
1110                                return -1;
1111                        if (!proposer_boolean_value)
1112                                SET_PSTATE_REPLY_OPTIONAL(param);
1113                }
1114        } else if (IS_TYPE_BOOL_OR(param)) {
1115                if (!strcmp(value, YES))
1116                        proposer_boolean_value = 1;
1117                if (!strcmp(param->value, YES))
1118                        acceptor_boolean_value = 1;
1119                if (acceptor_boolean_value || proposer_boolean_value) {
1120                        if (iscsi_update_param_value(param, YES) < 0)
1121                                return -1;
1122                        if (proposer_boolean_value)
1123                                SET_PSTATE_REPLY_OPTIONAL(param);
1124                }
1125        } else if (IS_TYPE_NUMBER(param)) {
1126                char *tmpptr, buf[11];
1127                u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
1128                u32 proposer_value = simple_strtoul(value, &tmpptr, 0);
1129
1130                memset(buf, 0, sizeof(buf));
1131
1132                if (!strcmp(param->name, MAXCONNECTIONS) ||
1133                    !strcmp(param->name, MAXBURSTLENGTH) ||
1134                    !strcmp(param->name, FIRSTBURSTLENGTH) ||
1135                    !strcmp(param->name, MAXOUTSTANDINGR2T) ||
1136                    !strcmp(param->name, DEFAULTTIME2RETAIN) ||
1137                    !strcmp(param->name, ERRORRECOVERYLEVEL)) {
1138                        if (proposer_value > acceptor_value) {
1139                                sprintf(buf, "%u", acceptor_value);
1140                                if (iscsi_update_param_value(param,
1141                                                &buf[0]) < 0)
1142                                        return -1;
1143                        } else {
1144                                if (iscsi_update_param_value(param, value) < 0)
1145                                        return -1;
1146                        }
1147                } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1148                        if (acceptor_value > proposer_value) {
1149                                sprintf(buf, "%u", acceptor_value);
1150                                if (iscsi_update_param_value(param,
1151                                                &buf[0]) < 0)
1152                                        return -1;
1153                        } else {
1154                                if (iscsi_update_param_value(param, value) < 0)
1155                                        return -1;
1156                        }
1157                } else {
1158                        if (iscsi_update_param_value(param, value) < 0)
1159                                return -1;
1160                }
1161
1162                if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1163                        struct iscsi_param *param_mxdsl;
1164                        unsigned long long tmp;
1165                        int rc;
1166
1167                        rc = kstrtoull(param->value, 0, &tmp);
1168                        if (rc < 0)
1169                                return -1;
1170
1171                        conn->conn_ops->MaxRecvDataSegmentLength = tmp;
1172                        pr_debug("Saving op->MaxRecvDataSegmentLength from"
1173                                " original initiator received value: %u\n",
1174                                conn->conn_ops->MaxRecvDataSegmentLength);
1175
1176                        param_mxdsl = iscsi_find_param_from_key(
1177                                                MAXXMITDATASEGMENTLENGTH,
1178                                                conn->param_list);
1179                        if (!param_mxdsl)
1180                                return -1;
1181
1182                        rc = iscsi_update_param_value(param,
1183                                                param_mxdsl->value);
1184                        if (rc < 0)
1185                                return -1;
1186
1187                        pr_debug("Updated %s to target MXDSL value: %s\n",
1188                                        param->name, param->value);
1189                }
1190
1191        } else if (IS_TYPE_NUMBER_RANGE(param)) {
1192                negoitated_value = iscsi_get_value_from_number_range(
1193                                        param, value);
1194                if (!negoitated_value)
1195                        return -1;
1196                if (iscsi_update_param_value(param, negoitated_value) < 0)
1197                        return -1;
1198        } else if (IS_TYPE_VALUE_LIST(param)) {
1199                negoitated_value = iscsi_check_valuelist_for_support(
1200                                        param, value);
1201                if (!negoitated_value) {
1202                        pr_err("Proposer's value list \"%s\" contains"
1203                                " no valid values from Acceptor's value list"
1204                                " \"%s\".\n", value, param->value);
1205                        return -1;
1206                }
1207                if (iscsi_update_param_value(param, negoitated_value) < 0)
1208                        return -1;
1209        } else if (IS_PHASE_DECLARATIVE(param)) {
1210                if (iscsi_update_param_value(param, value) < 0)
1211                        return -1;
1212                SET_PSTATE_REPLY_OPTIONAL(param);
1213        }
1214
1215        return 0;
1216}
1217
1218static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
1219{
1220        if (IS_PSTATE_RESPONSE_GOT(param)) {
1221                pr_err("Received key \"%s\" twice, protocol error.\n",
1222                                param->name);
1223                return -1;
1224        }
1225
1226        if (IS_TYPE_NUMBER_RANGE(param)) {
1227                u32 left_val = 0, right_val = 0, recieved_value = 0;
1228                char *left_val_ptr = NULL, *right_val_ptr = NULL;
1229                char *tilde_ptr = NULL;
1230
1231                if (!strcmp(value, IRRELEVANT) || !strcmp(value, REJECT)) {
1232                        if (iscsi_update_param_value(param, value) < 0)
1233                                return -1;
1234                        return 0;
1235                }
1236
1237                tilde_ptr = strchr(value, '~');
1238                if (tilde_ptr) {
1239                        pr_err("Illegal \"~\" in response for \"%s\".\n",
1240                                        param->name);
1241                        return -1;
1242                }
1243                tilde_ptr = strchr(param->value, '~');
1244                if (!tilde_ptr) {
1245                        pr_err("Unable to locate numerical range"
1246                                " indicator \"~\" for \"%s\".\n", param->name);
1247                        return -1;
1248                }
1249                *tilde_ptr = '\0';
1250
1251                left_val_ptr = param->value;
1252                right_val_ptr = param->value + strlen(left_val_ptr) + 1;
1253                left_val = simple_strtoul(left_val_ptr, NULL, 0);
1254                right_val = simple_strtoul(right_val_ptr, NULL, 0);
1255                recieved_value = simple_strtoul(value, NULL, 0);
1256
1257                *tilde_ptr = '~';
1258
1259                if ((recieved_value < left_val) ||
1260                    (recieved_value > right_val)) {
1261                        pr_err("Illegal response \"%s=%u\", value must"
1262                                " be between %u and %u.\n", param->name,
1263                                recieved_value, left_val, right_val);
1264                        return -1;
1265                }
1266        } else if (IS_TYPE_VALUE_LIST(param)) {
1267                char *comma_ptr = NULL, *tmp_ptr = NULL;
1268
1269                comma_ptr = strchr(value, ',');
1270                if (comma_ptr) {
1271                        pr_err("Illegal \",\" in response for \"%s\".\n",
1272                                        param->name);
1273                        return -1;
1274                }
1275
1276                tmp_ptr = iscsi_check_valuelist_for_support(param, value);
1277                if (!tmp_ptr)
1278                        return -1;
1279        }
1280
1281        if (iscsi_update_param_value(param, value) < 0)
1282                return -1;
1283
1284        return 0;
1285}
1286
1287static int iscsi_check_value(struct iscsi_param *param, char *value)
1288{
1289        char *comma_ptr = NULL;
1290
1291        if (!strcmp(value, REJECT)) {
1292                if (!strcmp(param->name, IFMARKINT) ||
1293                    !strcmp(param->name, OFMARKINT)) {
1294                        /*
1295                         * Reject is not fatal for [I,O]FMarkInt,  and causes
1296                         * [I,O]FMarker to be reset to No. (See iSCSI v20 A.3.2)
1297                         */
1298                        SET_PSTATE_REJECT(param);
1299                        return 0;
1300                }
1301                pr_err("Received %s=%s\n", param->name, value);
1302                return -1;
1303        }
1304        if (!strcmp(value, IRRELEVANT)) {
1305                pr_debug("Received %s=%s\n", param->name, value);
1306                SET_PSTATE_IRRELEVANT(param);
1307                return 0;
1308        }
1309        if (!strcmp(value, NOTUNDERSTOOD)) {
1310                if (!IS_PSTATE_PROPOSER(param)) {
1311                        pr_err("Received illegal offer %s=%s\n",
1312                                param->name, value);
1313                        return -1;
1314                }
1315
1316/* #warning FIXME: Add check for X-ExtensionKey here */
1317                pr_err("Standard iSCSI key \"%s\" cannot be answered"
1318                        " with \"%s\", protocol error.\n", param->name, value);
1319                return -1;
1320        }
1321
1322        do {
1323                comma_ptr = NULL;
1324                comma_ptr = strchr(value, ',');
1325
1326                if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
1327                        pr_err("Detected value separator \",\", but"
1328                                " key \"%s\" does not allow a value list,"
1329                                " protocol error.\n", param->name);
1330                        return -1;
1331                }
1332                if (comma_ptr)
1333                        *comma_ptr = '\0';
1334
1335                if (strlen(value) > VALUE_MAXLEN) {
1336                        pr_err("Value for key \"%s\" exceeds %d,"
1337                                " protocol error.\n", param->name,
1338                                VALUE_MAXLEN);
1339                        return -1;
1340                }
1341
1342                if (IS_TYPE_BOOL_AND(param) || IS_TYPE_BOOL_OR(param)) {
1343                        if (iscsi_check_boolean_value(param, value) < 0)
1344                                return -1;
1345                } else if (IS_TYPE_NUMBER(param)) {
1346                        if (iscsi_check_numerical_value(param, value) < 0)
1347                                return -1;
1348                } else if (IS_TYPE_NUMBER_RANGE(param)) {
1349                        if (iscsi_check_numerical_range_value(param, value) < 0)
1350                                return -1;
1351                } else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
1352                        if (iscsi_check_string_or_list_value(param, value) < 0)
1353                                return -1;
1354                } else {
1355                        pr_err("Huh? 0x%02x\n", param->type);
1356                        return -1;
1357                }
1358
1359                if (comma_ptr)
1360                        *comma_ptr++ = ',';
1361
1362                value = comma_ptr;
1363        } while (value);
1364
1365        return 0;
1366}
1367
1368static struct iscsi_param *__iscsi_check_key(
1369        char *key,
1370        int sender,
1371        struct iscsi_param_list *param_list)
1372{
1373        struct iscsi_param *param;
1374
1375        if (strlen(key) > KEY_MAXLEN) {
1376                pr_err("Length of key name \"%s\" exceeds %d.\n",
1377                        key, KEY_MAXLEN);
1378                return NULL;
1379        }
1380
1381        param = iscsi_find_param_from_key(key, param_list);
1382        if (!param)
1383                return NULL;
1384
1385        if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1386                pr_err("Key \"%s\" may not be sent to %s,"
1387                        " protocol error.\n", param->name,
1388                        (sender & SENDER_RECEIVER) ? "target" : "initiator");
1389                return NULL;
1390        }
1391
1392        if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1393                pr_err("Key \"%s\" may not be sent to %s,"
1394                        " protocol error.\n", param->name,
1395                        (sender & SENDER_RECEIVER) ? "initiator" : "target");
1396                return NULL;
1397        }
1398
1399        return param;
1400}
1401
1402static struct iscsi_param *iscsi_check_key(
1403        char *key,
1404        int phase,
1405        int sender,
1406        struct iscsi_param_list *param_list)
1407{
1408        struct iscsi_param *param;
1409        /*
1410         * Key name length must not exceed 63 bytes. (See iSCSI v20 5.1)
1411         */
1412        if (strlen(key) > KEY_MAXLEN) {
1413                pr_err("Length of key name \"%s\" exceeds %d.\n",
1414                        key, KEY_MAXLEN);
1415                return NULL;
1416        }
1417
1418        param = iscsi_find_param_from_key(key, param_list);
1419        if (!param)
1420                return NULL;
1421
1422        if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1423                pr_err("Key \"%s\" may not be sent to %s,"
1424                        " protocol error.\n", param->name,
1425                        (sender & SENDER_RECEIVER) ? "target" : "initiator");
1426                return NULL;
1427        }
1428        if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1429                pr_err("Key \"%s\" may not be sent to %s,"
1430                                " protocol error.\n", param->name,
1431                        (sender & SENDER_RECEIVER) ? "initiator" : "target");
1432                return NULL;
1433        }
1434
1435        if (IS_PSTATE_ACCEPTOR(param)) {
1436                pr_err("Key \"%s\" received twice, protocol error.\n",
1437                                key);
1438                return NULL;
1439        }
1440
1441        if (!phase)
1442                return param;
1443
1444        if (!(param->phase & phase)) {
1445                pr_err("Key \"%s\" may not be negotiated during ",
1446                                param->name);
1447                switch (phase) {
1448                case PHASE_SECURITY:
1449                        pr_debug("Security phase.\n");
1450                        break;
1451                case PHASE_OPERATIONAL:
1452                        pr_debug("Operational phase.\n");
1453                        break;
1454                default:
1455                        pr_debug("Unknown phase.\n");
1456                }
1457                return NULL;
1458        }
1459
1460        return param;
1461}
1462
1463static int iscsi_enforce_integrity_rules(
1464        u8 phase,
1465        struct iscsi_param_list *param_list)
1466{
1467        char *tmpptr;
1468        u8 DataSequenceInOrder = 0;
1469        u8 ErrorRecoveryLevel = 0, SessionType = 0;
1470        u8 IFMarker = 0, OFMarker = 0;
1471        u8 IFMarkInt_Reject = 1, OFMarkInt_Reject = 1;
1472        u32 FirstBurstLength = 0, MaxBurstLength = 0;
1473        struct iscsi_param *param = NULL;
1474
1475        list_for_each_entry(param, &param_list->param_list, p_list) {
1476                if (!(param->phase & phase))
1477                        continue;
1478                if (!strcmp(param->name, SESSIONTYPE))
1479                        if (!strcmp(param->value, NORMAL))
1480                                SessionType = 1;
1481                if (!strcmp(param->name, ERRORRECOVERYLEVEL))
1482                        ErrorRecoveryLevel = simple_strtoul(param->value,
1483                                        &tmpptr, 0);
1484                if (!strcmp(param->name, DATASEQUENCEINORDER))
1485                        if (!strcmp(param->value, YES))
1486                                DataSequenceInOrder = 1;
1487                if (!strcmp(param->name, MAXBURSTLENGTH))
1488                        MaxBurstLength = simple_strtoul(param->value,
1489                                        &tmpptr, 0);
1490                if (!strcmp(param->name, IFMARKER))
1491                        if (!strcmp(param->value, YES))
1492                                IFMarker = 1;
1493                if (!strcmp(param->name, OFMARKER))
1494                        if (!strcmp(param->value, YES))
1495                                OFMarker = 1;
1496                if (!strcmp(param->name, IFMARKINT))
1497                        if (!strcmp(param->value, REJECT))
1498                                IFMarkInt_Reject = 1;
1499                if (!strcmp(param->name, OFMARKINT))
1500                        if (!strcmp(param->value, REJECT))
1501                                OFMarkInt_Reject = 1;
1502        }
1503
1504        list_for_each_entry(param, &param_list->param_list, p_list) {
1505                if (!(param->phase & phase))
1506                        continue;
1507                if (!SessionType && (!IS_PSTATE_ACCEPTOR(param) &&
1508                     (strcmp(param->name, IFMARKER) &&
1509                      strcmp(param->name, OFMARKER) &&
1510                      strcmp(param->name, IFMARKINT) &&
1511                      strcmp(param->name, OFMARKINT))))
1512                        continue;
1513                if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
1514                    DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
1515                        if (strcmp(param->value, "1")) {
1516                                if (iscsi_update_param_value(param, "1") < 0)
1517                                        return -1;
1518                                pr_debug("Reset \"%s\" to \"%s\".\n",
1519                                        param->name, param->value);
1520                        }
1521                }
1522                if (!strcmp(param->name, MAXCONNECTIONS) && !SessionType) {
1523                        if (strcmp(param->value, "1")) {
1524                                if (iscsi_update_param_value(param, "1") < 0)
1525                                        return -1;
1526                                pr_debug("Reset \"%s\" to \"%s\".\n",
1527                                        param->name, param->value);
1528                        }
1529                }
1530                if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1531                        FirstBurstLength = simple_strtoul(param->value,
1532                                        &tmpptr, 0);
1533                        if (FirstBurstLength > MaxBurstLength) {
1534                                char tmpbuf[11];
1535                                memset(tmpbuf, 0, sizeof(tmpbuf));
1536                                sprintf(tmpbuf, "%u", MaxBurstLength);
1537                                if (iscsi_update_param_value(param, tmpbuf))
1538                                        return -1;
1539                                pr_debug("Reset \"%s\" to \"%s\".\n",
1540                                        param->name, param->value);
1541                        }
1542                }
1543                if (!strcmp(param->name, IFMARKER) && IFMarkInt_Reject) {
1544                        if (iscsi_update_param_value(param, NO) < 0)
1545                                return -1;
1546                        IFMarker = 0;
1547                        pr_debug("Reset \"%s\" to \"%s\".\n",
1548                                        param->name, param->value);
1549                }
1550                if (!strcmp(param->name, OFMARKER) && OFMarkInt_Reject) {
1551                        if (iscsi_update_param_value(param, NO) < 0)
1552                                return -1;
1553                        OFMarker = 0;
1554                        pr_debug("Reset \"%s\" to \"%s\".\n",
1555                                         param->name, param->value);
1556                }
1557                if (!strcmp(param->name, IFMARKINT) && !IFMarker) {
1558                        if (!strcmp(param->value, REJECT))
1559                                continue;
1560                        param->state &= ~PSTATE_NEGOTIATE;
1561                        if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1562                                return -1;
1563                        pr_debug("Reset \"%s\" to \"%s\".\n",
1564                                        param->name, param->value);
1565                }
1566                if (!strcmp(param->name, OFMARKINT) && !OFMarker) {
1567                        if (!strcmp(param->value, REJECT))
1568                                continue;
1569                        param->state &= ~PSTATE_NEGOTIATE;
1570                        if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1571                                return -1;
1572                        pr_debug("Reset \"%s\" to \"%s\".\n",
1573                                        param->name, param->value);
1574                }
1575        }
1576
1577        return 0;
1578}
1579
1580int iscsi_decode_text_input(
1581        u8 phase,
1582        u8 sender,
1583        char *textbuf,
1584        u32 length,
1585        struct iscsi_conn *conn)
1586{
1587        struct iscsi_param_list *param_list = conn->param_list;
1588        char *tmpbuf, *start = NULL, *end = NULL;
1589
1590        tmpbuf = kzalloc(length + 1, GFP_KERNEL);
1591        if (!tmpbuf) {
1592                pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length);
1593                return -1;
1594        }
1595
1596        memcpy(tmpbuf, textbuf, length);
1597        tmpbuf[length] = '\0';
1598        start = tmpbuf;
1599        end = (start + length);
1600
1601        while (start < end) {
1602                char *key, *value;
1603                struct iscsi_param *param;
1604
1605                if (iscsi_extract_key_value(start, &key, &value) < 0) {
1606                        kfree(tmpbuf);
1607                        return -1;
1608                }
1609
1610                pr_debug("Got key: %s=%s\n", key, value);
1611
1612                if (phase & PHASE_SECURITY) {
1613                        if (iscsi_check_for_auth_key(key) > 0) {
1614                                kfree(tmpbuf);
1615                                return 1;
1616                        }
1617                }
1618
1619                param = iscsi_check_key(key, phase, sender, param_list);
1620                if (!param) {
1621                        if (iscsi_add_notunderstood_response(key,
1622                                        value, param_list) < 0) {
1623                                kfree(tmpbuf);
1624                                return -1;
1625                        }
1626                        start += strlen(key) + strlen(value) + 2;
1627                        continue;
1628                }
1629                if (iscsi_check_value(param, value) < 0) {
1630                        kfree(tmpbuf);
1631                        return -1;
1632                }
1633
1634                start += strlen(key) + strlen(value) + 2;
1635
1636                if (IS_PSTATE_PROPOSER(param)) {
1637                        if (iscsi_check_proposer_state(param, value) < 0) {
1638                                kfree(tmpbuf);
1639                                return -1;
1640                        }
1641                        SET_PSTATE_RESPONSE_GOT(param);
1642                } else {
1643                        if (iscsi_check_acceptor_state(param, value, conn) < 0) {
1644                                kfree(tmpbuf);
1645                                return -1;
1646                        }
1647                        SET_PSTATE_ACCEPTOR(param);
1648                }
1649        }
1650
1651        kfree(tmpbuf);
1652        return 0;
1653}
1654
1655int iscsi_encode_text_output(
1656        u8 phase,
1657        u8 sender,
1658        char *textbuf,
1659        u32 *length,
1660        struct iscsi_param_list *param_list)
1661{
1662        char *output_buf = NULL;
1663        struct iscsi_extra_response *er;
1664        struct iscsi_param *param;
1665
1666        output_buf = textbuf + *length;
1667
1668        if (iscsi_enforce_integrity_rules(phase, param_list) < 0)
1669                return -1;
1670
1671        list_for_each_entry(param, &param_list->param_list, p_list) {
1672                if (!(param->sender & sender))
1673                        continue;
1674                if (IS_PSTATE_ACCEPTOR(param) &&
1675                    !IS_PSTATE_RESPONSE_SENT(param) &&
1676                    !IS_PSTATE_REPLY_OPTIONAL(param) &&
1677                    (param->phase & phase)) {
1678                        *length += sprintf(output_buf, "%s=%s",
1679                                param->name, param->value);
1680                        *length += 1;
1681                        output_buf = textbuf + *length;
1682                        SET_PSTATE_RESPONSE_SENT(param);
1683                        pr_debug("Sending key: %s=%s\n",
1684                                param->name, param->value);
1685                        continue;
1686                }
1687                if (IS_PSTATE_NEGOTIATE(param) &&
1688                    !IS_PSTATE_ACCEPTOR(param) &&
1689                    !IS_PSTATE_PROPOSER(param) &&
1690                    (param->phase & phase)) {
1691                        *length += sprintf(output_buf, "%s=%s",
1692                                param->name, param->value);
1693                        *length += 1;
1694                        output_buf = textbuf + *length;
1695                        SET_PSTATE_PROPOSER(param);
1696                        iscsi_check_proposer_for_optional_reply(param);
1697                        pr_debug("Sending key: %s=%s\n",
1698                                param->name, param->value);
1699                }
1700        }
1701
1702        list_for_each_entry(er, &param_list->extra_response_list, er_list) {
1703                *length += sprintf(output_buf, "%s=%s", er->key, er->value);
1704                *length += 1;
1705                output_buf = textbuf + *length;
1706                pr_debug("Sending key: %s=%s\n", er->key, er->value);
1707        }
1708        iscsi_release_extra_responses(param_list);
1709
1710        return 0;
1711}
1712
1713int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list)
1714{
1715        int ret = 0;
1716        struct iscsi_param *param;
1717
1718        list_for_each_entry(param, &param_list->param_list, p_list) {
1719                if (IS_PSTATE_NEGOTIATE(param) &&
1720                    IS_PSTATE_PROPOSER(param) &&
1721                    !IS_PSTATE_RESPONSE_GOT(param) &&
1722                    !IS_PSTATE_REPLY_OPTIONAL(param) &&
1723                    !IS_PHASE_DECLARATIVE(param)) {
1724                        pr_err("No response for proposed key \"%s\".\n",
1725                                        param->name);
1726                        ret = -1;
1727                }
1728        }
1729
1730        return ret;
1731}
1732
1733int iscsi_change_param_value(
1734        char *keyvalue,
1735        struct iscsi_param_list *param_list,
1736        int check_key)
1737{
1738        char *key = NULL, *value = NULL;
1739        struct iscsi_param *param;
1740        int sender = 0;
1741
1742        if (iscsi_extract_key_value(keyvalue, &key, &value) < 0)
1743                return -1;
1744
1745        if (!check_key) {
1746                param = __iscsi_check_key(keyvalue, sender, param_list);
1747                if (!param)
1748                        return -1;
1749        } else {
1750                param = iscsi_check_key(keyvalue, 0, sender, param_list);
1751                if (!param)
1752                        return -1;
1753
1754                param->set_param = 1;
1755                if (iscsi_check_value(param, value) < 0) {
1756                        param->set_param = 0;
1757                        return -1;
1758                }
1759                param->set_param = 0;
1760        }
1761
1762        if (iscsi_update_param_value(param, value) < 0)
1763                return -1;
1764
1765        return 0;
1766}
1767
1768void iscsi_set_connection_parameters(
1769        struct iscsi_conn_ops *ops,
1770        struct iscsi_param_list *param_list)
1771{
1772        char *tmpptr;
1773        struct iscsi_param *param;
1774
1775        pr_debug("---------------------------------------------------"
1776                        "---------------\n");
1777        list_for_each_entry(param, &param_list->param_list, p_list) {
1778                /*
1779                 * Special case to set MAXXMITDATASEGMENTLENGTH from the
1780                 * target requested MaxRecvDataSegmentLength, even though
1781                 * this key is not sent over the wire.
1782                 */
1783                if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
1784                        ops->MaxXmitDataSegmentLength =
1785                                simple_strtoul(param->value, &tmpptr, 0);
1786                        pr_debug("MaxXmitDataSegmentLength:     %s\n",
1787                                param->value);
1788                }
1789
1790                if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1791                        continue;
1792                if (!strcmp(param->name, AUTHMETHOD)) {
1793                        pr_debug("AuthMethod:                   %s\n",
1794                                param->value);
1795                } else if (!strcmp(param->name, HEADERDIGEST)) {
1796                        ops->HeaderDigest = !strcmp(param->value, CRC32C);
1797                        pr_debug("HeaderDigest:                 %s\n",
1798                                param->value);
1799                } else if (!strcmp(param->name, DATADIGEST)) {
1800                        ops->DataDigest = !strcmp(param->value, CRC32C);
1801                        pr_debug("DataDigest:                   %s\n",
1802                                param->value);
1803                } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1804                        /*
1805                         * At this point iscsi_check_acceptor_state() will have
1806                         * set ops->MaxRecvDataSegmentLength from the original
1807                         * initiator provided value.
1808                         */
1809                        pr_debug("MaxRecvDataSegmentLength:     %u\n",
1810                                ops->MaxRecvDataSegmentLength);
1811                } else if (!strcmp(param->name, OFMARKER)) {
1812                        ops->OFMarker = !strcmp(param->value, YES);
1813                        pr_debug("OFMarker:                     %s\n",
1814                                param->value);
1815                } else if (!strcmp(param->name, IFMARKER)) {
1816                        ops->IFMarker = !strcmp(param->value, YES);
1817                        pr_debug("IFMarker:                     %s\n",
1818                                param->value);
1819                } else if (!strcmp(param->name, OFMARKINT)) {
1820                        ops->OFMarkInt =
1821                                simple_strtoul(param->value, &tmpptr, 0);
1822                        pr_debug("OFMarkInt:                    %s\n",
1823                                param->value);
1824                } else if (!strcmp(param->name, IFMARKINT)) {
1825                        ops->IFMarkInt =
1826                                simple_strtoul(param->value, &tmpptr, 0);
1827                        pr_debug("IFMarkInt:                    %s\n",
1828                                param->value);
1829                } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
1830                        ops->InitiatorRecvDataSegmentLength =
1831                                simple_strtoul(param->value, &tmpptr, 0);
1832                        pr_debug("InitiatorRecvDataSegmentLength: %s\n",
1833                                param->value);
1834                        ops->MaxRecvDataSegmentLength =
1835                                        ops->InitiatorRecvDataSegmentLength;
1836                        pr_debug("Set MRDSL from InitiatorRecvDataSegmentLength\n");
1837                } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
1838                        ops->TargetRecvDataSegmentLength =
1839                                simple_strtoul(param->value, &tmpptr, 0);
1840                        pr_debug("TargetRecvDataSegmentLength:  %s\n",
1841                                param->value);
1842                        ops->MaxXmitDataSegmentLength =
1843                                        ops->TargetRecvDataSegmentLength;
1844                        pr_debug("Set MXDSL from TargetRecvDataSegmentLength\n");
1845                }
1846        }
1847        pr_debug("----------------------------------------------------"
1848                        "--------------\n");
1849}
1850
1851void iscsi_set_session_parameters(
1852        struct iscsi_sess_ops *ops,
1853        struct iscsi_param_list *param_list,
1854        int leading)
1855{
1856        char *tmpptr;
1857        struct iscsi_param *param;
1858
1859        pr_debug("----------------------------------------------------"
1860                        "--------------\n");
1861        list_for_each_entry(param, &param_list->param_list, p_list) {
1862                if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1863                        continue;
1864                if (!strcmp(param->name, INITIATORNAME)) {
1865                        if (!param->value)
1866                                continue;
1867                        if (leading)
1868                                snprintf(ops->InitiatorName,
1869                                                sizeof(ops->InitiatorName),
1870                                                "%s", param->value);
1871                        pr_debug("InitiatorName:                %s\n",
1872                                param->value);
1873                } else if (!strcmp(param->name, INITIATORALIAS)) {
1874                        if (!param->value)
1875                                continue;
1876                        snprintf(ops->InitiatorAlias,
1877                                                sizeof(ops->InitiatorAlias),
1878                                                "%s", param->value);
1879                        pr_debug("InitiatorAlias:               %s\n",
1880                                param->value);
1881                } else if (!strcmp(param->name, TARGETNAME)) {
1882                        if (!param->value)
1883                                continue;
1884                        if (leading)
1885                                snprintf(ops->TargetName,
1886                                                sizeof(ops->TargetName),
1887                                                "%s", param->value);
1888                        pr_debug("TargetName:                   %s\n",
1889                                param->value);
1890                } else if (!strcmp(param->name, TARGETALIAS)) {
1891                        if (!param->value)
1892                                continue;
1893                        snprintf(ops->TargetAlias, sizeof(ops->TargetAlias),
1894                                        "%s", param->value);
1895                        pr_debug("TargetAlias:                  %s\n",
1896                                param->value);
1897                } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
1898                        ops->TargetPortalGroupTag =
1899                                simple_strtoul(param->value, &tmpptr, 0);
1900                        pr_debug("TargetPortalGroupTag:         %s\n",
1901                                param->value);
1902                } else if (!strcmp(param->name, MAXCONNECTIONS)) {
1903                        ops->MaxConnections =
1904                                simple_strtoul(param->value, &tmpptr, 0);
1905                        pr_debug("MaxConnections:               %s\n",
1906                                param->value);
1907                } else if (!strcmp(param->name, INITIALR2T)) {
1908                        ops->InitialR2T = !strcmp(param->value, YES);
1909                         pr_debug("InitialR2T:                   %s\n",
1910                                param->value);
1911                } else if (!strcmp(param->name, IMMEDIATEDATA)) {
1912                        ops->ImmediateData = !strcmp(param->value, YES);
1913                        pr_debug("ImmediateData:                %s\n",
1914                                param->value);
1915                } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
1916                        ops->MaxBurstLength =
1917                                simple_strtoul(param->value, &tmpptr, 0);
1918                        pr_debug("MaxBurstLength:               %s\n",
1919                                param->value);
1920                } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1921                        ops->FirstBurstLength =
1922                                simple_strtoul(param->value, &tmpptr, 0);
1923                        pr_debug("FirstBurstLength:             %s\n",
1924                                param->value);
1925                } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1926                        ops->DefaultTime2Wait =
1927                                simple_strtoul(param->value, &tmpptr, 0);
1928                        pr_debug("DefaultTime2Wait:             %s\n",
1929                                param->value);
1930                } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
1931                        ops->DefaultTime2Retain =
1932                                simple_strtoul(param->value, &tmpptr, 0);
1933                        pr_debug("DefaultTime2Retain:           %s\n",
1934                                param->value);
1935                } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
1936                        ops->MaxOutstandingR2T =
1937                                simple_strtoul(param->value, &tmpptr, 0);
1938                        pr_debug("MaxOutstandingR2T:            %s\n",
1939                                param->value);
1940                } else if (!strcmp(param->name, DATAPDUINORDER)) {
1941                        ops->DataPDUInOrder = !strcmp(param->value, YES);
1942                        pr_debug("DataPDUInOrder:               %s\n",
1943                                param->value);
1944                } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
1945                        ops->DataSequenceInOrder = !strcmp(param->value, YES);
1946                        pr_debug("DataSequenceInOrder:          %s\n",
1947                                param->value);
1948                } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
1949                        ops->ErrorRecoveryLevel =
1950                                simple_strtoul(param->value, &tmpptr, 0);
1951                        pr_debug("ErrorRecoveryLevel:           %s\n",
1952                                param->value);
1953                } else if (!strcmp(param->name, SESSIONTYPE)) {
1954                        ops->SessionType = !strcmp(param->value, DISCOVERY);
1955                        pr_debug("SessionType:                  %s\n",
1956                                param->value);
1957                } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
1958                        ops->RDMAExtensions = !strcmp(param->value, YES);
1959                        pr_debug("RDMAExtensions:               %s\n",
1960                                param->value);
1961                }
1962        }
1963        pr_debug("----------------------------------------------------"
1964                        "--------------\n");
1965
1966}
Note: See TracBrowser for help on using the repository browser.