Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iscsi-target: Add login_keys_workaround attribute for non RFC initiators

This patch re-introduces part of a long standing login workaround that
was recently dropped by:

commit 1c99de981f30b3e7868b8d20ce5479fa1c0fea46
Author: Nicholas Bellinger <nab@linux-iscsi.org>
Date: Sun Apr 2 13:36:44 2017 -0700

iscsi-target: Drop work-around for legacy GlobalSAN initiator

Namely, the workaround for FirstBurstLength ended up being required by
Mellanox Flexboot PXE boot ROMs as reported by Robert.

So this patch re-adds the work-around for FirstBurstLength within
iscsi_check_proposer_for_optional_reply(), and makes the key optional
to respond when the initiator does not propose, nor respond to it.

Also as requested by Arun, this patch introduces a new TPG attribute
named 'login_keys_workaround' that controls the use of both the
FirstBurstLength workaround, as well as the two other existing
workarounds for gPXE iSCSI boot client.

By default, the workaround is enabled with login_keys_workaround=1,
since Mellanox FlexBoot requires it, and Arun has verified the Qlogic
MSFT initiator already proposes FirstBurstLength, so it's uneffected
by this re-adding this part of the original work-around.

Reported-by: Robert LeBlanc <robert@leblancnet.us>
Cc: Robert LeBlanc <robert@leblancnet.us>
Reviewed-by: Arun Easi <arun.easi@cavium.com>
Cc: <stable@vger.kernel.org> # 3.1+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>

+64 -16
+2
drivers/target/iscsi/iscsi_target_configfs.c
··· 781 781 DEF_TPG_ATTRIB(t10_pi); 782 782 DEF_TPG_ATTRIB(fabric_prot_type); 783 783 DEF_TPG_ATTRIB(tpg_enabled_sendtargets); 784 + DEF_TPG_ATTRIB(login_keys_workaround); 784 785 785 786 static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { 786 787 &iscsi_tpg_attrib_attr_authentication, ··· 797 796 &iscsi_tpg_attrib_attr_t10_pi, 798 797 &iscsi_tpg_attrib_attr_fabric_prot_type, 799 798 &iscsi_tpg_attrib_attr_tpg_enabled_sendtargets, 799 + &iscsi_tpg_attrib_attr_login_keys_workaround, 800 800 NULL, 801 801 }; 802 802
+4 -2
drivers/target/iscsi/iscsi_target_nego.c
··· 864 864 SENDER_TARGET, 865 865 login->rsp_buf, 866 866 &login->rsp_length, 867 - conn->param_list); 867 + conn->param_list, 868 + conn->tpg->tpg_attrib.login_keys_workaround); 868 869 if (ret < 0) 869 870 return -1; 870 871 ··· 935 934 SENDER_TARGET, 936 935 login->rsp_buf, 937 936 &login->rsp_length, 938 - conn->param_list); 937 + conn->param_list, 938 + conn->tpg->tpg_attrib.login_keys_workaround); 939 939 if (ret < 0) { 940 940 iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, 941 941 ISCSI_LOGIN_STATUS_INIT_ERR);
+28 -13
drivers/target/iscsi/iscsi_target_parameters.c
··· 765 765 return 0; 766 766 } 767 767 768 - static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) 768 + static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param, 769 + bool keys_workaround) 769 770 { 770 771 if (IS_TYPE_BOOL_AND(param)) { 771 772 if (!strcmp(param->value, NO)) ··· 774 773 } else if (IS_TYPE_BOOL_OR(param)) { 775 774 if (!strcmp(param->value, YES)) 776 775 SET_PSTATE_REPLY_OPTIONAL(param); 777 - /* 778 - * Required for gPXE iSCSI boot client 779 - */ 780 - if (!strcmp(param->name, IMMEDIATEDATA)) 781 - SET_PSTATE_REPLY_OPTIONAL(param); 776 + 777 + if (keys_workaround) { 778 + /* 779 + * Required for gPXE iSCSI boot client 780 + */ 781 + if (!strcmp(param->name, IMMEDIATEDATA)) 782 + SET_PSTATE_REPLY_OPTIONAL(param); 783 + } 782 784 } else if (IS_TYPE_NUMBER(param)) { 783 785 if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) 784 786 SET_PSTATE_REPLY_OPTIONAL(param); 785 - /* 786 - * Required for gPXE iSCSI boot client 787 - */ 788 - if (!strcmp(param->name, MAXCONNECTIONS)) 789 - SET_PSTATE_REPLY_OPTIONAL(param); 787 + 788 + if (keys_workaround) { 789 + /* 790 + * Required for Mellanox Flexboot PXE boot ROM 791 + */ 792 + if (!strcmp(param->name, FIRSTBURSTLENGTH)) 793 + SET_PSTATE_REPLY_OPTIONAL(param); 794 + 795 + /* 796 + * Required for gPXE iSCSI boot client 797 + */ 798 + if (!strcmp(param->name, MAXCONNECTIONS)) 799 + SET_PSTATE_REPLY_OPTIONAL(param); 800 + } 790 801 } else if (IS_PHASE_DECLARATIVE(param)) 791 802 SET_PSTATE_REPLY_OPTIONAL(param); 792 803 } ··· 1435 1422 u8 sender, 1436 1423 char *textbuf, 1437 1424 u32 *length, 1438 - struct iscsi_param_list *param_list) 1425 + struct iscsi_param_list *param_list, 1426 + bool keys_workaround) 1439 1427 { 1440 1428 char *output_buf = NULL; 1441 1429 struct iscsi_extra_response *er; ··· 1472 1458 *length += 1; 1473 1459 output_buf = textbuf + *length; 1474 1460 SET_PSTATE_PROPOSER(param); 1475 - iscsi_check_proposer_for_optional_reply(param); 1461 + iscsi_check_proposer_for_optional_reply(param, 1462 + keys_workaround); 1476 1463 pr_debug("Sending key: %s=%s\n", 1477 1464 param->name, param->value); 1478 1465 }
+1 -1
drivers/target/iscsi/iscsi_target_parameters.h
··· 46 46 extern int iscsi_update_param_value(struct iscsi_param *, char *); 47 47 extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *); 48 48 extern int iscsi_encode_text_output(u8, u8, char *, u32 *, 49 - struct iscsi_param_list *); 49 + struct iscsi_param_list *, bool); 50 50 extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); 51 51 extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *, 52 52 struct iscsi_param_list *);
+19
drivers/target/iscsi/iscsi_target_tpg.c
··· 227 227 a->t10_pi = TA_DEFAULT_T10_PI; 228 228 a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; 229 229 a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS; 230 + a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND; 230 231 } 231 232 232 233 int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) ··· 893 892 a->tpg_enabled_sendtargets = flag; 894 893 pr_debug("iSCSI_TPG[%hu] - TPG enabled bit required for SendTargets:" 895 894 " %s\n", tpg->tpgt, (a->tpg_enabled_sendtargets) ? "ON" : "OFF"); 895 + 896 + return 0; 897 + } 898 + 899 + int iscsit_ta_login_keys_workaround( 900 + struct iscsi_portal_group *tpg, 901 + u32 flag) 902 + { 903 + struct iscsi_tpg_attrib *a = &tpg->tpg_attrib; 904 + 905 + if ((flag != 0) && (flag != 1)) { 906 + pr_err("Illegal value %d\n", flag); 907 + return -EINVAL; 908 + } 909 + 910 + a->login_keys_workaround = flag; 911 + pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ", 912 + tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF"); 896 913 897 914 return 0; 898 915 }
+1
drivers/target/iscsi/iscsi_target_tpg.h
··· 48 48 extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); 49 49 extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); 50 50 extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32); 51 + extern int iscsit_ta_login_keys_workaround(struct iscsi_portal_group *, u32); 51 52 52 53 #endif /* ISCSI_TARGET_TPG_H */
+9
include/target/iscsi/iscsi_target_core.h
··· 66 66 #define TA_DEFAULT_FABRIC_PROT_TYPE 0 67 67 /* TPG status needs to be enabled to return sendtargets discovery endpoint info */ 68 68 #define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1 69 + /* 70 + * Used to control the sending of keys with optional to respond state bit, 71 + * as a workaround for non RFC compliant initiators,that do not propose, 72 + * nor respond to specific keys required for login to complete. 73 + * 74 + * See iscsi_check_proposer_for_optional_reply() for more details. 75 + */ 76 + #define TA_DEFAULT_LOGIN_KEYS_WORKAROUND 1 69 77 70 78 #define ISCSI_IOV_DATA_BUFFER 5 71 79 ··· 776 768 u8 t10_pi; 777 769 u32 fabric_prot_type; 778 770 u32 tpg_enabled_sendtargets; 771 + u32 login_keys_workaround; 779 772 struct iscsi_portal_group *tpg; 780 773 }; 781 774