Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
[pandora-kernel.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, MAXRECVDATASEGMENTLENGTH,
338                         INITIAL_MAXRECVDATASEGMENTLENGTH,
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, MAXBURSTLENGTH,
345                         INITIAL_MAXBURSTLENGTH, PHASE_OPERATIONAL,
346                         SCOPE_SESSION_WIDE, SENDER_BOTH,
347                         TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
348         if (!param)
349                 goto out;
350
351         param = iscsi_set_default_param(pl, FIRSTBURSTLENGTH,
352                         INITIAL_FIRSTBURSTLENGTH,
353                         PHASE_OPERATIONAL, 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, DEFAULTTIME2WAIT,
359                         INITIAL_DEFAULTTIME2WAIT,
360                         PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
361                         TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
362         if (!param)
363                 goto out;
364
365         param = iscsi_set_default_param(pl, DEFAULTTIME2RETAIN,
366                         INITIAL_DEFAULTTIME2RETAIN,
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, MAXOUTSTANDINGR2T,
373                         INITIAL_MAXOUTSTANDINGR2T,
374                         PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
375                         TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
376         if (!param)
377                 goto out;
378
379         param = iscsi_set_default_param(pl, DATAPDUINORDER,
380                         INITIAL_DATAPDUINORDER, PHASE_OPERATIONAL,
381                         SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_OR,
382                         USE_LEADING_ONLY);
383         if (!param)
384                 goto out;
385
386         param = iscsi_set_default_param(pl, DATASEQUENCEINORDER,
387                         INITIAL_DATASEQUENCEINORDER,
388                         PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
389                         TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
390         if (!param)
391                 goto out;
392
393         param = iscsi_set_default_param(pl, ERRORRECOVERYLEVEL,
394                         INITIAL_ERRORRECOVERYLEVEL,
395                         PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
396                         TYPERANGE_0_TO_2, USE_LEADING_ONLY);
397         if (!param)
398                 goto out;
399
400         param = iscsi_set_default_param(pl, SESSIONTYPE, INITIAL_SESSIONTYPE,
401                         PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
402                         TYPERANGE_SESSIONTYPE, USE_LEADING_ONLY);
403         if (!param)
404                 goto out;
405
406         param = iscsi_set_default_param(pl, IFMARKER, INITIAL_IFMARKER,
407                         PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
408                         TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
409         if (!param)
410                 goto out;
411
412         param = iscsi_set_default_param(pl, OFMARKER, INITIAL_OFMARKER,
413                         PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
414                         TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
415         if (!param)
416                 goto out;
417
418         param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT,
419                         PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
420                         TYPERANGE_MARKINT, USE_INITIAL_ONLY);
421         if (!param)
422                 goto out;
423
424         param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT,
425                         PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
426                         TYPERANGE_MARKINT, USE_INITIAL_ONLY);
427         if (!param)
428                 goto out;
429
430         *param_list_ptr = pl;
431         return 0;
432 out:
433         iscsi_release_param_list(pl);
434         return -1;
435 }
436
437 int iscsi_set_keys_to_negotiate(
438         int sessiontype,
439         struct iscsi_param_list *param_list)
440 {
441         struct iscsi_param *param;
442
443         list_for_each_entry(param, &param_list->param_list, p_list) {
444                 param->state = 0;
445                 if (!strcmp(param->name, AUTHMETHOD)) {
446                         SET_PSTATE_NEGOTIATE(param);
447                 } else if (!strcmp(param->name, HEADERDIGEST)) {
448                         SET_PSTATE_NEGOTIATE(param);
449                 } else if (!strcmp(param->name, DATADIGEST)) {
450                         SET_PSTATE_NEGOTIATE(param);
451                 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
452                         SET_PSTATE_NEGOTIATE(param);
453                 } else if (!strcmp(param->name, TARGETNAME)) {
454                         continue;
455                 } else if (!strcmp(param->name, INITIATORNAME)) {
456                         continue;
457                 } else if (!strcmp(param->name, TARGETALIAS)) {
458                         if (param->value)
459                                 SET_PSTATE_NEGOTIATE(param);
460                 } else if (!strcmp(param->name, INITIATORALIAS)) {
461                         continue;
462                 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
463                         SET_PSTATE_NEGOTIATE(param);
464                 } else if (!strcmp(param->name, INITIALR2T)) {
465                         SET_PSTATE_NEGOTIATE(param);
466                 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
467                         SET_PSTATE_NEGOTIATE(param);
468                 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
469                         SET_PSTATE_NEGOTIATE(param);
470                 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
471                         SET_PSTATE_NEGOTIATE(param);
472                 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
473                         SET_PSTATE_NEGOTIATE(param);
474                 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
475                         SET_PSTATE_NEGOTIATE(param);
476                 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
477                         SET_PSTATE_NEGOTIATE(param);
478                 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
479                         SET_PSTATE_NEGOTIATE(param);
480                 } else if (!strcmp(param->name, DATAPDUINORDER)) {
481                         SET_PSTATE_NEGOTIATE(param);
482                 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
483                         SET_PSTATE_NEGOTIATE(param);
484                 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
485                         SET_PSTATE_NEGOTIATE(param);
486                 } else if (!strcmp(param->name, SESSIONTYPE)) {
487                         SET_PSTATE_NEGOTIATE(param);
488                 } else if (!strcmp(param->name, IFMARKER)) {
489                         SET_PSTATE_NEGOTIATE(param);
490                 } else if (!strcmp(param->name, OFMARKER)) {
491                         SET_PSTATE_NEGOTIATE(param);
492                 } else if (!strcmp(param->name, IFMARKINT)) {
493                         SET_PSTATE_NEGOTIATE(param);
494                 } else if (!strcmp(param->name, OFMARKINT)) {
495                         SET_PSTATE_NEGOTIATE(param);
496                 }
497         }
498
499         return 0;
500 }
501
502 int iscsi_set_keys_irrelevant_for_discovery(
503         struct iscsi_param_list *param_list)
504 {
505         struct iscsi_param *param;
506
507         list_for_each_entry(param, &param_list->param_list, p_list) {
508                 if (!strcmp(param->name, MAXCONNECTIONS))
509                         param->state &= ~PSTATE_NEGOTIATE;
510                 else if (!strcmp(param->name, INITIALR2T))
511                         param->state &= ~PSTATE_NEGOTIATE;
512                 else if (!strcmp(param->name, IMMEDIATEDATA))
513                         param->state &= ~PSTATE_NEGOTIATE;
514                 else if (!strcmp(param->name, MAXBURSTLENGTH))
515                         param->state &= ~PSTATE_NEGOTIATE;
516                 else if (!strcmp(param->name, FIRSTBURSTLENGTH))
517                         param->state &= ~PSTATE_NEGOTIATE;
518                 else if (!strcmp(param->name, MAXOUTSTANDINGR2T))
519                         param->state &= ~PSTATE_NEGOTIATE;
520                 else if (!strcmp(param->name, DATAPDUINORDER))
521                         param->state &= ~PSTATE_NEGOTIATE;
522                 else if (!strcmp(param->name, DATASEQUENCEINORDER))
523                         param->state &= ~PSTATE_NEGOTIATE;
524                 else if (!strcmp(param->name, ERRORRECOVERYLEVEL))
525                         param->state &= ~PSTATE_NEGOTIATE;
526                 else if (!strcmp(param->name, DEFAULTTIME2WAIT))
527                         param->state &= ~PSTATE_NEGOTIATE;
528                 else if (!strcmp(param->name, DEFAULTTIME2RETAIN))
529                         param->state &= ~PSTATE_NEGOTIATE;
530                 else if (!strcmp(param->name, IFMARKER))
531                         param->state &= ~PSTATE_NEGOTIATE;
532                 else if (!strcmp(param->name, OFMARKER))
533                         param->state &= ~PSTATE_NEGOTIATE;
534                 else if (!strcmp(param->name, IFMARKINT))
535                         param->state &= ~PSTATE_NEGOTIATE;
536                 else if (!strcmp(param->name, OFMARKINT))
537                         param->state &= ~PSTATE_NEGOTIATE;
538         }
539
540         return 0;
541 }
542
543 int iscsi_copy_param_list(
544         struct iscsi_param_list **dst_param_list,
545         struct iscsi_param_list *src_param_list,
546         int leading)
547 {
548         struct iscsi_param *new_param = NULL, *param = NULL;
549         struct iscsi_param_list *param_list = NULL;
550
551         param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
552         if (!param_list) {
553                 pr_err("Unable to allocate memory for"
554                                 " struct iscsi_param_list.\n");
555                 goto err_out;
556         }
557         INIT_LIST_HEAD(&param_list->param_list);
558         INIT_LIST_HEAD(&param_list->extra_response_list);
559
560         list_for_each_entry(param, &src_param_list->param_list, p_list) {
561                 if (!leading && (param->scope & SCOPE_SESSION_WIDE)) {
562                         if ((strcmp(param->name, "TargetName") != 0) &&
563                             (strcmp(param->name, "InitiatorName") != 0) &&
564                             (strcmp(param->name, "TargetPortalGroupTag") != 0))
565                                 continue;
566                 }
567
568                 new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
569                 if (!new_param) {
570                         pr_err("Unable to allocate memory for"
571                                 " struct iscsi_param.\n");
572                         goto err_out;
573                 }
574
575                 new_param->set_param = param->set_param;
576                 new_param->phase = param->phase;
577                 new_param->scope = param->scope;
578                 new_param->sender = param->sender;
579                 new_param->type = param->type;
580                 new_param->use = param->use;
581                 new_param->type_range = param->type_range;
582
583                 new_param->name = kzalloc(strlen(param->name) + 1, GFP_KERNEL);
584                 if (!new_param->name) {
585                         pr_err("Unable to allocate memory for"
586                                 " parameter name.\n");
587                         goto err_out;
588                 }
589
590                 new_param->value = kzalloc(strlen(param->value) + 1,
591                                 GFP_KERNEL);
592                 if (!new_param->value) {
593                         pr_err("Unable to allocate memory for"
594                                 " parameter value.\n");
595                         goto err_out;
596                 }
597
598                 memcpy(new_param->name, param->name, strlen(param->name));
599                 new_param->name[strlen(param->name)] = '\0';
600                 memcpy(new_param->value, param->value, strlen(param->value));
601                 new_param->value[strlen(param->value)] = '\0';
602
603                 list_add_tail(&new_param->p_list, &param_list->param_list);
604         }
605
606         if (!list_empty(&param_list->param_list))
607                 *dst_param_list = param_list;
608         else {
609                 pr_err("No parameters allocated.\n");
610                 goto err_out;
611         }
612
613         return 0;
614
615 err_out:
616         iscsi_release_param_list(param_list);
617         return -1;
618 }
619
620 static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
621 {
622         struct iscsi_extra_response *er, *er_tmp;
623
624         list_for_each_entry_safe(er, er_tmp, &param_list->extra_response_list,
625                         er_list) {
626                 list_del(&er->er_list);
627                 kfree(er);
628         }
629 }
630
631 void iscsi_release_param_list(struct iscsi_param_list *param_list)
632 {
633         struct iscsi_param *param, *param_tmp;
634
635         list_for_each_entry_safe(param, param_tmp, &param_list->param_list,
636                         p_list) {
637                 list_del(&param->p_list);
638
639                 kfree(param->name);
640                 param->name = NULL;
641                 kfree(param->value);
642                 param->value = NULL;
643                 kfree(param);
644                 param = NULL;
645         }
646
647         iscsi_release_extra_responses(param_list);
648
649         kfree(param_list);
650 }
651
652 struct iscsi_param *iscsi_find_param_from_key(
653         char *key,
654         struct iscsi_param_list *param_list)
655 {
656         struct iscsi_param *param;
657
658         if (!key || !param_list) {
659                 pr_err("Key or parameter list pointer is NULL.\n");
660                 return NULL;
661         }
662
663         list_for_each_entry(param, &param_list->param_list, p_list) {
664                 if (!strcmp(key, param->name))
665                         return param;
666         }
667
668         pr_err("Unable to locate key \"%s\".\n", key);
669         return NULL;
670 }
671
672 int iscsi_extract_key_value(char *textbuf, char **key, char **value)
673 {
674         *value = strchr(textbuf, '=');
675         if (!*value) {
676                 pr_err("Unable to locate \"=\" seperator for key,"
677                                 " ignoring request.\n");
678                 return -1;
679         }
680
681         *key = textbuf;
682         **value = '\0';
683         *value = *value + 1;
684
685         return 0;
686 }
687
688 int iscsi_update_param_value(struct iscsi_param *param, char *value)
689 {
690         kfree(param->value);
691
692         param->value = kzalloc(strlen(value) + 1, GFP_KERNEL);
693         if (!param->value) {
694                 pr_err("Unable to allocate memory for value.\n");
695                 return -1;
696         }
697
698         memcpy(param->value, value, strlen(value));
699         param->value[strlen(value)] = '\0';
700
701         pr_debug("iSCSI Parameter updated to %s=%s\n",
702                         param->name, param->value);
703         return 0;
704 }
705
706 static int iscsi_add_notunderstood_response(
707         char *key,
708         char *value,
709         struct iscsi_param_list *param_list)
710 {
711         struct iscsi_extra_response *extra_response;
712
713         if (strlen(value) > VALUE_MAXLEN) {
714                 pr_err("Value for notunderstood key \"%s\" exceeds %d,"
715                         " protocol error.\n", key, VALUE_MAXLEN);
716                 return -1;
717         }
718
719         extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL);
720         if (!extra_response) {
721                 pr_err("Unable to allocate memory for"
722                         " struct iscsi_extra_response.\n");
723                 return -1;
724         }
725         INIT_LIST_HEAD(&extra_response->er_list);
726
727         strncpy(extra_response->key, key, strlen(key) + 1);
728         strncpy(extra_response->value, NOTUNDERSTOOD,
729                         strlen(NOTUNDERSTOOD) + 1);
730
731         list_add_tail(&extra_response->er_list,
732                         &param_list->extra_response_list);
733         return 0;
734 }
735
736 static int iscsi_check_for_auth_key(char *key)
737 {
738         /*
739          * RFC 1994
740          */
741         if (!strcmp(key, "CHAP_A") || !strcmp(key, "CHAP_I") ||
742             !strcmp(key, "CHAP_C") || !strcmp(key, "CHAP_N") ||
743             !strcmp(key, "CHAP_R"))
744                 return 1;
745
746         /*
747          * RFC 2945
748          */
749         if (!strcmp(key, "SRP_U") || !strcmp(key, "SRP_N") ||
750             !strcmp(key, "SRP_g") || !strcmp(key, "SRP_s") ||
751             !strcmp(key, "SRP_A") || !strcmp(key, "SRP_B") ||
752             !strcmp(key, "SRP_M") || !strcmp(key, "SRP_HM"))
753                 return 1;
754
755         return 0;
756 }
757
758 static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
759 {
760         if (IS_TYPE_BOOL_AND(param)) {
761                 if (!strcmp(param->value, NO))
762                         SET_PSTATE_REPLY_OPTIONAL(param);
763         } else if (IS_TYPE_BOOL_OR(param)) {
764                 if (!strcmp(param->value, YES))
765                         SET_PSTATE_REPLY_OPTIONAL(param);
766                  /*
767                   * Required for gPXE iSCSI boot client
768                   */
769                 if (!strcmp(param->name, IMMEDIATEDATA))
770                         SET_PSTATE_REPLY_OPTIONAL(param);
771         } else if (IS_TYPE_NUMBER(param)) {
772                 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
773                         SET_PSTATE_REPLY_OPTIONAL(param);
774                 /*
775                  * The GlobalSAN iSCSI Initiator for MacOSX does
776                  * not respond to MaxBurstLength, FirstBurstLength,
777                  * DefaultTime2Wait or DefaultTime2Retain parameter keys.
778                  * So, we set them to 'reply optional' here, and assume the
779                  * the defaults from iscsi_parameters.h if the initiator
780                  * is not RFC compliant and the keys are not negotiated.
781                  */
782                 if (!strcmp(param->name, MAXBURSTLENGTH))
783                         SET_PSTATE_REPLY_OPTIONAL(param);
784                 if (!strcmp(param->name, FIRSTBURSTLENGTH))
785                         SET_PSTATE_REPLY_OPTIONAL(param);
786                 if (!strcmp(param->name, DEFAULTTIME2WAIT))
787                         SET_PSTATE_REPLY_OPTIONAL(param);
788                 if (!strcmp(param->name, DEFAULTTIME2RETAIN))
789                         SET_PSTATE_REPLY_OPTIONAL(param);
790                 /*
791                  * Required for gPXE iSCSI boot client
792                  */
793                 if (!strcmp(param->name, MAXCONNECTIONS))
794                         SET_PSTATE_REPLY_OPTIONAL(param);
795         } else if (IS_PHASE_DECLARATIVE(param))
796                 SET_PSTATE_REPLY_OPTIONAL(param);
797 }
798
799 static int iscsi_check_boolean_value(struct iscsi_param *param, char *value)
800 {
801         if (strcmp(value, YES) && strcmp(value, NO)) {
802                 pr_err("Illegal value for \"%s\", must be either"
803                         " \"%s\" or \"%s\".\n", param->name, YES, NO);
804                 return -1;
805         }
806
807         return 0;
808 }
809
810 static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_ptr)
811 {
812         char *tmpptr;
813         int value = 0;
814
815         value = simple_strtoul(value_ptr, &tmpptr, 0);
816
817 /* #warning FIXME: Fix this */
818 #if 0
819         if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) {
820                 pr_err("Illegal value \"%s\" for \"%s\".\n",
821                         value, param->name);
822                 return -1;
823         }
824 #endif
825         if (IS_TYPERANGE_0_TO_2(param)) {
826                 if ((value < 0) || (value > 2)) {
827                         pr_err("Illegal value for \"%s\", must be"
828                                 " between 0 and 2.\n", param->name);
829                         return -1;
830                 }
831                 return 0;
832         }
833         if (IS_TYPERANGE_0_TO_3600(param)) {
834                 if ((value < 0) || (value > 3600)) {
835                         pr_err("Illegal value for \"%s\", must be"
836                                 " between 0 and 3600.\n", param->name);
837                         return -1;
838                 }
839                 return 0;
840         }
841         if (IS_TYPERANGE_0_TO_32767(param)) {
842                 if ((value < 0) || (value > 32767)) {
843                         pr_err("Illegal value for \"%s\", must be"
844                                 " between 0 and 32767.\n", param->name);
845                         return -1;
846                 }
847                 return 0;
848         }
849         if (IS_TYPERANGE_0_TO_65535(param)) {
850                 if ((value < 0) || (value > 65535)) {
851                         pr_err("Illegal value for \"%s\", must be"
852                                 " between 0 and 65535.\n", param->name);
853                         return -1;
854                 }
855                 return 0;
856         }
857         if (IS_TYPERANGE_1_TO_65535(param)) {
858                 if ((value < 1) || (value > 65535)) {
859                         pr_err("Illegal value for \"%s\", must be"
860                                 " between 1 and 65535.\n", param->name);
861                         return -1;
862                 }
863                 return 0;
864         }
865         if (IS_TYPERANGE_2_TO_3600(param)) {
866                 if ((value < 2) || (value > 3600)) {
867                         pr_err("Illegal value for \"%s\", must be"
868                                 " between 2 and 3600.\n", param->name);
869                         return -1;
870                 }
871                 return 0;
872         }
873         if (IS_TYPERANGE_512_TO_16777215(param)) {
874                 if ((value < 512) || (value > 16777215)) {
875                         pr_err("Illegal value for \"%s\", must be"
876                                 " between 512 and 16777215.\n", param->name);
877                         return -1;
878                 }
879                 return 0;
880         }
881
882         return 0;
883 }
884
885 static int iscsi_check_numerical_range_value(struct iscsi_param *param, char *value)
886 {
887         char *left_val_ptr = NULL, *right_val_ptr = NULL;
888         char *tilde_ptr = NULL, *tmp_ptr = NULL;
889         u32 left_val, right_val, local_left_val, local_right_val;
890
891         if (strcmp(param->name, IFMARKINT) &&
892             strcmp(param->name, OFMARKINT)) {
893                 pr_err("Only parameters \"%s\" or \"%s\" may contain a"
894                        " numerical range value.\n", IFMARKINT, OFMARKINT);
895                 return -1;
896         }
897
898         if (IS_PSTATE_PROPOSER(param))
899                 return 0;
900
901         tilde_ptr = strchr(value, '~');
902         if (!tilde_ptr) {
903                 pr_err("Unable to locate numerical range indicator"
904                         " \"~\" for \"%s\".\n", param->name);
905                 return -1;
906         }
907         *tilde_ptr = '\0';
908
909         left_val_ptr = value;
910         right_val_ptr = value + strlen(left_val_ptr) + 1;
911
912         if (iscsi_check_numerical_value(param, left_val_ptr) < 0)
913                 return -1;
914         if (iscsi_check_numerical_value(param, right_val_ptr) < 0)
915                 return -1;
916
917         left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
918         right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
919         *tilde_ptr = '~';
920
921         if (right_val < left_val) {
922                 pr_err("Numerical range for parameter \"%s\" contains"
923                         " a right value which is less than the left.\n",
924                                 param->name);
925                 return -1;
926         }
927
928         /*
929          * For now,  enforce reasonable defaults for [I,O]FMarkInt.
930          */
931         tilde_ptr = strchr(param->value, '~');
932         if (!tilde_ptr) {
933                 pr_err("Unable to locate numerical range indicator"
934                         " \"~\" for \"%s\".\n", param->name);
935                 return -1;
936         }
937         *tilde_ptr = '\0';
938
939         left_val_ptr = param->value;
940         right_val_ptr = param->value + strlen(left_val_ptr) + 1;
941
942         local_left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
943         local_right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
944         *tilde_ptr = '~';
945
946         if (param->set_param) {
947                 if ((left_val < local_left_val) ||
948                     (right_val < local_left_val)) {
949                         pr_err("Passed value range \"%u~%u\" is below"
950                                 " minimum left value \"%u\" for key \"%s\","
951                                 " rejecting.\n", left_val, right_val,
952                                 local_left_val, param->name);
953                         return -1;
954                 }
955         } else {
956                 if ((left_val < local_left_val) &&
957                     (right_val < local_left_val)) {
958                         pr_err("Received value range \"%u~%u\" is"
959                                 " below minimum left value \"%u\" for key"
960                                 " \"%s\", rejecting.\n", left_val, right_val,
961                                 local_left_val, param->name);
962                         SET_PSTATE_REJECT(param);
963                         if (iscsi_update_param_value(param, REJECT) < 0)
964                                 return -1;
965                 }
966         }
967
968         return 0;
969 }
970
971 static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
972 {
973         if (IS_PSTATE_PROPOSER(param))
974                 return 0;
975
976         if (IS_TYPERANGE_AUTH_PARAM(param)) {
977                 if (strcmp(value, KRB5) && strcmp(value, SPKM1) &&
978                     strcmp(value, SPKM2) && strcmp(value, SRP) &&
979                     strcmp(value, CHAP) && strcmp(value, NONE)) {
980                         pr_err("Illegal value for \"%s\", must be"
981                                 " \"%s\", \"%s\", \"%s\", \"%s\", \"%s\""
982                                 " or \"%s\".\n", param->name, KRB5,
983                                         SPKM1, SPKM2, SRP, CHAP, NONE);
984                         return -1;
985                 }
986         }
987         if (IS_TYPERANGE_DIGEST_PARAM(param)) {
988                 if (strcmp(value, CRC32C) && strcmp(value, NONE)) {
989                         pr_err("Illegal value for \"%s\", must be"
990                                 " \"%s\" or \"%s\".\n", param->name,
991                                         CRC32C, NONE);
992                         return -1;
993                 }
994         }
995         if (IS_TYPERANGE_SESSIONTYPE(param)) {
996                 if (strcmp(value, DISCOVERY) && strcmp(value, NORMAL)) {
997                         pr_err("Illegal value for \"%s\", must be"
998                                 " \"%s\" or \"%s\".\n", param->name,
999                                         DISCOVERY, NORMAL);
1000                         return -1;
1001                 }
1002         }
1003
1004         return 0;
1005 }
1006
1007 /*
1008  *      This function is used to pick a value range number,  currently just
1009  *      returns the lesser of both right values.
1010  */
1011 static char *iscsi_get_value_from_number_range(
1012         struct iscsi_param *param,
1013         char *value)
1014 {
1015         char *end_ptr, *tilde_ptr1 = NULL, *tilde_ptr2 = NULL;
1016         u32 acceptor_right_value, proposer_right_value;
1017
1018         tilde_ptr1 = strchr(value, '~');
1019         if (!tilde_ptr1)
1020                 return NULL;
1021         *tilde_ptr1++ = '\0';
1022         proposer_right_value = simple_strtoul(tilde_ptr1, &end_ptr, 0);
1023
1024         tilde_ptr2 = strchr(param->value, '~');
1025         if (!tilde_ptr2)
1026                 return NULL;
1027         *tilde_ptr2++ = '\0';
1028         acceptor_right_value = simple_strtoul(tilde_ptr2, &end_ptr, 0);
1029
1030         return (acceptor_right_value >= proposer_right_value) ?
1031                 tilde_ptr1 : tilde_ptr2;
1032 }
1033
1034 static char *iscsi_check_valuelist_for_support(
1035         struct iscsi_param *param,
1036         char *value)
1037 {
1038         char *tmp1 = NULL, *tmp2 = NULL;
1039         char *acceptor_values = NULL, *proposer_values = NULL;
1040
1041         acceptor_values = param->value;
1042         proposer_values = value;
1043
1044         do {
1045                 if (!proposer_values)
1046                         return NULL;
1047                 tmp1 = strchr(proposer_values, ',');
1048                 if (tmp1)
1049                         *tmp1 = '\0';
1050                 acceptor_values = param->value;
1051                 do {
1052                         if (!acceptor_values) {
1053                                 if (tmp1)
1054                                         *tmp1 = ',';
1055                                 return NULL;
1056                         }
1057                         tmp2 = strchr(acceptor_values, ',');
1058                         if (tmp2)
1059                                 *tmp2 = '\0';
1060                         if (!acceptor_values || !proposer_values) {
1061                                 if (tmp1)
1062                                         *tmp1 = ',';
1063                                 if (tmp2)
1064                                         *tmp2 = ',';
1065                                 return NULL;
1066                         }
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                         if (!acceptor_values)
1077                                 break;
1078                 } while (acceptor_values);
1079                 if (tmp1)
1080                         *tmp1++ = ',';
1081                 proposer_values = tmp1;
1082         } while (proposer_values);
1083
1084 out:
1085         return proposer_values;
1086 }
1087
1088 static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
1089 {
1090         u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
1091         char *negoitated_value = NULL;
1092
1093         if (IS_PSTATE_ACCEPTOR(param)) {
1094                 pr_err("Received key \"%s\" twice, protocol error.\n",
1095                                 param->name);
1096                 return -1;
1097         }
1098
1099         if (IS_PSTATE_REJECT(param))
1100                 return 0;
1101
1102         if (IS_TYPE_BOOL_AND(param)) {
1103                 if (!strcmp(value, YES))
1104                         proposer_boolean_value = 1;
1105                 if (!strcmp(param->value, YES))
1106                         acceptor_boolean_value = 1;
1107                 if (acceptor_boolean_value && proposer_boolean_value)
1108                         do {} while (0);
1109                 else {
1110                         if (iscsi_update_param_value(param, NO) < 0)
1111                                 return -1;
1112                         if (!proposer_boolean_value)
1113                                 SET_PSTATE_REPLY_OPTIONAL(param);
1114                 }
1115         } else if (IS_TYPE_BOOL_OR(param)) {
1116                 if (!strcmp(value, YES))
1117                         proposer_boolean_value = 1;
1118                 if (!strcmp(param->value, YES))
1119                         acceptor_boolean_value = 1;
1120                 if (acceptor_boolean_value || proposer_boolean_value) {
1121                         if (iscsi_update_param_value(param, YES) < 0)
1122                                 return -1;
1123                         if (proposer_boolean_value)
1124                                 SET_PSTATE_REPLY_OPTIONAL(param);
1125                 }
1126         } else if (IS_TYPE_NUMBER(param)) {
1127                 char *tmpptr, buf[10];
1128                 u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
1129                 u32 proposer_value = simple_strtoul(value, &tmpptr, 0);
1130
1131                 memset(buf, 0, 10);
1132
1133                 if (!strcmp(param->name, MAXCONNECTIONS) ||
1134                     !strcmp(param->name, MAXBURSTLENGTH) ||
1135                     !strcmp(param->name, FIRSTBURSTLENGTH) ||
1136                     !strcmp(param->name, MAXOUTSTANDINGR2T) ||
1137                     !strcmp(param->name, DEFAULTTIME2RETAIN) ||
1138                     !strcmp(param->name, ERRORRECOVERYLEVEL)) {
1139                         if (proposer_value > acceptor_value) {
1140                                 sprintf(buf, "%u", acceptor_value);
1141                                 if (iscsi_update_param_value(param,
1142                                                 &buf[0]) < 0)
1143                                         return -1;
1144                         } else {
1145                                 if (iscsi_update_param_value(param, value) < 0)
1146                                         return -1;
1147                         }
1148                 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1149                         if (acceptor_value > proposer_value) {
1150                                 sprintf(buf, "%u", acceptor_value);
1151                                 if (iscsi_update_param_value(param,
1152                                                 &buf[0]) < 0)
1153                                         return -1;
1154                         } else {
1155                                 if (iscsi_update_param_value(param, value) < 0)
1156                                         return -1;
1157                         }
1158                 } else {
1159                         if (iscsi_update_param_value(param, value) < 0)
1160                                 return -1;
1161                 }
1162
1163                 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
1164                         SET_PSTATE_REPLY_OPTIONAL(param);
1165         } else if (IS_TYPE_NUMBER_RANGE(param)) {
1166                 negoitated_value = iscsi_get_value_from_number_range(
1167                                         param, value);
1168                 if (!negoitated_value)
1169                         return -1;
1170                 if (iscsi_update_param_value(param, negoitated_value) < 0)
1171                         return -1;
1172         } else if (IS_TYPE_VALUE_LIST(param)) {
1173                 negoitated_value = iscsi_check_valuelist_for_support(
1174                                         param, value);
1175                 if (!negoitated_value) {
1176                         pr_err("Proposer's value list \"%s\" contains"
1177                                 " no valid values from Acceptor's value list"
1178                                 " \"%s\".\n", value, param->value);
1179                         return -1;
1180                 }
1181                 if (iscsi_update_param_value(param, negoitated_value) < 0)
1182                         return -1;
1183         } else if (IS_PHASE_DECLARATIVE(param)) {
1184                 if (iscsi_update_param_value(param, value) < 0)
1185                         return -1;
1186                 SET_PSTATE_REPLY_OPTIONAL(param);
1187         }
1188
1189         return 0;
1190 }
1191
1192 static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
1193 {
1194         if (IS_PSTATE_RESPONSE_GOT(param)) {
1195                 pr_err("Received key \"%s\" twice, protocol error.\n",
1196                                 param->name);
1197                 return -1;
1198         }
1199
1200         if (IS_TYPE_NUMBER_RANGE(param)) {
1201                 u32 left_val = 0, right_val = 0, recieved_value = 0;
1202                 char *left_val_ptr = NULL, *right_val_ptr = NULL;
1203                 char *tilde_ptr = NULL, *tmp_ptr = NULL;
1204
1205                 if (!strcmp(value, IRRELEVANT) || !strcmp(value, REJECT)) {
1206                         if (iscsi_update_param_value(param, value) < 0)
1207                                 return -1;
1208                         return 0;
1209                 }
1210
1211                 tilde_ptr = strchr(value, '~');
1212                 if (tilde_ptr) {
1213                         pr_err("Illegal \"~\" in response for \"%s\".\n",
1214                                         param->name);
1215                         return -1;
1216                 }
1217                 tilde_ptr = strchr(param->value, '~');
1218                 if (!tilde_ptr) {
1219                         pr_err("Unable to locate numerical range"
1220                                 " indicator \"~\" for \"%s\".\n", param->name);
1221                         return -1;
1222                 }
1223                 *tilde_ptr = '\0';
1224
1225                 left_val_ptr = param->value;
1226                 right_val_ptr = param->value + strlen(left_val_ptr) + 1;
1227                 left_val = simple_strtoul(left_val_ptr, &tmp_ptr, 0);
1228                 right_val = simple_strtoul(right_val_ptr, &tmp_ptr, 0);
1229                 recieved_value = simple_strtoul(value, &tmp_ptr, 0);
1230
1231                 *tilde_ptr = '~';
1232
1233                 if ((recieved_value < left_val) ||
1234                     (recieved_value > right_val)) {
1235                         pr_err("Illegal response \"%s=%u\", value must"
1236                                 " be between %u and %u.\n", param->name,
1237                                 recieved_value, left_val, right_val);
1238                         return -1;
1239                 }
1240         } else if (IS_TYPE_VALUE_LIST(param)) {
1241                 char *comma_ptr = NULL, *tmp_ptr = NULL;
1242
1243                 comma_ptr = strchr(value, ',');
1244                 if (comma_ptr) {
1245                         pr_err("Illegal \",\" in response for \"%s\".\n",
1246                                         param->name);
1247                         return -1;
1248                 }
1249
1250                 tmp_ptr = iscsi_check_valuelist_for_support(param, value);
1251                 if (!tmp_ptr)
1252                         return -1;
1253         }
1254
1255         if (iscsi_update_param_value(param, value) < 0)
1256                 return -1;
1257
1258         return 0;
1259 }
1260
1261 static int iscsi_check_value(struct iscsi_param *param, char *value)
1262 {
1263         char *comma_ptr = NULL;
1264
1265         if (!strcmp(value, REJECT)) {
1266                 if (!strcmp(param->name, IFMARKINT) ||
1267                     !strcmp(param->name, OFMARKINT)) {
1268                         /*
1269                          * Reject is not fatal for [I,O]FMarkInt,  and causes
1270                          * [I,O]FMarker to be reset to No. (See iSCSI v20 A.3.2)
1271                          */
1272                         SET_PSTATE_REJECT(param);
1273                         return 0;
1274                 }
1275                 pr_err("Received %s=%s\n", param->name, value);
1276                 return -1;
1277         }
1278         if (!strcmp(value, IRRELEVANT)) {
1279                 pr_debug("Received %s=%s\n", param->name, value);
1280                 SET_PSTATE_IRRELEVANT(param);
1281                 return 0;
1282         }
1283         if (!strcmp(value, NOTUNDERSTOOD)) {
1284                 if (!IS_PSTATE_PROPOSER(param)) {
1285                         pr_err("Received illegal offer %s=%s\n",
1286                                 param->name, value);
1287                         return -1;
1288                 }
1289
1290 /* #warning FIXME: Add check for X-ExtensionKey here */
1291                 pr_err("Standard iSCSI key \"%s\" cannot be answered"
1292                         " with \"%s\", protocol error.\n", param->name, value);
1293                 return -1;
1294         }
1295
1296         do {
1297                 comma_ptr = NULL;
1298                 comma_ptr = strchr(value, ',');
1299
1300                 if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
1301                         pr_err("Detected value seperator \",\", but"
1302                                 " key \"%s\" does not allow a value list,"
1303                                 " protocol error.\n", param->name);
1304                         return -1;
1305                 }
1306                 if (comma_ptr)
1307                         *comma_ptr = '\0';
1308
1309                 if (strlen(value) > VALUE_MAXLEN) {
1310                         pr_err("Value for key \"%s\" exceeds %d,"
1311                                 " protocol error.\n", param->name,
1312                                 VALUE_MAXLEN);
1313                         return -1;
1314                 }
1315
1316                 if (IS_TYPE_BOOL_AND(param) || IS_TYPE_BOOL_OR(param)) {
1317                         if (iscsi_check_boolean_value(param, value) < 0)
1318                                 return -1;
1319                 } else if (IS_TYPE_NUMBER(param)) {
1320                         if (iscsi_check_numerical_value(param, value) < 0)
1321                                 return -1;
1322                 } else if (IS_TYPE_NUMBER_RANGE(param)) {
1323                         if (iscsi_check_numerical_range_value(param, value) < 0)
1324                                 return -1;
1325                 } else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
1326                         if (iscsi_check_string_or_list_value(param, value) < 0)
1327                                 return -1;
1328                 } else {
1329                         pr_err("Huh? 0x%02x\n", param->type);
1330                         return -1;
1331                 }
1332
1333                 if (comma_ptr)
1334                         *comma_ptr++ = ',';
1335
1336                 value = comma_ptr;
1337         } while (value);
1338
1339         return 0;
1340 }
1341
1342 static struct iscsi_param *__iscsi_check_key(
1343         char *key,
1344         int sender,
1345         struct iscsi_param_list *param_list)
1346 {
1347         struct iscsi_param *param;
1348
1349         if (strlen(key) > KEY_MAXLEN) {
1350                 pr_err("Length of key name \"%s\" exceeds %d.\n",
1351                         key, KEY_MAXLEN);
1352                 return NULL;
1353         }
1354
1355         param = iscsi_find_param_from_key(key, param_list);
1356         if (!param)
1357                 return NULL;
1358
1359         if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1360                 pr_err("Key \"%s\" may not be sent to %s,"
1361                         " protocol error.\n", param->name,
1362                         (sender & SENDER_RECEIVER) ? "target" : "initiator");
1363                 return NULL;
1364         }
1365
1366         if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1367                 pr_err("Key \"%s\" may not be sent to %s,"
1368                         " protocol error.\n", param->name,
1369                         (sender & SENDER_RECEIVER) ? "initiator" : "target");
1370                 return NULL;
1371         }
1372
1373         return param;
1374 }
1375
1376 static struct iscsi_param *iscsi_check_key(
1377         char *key,
1378         int phase,
1379         int sender,
1380         struct iscsi_param_list *param_list)
1381 {
1382         struct iscsi_param *param;
1383         /*
1384          * Key name length must not exceed 63 bytes. (See iSCSI v20 5.1)
1385          */
1386         if (strlen(key) > KEY_MAXLEN) {
1387                 pr_err("Length of key name \"%s\" exceeds %d.\n",
1388                         key, KEY_MAXLEN);
1389                 return NULL;
1390         }
1391
1392         param = iscsi_find_param_from_key(key, param_list);
1393         if (!param)
1394                 return NULL;
1395
1396         if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1397                 pr_err("Key \"%s\" may not be sent to %s,"
1398                         " protocol error.\n", param->name,
1399                         (sender & SENDER_RECEIVER) ? "target" : "initiator");
1400                 return NULL;
1401         }
1402         if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1403                 pr_err("Key \"%s\" may not be sent to %s,"
1404                                 " protocol error.\n", param->name,
1405                         (sender & SENDER_RECEIVER) ? "initiator" : "target");
1406                 return NULL;
1407         }
1408
1409         if (IS_PSTATE_ACCEPTOR(param)) {
1410                 pr_err("Key \"%s\" received twice, protocol error.\n",
1411                                 key);
1412                 return NULL;
1413         }
1414
1415         if (!phase)
1416                 return param;
1417
1418         if (!(param->phase & phase)) {
1419                 pr_err("Key \"%s\" may not be negotiated during ",
1420                                 param->name);
1421                 switch (phase) {
1422                 case PHASE_SECURITY:
1423                         pr_debug("Security phase.\n");
1424                         break;
1425                 case PHASE_OPERATIONAL:
1426                         pr_debug("Operational phase.\n");
1427                 default:
1428                         pr_debug("Unknown phase.\n");
1429                 }
1430                 return NULL;
1431         }
1432
1433         return param;
1434 }
1435
1436 static int iscsi_enforce_integrity_rules(
1437         u8 phase,
1438         struct iscsi_param_list *param_list)
1439 {
1440         char *tmpptr;
1441         u8 DataSequenceInOrder = 0;
1442         u8 ErrorRecoveryLevel = 0, SessionType = 0;
1443         u8 IFMarker = 0, OFMarker = 0;
1444         u8 IFMarkInt_Reject = 0, OFMarkInt_Reject = 0;
1445         u32 FirstBurstLength = 0, MaxBurstLength = 0;
1446         struct iscsi_param *param = NULL;
1447
1448         list_for_each_entry(param, &param_list->param_list, p_list) {
1449                 if (!(param->phase & phase))
1450                         continue;
1451                 if (!strcmp(param->name, SESSIONTYPE))
1452                         if (!strcmp(param->value, NORMAL))
1453                                 SessionType = 1;
1454                 if (!strcmp(param->name, ERRORRECOVERYLEVEL))
1455                         ErrorRecoveryLevel = simple_strtoul(param->value,
1456                                         &tmpptr, 0);
1457                 if (!strcmp(param->name, DATASEQUENCEINORDER))
1458                         if (!strcmp(param->value, YES))
1459                                 DataSequenceInOrder = 1;
1460                 if (!strcmp(param->name, MAXBURSTLENGTH))
1461                         MaxBurstLength = simple_strtoul(param->value,
1462                                         &tmpptr, 0);
1463                 if (!strcmp(param->name, IFMARKER))
1464                         if (!strcmp(param->value, YES))
1465                                 IFMarker = 1;
1466                 if (!strcmp(param->name, OFMARKER))
1467                         if (!strcmp(param->value, YES))
1468                                 OFMarker = 1;
1469                 if (!strcmp(param->name, IFMARKINT))
1470                         if (!strcmp(param->value, REJECT))
1471                                 IFMarkInt_Reject = 1;
1472                 if (!strcmp(param->name, OFMARKINT))
1473                         if (!strcmp(param->value, REJECT))
1474                                 OFMarkInt_Reject = 1;
1475         }
1476
1477         list_for_each_entry(param, &param_list->param_list, p_list) {
1478                 if (!(param->phase & phase))
1479                         continue;
1480                 if (!SessionType && (!IS_PSTATE_ACCEPTOR(param) &&
1481                      (strcmp(param->name, IFMARKER) &&
1482                       strcmp(param->name, OFMARKER) &&
1483                       strcmp(param->name, IFMARKINT) &&
1484                       strcmp(param->name, OFMARKINT))))
1485                         continue;
1486                 if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
1487                     DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
1488                         if (strcmp(param->value, "1")) {
1489                                 if (iscsi_update_param_value(param, "1") < 0)
1490                                         return -1;
1491                                 pr_debug("Reset \"%s\" to \"%s\".\n",
1492                                         param->name, param->value);
1493                         }
1494                 }
1495                 if (!strcmp(param->name, MAXCONNECTIONS) && !SessionType) {
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, FIRSTBURSTLENGTH)) {
1504                         FirstBurstLength = simple_strtoul(param->value,
1505                                         &tmpptr, 0);
1506                         if (FirstBurstLength > MaxBurstLength) {
1507                                 char tmpbuf[10];
1508                                 memset(tmpbuf, 0, 10);
1509                                 sprintf(tmpbuf, "%u", MaxBurstLength);
1510                                 if (iscsi_update_param_value(param, tmpbuf))
1511                                         return -1;
1512                                 pr_debug("Reset \"%s\" to \"%s\".\n",
1513                                         param->name, param->value);
1514                         }
1515                 }
1516                 if (!strcmp(param->name, IFMARKER) && IFMarkInt_Reject) {
1517                         if (iscsi_update_param_value(param, NO) < 0)
1518                                 return -1;
1519                         IFMarker = 0;
1520                         pr_debug("Reset \"%s\" to \"%s\".\n",
1521                                         param->name, param->value);
1522                 }
1523                 if (!strcmp(param->name, OFMARKER) && OFMarkInt_Reject) {
1524                         if (iscsi_update_param_value(param, NO) < 0)
1525                                 return -1;
1526                         OFMarker = 0;
1527                         pr_debug("Reset \"%s\" to \"%s\".\n",
1528                                          param->name, param->value);
1529                 }
1530                 if (!strcmp(param->name, IFMARKINT) && !IFMarker) {
1531                         if (!strcmp(param->value, REJECT))
1532                                 continue;
1533                         param->state &= ~PSTATE_NEGOTIATE;
1534                         if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1535                                 return -1;
1536                         pr_debug("Reset \"%s\" to \"%s\".\n",
1537                                         param->name, param->value);
1538                 }
1539                 if (!strcmp(param->name, OFMARKINT) && !OFMarker) {
1540                         if (!strcmp(param->value, REJECT))
1541                                 continue;
1542                         param->state &= ~PSTATE_NEGOTIATE;
1543                         if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1544                                 return -1;
1545                         pr_debug("Reset \"%s\" to \"%s\".\n",
1546                                         param->name, param->value);
1547                 }
1548         }
1549
1550         return 0;
1551 }
1552
1553 int iscsi_decode_text_input(
1554         u8 phase,
1555         u8 sender,
1556         char *textbuf,
1557         u32 length,
1558         struct iscsi_param_list *param_list)
1559 {
1560         char *tmpbuf, *start = NULL, *end = NULL;
1561
1562         tmpbuf = kzalloc(length + 1, GFP_KERNEL);
1563         if (!tmpbuf) {
1564                 pr_err("Unable to allocate memory for tmpbuf.\n");
1565                 return -1;
1566         }
1567
1568         memcpy(tmpbuf, textbuf, length);
1569         tmpbuf[length] = '\0';
1570         start = tmpbuf;
1571         end = (start + length);
1572
1573         while (start < end) {
1574                 char *key, *value;
1575                 struct iscsi_param *param;
1576
1577                 if (iscsi_extract_key_value(start, &key, &value) < 0) {
1578                         kfree(tmpbuf);
1579                         return -1;
1580                 }
1581
1582                 pr_debug("Got key: %s=%s\n", key, value);
1583
1584                 if (phase & PHASE_SECURITY) {
1585                         if (iscsi_check_for_auth_key(key) > 0) {
1586                                 char *tmpptr = key + strlen(key);
1587                                 *tmpptr = '=';
1588                                 kfree(tmpbuf);
1589                                 return 1;
1590                         }
1591                 }
1592
1593                 param = iscsi_check_key(key, phase, sender, param_list);
1594                 if (!param) {
1595                         if (iscsi_add_notunderstood_response(key,
1596                                         value, param_list) < 0) {
1597                                 kfree(tmpbuf);
1598                                 return -1;
1599                         }
1600                         start += strlen(key) + strlen(value) + 2;
1601                         continue;
1602                 }
1603                 if (iscsi_check_value(param, value) < 0) {
1604                         kfree(tmpbuf);
1605                         return -1;
1606                 }
1607
1608                 start += strlen(key) + strlen(value) + 2;
1609
1610                 if (IS_PSTATE_PROPOSER(param)) {
1611                         if (iscsi_check_proposer_state(param, value) < 0) {
1612                                 kfree(tmpbuf);
1613                                 return -1;
1614                         }
1615                         SET_PSTATE_RESPONSE_GOT(param);
1616                 } else {
1617                         if (iscsi_check_acceptor_state(param, value) < 0) {
1618                                 kfree(tmpbuf);
1619                                 return -1;
1620                         }
1621                         SET_PSTATE_ACCEPTOR(param);
1622                 }
1623         }
1624
1625         kfree(tmpbuf);
1626         return 0;
1627 }
1628
1629 int iscsi_encode_text_output(
1630         u8 phase,
1631         u8 sender,
1632         char *textbuf,
1633         u32 *length,
1634         struct iscsi_param_list *param_list)
1635 {
1636         char *output_buf = NULL;
1637         struct iscsi_extra_response *er;
1638         struct iscsi_param *param;
1639
1640         output_buf = textbuf + *length;
1641
1642         if (iscsi_enforce_integrity_rules(phase, param_list) < 0)
1643                 return -1;
1644
1645         list_for_each_entry(param, &param_list->param_list, p_list) {
1646                 if (!(param->sender & sender))
1647                         continue;
1648                 if (IS_PSTATE_ACCEPTOR(param) &&
1649                     !IS_PSTATE_RESPONSE_SENT(param) &&
1650                     !IS_PSTATE_REPLY_OPTIONAL(param) &&
1651                     (param->phase & phase)) {
1652                         *length += sprintf(output_buf, "%s=%s",
1653                                 param->name, param->value);
1654                         *length += 1;
1655                         output_buf = textbuf + *length;
1656                         SET_PSTATE_RESPONSE_SENT(param);
1657                         pr_debug("Sending key: %s=%s\n",
1658                                 param->name, param->value);
1659                         continue;
1660                 }
1661                 if (IS_PSTATE_NEGOTIATE(param) &&
1662                     !IS_PSTATE_ACCEPTOR(param) &&
1663                     !IS_PSTATE_PROPOSER(param) &&
1664                     (param->phase & phase)) {
1665                         *length += sprintf(output_buf, "%s=%s",
1666                                 param->name, param->value);
1667                         *length += 1;
1668                         output_buf = textbuf + *length;
1669                         SET_PSTATE_PROPOSER(param);
1670                         iscsi_check_proposer_for_optional_reply(param);
1671                         pr_debug("Sending key: %s=%s\n",
1672                                 param->name, param->value);
1673                 }
1674         }
1675
1676         list_for_each_entry(er, &param_list->extra_response_list, er_list) {
1677                 *length += sprintf(output_buf, "%s=%s", er->key, er->value);
1678                 *length += 1;
1679                 output_buf = textbuf + *length;
1680                 pr_debug("Sending key: %s=%s\n", er->key, er->value);
1681         }
1682         iscsi_release_extra_responses(param_list);
1683
1684         return 0;
1685 }
1686
1687 int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list)
1688 {
1689         int ret = 0;
1690         struct iscsi_param *param;
1691
1692         list_for_each_entry(param, &param_list->param_list, p_list) {
1693                 if (IS_PSTATE_NEGOTIATE(param) &&
1694                     IS_PSTATE_PROPOSER(param) &&
1695                     !IS_PSTATE_RESPONSE_GOT(param) &&
1696                     !IS_PSTATE_REPLY_OPTIONAL(param) &&
1697                     !IS_PHASE_DECLARATIVE(param)) {
1698                         pr_err("No response for proposed key \"%s\".\n",
1699                                         param->name);
1700                         ret = -1;
1701                 }
1702         }
1703
1704         return ret;
1705 }
1706
1707 int iscsi_change_param_value(
1708         char *keyvalue,
1709         struct iscsi_param_list *param_list,
1710         int check_key)
1711 {
1712         char *key = NULL, *value = NULL;
1713         struct iscsi_param *param;
1714         int sender = 0;
1715
1716         if (iscsi_extract_key_value(keyvalue, &key, &value) < 0)
1717                 return -1;
1718
1719         if (!check_key) {
1720                 param = __iscsi_check_key(keyvalue, sender, param_list);
1721                 if (!param)
1722                         return -1;
1723         } else {
1724                 param = iscsi_check_key(keyvalue, 0, sender, param_list);
1725                 if (!param)
1726                         return -1;
1727
1728                 param->set_param = 1;
1729                 if (iscsi_check_value(param, value) < 0) {
1730                         param->set_param = 0;
1731                         return -1;
1732                 }
1733                 param->set_param = 0;
1734         }
1735
1736         if (iscsi_update_param_value(param, value) < 0)
1737                 return -1;
1738
1739         return 0;
1740 }
1741
1742 void iscsi_set_connection_parameters(
1743         struct iscsi_conn_ops *ops,
1744         struct iscsi_param_list *param_list)
1745 {
1746         char *tmpptr;
1747         struct iscsi_param *param;
1748
1749         pr_debug("---------------------------------------------------"
1750                         "---------------\n");
1751         list_for_each_entry(param, &param_list->param_list, p_list) {
1752                 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1753                         continue;
1754                 if (!strcmp(param->name, AUTHMETHOD)) {
1755                         pr_debug("AuthMethod:                   %s\n",
1756                                 param->value);
1757                 } else if (!strcmp(param->name, HEADERDIGEST)) {
1758                         ops->HeaderDigest = !strcmp(param->value, CRC32C);
1759                         pr_debug("HeaderDigest:                 %s\n",
1760                                 param->value);
1761                 } else if (!strcmp(param->name, DATADIGEST)) {
1762                         ops->DataDigest = !strcmp(param->value, CRC32C);
1763                         pr_debug("DataDigest:                   %s\n",
1764                                 param->value);
1765                 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1766                         ops->MaxRecvDataSegmentLength =
1767                                 simple_strtoul(param->value, &tmpptr, 0);
1768                         pr_debug("MaxRecvDataSegmentLength:     %s\n",
1769                                 param->value);
1770                 } else if (!strcmp(param->name, OFMARKER)) {
1771                         ops->OFMarker = !strcmp(param->value, YES);
1772                         pr_debug("OFMarker:                     %s\n",
1773                                 param->value);
1774                 } else if (!strcmp(param->name, IFMARKER)) {
1775                         ops->IFMarker = !strcmp(param->value, YES);
1776                         pr_debug("IFMarker:                     %s\n",
1777                                 param->value);
1778                 } else if (!strcmp(param->name, OFMARKINT)) {
1779                         ops->OFMarkInt =
1780                                 simple_strtoul(param->value, &tmpptr, 0);
1781                         pr_debug("OFMarkInt:                    %s\n",
1782                                 param->value);
1783                 } else if (!strcmp(param->name, IFMARKINT)) {
1784                         ops->IFMarkInt =
1785                                 simple_strtoul(param->value, &tmpptr, 0);
1786                         pr_debug("IFMarkInt:                    %s\n",
1787                                 param->value);
1788                 }
1789         }
1790         pr_debug("----------------------------------------------------"
1791                         "--------------\n");
1792 }
1793
1794 void iscsi_set_session_parameters(
1795         struct iscsi_sess_ops *ops,
1796         struct iscsi_param_list *param_list,
1797         int leading)
1798 {
1799         char *tmpptr;
1800         struct iscsi_param *param;
1801
1802         pr_debug("----------------------------------------------------"
1803                         "--------------\n");
1804         list_for_each_entry(param, &param_list->param_list, p_list) {
1805                 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1806                         continue;
1807                 if (!strcmp(param->name, INITIATORNAME)) {
1808                         if (!param->value)
1809                                 continue;
1810                         if (leading)
1811                                 snprintf(ops->InitiatorName,
1812                                                 sizeof(ops->InitiatorName),
1813                                                 "%s", param->value);
1814                         pr_debug("InitiatorName:                %s\n",
1815                                 param->value);
1816                 } else if (!strcmp(param->name, INITIATORALIAS)) {
1817                         if (!param->value)
1818                                 continue;
1819                         snprintf(ops->InitiatorAlias,
1820                                                 sizeof(ops->InitiatorAlias),
1821                                                 "%s", param->value);
1822                         pr_debug("InitiatorAlias:               %s\n",
1823                                 param->value);
1824                 } else if (!strcmp(param->name, TARGETNAME)) {
1825                         if (!param->value)
1826                                 continue;
1827                         if (leading)
1828                                 snprintf(ops->TargetName,
1829                                                 sizeof(ops->TargetName),
1830                                                 "%s", param->value);
1831                         pr_debug("TargetName:                   %s\n",
1832                                 param->value);
1833                 } else if (!strcmp(param->name, TARGETALIAS)) {
1834                         if (!param->value)
1835                                 continue;
1836                         snprintf(ops->TargetAlias, sizeof(ops->TargetAlias),
1837                                         "%s", param->value);
1838                         pr_debug("TargetAlias:                  %s\n",
1839                                 param->value);
1840                 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
1841                         ops->TargetPortalGroupTag =
1842                                 simple_strtoul(param->value, &tmpptr, 0);
1843                         pr_debug("TargetPortalGroupTag:         %s\n",
1844                                 param->value);
1845                 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
1846                         ops->MaxConnections =
1847                                 simple_strtoul(param->value, &tmpptr, 0);
1848                         pr_debug("MaxConnections:               %s\n",
1849                                 param->value);
1850                 } else if (!strcmp(param->name, INITIALR2T)) {
1851                         ops->InitialR2T = !strcmp(param->value, YES);
1852                          pr_debug("InitialR2T:                   %s\n",
1853                                 param->value);
1854                 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
1855                         ops->ImmediateData = !strcmp(param->value, YES);
1856                         pr_debug("ImmediateData:                %s\n",
1857                                 param->value);
1858                 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
1859                         ops->MaxBurstLength =
1860                                 simple_strtoul(param->value, &tmpptr, 0);
1861                         pr_debug("MaxBurstLength:               %s\n",
1862                                 param->value);
1863                 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1864                         ops->FirstBurstLength =
1865                                 simple_strtoul(param->value, &tmpptr, 0);
1866                         pr_debug("FirstBurstLength:             %s\n",
1867                                 param->value);
1868                 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1869                         ops->DefaultTime2Wait =
1870                                 simple_strtoul(param->value, &tmpptr, 0);
1871                         pr_debug("DefaultTime2Wait:             %s\n",
1872                                 param->value);
1873                 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
1874                         ops->DefaultTime2Retain =
1875                                 simple_strtoul(param->value, &tmpptr, 0);
1876                         pr_debug("DefaultTime2Retain:           %s\n",
1877                                 param->value);
1878                 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
1879                         ops->MaxOutstandingR2T =
1880                                 simple_strtoul(param->value, &tmpptr, 0);
1881                         pr_debug("MaxOutstandingR2T:            %s\n",
1882                                 param->value);
1883                 } else if (!strcmp(param->name, DATAPDUINORDER)) {
1884                         ops->DataPDUInOrder = !strcmp(param->value, YES);
1885                         pr_debug("DataPDUInOrder:               %s\n",
1886                                 param->value);
1887                 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
1888                         ops->DataSequenceInOrder = !strcmp(param->value, YES);
1889                         pr_debug("DataSequenceInOrder:          %s\n",
1890                                 param->value);
1891                 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
1892                         ops->ErrorRecoveryLevel =
1893                                 simple_strtoul(param->value, &tmpptr, 0);
1894                         pr_debug("ErrorRecoveryLevel:           %s\n",
1895                                 param->value);
1896                 } else if (!strcmp(param->name, SESSIONTYPE)) {
1897                         ops->SessionType = !strcmp(param->value, DISCOVERY);
1898                         pr_debug("SessionType:                  %s\n",
1899                                 param->value);
1900                 }
1901         }
1902         pr_debug("----------------------------------------------------"
1903                         "--------------\n");
1904
1905 }