brintos

brintos / linux-shallow public Read only

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