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 
iscsi_login_rx_data(struct iscsi_conn * conn,char * buf,int length)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 
iscsi_login_tx_data(struct iscsi_conn * conn,char * pdu_buf,char * text_buf,int text_length)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 
iscsi_dump_conn_ops(struct iscsi_conn_ops * conn_ops)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 
iscsi_dump_sess_ops(struct iscsi_sess_ops * sess_ops)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 
iscsi_print_params(struct iscsi_param_list * param_list)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 
iscsi_set_default_param(struct iscsi_param_list * param_list,char * name,char * value,u8 phase,u8 scope,u8 sender,u16 type_range,u8 use)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 */
iscsi_create_default_params(struct iscsi_param_list ** param_list_ptr)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 
iscsi_set_keys_to_negotiate(int sessiontype,struct iscsi_param_list * param_list)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 
iscsi_set_keys_irrelevant_for_discovery(struct iscsi_param_list * param_list)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 
iscsi_copy_param_list(struct iscsi_param_list ** dst_param_list,struct iscsi_param_list * src_param_list,int leading)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 
iscsi_release_extra_responses(struct iscsi_param_list * param_list)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 
iscsi_release_param_list(struct iscsi_param_list * param_list)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 
iscsi_find_param_from_key(char * key,struct iscsi_param_list * param_list)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 
iscsi_extract_key_value(char * textbuf,char ** key,char ** value)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 
iscsi_update_param_value(struct iscsi_param * param,char * value)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 
iscsi_add_notunderstood_response(char * key,char * value,struct iscsi_param_list * param_list)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 	strlcpy(extra_response->key, key, sizeof(extra_response->key));
717 	strlcpy(extra_response->value, NOTUNDERSTOOD,
718 		sizeof(extra_response->value));
719 
720 	list_add_tail(&extra_response->er_list,
721 			&param_list->extra_response_list);
722 	return 0;
723 }
724 
iscsi_check_for_auth_key(char * key)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 
iscsi_check_proposer_for_optional_reply(struct iscsi_param * param)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 
iscsi_check_boolean_value(struct iscsi_param * param,char * value)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 
iscsi_check_numerical_value(struct iscsi_param * param,char * value_ptr)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 
iscsi_check_numerical_range_value(struct iscsi_param * param,char * value)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;
878 	u32 left_val, right_val, local_left_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, NULL, 0);
907 	right_val = simple_strtoul(right_val_ptr, NULL, 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, NULL, 0);
932 	*tilde_ptr = '~';
933 
934 	if (param->set_param) {
935 		if ((left_val < local_left_val) ||
936 		    (right_val < local_left_val)) {
937 			pr_err("Passed value range \"%u~%u\" is below"
938 				" minimum left value \"%u\" for key \"%s\","
939 				" rejecting.\n", left_val, right_val,
940 				local_left_val, param->name);
941 			return -1;
942 		}
943 	} else {
944 		if ((left_val < local_left_val) &&
945 		    (right_val < local_left_val)) {
946 			pr_err("Received value range \"%u~%u\" is"
947 				" below minimum left value \"%u\" for key"
948 				" \"%s\", rejecting.\n", left_val, right_val,
949 				local_left_val, param->name);
950 			SET_PSTATE_REJECT(param);
951 			if (iscsi_update_param_value(param, REJECT) < 0)
952 				return -1;
953 		}
954 	}
955 
956 	return 0;
957 }
958 
iscsi_check_string_or_list_value(struct iscsi_param * param,char * value)959 static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
960 {
961 	if (IS_PSTATE_PROPOSER(param))
962 		return 0;
963 
964 	if (IS_TYPERANGE_AUTH_PARAM(param)) {
965 		if (strcmp(value, KRB5) && strcmp(value, SPKM1) &&
966 		    strcmp(value, SPKM2) && strcmp(value, SRP) &&
967 		    strcmp(value, CHAP) && strcmp(value, NONE)) {
968 			pr_err("Illegal value for \"%s\", must be"
969 				" \"%s\", \"%s\", \"%s\", \"%s\", \"%s\""
970 				" or \"%s\".\n", param->name, KRB5,
971 					SPKM1, SPKM2, SRP, CHAP, NONE);
972 			return -1;
973 		}
974 	}
975 	if (IS_TYPERANGE_DIGEST_PARAM(param)) {
976 		if (strcmp(value, CRC32C) && strcmp(value, NONE)) {
977 			pr_err("Illegal value for \"%s\", must be"
978 				" \"%s\" or \"%s\".\n", param->name,
979 					CRC32C, NONE);
980 			return -1;
981 		}
982 	}
983 	if (IS_TYPERANGE_SESSIONTYPE(param)) {
984 		if (strcmp(value, DISCOVERY) && strcmp(value, NORMAL)) {
985 			pr_err("Illegal value for \"%s\", must be"
986 				" \"%s\" or \"%s\".\n", param->name,
987 					DISCOVERY, NORMAL);
988 			return -1;
989 		}
990 	}
991 
992 	return 0;
993 }
994 
995 /*
996  *	This function is used to pick a value range number,  currently just
997  *	returns the lesser of both right values.
998  */
iscsi_get_value_from_number_range(struct iscsi_param * param,char * value)999 static char *iscsi_get_value_from_number_range(
1000 	struct iscsi_param *param,
1001 	char *value)
1002 {
1003 	char *end_ptr, *tilde_ptr1 = NULL, *tilde_ptr2 = NULL;
1004 	u32 acceptor_right_value, proposer_right_value;
1005 
1006 	tilde_ptr1 = strchr(value, '~');
1007 	if (!tilde_ptr1)
1008 		return NULL;
1009 	*tilde_ptr1++ = '\0';
1010 	proposer_right_value = simple_strtoul(tilde_ptr1, &end_ptr, 0);
1011 
1012 	tilde_ptr2 = strchr(param->value, '~');
1013 	if (!tilde_ptr2)
1014 		return NULL;
1015 	*tilde_ptr2++ = '\0';
1016 	acceptor_right_value = simple_strtoul(tilde_ptr2, &end_ptr, 0);
1017 
1018 	return (acceptor_right_value >= proposer_right_value) ?
1019 		tilde_ptr1 : tilde_ptr2;
1020 }
1021 
iscsi_check_valuelist_for_support(struct iscsi_param * param,char * value)1022 static char *iscsi_check_valuelist_for_support(
1023 	struct iscsi_param *param,
1024 	char *value)
1025 {
1026 	char *tmp1 = NULL, *tmp2 = NULL;
1027 	char *acceptor_values = NULL, *proposer_values = NULL;
1028 
1029 	acceptor_values = param->value;
1030 	proposer_values = value;
1031 
1032 	do {
1033 		if (!proposer_values)
1034 			return NULL;
1035 		tmp1 = strchr(proposer_values, ',');
1036 		if (tmp1)
1037 			*tmp1 = '\0';
1038 		acceptor_values = param->value;
1039 		do {
1040 			if (!acceptor_values) {
1041 				if (tmp1)
1042 					*tmp1 = ',';
1043 				return NULL;
1044 			}
1045 			tmp2 = strchr(acceptor_values, ',');
1046 			if (tmp2)
1047 				*tmp2 = '\0';
1048 			if (!acceptor_values || !proposer_values) {
1049 				if (tmp1)
1050 					*tmp1 = ',';
1051 				if (tmp2)
1052 					*tmp2 = ',';
1053 				return NULL;
1054 			}
1055 			if (!strcmp(acceptor_values, proposer_values)) {
1056 				if (tmp2)
1057 					*tmp2 = ',';
1058 				goto out;
1059 			}
1060 			if (tmp2)
1061 				*tmp2++ = ',';
1062 
1063 			acceptor_values = tmp2;
1064 			if (!acceptor_values)
1065 				break;
1066 		} while (acceptor_values);
1067 		if (tmp1)
1068 			*tmp1++ = ',';
1069 		proposer_values = tmp1;
1070 	} while (proposer_values);
1071 
1072 out:
1073 	return proposer_values;
1074 }
1075 
iscsi_check_acceptor_state(struct iscsi_param * param,char * value)1076 static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value)
1077 {
1078 	u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
1079 	char *negoitated_value = NULL;
1080 
1081 	if (IS_PSTATE_ACCEPTOR(param)) {
1082 		pr_err("Received key \"%s\" twice, protocol error.\n",
1083 				param->name);
1084 		return -1;
1085 	}
1086 
1087 	if (IS_PSTATE_REJECT(param))
1088 		return 0;
1089 
1090 	if (IS_TYPE_BOOL_AND(param)) {
1091 		if (!strcmp(value, YES))
1092 			proposer_boolean_value = 1;
1093 		if (!strcmp(param->value, YES))
1094 			acceptor_boolean_value = 1;
1095 		if (acceptor_boolean_value && proposer_boolean_value)
1096 			do {} while (0);
1097 		else {
1098 			if (iscsi_update_param_value(param, NO) < 0)
1099 				return -1;
1100 			if (!proposer_boolean_value)
1101 				SET_PSTATE_REPLY_OPTIONAL(param);
1102 		}
1103 	} else if (IS_TYPE_BOOL_OR(param)) {
1104 		if (!strcmp(value, YES))
1105 			proposer_boolean_value = 1;
1106 		if (!strcmp(param->value, YES))
1107 			acceptor_boolean_value = 1;
1108 		if (acceptor_boolean_value || proposer_boolean_value) {
1109 			if (iscsi_update_param_value(param, YES) < 0)
1110 				return -1;
1111 			if (proposer_boolean_value)
1112 				SET_PSTATE_REPLY_OPTIONAL(param);
1113 		}
1114 	} else if (IS_TYPE_NUMBER(param)) {
1115 		char *tmpptr, buf[10];
1116 		u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
1117 		u32 proposer_value = simple_strtoul(value, &tmpptr, 0);
1118 
1119 		memset(buf, 0, 10);
1120 
1121 		if (!strcmp(param->name, MAXCONNECTIONS) ||
1122 		    !strcmp(param->name, MAXBURSTLENGTH) ||
1123 		    !strcmp(param->name, FIRSTBURSTLENGTH) ||
1124 		    !strcmp(param->name, MAXOUTSTANDINGR2T) ||
1125 		    !strcmp(param->name, DEFAULTTIME2RETAIN) ||
1126 		    !strcmp(param->name, ERRORRECOVERYLEVEL)) {
1127 			if (proposer_value > acceptor_value) {
1128 				sprintf(buf, "%u", acceptor_value);
1129 				if (iscsi_update_param_value(param,
1130 						&buf[0]) < 0)
1131 					return -1;
1132 			} else {
1133 				if (iscsi_update_param_value(param, value) < 0)
1134 					return -1;
1135 			}
1136 		} else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1137 			if (acceptor_value > proposer_value) {
1138 				sprintf(buf, "%u", acceptor_value);
1139 				if (iscsi_update_param_value(param,
1140 						&buf[0]) < 0)
1141 					return -1;
1142 			} else {
1143 				if (iscsi_update_param_value(param, value) < 0)
1144 					return -1;
1145 			}
1146 		} else {
1147 			if (iscsi_update_param_value(param, value) < 0)
1148 				return -1;
1149 		}
1150 
1151 		if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
1152 			SET_PSTATE_REPLY_OPTIONAL(param);
1153 	} else if (IS_TYPE_NUMBER_RANGE(param)) {
1154 		negoitated_value = iscsi_get_value_from_number_range(
1155 					param, value);
1156 		if (!negoitated_value)
1157 			return -1;
1158 		if (iscsi_update_param_value(param, negoitated_value) < 0)
1159 			return -1;
1160 	} else if (IS_TYPE_VALUE_LIST(param)) {
1161 		negoitated_value = iscsi_check_valuelist_for_support(
1162 					param, value);
1163 		if (!negoitated_value) {
1164 			pr_err("Proposer's value list \"%s\" contains"
1165 				" no valid values from Acceptor's value list"
1166 				" \"%s\".\n", value, param->value);
1167 			return -1;
1168 		}
1169 		if (iscsi_update_param_value(param, negoitated_value) < 0)
1170 			return -1;
1171 	} else if (IS_PHASE_DECLARATIVE(param)) {
1172 		if (iscsi_update_param_value(param, value) < 0)
1173 			return -1;
1174 		SET_PSTATE_REPLY_OPTIONAL(param);
1175 	}
1176 
1177 	return 0;
1178 }
1179 
iscsi_check_proposer_state(struct iscsi_param * param,char * value)1180 static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
1181 {
1182 	if (IS_PSTATE_RESPONSE_GOT(param)) {
1183 		pr_err("Received key \"%s\" twice, protocol error.\n",
1184 				param->name);
1185 		return -1;
1186 	}
1187 
1188 	if (IS_TYPE_NUMBER_RANGE(param)) {
1189 		u32 left_val = 0, right_val = 0, recieved_value = 0;
1190 		char *left_val_ptr = NULL, *right_val_ptr = NULL;
1191 		char *tilde_ptr = NULL;
1192 
1193 		if (!strcmp(value, IRRELEVANT) || !strcmp(value, REJECT)) {
1194 			if (iscsi_update_param_value(param, value) < 0)
1195 				return -1;
1196 			return 0;
1197 		}
1198 
1199 		tilde_ptr = strchr(value, '~');
1200 		if (tilde_ptr) {
1201 			pr_err("Illegal \"~\" in response for \"%s\".\n",
1202 					param->name);
1203 			return -1;
1204 		}
1205 		tilde_ptr = strchr(param->value, '~');
1206 		if (!tilde_ptr) {
1207 			pr_err("Unable to locate numerical range"
1208 				" indicator \"~\" for \"%s\".\n", param->name);
1209 			return -1;
1210 		}
1211 		*tilde_ptr = '\0';
1212 
1213 		left_val_ptr = param->value;
1214 		right_val_ptr = param->value + strlen(left_val_ptr) + 1;
1215 		left_val = simple_strtoul(left_val_ptr, NULL, 0);
1216 		right_val = simple_strtoul(right_val_ptr, NULL, 0);
1217 		recieved_value = simple_strtoul(value, NULL, 0);
1218 
1219 		*tilde_ptr = '~';
1220 
1221 		if ((recieved_value < left_val) ||
1222 		    (recieved_value > right_val)) {
1223 			pr_err("Illegal response \"%s=%u\", value must"
1224 				" be between %u and %u.\n", param->name,
1225 				recieved_value, left_val, right_val);
1226 			return -1;
1227 		}
1228 	} else if (IS_TYPE_VALUE_LIST(param)) {
1229 		char *comma_ptr = NULL, *tmp_ptr = NULL;
1230 
1231 		comma_ptr = strchr(value, ',');
1232 		if (comma_ptr) {
1233 			pr_err("Illegal \",\" in response for \"%s\".\n",
1234 					param->name);
1235 			return -1;
1236 		}
1237 
1238 		tmp_ptr = iscsi_check_valuelist_for_support(param, value);
1239 		if (!tmp_ptr)
1240 			return -1;
1241 	}
1242 
1243 	if (iscsi_update_param_value(param, value) < 0)
1244 		return -1;
1245 
1246 	return 0;
1247 }
1248 
iscsi_check_value(struct iscsi_param * param,char * value)1249 static int iscsi_check_value(struct iscsi_param *param, char *value)
1250 {
1251 	char *comma_ptr = NULL;
1252 
1253 	if (!strcmp(value, REJECT)) {
1254 		if (!strcmp(param->name, IFMARKINT) ||
1255 		    !strcmp(param->name, OFMARKINT)) {
1256 			/*
1257 			 * Reject is not fatal for [I,O]FMarkInt,  and causes
1258 			 * [I,O]FMarker to be reset to No. (See iSCSI v20 A.3.2)
1259 			 */
1260 			SET_PSTATE_REJECT(param);
1261 			return 0;
1262 		}
1263 		pr_err("Received %s=%s\n", param->name, value);
1264 		return -1;
1265 	}
1266 	if (!strcmp(value, IRRELEVANT)) {
1267 		pr_debug("Received %s=%s\n", param->name, value);
1268 		SET_PSTATE_IRRELEVANT(param);
1269 		return 0;
1270 	}
1271 	if (!strcmp(value, NOTUNDERSTOOD)) {
1272 		if (!IS_PSTATE_PROPOSER(param)) {
1273 			pr_err("Received illegal offer %s=%s\n",
1274 				param->name, value);
1275 			return -1;
1276 		}
1277 
1278 /* #warning FIXME: Add check for X-ExtensionKey here */
1279 		pr_err("Standard iSCSI key \"%s\" cannot be answered"
1280 			" with \"%s\", protocol error.\n", param->name, value);
1281 		return -1;
1282 	}
1283 
1284 	do {
1285 		comma_ptr = NULL;
1286 		comma_ptr = strchr(value, ',');
1287 
1288 		if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
1289 			pr_err("Detected value seperator \",\", but"
1290 				" key \"%s\" does not allow a value list,"
1291 				" protocol error.\n", param->name);
1292 			return -1;
1293 		}
1294 		if (comma_ptr)
1295 			*comma_ptr = '\0';
1296 
1297 		if (strlen(value) > VALUE_MAXLEN) {
1298 			pr_err("Value for key \"%s\" exceeds %d,"
1299 				" protocol error.\n", param->name,
1300 				VALUE_MAXLEN);
1301 			return -1;
1302 		}
1303 
1304 		if (IS_TYPE_BOOL_AND(param) || IS_TYPE_BOOL_OR(param)) {
1305 			if (iscsi_check_boolean_value(param, value) < 0)
1306 				return -1;
1307 		} else if (IS_TYPE_NUMBER(param)) {
1308 			if (iscsi_check_numerical_value(param, value) < 0)
1309 				return -1;
1310 		} else if (IS_TYPE_NUMBER_RANGE(param)) {
1311 			if (iscsi_check_numerical_range_value(param, value) < 0)
1312 				return -1;
1313 		} else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
1314 			if (iscsi_check_string_or_list_value(param, value) < 0)
1315 				return -1;
1316 		} else {
1317 			pr_err("Huh? 0x%02x\n", param->type);
1318 			return -1;
1319 		}
1320 
1321 		if (comma_ptr)
1322 			*comma_ptr++ = ',';
1323 
1324 		value = comma_ptr;
1325 	} while (value);
1326 
1327 	return 0;
1328 }
1329 
__iscsi_check_key(char * key,int sender,struct iscsi_param_list * param_list)1330 static struct iscsi_param *__iscsi_check_key(
1331 	char *key,
1332 	int sender,
1333 	struct iscsi_param_list *param_list)
1334 {
1335 	struct iscsi_param *param;
1336 
1337 	if (strlen(key) > KEY_MAXLEN) {
1338 		pr_err("Length of key name \"%s\" exceeds %d.\n",
1339 			key, KEY_MAXLEN);
1340 		return NULL;
1341 	}
1342 
1343 	param = iscsi_find_param_from_key(key, param_list);
1344 	if (!param)
1345 		return NULL;
1346 
1347 	if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1348 		pr_err("Key \"%s\" may not be sent to %s,"
1349 			" protocol error.\n", param->name,
1350 			(sender & SENDER_RECEIVER) ? "target" : "initiator");
1351 		return NULL;
1352 	}
1353 
1354 	if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1355 		pr_err("Key \"%s\" may not be sent to %s,"
1356 			" protocol error.\n", param->name,
1357 			(sender & SENDER_RECEIVER) ? "initiator" : "target");
1358 		return NULL;
1359 	}
1360 
1361 	return param;
1362 }
1363 
iscsi_check_key(char * key,int phase,int sender,struct iscsi_param_list * param_list)1364 static struct iscsi_param *iscsi_check_key(
1365 	char *key,
1366 	int phase,
1367 	int sender,
1368 	struct iscsi_param_list *param_list)
1369 {
1370 	struct iscsi_param *param;
1371 	/*
1372 	 * Key name length must not exceed 63 bytes. (See iSCSI v20 5.1)
1373 	 */
1374 	if (strlen(key) > KEY_MAXLEN) {
1375 		pr_err("Length of key name \"%s\" exceeds %d.\n",
1376 			key, KEY_MAXLEN);
1377 		return NULL;
1378 	}
1379 
1380 	param = iscsi_find_param_from_key(key, param_list);
1381 	if (!param)
1382 		return NULL;
1383 
1384 	if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1385 		pr_err("Key \"%s\" may not be sent to %s,"
1386 			" protocol error.\n", param->name,
1387 			(sender & SENDER_RECEIVER) ? "target" : "initiator");
1388 		return NULL;
1389 	}
1390 	if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1391 		pr_err("Key \"%s\" may not be sent to %s,"
1392 				" protocol error.\n", param->name,
1393 			(sender & SENDER_RECEIVER) ? "initiator" : "target");
1394 		return NULL;
1395 	}
1396 
1397 	if (IS_PSTATE_ACCEPTOR(param)) {
1398 		pr_err("Key \"%s\" received twice, protocol error.\n",
1399 				key);
1400 		return NULL;
1401 	}
1402 
1403 	if (!phase)
1404 		return param;
1405 
1406 	if (!(param->phase & phase)) {
1407 		pr_err("Key \"%s\" may not be negotiated during ",
1408 				param->name);
1409 		switch (phase) {
1410 		case PHASE_SECURITY:
1411 			pr_debug("Security phase.\n");
1412 			break;
1413 		case PHASE_OPERATIONAL:
1414 			pr_debug("Operational phase.\n");
1415 		default:
1416 			pr_debug("Unknown phase.\n");
1417 		}
1418 		return NULL;
1419 	}
1420 
1421 	return param;
1422 }
1423 
iscsi_enforce_integrity_rules(u8 phase,struct iscsi_param_list * param_list)1424 static int iscsi_enforce_integrity_rules(
1425 	u8 phase,
1426 	struct iscsi_param_list *param_list)
1427 {
1428 	char *tmpptr;
1429 	u8 DataSequenceInOrder = 0;
1430 	u8 ErrorRecoveryLevel = 0, SessionType = 0;
1431 	u8 IFMarker = 0, OFMarker = 0;
1432 	u8 IFMarkInt_Reject = 1, OFMarkInt_Reject = 1;
1433 	u32 FirstBurstLength = 0, MaxBurstLength = 0;
1434 	struct iscsi_param *param = NULL;
1435 
1436 	list_for_each_entry(param, &param_list->param_list, p_list) {
1437 		if (!(param->phase & phase))
1438 			continue;
1439 		if (!strcmp(param->name, SESSIONTYPE))
1440 			if (!strcmp(param->value, NORMAL))
1441 				SessionType = 1;
1442 		if (!strcmp(param->name, ERRORRECOVERYLEVEL))
1443 			ErrorRecoveryLevel = simple_strtoul(param->value,
1444 					&tmpptr, 0);
1445 		if (!strcmp(param->name, DATASEQUENCEINORDER))
1446 			if (!strcmp(param->value, YES))
1447 				DataSequenceInOrder = 1;
1448 		if (!strcmp(param->name, MAXBURSTLENGTH))
1449 			MaxBurstLength = simple_strtoul(param->value,
1450 					&tmpptr, 0);
1451 		if (!strcmp(param->name, IFMARKER))
1452 			if (!strcmp(param->value, YES))
1453 				IFMarker = 1;
1454 		if (!strcmp(param->name, OFMARKER))
1455 			if (!strcmp(param->value, YES))
1456 				OFMarker = 1;
1457 		if (!strcmp(param->name, IFMARKINT))
1458 			if (!strcmp(param->value, REJECT))
1459 				IFMarkInt_Reject = 1;
1460 		if (!strcmp(param->name, OFMARKINT))
1461 			if (!strcmp(param->value, REJECT))
1462 				OFMarkInt_Reject = 1;
1463 	}
1464 
1465 	list_for_each_entry(param, &param_list->param_list, p_list) {
1466 		if (!(param->phase & phase))
1467 			continue;
1468 		if (!SessionType && (!IS_PSTATE_ACCEPTOR(param) &&
1469 		     (strcmp(param->name, IFMARKER) &&
1470 		      strcmp(param->name, OFMARKER) &&
1471 		      strcmp(param->name, IFMARKINT) &&
1472 		      strcmp(param->name, OFMARKINT))))
1473 			continue;
1474 		if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
1475 		    DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
1476 			if (strcmp(param->value, "1")) {
1477 				if (iscsi_update_param_value(param, "1") < 0)
1478 					return -1;
1479 				pr_debug("Reset \"%s\" to \"%s\".\n",
1480 					param->name, param->value);
1481 			}
1482 		}
1483 		if (!strcmp(param->name, MAXCONNECTIONS) && !SessionType) {
1484 			if (strcmp(param->value, "1")) {
1485 				if (iscsi_update_param_value(param, "1") < 0)
1486 					return -1;
1487 				pr_debug("Reset \"%s\" to \"%s\".\n",
1488 					param->name, param->value);
1489 			}
1490 		}
1491 		if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1492 			FirstBurstLength = simple_strtoul(param->value,
1493 					&tmpptr, 0);
1494 			if (FirstBurstLength > MaxBurstLength) {
1495 				char tmpbuf[10];
1496 				memset(tmpbuf, 0, 10);
1497 				sprintf(tmpbuf, "%u", MaxBurstLength);
1498 				if (iscsi_update_param_value(param, tmpbuf))
1499 					return -1;
1500 				pr_debug("Reset \"%s\" to \"%s\".\n",
1501 					param->name, param->value);
1502 			}
1503 		}
1504 		if (!strcmp(param->name, IFMARKER) && IFMarkInt_Reject) {
1505 			if (iscsi_update_param_value(param, NO) < 0)
1506 				return -1;
1507 			IFMarker = 0;
1508 			pr_debug("Reset \"%s\" to \"%s\".\n",
1509 					param->name, param->value);
1510 		}
1511 		if (!strcmp(param->name, OFMARKER) && OFMarkInt_Reject) {
1512 			if (iscsi_update_param_value(param, NO) < 0)
1513 				return -1;
1514 			OFMarker = 0;
1515 			pr_debug("Reset \"%s\" to \"%s\".\n",
1516 					 param->name, param->value);
1517 		}
1518 		if (!strcmp(param->name, IFMARKINT) && !IFMarker) {
1519 			if (!strcmp(param->value, REJECT))
1520 				continue;
1521 			param->state &= ~PSTATE_NEGOTIATE;
1522 			if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1523 				return -1;
1524 			pr_debug("Reset \"%s\" to \"%s\".\n",
1525 					param->name, param->value);
1526 		}
1527 		if (!strcmp(param->name, OFMARKINT) && !OFMarker) {
1528 			if (!strcmp(param->value, REJECT))
1529 				continue;
1530 			param->state &= ~PSTATE_NEGOTIATE;
1531 			if (iscsi_update_param_value(param, IRRELEVANT) < 0)
1532 				return -1;
1533 			pr_debug("Reset \"%s\" to \"%s\".\n",
1534 					param->name, param->value);
1535 		}
1536 	}
1537 
1538 	return 0;
1539 }
1540 
iscsi_decode_text_input(u8 phase,u8 sender,char * textbuf,u32 length,struct iscsi_param_list * param_list)1541 int iscsi_decode_text_input(
1542 	u8 phase,
1543 	u8 sender,
1544 	char *textbuf,
1545 	u32 length,
1546 	struct iscsi_param_list *param_list)
1547 {
1548 	char *tmpbuf, *start = NULL, *end = NULL;
1549 
1550 	tmpbuf = kzalloc(length + 1, GFP_KERNEL);
1551 	if (!tmpbuf) {
1552 		pr_err("Unable to allocate memory for tmpbuf.\n");
1553 		return -1;
1554 	}
1555 
1556 	memcpy(tmpbuf, textbuf, length);
1557 	tmpbuf[length] = '\0';
1558 	start = tmpbuf;
1559 	end = (start + length);
1560 
1561 	while (start < end) {
1562 		char *key, *value;
1563 		struct iscsi_param *param;
1564 
1565 		if (iscsi_extract_key_value(start, &key, &value) < 0) {
1566 			kfree(tmpbuf);
1567 			return -1;
1568 		}
1569 
1570 		pr_debug("Got key: %s=%s\n", key, value);
1571 
1572 		if (phase & PHASE_SECURITY) {
1573 			if (iscsi_check_for_auth_key(key) > 0) {
1574 				kfree(tmpbuf);
1575 				return 1;
1576 			}
1577 		}
1578 
1579 		param = iscsi_check_key(key, phase, sender, param_list);
1580 		if (!param) {
1581 			if (iscsi_add_notunderstood_response(key,
1582 					value, param_list) < 0) {
1583 				kfree(tmpbuf);
1584 				return -1;
1585 			}
1586 			start += strlen(key) + strlen(value) + 2;
1587 			continue;
1588 		}
1589 		if (iscsi_check_value(param, value) < 0) {
1590 			kfree(tmpbuf);
1591 			return -1;
1592 		}
1593 
1594 		start += strlen(key) + strlen(value) + 2;
1595 
1596 		if (IS_PSTATE_PROPOSER(param)) {
1597 			if (iscsi_check_proposer_state(param, value) < 0) {
1598 				kfree(tmpbuf);
1599 				return -1;
1600 			}
1601 			SET_PSTATE_RESPONSE_GOT(param);
1602 		} else {
1603 			if (iscsi_check_acceptor_state(param, value) < 0) {
1604 				kfree(tmpbuf);
1605 				return -1;
1606 			}
1607 			SET_PSTATE_ACCEPTOR(param);
1608 		}
1609 	}
1610 
1611 	kfree(tmpbuf);
1612 	return 0;
1613 }
1614 
iscsi_encode_text_output(u8 phase,u8 sender,char * textbuf,u32 * length,struct iscsi_param_list * param_list)1615 int iscsi_encode_text_output(
1616 	u8 phase,
1617 	u8 sender,
1618 	char *textbuf,
1619 	u32 *length,
1620 	struct iscsi_param_list *param_list)
1621 {
1622 	char *output_buf = NULL;
1623 	struct iscsi_extra_response *er;
1624 	struct iscsi_param *param;
1625 
1626 	output_buf = textbuf + *length;
1627 
1628 	if (iscsi_enforce_integrity_rules(phase, param_list) < 0)
1629 		return -1;
1630 
1631 	list_for_each_entry(param, &param_list->param_list, p_list) {
1632 		if (!(param->sender & sender))
1633 			continue;
1634 		if (IS_PSTATE_ACCEPTOR(param) &&
1635 		    !IS_PSTATE_RESPONSE_SENT(param) &&
1636 		    !IS_PSTATE_REPLY_OPTIONAL(param) &&
1637 		    (param->phase & phase)) {
1638 			*length += sprintf(output_buf, "%s=%s",
1639 				param->name, param->value);
1640 			*length += 1;
1641 			output_buf = textbuf + *length;
1642 			SET_PSTATE_RESPONSE_SENT(param);
1643 			pr_debug("Sending key: %s=%s\n",
1644 				param->name, param->value);
1645 			continue;
1646 		}
1647 		if (IS_PSTATE_NEGOTIATE(param) &&
1648 		    !IS_PSTATE_ACCEPTOR(param) &&
1649 		    !IS_PSTATE_PROPOSER(param) &&
1650 		    (param->phase & phase)) {
1651 			*length += sprintf(output_buf, "%s=%s",
1652 				param->name, param->value);
1653 			*length += 1;
1654 			output_buf = textbuf + *length;
1655 			SET_PSTATE_PROPOSER(param);
1656 			iscsi_check_proposer_for_optional_reply(param);
1657 			pr_debug("Sending key: %s=%s\n",
1658 				param->name, param->value);
1659 		}
1660 	}
1661 
1662 	list_for_each_entry(er, &param_list->extra_response_list, er_list) {
1663 		*length += sprintf(output_buf, "%s=%s", er->key, er->value);
1664 		*length += 1;
1665 		output_buf = textbuf + *length;
1666 		pr_debug("Sending key: %s=%s\n", er->key, er->value);
1667 	}
1668 	iscsi_release_extra_responses(param_list);
1669 
1670 	return 0;
1671 }
1672 
iscsi_check_negotiated_keys(struct iscsi_param_list * param_list)1673 int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list)
1674 {
1675 	int ret = 0;
1676 	struct iscsi_param *param;
1677 
1678 	list_for_each_entry(param, &param_list->param_list, p_list) {
1679 		if (IS_PSTATE_NEGOTIATE(param) &&
1680 		    IS_PSTATE_PROPOSER(param) &&
1681 		    !IS_PSTATE_RESPONSE_GOT(param) &&
1682 		    !IS_PSTATE_REPLY_OPTIONAL(param) &&
1683 		    !IS_PHASE_DECLARATIVE(param)) {
1684 			pr_err("No response for proposed key \"%s\".\n",
1685 					param->name);
1686 			ret = -1;
1687 		}
1688 	}
1689 
1690 	return ret;
1691 }
1692 
iscsi_change_param_value(char * keyvalue,struct iscsi_param_list * param_list,int check_key)1693 int iscsi_change_param_value(
1694 	char *keyvalue,
1695 	struct iscsi_param_list *param_list,
1696 	int check_key)
1697 {
1698 	char *key = NULL, *value = NULL;
1699 	struct iscsi_param *param;
1700 	int sender = 0;
1701 
1702 	if (iscsi_extract_key_value(keyvalue, &key, &value) < 0)
1703 		return -1;
1704 
1705 	if (!check_key) {
1706 		param = __iscsi_check_key(keyvalue, sender, param_list);
1707 		if (!param)
1708 			return -1;
1709 	} else {
1710 		param = iscsi_check_key(keyvalue, 0, sender, param_list);
1711 		if (!param)
1712 			return -1;
1713 
1714 		param->set_param = 1;
1715 		if (iscsi_check_value(param, value) < 0) {
1716 			param->set_param = 0;
1717 			return -1;
1718 		}
1719 		param->set_param = 0;
1720 	}
1721 
1722 	if (iscsi_update_param_value(param, value) < 0)
1723 		return -1;
1724 
1725 	return 0;
1726 }
1727 
iscsi_set_connection_parameters(struct iscsi_conn_ops * ops,struct iscsi_param_list * param_list)1728 void iscsi_set_connection_parameters(
1729 	struct iscsi_conn_ops *ops,
1730 	struct iscsi_param_list *param_list)
1731 {
1732 	char *tmpptr;
1733 	struct iscsi_param *param;
1734 
1735 	pr_debug("---------------------------------------------------"
1736 			"---------------\n");
1737 	list_for_each_entry(param, &param_list->param_list, p_list) {
1738 		if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1739 			continue;
1740 		if (!strcmp(param->name, AUTHMETHOD)) {
1741 			pr_debug("AuthMethod:                   %s\n",
1742 				param->value);
1743 		} else if (!strcmp(param->name, HEADERDIGEST)) {
1744 			ops->HeaderDigest = !strcmp(param->value, CRC32C);
1745 			pr_debug("HeaderDigest:                 %s\n",
1746 				param->value);
1747 		} else if (!strcmp(param->name, DATADIGEST)) {
1748 			ops->DataDigest = !strcmp(param->value, CRC32C);
1749 			pr_debug("DataDigest:                   %s\n",
1750 				param->value);
1751 		} else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1752 			ops->MaxRecvDataSegmentLength =
1753 				simple_strtoul(param->value, &tmpptr, 0);
1754 			pr_debug("MaxRecvDataSegmentLength:     %s\n",
1755 				param->value);
1756 		} else if (!strcmp(param->name, OFMARKER)) {
1757 			ops->OFMarker = !strcmp(param->value, YES);
1758 			pr_debug("OFMarker:                     %s\n",
1759 				param->value);
1760 		} else if (!strcmp(param->name, IFMARKER)) {
1761 			ops->IFMarker = !strcmp(param->value, YES);
1762 			pr_debug("IFMarker:                     %s\n",
1763 				param->value);
1764 		} else if (!strcmp(param->name, OFMARKINT)) {
1765 			ops->OFMarkInt =
1766 				simple_strtoul(param->value, &tmpptr, 0);
1767 			pr_debug("OFMarkInt:                    %s\n",
1768 				param->value);
1769 		} else if (!strcmp(param->name, IFMARKINT)) {
1770 			ops->IFMarkInt =
1771 				simple_strtoul(param->value, &tmpptr, 0);
1772 			pr_debug("IFMarkInt:                    %s\n",
1773 				param->value);
1774 		}
1775 	}
1776 	pr_debug("----------------------------------------------------"
1777 			"--------------\n");
1778 }
1779 
iscsi_set_session_parameters(struct iscsi_sess_ops * ops,struct iscsi_param_list * param_list,int leading)1780 void iscsi_set_session_parameters(
1781 	struct iscsi_sess_ops *ops,
1782 	struct iscsi_param_list *param_list,
1783 	int leading)
1784 {
1785 	char *tmpptr;
1786 	struct iscsi_param *param;
1787 
1788 	pr_debug("----------------------------------------------------"
1789 			"--------------\n");
1790 	list_for_each_entry(param, &param_list->param_list, p_list) {
1791 		if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1792 			continue;
1793 		if (!strcmp(param->name, INITIATORNAME)) {
1794 			if (!param->value)
1795 				continue;
1796 			if (leading)
1797 				snprintf(ops->InitiatorName,
1798 						sizeof(ops->InitiatorName),
1799 						"%s", param->value);
1800 			pr_debug("InitiatorName:                %s\n",
1801 				param->value);
1802 		} else if (!strcmp(param->name, INITIATORALIAS)) {
1803 			if (!param->value)
1804 				continue;
1805 			snprintf(ops->InitiatorAlias,
1806 						sizeof(ops->InitiatorAlias),
1807 						"%s", param->value);
1808 			pr_debug("InitiatorAlias:               %s\n",
1809 				param->value);
1810 		} else if (!strcmp(param->name, TARGETNAME)) {
1811 			if (!param->value)
1812 				continue;
1813 			if (leading)
1814 				snprintf(ops->TargetName,
1815 						sizeof(ops->TargetName),
1816 						"%s", param->value);
1817 			pr_debug("TargetName:                   %s\n",
1818 				param->value);
1819 		} else if (!strcmp(param->name, TARGETALIAS)) {
1820 			if (!param->value)
1821 				continue;
1822 			snprintf(ops->TargetAlias, sizeof(ops->TargetAlias),
1823 					"%s", param->value);
1824 			pr_debug("TargetAlias:                  %s\n",
1825 				param->value);
1826 		} else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
1827 			ops->TargetPortalGroupTag =
1828 				simple_strtoul(param->value, &tmpptr, 0);
1829 			pr_debug("TargetPortalGroupTag:         %s\n",
1830 				param->value);
1831 		} else if (!strcmp(param->name, MAXCONNECTIONS)) {
1832 			ops->MaxConnections =
1833 				simple_strtoul(param->value, &tmpptr, 0);
1834 			pr_debug("MaxConnections:               %s\n",
1835 				param->value);
1836 		} else if (!strcmp(param->name, INITIALR2T)) {
1837 			ops->InitialR2T = !strcmp(param->value, YES);
1838 			 pr_debug("InitialR2T:                   %s\n",
1839 				param->value);
1840 		} else if (!strcmp(param->name, IMMEDIATEDATA)) {
1841 			ops->ImmediateData = !strcmp(param->value, YES);
1842 			pr_debug("ImmediateData:                %s\n",
1843 				param->value);
1844 		} else if (!strcmp(param->name, MAXBURSTLENGTH)) {
1845 			ops->MaxBurstLength =
1846 				simple_strtoul(param->value, &tmpptr, 0);
1847 			pr_debug("MaxBurstLength:               %s\n",
1848 				param->value);
1849 		} else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1850 			ops->FirstBurstLength =
1851 				simple_strtoul(param->value, &tmpptr, 0);
1852 			pr_debug("FirstBurstLength:             %s\n",
1853 				param->value);
1854 		} else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1855 			ops->DefaultTime2Wait =
1856 				simple_strtoul(param->value, &tmpptr, 0);
1857 			pr_debug("DefaultTime2Wait:             %s\n",
1858 				param->value);
1859 		} else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
1860 			ops->DefaultTime2Retain =
1861 				simple_strtoul(param->value, &tmpptr, 0);
1862 			pr_debug("DefaultTime2Retain:           %s\n",
1863 				param->value);
1864 		} else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
1865 			ops->MaxOutstandingR2T =
1866 				simple_strtoul(param->value, &tmpptr, 0);
1867 			pr_debug("MaxOutstandingR2T:            %s\n",
1868 				param->value);
1869 		} else if (!strcmp(param->name, DATAPDUINORDER)) {
1870 			ops->DataPDUInOrder = !strcmp(param->value, YES);
1871 			pr_debug("DataPDUInOrder:               %s\n",
1872 				param->value);
1873 		} else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
1874 			ops->DataSequenceInOrder = !strcmp(param->value, YES);
1875 			pr_debug("DataSequenceInOrder:          %s\n",
1876 				param->value);
1877 		} else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
1878 			ops->ErrorRecoveryLevel =
1879 				simple_strtoul(param->value, &tmpptr, 0);
1880 			pr_debug("ErrorRecoveryLevel:           %s\n",
1881 				param->value);
1882 		} else if (!strcmp(param->name, SESSIONTYPE)) {
1883 			ops->SessionType = !strcmp(param->value, DISCOVERY);
1884 			pr_debug("SessionType:                  %s\n",
1885 				param->value);
1886 		}
1887 	}
1888 	pr_debug("----------------------------------------------------"
1889 			"--------------\n");
1890 
1891 }
1892