aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2013-03-07 00:54:38 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2013-04-25 04:05:27 -0400
commit03aa207060e395282c5ea0c055e2050b35803b4d (patch)
tree595735b85a7ad1f90b2976c4bd8e4f54793b8503 /drivers/target
parentbaa4d64b147a4064626f6597646ae8a330d9e2ed (diff)
iscsi-target: Add iser-target parameter keys + setup during login
This patch adds RDMAExtensions, InitiatorRecvDataSegmentLength and TargetRecvDataSegmentLength parameters keys necessary for iser-target login to occur. This includes setting the necessary parameters during login path code within iscsi_login_zero_tsih_s2(), and currently PAGE_SIZE aligning the target's advertised MRDSL for immediate data and unsolicited data-out incoming payloads. v3 changes: - Add iscsi_post_login_start_timers FIXME for ISER v2 changes: - Fix RDMAExtentions -> RDMAExtensions typo (andy) - Drop unnecessary '== true' conditional checks for type bool Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/iscsi/iscsi_target_core.h10
-rw-r--r--drivers/target/iscsi/iscsi_target_login.c77
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.c75
-rw-r--r--drivers/target/iscsi/iscsi_target_parameters.h16
4 files changed, 161 insertions, 17 deletions
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h
index 258767776090..53400b0bf711 100644
--- a/drivers/target/iscsi/iscsi_target_core.h
+++ b/drivers/target/iscsi/iscsi_target_core.h
@@ -244,6 +244,11 @@ struct iscsi_conn_ops {
244 u8 IFMarker; /* [0,1] == [No,Yes] */ 244 u8 IFMarker; /* [0,1] == [No,Yes] */
245 u32 OFMarkInt; /* [1..65535] */ 245 u32 OFMarkInt; /* [1..65535] */
246 u32 IFMarkInt; /* [1..65535] */ 246 u32 IFMarkInt; /* [1..65535] */
247 /*
248 * iSER specific connection parameters
249 */
250 u32 InitiatorRecvDataSegmentLength; /* [512..2**24-1] */
251 u32 TargetRecvDataSegmentLength; /* [512..2**24-1] */
247}; 252};
248 253
249struct iscsi_sess_ops { 254struct iscsi_sess_ops {
@@ -265,6 +270,10 @@ struct iscsi_sess_ops {
265 u8 DataSequenceInOrder; /* [0,1] == [No,Yes] */ 270 u8 DataSequenceInOrder; /* [0,1] == [No,Yes] */
266 u8 ErrorRecoveryLevel; /* [0..2] */ 271 u8 ErrorRecoveryLevel; /* [0..2] */
267 u8 SessionType; /* [0,1] == [Normal,Discovery]*/ 272 u8 SessionType; /* [0,1] == [Normal,Discovery]*/
273 /*
274 * iSER specific session parameters
275 */
276 u8 RDMAExtensions; /* [0,1] == [No,Yes] */
268}; 277};
269 278
270struct iscsi_queue_req { 279struct iscsi_queue_req {
@@ -284,6 +293,7 @@ struct iscsi_data_count {
284}; 293};
285 294
286struct iscsi_param_list { 295struct iscsi_param_list {
296 bool iser;
287 struct list_head param_list; 297 struct list_head param_list;
288 struct list_head extra_response_list; 298 struct list_head extra_response_list;
289}; 299};
diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
index 0de5c47d1c81..e6a826927a40 100644
--- a/drivers/target/iscsi/iscsi_target_login.c
+++ b/drivers/target/iscsi/iscsi_target_login.c
@@ -340,6 +340,7 @@ static int iscsi_login_zero_tsih_s2(
340 struct iscsi_node_attrib *na; 340 struct iscsi_node_attrib *na;
341 struct iscsi_session *sess = conn->sess; 341 struct iscsi_session *sess = conn->sess;
342 unsigned char buf[32]; 342 unsigned char buf[32];
343 bool iser = false;
343 344
344 sess->tpg = conn->tpg; 345 sess->tpg = conn->tpg;
345 346
@@ -361,7 +362,10 @@ static int iscsi_login_zero_tsih_s2(
361 return -1; 362 return -1;
362 } 363 }
363 364
364 iscsi_set_keys_to_negotiate(0, conn->param_list); 365 if (conn->conn_transport->transport_type == ISCSI_INFINIBAND)
366 iser = true;
367
368 iscsi_set_keys_to_negotiate(conn->param_list, iser);
365 369
366 if (sess->sess_ops->SessionType) 370 if (sess->sess_ops->SessionType)
367 return iscsi_set_keys_irrelevant_for_discovery( 371 return iscsi_set_keys_irrelevant_for_discovery(
@@ -399,6 +403,56 @@ static int iscsi_login_zero_tsih_s2(
399 403
400 if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0) 404 if (iscsi_login_disable_FIM_keys(conn->param_list, conn) < 0)
401 return -1; 405 return -1;
406 /*
407 * Set RDMAExtensions=Yes by default for iSER enabled network portals
408 */
409 if (iser) {
410 struct iscsi_param *param;
411 unsigned long mrdsl, off;
412 int rc;
413
414 sprintf(buf, "RDMAExtensions=Yes");
415 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
416 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
417 ISCSI_LOGIN_STATUS_NO_RESOURCES);
418 return -1;
419 }
420 /*
421 * Make MaxRecvDataSegmentLength PAGE_SIZE aligned for
422 * Immediate Data + Unsolicitied Data-OUT if necessary..
423 */
424 param = iscsi_find_param_from_key("MaxRecvDataSegmentLength",
425 conn->param_list);
426 if (!param) {
427 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
428 ISCSI_LOGIN_STATUS_NO_RESOURCES);
429 return -1;
430 }
431 rc = strict_strtoul(param->value, 0, &mrdsl);
432 if (rc < 0) {
433 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
434 ISCSI_LOGIN_STATUS_NO_RESOURCES);
435 return -1;
436 }
437 off = mrdsl % PAGE_SIZE;
438 if (!off)
439 return 0;
440
441 if (mrdsl < PAGE_SIZE)
442 mrdsl = PAGE_SIZE;
443 else
444 mrdsl -= off;
445
446 pr_warn("Aligning ISER MaxRecvDataSegmentLength: %lu down"
447 " to PAGE_SIZE\n", mrdsl);
448
449 sprintf(buf, "MaxRecvDataSegmentLength=%lu\n", mrdsl);
450 if (iscsi_change_param_value(buf, conn->param_list, 0) < 0) {
451 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_TARGET_ERR,
452 ISCSI_LOGIN_STATUS_NO_RESOURCES);
453 return -1;
454 }
455 }
402 456
403 return 0; 457 return 0;
404} 458}
@@ -478,6 +532,7 @@ static int iscsi_login_non_zero_tsih_s2(
478 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg; 532 struct se_portal_group *se_tpg = &tpg->tpg_se_tpg;
479 struct se_session *se_sess, *se_sess_tmp; 533 struct se_session *se_sess, *se_sess_tmp;
480 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf; 534 struct iscsi_login_req *pdu = (struct iscsi_login_req *)buf;
535 bool iser = false;
481 536
482 spin_lock_bh(&se_tpg->session_lock); 537 spin_lock_bh(&se_tpg->session_lock);
483 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list, 538 list_for_each_entry_safe(se_sess, se_sess_tmp, &se_tpg->tpg_sess_list,
@@ -527,7 +582,10 @@ static int iscsi_login_non_zero_tsih_s2(
527 return -1; 582 return -1;
528 } 583 }
529 584
530 iscsi_set_keys_to_negotiate(0, conn->param_list); 585 if (conn->conn_transport->transport_type == ISCSI_INFINIBAND)
586 iser = true;
587
588 iscsi_set_keys_to_negotiate(conn->param_list, iser);
531 /* 589 /*
532 * Need to send TargetPortalGroupTag back in first login response 590 * Need to send TargetPortalGroupTag back in first login response
533 * on any iSCSI connection where the Initiator provides TargetName. 591 * on any iSCSI connection where the Initiator provides TargetName.
@@ -615,13 +673,15 @@ int iscsi_login_post_auth_non_zero_tsih(
615 673
616static void iscsi_post_login_start_timers(struct iscsi_conn *conn) 674static void iscsi_post_login_start_timers(struct iscsi_conn *conn)
617{ 675{
618#warning FIXME: Reenable iscsit_start_nopin_timer
619#if 0
620 struct iscsi_session *sess = conn->sess; 676 struct iscsi_session *sess = conn->sess;
677 /*
678 * FIXME: Unsolicitied NopIN support for ISER
679 */
680 if (conn->conn_transport->transport_type == ISCSI_INFINIBAND)
681 return;
621 682
622 if (!sess->sess_ops->SessionType) 683 if (!sess->sess_ops->SessionType)
623 iscsit_start_nopin_timer(conn); 684 iscsit_start_nopin_timer(conn);
624#endif
625} 685}
626 686
627static int iscsi_post_login_handler( 687static int iscsi_post_login_handler(
@@ -678,12 +738,7 @@ static int iscsi_post_login_handler(
678 738
679 iscsi_post_login_start_timers(conn); 739 iscsi_post_login_start_timers(conn);
680 740
681 if (conn->conn_transport == ISCSI_TCP) { 741 iscsi_activate_thread_set(conn, ts);
682 iscsi_activate_thread_set(conn, ts);
683 } else {
684 printk("Not calling iscsi_activate_thread_set....\n");
685 dump_stack();
686 }
687 /* 742 /*
688 * Determine CPU mask to ensure connection's RX and TX kthreads 743 * Determine CPU mask to ensure connection's RX and TX kthreads
689 * are scheduled on the same CPU. 744 * are scheduled on the same CPU.
diff --git a/drivers/target/iscsi/iscsi_target_parameters.c b/drivers/target/iscsi/iscsi_target_parameters.c
index 84ce94a14948..f690be9e5293 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.c
+++ b/drivers/target/iscsi/iscsi_target_parameters.c
@@ -433,6 +433,28 @@ int iscsi_create_default_params(struct iscsi_param_list **param_list_ptr)
433 TYPERANGE_MARKINT, USE_INITIAL_ONLY); 433 TYPERANGE_MARKINT, USE_INITIAL_ONLY);
434 if (!param) 434 if (!param)
435 goto out; 435 goto out;
436 /*
437 * Extra parameters for ISER from RFC-5046
438 */
439 param = iscsi_set_default_param(pl, RDMAEXTENTIONS, INITIAL_RDMAEXTENTIONS,
440 PHASE_OPERATIONAL, SCOPE_SESSION_WIDE, SENDER_BOTH,
441 TYPERANGE_BOOL_AND, USE_LEADING_ONLY);
442 if (!param)
443 goto out;
444
445 param = iscsi_set_default_param(pl, INITIATORRECVDATASEGMENTLENGTH,
446 INITIAL_INITIATORRECVDATASEGMENTLENGTH,
447 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
448 TYPERANGE_512_TO_16777215, USE_ALL);
449 if (!param)
450 goto out;
451
452 param = iscsi_set_default_param(pl, TARGETRECVDATASEGMENTLENGTH,
453 INITIAL_TARGETRECVDATASEGMENTLENGTH,
454 PHASE_OPERATIONAL, SCOPE_CONNECTION_ONLY, SENDER_BOTH,
455 TYPERANGE_512_TO_16777215, USE_ALL);
456 if (!param)
457 goto out;
436 458
437 *param_list_ptr = pl; 459 *param_list_ptr = pl;
438 return 0; 460 return 0;
@@ -442,19 +464,23 @@ out:
442} 464}
443 465
444int iscsi_set_keys_to_negotiate( 466int iscsi_set_keys_to_negotiate(
445 int sessiontype, 467 struct iscsi_param_list *param_list,
446 struct iscsi_param_list *param_list) 468 bool iser)
447{ 469{
448 struct iscsi_param *param; 470 struct iscsi_param *param;
449 471
472 param_list->iser = iser;
473
450 list_for_each_entry(param, &param_list->param_list, p_list) { 474 list_for_each_entry(param, &param_list->param_list, p_list) {
451 param->state = 0; 475 param->state = 0;
452 if (!strcmp(param->name, AUTHMETHOD)) { 476 if (!strcmp(param->name, AUTHMETHOD)) {
453 SET_PSTATE_NEGOTIATE(param); 477 SET_PSTATE_NEGOTIATE(param);
454 } else if (!strcmp(param->name, HEADERDIGEST)) { 478 } else if (!strcmp(param->name, HEADERDIGEST)) {
455 SET_PSTATE_NEGOTIATE(param); 479 if (iser == false)
480 SET_PSTATE_NEGOTIATE(param);
456 } else if (!strcmp(param->name, DATADIGEST)) { 481 } else if (!strcmp(param->name, DATADIGEST)) {
457 SET_PSTATE_NEGOTIATE(param); 482 if (iser == false)
483 SET_PSTATE_NEGOTIATE(param);
458 } else if (!strcmp(param->name, MAXCONNECTIONS)) { 484 } else if (!strcmp(param->name, MAXCONNECTIONS)) {
459 SET_PSTATE_NEGOTIATE(param); 485 SET_PSTATE_NEGOTIATE(param);
460 } else if (!strcmp(param->name, TARGETNAME)) { 486 } else if (!strcmp(param->name, TARGETNAME)) {
@@ -473,7 +499,8 @@ int iscsi_set_keys_to_negotiate(
473 } else if (!strcmp(param->name, IMMEDIATEDATA)) { 499 } else if (!strcmp(param->name, IMMEDIATEDATA)) {
474 SET_PSTATE_NEGOTIATE(param); 500 SET_PSTATE_NEGOTIATE(param);
475 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) { 501 } else if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) {
476 SET_PSTATE_NEGOTIATE(param); 502 if (iser == false)
503 SET_PSTATE_NEGOTIATE(param);
477 } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { 504 } else if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
478 continue; 505 continue;
479 } else if (!strcmp(param->name, MAXBURSTLENGTH)) { 506 } else if (!strcmp(param->name, MAXBURSTLENGTH)) {
@@ -502,6 +529,15 @@ int iscsi_set_keys_to_negotiate(
502 SET_PSTATE_NEGOTIATE(param); 529 SET_PSTATE_NEGOTIATE(param);
503 } else if (!strcmp(param->name, OFMARKINT)) { 530 } else if (!strcmp(param->name, OFMARKINT)) {
504 SET_PSTATE_NEGOTIATE(param); 531 SET_PSTATE_NEGOTIATE(param);
532 } else if (!strcmp(param->name, RDMAEXTENTIONS)) {
533 if (iser == true)
534 SET_PSTATE_NEGOTIATE(param);
535 } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
536 if (iser == true)
537 SET_PSTATE_NEGOTIATE(param);
538 } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
539 if (iser == true)
540 SET_PSTATE_NEGOTIATE(param);
505 } 541 }
506 } 542 }
507 543
@@ -544,6 +580,12 @@ int iscsi_set_keys_irrelevant_for_discovery(
544 param->state &= ~PSTATE_NEGOTIATE; 580 param->state &= ~PSTATE_NEGOTIATE;
545 else if (!strcmp(param->name, OFMARKINT)) 581 else if (!strcmp(param->name, OFMARKINT))
546 param->state &= ~PSTATE_NEGOTIATE; 582 param->state &= ~PSTATE_NEGOTIATE;
583 else if (!strcmp(param->name, RDMAEXTENTIONS))
584 param->state &= ~PSTATE_NEGOTIATE;
585 else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH))
586 param->state &= ~PSTATE_NEGOTIATE;
587 else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH))
588 param->state &= ~PSTATE_NEGOTIATE;
547 } 589 }
548 590
549 return 0; 591 return 0;
@@ -1759,6 +1801,9 @@ void iscsi_set_connection_parameters(
1759 * this key is not sent over the wire. 1801 * this key is not sent over the wire.
1760 */ 1802 */
1761 if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) { 1803 if (!strcmp(param->name, MAXXMITDATASEGMENTLENGTH)) {
1804 if (param_list->iser == true)
1805 continue;
1806
1762 ops->MaxXmitDataSegmentLength = 1807 ops->MaxXmitDataSegmentLength =
1763 simple_strtoul(param->value, &tmpptr, 0); 1808 simple_strtoul(param->value, &tmpptr, 0);
1764 pr_debug("MaxXmitDataSegmentLength: %s\n", 1809 pr_debug("MaxXmitDataSegmentLength: %s\n",
@@ -1804,6 +1849,22 @@ void iscsi_set_connection_parameters(
1804 simple_strtoul(param->value, &tmpptr, 0); 1849 simple_strtoul(param->value, &tmpptr, 0);
1805 pr_debug("IFMarkInt: %s\n", 1850 pr_debug("IFMarkInt: %s\n",
1806 param->value); 1851 param->value);
1852 } else if (!strcmp(param->name, INITIATORRECVDATASEGMENTLENGTH)) {
1853 ops->InitiatorRecvDataSegmentLength =
1854 simple_strtoul(param->value, &tmpptr, 0);
1855 pr_debug("InitiatorRecvDataSegmentLength: %s\n",
1856 param->value);
1857 ops->MaxRecvDataSegmentLength =
1858 ops->InitiatorRecvDataSegmentLength;
1859 pr_debug("Set MRDSL from InitiatorRecvDataSegmentLength\n");
1860 } else if (!strcmp(param->name, TARGETRECVDATASEGMENTLENGTH)) {
1861 ops->TargetRecvDataSegmentLength =
1862 simple_strtoul(param->value, &tmpptr, 0);
1863 pr_debug("TargetRecvDataSegmentLength: %s\n",
1864 param->value);
1865 ops->MaxXmitDataSegmentLength =
1866 ops->TargetRecvDataSegmentLength;
1867 pr_debug("Set MXDSL from TargetRecvDataSegmentLength\n");
1807 } 1868 }
1808 } 1869 }
1809 pr_debug("----------------------------------------------------" 1870 pr_debug("----------------------------------------------------"
@@ -1916,6 +1977,10 @@ void iscsi_set_session_parameters(
1916 ops->SessionType = !strcmp(param->value, DISCOVERY); 1977 ops->SessionType = !strcmp(param->value, DISCOVERY);
1917 pr_debug("SessionType: %s\n", 1978 pr_debug("SessionType: %s\n",
1918 param->value); 1979 param->value);
1980 } else if (!strcmp(param->name, RDMAEXTENTIONS)) {
1981 ops->RDMAExtensions = !strcmp(param->value, YES);
1982 pr_debug("RDMAExtensions: %s\n",
1983 param->value);
1919 } 1984 }
1920 } 1985 }
1921 pr_debug("----------------------------------------------------" 1986 pr_debug("----------------------------------------------------"
diff --git a/drivers/target/iscsi/iscsi_target_parameters.h b/drivers/target/iscsi/iscsi_target_parameters.h
index 1e1b7504a76b..f31b9c4b83f2 100644
--- a/drivers/target/iscsi/iscsi_target_parameters.h
+++ b/drivers/target/iscsi/iscsi_target_parameters.h
@@ -27,7 +27,7 @@ extern void iscsi_dump_conn_ops(struct iscsi_conn_ops *);
27extern void iscsi_dump_sess_ops(struct iscsi_sess_ops *); 27extern void iscsi_dump_sess_ops(struct iscsi_sess_ops *);
28extern void iscsi_print_params(struct iscsi_param_list *); 28extern void iscsi_print_params(struct iscsi_param_list *);
29extern int iscsi_create_default_params(struct iscsi_param_list **); 29extern int iscsi_create_default_params(struct iscsi_param_list **);
30extern int iscsi_set_keys_to_negotiate(int, struct iscsi_param_list *); 30extern int iscsi_set_keys_to_negotiate(struct iscsi_param_list *, bool);
31extern int iscsi_set_keys_irrelevant_for_discovery(struct iscsi_param_list *); 31extern int iscsi_set_keys_irrelevant_for_discovery(struct iscsi_param_list *);
32extern int iscsi_copy_param_list(struct iscsi_param_list **, 32extern int iscsi_copy_param_list(struct iscsi_param_list **,
33 struct iscsi_param_list *, int); 33 struct iscsi_param_list *, int);
@@ -89,6 +89,13 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
89#define X_EXTENSIONKEY_CISCO_OLD "X-com.cisco.iscsi.draft" 89#define X_EXTENSIONKEY_CISCO_OLD "X-com.cisco.iscsi.draft"
90 90
91/* 91/*
92 * Parameter names of iSCSI Extentions for RDMA (iSER). See RFC-5046
93 */
94#define RDMAEXTENTIONS "RDMAExtensions"
95#define INITIATORRECVDATASEGMENTLENGTH "InitiatorRecvDataSegmentLength"
96#define TARGETRECVDATASEGMENTLENGTH "TargetRecvDataSegmentLength"
97
98/*
92 * For AuthMethod. 99 * For AuthMethod.
93 */ 100 */
94#define KRB5 "KRB5" 101#define KRB5 "KRB5"
@@ -133,6 +140,13 @@ extern void iscsi_set_session_parameters(struct iscsi_sess_ops *,
133#define INITIAL_OFMARKINT "2048~65535" 140#define INITIAL_OFMARKINT "2048~65535"
134 141
135/* 142/*
143 * Initial values for iSER parameters following RFC-5046 Section 6
144 */
145#define INITIAL_RDMAEXTENTIONS NO
146#define INITIAL_INITIATORRECVDATASEGMENTLENGTH "262144"
147#define INITIAL_TARGETRECVDATASEGMENTLENGTH "8192"
148
149/*
136 * For [Header,Data]Digests. 150 * For [Header,Data]Digests.
137 */ 151 */
138#define CRC32C "CRC32C" 152#define CRC32C "CRC32C"