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