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