Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/iscsid/login.c
Show First 20 Lines • Show All 324 Lines • ▼ Show 20 Lines | login_list_prefers(const char *list, | ||||
free(tofree); | free(tofree); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
static void | static void | ||||
login_negotiate_key(struct connection *conn, const char *name, | login_negotiate_key(struct connection *conn, const char *name, | ||||
const char *value) | const char *value) | ||||
{ | { | ||||
struct iscsi_session_limits *isl; | |||||
int which, tmp; | int which, tmp; | ||||
isl = &conn->conn_limits; | |||||
if (strcmp(name, "TargetAlias") == 0) { | if (strcmp(name, "TargetAlias") == 0) { | ||||
strlcpy(conn->conn_target_alias, value, | strlcpy(conn->conn_target_alias, value, | ||||
sizeof(conn->conn_target_alias)); | sizeof(conn->conn_target_alias)); | ||||
} else if (strcmp(value, "Irrelevant") == 0) { | } else if (strcmp(value, "Irrelevant") == 0) { | ||||
/* Ignore. */ | /* Ignore. */ | ||||
} else if (strcmp(name, "HeaderDigest") == 0) { | } else if (strcmp(name, "HeaderDigest") == 0) { | ||||
which = login_list_prefers(value, "CRC32C", "None"); | which = login_list_prefers(value, "CRC32C", "None"); | ||||
switch (which) { | switch (which) { | ||||
Show All 40 Lines | if (strcmp(value, "Yes") == 0) | ||||
conn->conn_immediate_data = true; | conn->conn_immediate_data = true; | ||||
else | else | ||||
conn->conn_immediate_data = false; | conn->conn_immediate_data = false; | ||||
} else if (strcmp(name, "MaxRecvDataSegmentLength") == 0) { | } else if (strcmp(name, "MaxRecvDataSegmentLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) | if (tmp <= 0) | ||||
log_errx(1, "received invalid " | log_errx(1, "received invalid " | ||||
"MaxRecvDataSegmentLength"); | "MaxRecvDataSegmentLength"); | ||||
if (tmp > ISCSI_MAX_DATA_SEGMENT_LENGTH) { | if (tmp > isl->isl_max_send_data_segment_length) { | ||||
log_debugx("capping MaxRecvDataSegmentLength " | log_debugx("capping max_send_data_segment_length " | ||||
"from %d to %d", tmp, ISCSI_MAX_DATA_SEGMENT_LENGTH); | "from %d to %d", tmp, | ||||
tmp = ISCSI_MAX_DATA_SEGMENT_LENGTH; | isl->isl_max_send_data_segment_length); | ||||
tmp = isl->isl_max_send_data_segment_length; | |||||
} | } | ||||
conn->conn_max_data_segment_length = tmp; | conn->conn_max_send_data_segment_length = tmp; | ||||
} else if (strcmp(name, "MaxBurstLength") == 0) { | } else if (strcmp(name, "MaxBurstLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) | if (tmp <= 0) | ||||
log_errx(1, "received invalid MaxBurstLength"); | log_errx(1, "received invalid MaxBurstLength"); | ||||
if (tmp > MAX_BURST_LENGTH) { | if (tmp > isl->isl_max_burst_length) { | ||||
log_debugx("capping MaxBurstLength " | log_debugx("capping MaxBurstLength " | ||||
"from %d to %d", tmp, MAX_BURST_LENGTH); | "from %d to %d", tmp, isl->isl_max_burst_length); | ||||
tmp = MAX_BURST_LENGTH; | tmp = isl->isl_max_burst_length; | ||||
} | } | ||||
conn->conn_max_burst_length = tmp; | conn->conn_max_burst_length = tmp; | ||||
} else if (strcmp(name, "FirstBurstLength") == 0) { | } else if (strcmp(name, "FirstBurstLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) | if (tmp <= 0) | ||||
log_errx(1, "received invalid FirstBurstLength"); | log_errx(1, "received invalid FirstBurstLength"); | ||||
if (tmp > FIRST_BURST_LENGTH) { | if (tmp > isl->isl_first_burst_length) { | ||||
log_debugx("capping FirstBurstLength " | log_debugx("capping FirstBurstLength " | ||||
"from %d to %d", tmp, FIRST_BURST_LENGTH); | "from %d to %d", tmp, isl->isl_first_burst_length); | ||||
tmp = FIRST_BURST_LENGTH; | tmp = isl->isl_first_burst_length; | ||||
} | } | ||||
conn->conn_first_burst_length = tmp; | conn->conn_first_burst_length = tmp; | ||||
} else if (strcmp(name, "DefaultTime2Wait") == 0) { | } else if (strcmp(name, "DefaultTime2Wait") == 0) { | ||||
/* Ignore */ | /* Ignore */ | ||||
} else if (strcmp(name, "DefaultTime2Retain") == 0) { | } else if (strcmp(name, "DefaultTime2Retain") == 0) { | ||||
/* Ignore */ | /* Ignore */ | ||||
} else if (strcmp(name, "MaxOutstandingR2T") == 0) { | } else if (strcmp(name, "MaxOutstandingR2T") == 0) { | ||||
/* Ignore */ | /* Ignore */ | ||||
Show All 12 Lines | if (conn->conn_conf.isc_iser == 1 && | ||||
strcmp(value, "Yes") != 0) { | strcmp(value, "Yes") != 0) { | ||||
log_errx(1, "received unsupported RDMAExtensions"); | log_errx(1, "received unsupported RDMAExtensions"); | ||||
} | } | ||||
} else if (strcmp(name, "InitiatorRecvDataSegmentLength") == 0) { | } else if (strcmp(name, "InitiatorRecvDataSegmentLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) | if (tmp <= 0) | ||||
log_errx(1, "received invalid " | log_errx(1, "received invalid " | ||||
"InitiatorRecvDataSegmentLength"); | "InitiatorRecvDataSegmentLength"); | ||||
if ((size_t)tmp > conn->conn_limits.isl_max_data_segment_length) { | if ((int)tmp > isl->isl_max_recv_data_segment_length) { | ||||
log_debugx("capping InitiatorRecvDataSegmentLength " | log_debugx("capping InitiatorRecvDataSegmentLength " | ||||
"from %d to %zd", tmp, | "from %d to %d", tmp, | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_recv_data_segment_length); | ||||
tmp = conn->conn_limits.isl_max_data_segment_length; | tmp = isl->isl_max_recv_data_segment_length; | ||||
} | } | ||||
conn->conn_max_data_segment_length = tmp; | conn->conn_max_recv_data_segment_length = tmp; | ||||
} else if (strcmp(name, "TargetPortalGroupTag") == 0) { | } else if (strcmp(name, "TargetPortalGroupTag") == 0) { | ||||
/* Ignore */ | /* Ignore */ | ||||
} else if (strcmp(name, "TargetRecvDataSegmentLength") == 0) { | } else if (strcmp(name, "TargetRecvDataSegmentLength") == 0) { | ||||
tmp = strtoul(value, NULL, 10); | tmp = strtoul(value, NULL, 10); | ||||
if (tmp <= 0) { | if (tmp <= 0) { | ||||
log_errx(1, | log_errx(1, | ||||
"received invalid TargetRecvDataSegmentLength"); | "received invalid TargetRecvDataSegmentLength"); | ||||
} | } | ||||
if ((size_t)tmp > conn->conn_limits.isl_max_data_segment_length) { | if (tmp > isl->isl_max_send_data_segment_length) { | ||||
log_debugx("capping TargetRecvDataSegmentLength " | log_debugx("capping TargetRecvDataSegmentLength " | ||||
"from %d to %zd", tmp, | "from %d to %d", tmp, | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_send_data_segment_length); | ||||
tmp = conn->conn_limits.isl_max_data_segment_length; | tmp = isl->isl_max_send_data_segment_length; | ||||
} | } | ||||
conn->conn_max_data_segment_length = tmp; | conn->conn_max_send_data_segment_length = tmp; | ||||
} else { | } else { | ||||
log_debugx("unknown key \"%s\"; ignoring", name); | log_debugx("unknown key \"%s\"; ignoring", name); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
login_negotiate(struct connection *conn) | login_negotiate(struct connection *conn) | ||||
{ | { | ||||
struct pdu *request, *response; | struct pdu *request, *response; | ||||
struct keys *request_keys, *response_keys; | struct keys *request_keys, *response_keys; | ||||
struct iscsi_bhs_login_response *bhslr; | struct iscsi_bhs_login_response *bhslr; | ||||
int i, nrequests = 0; | int i, nrequests = 0; | ||||
struct iscsi_session_limits *isl; | |||||
log_debugx("beginning operational parameter negotiation"); | log_debugx("beginning operational parameter negotiation"); | ||||
request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION); | request = login_new_request(conn, BHSLR_STAGE_OPERATIONAL_NEGOTIATION); | ||||
request_keys = keys_new(); | request_keys = keys_new(); | ||||
log_debugx("offload \"%s\" limits MaxRecvDataSegmentLength to %zd", | isl = &conn->conn_limits; | ||||
conn->conn_conf.isc_offload, | log_debugx("Limits for offload \"%s\" are " | ||||
conn->conn_limits.isl_max_data_segment_length); | "MaxRecvDataSegment=%d, max_send_dsl=%d, " | ||||
"MaxBurstLength=%d, FirstBurstLength=%d", | |||||
conn->conn_conf.isc_offload, isl->isl_max_recv_data_segment_length, | |||||
isl->isl_max_send_data_segment_length, isl->isl_max_burst_length, | |||||
isl->isl_first_burst_length); | |||||
/* | /* | ||||
* The following keys are irrelevant for discovery sessions. | * The following keys are irrelevant for discovery sessions. | ||||
*/ | */ | ||||
if (conn->conn_conf.isc_discovery == 0) { | if (conn->conn_conf.isc_discovery == 0) { | ||||
if (conn->conn_conf.isc_header_digest != 0) | if (conn->conn_conf.isc_header_digest != 0) | ||||
keys_add(request_keys, "HeaderDigest", "CRC32C"); | keys_add(request_keys, "HeaderDigest", "CRC32C"); | ||||
else | else | ||||
keys_add(request_keys, "HeaderDigest", "None"); | keys_add(request_keys, "HeaderDigest", "None"); | ||||
if (conn->conn_conf.isc_data_digest != 0) | if (conn->conn_conf.isc_data_digest != 0) | ||||
keys_add(request_keys, "DataDigest", "CRC32C"); | keys_add(request_keys, "DataDigest", "CRC32C"); | ||||
else | else | ||||
keys_add(request_keys, "DataDigest", "None"); | keys_add(request_keys, "DataDigest", "None"); | ||||
keys_add(request_keys, "ImmediateData", "Yes"); | keys_add(request_keys, "ImmediateData", "Yes"); | ||||
keys_add_int(request_keys, "MaxBurstLength", MAX_BURST_LENGTH); | keys_add_int(request_keys, "MaxBurstLength", | ||||
keys_add_int(request_keys, "FirstBurstLength", FIRST_BURST_LENGTH); | isl->isl_max_burst_length); | ||||
keys_add_int(request_keys, "FirstBurstLength", | |||||
isl->isl_first_burst_length); | |||||
keys_add(request_keys, "InitialR2T", "Yes"); | keys_add(request_keys, "InitialR2T", "Yes"); | ||||
keys_add(request_keys, "MaxOutstandingR2T", "1"); | keys_add(request_keys, "MaxOutstandingR2T", "1"); | ||||
if (conn->conn_conf.isc_iser == 1) { | if (conn->conn_conf.isc_iser == 1) { | ||||
keys_add_int(request_keys, "InitiatorRecvDataSegmentLength", | keys_add_int(request_keys, "InitiatorRecvDataSegmentLength", | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_recv_data_segment_length); | ||||
keys_add_int(request_keys, "TargetRecvDataSegmentLength", | keys_add_int(request_keys, "TargetRecvDataSegmentLength", | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_send_data_segment_length); | ||||
keys_add(request_keys, "RDMAExtensions", "Yes"); | keys_add(request_keys, "RDMAExtensions", "Yes"); | ||||
} else { | } else { | ||||
keys_add_int(request_keys, "MaxRecvDataSegmentLength", | keys_add_int(request_keys, "MaxRecvDataSegmentLength", | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_recv_data_segment_length); | ||||
} | } | ||||
} else { | } else { | ||||
keys_add(request_keys, "HeaderDigest", "None"); | keys_add(request_keys, "HeaderDigest", "None"); | ||||
keys_add(request_keys, "DataDigest", "None"); | keys_add(request_keys, "DataDigest", "None"); | ||||
keys_add_int(request_keys, "MaxRecvDataSegmentLength", | keys_add_int(request_keys, "MaxRecvDataSegmentLength", | ||||
conn->conn_limits.isl_max_data_segment_length); | isl->isl_max_recv_data_segment_length); | ||||
} | } | ||||
keys_add(request_keys, "DefaultTime2Wait", "0"); | keys_add(request_keys, "DefaultTime2Wait", "0"); | ||||
keys_add(request_keys, "DefaultTime2Retain", "0"); | keys_add(request_keys, "DefaultTime2Retain", "0"); | ||||
keys_add(request_keys, "ErrorRecoveryLevel", "0"); | keys_add(request_keys, "ErrorRecoveryLevel", "0"); | ||||
keys_save(request_keys, request); | keys_save(request_keys, request); | ||||
keys_delete(request_keys); | keys_delete(request_keys); | ||||
request_keys = NULL; | request_keys = NULL; | ||||
▲ Show 20 Lines • Show All 351 Lines • Show Last 20 Lines |