iscsi-target: Add iSCSI fabric support for target v4.1
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / target / iscsi / iscsi_target_parameters.c
CommitLineData
e48354ce
NB
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
27int 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
56int 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
90void 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
106void 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
136void 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
144static 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;
217out:
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 */
228int 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;
432out:
433 iscsi_release_param_list(pl);
434 return -1;
435}
436
437int 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
502int 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
543int 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
615err_out:
616 iscsi_release_param_list(param_list);
617 return -1;
618}
619
620static 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
631void 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
652struct 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
672int 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
688int 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
706static 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
736static 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
758static 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
799static 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
810static 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
885static 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
971static 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 */
1011static 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
1034static 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
1084out:
1085 return proposer_values;
1086}
1087
1088static 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
1192static 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
1261static 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
1342static 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
1376static 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
1436static 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
1553int 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
1629int 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
1687int 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
1707int 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
1742void 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
1794void 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}