File Index
Files and directories
Sign in
FILE

iscsi_target_parameters.c

File preview with syntax highlighting.

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