1 /******************************************************************************* 2 * This file contains main functions related to iSCSI Parameter negotiation. 3 * 4 * \u00a9 Copyright 2007-2011 RisingTide Systems LLC. 5 * 6 * Licensed to the Linux Foundation under the General Public License (GPL) version 2. 7 * 8 * Author: Nicholas A. Bellinger <nab@linux-iscsi.org> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 ******************************************************************************/ 20 21 #include <linux/slab.h> 22 23 #include "iscsi_target_core.h" 24 #include "iscsi_target_util.h" 25 #include "iscsi_target_parameters.h" 26 27 int iscsi_login_rx_data( 28 struct iscsi_conn *conn, 29 char *buf, 30 int length) 31 { 32 int rx_got; 33 struct kvec iov; 34 35 memset(&iov, 0, sizeof(struct kvec)); 36 iov.iov_len = length; 37 iov.iov_base = buf; 38 39 /* 40 * Initial Marker-less Interval. 41 * Add the values regardless of IFMarker/OFMarker, considering 42 * it may not be negoitated yet. 43 */ 44 conn->of_marker += length; 45 46 rx_got = rx_data(conn, &iov, 1, length); 47 if (rx_got != length) { 48 pr_err("rx_data returned %d, expecting %d.\n", 49 rx_got, length); 50 return -1; 51 } 52 53 return 0 ; 54 } 55 56 int iscsi_login_tx_data( 57 struct iscsi_conn *conn, 58 char *pdu_buf, 59 char *text_buf, 60 int text_length) 61 { 62 int length, tx_sent; 63 struct kvec iov[2]; 64 65 length = (ISCSI_HDR_LEN + text_length); 66 67 memset(&iov[0], 0, 2 * sizeof(struct kvec)); 68 iov[0].iov_len = ISCSI_HDR_LEN; 69 iov[0].iov_base = pdu_buf; 70 iov[1].iov_len = text_length; 71 iov[1].iov_base = text_buf; 72 73 /* 74 * Initial Marker-less Interval. 75 * Add the values regardless of IFMarker/OFMarker, considering 76 * it may not be negoitated yet. 77 */ 78 conn->if_marker += length; 79 80 tx_sent = tx_data(conn, &iov[0], 2, length); 81 if (tx_sent != length) { 82 pr_err("tx_data returned %d, expecting %d.\n", 83 tx_sent, length); 84 return -1; 85 } 86 87 return 0; 88 } 89 90 void iscsi_dump_conn_ops(struct iscsi_conn_ops *conn_ops) 91 { 92 pr_debug("HeaderDigest: %s\n", (conn_ops->HeaderDigest) ? 93 "CRC32C" : "None"); 94 pr_debug("DataDigest: %s\n", (conn_ops->DataDigest) ? 95 "CRC32C" : "None"); 96 pr_debug("MaxRecvDataSegmentLength: %u\n", 97 conn_ops->MaxRecvDataSegmentLength); 98 pr_debug("OFMarker: %s\n", (conn_ops->OFMarker) ? "Yes" : "No"); 99 pr_debug("IFMarker: %s\n", (conn_ops->IFMarker) ? "Yes" : "No"); 100 if (conn_ops->OFMarker) 101 pr_debug("OFMarkInt: %u\n", conn_ops->OFMarkInt); 102 if (conn_ops->IFMarker) 103 pr_debug("IFMarkInt: %u\n", conn_ops->IFMarkInt); 104 } 105 106 void iscsi_dump_sess_ops(struct iscsi_sess_ops *sess_ops) 107 { 108 pr_debug("InitiatorName: %s\n", sess_ops->InitiatorName); 109 pr_debug("InitiatorAlias: %s\n", sess_ops->InitiatorAlias); 110 pr_debug("TargetName: %s\n", sess_ops->TargetName); 111 pr_debug("TargetAlias: %s\n", sess_ops->TargetAlias); 112 pr_debug("TargetPortalGroupTag: %hu\n", 113 sess_ops->TargetPortalGroupTag); 114 pr_debug("MaxConnections: %hu\n", sess_ops->MaxConnections); 115 pr_debug("InitialR2T: %s\n", 116 (sess_ops->InitialR2T) ? "Yes" : "No"); 117 pr_debug("ImmediateData: %s\n", (sess_ops->ImmediateData) ? 118 "Yes" : "No"); 119 pr_debug("MaxBurstLength: %u\n", sess_ops->MaxBurstLength); 120 pr_debug("FirstBurstLength: %u\n", sess_ops->FirstBurstLength); 121 pr_debug("DefaultTime2Wait: %hu\n", sess_ops->DefaultTime2Wait); 122 pr_debug("DefaultTime2Retain: %hu\n", 123 sess_ops->DefaultTime2Retain); 124 pr_debug("MaxOutstandingR2T: %hu\n", 125 sess_ops->MaxOutstandingR2T); 126 pr_debug("DataPDUInOrder: %s\n", 127 (sess_ops->DataPDUInOrder) ? "Yes" : "No"); 128 pr_debug("DataSequenceInOrder: %s\n", 129 (sess_ops->DataSequenceInOrder) ? "Yes" : "No"); 130 pr_debug("ErrorRecoveryLevel: %hu\n", 131 sess_ops->ErrorRecoveryLevel); 132 pr_debug("SessionType: %s\n", (sess_ops->SessionType) ? 133 "Discovery" : "Normal"); 134 } 135 136 void iscsi_print_params(struct iscsi_param_list *param_list) 137 { 138 struct iscsi_param *param; 139 140 list_for_each_entry(param, ¶m_list->param_list, p_list) 141 pr_debug("%s: %s\n", param->name, param->value); 142 } 143 144 static struct iscsi_param *iscsi_set_default_param(struct iscsi_param_list *param_list, 145 char *name, char *value, u8 phase, u8 scope, u8 sender, 146 u16 type_range, u8 use) 147 { 148 struct iscsi_param *param = NULL; 149 150 param = kzalloc(sizeof(struct iscsi_param), GFP_KERNEL); 151 if (!param) { 152 pr_err("Unable to allocate memory for parameter.\n"); 153 goto out; 154 } 155 INIT_LIST_HEAD(¶m->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(¶m->p_list, ¶m_list->param_list); 215 216 return param; 217 out: 218 if (param) { 219 kfree(param->value); 220 kfree(param->name); 221 kfree(param); 222 } 223 224 return NULL; 225 } 226 227 /* #warning Add extension keys */ 228 int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr) 229 { 230 struct iscsi_param *param = NULL; 231 struct iscsi_param_list *pl; 232 233 pl = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); 234 if (!pl) { 235 pr_err("Unable to allocate memory for" 236 " struct iscsi_param_list.\n"); 237 return -1 ; 238 } 239 INIT_LIST_HEAD(&pl->param_list); 240 INIT_LIST_HEAD(&pl->extra_response_list); 241 242 /* 243 * The format for setting the initial parameter definitions are: 244 * 245 * Parameter name: 246 * Initial value: 247 * Allowable phase: 248 * Scope: 249 * Allowable senders: 250 * Typerange: 251 * Use: 252 */ 253 param = iscsi_set_default_param(pl, AUTHMETHOD, INITIAL_AUTHMETHOD, 254 PHASE_SECURITY, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 255 TYPERANGE_AUTH, USE_INITIAL_ONLY); 256 if (!param) 257 goto out; 258 259 param = iscsi_set_default_param(pl, HEADERDIGEST, INITIAL_HEADERDIGEST, 260 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 261 TYPERANGE_DIGEST, USE_INITIAL_ONLY); 262 if (!param) 263 goto out; 264 265 param = iscsi_set_default_param(pl, DATADIGEST, INITIAL_DATADIGEST, 266 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 267 TYPERANGE_DIGEST, USE_INITIAL_ONLY); 268 if (!param) 269 goto out; 270 271 param = iscsi_set_default_param(pl, MAXCONNECTIONS, 272 INITIAL_MAXCONNECTIONS, PHASE_OPERATIONAL, 273 SCOPE_SESSION_WIDE, SENDER_BOTH, 274 TYPERANGE_1_TO_65535, USE_LEADING_ONLY); 275 if (!param) 276 goto out; 277 278 param = iscsi_set_default_param(pl, SENDTARGETS, INITIAL_SENDTARGETS, 279 PHASE_FFP0, SCOPE_SESSION_WIDE, SENDER_INITIATOR, 280 TYPERANGE_UTF8, 0); 281 if (!param) 282 goto out; 283 284 param = iscsi_set_default_param(pl, TARGETNAME, INITIAL_TARGETNAME, 285 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_BOTH, 286 TYPERANGE_ISCSINAME, USE_ALL); 287 if (!param) 288 goto out; 289 290 param = iscsi_set_default_param(pl, INITIATORNAME, 291 INITIAL_INITIATORNAME, PHASE_DECLARATIVE, 292 SCOPE_SESSION_WIDE, SENDER_INITIATOR, 293 TYPERANGE_ISCSINAME, USE_INITIAL_ONLY); 294 if (!param) 295 goto out; 296 297 param = iscsi_set_default_param(pl, TARGETALIAS, INITIAL_TARGETALIAS, 298 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET, 299 TYPERANGE_UTF8, USE_ALL); 300 if (!param) 301 goto out; 302 303 param = iscsi_set_default_param(pl, INITIATORALIAS, 304 INITIAL_INITIATORALIAS, PHASE_DECLARATIVE, 305 SCOPE_SESSION_WIDE, SENDER_INITIATOR, TYPERANGE_UTF8, 306 USE_ALL); 307 if (!param) 308 goto out; 309 310 param = iscsi_set_default_param(pl, TARGETADDRESS, 311 INITIAL_TARGETADDRESS, PHASE_DECLARATIVE, 312 SCOPE_SESSION_WIDE, SENDER_TARGET, 313 TYPERANGE_TARGETADDRESS, USE_ALL); 314 if (!param) 315 goto out; 316 317 param = iscsi_set_default_param(pl, TARGETPORTALGROUPTAG, 318 INITIAL_TARGETPORTALGROUPTAG, 319 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_TARGET, 320 TYPERANGE_0_TO_65535, USE_INITIAL_ONLY); 321 if (!param) 322 goto out; 323 324 param = iscsi_set_default_param(pl, INITIALR2T, INITIAL_INITIALR2T, 325 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 326 TYPERANGE_BOOL_OR, USE_LEADING_ONLY); 327 if (!param) 328 goto out; 329 330 param = iscsi_set_default_param(pl, IMMEDIATEDATA, 331 INITIAL_IMMEDIATEDATA, PHASE_OPERATIONAL, 332 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_AND, 333 USE_LEADING_ONLY); 334 if (!param) 335 goto out; 336 337 param = iscsi_set_default_param(pl, MAXRECVDATASEGMENTLENGTH, 338 INITIAL_MAXRECVDATASEGMENTLENGTH, 339 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 340 TYPERANGE_512_TO_16777215, USE_ALL); 341 if (!param) 342 goto out; 343 344 param = iscsi_set_default_param(pl, MAXBURSTLENGTH, 345 INITIAL_MAXBURSTLENGTH, PHASE_OPERATIONAL, 346 SCOPE_SESSION_WIDE, SENDER_BOTH, 347 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY); 348 if (!param) 349 goto out; 350 351 param = iscsi_set_default_param(pl, FIRSTBURSTLENGTH, 352 INITIAL_FIRSTBURSTLENGTH, 353 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 354 TYPERANGE_512_TO_16777215, USE_LEADING_ONLY); 355 if (!param) 356 goto out; 357 358 param = iscsi_set_default_param(pl, DEFAULTTIME2WAIT, 359 INITIAL_DEFAULTTIME2WAIT, 360 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 361 TYPERANGE_0_TO_3600, USE_LEADING_ONLY); 362 if (!param) 363 goto out; 364 365 param = iscsi_set_default_param(pl, DEFAULTTIME2RETAIN, 366 INITIAL_DEFAULTTIME2RETAIN, 367 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 368 TYPERANGE_0_TO_3600, USE_LEADING_ONLY); 369 if (!param) 370 goto out; 371 372 param = iscsi_set_default_param(pl, MAXOUTSTANDINGR2T, 373 INITIAL_MAXOUTSTANDINGR2T, 374 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 375 TYPERANGE_1_TO_65535, USE_LEADING_ONLY); 376 if (!param) 377 goto out; 378 379 param = iscsi_set_default_param(pl, DATAPDUINORDER, 380 INITIAL_DATAPDUINORDER, PHASE_OPERATIONAL, 381 SCOPE_SESSION_WIDE, SENDER_BOTH, TYPERANGE_BOOL_OR, 382 USE_LEADING_ONLY); 383 if (!param) 384 goto out; 385 386 param = iscsi_set_default_param(pl, DATASEQUENCEINORDER, 387 INITIAL_DATASEQUENCEINORDER, 388 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 389 TYPERANGE_BOOL_OR, USE_LEADING_ONLY); 390 if (!param) 391 goto out; 392 393 param = iscsi_set_default_param(pl, ERRORRECOVERYLEVEL, 394 INITIAL_ERRORRECOVERYLEVEL, 395 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH, 396 TYPERANGE_0_TO_2, USE_LEADING_ONLY); 397 if (!param) 398 goto out; 399 400 param = iscsi_set_default_param(pl, SESSIONTYPE, INITIAL_SESSIONTYPE, 401 PHASE_DECLARATIVE, SCOPE_SESSION_WIDE, SENDER_INITIATOR, 402 TYPERANGE_SESSIONTYPE, USE_LEADING_ONLY); 403 if (!param) 404 goto out; 405 406 param = iscsi_set_default_param(pl, IFMARKER, INITIAL_IFMARKER, 407 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 408 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY); 409 if (!param) 410 goto out; 411 412 param = iscsi_set_default_param(pl, OFMARKER, INITIAL_OFMARKER, 413 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 414 TYPERANGE_BOOL_AND, USE_INITIAL_ONLY); 415 if (!param) 416 goto out; 417 418 param = iscsi_set_default_param(pl, IFMARKINT, INITIAL_IFMARKINT, 419 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 420 TYPERANGE_MARKINT, USE_INITIAL_ONLY); 421 if (!param) 422 goto out; 423 424 param = iscsi_set_default_param(pl, OFMARKINT, INITIAL_OFMARKINT, 425 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH, 426 TYPERANGE_MARKINT, USE_INITIAL_ONLY); 427 if (!param) 428 goto out; 429 430 *param_list_ptr = pl; 431 return 0; 432 out: 433 iscsi_release_param_list(pl); 434 return -1; 435 } 436 437 int iscsi_set_keys_to_negotiate( 438 int sessiontype, 439 struct iscsi_param_list *param_list) 440 { 441 struct iscsi_param *param; 442 443 list_for_each_entry(param, ¶m_list->param_list, p_list) { 444 param->state = 0; 445 if (!strcmp(param->name, AUTHMETHOD)) { 446 SET_PSTATE_NEGOTIATE(param); 447 } else if (!strcmp(param->name, HEADERDIGEST)) { 448 SET_PSTATE_NEGOTIATE(param); 449 } else if (!strcmp(param->name, DATADIGEST)) { 450 SET_PSTATE_NEGOTIATE(param); 451 } else if (!strcmp(param->name, MAXCONNECTIONS)) { 452 SET_PSTATE_NEGOTIATE(param); 453 } else if (!strcmp(param->name, TARGETNAME)) { 454 continue; 455 } else if (!strcmp(param->name, INITIATORNAME)) { 456 continue; 457 } else if (!strcmp(param->name, TARGETALIAS)) { 458 if (param->value) 459 SET_PSTATE_NEGOTIATE(param); 460 } else if (!strcmp(param->name, INITIATORALIAS)) { 461 continue; 462 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) { 463 SET_PSTATE_NEGOTIATE(param); 464 } else if (!strcmp(param->name, INITIALR2T)) { 465 SET_PSTATE_NEGOTIATE(param); 466 } else if (!strcmp(param->name, IMMEDIATEDATA)) { 467 SET_PSTATE_NEGOTIATE(param); 468 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { 469 SET_PSTATE_NEGOTIATE(param); 470 } else if (!strcmp(param->name, MAXBURSTLENGTH)) { 471 SET_PSTATE_NEGOTIATE(param); 472 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) { 473 SET_PSTATE_NEGOTIATE(param); 474 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) { 475 SET_PSTATE_NEGOTIATE(param); 476 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) { 477 SET_PSTATE_NEGOTIATE(param); 478 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) { 479 SET_PSTATE_NEGOTIATE(param); 480 } else if (!strcmp(param->name, DATAPDUINORDER)) { 481 SET_PSTATE_NEGOTIATE(param); 482 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) { 483 SET_PSTATE_NEGOTIATE(param); 484 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) { 485 SET_PSTATE_NEGOTIATE(param); 486 } else if (!strcmp(param->name, SESSIONTYPE)) { 487 SET_PSTATE_NEGOTIATE(param); 488 } else if (!strcmp(param->name, IFMARKER)) { 489 SET_PSTATE_NEGOTIATE(param); 490 } else if (!strcmp(param->name, OFMARKER)) { 491 SET_PSTATE_NEGOTIATE(param); 492 } else if (!strcmp(param->name, IFMARKINT)) { 493 SET_PSTATE_NEGOTIATE(param); 494 } else if (!strcmp(param->name, OFMARKINT)) { 495 SET_PSTATE_NEGOTIATE(param); 496 } 497 } 498 499 return 0; 500 } 501 502 int iscsi_set_keys_irrelevant_for_discovery( 503 struct iscsi_param_list *param_list) 504 { 505 struct iscsi_param *param; 506 507 list_for_each_entry(param, ¶m_list->param_list, p_list) { 508 if (!strcmp(param->name, MAXCONNECTIONS)) 509 param->state &= ~PSTATE_NEGOTIATE; 510 else if (!strcmp(param->name, INITIALR2T)) 511 param->state &= ~PSTATE_NEGOTIATE; 512 else if (!strcmp(param->name, IMMEDIATEDATA)) 513 param->state &= ~PSTATE_NEGOTIATE; 514 else if (!strcmp(param->name, MAXBURSTLENGTH)) 515 param->state &= ~PSTATE_NEGOTIATE; 516 else if (!strcmp(param->name, FIRSTBURSTLENGTH)) 517 param->state &= ~PSTATE_NEGOTIATE; 518 else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) 519 param->state &= ~PSTATE_NEGOTIATE; 520 else if (!strcmp(param->name, DATAPDUINORDER)) 521 param->state &= ~PSTATE_NEGOTIATE; 522 else if (!strcmp(param->name, DATASEQUENCEINORDER)) 523 param->state &= ~PSTATE_NEGOTIATE; 524 else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) 525 param->state &= ~PSTATE_NEGOTIATE; 526 else if (!strcmp(param->name, DEFAULTTIME2WAIT)) 527 param->state &= ~PSTATE_NEGOTIATE; 528 else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) 529 param->state &= ~PSTATE_NEGOTIATE; 530 else if (!strcmp(param->name, IFMARKER)) 531 param->state &= ~PSTATE_NEGOTIATE; 532 else if (!strcmp(param->name, OFMARKER)) 533 param->state &= ~PSTATE_NEGOTIATE; 534 else if (!strcmp(param->name, IFMARKINT)) 535 param->state &= ~PSTATE_NEGOTIATE; 536 else if (!strcmp(param->name, OFMARKINT)) 537 param->state &= ~PSTATE_NEGOTIATE; 538 } 539 540 return 0; 541 } 542 543 int iscsi_copy_param_list( 544 struct iscsi_param_list **dst_param_list, 545 struct iscsi_param_list *src_param_list, 546 int leading) 547 { 548 struct iscsi_param *param = NULL; 549 struct iscsi_param *new_param = NULL; 550 struct iscsi_param_list *param_list = NULL; 551 552 param_list = kzalloc(sizeof(struct iscsi_param_list), GFP_KERNEL); 553 if (!param_list) { 554 pr_err("Unable to allocate memory for struct iscsi_param_list.\n"); 555 goto err_out; 556 } 557 INIT_LIST_HEAD(¶m_list->param_list); 558 INIT_LIST_HEAD(¶m_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, ¶m_list->param_list); 593 } 594 595 if (!list_empty(¶m_list->param_list)) { 596 *dst_param_list = param_list; 597 } else { 598 pr_err("No parameters allocated.\n"); 599 goto err_out; 600 } 601 602 return 0; 603 604 err_out: 605 iscsi_release_param_list(param_list); 606 return -1; 607 } 608 609 static void iscsi_release_extra_responses(struct iscsi_param_list *param_list) 610 { 611 struct iscsi_extra_response *er, *er_tmp; 612 613 list_for_each_entry_safe(er, er_tmp, ¶m_list->extra_response_list, 614 er_list) { 615 list_del(&er->er_list); 616 kfree(er); 617 } 618 } 619 620 void iscsi_release_param_list(struct iscsi_param_list *param_list) 621 { 622 struct iscsi_param *param, *param_tmp; 623 624 list_for_each_entry_safe(param, param_tmp, ¶m_list->param_list, 625 p_list) { 626 list_del(¶m->p_list); 627 628 kfree(param->name); 629 param->name = NULL; 630 kfree(param->value); 631 param->value = NULL; 632 kfree(param); 633 param = NULL; 634 } 635 636 iscsi_release_extra_responses(param_list); 637 638 kfree(param_list); 639 } 640 641 struct iscsi_param *iscsi_find_param_from_key( 642 char *key, 643 struct iscsi_param_list *param_list) 644 { 645 struct iscsi_param *param; 646 647 if (!key || !param_list) { 648 pr_err("Key or parameter list pointer is NULL.\n"); 649 return NULL; 650 } 651 652 list_for_each_entry(param, ¶m_list->param_list, p_list) { 653 if (!strcmp(key, param->name)) 654 return param; 655 } 656 657 pr_err("Unable to locate key \"%s\".\n", key); 658 return NULL; 659 } 660 661 int iscsi_extract_key_value(char *textbuf, char **key, char **value) 662 { 663 *value = strchr(textbuf, '='); 664 if (!*value) { 665 pr_err("Unable to locate \"=\" seperator for key," 666 " ignoring request.\n"); 667 return -1; 668 } 669 670 *key = textbuf; 671 **value = '\0'; 672 *value = *value + 1; 673 674 return 0; 675 } 676 677 int iscsi_update_param_value(struct iscsi_param *param, char *value) 678 { 679 kfree(param->value); 680 681 param->value = kzalloc(strlen(value) + 1, GFP_KERNEL); 682 if (!param->value) { 683 pr_err("Unable to allocate memory for value.\n"); 684 return -1; 685 } 686 687 memcpy(param->value, value, strlen(value)); 688 param->value[strlen(value)] = '\0'; 689 690 pr_debug("iSCSI Parameter updated to %s=%s\n", 691 param->name, param->value); 692 return 0; 693 } 694 695 static int iscsi_add_notunderstood_response( 696 char *key, 697 char *value, 698 struct iscsi_param_list *param_list) 699 { 700 struct iscsi_extra_response *extra_response; 701 702 if (strlen(value) > VALUE_MAXLEN) { 703 pr_err("Value for notunderstood key \"%s\" exceeds %d," 704 " protocol error.\n", key, VALUE_MAXLEN); 705 return -1; 706 } 707 708 extra_response = kzalloc(sizeof(struct iscsi_extra_response), GFP_KERNEL); 709 if (!extra_response) { 710 pr_err("Unable to allocate memory for" 711 " struct iscsi_extra_response.\n"); 712 return -1; 713 } 714 INIT_LIST_HEAD(&extra_response->er_list); 715 716 strncpy(extra_response->key, key, strlen(key) + 1); 717 strncpy(extra_response->value, NOTUNDERSTOOD, 718 strlen(NOTUNDERSTOOD) + 1); 719 720 list_add_tail(&extra_response->er_list, 721 ¶m_list->extra_response_list); 722 return 0; 723 } 724 725 static int iscsi_check_for_auth_key(char *key) 726 { 727 /* 728 * RFC 1994 729 */ 730 if (!strcmp(key, "CHAP_A") || !strcmp(key, "CHAP_I") || 731 !strcmp(key, "CHAP_C") || !strcmp(key, "CHAP_N") || 732 !strcmp(key, "CHAP_R")) 733 return 1; 734 735 /* 736 * RFC 2945 737 */ 738 if (!strcmp(key, "SRP_U") || !strcmp(key, "SRP_N") || 739 !strcmp(key, "SRP_g") || !strcmp(key, "SRP_s") || 740 !strcmp(key, "SRP_A") || !strcmp(key, "SRP_B") || 741 !strcmp(key, "SRP_M") || !strcmp(key, "SRP_HM")) 742 return 1; 743 744 return 0; 745 } 746 747 static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) 748 { 749 if (IS_TYPE_BOOL_AND(param)) { 750 if (!strcmp(param->value, NO)) 751 SET_PSTATE_REPLY_OPTIONAL(param); 752 } else if (IS_TYPE_BOOL_OR(param)) { 753 if (!strcmp(param->value, YES)) 754 SET_PSTATE_REPLY_OPTIONAL(param); 755 /* 756 * Required for gPXE iSCSI boot client 757 */ 758 if (!strcmp(param->name, IMMEDIATEDATA)) 759 SET_PSTATE_REPLY_OPTIONAL(param); 760 } else if (IS_TYPE_NUMBER(param)) { 761 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) 762 SET_PSTATE_REPLY_OPTIONAL(param); 763 /* 764 * The GlobalSAN iSCSI Initiator for MacOSX does 765 * not respond to MaxBurstLength, FirstBurstLength, 766 * DefaultTime2Wait or DefaultTime2Retain parameter keys. 767 * So, we set them to 'reply optional' here, and assume the 768 * the defaults from iscsi_parameters.h if the initiator 769 * is not RFC compliant and the keys are not negotiated. 770 */ 771 if (!strcmp(param->name, MAXBURSTLENGTH)) 772 SET_PSTATE_REPLY_OPTIONAL(param); 773 if (!strcmp(param->name, FIRSTBURSTLENGTH)) 774 SET_PSTATE_REPLY_OPTIONAL(param); 775 if (!strcmp(param->name, DEFAULTTIME2WAIT)) 776 SET_PSTATE_REPLY_OPTIONAL(param); 777 if (!strcmp(param->name, DEFAULTTIME2RETAIN)) 778 SET_PSTATE_REPLY_OPTIONAL(param); 779 /* 780 * Required for gPXE iSCSI boot client 781 */ 782 if (!strcmp(param->name, MAXCONNECTIONS)) 783 SET_PSTATE_REPLY_OPTIONAL(param); 784 } else if (IS_PHASE_DECLARATIVE(param)) 785 SET_PSTATE_REPLY_OPTIONAL(param); 786 } 787 788 static int iscsi_check_boolean_value(struct iscsi_param *param, char *value) 789 { 790 if (strcmp(value, YES) && strcmp(value, NO)) { 791 pr_err("Illegal value for \"%s\", must be either" 792 " \"%s\" or \"%s\".\n", param->name, YES, NO); 793 return -1; 794 } 795 796 return 0; 797 } 798 799 static int iscsi_check_numerical_value(struct iscsi_param *param, char *value_ptr) 800 { 801 char *tmpptr; 802 int value = 0; 803 804 value = simple_strtoul(value_ptr, &tmpptr, 0); 805 806 /* #warning FIXME: Fix this */ 807 #if 0 808 if (strspn(endptr, WHITE_SPACE) != strlen(endptr)) { 809 pr_err("Illegal value \"%s\" for \"%s\".\n", 810 value, param->name); 811 return -1; 812 } 813 #endif 814 if (IS_TYPERANGE_0_TO_2(param)) { 815 if ((value < 0) || (value > 2)) { 816 pr_err("Illegal value for \"%s\", must be" 817 " between 0 and 2.\n", param->name); 818 return -1; 819 } 820 return 0; 821 } 822 if (IS_TYPERANGE_0_TO_3600(param)) { 823 if ((value < 0) || (value > 3600)) { 824 pr_err("Illegal value for \"%s\", must be" 825 " between 0 and 3600.\n", param->name); 826 return -1; 827 } 828 return 0; 829 } 830 if (IS_TYPERANGE_0_TO_32767(param)) { 831 if ((value < 0) || (value > 32767)) { 832 pr_err("Illegal value for \"%s\", must be" 833 " between 0 and 32767.\n", param->name); 834 return -1; 835 } 836 return 0; 837 } 838 if (IS_TYPERANGE_0_TO_65535(param)) { 839 if ((value < 0) || (value > 65535)) { 840 pr_err("Illegal value for \"%s\", must be" 841 " between 0 and 65535.\n", param->name); 842 return -1; 843 } 844 return 0; 845 } 846 if (IS_TYPERANGE_1_TO_65535(param)) { 847 if ((value < 1) || (value > 65535)) { 848 pr_err("Illegal value for \"%s\", must be" 849 " between 1 and 65535.\n", param->name); 850 return -1; 851 } 852 return 0; 853 } 854 if (IS_TYPERANGE_2_TO_3600(param)) { 855 if ((value < 2) || (value > 3600)) { 856 pr_err("Illegal value for \"%s\", must be" 857 " between 2 and 3600.\n", param->name); 858 return -1; 859 } 860 return 0; 861 } 862 if (IS_TYPERANGE_512_TO_16777215(param)) { 863 if ((value < 512) || (value > 16777215)) { 864 pr_err("Illegal value for \"%s\", must be" 865 " between 512 and 16777215.\n", param->name); 866 return -1; 867 } 868 return 0; 869 } 870 871 return 0; 872 } 873 874 static int iscsi_check_numerical_range_value(struct iscsi_param *param, char *value) 875 { 876 char *left_val_ptr = NULL, *right_val_ptr = NULL; 877 char *tilde_ptr = NULL; 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 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 */ 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 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 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 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 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 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 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 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, ¶m_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, ¶m_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 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 char *tmpptr = key + strlen(key); 1575 *tmpptr = '='; 1576 kfree(tmpbuf); 1577 return 1; 1578 } 1579 } 1580 1581 param = iscsi_check_key(key, phase, sender, param_list); 1582 if (!param) { 1583 if (iscsi_add_notunderstood_response(key, 1584 value, param_list) < 0) { 1585 kfree(tmpbuf); 1586 return -1; 1587 } 1588 start += strlen(key) + strlen(value) + 2; 1589 continue; 1590 } 1591 if (iscsi_check_value(param, value) < 0) { 1592 kfree(tmpbuf); 1593 return -1; 1594 } 1595 1596 start += strlen(key) + strlen(value) + 2; 1597 1598 if (IS_PSTATE_PROPOSER(param)) { 1599 if (iscsi_check_proposer_state(param, value) < 0) { 1600 kfree(tmpbuf); 1601 return -1; 1602 } 1603 SET_PSTATE_RESPONSE_GOT(param); 1604 } else { 1605 if (iscsi_check_acceptor_state(param, value) < 0) { 1606 kfree(tmpbuf); 1607 return -1; 1608 } 1609 SET_PSTATE_ACCEPTOR(param); 1610 } 1611 } 1612 1613 kfree(tmpbuf); 1614 return 0; 1615 } 1616 1617 int iscsi_encode_text_output( 1618 u8 phase, 1619 u8 sender, 1620 char *textbuf, 1621 u32 *length, 1622 struct iscsi_param_list *param_list) 1623 { 1624 char *output_buf = NULL; 1625 struct iscsi_extra_response *er; 1626 struct iscsi_param *param; 1627 1628 output_buf = textbuf + *length; 1629 1630 if (iscsi_enforce_integrity_rules(phase, param_list) < 0) 1631 return -1; 1632 1633 list_for_each_entry(param, ¶m_list->param_list, p_list) { 1634 if (!(param->sender & sender)) 1635 continue; 1636 if (IS_PSTATE_ACCEPTOR(param) && 1637 !IS_PSTATE_RESPONSE_SENT(param) && 1638 !IS_PSTATE_REPLY_OPTIONAL(param) && 1639 (param->phase & phase)) { 1640 *length += sprintf(output_buf, "%s=%s", 1641 param->name, param->value); 1642 *length += 1; 1643 output_buf = textbuf + *length; 1644 SET_PSTATE_RESPONSE_SENT(param); 1645 pr_debug("Sending key: %s=%s\n", 1646 param->name, param->value); 1647 continue; 1648 } 1649 if (IS_PSTATE_NEGOTIATE(param) && 1650 !IS_PSTATE_ACCEPTOR(param) && 1651 !IS_PSTATE_PROPOSER(param) && 1652 (param->phase & phase)) { 1653 *length += sprintf(output_buf, "%s=%s", 1654 param->name, param->value); 1655 *length += 1; 1656 output_buf = textbuf + *length; 1657 SET_PSTATE_PROPOSER(param); 1658 iscsi_check_proposer_for_optional_reply(param); 1659 pr_debug("Sending key: %s=%s\n", 1660 param->name, param->value); 1661 } 1662 } 1663 1664 list_for_each_entry(er, ¶m_list->extra_response_list, er_list) { 1665 *length += sprintf(output_buf, "%s=%s", er->key, er->value); 1666 *length += 1; 1667 output_buf = textbuf + *length; 1668 pr_debug("Sending key: %s=%s\n", er->key, er->value); 1669 } 1670 iscsi_release_extra_responses(param_list); 1671 1672 return 0; 1673 } 1674 1675 int iscsi_check_negotiated_keys(struct iscsi_param_list *param_list) 1676 { 1677 int ret = 0; 1678 struct iscsi_param *param; 1679 1680 list_for_each_entry(param, ¶m_list->param_list, p_list) { 1681 if (IS_PSTATE_NEGOTIATE(param) && 1682 IS_PSTATE_PROPOSER(param) && 1683 !IS_PSTATE_RESPONSE_GOT(param) && 1684 !IS_PSTATE_REPLY_OPTIONAL(param) && 1685 !IS_PHASE_DECLARATIVE(param)) { 1686 pr_err("No response for proposed key \"%s\".\n", 1687 param->name); 1688 ret = -1; 1689 } 1690 } 1691 1692 return ret; 1693 } 1694 1695 int iscsi_change_param_value( 1696 char *keyvalue, 1697 struct iscsi_param_list *param_list, 1698 int check_key) 1699 { 1700 char *key = NULL, *value = NULL; 1701 struct iscsi_param *param; 1702 int sender = 0; 1703 1704 if (iscsi_extract_key_value(keyvalue, &key, &value) < 0) 1705 return -1; 1706 1707 if (!check_key) { 1708 param = __iscsi_check_key(keyvalue, sender, param_list); 1709 if (!param) 1710 return -1; 1711 } else { 1712 param = iscsi_check_key(keyvalue, 0, sender, param_list); 1713 if (!param) 1714 return -1; 1715 1716 param->set_param = 1; 1717 if (iscsi_check_value(param, value) < 0) { 1718 param->set_param = 0; 1719 return -1; 1720 } 1721 param->set_param = 0; 1722 } 1723 1724 if (iscsi_update_param_value(param, value) < 0) 1725 return -1; 1726 1727 return 0; 1728 } 1729 1730 void iscsi_set_connection_parameters( 1731 struct iscsi_conn_ops *ops, 1732 struct iscsi_param_list *param_list) 1733 { 1734 char *tmpptr; 1735 struct iscsi_param *param; 1736 1737 pr_debug("---------------------------------------------------" 1738 "---------------\n"); 1739 list_for_each_entry(param, ¶m_list->param_list, p_list) { 1740 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param)) 1741 continue; 1742 if (!strcmp(param->name, AUTHMETHOD)) { 1743 pr_debug("AuthMethod: %s\n", 1744 param->value); 1745 } else if (!strcmp(param->name, HEADERDIGEST)) { 1746 ops->HeaderDigest = !strcmp(param->value, CRC32C); 1747 pr_debug("HeaderDigest: %s\n", 1748 param->value); 1749 } else if (!strcmp(param->name, DATADIGEST)) { 1750 ops->DataDigest = !strcmp(param->value, CRC32C); 1751 pr_debug("DataDigest: %s\n", 1752 param->value); 1753 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { 1754 ops->MaxRecvDataSegmentLength = 1755 simple_strtoul(param->value, &tmpptr, 0); 1756 pr_debug("MaxRecvDataSegmentLength: %s\n", 1757 param->value); 1758 } else if (!strcmp(param->name, OFMARKER)) { 1759 ops->OFMarker = !strcmp(param->value, YES); 1760 pr_debug("OFMarker: %s\n", 1761 param->value); 1762 } else if (!strcmp(param->name, IFMARKER)) { 1763 ops->IFMarker = !strcmp(param->value, YES); 1764 pr_debug("IFMarker: %s\n", 1765 param->value); 1766 } else if (!strcmp(param->name, OFMARKINT)) { 1767 ops->OFMarkInt = 1768 simple_strtoul(param->value, &tmpptr, 0); 1769 pr_debug("OFMarkInt: %s\n", 1770 param->value); 1771 } else if (!strcmp(param->name, IFMARKINT)) { 1772 ops->IFMarkInt = 1773 simple_strtoul(param->value, &tmpptr, 0); 1774 pr_debug("IFMarkInt: %s\n", 1775 param->value); 1776 } 1777 } 1778 pr_debug("----------------------------------------------------" 1779 "--------------\n"); 1780 } 1781 1782 void iscsi_set_session_parameters( 1783 struct iscsi_sess_ops *ops, 1784 struct iscsi_param_list *param_list, 1785 int leading) 1786 { 1787 char *tmpptr; 1788 struct iscsi_param *param; 1789 1790 pr_debug("----------------------------------------------------" 1791 "--------------\n"); 1792 list_for_each_entry(param, ¶m_list->param_list, p_list) { 1793 if (!IS_PSTATE_ACCEPTOR(param) && !IS_PSTATE_PROPOSER(param)) 1794 continue; 1795 if (!strcmp(param->name, INITIATORNAME)) { 1796 if (!param->value) 1797 continue; 1798 if (leading) 1799 snprintf(ops->InitiatorName, 1800 sizeof(ops->InitiatorName), 1801 "%s", param->value); 1802 pr_debug("InitiatorName: %s\n", 1803 param->value); 1804 } else if (!strcmp(param->name, INITIATORALIAS)) { 1805 if (!param->value) 1806 continue; 1807 snprintf(ops->InitiatorAlias, 1808 sizeof(ops->InitiatorAlias), 1809 "%s", param->value); 1810 pr_debug("InitiatorAlias: %s\n", 1811 param->value); 1812 } else if (!strcmp(param->name, TARGETNAME)) { 1813 if (!param->value) 1814 continue; 1815 if (leading) 1816 snprintf(ops->TargetName, 1817 sizeof(ops->TargetName), 1818 "%s", param->value); 1819 pr_debug("TargetName: %s\n", 1820 param->value); 1821 } else if (!strcmp(param->name, TARGETALIAS)) { 1822 if (!param->value) 1823 continue; 1824 snprintf(ops->TargetAlias, sizeof(ops->TargetAlias), 1825 "%s", param->value); 1826 pr_debug("TargetAlias: %s\n", 1827 param->value); 1828 } else if (!strcmp(param->name, TARGETPORTALGROUPTAG)) { 1829 ops->TargetPortalGroupTag = 1830 simple_strtoul(param->value, &tmpptr, 0); 1831 pr_debug("TargetPortalGroupTag: %s\n", 1832 param->value); 1833 } else if (!strcmp(param->name, MAXCONNECTIONS)) { 1834 ops->MaxConnections = 1835 simple_strtoul(param->value, &tmpptr, 0); 1836 pr_debug("MaxConnections: %s\n", 1837 param->value); 1838 } else if (!strcmp(param->name, INITIALR2T)) { 1839 ops->InitialR2T = !strcmp(param->value, YES); 1840 pr_debug("InitialR2T: %s\n", 1841 param->value); 1842 } else if (!strcmp(param->name, IMMEDIATEDATA)) { 1843 ops->ImmediateData = !strcmp(param->value, YES); 1844 pr_debug("ImmediateData: %s\n", 1845 param->value); 1846 } else if (!strcmp(param->name, MAXBURSTLENGTH)) { 1847 ops->MaxBurstLength = 1848 simple_strtoul(param->value, &tmpptr, 0); 1849 pr_debug("MaxBurstLength: %s\n", 1850 param->value); 1851 } else if (!strcmp(param->name, FIRSTBURSTLENGTH)) { 1852 ops->FirstBurstLength = 1853 simple_strtoul(param->value, &tmpptr, 0); 1854 pr_debug("FirstBurstLength: %s\n", 1855 param->value); 1856 } else if (!strcmp(param->name, DEFAULTTIME2WAIT)) { 1857 ops->DefaultTime2Wait = 1858 simple_strtoul(param->value, &tmpptr, 0); 1859 pr_debug("DefaultTime2Wait: %s\n", 1860 param->value); 1861 } else if (!strcmp(param->name, DEFAULTTIME2RETAIN)) { 1862 ops->DefaultTime2Retain = 1863 simple_strtoul(param->value, &tmpptr, 0); 1864 pr_debug("DefaultTime2Retain: %s\n", 1865 param->value); 1866 } else if (!strcmp(param->name, MAXOUTSTANDINGR2T)) { 1867 ops->MaxOutstandingR2T = 1868 simple_strtoul(param->value, &tmpptr, 0); 1869 pr_debug("MaxOutstandingR2T: %s\n", 1870 param->value); 1871 } else if (!strcmp(param->name, DATAPDUINORDER)) { 1872 ops->DataPDUInOrder = !strcmp(param->value, YES); 1873 pr_debug("DataPDUInOrder: %s\n", 1874 param->value); 1875 } else if (!strcmp(param->name, DATASEQUENCEINORDER)) { 1876 ops->DataSequenceInOrder = !strcmp(param->value, YES); 1877 pr_debug("DataSequenceInOrder: %s\n", 1878 param->value); 1879 } else if (!strcmp(param->name, ERRORRECOVERYLEVEL)) { 1880 ops->ErrorRecoveryLevel = 1881 simple_strtoul(param->value, &tmpptr, 0); 1882 pr_debug("ErrorRecoveryLevel: %s\n", 1883 param->value); 1884 } else if (!strcmp(param->name, SESSIONTYPE)) { 1885 ops->SessionType = !strcmp(param->value, DISCOVERY); 1886 pr_debug("SessionType: %s\n", 1887 param->value); 1888 } 1889 } 1890 pr_debug("----------------------------------------------------" 1891 "--------------\n"); 1892 1893 } 1894