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