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