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