blob: be336df0a8878c5a1c1b898633c08a0b5b3a835d [file] [log] [blame]
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001/*******************************************************************************
2 * This file contains main functions related to iSCSI Parameter negotiation.
3 *
Nicholas Bellinger4c762512013-09-05 15:29:12 -07004 * (c) Copyright 2007-2013 Datera, Inc.
Nicholas Bellingere48354c2011-07-23 06:43:04 +00005 *
6 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 ******************************************************************************/
18
19#include <linux/slab.h>
20
Sagi Grimberg67f091f2015-01-07 14:57:31 +020021#include <target/iscsi/iscsi_target_core.h>
Nicholas Bellingere48354c2011-07-23 06:43:04 +000022#include "iscsi_target_util.h"
23#include "iscsi_target_parameters.h"
24
25int iscsi_login_rx_data(
26 struct iscsi_conn *conn,
27 char *buf,
28 int length)
29{
30 int rx_got;
31 struct kvec iov;
32
33 memset(&iov, 0, sizeof(struct kvec));
34 iov.iov_len = length;
35 iov.iov_base = buf;
36
Nicholas Bellingere48354c2011-07-23 06:43:04 +000037 rx_got = rx_data(conn, &iov, 1, length);
38 if (rx_got != length) {
39 pr_err("rx_data returned %d, expecting %d.\n",
40 rx_got, length);
41 return -1;
42 }
43
44 return 0 ;
45}
46
47int iscsi_login_tx_data(
48 struct iscsi_conn *conn,
49 char *pdu_buf,
50 char *text_buf,
51 int text_length)
52{
Nicholas Bellingerbaa4d642013-03-06 21:54:13 -080053 int length, tx_sent, iov_cnt = 1;
Nicholas Bellingere48354c2011-07-23 06:43:04 +000054 struct kvec iov[2];
55
56 length = (ISCSI_HDR_LEN + text_length);
57
58 memset(&iov[0], 0, 2 * sizeof(struct kvec));
59 iov[0].iov_len = ISCSI_HDR_LEN;
60 iov[0].iov_base = pdu_buf;
Nicholas Bellingerbaa4d642013-03-06 21:54:13 -080061
62 if (text_buf && text_length) {
63 iov[1].iov_len = text_length;
64 iov[1].iov_base = text_buf;
65 iov_cnt++;
66 }
Nicholas Bellingere48354c2011-07-23 06:43:04 +000067
Nicholas Bellingerbaa4d642013-03-06 21:54:13 -080068 tx_sent = tx_data(conn, &iov[0], iov_cnt, length);
Nicholas Bellingere48354c2011-07-23 06:43:04 +000069 if (tx_sent != length) {
70 pr_err("tx_data returned %d, expecting %d.\n",
71 tx_sent, length);
72 return -1;
73 }
74
75 return 0;
76}
77
78void iscsi_dump_conn_ops(struct iscsi_conn_ops *conn_ops)
79{
80 pr_debug("HeaderDigest: %s\n", (conn_ops->HeaderDigest) ?
81 "CRC32C" : "None");
82 pr_debug("DataDigest: %s\n", (conn_ops->DataDigest) ?
83 "CRC32C" : "None");
84 pr_debug("MaxRecvDataSegmentLength: %u\n",
85 conn_ops->MaxRecvDataSegmentLength);
Nicholas Bellingere48354c2011-07-23 06:43:04 +000086}
87
88void iscsi_dump_sess_ops(struct iscsi_sess_ops *sess_ops)
89{
90 pr_debug("InitiatorName: %s\n", sess_ops->InitiatorName);
91 pr_debug("InitiatorAlias: %s\n", sess_ops->InitiatorAlias);
92 pr_debug("TargetName: %s\n", sess_ops->TargetName);
93 pr_debug("TargetAlias: %s\n", sess_ops->TargetAlias);
94 pr_debug("TargetPortalGroupTag: %hu\n",
95 sess_ops->TargetPortalGroupTag);
96 pr_debug("MaxConnections: %hu\n", sess_ops->MaxConnections);
97 pr_debug("InitialR2T: %s\n",
98 (sess_ops->InitialR2T) ? "Yes" : "No");
99 pr_debug("ImmediateData: %s\n", (sess_ops->ImmediateData) ?
100 "Yes" : "No");
101 pr_debug("MaxBurstLength: %u\n", sess_ops->MaxBurstLength);
102 pr_debug("FirstBurstLength: %u\n", sess_ops->FirstBurstLength);
103 pr_debug("DefaultTime2Wait: %hu\n", sess_ops->DefaultTime2Wait);
104 pr_debug("DefaultTime2Retain: %hu\n",
105 sess_ops->DefaultTime2Retain);
106 pr_debug("MaxOutstandingR2T: %hu\n",
107 sess_ops->MaxOutstandingR2T);
108 pr_debug("DataPDUInOrder: %s\n",
109 (sess_ops->DataPDUInOrder) ? "Yes" : "No");
110 pr_debug("DataSequenceInOrder: %s\n",
111 (sess_ops->DataSequenceInOrder) ? "Yes" : "No");
112 pr_debug("ErrorRecoveryLevel: %hu\n",
113 sess_ops->ErrorRecoveryLevel);
114 pr_debug("SessionType: %s\n", (sess_ops->SessionType) ?
115 "Discovery" : "Normal");
116}
117
118void iscsi_print_params(struct iscsi_param_list *param_list)
119{
120 struct iscsi_param *param;
121
122 list_for_each_entry(param, &param_list->param_list, p_list)
123 pr_debug("%s: %s\n", param->name, param->value);
124}
125
126static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *param_list,
127 char *name, char *value, u8 phase, u8 scope, u8 sender,
128 u16 type_range, u8 use)
129{
130 struct iscsi_param *param = NULL;
131
132 param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
133 if (!param) {
134 pr_err("Unable to allocate memory for parameter.\n");
135 goto out;
136 }
137 INIT_LIST_HEAD(&param->p_list);
138
Sebastian Andrzej Siewiored72a4d2012-11-29 20:29:01 +0100139 param->name = kstrdup(name, GFP_KERNEL);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000140 if (!param->name) {
141 pr_err("Unable to allocate memory for parameter name.\n");
142 goto out;
143 }
144
Sebastian Andrzej Siewiored72a4d2012-11-29 20:29:01 +0100145 param->value = kstrdup(value, GFP_KERNEL);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000146 if (!param->value) {
147 pr_err("Unable to allocate memory for parameter value.\n");
148 goto out;
149 }
150
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000151 param->phase = phase;
152 param->scope = scope;
153 param->sender = sender;
154 param->use = use;
155 param->type_range = type_range;
156
157 switch (param->type_range) {
158 case TYPERANGE_BOOL_AND:
159 param->type = TYPE_BOOL_AND;
160 break;
161 case TYPERANGE_BOOL_OR:
162 param->type = TYPE_BOOL_OR;
163 break;
164 case TYPERANGE_0_TO_2:
165 case TYPERANGE_0_TO_3600:
166 case TYPERANGE_0_TO_32767:
167 case TYPERANGE_0_TO_65535:
168 case TYPERANGE_1_TO_65535:
169 case TYPERANGE_2_TO_3600:
170 case TYPERANGE_512_TO_16777215:
171 param->type = TYPE_NUMBER;
172 break;
173 case TYPERANGE_AUTH:
174 case TYPERANGE_DIGEST:
175 param->type = TYPE_VALUE_LIST | TYPE_STRING;
176 break;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000177 case TYPERANGE_ISCSINAME:
178 case TYPERANGE_SESSIONTYPE:
179 case TYPERANGE_TARGETADDRESS:
180 case TYPERANGE_UTF8:
181 param->type = TYPE_STRING;
182 break;
183 default:
184 pr_err("Unknown type_range 0x%02x\n",
185 param->type_range);
186 goto out;
187 }
188 list_add_tail(&param->p_list, &param_list->param_list);
189
190 return param;
191out:
192 if (param) {
193 kfree(param->value);
194 kfree(param->name);
195 kfree(param);
196 }
197
198 return NULL;
199}
200
201/* #warning Add extension keys */
202int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
203{
204 struct iscsi_param *param = NULL;
205 struct iscsi_param_list *pl;
206
207 pl = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
208 if (!pl) {
209 pr_err("Unable to allocate memory for"
210 " struct iscsi_param_list.\n");
211 return -1 ;
212 }
213 INIT_LIST_HEAD(&pl->param_list);
214 INIT_LIST_HEAD(&pl->extra_response_list);
215
216 /*
217 * The format for setting the initial parameter definitions are:
218 *
219 * Parameter name:
220 * Initial value:
221 * Allowable phase:
222 * Scope:
223 * Allowable senders:
224 * Typerange:
225 * Use:
226 */
227 param = iscsi_set_default_param(pl, AUTHMETHOD, INITIAL_AUTHMETHOD,
228 PHASE_SECURITY, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
229 TYPERANGE_AUTH, USE_INITIAL_ONLY);
230 if (!param)
231 goto out;
232
233 param = iscsi_set_default_param(pl, HEADERDIGEST, INITIAL_HEADERDIGEST,
234 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
235 TYPERANGE_DIGEST, USE_INITIAL_ONLY);
236 if (!param)
237 goto out;
238
239 param = iscsi_set_default_param(pl, DATADIGEST, INITIAL_DATADIGEST,
240 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
241 TYPERANGE_DIGEST, USE_INITIAL_ONLY);
242 if (!param)
243 goto out;
244
245 param = iscsi_set_default_param(pl, MAXCONNECTIONS,
246 INITIAL_MAXCONNECTIONS, PHASE_OPERATIONAL,
247 SCOPE_SESSION_WIDE, SENDER_BOTH,
248 TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
249 if (!param)
250 goto out;
251
252 param = iscsi_set_default_param(pl, SENDTARGETS, INITIAL_SENDTARGETS,
253 PHASE_FFP0, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
254 TYPERANGE_UTF8, 0);
255 if (!param)
256 goto out;
257
258 param = iscsi_set_default_param(pl, TARGETNAME, INITIAL_TARGETNAME,
259 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_BOTH,
260 TYPERANGE_ISCSINAME, USE_ALL);
261 if (!param)
262 goto out;
263
264 param = iscsi_set_default_param(pl, INITIATORNAME,
265 INITIAL_INITIATORNAME, PHASE_DECLARATIVE,
266 SCOPE_SESSION_WIDE, SENDER_INITIATOR,
267 TYPERANGE_ISCSINAME, USE_INITIAL_ONLY);
268 if (!param)
269 goto out;
270
271 param = iscsi_set_default_param(pl, TARGETALIAS, INITIAL_TARGETALIAS,
272 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
273 TYPERANGE_UTF8, USE_ALL);
274 if (!param)
275 goto out;
276
277 param = iscsi_set_default_param(pl, INITIATORALIAS,
278 INITIAL_INITIATORALIAS, PHASE_DECLARATIVE,
279 SCOPE_SESSION_WIDE, SENDER_INITIATOR, TYPERANGE_UTF8,
280 USE_ALL);
281 if (!param)
282 goto out;
283
284 param = iscsi_set_default_param(pl, TARGETADDRESS,
285 INITIAL_TARGETADDRESS, PHASE_DECLARATIVE,
286 SCOPE_SESSION_WIDE, SENDER_TARGET,
287 TYPERANGE_TARGETADDRESS, USE_ALL);
288 if (!param)
289 goto out;
290
291 param = iscsi_set_default_param(pl, TARGETPORTALGROUPTAG,
292 INITIAL_TARGETPORTALGROUPTAG,
293 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET,
294 TYPERANGE_0_TO_65535, USE_INITIAL_ONLY);
295 if (!param)
296 goto out;
297
298 param = iscsi_set_default_param(pl, INITIALR2T, INITIAL_INITIALR2T,
299 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
300 TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
301 if (!param)
302 goto out;
303
304 param = iscsi_set_default_param(pl, IMMEDIATEDATA,
305 INITIAL_IMMEDIATEDATA, PHASE_OPERATIONAL,
306 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_AND,
307 USE_LEADING_ONLY);
308 if (!param)
309 goto out;
310
Nicholas Bellingere004cb22012-09-29 21:47:16 -0700311 param = iscsi_set_default_param(pl, MAXXMITDATASEGMENTLENGTH,
312 INITIAL_MAXXMITDATASEGMENTLENGTH,
313 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
314 TYPERANGE_512_TO_16777215, USE_ALL);
315 if (!param)
316 goto out;
317
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000318 param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH,
319 INITIAL_MAXRECVDATASEGMENTLENGTH,
320 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
321 TYPERANGE_512_TO_16777215, USE_ALL);
322 if (!param)
323 goto out;
324
325 param = iscsi_set_default_param(pl, MAXBURSTLENGTH,
326 INITIAL_MAXBURSTLENGTH, PHASE_OPERATIONAL,
327 SCOPE_SESSION_WIDE, SENDER_BOTH,
328 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
329 if (!param)
330 goto out;
331
332 param = iscsi_set_default_param(pl, FIRSTBURSTLENGTH,
333 INITIAL_FIRSTBURSTLENGTH,
334 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
335 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY);
336 if (!param)
337 goto out;
338
339 param = iscsi_set_default_param(pl, DEFAULTTIME2WAIT,
340 INITIAL_DEFAULTTIME2WAIT,
341 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
342 TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
343 if (!param)
344 goto out;
345
346 param = iscsi_set_default_param(pl, DEFAULTTIME2RETAIN,
347 INITIAL_DEFAULTTIME2RETAIN,
348 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
349 TYPERANGE_0_TO_3600, USE_LEADING_ONLY);
350 if (!param)
351 goto out;
352
353 param = iscsi_set_default_param(pl, MAXOUTSTANDINGR2T,
354 INITIAL_MAXOUTSTANDINGR2T,
355 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
356 TYPERANGE_1_TO_65535, USE_LEADING_ONLY);
357 if (!param)
358 goto out;
359
360 param = iscsi_set_default_param(pl, DATAPDUINORDER,
361 INITIAL_DATAPDUINORDER, PHASE_OPERATIONAL,
362 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_OR,
363 USE_LEADING_ONLY);
364 if (!param)
365 goto out;
366
367 param = iscsi_set_default_param(pl, DATASEQUENCEINORDER,
368 INITIAL_DATASEQUENCEINORDER,
369 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
370 TYPERANGE_BOOL_OR, USE_LEADING_ONLY);
371 if (!param)
372 goto out;
373
374 param = iscsi_set_default_param(pl, ERRORRECOVERYLEVEL,
375 INITIAL_ERRORRECOVERYLEVEL,
376 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
377 TYPERANGE_0_TO_2, USE_LEADING_ONLY);
378 if (!param)
379 goto out;
380
381 param = iscsi_set_default_param(pl, SESSIONTYPE, INITIAL_SESSIONTYPE,
382 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_INITIATOR,
383 TYPERANGE_SESSIONTYPE, USE_LEADING_ONLY);
384 if (!param)
385 goto out;
386
387 param = iscsi_set_default_param(pl, IFMARKER, INITIAL_IFMARKER,
388 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
389 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
390 if (!param)
391 goto out;
392
393 param = iscsi_set_default_param(pl, OFMARKER, INITIAL_OFMARKER,
394 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
395 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY);
396 if (!param)
397 goto out;
398
399 param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT,
400 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +0200401 TYPERANGE_UTF8, USE_INITIAL_ONLY);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000402 if (!param)
403 goto out;
404
405 param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT,
406 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +0200407 TYPERANGE_UTF8, USE_INITIAL_ONLY);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000408 if (!param)
409 goto out;
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800410 /*
411 * Extra parameters for ISER from RFC-5046
412 */
Nicholas Bellingeraf40bb02013-05-11 16:24:21 -0700413 param = iscsi_set_default_param(pl, RDMAEXTENSIONS, INITIAL_RDMAEXTENSIONS,
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800414 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
415 TYPERANGE_BOOL_AND, USE_LEADING_ONLY);
416 if (!param)
417 goto out;
418
419 param = iscsi_set_default_param(pl, INITIATORRECVDATASEGMENTLENGTH,
420 INITIAL_INITIATORRECVDATASEGMENTLENGTH,
421 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
422 TYPERANGE_512_TO_16777215, USE_ALL);
423 if (!param)
424 goto out;
425
426 param = iscsi_set_default_param(pl, TARGETRECVDATASEGMENTLENGTH,
427 INITIAL_TARGETRECVDATASEGMENTLENGTH,
428 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
429 TYPERANGE_512_TO_16777215, USE_ALL);
430 if (!param)
431 goto out;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000432
433 *param_list_ptr = pl;
434 return 0;
435out:
436 iscsi_release_param_list(pl);
437 return -1;
438}
439
440int iscsi_set_keys_to_negotiate(
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800441 struct iscsi_param_list *param_list,
442 bool iser)
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000443{
444 struct iscsi_param *param;
445
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800446 param_list->iser = iser;
447
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000448 list_for_each_entry(param, &param_list->param_list, p_list) {
449 param->state = 0;
450 if (!strcmp(param->name, AUTHMETHOD)) {
451 SET_PSTATE_NEGOTIATE(param);
452 } else if (!strcmp(param->name, HEADERDIGEST)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200453 if (!iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800454 SET_PSTATE_NEGOTIATE(param);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000455 } else if (!strcmp(param->name, DATADIGEST)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200456 if (!iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800457 SET_PSTATE_NEGOTIATE(param);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000458 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
459 SET_PSTATE_NEGOTIATE(param);
460 } else if (!strcmp(param->name, TARGETNAME)) {
461 continue;
462 } else if (!strcmp(param->name, INITIATORNAME)) {
463 continue;
464 } else if (!strcmp(param->name, TARGETALIAS)) {
465 if (param->value)
466 SET_PSTATE_NEGOTIATE(param);
467 } else if (!strcmp(param->name, INITIATORALIAS)) {
468 continue;
469 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
470 SET_PSTATE_NEGOTIATE(param);
471 } else if (!strcmp(param->name, INITIALR2T)) {
472 SET_PSTATE_NEGOTIATE(param);
473 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
474 SET_PSTATE_NEGOTIATE(param);
475 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200476 if (!iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800477 SET_PSTATE_NEGOTIATE(param);
Nicholas Bellingere004cb22012-09-29 21:47:16 -0700478 } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
479 continue;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000480 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
481 SET_PSTATE_NEGOTIATE(param);
482 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
483 SET_PSTATE_NEGOTIATE(param);
484 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
485 SET_PSTATE_NEGOTIATE(param);
486 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
487 SET_PSTATE_NEGOTIATE(param);
488 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
489 SET_PSTATE_NEGOTIATE(param);
490 } else if (!strcmp(param->name, DATAPDUINORDER)) {
491 SET_PSTATE_NEGOTIATE(param);
492 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
493 SET_PSTATE_NEGOTIATE(param);
494 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
495 SET_PSTATE_NEGOTIATE(param);
496 } else if (!strcmp(param->name, SESSIONTYPE)) {
497 SET_PSTATE_NEGOTIATE(param);
498 } else if (!strcmp(param->name, IFMARKER)) {
499 SET_PSTATE_NEGOTIATE(param);
500 } else if (!strcmp(param->name, OFMARKER)) {
501 SET_PSTATE_NEGOTIATE(param);
502 } else if (!strcmp(param->name, IFMARKINT)) {
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +0200503 SET_PSTATE_REJECT(param);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000504 } else if (!strcmp(param->name, OFMARKINT)) {
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +0200505 SET_PSTATE_REJECT(param);
Nicholas Bellingeraf40bb02013-05-11 16:24:21 -0700506 } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200507 if (iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800508 SET_PSTATE_NEGOTIATE(param);
509 } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200510 if (iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800511 SET_PSTATE_NEGOTIATE(param);
512 } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
Christophe Vu-Brugier0bcc2972014-06-06 17:15:16 +0200513 if (iser)
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800514 SET_PSTATE_NEGOTIATE(param);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000515 }
516 }
517
518 return 0;
519}
520
521int iscsi_set_keys_irrelevant_for_discovery(
522 struct iscsi_param_list *param_list)
523{
524 struct iscsi_param *param;
525
526 list_for_each_entry(param, &param_list->param_list, p_list) {
527 if (!strcmp(param->name, MAXCONNECTIONS))
528 param->state &= ~PSTATE_NEGOTIATE;
529 else if (!strcmp(param->name, INITIALR2T))
530 param->state &= ~PSTATE_NEGOTIATE;
531 else if (!strcmp(param->name, IMMEDIATEDATA))
532 param->state &= ~PSTATE_NEGOTIATE;
533 else if (!strcmp(param->name, MAXBURSTLENGTH))
534 param->state &= ~PSTATE_NEGOTIATE;
535 else if (!strcmp(param->name, FIRSTBURSTLENGTH))
536 param->state &= ~PSTATE_NEGOTIATE;
537 else if (!strcmp(param->name, MAXOUTSTANDINGR2T))
538 param->state &= ~PSTATE_NEGOTIATE;
539 else if (!strcmp(param->name, DATAPDUINORDER))
540 param->state &= ~PSTATE_NEGOTIATE;
541 else if (!strcmp(param->name, DATASEQUENCEINORDER))
542 param->state &= ~PSTATE_NEGOTIATE;
543 else if (!strcmp(param->name, ERRORRECOVERYLEVEL))
544 param->state &= ~PSTATE_NEGOTIATE;
545 else if (!strcmp(param->name, DEFAULTTIME2WAIT))
546 param->state &= ~PSTATE_NEGOTIATE;
547 else if (!strcmp(param->name, DEFAULTTIME2RETAIN))
548 param->state &= ~PSTATE_NEGOTIATE;
549 else if (!strcmp(param->name, IFMARKER))
550 param->state &= ~PSTATE_NEGOTIATE;
551 else if (!strcmp(param->name, OFMARKER))
552 param->state &= ~PSTATE_NEGOTIATE;
553 else if (!strcmp(param->name, IFMARKINT))
554 param->state &= ~PSTATE_NEGOTIATE;
555 else if (!strcmp(param->name, OFMARKINT))
556 param->state &= ~PSTATE_NEGOTIATE;
Nicholas Bellingeraf40bb02013-05-11 16:24:21 -0700557 else if (!strcmp(param->name, RDMAEXTENSIONS))
Nicholas Bellinger03aa2072013-03-06 21:54:38 -0800558 param->state &= ~PSTATE_NEGOTIATE;
559 else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH))
560 param->state &= ~PSTATE_NEGOTIATE;
561 else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH))
562 param->state &= ~PSTATE_NEGOTIATE;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000563 }
564
565 return 0;
566}
567
568int iscsi_copy_param_list(
569 struct iscsi_param_list **dst_param_list,
570 struct iscsi_param_list *src_param_list,
571 int leading)
572{
Jesper Juhl9be08c52011-08-02 10:26:36 +0200573 struct iscsi_param *param = NULL;
574 struct iscsi_param *new_param = NULL;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000575 struct iscsi_param_list *param_list = NULL;
576
577 param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL);
578 if (!param_list) {
Jesper Juhl9be08c52011-08-02 10:26:36 +0200579 pr_err("Unable to allocate memory for struct iscsi_param_list.\n");
Joern Engel8ae757d2014-09-02 17:49:54 -0400580 return -1;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000581 }
582 INIT_LIST_HEAD(&param_list->param_list);
583 INIT_LIST_HEAD(&param_list->extra_response_list);
584
585 list_for_each_entry(param, &src_param_list->param_list, p_list) {
586 if (!leading && (param->scope & SCOPE_SESSION_WIDE)) {
587 if ((strcmp(param->name, "TargetName") != 0) &&
588 (strcmp(param->name, "InitiatorName") != 0) &&
589 (strcmp(param->name, "TargetPortalGroupTag") != 0))
590 continue;
591 }
592
593 new_param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL);
594 if (!new_param) {
Jesper Juhl9be08c52011-08-02 10:26:36 +0200595 pr_err("Unable to allocate memory for struct iscsi_param.\n");
596 goto err_out;
597 }
598
599 new_param->name = kstrdup(param->name, GFP_KERNEL);
600 new_param->value = kstrdup(param->value, GFP_KERNEL);
601 if (!new_param->value || !new_param->name) {
602 kfree(new_param->value);
603 kfree(new_param->name);
604 kfree(new_param);
605 pr_err("Unable to allocate memory for parameter name/value.\n");
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000606 goto err_out;
607 }
608
609 new_param->set_param = param->set_param;
610 new_param->phase = param->phase;
611 new_param->scope = param->scope;
612 new_param->sender = param->sender;
613 new_param->type = param->type;
614 new_param->use = param->use;
615 new_param->type_range = param->type_range;
616
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000617 list_add_tail(&new_param->p_list, &param_list->param_list);
618 }
619
Jesper Juhl9be08c52011-08-02 10:26:36 +0200620 if (!list_empty(&param_list->param_list)) {
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000621 *dst_param_list = param_list;
Jesper Juhl9be08c52011-08-02 10:26:36 +0200622 } else {
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000623 pr_err("No parameters allocated.\n");
624 goto err_out;
625 }
626
627 return 0;
628
629err_out:
630 iscsi_release_param_list(param_list);
631 return -1;
632}
633
634static void iscsi_release_extra_responses(struct iscsi_param_list *param_list)
635{
636 struct iscsi_extra_response *er, *er_tmp;
637
638 list_for_each_entry_safe(er, er_tmp, &param_list->extra_response_list,
639 er_list) {
640 list_del(&er->er_list);
641 kfree(er);
642 }
643}
644
645void iscsi_release_param_list(struct iscsi_param_list *param_list)
646{
647 struct iscsi_param *param, *param_tmp;
648
649 list_for_each_entry_safe(param, param_tmp, &param_list->param_list,
650 p_list) {
651 list_del(&param->p_list);
652
653 kfree(param->name);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000654 kfree(param->value);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000655 kfree(param);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000656 }
657
658 iscsi_release_extra_responses(param_list);
659
660 kfree(param_list);
661}
662
663struct iscsi_param *iscsi_find_param_from_key(
664 char *key,
665 struct iscsi_param_list *param_list)
666{
667 struct iscsi_param *param;
668
669 if (!key || !param_list) {
670 pr_err("Key or parameter list pointer is NULL.\n");
671 return NULL;
672 }
673
674 list_for_each_entry(param, &param_list->param_list, p_list) {
675 if (!strcmp(key, param->name))
676 return param;
677 }
678
679 pr_err("Unable to locate key \"%s\".\n", key);
680 return NULL;
681}
682
683int iscsi_extract_key_value(char *textbuf, char **key, char **value)
684{
685 *value = strchr(textbuf, '=');
686 if (!*value) {
Masanari Iida59e13d42012-04-25 00:24:16 +0900687 pr_err("Unable to locate \"=\" separator for key,"
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000688 " ignoring request.\n");
689 return -1;
690 }
691
692 *key = textbuf;
693 **value = '\0';
694 *value = *value + 1;
695
696 return 0;
697}
698
699int iscsi_update_param_value(struct iscsi_param *param, char *value)
700{
701 kfree(param->value);
702
Sebastian Andrzej Siewiored72a4d2012-11-29 20:29:01 +0100703 param->value = kstrdup(value, GFP_KERNEL);
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000704 if (!param->value) {
705 pr_err("Unable to allocate memory for value.\n");
Andy Grover617a0c22012-07-12 17:34:56 -0700706 return -ENOMEM;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000707 }
708
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000709 pr_debug("iSCSI Parameter updated to %s=%s\n",
710 param->name, param->value);
711 return 0;
712}
713
714static int iscsi_add_notunderstood_response(
715 char *key,
716 char *value,
717 struct iscsi_param_list *param_list)
718{
719 struct iscsi_extra_response *extra_response;
720
721 if (strlen(value) > VALUE_MAXLEN) {
722 pr_err("Value for notunderstood key \"%s\" exceeds %d,"
723 " protocol error.\n", key, VALUE_MAXLEN);
724 return -1;
725 }
726
727 extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL);
728 if (!extra_response) {
729 pr_err("Unable to allocate memory for"
730 " struct iscsi_extra_response.\n");
731 return -1;
732 }
733 INIT_LIST_HEAD(&extra_response->er_list);
734
Kees Cookcea4dcf2013-05-23 10:32:17 -0700735 strlcpy(extra_response->key, key, sizeof(extra_response->key));
736 strlcpy(extra_response->value, NOTUNDERSTOOD,
737 sizeof(extra_response->value));
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000738
739 list_add_tail(&extra_response->er_list,
740 &param_list->extra_response_list);
741 return 0;
742}
743
744static int iscsi_check_for_auth_key(char *key)
745{
746 /*
747 * RFC 1994
748 */
749 if (!strcmp(key, "CHAP_A") || !strcmp(key, "CHAP_I") ||
750 !strcmp(key, "CHAP_C") || !strcmp(key, "CHAP_N") ||
751 !strcmp(key, "CHAP_R"))
752 return 1;
753
754 /*
755 * RFC 2945
756 */
757 if (!strcmp(key, "SRP_U") || !strcmp(key, "SRP_N") ||
758 !strcmp(key, "SRP_g") || !strcmp(key, "SRP_s") ||
759 !strcmp(key, "SRP_A") || !strcmp(key, "SRP_B") ||
760 !strcmp(key, "SRP_M") || !strcmp(key, "SRP_HM"))
761 return 1;
762
763 return 0;
764}
765
766static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
767{
768 if (IS_TYPE_BOOL_AND(param)) {
769 if (!strcmp(param->value, NO))
770 SET_PSTATE_REPLY_OPTIONAL(param);
771 } else if (IS_TYPE_BOOL_OR(param)) {
772 if (!strcmp(param->value, YES))
773 SET_PSTATE_REPLY_OPTIONAL(param);
774 /*
775 * Required for gPXE iSCSI boot client
776 */
777 if (!strcmp(param->name, IMMEDIATEDATA))
778 SET_PSTATE_REPLY_OPTIONAL(param);
779 } else if (IS_TYPE_NUMBER(param)) {
780 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
781 SET_PSTATE_REPLY_OPTIONAL(param);
782 /*
783 * The GlobalSAN iSCSI Initiator for MacOSX does
784 * not respond to MaxBurstLength, FirstBurstLength,
785 * DefaultTime2Wait or DefaultTime2Retain parameter keys.
786 * So, we set them to 'reply optional' here, and assume the
787 * the defaults from iscsi_parameters.h if the initiator
788 * is not RFC compliant and the keys are not negotiated.
789 */
790 if (!strcmp(param->name, MAXBURSTLENGTH))
791 SET_PSTATE_REPLY_OPTIONAL(param);
792 if (!strcmp(param->name, FIRSTBURSTLENGTH))
793 SET_PSTATE_REPLY_OPTIONAL(param);
794 if (!strcmp(param->name, DEFAULTTIME2WAIT))
795 SET_PSTATE_REPLY_OPTIONAL(param);
796 if (!strcmp(param->name, DEFAULTTIME2RETAIN))
797 SET_PSTATE_REPLY_OPTIONAL(param);
798 /*
799 * Required for gPXE iSCSI boot client
800 */
801 if (!strcmp(param->name, MAXCONNECTIONS))
802 SET_PSTATE_REPLY_OPTIONAL(param);
803 } else if (IS_PHASE_DECLARATIVE(param))
804 SET_PSTATE_REPLY_OPTIONAL(param);
805}
806
807static int iscsi_check_boolean_value(struct iscsi_param *param, char *value)
808{
809 if (strcmp(value, YES) && strcmp(value, NO)) {
810 pr_err("Illegal value for \"%s\", must be either"
811 " \"%s\" or \"%s\".\n", param->name, YES, NO);
812 return -1;
813 }
814
815 return 0;
816}
817
818static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_ptr)
819{
820 char *tmpptr;
821 int value = 0;
822
823 value = simple_strtoul(value_ptr, &tmpptr, 0);
824
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000825 if (IS_TYPERANGE_0_TO_2(param)) {
826 if ((value < 0) || (value > 2)) {
827 pr_err("Illegal value for \"%s\", must be"
828 " between 0 and 2.\n", param->name);
829 return -1;
830 }
831 return 0;
832 }
833 if (IS_TYPERANGE_0_TO_3600(param)) {
834 if ((value < 0) || (value > 3600)) {
835 pr_err("Illegal value for \"%s\", must be"
836 " between 0 and 3600.\n", param->name);
837 return -1;
838 }
839 return 0;
840 }
841 if (IS_TYPERANGE_0_TO_32767(param)) {
842 if ((value < 0) || (value > 32767)) {
843 pr_err("Illegal value for \"%s\", must be"
844 " between 0 and 32767.\n", param->name);
845 return -1;
846 }
847 return 0;
848 }
849 if (IS_TYPERANGE_0_TO_65535(param)) {
850 if ((value < 0) || (value > 65535)) {
851 pr_err("Illegal value for \"%s\", must be"
852 " between 0 and 65535.\n", param->name);
853 return -1;
854 }
855 return 0;
856 }
857 if (IS_TYPERANGE_1_TO_65535(param)) {
858 if ((value < 1) || (value > 65535)) {
859 pr_err("Illegal value for \"%s\", must be"
860 " between 1 and 65535.\n", param->name);
861 return -1;
862 }
863 return 0;
864 }
865 if (IS_TYPERANGE_2_TO_3600(param)) {
866 if ((value < 2) || (value > 3600)) {
867 pr_err("Illegal value for \"%s\", must be"
868 " between 2 and 3600.\n", param->name);
869 return -1;
870 }
871 return 0;
872 }
873 if (IS_TYPERANGE_512_TO_16777215(param)) {
874 if ((value < 512) || (value > 16777215)) {
875 pr_err("Illegal value for \"%s\", must be"
876 " between 512 and 16777215.\n", param->name);
877 return -1;
878 }
879 return 0;
880 }
881
882 return 0;
883}
884
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000885static int iscsi_check_string_or_list_value(struct iscsi_param *param, char *value)
886{
887 if (IS_PSTATE_PROPOSER(param))
888 return 0;
889
890 if (IS_TYPERANGE_AUTH_PARAM(param)) {
891 if (strcmp(value, KRB5) && strcmp(value, SPKM1) &&
892 strcmp(value, SPKM2) && strcmp(value, SRP) &&
893 strcmp(value, CHAP) && strcmp(value, NONE)) {
894 pr_err("Illegal value for \"%s\", must be"
895 " \"%s\", \"%s\", \"%s\", \"%s\", \"%s\""
896 " or \"%s\".\n", param->name, KRB5,
897 SPKM1, SPKM2, SRP, CHAP, NONE);
898 return -1;
899 }
900 }
901 if (IS_TYPERANGE_DIGEST_PARAM(param)) {
902 if (strcmp(value, CRC32C) && strcmp(value, NONE)) {
903 pr_err("Illegal value for \"%s\", must be"
904 " \"%s\" or \"%s\".\n", param->name,
905 CRC32C, NONE);
906 return -1;
907 }
908 }
909 if (IS_TYPERANGE_SESSIONTYPE(param)) {
910 if (strcmp(value, DISCOVERY) && strcmp(value, NORMAL)) {
911 pr_err("Illegal value for \"%s\", must be"
912 " \"%s\" or \"%s\".\n", param->name,
913 DISCOVERY, NORMAL);
914 return -1;
915 }
916 }
917
918 return 0;
919}
920
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000921static char *iscsi_check_valuelist_for_support(
922 struct iscsi_param *param,
923 char *value)
924{
925 char *tmp1 = NULL, *tmp2 = NULL;
926 char *acceptor_values = NULL, *proposer_values = NULL;
927
928 acceptor_values = param->value;
929 proposer_values = value;
930
931 do {
932 if (!proposer_values)
933 return NULL;
934 tmp1 = strchr(proposer_values, ',');
935 if (tmp1)
936 *tmp1 = '\0';
937 acceptor_values = param->value;
938 do {
939 if (!acceptor_values) {
940 if (tmp1)
941 *tmp1 = ',';
942 return NULL;
943 }
944 tmp2 = strchr(acceptor_values, ',');
945 if (tmp2)
946 *tmp2 = '\0';
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000947 if (!strcmp(acceptor_values, proposer_values)) {
948 if (tmp2)
949 *tmp2 = ',';
950 goto out;
951 }
952 if (tmp2)
953 *tmp2++ = ',';
954
955 acceptor_values = tmp2;
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000956 } while (acceptor_values);
957 if (tmp1)
958 *tmp1++ = ',';
959 proposer_values = tmp1;
960 } while (proposer_values);
961
962out:
963 return proposer_values;
964}
965
Nicholas Bellinger9977bb12012-09-29 21:49:59 -0700966static int iscsi_check_acceptor_state(struct iscsi_param *param, char *value,
967 struct iscsi_conn *conn)
Nicholas Bellingere48354c2011-07-23 06:43:04 +0000968{
969 u8 acceptor_boolean_value = 0, proposer_boolean_value = 0;
970 char *negoitated_value = NULL;
971
972 if (IS_PSTATE_ACCEPTOR(param)) {
973 pr_err("Received key \"%s\" twice, protocol error.\n",
974 param->name);
975 return -1;
976 }
977
978 if (IS_PSTATE_REJECT(param))
979 return 0;
980
981 if (IS_TYPE_BOOL_AND(param)) {
982 if (!strcmp(value, YES))
983 proposer_boolean_value = 1;
984 if (!strcmp(param->value, YES))
985 acceptor_boolean_value = 1;
986 if (acceptor_boolean_value && proposer_boolean_value)
987 do {} while (0);
988 else {
989 if (iscsi_update_param_value(param, NO) < 0)
990 return -1;
991 if (!proposer_boolean_value)
992 SET_PSTATE_REPLY_OPTIONAL(param);
993 }
994 } else if (IS_TYPE_BOOL_OR(param)) {
995 if (!strcmp(value, YES))
996 proposer_boolean_value = 1;
997 if (!strcmp(param->value, YES))
998 acceptor_boolean_value = 1;
999 if (acceptor_boolean_value || proposer_boolean_value) {
1000 if (iscsi_update_param_value(param, YES) < 0)
1001 return -1;
1002 if (proposer_boolean_value)
1003 SET_PSTATE_REPLY_OPTIONAL(param);
1004 }
1005 } else if (IS_TYPE_NUMBER(param)) {
Dan Carpenter1be29562013-01-24 10:06:37 +03001006 char *tmpptr, buf[11];
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001007 u32 acceptor_value = simple_strtoul(param->value, &tmpptr, 0);
1008 u32 proposer_value = simple_strtoul(value, &tmpptr, 0);
1009
Dan Carpenter1be29562013-01-24 10:06:37 +03001010 memset(buf, 0, sizeof(buf));
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001011
1012 if (!strcmp(param->name, MAXCONNECTIONS) ||
1013 !strcmp(param->name, MAXBURSTLENGTH) ||
1014 !strcmp(param->name, FIRSTBURSTLENGTH) ||
1015 !strcmp(param->name, MAXOUTSTANDINGR2T) ||
1016 !strcmp(param->name, DEFAULTTIME2RETAIN) ||
1017 !strcmp(param->name, ERRORRECOVERYLEVEL)) {
1018 if (proposer_value > acceptor_value) {
1019 sprintf(buf, "%u", acceptor_value);
1020 if (iscsi_update_param_value(param,
1021 &buf[0]) < 0)
1022 return -1;
1023 } else {
1024 if (iscsi_update_param_value(param, value) < 0)
1025 return -1;
1026 }
1027 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1028 if (acceptor_value > proposer_value) {
1029 sprintf(buf, "%u", acceptor_value);
1030 if (iscsi_update_param_value(param,
1031 &buf[0]) < 0)
1032 return -1;
1033 } else {
1034 if (iscsi_update_param_value(param, value) < 0)
1035 return -1;
1036 }
1037 } else {
1038 if (iscsi_update_param_value(param, value) < 0)
1039 return -1;
1040 }
1041
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001042 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
1043 struct iscsi_param *param_mxdsl;
1044 unsigned long long tmp;
1045 int rc;
1046
Jingoo Han57103d72013-07-19 16:22:19 +09001047 rc = kstrtoull(param->value, 0, &tmp);
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001048 if (rc < 0)
1049 return -1;
1050
1051 conn->conn_ops->MaxRecvDataSegmentLength = tmp;
1052 pr_debug("Saving op->MaxRecvDataSegmentLength from"
1053 " original initiator received value: %u\n",
1054 conn->conn_ops->MaxRecvDataSegmentLength);
1055
1056 param_mxdsl = iscsi_find_param_from_key(
1057 MAXXMITDATASEGMENTLENGTH,
1058 conn->param_list);
1059 if (!param_mxdsl)
1060 return -1;
1061
1062 rc = iscsi_update_param_value(param,
1063 param_mxdsl->value);
1064 if (rc < 0)
1065 return -1;
1066
1067 pr_debug("Updated %s to target MXDSL value: %s\n",
1068 param->name, param->value);
1069 }
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001070 } else if (IS_TYPE_VALUE_LIST(param)) {
1071 negoitated_value = iscsi_check_valuelist_for_support(
1072 param, value);
1073 if (!negoitated_value) {
1074 pr_err("Proposer's value list \"%s\" contains"
1075 " no valid values from Acceptor's value list"
1076 " \"%s\".\n", value, param->value);
1077 return -1;
1078 }
1079 if (iscsi_update_param_value(param, negoitated_value) < 0)
1080 return -1;
1081 } else if (IS_PHASE_DECLARATIVE(param)) {
1082 if (iscsi_update_param_value(param, value) < 0)
1083 return -1;
1084 SET_PSTATE_REPLY_OPTIONAL(param);
1085 }
1086
1087 return 0;
1088}
1089
1090static int iscsi_check_proposer_state(struct iscsi_param *param, char *value)
1091{
1092 if (IS_PSTATE_RESPONSE_GOT(param)) {
1093 pr_err("Received key \"%s\" twice, protocol error.\n",
1094 param->name);
1095 return -1;
1096 }
1097
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +02001098 if (IS_TYPE_VALUE_LIST(param)) {
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001099 char *comma_ptr = NULL, *tmp_ptr = NULL;
1100
1101 comma_ptr = strchr(value, ',');
1102 if (comma_ptr) {
1103 pr_err("Illegal \",\" in response for \"%s\".\n",
1104 param->name);
1105 return -1;
1106 }
1107
1108 tmp_ptr = iscsi_check_valuelist_for_support(param, value);
1109 if (!tmp_ptr)
1110 return -1;
1111 }
1112
1113 if (iscsi_update_param_value(param, value) < 0)
1114 return -1;
1115
1116 return 0;
1117}
1118
1119static int iscsi_check_value(struct iscsi_param *param, char *value)
1120{
1121 char *comma_ptr = NULL;
1122
1123 if (!strcmp(value, REJECT)) {
1124 if (!strcmp(param->name, IFMARKINT) ||
1125 !strcmp(param->name, OFMARKINT)) {
1126 /*
1127 * Reject is not fatal for [I,O]FMarkInt, and causes
1128 * [I,O]FMarker to be reset to No. (See iSCSI v20 A.3.2)
1129 */
1130 SET_PSTATE_REJECT(param);
1131 return 0;
1132 }
1133 pr_err("Received %s=%s\n", param->name, value);
1134 return -1;
1135 }
1136 if (!strcmp(value, IRRELEVANT)) {
1137 pr_debug("Received %s=%s\n", param->name, value);
1138 SET_PSTATE_IRRELEVANT(param);
1139 return 0;
1140 }
1141 if (!strcmp(value, NOTUNDERSTOOD)) {
1142 if (!IS_PSTATE_PROPOSER(param)) {
1143 pr_err("Received illegal offer %s=%s\n",
1144 param->name, value);
1145 return -1;
1146 }
1147
1148/* #warning FIXME: Add check for X-ExtensionKey here */
1149 pr_err("Standard iSCSI key \"%s\" cannot be answered"
1150 " with \"%s\", protocol error.\n", param->name, value);
1151 return -1;
1152 }
1153
1154 do {
1155 comma_ptr = NULL;
1156 comma_ptr = strchr(value, ',');
1157
1158 if (comma_ptr && !IS_TYPE_VALUE_LIST(param)) {
Masanari Iida59e13d42012-04-25 00:24:16 +09001159 pr_err("Detected value separator \",\", but"
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001160 " key \"%s\" does not allow a value list,"
1161 " protocol error.\n", param->name);
1162 return -1;
1163 }
1164 if (comma_ptr)
1165 *comma_ptr = '\0';
1166
1167 if (strlen(value) > VALUE_MAXLEN) {
1168 pr_err("Value for key \"%s\" exceeds %d,"
1169 " protocol error.\n", param->name,
1170 VALUE_MAXLEN);
1171 return -1;
1172 }
1173
1174 if (IS_TYPE_BOOL_AND(param) || IS_TYPE_BOOL_OR(param)) {
1175 if (iscsi_check_boolean_value(param, value) < 0)
1176 return -1;
1177 } else if (IS_TYPE_NUMBER(param)) {
1178 if (iscsi_check_numerical_value(param, value) < 0)
1179 return -1;
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001180 } else if (IS_TYPE_STRING(param) || IS_TYPE_VALUE_LIST(param)) {
1181 if (iscsi_check_string_or_list_value(param, value) < 0)
1182 return -1;
1183 } else {
1184 pr_err("Huh? 0x%02x\n", param->type);
1185 return -1;
1186 }
1187
1188 if (comma_ptr)
1189 *comma_ptr++ = ',';
1190
1191 value = comma_ptr;
1192 } while (value);
1193
1194 return 0;
1195}
1196
1197static struct iscsi_param *__iscsi_check_key(
1198 char *key,
1199 int sender,
1200 struct iscsi_param_list *param_list)
1201{
1202 struct iscsi_param *param;
1203
1204 if (strlen(key) > KEY_MAXLEN) {
1205 pr_err("Length of key name \"%s\" exceeds %d.\n",
1206 key, KEY_MAXLEN);
1207 return NULL;
1208 }
1209
1210 param = iscsi_find_param_from_key(key, param_list);
1211 if (!param)
1212 return NULL;
1213
1214 if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1215 pr_err("Key \"%s\" may not be sent to %s,"
1216 " protocol error.\n", param->name,
1217 (sender & SENDER_RECEIVER) ? "target" : "initiator");
1218 return NULL;
1219 }
1220
1221 if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1222 pr_err("Key \"%s\" may not be sent to %s,"
1223 " protocol error.\n", param->name,
1224 (sender & SENDER_RECEIVER) ? "initiator" : "target");
1225 return NULL;
1226 }
1227
1228 return param;
1229}
1230
1231static struct iscsi_param *iscsi_check_key(
1232 char *key,
1233 int phase,
1234 int sender,
1235 struct iscsi_param_list *param_list)
1236{
1237 struct iscsi_param *param;
1238 /*
1239 * Key name length must not exceed 63 bytes. (See iSCSI v20 5.1)
1240 */
1241 if (strlen(key) > KEY_MAXLEN) {
1242 pr_err("Length of key name \"%s\" exceeds %d.\n",
1243 key, KEY_MAXLEN);
1244 return NULL;
1245 }
1246
1247 param = iscsi_find_param_from_key(key, param_list);
1248 if (!param)
1249 return NULL;
1250
1251 if ((sender & SENDER_INITIATOR) && !IS_SENDER_INITIATOR(param)) {
1252 pr_err("Key \"%s\" may not be sent to %s,"
1253 " protocol error.\n", param->name,
1254 (sender & SENDER_RECEIVER) ? "target" : "initiator");
1255 return NULL;
1256 }
1257 if ((sender & SENDER_TARGET) && !IS_SENDER_TARGET(param)) {
1258 pr_err("Key \"%s\" may not be sent to %s,"
1259 " protocol error.\n", param->name,
1260 (sender & SENDER_RECEIVER) ? "initiator" : "target");
1261 return NULL;
1262 }
1263
1264 if (IS_PSTATE_ACCEPTOR(param)) {
1265 pr_err("Key \"%s\" received twice, protocol error.\n",
1266 key);
1267 return NULL;
1268 }
1269
1270 if (!phase)
1271 return param;
1272
1273 if (!(param->phase & phase)) {
1274 pr_err("Key \"%s\" may not be negotiated during ",
1275 param->name);
1276 switch (phase) {
1277 case PHASE_SECURITY:
1278 pr_debug("Security phase.\n");
1279 break;
1280 case PHASE_OPERATIONAL:
1281 pr_debug("Operational phase.\n");
Alan Coxdb831012012-10-16 11:52:32 +01001282 break;
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001283 default:
1284 pr_debug("Unknown phase.\n");
1285 }
1286 return NULL;
1287 }
1288
1289 return param;
1290}
1291
1292static int iscsi_enforce_integrity_rules(
1293 u8 phase,
1294 struct iscsi_param_list *param_list)
1295{
1296 char *tmpptr;
1297 u8 DataSequenceInOrder = 0;
1298 u8 ErrorRecoveryLevel = 0, SessionType = 0;
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001299 u32 FirstBurstLength = 0, MaxBurstLength = 0;
1300 struct iscsi_param *param = NULL;
1301
1302 list_for_each_entry(param, &param_list->param_list, p_list) {
1303 if (!(param->phase & phase))
1304 continue;
1305 if (!strcmp(param->name, SESSIONTYPE))
1306 if (!strcmp(param->value, NORMAL))
1307 SessionType = 1;
1308 if (!strcmp(param->name, ERRORRECOVERYLEVEL))
1309 ErrorRecoveryLevel = simple_strtoul(param->value,
1310 &tmpptr, 0);
1311 if (!strcmp(param->name, DATASEQUENCEINORDER))
1312 if (!strcmp(param->value, YES))
1313 DataSequenceInOrder = 1;
1314 if (!strcmp(param->name, MAXBURSTLENGTH))
1315 MaxBurstLength = simple_strtoul(param->value,
1316 &tmpptr, 0);
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001317 }
1318
1319 list_for_each_entry(param, &param_list->param_list, p_list) {
1320 if (!(param->phase & phase))
1321 continue;
Christophe Vu-Brugierc04a6092015-04-19 22:18:33 +02001322 if (!SessionType && !IS_PSTATE_ACCEPTOR(param))
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001323 continue;
1324 if (!strcmp(param->name, MAXOUTSTANDINGR2T) &&
1325 DataSequenceInOrder && (ErrorRecoveryLevel > 0)) {
1326 if (strcmp(param->value, "1")) {
1327 if (iscsi_update_param_value(param, "1") < 0)
1328 return -1;
1329 pr_debug("Reset \"%s\" to \"%s\".\n",
1330 param->name, param->value);
1331 }
1332 }
1333 if (!strcmp(param->name, MAXCONNECTIONS) && !SessionType) {
1334 if (strcmp(param->value, "1")) {
1335 if (iscsi_update_param_value(param, "1") < 0)
1336 return -1;
1337 pr_debug("Reset \"%s\" to \"%s\".\n",
1338 param->name, param->value);
1339 }
1340 }
1341 if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1342 FirstBurstLength = simple_strtoul(param->value,
1343 &tmpptr, 0);
1344 if (FirstBurstLength > MaxBurstLength) {
Dan Carpenter1be29562013-01-24 10:06:37 +03001345 char tmpbuf[11];
1346 memset(tmpbuf, 0, sizeof(tmpbuf));
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001347 sprintf(tmpbuf, "%u", MaxBurstLength);
1348 if (iscsi_update_param_value(param, tmpbuf))
1349 return -1;
1350 pr_debug("Reset \"%s\" to \"%s\".\n",
1351 param->name, param->value);
1352 }
1353 }
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001354 }
1355
1356 return 0;
1357}
1358
1359int iscsi_decode_text_input(
1360 u8 phase,
1361 u8 sender,
1362 char *textbuf,
1363 u32 length,
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001364 struct iscsi_conn *conn)
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001365{
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001366 struct iscsi_param_list *param_list = conn->param_list;
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001367 char *tmpbuf, *start = NULL, *end = NULL;
1368
1369 tmpbuf = kzalloc(length + 1, GFP_KERNEL);
1370 if (!tmpbuf) {
Roland Dreiercee60292014-05-29 13:32:29 -07001371 pr_err("Unable to allocate %u + 1 bytes for tmpbuf.\n", length);
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001372 return -1;
1373 }
1374
1375 memcpy(tmpbuf, textbuf, length);
1376 tmpbuf[length] = '\0';
1377 start = tmpbuf;
1378 end = (start + length);
1379
1380 while (start < end) {
1381 char *key, *value;
1382 struct iscsi_param *param;
1383
1384 if (iscsi_extract_key_value(start, &key, &value) < 0) {
1385 kfree(tmpbuf);
1386 return -1;
1387 }
1388
1389 pr_debug("Got key: %s=%s\n", key, value);
1390
1391 if (phase & PHASE_SECURITY) {
1392 if (iscsi_check_for_auth_key(key) > 0) {
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001393 kfree(tmpbuf);
1394 return 1;
1395 }
1396 }
1397
1398 param = iscsi_check_key(key, phase, sender, param_list);
1399 if (!param) {
1400 if (iscsi_add_notunderstood_response(key,
1401 value, param_list) < 0) {
1402 kfree(tmpbuf);
1403 return -1;
1404 }
1405 start += strlen(key) + strlen(value) + 2;
1406 continue;
1407 }
1408 if (iscsi_check_value(param, value) < 0) {
1409 kfree(tmpbuf);
1410 return -1;
1411 }
1412
1413 start += strlen(key) + strlen(value) + 2;
1414
1415 if (IS_PSTATE_PROPOSER(param)) {
1416 if (iscsi_check_proposer_state(param, value) < 0) {
1417 kfree(tmpbuf);
1418 return -1;
1419 }
1420 SET_PSTATE_RESPONSE_GOT(param);
1421 } else {
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001422 if (iscsi_check_acceptor_state(param, value, conn) < 0) {
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001423 kfree(tmpbuf);
1424 return -1;
1425 }
1426 SET_PSTATE_ACCEPTOR(param);
1427 }
1428 }
1429
1430 kfree(tmpbuf);
1431 return 0;
1432}
1433
1434int iscsi_encode_text_output(
1435 u8 phase,
1436 u8 sender,
1437 char *textbuf,
1438 u32 *length,
1439 struct iscsi_param_list *param_list)
1440{
1441 char *output_buf = NULL;
1442 struct iscsi_extra_response *er;
1443 struct iscsi_param *param;
1444
1445 output_buf = textbuf + *length;
1446
1447 if (iscsi_enforce_integrity_rules(phase, param_list) < 0)
1448 return -1;
1449
1450 list_for_each_entry(param, &param_list->param_list, p_list) {
1451 if (!(param->sender & sender))
1452 continue;
1453 if (IS_PSTATE_ACCEPTOR(param) &&
1454 !IS_PSTATE_RESPONSE_SENT(param) &&
1455 !IS_PSTATE_REPLY_OPTIONAL(param) &&
1456 (param->phase & phase)) {
1457 *length += sprintf(output_buf, "%s=%s",
1458 param->name, param->value);
1459 *length += 1;
1460 output_buf = textbuf + *length;
1461 SET_PSTATE_RESPONSE_SENT(param);
1462 pr_debug("Sending key: %s=%s\n",
1463 param->name, param->value);
1464 continue;
1465 }
1466 if (IS_PSTATE_NEGOTIATE(param) &&
1467 !IS_PSTATE_ACCEPTOR(param) &&
1468 !IS_PSTATE_PROPOSER(param) &&
1469 (param->phase & phase)) {
1470 *length += sprintf(output_buf, "%s=%s",
1471 param->name, param->value);
1472 *length += 1;
1473 output_buf = textbuf + *length;
1474 SET_PSTATE_PROPOSER(param);
1475 iscsi_check_proposer_for_optional_reply(param);
1476 pr_debug("Sending key: %s=%s\n",
1477 param->name, param->value);
1478 }
1479 }
1480
1481 list_for_each_entry(er, &param_list->extra_response_list, er_list) {
1482 *length += sprintf(output_buf, "%s=%s", er->key, er->value);
1483 *length += 1;
1484 output_buf = textbuf + *length;
1485 pr_debug("Sending key: %s=%s\n", er->key, er->value);
1486 }
1487 iscsi_release_extra_responses(param_list);
1488
1489 return 0;
1490}
1491
1492int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list)
1493{
1494 int ret = 0;
1495 struct iscsi_param *param;
1496
1497 list_for_each_entry(param, &param_list->param_list, p_list) {
1498 if (IS_PSTATE_NEGOTIATE(param) &&
1499 IS_PSTATE_PROPOSER(param) &&
1500 !IS_PSTATE_RESPONSE_GOT(param) &&
1501 !IS_PSTATE_REPLY_OPTIONAL(param) &&
1502 !IS_PHASE_DECLARATIVE(param)) {
1503 pr_err("No response for proposed key \"%s\".\n",
1504 param->name);
1505 ret = -1;
1506 }
1507 }
1508
1509 return ret;
1510}
1511
1512int iscsi_change_param_value(
1513 char *keyvalue,
1514 struct iscsi_param_list *param_list,
1515 int check_key)
1516{
1517 char *key = NULL, *value = NULL;
1518 struct iscsi_param *param;
1519 int sender = 0;
1520
1521 if (iscsi_extract_key_value(keyvalue, &key, &value) < 0)
1522 return -1;
1523
1524 if (!check_key) {
1525 param = __iscsi_check_key(keyvalue, sender, param_list);
1526 if (!param)
1527 return -1;
1528 } else {
1529 param = iscsi_check_key(keyvalue, 0, sender, param_list);
1530 if (!param)
1531 return -1;
1532
1533 param->set_param = 1;
1534 if (iscsi_check_value(param, value) < 0) {
1535 param->set_param = 0;
1536 return -1;
1537 }
1538 param->set_param = 0;
1539 }
1540
1541 if (iscsi_update_param_value(param, value) < 0)
1542 return -1;
1543
1544 return 0;
1545}
1546
1547void iscsi_set_connection_parameters(
1548 struct iscsi_conn_ops *ops,
1549 struct iscsi_param_list *param_list)
1550{
1551 char *tmpptr;
1552 struct iscsi_param *param;
1553
1554 pr_debug("---------------------------------------------------"
1555 "---------------\n");
1556 list_for_each_entry(param, &param_list->param_list, p_list) {
Nicholas Bellingere004cb22012-09-29 21:47:16 -07001557 /*
1558 * Special case to set MAXXMITDATASEGMENTLENGTH from the
1559 * target requested MaxRecvDataSegmentLength, even though
1560 * this key is not sent over the wire.
1561 */
1562 if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
1563 ops->MaxXmitDataSegmentLength =
1564 simple_strtoul(param->value, &tmpptr, 0);
1565 pr_debug("MaxXmitDataSegmentLength: %s\n",
1566 param->value);
1567 }
1568
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001569 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1570 continue;
1571 if (!strcmp(param->name, AUTHMETHOD)) {
1572 pr_debug("AuthMethod: %s\n",
1573 param->value);
1574 } else if (!strcmp(param->name, HEADERDIGEST)) {
1575 ops->HeaderDigest = !strcmp(param->value, CRC32C);
1576 pr_debug("HeaderDigest: %s\n",
1577 param->value);
1578 } else if (!strcmp(param->name, DATADIGEST)) {
1579 ops->DataDigest = !strcmp(param->value, CRC32C);
1580 pr_debug("DataDigest: %s\n",
1581 param->value);
1582 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
Nicholas Bellinger9977bb12012-09-29 21:49:59 -07001583 /*
1584 * At this point iscsi_check_acceptor_state() will have
1585 * set ops->MaxRecvDataSegmentLength from the original
1586 * initiator provided value.
1587 */
1588 pr_debug("MaxRecvDataSegmentLength: %u\n",
1589 ops->MaxRecvDataSegmentLength);
Nicholas Bellinger03aa2072013-03-06 21:54:38 -08001590 } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
1591 ops->InitiatorRecvDataSegmentLength =
1592 simple_strtoul(param->value, &tmpptr, 0);
1593 pr_debug("InitiatorRecvDataSegmentLength: %s\n",
1594 param->value);
1595 ops->MaxRecvDataSegmentLength =
1596 ops->InitiatorRecvDataSegmentLength;
1597 pr_debug("Set MRDSL from InitiatorRecvDataSegmentLength\n");
1598 } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
1599 ops->TargetRecvDataSegmentLength =
1600 simple_strtoul(param->value, &tmpptr, 0);
1601 pr_debug("TargetRecvDataSegmentLength: %s\n",
1602 param->value);
1603 ops->MaxXmitDataSegmentLength =
1604 ops->TargetRecvDataSegmentLength;
1605 pr_debug("Set MXDSL from TargetRecvDataSegmentLength\n");
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001606 }
1607 }
1608 pr_debug("----------------------------------------------------"
1609 "--------------\n");
1610}
1611
1612void iscsi_set_session_parameters(
1613 struct iscsi_sess_ops *ops,
1614 struct iscsi_param_list *param_list,
1615 int leading)
1616{
1617 char *tmpptr;
1618 struct iscsi_param *param;
1619
1620 pr_debug("----------------------------------------------------"
1621 "--------------\n");
1622 list_for_each_entry(param, &param_list->param_list, p_list) {
1623 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param))
1624 continue;
1625 if (!strcmp(param->name, INITIATORNAME)) {
1626 if (!param->value)
1627 continue;
1628 if (leading)
1629 snprintf(ops->InitiatorName,
1630 sizeof(ops->InitiatorName),
1631 "%s", param->value);
1632 pr_debug("InitiatorName: %s\n",
1633 param->value);
1634 } else if (!strcmp(param->name, INITIATORALIAS)) {
1635 if (!param->value)
1636 continue;
1637 snprintf(ops->InitiatorAlias,
1638 sizeof(ops->InitiatorAlias),
1639 "%s", param->value);
1640 pr_debug("InitiatorAlias: %s\n",
1641 param->value);
1642 } else if (!strcmp(param->name, TARGETNAME)) {
1643 if (!param->value)
1644 continue;
1645 if (leading)
1646 snprintf(ops->TargetName,
1647 sizeof(ops->TargetName),
1648 "%s", param->value);
1649 pr_debug("TargetName: %s\n",
1650 param->value);
1651 } else if (!strcmp(param->name, TARGETALIAS)) {
1652 if (!param->value)
1653 continue;
1654 snprintf(ops->TargetAlias, sizeof(ops->TargetAlias),
1655 "%s", param->value);
1656 pr_debug("TargetAlias: %s\n",
1657 param->value);
1658 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) {
1659 ops->TargetPortalGroupTag =
1660 simple_strtoul(param->value, &tmpptr, 0);
1661 pr_debug("TargetPortalGroupTag: %s\n",
1662 param->value);
1663 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
1664 ops->MaxConnections =
1665 simple_strtoul(param->value, &tmpptr, 0);
1666 pr_debug("MaxConnections: %s\n",
1667 param->value);
1668 } else if (!strcmp(param->name, INITIALR2T)) {
1669 ops->InitialR2T = !strcmp(param->value, YES);
1670 pr_debug("InitialR2T: %s\n",
1671 param->value);
1672 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
1673 ops->ImmediateData = !strcmp(param->value, YES);
1674 pr_debug("ImmediateData: %s\n",
1675 param->value);
1676 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
1677 ops->MaxBurstLength =
1678 simple_strtoul(param->value, &tmpptr, 0);
1679 pr_debug("MaxBurstLength: %s\n",
1680 param->value);
1681 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) {
1682 ops->FirstBurstLength =
1683 simple_strtoul(param->value, &tmpptr, 0);
1684 pr_debug("FirstBurstLength: %s\n",
1685 param->value);
1686 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) {
1687 ops->DefaultTime2Wait =
1688 simple_strtoul(param->value, &tmpptr, 0);
1689 pr_debug("DefaultTime2Wait: %s\n",
1690 param->value);
1691 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) {
1692 ops->DefaultTime2Retain =
1693 simple_strtoul(param->value, &tmpptr, 0);
1694 pr_debug("DefaultTime2Retain: %s\n",
1695 param->value);
1696 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) {
1697 ops->MaxOutstandingR2T =
1698 simple_strtoul(param->value, &tmpptr, 0);
1699 pr_debug("MaxOutstandingR2T: %s\n",
1700 param->value);
1701 } else if (!strcmp(param->name, DATAPDUINORDER)) {
1702 ops->DataPDUInOrder = !strcmp(param->value, YES);
1703 pr_debug("DataPDUInOrder: %s\n",
1704 param->value);
1705 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) {
1706 ops->DataSequenceInOrder = !strcmp(param->value, YES);
1707 pr_debug("DataSequenceInOrder: %s\n",
1708 param->value);
1709 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) {
1710 ops->ErrorRecoveryLevel =
1711 simple_strtoul(param->value, &tmpptr, 0);
1712 pr_debug("ErrorRecoveryLevel: %s\n",
1713 param->value);
1714 } else if (!strcmp(param->name, SESSIONTYPE)) {
1715 ops->SessionType = !strcmp(param->value, DISCOVERY);
1716 pr_debug("SessionType: %s\n",
1717 param->value);
Nicholas Bellingeraf40bb02013-05-11 16:24:21 -07001718 } else if (!strcmp(param->name, RDMAEXTENSIONS)) {
Nicholas Bellinger03aa2072013-03-06 21:54:38 -08001719 ops->RDMAExtensions = !strcmp(param->value, YES);
1720 pr_debug("RDMAExtensions: %s\n",
1721 param->value);
Nicholas Bellingere48354c2011-07-23 06:43:04 +00001722 }
1723 }
1724 pr_debug("----------------------------------------------------"
1725 "--------------\n");
1726
1727}