iscsi_target_parameters.c 46 KB

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