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