Commit 138d351e authored by Nicholas Bellinger's avatar Nicholas Bellinger

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 1c99de98
  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: default avatarRobert LeBlanc <robert@leblancnet.us>
Cc: Robert LeBlanc <robert@leblancnet.us>
Reviewed-by: default avatarArun Easi <arun.easi@cavium.com>
Cc: <stable@vger.kernel.org> # 3.1+
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 55dd8cf2
...@@ -781,6 +781,7 @@ DEF_TPG_ATTRIB(default_erl); ...@@ -781,6 +781,7 @@ DEF_TPG_ATTRIB(default_erl);
DEF_TPG_ATTRIB(t10_pi); DEF_TPG_ATTRIB(t10_pi);
DEF_TPG_ATTRIB(fabric_prot_type); DEF_TPG_ATTRIB(fabric_prot_type);
DEF_TPG_ATTRIB(tpg_enabled_sendtargets); DEF_TPG_ATTRIB(tpg_enabled_sendtargets);
DEF_TPG_ATTRIB(login_keys_workaround);
static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_attr_authentication, &iscsi_tpg_attrib_attr_authentication,
...@@ -796,6 +797,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = { ...@@ -796,6 +797,7 @@ static struct configfs_attribute *lio_target_tpg_attrib_attrs[] = {
&iscsi_tpg_attrib_attr_t10_pi, &iscsi_tpg_attrib_attr_t10_pi,
&iscsi_tpg_attrib_attr_fabric_prot_type, &iscsi_tpg_attrib_attr_fabric_prot_type,
&iscsi_tpg_attrib_attr_tpg_enabled_sendtargets, &iscsi_tpg_attrib_attr_tpg_enabled_sendtargets,
&iscsi_tpg_attrib_attr_login_keys_workaround,
NULL, NULL,
}; };
......
...@@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero( ...@@ -864,7 +864,8 @@ static int iscsi_target_handle_csg_zero(
SENDER_TARGET, SENDER_TARGET,
login->rsp_buf, login->rsp_buf,
&login->rsp_length, &login->rsp_length,
conn->param_list); conn->param_list,
conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0) if (ret < 0)
return -1; return -1;
...@@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log ...@@ -934,7 +935,8 @@ static int iscsi_target_handle_csg_one(struct iscsi_conn *conn, struct iscsi_log
SENDER_TARGET, SENDER_TARGET,
login->rsp_buf, login->rsp_buf,
&login->rsp_length, &login->rsp_length,
conn->param_list); conn->param_list,
conn->tpg->tpg_attrib.login_keys_workaround);
if (ret < 0) { if (ret < 0) {
iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR, iscsit_tx_login_rsp(conn, ISCSI_STATUS_CLS_INITIATOR_ERR,
ISCSI_LOGIN_STATUS_INIT_ERR); ISCSI_LOGIN_STATUS_INIT_ERR);
......
...@@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char *key) ...@@ -765,7 +765,8 @@ static int iscsi_check_for_auth_key(char *key)
return 0; return 0;
} }
static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param,
bool keys_workaround)
{ {
if (IS_TYPE_BOOL_AND(param)) { if (IS_TYPE_BOOL_AND(param)) {
if (!strcmp(param->value, NO)) if (!strcmp(param->value, NO))
...@@ -773,19 +774,31 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param) ...@@ -773,19 +774,31 @@ static void iscsi_check_proposer_for_optional_reply(struct iscsi_param *param)
} else if (IS_TYPE_BOOL_OR(param)) { } else if (IS_TYPE_BOOL_OR(param)) {
if (!strcmp(param->value, YES)) if (!strcmp(param->value, YES))
SET_PSTATE_REPLY_OPTIONAL(param); SET_PSTATE_REPLY_OPTIONAL(param);
/*
* Required for gPXE iSCSI boot client if (keys_workaround) {
*/ /*
if (!strcmp(param->name, IMMEDIATEDATA)) * Required for gPXE iSCSI boot client
SET_PSTATE_REPLY_OPTIONAL(param); */
if (!strcmp(param->name, IMMEDIATEDATA))
SET_PSTATE_REPLY_OPTIONAL(param);
}
} else if (IS_TYPE_NUMBER(param)) { } else if (IS_TYPE_NUMBER(param)) {
if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH)) if (!strcmp(param->name, MAXRECVDATASEGMENTLENGTH))
SET_PSTATE_REPLY_OPTIONAL(param); SET_PSTATE_REPLY_OPTIONAL(param);
/*
* Required for gPXE iSCSI boot client if (keys_workaround) {
*/ /*
if (!strcmp(param->name, MAXCONNECTIONS)) * Required for Mellanox Flexboot PXE boot ROM
SET_PSTATE_REPLY_OPTIONAL(param); */
if (!strcmp(param->name, FIRSTBURSTLENGTH))
SET_PSTATE_REPLY_OPTIONAL(param);
/*
* Required for gPXE iSCSI boot client
*/
if (!strcmp(param->name, MAXCONNECTIONS))
SET_PSTATE_REPLY_OPTIONAL(param);
}
} else if (IS_PHASE_DECLARATIVE(param)) } else if (IS_PHASE_DECLARATIVE(param))
SET_PSTATE_REPLY_OPTIONAL(param); SET_PSTATE_REPLY_OPTIONAL(param);
} }
...@@ -1422,7 +1435,8 @@ int iscsi_encode_text_output( ...@@ -1422,7 +1435,8 @@ int iscsi_encode_text_output(
u8 sender, u8 sender,
char *textbuf, char *textbuf,
u32 *length, u32 *length,
struct iscsi_param_list *param_list) struct iscsi_param_list *param_list,
bool keys_workaround)
{ {
char *output_buf = NULL; char *output_buf = NULL;
struct iscsi_extra_response *er; struct iscsi_extra_response *er;
...@@ -1458,7 +1472,8 @@ int iscsi_encode_text_output( ...@@ -1458,7 +1472,8 @@ int iscsi_encode_text_output(
*length += 1; *length += 1;
output_buf = textbuf + *length; output_buf = textbuf + *length;
SET_PSTATE_PROPOSER(param); SET_PSTATE_PROPOSER(param);
iscsi_check_proposer_for_optional_reply(param); iscsi_check_proposer_for_optional_reply(param,
keys_workaround);
pr_debug("Sending key: %s=%s\n", pr_debug("Sending key: %s=%s\n",
param->name, param->value); param->name, param->value);
} }
......
...@@ -46,7 +46,7 @@ extern int iscsi_extract_key_value(char *, char **, char **); ...@@ -46,7 +46,7 @@ extern int iscsi_extract_key_value(char *, char **, char **);
extern int iscsi_update_param_value(struct iscsi_param *, char *); extern int iscsi_update_param_value(struct iscsi_param *, char *);
extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *); extern int iscsi_decode_text_input(u8, u8, char *, u32, struct iscsi_conn *);
extern int iscsi_encode_text_output(u8, u8, char *, u32 *, extern int iscsi_encode_text_output(u8, u8, char *, u32 *,
struct iscsi_param_list *); struct iscsi_param_list *, bool);
extern int iscsi_check_negotiated_keys(struct iscsi_param_list *); extern int iscsi_check_negotiated_keys(struct iscsi_param_list *);
extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *, extern void iscsi_set_connection_parameters(struct iscsi_conn_ops *,
struct iscsi_param_list *); struct iscsi_param_list *);
......
...@@ -227,6 +227,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg) ...@@ -227,6 +227,7 @@ static void iscsit_set_default_tpg_attribs(struct iscsi_portal_group *tpg)
a->t10_pi = TA_DEFAULT_T10_PI; a->t10_pi = TA_DEFAULT_T10_PI;
a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE; a->fabric_prot_type = TA_DEFAULT_FABRIC_PROT_TYPE;
a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS; a->tpg_enabled_sendtargets = TA_DEFAULT_TPG_ENABLED_SENDTARGETS;
a->login_keys_workaround = TA_DEFAULT_LOGIN_KEYS_WORKAROUND;
} }
int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg) int iscsit_tpg_add_portal_group(struct iscsi_tiqn *tiqn, struct iscsi_portal_group *tpg)
...@@ -895,3 +896,21 @@ int iscsit_ta_tpg_enabled_sendtargets( ...@@ -895,3 +896,21 @@ int iscsit_ta_tpg_enabled_sendtargets(
return 0; return 0;
} }
int iscsit_ta_login_keys_workaround(
struct iscsi_portal_group *tpg,
u32 flag)
{
struct iscsi_tpg_attrib *a = &tpg->tpg_attrib;
if ((flag != 0) && (flag != 1)) {
pr_err("Illegal value %d\n", flag);
return -EINVAL;
}
a->login_keys_workaround = flag;
pr_debug("iSCSI_TPG[%hu] - TPG enabled bit for login keys workaround: %s ",
tpg->tpgt, (a->login_keys_workaround) ? "ON" : "OFF");
return 0;
}
...@@ -48,5 +48,6 @@ extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32); ...@@ -48,5 +48,6 @@ extern int iscsit_ta_default_erl(struct iscsi_portal_group *, u32);
extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32); extern int iscsit_ta_t10_pi(struct iscsi_portal_group *, u32);
extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32); extern int iscsit_ta_fabric_prot_type(struct iscsi_portal_group *, u32);
extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32); extern int iscsit_ta_tpg_enabled_sendtargets(struct iscsi_portal_group *, u32);
extern int iscsit_ta_login_keys_workaround(struct iscsi_portal_group *, u32);
#endif /* ISCSI_TARGET_TPG_H */ #endif /* ISCSI_TARGET_TPG_H */
...@@ -66,6 +66,14 @@ struct sock; ...@@ -66,6 +66,14 @@ struct sock;
#define TA_DEFAULT_FABRIC_PROT_TYPE 0 #define TA_DEFAULT_FABRIC_PROT_TYPE 0
/* TPG status needs to be enabled to return sendtargets discovery endpoint info */ /* TPG status needs to be enabled to return sendtargets discovery endpoint info */
#define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1 #define TA_DEFAULT_TPG_ENABLED_SENDTARGETS 1
/*
* Used to control the sending of keys with optional to respond state bit,
* as a workaround for non RFC compliant initiators,that do not propose,
* nor respond to specific keys required for login to complete.
*
* See iscsi_check_proposer_for_optional_reply() for more details.
*/
#define TA_DEFAULT_LOGIN_KEYS_WORKAROUND 1
#define ISCSI_IOV_DATA_BUFFER 5 #define ISCSI_IOV_DATA_BUFFER 5
...@@ -768,6 +776,7 @@ struct iscsi_tpg_attrib { ...@@ -768,6 +776,7 @@ struct iscsi_tpg_attrib {
u8 t10_pi; u8 t10_pi;
u32 fabric_prot_type; u32 fabric_prot_type;
u32 tpg_enabled_sendtargets; u32 tpg_enabled_sendtargets;
u32 login_keys_workaround;
struct iscsi_portal_group *tpg; struct iscsi_portal_group *tpg;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment