56 #define OCS_TEXT_TIMEOUT_MS (1 * 1000)
149 static const char chap[] =
"CHAP";
150 static const char none[] =
"None";
152 static const char yes[] =
"Yes";
153 static const char no[] =
"No";
154 static const char all[] =
"All";
190 char*str, uint32_t max_str);
214 ocs_log_err(iscsi->
os,
"ocs_iscsi_login_retries_allocate failed\n");
255 if (cxn == retry->
cxn) {
262 in_use = ocs_atomic_read(&cxn->login_mem_in_use);
286 if (cxn == retry->
cxn) {
288 if (retry->
hdr != NULL) {
314 value = ocs_atomic_add_return(&cxn->login_mem_in_use, 1);
318 (void)ocs_atomic_sub_return(&cxn->login_mem_in_use, 1);
331 (void)ocs_atomic_sub_return(&cxn->login_mem_in_use, 1);
359 OCS_M_ZERO | OCS_M_NOWAIT);
361 ocs_log_err(iscsi->
os,
"Failed to allocate login memory list\n");
416 if (retry->
cxn != cxn) {
421 retry_local = *retry;
427 switch(retry_local.
type) {
435 (retry_local.
cxn, retry_local.
itt);
494 ocs_log_test(iscsi->
os,
"Unhandled retry type %d\n",
500 ocs_log_test(iscsi->
os,
"failed sending retry request\n");
529 ocs_log_err(iscsi->
os,
"failed to allocate a login retry buffer\n");
578 unsigned int j, k, instring;
584 for (instring = j = 0; j != length; j++) {
589 if (instring++ == 0) {
592 if (text[j] ==
'=') {
594 if (ocs_strcmp(key, p) == 0) {
596 val = (
char *)&text[++j];
597 for (k = j; k != length; k++) {
601 if (k == length || text[k] != 0)
640 while (index < data_len) {
641 if (data[index] ==
'=' &&
646 if (data[index] ==
'\0') {
648 }
else if (*null_pos != 0) {
657 if (*equal_pos != 0) {
658 for (index = 0; index <
KEY_MAX; index++) {
661 while (matches && cmp_index < (*equal_pos - pos)) {
662 matches = (ocs_login_key_defs[index].
key_name[cmp_index] ==
663 data[pos + cmp_index]);
668 matches = ocs_login_key_defs[index].
key_name
669 [(*equal_pos - pos)] ==
'\0';
698 for (j = 0; j != strlen(text) + 1; j++) {
699 if (text[j] ==
',' || text[j] == 0) {
702 if (ocs_strcmp(value, p) == 0) {
728 uint32_t avail_bytes)
731 ocs_t *ocs = cxn->ocs;
732 ocs_session_t *session = cxn->session;
733 uint8_t has_text_reply = FALSE;
734 uint8_t has_int_reply = FALSE;
735 uint32_t int_reply = FALSE;
736 char *text_reply = NULL;
745 if (cxn->lgn_parms_sent & (1l << key)) {
750 has_text_reply = TRUE;
753 if (cxn->is_ini_cxn) {
766 text_reply = (
char*)chap;
768 (void)ocs_snprintf(tmp_str, ARRAY_SIZE(tmp_str),
770 text_reply = tmp_str;
775 text_reply = (
char*)chap;
780 text_reply = (
char*)none;
786 has_text_reply = TRUE;
789 if (cxn->hdr_digest) {
790 (void)ocs_snprintf(tmp_str, ARRAY_SIZE(tmp_str),
792 text_reply = tmp_str;
794 text_reply = (
char*)none;
797 text_reply = (
char*)(cxn->hdr_digest ? crc32c : none);
802 has_text_reply = TRUE;
805 if (cxn->data_digest) {
806 (void)ocs_snprintf(tmp_str, ARRAY_SIZE(tmp_str),
808 text_reply = tmp_str;
810 text_reply = (
char*)none;
813 text_reply = (
char*)(cxn->data_digest ? crc32c : none);
818 has_int_reply = TRUE;
819 int_reply = session->login_options.max_connections;
823 has_text_reply = TRUE;
824 text_reply = (
char*)all;
828 has_text_reply = TRUE;
829 text_reply = (
char*)(session->login_options.initial_r2t ? yes : no);
833 has_text_reply = TRUE;
834 text_reply = (
char*)(session->login_options.immediate_data ? yes : no);
839 has_int_reply = TRUE;
841 int_reply = cxn->max_rcv_dsl;
845 has_int_reply = TRUE;
846 int_reply = session->login_options.max_burst;
856 session->login_options.initial_r2t != 0 &&
857 session->login_options.immediate_data == 0) {
858 has_text_reply = TRUE;
859 text_reply = (
char*)irrelevant;
861 has_int_reply = TRUE;
862 int_reply = session->login_options.first_burst;
867 has_int_reply = TRUE;
868 int_reply = session->login_options.def_time_to_wait;
872 has_int_reply = TRUE;
873 int_reply = session->login_options.def_time_to_retain;
877 has_int_reply = TRUE;
878 int_reply = session->login_options.max_r2t;
882 has_text_reply = TRUE;
883 text_reply = (
char*)(session->login_options.data_pdu_in_order ? yes : no);
887 has_text_reply = TRUE;
888 text_reply = (
char*)(session->login_options.data_sequence_in_order ? yes : no);
892 has_int_reply = TRUE;
893 int_reply = session->login_options.error_recovery_level;
897 has_text_reply = TRUE;
898 text_reply = (
char*)rfc3720;
902 has_text_reply = TRUE;
903 text_reply = (
char*)no;
907 has_text_reply = TRUE;
908 text_reply = (
char*)no;
913 if (cxn->lgn_parms_recv & (1l << key)) {
914 has_text_reply = TRUE;
915 text_reply = (
char*)irrelevant;
920 has_int_reply = TRUE;
921 ip.
ip_type = cxn->dest_ip_type;
929 if (ocs_strcmp(session->tgt_name, tmp_tgt_name) == 0) {
931 if (text_reply != NULL) {
932 has_text_reply = TRUE;
941 if (text_reply != NULL) {
942 has_text_reply = TRUE;
946 has_int_reply = TRUE;
951 has_int_reply = TRUE;
953 int_reply = cxn->chap_ident_sent;
960 challenge_str, ARRAY_SIZE(challenge_str));
961 has_text_reply = TRUE;
962 text_reply = challenge_str;
966 has_text_reply = TRUE;
967 text_reply = cxn->chap_name_send;
971 has_text_reply = TRUE;
972 text_reply = cxn->chap_response;
986 cxn->lgn_parms_sent |= (1l << key);
988 if (has_text_reply) {
989 rc = ocs_snprintf(strptr, avail_bytes,
"%s=%s",
990 ocs_login_key_defs[key].key_name,
992 }
else if(has_int_reply) {
993 rc = ocs_snprintf(strptr, avail_bytes,
"%s=%d",
994 ocs_login_key_defs[key].key_name,
1014 uint8_t *status_detail)
1017 ocs_session_t *session = cxn->session;
1019 unsigned long lvalue;
1021 uint8_t out_of_range = FALSE;
1022 uint8_t list_not_supported = FALSE;
1023 uint8_t invalid_boolean = FALSE;
1028 if (cxn->is_ini_cxn) {
1044 ocs_log_test(iscsi->
os,
"CHAP is required and AuthMethod=CHAP was not offered\n");
1054 ocs_log_test(iscsi->
os,
"Cxn %s CHAP Enabled", cxn->display_name);
1061 list_not_supported = TRUE;
1069 if (cxn->hdr_digest == 1) {
1070 cxn->hdr_digest = 0;
1073 list_not_supported = TRUE;
1081 if (cxn->data_digest == 1) {
1082 cxn->data_digest = 0;
1085 list_not_supported = TRUE;
1090 lvalue = ocs_strtoul(value, NULL, 0);
1091 if (lvalue < 1 || lvalue > 65535) {
1092 out_of_range = TRUE;
1093 }
else if (lvalue < session->login_options.max_connections) {
1094 session->login_options.max_connections = lvalue;
1102 if (ocs_strcmp(value, yes) == 0) {
1103 if (session->login_options.initial_r2t == 0) {
1104 session->login_options.initial_r2t = 1;
1106 }
else if (ocs_strcmp(value, no) != 0) {
1107 invalid_boolean = TRUE;
1112 if (ocs_strcmp(value, no) == 0) {
1113 if (session->login_options.immediate_data == 1) {
1114 session->login_options.immediate_data = 0;
1116 }
else if (ocs_strcmp(value, yes) != 0) {
1117 invalid_boolean = TRUE;
1122 lvalue = ocs_strtoul(value, NULL, 0);
1123 if (lvalue < 512 || lvalue > 16777215) {
1124 out_of_range = TRUE;
1127 if (lvalue >= (1 << 17) - 1) {
1128 cxn->max_xmit_dsl = (1 << 17) - 1;
1130 cxn->max_xmit_dsl = lvalue;
1134 if (cxn->max_xmit_dsl > 65536) {
1135 cxn->max_xmit_dsl = 65536;
1139 cxn->max_xmit_dsl = cxn->max_xmit_dsl & ~(0x3);
1144 lvalue = ocs_strtoul(value, NULL, 0);
1145 if (lvalue < 512 || lvalue > 16777215) {
1146 out_of_range = TRUE;
1147 }
else if (lvalue < session->login_options.max_burst) {
1149 if (lvalue >= (1 << 19) - 1) {
1150 session->login_options.max_burst = (1 << 19) - 1;
1152 session->login_options.max_burst = lvalue;
1155 session->login_options.max_burst =
1156 session->login_options.max_burst & ~(0x3);
1159 if (session->login_options.first_burst >
1160 session->login_options.max_burst) {
1161 session->login_options.first_burst =
1162 session->login_options.max_burst;
1170 session->login_options.immediate_data == 0 &&
1171 ocs_strcmp(value, irrelevant) == 0) {
1174 lvalue = ocs_strtoul(value, NULL, 0);
1175 if (lvalue < 512 || lvalue > 16777215) {
1176 out_of_range = TRUE;
1177 }
else if (lvalue < session->login_options.first_burst &&
1180 if (lvalue >= (1 << 14) - 1) {
1181 session->login_options.first_burst = (1 << 14) - 1;
1183 session->login_options.first_burst = lvalue;
1186 session->login_options.first_burst =
1187 session->login_options.first_burst & ~(0x3);
1193 lvalue = ocs_strtoul(value, NULL, 0);
1194 if (lvalue > 3600) {
1195 out_of_range = TRUE;
1196 }
else if (lvalue < session->login_options.def_time_to_wait) {
1197 session->login_options.def_time_to_wait = lvalue;
1202 lvalue = ocs_strtoul(value, NULL, 0);
1203 if (lvalue > 3600) {
1204 out_of_range = TRUE;
1205 }
else if (lvalue < session->login_options.def_time_to_retain) {
1206 session->login_options.def_time_to_retain = lvalue;
1211 lvalue = ocs_strtoul(value, NULL, 0);
1212 if (lvalue < 1 || lvalue > 65535) {
1213 out_of_range = TRUE;
1214 }
else if (lvalue < session->login_options.max_r2t) {
1215 session->login_options.max_r2t = lvalue;
1220 if (ocs_strcmp(value, yes) == 0) {
1221 if (session->login_options.data_pdu_in_order == 0) {
1222 session->login_options.data_pdu_in_order = 1;
1224 }
else if (ocs_strcmp(value, no) != 0) {
1225 invalid_boolean = TRUE;
1230 if (ocs_strcmp(value, yes) == 0) {
1231 if (session->login_options.data_sequence_in_order == 0) {
1232 session->login_options.data_sequence_in_order = 1;
1234 }
else if (ocs_strcmp(value, no) != 0) {
1235 invalid_boolean = TRUE;
1240 lvalue = ocs_strtoul(value, NULL, 0);
1242 out_of_range = TRUE;
1243 }
else if (lvalue < session->login_options.error_recovery_level) {
1244 session->login_options.error_recovery_level = lvalue;
1252 list_not_supported = TRUE;
1261 ocs_log_test(iscsi->
os,
"CHAP Algorithm 5 was not offered, other are not supported\n");
1268 lvalue = ocs_strtoul(value, NULL, 0);
1269 cxn->chap_ident_recv = lvalue;
1274 cxn->chap_challenge_recv = value;
1279 cxn->chap_response = value;
1284 cxn->chap_name_recv = value;
1289 lvalue = ocs_strtoul(value, NULL, 0);
1290 if (lvalue > 65535) {
1291 out_of_range = TRUE;
1298 if (ocs_strcmp(value, yes) != 0 &&
1299 ocs_strcmp(value, no) != 0) {
1300 invalid_boolean = TRUE;
1306 lvalue = ocs_strtoul(value, NULL, 0);
1307 if (lvalue < 1 || lvalue > 65535) {
1308 out_of_range = TRUE;
1329 if ((cxn->lgn_parms_recv & (1l << key)) != 0) {
1330 ocs_log_test(iscsi->
os,
"Key %s was negotiated multiple times\n",
1335 cxn->lgn_parms_recv |= (1l << key);
1337 ocs_log_test(iscsi->
os,
"Key %s is out of range\n",
1341 }
else if (list_not_supported) {
1342 ocs_log_test(iscsi->
os,
"No supported list value found for key %s, value recv %s\n",
1347 }
else if (invalid_boolean) {
1348 ocs_log_test(iscsi->
os,
"Invalid boolean value for key %s, value recv %s\n",
1371 ocs_sport_t *rval = NULL;
1372 ocs_t *ocs = cxn->ocs;
1379 if (ocs_strcmp(tgt_name, tmp_tgt_name) == 0) {
1380 rval = &ocs->sport[i];
1407 uint8_t *status_detail,
1412 ocs_session_t *session;
1413 ocs_t *ocs = iscsi->
os;
1429 ocs_log_test(ocs,
"no Initiator name\n");
1442 for (i = 0; i < 6; i++) {
1443 isid = (isid << 8) | isid_ptr[i];
1449 cxn->cid = ocs_be16toh(pi->
cid);
1455 ocs_be16toh(pi->
cid),
1456 ocs_be32toh(pi->
cmd_sn));
1459 ocs_log_test(ocs,
"session 0x%x does not exist\n",
1464 }
else if (rc == 2) {
1465 ocs_log_test(ocs,
"session 0x%x exceeded max connections\n",
1470 }
else if (rc == 3) {
1471 ocs_log_test(ocs,
"session 0x%x out of resources\n",
1476 }
else if (rc != 0) {
1477 ocs_log_test(ocs,
"session 0x%x unhandled error\n",
1483 session = cxn->session;
1491 if (ocs_strcmp(sessType,
"Discovery") == 0) {
1492 session->is_discovery_session = 1;
1493 ocs_log_debug(ocs,
"SessionType is Discovery\n");
1494 }
else if (ocs_strcmp(sessType,
"Normal") == 0) {
1497 ocs_log_test(ocs,
"Invalid session type\n");
1502 }
else if (cxn->is_leading_login) {
1503 ocs_log_test(ocs,
"no session key on leading login\n");
1512 if (!session->is_discovery_session) {
1513 if (tgt_name == NULL) {
1514 ocs_log_test(ocs,
"no target name\n");
1519 ocs_log_test(ocs,
"Target name mismatch, received %s\n", tgt_name);
1524 ocs_log_test(ocs,
"No access to target allowed\n");
1534 if (sport != cxn->sport) {
1556 session->login_options.max_connections =
1558 if (cxn->is_leading_login) {
1585 uint8_t *status_detail,
1592 ocs_session_t *session = cxn->session;
1594 uint32_t lavail = rsp_size;
1597 uint32_t equal_pos, null_pos;
1607 while (pos < recv_len) {
1612 &equal_pos, &null_pos);
1613 if (equal_pos != 0 &&
1616 recv[equal_pos] =
'\0';
1617 ocs_log_test(iscsi->
os,
"key %s not understood\n", &recv[pos]);
1620 skip = ocs_snprintf(strptr, lavail,
1621 "%s=NotUnderstood", &recv[pos]) + 1;
1629 }
else if (equal_pos - pos > 63) {
1630 recv[equal_pos] =
'\0';
1631 ocs_log_test(iscsi->
os,
"key %s is longer than 63 characters\n", &recv[pos]);
1638 }
else if ((null_pos - equal_pos) > 255 &&
1640 recv[equal_pos] =
'\0';
1641 ocs_log_test(iscsi->
os,
"key data for %s is longer than 255 characters\n",
1645 }
else if ((!cxn->is_ini_cxn &&
1649 ocs_log_test(iscsi->
os,
"key %s sent by wrong side\n",
1660 ocs_log_test(iscsi->
os,
"key %s sent in wrong phase\n",
1665 }
else if (!cxn->is_leading_login &&
1667 ocs_log_test(iscsi->
os,
"Leading Login key %s sent on non-leading login\n",
1672 }
else if (session->is_discovery_session &&
1675 ocs_log_test(iscsi->
os,
"key %s is irrelevant\n",
1678 skip = ocs_snprintf(strptr, lavail,
1680 ocs_login_key_defs[key].key_name,
1690 ocs_log_test(iscsi->
os,
"key %s negotiation error\n",
1695 skip = ocs_snprintf(strptr, lavail,
1697 ocs_login_key_defs[key].key_name) + 1;
1701 ((cxn->is_ini_cxn &&
1702 (ocs_login_key_defs[key].
flags & KEY_FLAG_SEND_INI)) ||
1703 (!cxn->is_ini_cxn &&
1704 (ocs_login_key_defs[key].
flags & KEY_FLAG_SEND_TGT))) &&
1705 (cxn->lgn_parms_sent & (1l << key)) == 0) {
1715 ocs_log_test(iscsi->
os,
"no equal found in string %s\n", recv);
1725 return strptr - rsp;
1739 char*str, uint32_t max_str)
1745 pos = ocs_snprintf(str, max_str,
"0x");
1746 for (i = 0; i < nbytes; i++) {
1747 pos += ocs_snprintf(&str[pos], max_str - pos,
"%02x", bin[i]);
1764 char *curr = hex_str;
1765 uint32_t nibbles = 0;
1771 (*(curr + 1) ==
'x' || *(curr + 1) ==
'X')) {
1776 if ((ocs_strlen(curr) % 2) == 1) {
1780 while(*curr !=
'\0') {
1781 if (*curr >=
'0' && *curr <=
'9') {
1782 byte = (byte << 4) + (*curr -
'0');
1783 }
else if (*curr >=
'A' && *curr <=
'F') {
1784 byte = (byte << 4) + ((*curr -
'A') + 10);
1785 }
else if (*curr >=
'a' && *curr <=
'f') {
1786 byte = (byte << 4) + ((*curr -
'a') + 10);
1818 uint8_t *status_detail,
1823 ocs_t *ocs = cxn->ocs;
1825 ocs_session_t *session = cxn->session;
1829 char response_str[16*2 + 3];
1830 uint8_t resp_bin[16];
1831 uint8_t *challenge_recv;
1834 uint32_t secret_len;
1837 uint8_t calc_resp[16];
1838 unsigned char id_data[1];
1840 switch (cxn->chap_state)
1853 rsp_size - *rsp_len);
1860 rsp_size - *rsp_len);
1864 ocs_memset(cxn->chap_challenge_sent, 0,
sizeof(cxn->chap_challenge_sent));
1869 rsp_size - *rsp_len);
1873 ocs_log_test(iscsi->
os,
"Chap algorithm not provided");
1886 (cxn->chap_response, resp_bin, ARRAY_SIZE(resp_bin));
1891 if (secret == NULL) {
1892 ocs_log_err(ocs,
"Incoming CHAP secret is not found\n");
1898 id_data[0] = cxn->chap_ident_sent;
1904 ocs_log_debug(iscsi->
os,
"Cxn %s verifying incoming CHAP\n",
1907 if (ocs_memcmp(calc_resp, resp_bin, ARRAY_SIZE(calc_resp)) != 0) {
1908 ocs_log_err(iscsi->
os,
"Failed Chap authentication for user %s",
1909 cxn->chap_name_recv);
1917 ocs_log_debug(iscsi->
os,
"Cxn %s CHAP Sending Target authentication",
1921 if (username == NULL) {
1922 ocs_log_err(ocs,
"Outgoing CHAP name is not registered\n");
1929 if (secret == NULL) {
1930 ocs_log_err(ocs,
"Outgoing CHAP secret is not registered\n");
1935 recv_size = ocs_strlen(cxn->chap_challenge_recv) / 2;
1936 challenge_recv = ocs_malloc(ocs, recv_size, OCS_M_NOWAIT);
1937 if (challenge_recv == NULL) {
1938 ocs_log_err(iscsi->
os,
"challenge_recv memalloc failed\n");
1944 (cxn->chap_challenge_recv, challenge_recv, recv_size);
1947 id_data[0] = cxn->chap_ident_recv;
1954 cxn->chap_name_send = username;
1958 rsp_size - *rsp_len);
1962 (calc_resp, ARRAY_SIZE(calc_resp),
1963 response_str, ARRAY_SIZE(response_str));
1964 cxn->chap_response = response_str;
1968 rsp_size - *rsp_len);
1970 cxn->chap_response = NULL;
1971 ocs_free(ocs, challenge_recv, recv_size);
1974 ocs_log_debug(ocs,
"CHAP state moved to complete state\n");
1980 ocs_log_test(iscsi->
os,
"Chap name or response not provided");
1993 cxn->chap_state = new_state;
2014 uint8_t *status_detail,
2019 ocs_t *ocs = cxn->ocs;
2021 ocs_session_t *session = cxn->session;
2025 char response_str[16*2 + 3];
2026 uint8_t resp_bin[16];
2027 uint8_t *challenge_recv;
2030 uint32_t secret_len;
2033 uint8_t calc_resp[16];
2034 unsigned char id_data[1];
2036 switch (cxn->chap_state)
2043 rsp_size - *rsp_len);
2057 if (username == NULL) {
2058 ocs_log_err(ocs,
"Outgoing CHAP name is not registered\n");
2065 if (secret == NULL) {
2066 ocs_log_err(ocs,
"Outgoing CHAP secret is not registered\n");
2071 recv_size = ocs_strlen(cxn->chap_challenge_recv) / 2;
2072 challenge_recv = ocs_malloc(ocs, recv_size,
2075 (cxn->chap_challenge_recv, challenge_recv, recv_size);
2078 id_data[0] = cxn->chap_ident_recv;
2085 cxn->chap_name_send = username;
2089 rsp_size - *rsp_len);
2093 (calc_resp, ARRAY_SIZE(calc_resp),
2094 response_str, ARRAY_SIZE(response_str));
2095 cxn->chap_response = response_str;
2099 rsp_size - *rsp_len);
2101 cxn->chap_response = NULL;
2102 ocs_free(ocs, challenge_recv, recv_size);
2110 rsp_size - *rsp_len);
2114 ocs_memset(cxn->chap_challenge_sent, 0,
sizeof(cxn->chap_challenge_sent));
2119 rsp_size - *rsp_len);
2123 ocs_log_test(iscsi->
os,
"Chap algorithm, ID or challenge not provided");
2135 (cxn->chap_response, resp_bin, ARRAY_SIZE(resp_bin));
2140 if (secret == NULL) {
2141 ocs_log_err(ocs,
"Incoming CHAP secret is not found\n");
2147 id_data[0] = cxn->chap_ident_sent;
2154 if (ocs_memcmp(calc_resp, resp_bin, ARRAY_SIZE(calc_resp)) != 0) {
2155 ocs_log_err(iscsi->
os,
"Failed Chap authentication for user %s",
2156 cxn->chap_name_recv);
2164 ocs_log_test(iscsi->
os,
"Chap name or response not provided");
2177 cxn->chap_state = new_state;
2206 ocs_log_err(iscsi->
os,
"No retry resources are available");
2210 lgn_retry->
type = type;
2211 lgn_retry->
cxn = cxn;
2212 lgn_retry->
hdr = hdr;
2214 lgn_retry->
data = data;
2240 static ocs_cxn_q_cbit_t *
2246 uint8_t *status_detail,
2250 uint32_t *resp_size)
2254 ocs_cxn_q_cbit_t *cbit_added = NULL;
2259 if (cxn->cbit_rsp_offset != 0 &&
2272 cbit_added = ocs_malloc(cxn->ocs,
sizeof(ocs_cxn_q_cbit_t), OCS_M_ZERO | OCS_M_NOWAIT);
2273 if (cbit_added == NULL) {
2274 ocs_log_test(iscsi->
os,
"Failed to allocate cbit object\n");
2277 }
else if (data != NULL) {
2278 cbit_added->hdr = hdr;
2279 cbit_added->data = data;
2280 cbit_added->data_len = data_len;
2293 cxn->cbit_rsp_offset == 0) {
2295 *recv_ptr = (data == NULL ? NULL : data->
dma.virt);
2296 *recv_len = data_len;
2297 *resp_ptr = cxn->login_data_mem.virt;
2298 *resp_size = cxn->login_data_mem.size;
2300 ocs_cxn_q_cbit_t *cbit;
2304 cxn->cbit_recv_len = data_len;
2306 cxn->cbit_recv_len += cbit->data_len;
2310 cxn->cbit_recv = ocs_malloc(cxn->ocs, cxn->cbit_recv_len, OCS_M_ZERO | OCS_M_NOWAIT);
2311 cxn->cbit_rsp_alloc_size = cxn->cbit_recv_len + 1024;
2312 cxn->cbit_rsp = ocs_malloc(cxn->ocs, cxn->cbit_rsp_alloc_size, OCS_M_ZERO | OCS_M_NOWAIT);
2313 if (cxn->cbit_recv == NULL ||
2314 cxn->cbit_rsp == NULL) {
2315 ocs_log_err(iscsi->
os,
"Failed to allocate cbit buffers\n");
2320 uint32_t offset = 0;
2324 ocs_memcpy(&cxn->cbit_recv[offset],
2325 cbit->data->dma.virt,
2327 offset += cbit->data_len;
2329 ocs_memcpy(&cxn->cbit_recv[offset],
2333 cxn->cbit_rsp_len = 0;
2334 cxn->cbit_rsp_offset = 0;
2335 *recv_ptr = cxn->cbit_recv;
2336 *recv_len = cxn->cbit_recv_len;
2337 *resp_ptr = cxn->cbit_rsp;
2338 *resp_size = cxn->cbit_rsp_alloc_size;
2362 if (cxn->cbit_rsp_offset == 0) {
2363 cxn->cbit_rsp_len = *len;
2367 if (cxn->cbit_rsp_len - cxn->cbit_rsp_offset > 8192) {
2371 *len = cxn->cbit_rsp_len - cxn->cbit_rsp_offset;
2375 ocs_memcpy(cxn->login_data_mem.virt,
2376 &cxn->cbit_rsp[cxn->cbit_rsp_offset],
2389 ocs_cxn_q_cbit_t *cbit)
2396 ocs_free(cxn->ocs, cbit,
sizeof(*cbit));
2413 ocs_cxn_q_cbit_t *cbit;
2416 if (cxn->cbit_recv != NULL) {
2417 ocs_free(cxn->ocs, cxn->cbit_recv, cxn->cbit_recv_len);
2418 cxn->cbit_recv = NULL;
2421 if (cxn->cbit_rsp != NULL) {
2422 ocs_free(cxn->ocs, cxn->cbit_rsp, cxn->cbit_rsp_alloc_size);
2423 cxn->cbit_rsp = NULL;
2427 while (cbit != NULL) {
2430 ocs_free(cxn->ocs, cbit,
sizeof(*cbit));
2456 ocs_t *ocs = cxn->ocs;
2458 ocs_session_t *session = NULL;
2459 char * recv_ptr = NULL;
2461 char * resp_ptr = NULL;
2469 uint8_t status_detail = 0;
2470 uint64_t lgn_parms_sent = cxn->lgn_parms_sent;
2471 uint64_t lgn_parms_recv = cxn->lgn_parms_recv;
2473 ocs_cxn_q_cbit_t *cbit_added = NULL;
2477 ocs_log_test(iscsi->
os,
"called with connection state %d",
2484 if (hal_io == NULL) {
2498 ocs_log_info(iscsi->
os,
2499 "CXN handle 0x%x state %d received csg %u nsg %u t %u c %u",
2500 cxn->conn_hdl, cxn->cxn_state, pi->
csg, pi->
nsg, pi->
t, pi->
c);
2512 if (!ocs->require_chap) {
2513 ocs_log_err(ocs,
"Error! Target is not configured "
2514 "for initiator authentication\n");
2530 ocs_log_err(ocs,
"Error! Target requires initiator authentication\n");
2552 ocs_log_test(iscsi->
os,
"Invalid iSCSI version\n");
2558 &status, &status_detail,
2559 &recv_ptr, &recv_len,
2560 &resp_ptr, &resp_size);
2567 cxn->cbit_rsp_offset == 0) {
2585 session = cxn->session;
2612 for (index = 0; index <
KEY_MAX; index++) {
2615 (!session->is_discovery_session ||
2618 ((cxn->is_ini_cxn &&
2620 (!cxn->is_ini_cxn &&
2622 (cxn->lgn_parms_sent & (1l << index)) == 0 &&
2659 !session->is_discovery_session &&
2681 session = cxn->session;
2690 po->status = status;
2691 po->status_detail = status_detail;
2698 po->stat_sn = ocs_htobe32(cxn->stat_sn++);
2719 ocs_log_debug(iscsi->
os,
"Cxn %s transitioning to FFP, hdr_digest=%d, data_digest=%d",
2720 cxn->display_name, cxn->hdr_digest, cxn->data_digest);
2721 cxn->max_wr_xfer_size = session->login_options.max_burst;
2725 ocs_log_test(iscsi->
os,
"send context update failed\n");
2732 iparam.unassisted.set_dm = TRUE;
2733 iparam.unassisted.incr_statsn = FALSE;
2734 iparam.unassisted.is_login = TRUE;
2735 iparam.unassisted.bhs = &cxn->login_hdr_mem;
2736 iparam.unassisted.payload1 = (len > 0 ? &cxn->login_data_mem : NULL);
2737 iparam.unassisted.payload2 = NULL;
2750 cxn->lgn_parms_sent = lgn_parms_sent;
2751 cxn->lgn_parms_recv = lgn_parms_recv;
2763 cxn->cbit_rsp_offset += len;
2766 cxn->cbit_rsp_offset == cxn->cbit_rsp_len) {
2793 ocs_log_test(iscsi->
os,
"No retry resources are available");
2798 lgn_retry->
cxn = cxn;
2799 lgn_retry->
itt = itt;
2827 ocs_log_test(iscsi->
os,
"called with connection state %d",
2833 if (hal_io == NULL) {
2844 po->
itt = ocs_htobe32(itt);
2845 po->
stat_sn = ocs_htobe32(cxn->stat_sn);
2852 for (i = 0; i < 6; i++) {
2853 isid_ptr[i] = (isid >> (48 - ((i+1)*8))) & 0xff;
2900 ocs_session_t *session = cxn->session;
2903 char * resp_ptr = NULL;
2911 uint8_t status_detail = 0;
2912 uint64_t lgn_parms_sent = cxn->lgn_parms_sent;
2913 uint64_t lgn_parms_recv = cxn->lgn_parms_recv;
2914 ocs_cxn_q_cbit_t *cbit_added = NULL;
2918 ocs_log_test(iscsi->
os,
"called with connection state %d",
2926 ocs_log_test(iscsi->
os,
"Target returned error status 0x%x, detail 0x%x",
2934 if (hal_io == NULL) {
2961 ocs_log_debug(iscsi->
os,
"received csg %u nsg %u t %u c %u",
2966 &status, &status_detail,
2967 &recv_ptr, &recv_len,
2968 &resp_ptr, &resp_size);
2975 cxn->cbit_rsp_offset == 0) {
2993 for (index = 0; index <
KEY_MAX; index++) {
2996 (!session->is_discovery_session ||
2999 ((cxn->is_ini_cxn &&
3001 (!cxn->is_ini_cxn &&
3003 (cxn->lgn_parms_sent & (1l << index)) == 0 &&
3032 if (cxn->is_first_login_rsp) {
3033 cxn->is_first_login_rsp = 0;
3034 cxn->stat_sn = ocs_be32toh(pi->
stat_sn);
3037 if (ocs_be32toh(pi->
stat_sn) != cxn->stat_sn) {
3038 ocs_log_test(iscsi->
os,
3039 "Expected stat_sn %d, but recv %d",
3040 cxn->stat_sn, ocs_be32toh(pi->
stat_sn));
3059 po->itt = ocs_htobe32(cxn->wq_index);
3060 po->cid = ocs_htobe16(cxn->cid);
3062 po->exp_stat_sn = ocs_htobe32(cxn->stat_sn);
3068 ocs_log_test(iscsi->
os,
"bad internal status, bailing");
3079 ocs_log_debug(iscsi->
os,
"Cxn %s transitioning to FFP, hdr_digest=%d, data_digest=%d",
3080 cxn->display_name, cxn->hdr_digest, cxn->data_digest);
3086 cxn->max_wr_xfer_size = session->login_options.max_burst;
3090 ocs_log_test(iscsi->
os,
"send context update failed\n");
3097 iparam.unassisted.set_dm = TRUE;
3098 iparam.unassisted.incr_statsn = FALSE;
3099 iparam.unassisted.is_login = TRUE;
3100 iparam.unassisted.bhs = &cxn->login_hdr_mem;
3101 iparam.unassisted.payload1 = (len > 0 ? &cxn->login_data_mem : NULL);
3102 iparam.unassisted.payload2 = NULL;
3114 cxn->lgn_parms_sent = lgn_parms_sent;
3115 cxn->lgn_parms_recv = lgn_parms_recv;
3123 cxn->cbit_rsp_offset += len;
3126 cxn->cbit_rsp_offset == cxn->cbit_rsp_len) {
3156 ocs_log_test(iscsi->
os,
"No retry resources are available");
3159 }
else if (ocs_strlen(tgt_name) + 1 > ARRAY_SIZE(lgn_retry->
virt_buffer)) {
3164 lgn_retry->
cxn = cxn;
3187 ocs_session_t *session = cxn->session;
3194 uint64_t lgn_parms_sent = cxn->lgn_parms_sent;
3195 uint64_t lgn_parms_recv = cxn->lgn_parms_recv;
3202 ocs_log_test(iscsi->
os,
"called with connection state %d", cxn->cxn_state);
3208 if (hal_io == NULL) {
3224 session->is_discovery_session = is_discovery;
3225 cxn->cid = cxn->wq_index;
3229 skip = ocs_snprintf(((
char *)cxn->login_data_mem.virt) + len,
3238 skip = ocs_snprintf(((
char *)cxn->login_data_mem.virt) + len,
3246 skip = ocs_snprintf(((
char *)cxn->login_data_mem.virt) + len,
3256 if (!is_discovery) {
3259 ((
char *)cxn->login_data_mem.virt) + len,
3265 if (!is_discovery) {
3266 skip = ocs_snprintf(((
char *)cxn->login_data_mem.virt) + len,
3276 ((
char *)cxn->login_data_mem.virt) + len,
3282 for (index = 0; index <
KEY_MAX; index++) {
3287 ((cxn->is_ini_cxn &&
3289 (!cxn->is_ini_cxn &&
3291 (cxn->lgn_parms_sent & (1l << index)) == 0 &&
3298 ((
char *)cxn->login_data_mem.virt) + len,
3308 po->
itt = ocs_htobe32(cxn->wq_index);
3309 po->
cid = ocs_htobe16(cxn->cid);
3316 for (i = 0; i < 6; i++) {
3317 isid_ptr[i] = (isid >> (48 - ((i+1)*8))) & 0xff;
3338 cxn->lgn_parms_sent = lgn_parms_sent;
3339 cxn->lgn_parms_recv = lgn_parms_recv;
3358 uint32_t resp_size, uint32_t plen_orig)
3360 ocs_t *ocs = cxn->ocs;
3362 uint32_t plen = plen_orig;
3364 int32_t remaining_sz;
3379 remaining_sz = resp_size - plen;
3385 key_sz += strlen(ctgt->
tgt_name) + 1;
3386 key_sz += strlen(ctgt->
tgt_addr) + 1;
3387 if (remaining_sz < key_sz) {
3388 ocs_log_debug(ocs,
"No response buffer for more "
3389 "cluster target entries.\n");
3394 skip = ocs_snprintf(resp_ptr + plen,
3401 remaining_sz = resp_size - plen;
3402 skip = ocs_snprintf(resp_ptr + plen,
3413 return plen - plen_orig;
3435 uint32_t plen = plen_orig;
3438 uint32_t portal_grp;
3441 char ip_addr_port[80];
3444 skip = ocs_snprintf(resp_ptr + plen,
3460 ocs_snprintf(ip_addr_port,
3461 sizeof(ip_addr_port),
3468 ocs_snprintf(ip_addr_port,
3469 sizeof(ip_addr_port),
3477 skip = ocs_snprintf(resp_ptr + plen,
3485 return plen - plen_orig;
3498 ocs_cxn_t *cxn = arg;
3499 ocs_session_t *session = cxn->session;
3501 uint32_t cmdsn = ocs_be32toh(bhs->
cmd_sn);
3504 if (cxn->ffp_is_neg_active) {
3509 if (cmdsn + 1 == session->exp_cmd_sn) {
3510 session->exp_cmd_sn--;
3514 ocs_log_test(cxn->ocs,
"%s FFP Text timeout\n", cxn->display_name);
3521 cxn->ffp_is_neg_active = FALSE;
3524 ocs_setup_timer(cxn->ocs, &cxn->ffp_timer,
3551 uint8_t *reject_reason)
3554 ocs_session_t *session = cxn->session;
3555 char * recv_ptr = NULL;
3557 char * resp_ptr = NULL;
3566 uint8_t status_detail = 0;
3569 ocs_cxn_q_cbit_t *cbit_added = NULL;
3573 ocs_log_test(iscsi->
os,
"%s called with connection state not running", cxn->display_name);
3579 if (ocs_timer_pending(&cxn->ffp_timer)) {
3580 ocs_del_timer(&cxn->ffp_timer);
3582 ocs_memcpy(cxn->text_hdr, pi, ARRAY_SIZE(cxn->text_hdr));
3590 ocs_log_test(iscsi->
os,
"%s C=1 and F=1 Invalid - Reject PDU",
3600 if (ttt == 0xFFFFFFFF) {
3601 cxn->ffp_is_neg_active = FALSE;
3602 }
else if (!cxn->ffp_is_neg_active) {
3603 ocs_log_test(iscsi->
os,
"%s TTT set with no negotiation active - Reject PDU",
3613 if (cxn->ffp_is_neg_active) {
3614 if (ocs_be32toh(pi->
itt) != cxn->ffp_itt) {
3615 ocs_log_test(iscsi->
os,
"%s negotiation active but TTT doesn't match - Reject PDU",
3621 cxn->ffp_is_neg_active = TRUE;
3622 cxn->ffp_itt = ocs_be32toh(pi->
itt);
3623 cxn->lgn_parms_recv = 0;
3627 if (hal_io == NULL) {
3643 &status, &status_detail,
3644 &recv_ptr, &recv_len,
3645 &resp_ptr, &resp_size);
3652 cxn->cbit_rsp_offset == 0) {
3671 (session->is_discovery_session &&
3676 ocs_log_test(iscsi->
os,
"%s Text on discovery session with non SendTarget key 0x%" PRIx64
", status %d - Reject PDU",
3678 cxn->lgn_parms_recv, status);
3684 recv_ptr, recv_len);
3697 if (ocs_strcmp(st,
"All") == 0) {
3699 if (!session->is_discovery_session) {
3700 ocs_log_test(iscsi->
os,
"%s All key invalid on normal sessions - Reject PDU",
3731 }
else if (ocs_strcmp(st,
"") == 0) {
3769 po->target_transfer_tag = 0;
3771 po->target_transfer_tag = 0xffffffff;
3790 po->target_transfer_tag = 0xffffffff;
3811 cxn->ffp_is_neg_active = FALSE;
3814 ocs_log_test(iscsi->
os,
"send context update failed\n");
3823 iparam.unassisted.set_dm = TRUE;
3824 iparam.unassisted.incr_statsn = TRUE;
3825 iparam.unassisted.is_login = FALSE;
3826 iparam.unassisted.bhs = &cxn->login_hdr_mem;
3827 iparam.unassisted.payload1 = (plen > 0 ? &cxn->login_data_mem : NULL);
3828 iparam.unassisted.payload2 = NULL;
3845 if (cxn->ffp_is_neg_active &&
3846 !ocs_timer_pending(&cxn->ffp_timer)) {
3847 ocs_setup_timer(cxn->ocs, &cxn->ffp_timer,
3858 cxn->cbit_rsp_offset += plen;
3861 cxn->cbit_rsp_offset == cxn->cbit_rsp_len) {
3892 ocs_cxn_t *cxn_to_close;
3893 uint8_t send_rsp = FALSE;
3896 ocs_log_test(iscsi->
os,
"called with connection state not running");
3902 cid = ocs_be16toh(pi->
cid);
3906 cxn->send_logout_rsp = TRUE;
3908 cxn->logout_itt = ocs_be32toh(pi->
itt);
3913 if (cxn_to_close == cxn) {
3915 cxn->send_logout_rsp = TRUE;
3917 cxn->logout_itt = ocs_be32toh(pi->
itt);
3919 }
else if (cxn_to_close == NULL ) {
3935 ocs_be32toh(pi->
itt));
3939 ocs_log_test(iscsi->
os,
"Failed sending logout response");
3960 uint8_t reason_code)
3967 ocs_log_test(iscsi->
os,
"No retry resources are available");
3972 lgn_retry->
cxn = cxn;
3974 lgn_retry->
reason = reason_code;
3994 uint8_t reason_code)
4002 ocs_log_test(iscsi->
os,
"called with connection state not running");
4008 if (hal_io == NULL) {
4017 ocs_log_debug(iscsi->
os,
"logout of a connection");
4024 po->
cid = ocs_htobe16(cxn->cid);
4070 ocs_log_test(iscsi->
os,
"No retry resources are available");
4075 lgn_retry->
cxn = cxn;
4076 lgn_retry->
reason = response;
4077 lgn_retry->
itt = itt;
4106 ocs_log_test(iscsi->
os,
"called with connection state not running");
4112 if (hal_io == NULL) {
4128 po->
itt = ocs_htobe32(itt);
4171 ocs_log_test(iscsi->
os,
"called with connection state of %d",
4179 ocs_log_test(iscsi->
os,
"logout response of %d", logout_rsp->
response);
4212 if (!lgn_retry || !data_ptr || !data_len) {
4213 ocs_log_test(iscsi->
os,
"No retry resources are available");
4216 }
else if (data_len > ARRAY_SIZE(lgn_retry->
virt_buffer)) {
4221 lgn_retry->
cxn = cxn;
4222 lgn_retry->
lun = lun;
4223 lgn_retry->
itt = itt;
4224 lgn_retry->
ttt = ttt;
4226 ocs_memcpy(lgn_retry->
virt_buffer, data_ptr, data_len);
4263 ocs_log_test(iscsi->
os,
"called with connection state not running");
4274 if (hal_io == NULL) {
4287 ocs_memset(po, 0,
sizeof (*po));
4290 if (data_ptr && data_len) {
4291 ocs_memcpy(cxn->login_data_mem.virt, data_ptr, data_len);
4315 po->
itt = ocs_htobe32(itt);
4316 po->
ttt = ocs_htobe32(ttt);
4335 cxn->idle_count = 0;
4366 if (!lgn_retry || !data_ptr || !data_len) {
4367 ocs_log_test(iscsi->
os,
"No retry resources are available");
4370 }
else if (data_len > ARRAY_SIZE(lgn_retry->
virt_buffer)) {
4375 lgn_retry->
cxn = cxn;
4376 lgn_retry->
lun = lun;
4377 lgn_retry->
itt = itt;
4378 lgn_retry->
ttt = ttt;
4380 ocs_memcpy(lgn_retry->
virt_buffer, data_ptr, data_len);
4417 ocs_log_test(iscsi->
os,
"called with connection state not running");
4428 if (hal_io == NULL) {
4443 ocs_memset(po, 0,
sizeof (*po));
4445 if (data_ptr && data_len) {
4446 ocs_memcpy(cxn->login_data_mem.virt, data_ptr, data_len);
4453 po->
itt = ocs_htobe32(itt);
4454 po->
ttt = ocs_htobe32(ttt);
4481 cxn->idle_count = 0;
4510 char *data_ptr = (data == NULL ? NULL : data->
dma.virt);
4515 ocs_log_test(iscsi->
os,
"called with connection state not running");
4522 if (pi->
ttt != 0xffffffff) {
4526 ocs_be32toh(pi->
ttt),
4536 ocs_log_test(iscsi->
os,
"sending nop-out failed\n");
4567 char *data_ptr = (data == NULL ? NULL : data->
dma.virt);
4572 ocs_log_test(iscsi->
os,
"called with connection state not running");
4579 if (pi->
itt != 0xffffffff) {
4582 ocs_be32toh(pi->
itt),
4592 ocs_log_test(iscsi->
os,
"sending nop-in failed\n");
4623 ocs_log_test(iscsi->
os,
"No retry resources are available");
4626 }
else if (hdr_len > ARRAY_SIZE(lgn_retry->
virt_buffer)) {
4631 lgn_retry->
cxn = cxn;
4632 lgn_retry->
reason = reason;
4663 uint32_t data_sn = 0;
4667 ocs_log_test(iscsi->
os,
"called with connection state %d",
4674 if (hal_io == NULL) {
4692 reject = cxn->login_hdr_mem.virt;
4696 reject->
itt = 0xFFFFFFFF;
4701 ocs_memcpy(cxn->login_data_mem.virt, bhs_hdr, hdr_len);
4744 uint32_t payload_len,
4756 ocs_log_test(iscsi->
os,
"No retry resources are available");
4759 }
else if (payload_len > ARRAY_SIZE(lgn_retry->
virt_buffer)) {
4764 lgn_retry->
cxn = cxn;
4766 lgn_retry->
reason = reason;
4767 lgn_retry->
lun = lun;
4768 lgn_retry->
param1 = param1;
4769 lgn_retry->
param2 = param2;
4770 lgn_retry->
param3 = param3;
4771 ocs_memcpy(lgn_retry->
virt_buffer, payload, payload_len);
4794 uint32_t payload_len,
4808 ocs_log_test(iscsi->
os,
"called with connection state %d",
4815 if (hal_io == NULL) {
4826 lun, param1, param2, param3);
4831 async = cxn->login_hdr_mem.virt;
4835 async->
rsvd3[0] = 0xFFFFFFFF;
4838 async->
param1 = ocs_htobe16(param1);
4839 async->
param2 = ocs_htobe16(param2);
4840 async->
param3 = ocs_htobe16(param3);
4843 if (payload_len > 0) {
4844 ocs_memcpy(cxn->login_data_mem.virt, payload, payload_len);
4869 lun, param1, param2, param3);
4946 ocs_log_test(iscsi->
os,
"Invalid status %d\n", status);
4950 if (cxn->is_ini_cxn) {
4951 if (ini_fields != NULL &&
#define KEY_FLAG_SEND_TGT
static void ocs_session_max_cmd_sn_set(ocs_cxn_t *cxn, uint32_t max_cmd_sn)
#define OCS_CHAP_MODE_INITIATOR
#define OCS_ISCSI_LOGIN_DEFAULT_TIME_2_WAIT
Defines the iSCSI reject PDU header.
static void ocs_sport_unlock(ocs_sport_t *sport)
static int32_t ocs_iscsi_send_reject_queue(ocs_cxn_t *cxn, void *hdr, uint32_t hdr_len, uint8_t reason)
Function to queue a send reject request.
ocs_login_key_t
enum identifying valid login keys.
int32_t ocs_iscsi_send_logout(ocs_cxn_t *cxn, uint8_t immediate, uint8_t reason_code)
Function to send a logout PDU.
void ocs_iscsi_ffp_text_timeout(void *arg)
This function is called to check for stalled text negotiations for a connection on a target...
Defines the iSCSI text command PDU header.
#define LOGIN_STAGE_NEGOTIATE_SECURITY
iscsi_isid_tsid_t isid_tsid_ptr
void ocs_iscsi_cbit_cleanup(ocs_cxn_t *cxn)
Sends the login parameters to the firmware.
#define LOGIN_STAGE_FULL_FEATURE
int32_t ocs_iscsi_recv_login_rsp(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len)
Function to process a login response PDU.
ocs_lock_t lgn_queue_lock
ocs_pdu_process_rtn_e ocs_iscsi_recv_login(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len)
Function to process a login PDU on a target.
uint32_t ocs_iscsi_tgt_is_access_allowed(ocs_t *ocs, char *tgt_name, char *ini_name)
Checks if this initiator is allowed access to a target.
int32_t ocs_iscsi_send_async(ocs_cxn_t *cxn, void *payload, uint32_t payload_len, uint8_t reason, uint64_t lun, uint16_t param1, uint16_t param2, uint16_t param3)
Sends a asynchronous PDU with an optional payload.
static int32_t ocs_iscsi_send_login_rsp_invalid_during_login_queue(ocs_cxn_t *cxn, uint32_t itt)
Function to queue a send login request.
ocs_ip_address_t * ocs_iscsi_tgt_get_ip_address(ocs_t *ocs, char *tgt_name, uint32_t index)
Returns the IP address of the target name based on the index.
int32_t ocs_iscsi_login_cb_no_lgn_mem(ocs_hal_io_t *io, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
Function to free resources for login responses.
ocs_pdu_process_rtn_e
iSCSI PDU processing return codes
Defines the iSCSI logout response PDU header.
int32_t ocs_iscsi_are_login_reqs_outstanding(ocs_cxn_t *cxn)
Checks to see if there are any retry or login IOs active on a connection.
#define OCS_LOGIN_ERROR_WRONG_STATE
static int32_t ocs_iscsi_login_negotiate_chap_tgt(ocs_cxn_t *cxn, uint8_t *status, uint8_t *status_detail, char *rsp, uint32_t rsp_size, uint32_t *rsp_len)
Function to negotiate CHAP keys on a target connection.
uint8_t data_segment_length[3]
uint32_t ocs_iscsi_tgt_get_portal_group(ocs_t *ocs, char *tgt_name, ocs_ip_address_t *ip_address)
Returns the portal group of an IP address of the target name.
int32_t ocs_iscsi_login_initialize(ocs_iscsi_t *iscsi)
Initialize the login and retry object used within the login module.
void ocs_iscsi_cluster_tgts_free(ocs_iscsi_t *iscsi)
iscsi cluster targets free
Defines the generic iSCSI basic header segment.
Defines the fields required to track the login keys during negotiation.
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
static void ocs_sport_lock(ocs_sport_t *sport)
static int32_t ocs_iscsi_login_buffer_get(ocs_cxn_t *)
Get an available login buffer from the pre-allocated pool.
static void ocs_iscsi_cbit_backout(ocs_cxn_t *cxn, ocs_cxn_q_cbit_t *cbit)
Backs out the adding of a cbit object on this connection.
ocs_chap_state_e
Defines the state of the CHAP negotiation.
#define LOGIN_STATUS_SUCCESS
static const char irrelevant[]
#define KEY_FLAG_SEND_BOTH
int32_t ocs_iscsi_send_login(ocs_cxn_t *cxn, bool is_discovery, char *tgt_name)
Function to send an initial login PDU.
static ocs_login_key_t ocs_iscsi_login_locate_key_locations(char *data, uint32_t data_len, uint32_t pos, uint32_t *equal_pos, uint32_t *null_pos)
Finds the next equal and null termination for the key.
static void * ocs_list_get_head(ocs_list_t *list)
Return the first item in the list.
#define OCS_CHAP_MODE_TARGET
#define KEY_FLAG_PHASE_FFP
#define OCS_CLUST_TARGET_TTT
ocs_hal_rq_buffer_t * data
static uint32_t ocs_session_max_cmd_sn_get(ocs_cxn_t *cxn)
void ocs_session_max_cmd_sn_upd(ocs_session_t *session)
Updates the max_cmd_sn based on the number IOs available.
void ocs_md5_final(md5byte digest[16], ocs_md5_ctx_t *ctx)
ocs_hal_rtn_e
defines common HAL return statuses.
const ocs_login_key_def_t ocs_login_key_defs[KEY_MAX]
ocs_hal_rtn_e ocs_hal_io_init_sges(ocs_hal_t *hal, ocs_hal_io_t *io, ocs_hal_io_type_e type, uint32_t offset)
Initialize the Scatter Gather List entries of an IO.
static int32_t ocs_iscsi_send_async_queue(ocs_cxn_t *cxn, void *payload, uint32_t payload_len, uint8_t reason, uint64_t lun, uint16_t param1, uint16_t param2, uint16_t param3)
Function to queue an asynchronous request.
#define KEY_FLAG_ALLOW_LARGE
#define OCS_ISCSI_LOGIN_RETRY_ENTRIES
static ocs_sport_t * ocs_iscsi_login_convert_tgt_name(ocs_cxn_t *cxn, char *tgt_name)
Convert a target name to a sport object.
ocs_iscsi_cluster_tgt_t * ctgt_next
static void ocs_session_calc_cmd_window(ocs_cxn_t *cxn)
int32_t ocs_iscsi_login_tgt_nop_cb_free_lgn_mem(ocs_hal_io_t *io, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
Function to target NOP completions.
#define OCS_ISCSI_LOGIN_PAYLOAD_SIZE
#define CONN_STATE_LOGIN_PROGRESS
ocs_pdu_process_rtn_e ocs_iscsi_recv_text(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len, uint8_t *reject_reason)
Function to process a text PDU.
char * ocs_iscsi_ini_get_name(ocs_t *ocs)
Return this initiator's name.
uint8_t ocs_iscsi_tgt_require_chap(ocs_t *ocs, char *tgt_name, ocs_session_type_e type)
Returns TRUE if CHAP is required for the session type.
uint32_t target_transfer_tag
static int32_t ocs_iscsi_send_nop_in_queue(ocs_cxn_t *cxn, uint64_t lun, uint32_t itt, uint32_t ttt, char *data_ptr, uint32_t data_len)
Function to queue a send nop-in request.
uint32_t ocs_iscsi_add_cluster_tgt_keys(ocs_cxn_t *cxn, char *resp_ptr, uint32_t resp_size, uint32_t plen_orig)
Add iSCSI cluster target name and address.
ocs_hal_rtn_e ocs_hal_io_add_sge(ocs_hal_t *hal, ocs_hal_io_t *io, uintptr_t addr, uint32_t length)
Add a Scatter Gather list Entry to an IO.
struct ocs_hal_io_param_t::@16 unassisted
void ocs_iscsi_login_teardown(ocs_iscsi_t *iscsi)
Releases the login and retry object used within the login module.
Defines the iSCSI logout PDU header.
static void ocs_iscsi_login_convert_bin_to_hexstring(uint8_t *bin, uint32_t nbytes, char *str, uint32_t max_str)
Converts binary to an ASCII hex string.
static uint32_t ocs_iscsi_login_send_key(ocs_cxn_t *cxn, ocs_login_key_t key, char *strptr, uint32_t avail_bytes)
Function to send iSCSI login keys.
int32_t ocs_iscsi_send_context_udpate(ocs_cxn_t *cxn)
Sends the login parameters to the FW.
#define CONN_STATE_NEW_CONN
int32_t ocs_iscsi_send_reject(ocs_cxn_t *cxn, void *hdr, uint32_t hdr_len, uint8_t reason)
Sends a reject PDU for the supplied PDU header.
static int32_t ocs_iscsi_send_nop_out_queue(ocs_cxn_t *cxn, uint64_t lun, uint32_t itt, uint32_t ttt, char *data_ptr, uint32_t data_len)
Function to queue a send nop-out request.
defines the parameters for an IO based on the IO type.
#define LOGIN_STAGE_NEGOTIATE_OPERATIONAL
#define LOGIN_STATUS_DETAIL_INI_AUTHENTICATION
#define LOGIN_STATUS_DETAIL_INI_AUTHORIZATION
static int32_t ocs_iscsi_login_recv_key(ocs_cxn_t *cxn, ocs_login_key_t key, char *value, uint8_t *status_detail)
Function to receive a login key and update the login structure.
struct ocs_hal_io_param_t::@12 ini_nop
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
char * ocs_iscsi_tgt_get_names(ocs_t *ocs, uint32_t index)
Returns the target name based on the index.
#define OCS_LOGIN_ERROR_VIRT_ARRAY_TOO_SMALL
#define CONN_STATE_IN_LOGOUT
#define OCS_CHAP_TYPE_INCOMING
#define KEY_FLAG_USE_LOGIN
ocs_hal_io_t * ocs_hal_io_alloc(ocs_hal_t *hal)
Allocate a HAL IO object.
Defines the iSCSI login response PDU header.
static int32_t ocs_iscsi_send_logout_rsp_queue(ocs_cxn_t *cxn, uint8_t response, uint32_t itt)
Function to queue a send logout response request.
static ocs_iscsi_lgn_retry_t * ocs_iscsi_login_retry_get(ocs_iscsi_t *)
Get an available retry buffer from the pre-allocated pool.
#define ocs_list_init(head, type, link)
#define LOGIN_STATUS_DETAIL_INI_SESSION_NOT_EXIST
int32_t ocs_iscsi_send_nop_out(ocs_cxn_t *cxn, uint64_t lun, uint32_t itt, uint32_t ttt, char *data_ptr, uint32_t data_len)
Send NOP-Out from an initiator.
char * ocs_iscsi_get_chap_name(ocs_t *ocs, uint8_t sess_type, uint32_t mode, uint32_t type)
Returns the CHAP user name of corresponding type.
static int32_t ocs_iscsi_login_negotiate_chap_ini(ocs_cxn_t *cxn, uint8_t *status, uint8_t *status_detail, char *rsp, uint32_t rsp_size, uint32_t *rsp_len)
Function to negotiate CHAP keys on an initiator connection.
#define KEY_FLAG_PHASE_ALL
static int32_t ocs_iscsi_login_find_value(char *text, const char *value)
Searches the list of comma-separated values for a specific value.
static ocs_cxn_q_cbit_t * ocs_iscsi_cbit_pdu_setup(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, ocs_hal_rq_buffer_t *data, uint32_t data_len, uint8_t *status, uint8_t *status_detail, char **recv_ptr, uint32_t *recv_len, char **resp_ptr, uint32_t *resp_size)
Does the initial checks and processing for the continue bit.
static int32_t ocs_iscsi_login_retries_allocate(ocs_iscsi_t *iscsi)
Allocate the iSCSI retry buffers and add them to the pool.
static int32_t ocs_iscsi_send_logout_queue(ocs_cxn_t *cxn, uint8_t immediate, uint8_t reason_code)
Function to queue a send logout request.
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
ocs_hal_rtn_e ocs_hal_io_send(ocs_hal_t *hal, ocs_hal_io_type_e type, ocs_hal_io_t *io, uint32_t len, ocs_hal_io_param_t *iparam, ocs_cxn_t *cxn, io_cb_t cb, void *arg)
Send a read, write, or response IO.
void ocs_target_io_aborted_nop_cmpl(ocs_cxn_t *cxn)
This function is called whenever a target NOP completes.
static int32_t ocs_iscsi_send_login_queue(ocs_cxn_t *cxn, bool is_discovery, char *tgt_name)
Function to queue a send login request.
#define KEY_FLAG_NEGOTIATE
#define CONN_STATE_LOGOUT_REQUESTED
Defines the iSCSI header for the async PDU.
#define ISCSI_REJECT_REASON_INVALID_PDU_FIELD
ocs_pdu_process_rtn_e ocs_iscsi_recv_nop_out(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len)
Handle NOP-OUT from an initiator.
static int32_t ocs_iscsi_add_tgt_keys(ocs_cxn_t *cxn, char *resp_ptr, uint32_t resp_size, uint32_t plen_orig, char *tgt_name)
Add targets to the sendTarget response.
static void ocs_iscsi_login_buffer_free(ocs_cxn_t *)
Return a login buffer to the pre-allocated pool.
#define LOGIN_STATUS_INI_ERROR
int32_t ocs_scsi_new_initiator(ocs_node_t *node)
Receive notification of a new SCSI initiator node.
#define KEY_FLAG_SEND_INI
Defines a wrapper for the RQ payload buffers so that we can place it back on the proper queue...
iscsi_isid_tsid_t isid_tsid_ptr
#define CONN_STATE_LOGIN_FAILED
ocs_pdu_process_rtn_e ocs_iscsi_recv_logout(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len)
Function to process a logout PDU.
static void ocs_session_exp_cmd_sn_set(ocs_cxn_t *cxn, uint32_t exp_cmd_sn)
Defines the iSCSI AHS and data segment length in the PDU header.
void ocs_md5_init(ocs_md5_ctx_t *ctx)
Defines the iSCSI nop-out PDU header.
#define LOGOUT_REASON_CLOSE_CONN_FOR_RECOVERY
#define LOGIN_STATUS_DETAIL_TGT_MISC
void ocs_session_close(ocs_session_t *session, uint8_t reset)
Closes all connections on a session.
uint32_t ocs_instance(void *os)
Return the instance index of an opaque ocs structure.
char * ocs_iscsi_get_chap_secret(ocs_t *ocs, char *name, uint32_t mode, uint32_t type, uint32_t *secret_len)
Returns the unenctypted CHAP secret for a specific user name. Note: Passwords should be at least 16 c...
int32_t ocs_iscsi_send_nop_in(ocs_cxn_t *cxn, uint64_t lun, uint32_t itt, uint32_t ttt, char *data_ptr, uint32_t data_len)
Send NOP-In from a target.
#define ISCSI_REJECT_REASON_PROTOCOL_ERR
Defines the iSCSI text response PDU header.
void ocs_iscsi_rx_buffers_free(ocs_iscsi_t *iscsi, ocs_hal_rq_buffer_t *header, ocs_hal_rq_buffer_t *payload)
Add a receive buffer pair to the Receive Queue, if an error is received, then queue the buffer...
static uint32_t ocs_session_exp_cmd_sn_get(ocs_cxn_t *cxn)
static int32_t ocs_iscsi_login_check_first(ocs_cxn_t *cxn, iscsi_login_cmd_hdr_t *pi, uint8_t *status, uint8_t *status_detail, char *data, uint32_t data_len)
Function to validate the initial login PDU.
int32_t ocs_iscsi_send_login_rsp_invalid_during_login(ocs_cxn_t *cxn, uint32_t itt)
Function to send an login Response PDU (invalid during login).
int ocs_sm_post_event(ocs_sm_ctx_t *ctx, ocs_sm_event_t evt, void *data)
Post an event to a context.
#define ISCSI_REJECT_REASON_NEG_RESET
ocs_list_t login_retry_busy
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
#define OCS_LOGIN_NO_QUEUING_RESOURCES
void ocs_hal_io_free(ocs_hal_t *hal, ocs_hal_io_t *io)
Free a previously allocated HAL IO object.
#define LOGIN_STATUS_DETAIL_INI_MISSING_PARAM
static const char crc32c[]
#define OCS_TEXT_TIMEOUT_MS
static const char rfc3720[]
#define KEY_FLAG_PHASE_SEC
#define OCS_ISCSI_LOGIN_MAX_RECV_DATA_SEG_LEN
#define KEY_FLAG_USE_LEADING
#define ocs_list_remove_head(list)
Remove and return an item from the head of the list.
ocs_hal_rq_buffer_t * hdr
static void ocs_iscsi_login_set_dslen(iscsi_hdr_dw2_t *dw, unsigned int count)
Fill in the data segment length in a PDU header.
void format_ip_address(ocs_ip_type_e ip_type, uint8_t *address, char *buffer, int size)
Format an IP address into a string.
ocs_iscsi_cluster_sendtargets_t clusttgt
#define ISCSI_VERSION_MAX
char * ocs_iscsi_ini_get_alias(ocs_t *ocs)
Returns the initiator alias.
static void ocs_node_lock(ocs_node_t *node)
#define ISCSI_CMD_DATA_OUT
#define ISCSI_RESP_LOGOUT
#define KEY_FLAG_PHASE_OPER
void ocs_iscsi_login_retry(ocs_cxn_t *cxn)
Attempt to start a request on the retry queue.
int32_t ocs_iscsi_send_logout_rsp(ocs_cxn_t *cxn, uint8_t response, uint32_t itt)
Function to send a logout response PDU.
defines a structure to contain the fields specific to an initiator IO completion. ...
#define ocs_is_target_enabled()
static void * ocs_list_next(ocs_list_t *list, void *item)
Get the next item on the list.
#define ISCSI_RESP_REJECT
static uint64_t ocs_session_isid_get(ocs_cxn_t *cxn)
#define LOGOUT_RESP_CID_NOT_FOUND
int32_t ocs_iscsi_recv_logout_rsp(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len)
Handle logout response from a target.
static uint32_t ocs_session_cmd_sn_get(ocs_cxn_t *cxn, uint32_t inc)
#define LOGOUT_RESP_CONN_RECOVERY_NOT_SUPPORTED
void ocs_md5_update(ocs_md5_ctx_t *ctx, md5byte const *buf, unsigned len)
static void ocs_node_unlock(ocs_node_t *node)
#define LOGOUT_REASON_CLOSE_SESS
#define LOGIN_STATUS_DETAIL_INI_UNSUPPORTED_VERSION
Defines the iSCSI data-out PDU header.
#define KEY_FLAG_VALID_DISC
ocs_iscsi_retry_type_e
The types of requests that may be retried.
static uint16_t ocs_session_tsih_get(ocs_cxn_t *cxn)
#define LOGIN_STATUS_DETAIL_INI_INVALID_DURING_LGN
static void ocs_session_tsih_set(ocs_cxn_t *cxn, uint16_t tsih)
#define KEY_FLAG_ALLOW_MULTI
ocs_iscsi_lgn_retry_t * lgn_retry
int32_t ocs_iscsi_recv_nop_in(ocs_cxn_t *cxn, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len)
Handle NOP-IN from a target.
int32_t ocs_session_cxn_new(ocs_cxn_t *cxn, char *tgt_name, char *ini_name, uint64_t isid, uint16_t tsih, uint16_t cid, uint32_t cmd_sn)
Find an existing session or create a new one based on the login parameters.
#define LOGOUT_REASON_CLOSE_CONN
static int32_t ocs_iscsi_recv_common_queue(ocs_cxn_t *cxn, ocs_iscsi_retry_type_e type, ocs_hal_rq_buffer_t *hdr, uint32_t hdr_len, ocs_hal_rq_buffer_t *data, uint32_t data_len)
Function to queue a receive request.
#define ocs_assert(cond,...)
static void ocs_iscsi_cbit_fill_buffer(ocs_cxn_t *cxn, uint8_t status, uint32_t *len)
Copies the appropriate send data from the c bit processing.
#define OCS_ISCSI_TCP_PORT
#define CONN_STATE_FULL_FEATURE
static uint32_t ocs_iscsi_login_convert_hexstring_to_bin(char *hex_str, uint8_t *bin, uint32_t nbytes)
Function to negotiate CHAP keys.
ocs_list_t login_retry_free
int32_t ocs_iscsi_login_tgt_nop_cb_no_lgn_mem(ocs_hal_io_t *io, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
Function to target NOP completions.
#define OCS_LOGIN_REQUEST_QUEUED
uint32_t ocs_iscsi_get_max_cxns(ocs_t *ocs, char *tgt_name, char *ini_name)
Returns the maximum number of connections allowed per session.
#define ocs_list_foreach(list, item)
Iterate a linked list.
structure wrapping an IP address together with it's type.
static uint32_t ocs_iscsi_login_negotiate(ocs_cxn_t *cxn, uint8_t phase, uint8_t *status, uint8_t *status_detail, char *recv, uint32_t recv_len, char *rsp, uint32_t rsp_size)
Function to negotiate iSCSI keys.
#define OCS_ISCSI_LOGIN_DEFAULT_TIME_2_RETAIN
#define LOGOUT_RESP_CONN_SESS_CLOSE_SUCCESS
#define LOGIN_STATUS_DETAIL_INI_MISC
int32_t ocs_iscsi_login_cb_free_lgn_mem(ocs_hal_io_t *io, ocs_cxn_t *cxn, int32_t status, ocs_ini_cmpl_fields_t *ini_fields, void *ul_arg)
#define OCS_CHAP_CHALLENGE_SIZE
static char * ocs_iscsi_login_find_key(char *key, char *text, unsigned int length)
Find a key within the passed login text.
char tgt_name[OCS_MAX_ISCSI_NAME]
#define KEY_FLAG_PHASE_SEC_OPER
Defines the iSCSI nop-in PDU header.
#define ISCSI_VERSION_MIN
char * ocs_iscsi_tgt_get_alias(ocs_t *ocs, uint32_t index)
Returns the target alias based on the index.
int32_t ocs_cxn_close(ocs_cxn_t *cxn, uint8_t sendRst)
Issues a request to the HAL to close the connection.
static void ocs_iscsi_login_retries_free(ocs_iscsi_t *iscsi)
Free the iSCSI login retry buffers.
object to queue login requests waiting for buffers
ocs_cxn_t * ocs_session_cxn_find(ocs_session_t *session, uint16_t cid)
Locate a connection within a session based on the cid.
static void ocs_iscsi_login_retry_free(ocs_iscsi_t *, ocs_iscsi_lgn_retry_t *)
Return a login retry buffer to the pre-allocated pool.
#define LOGIN_STATUS_DETAIL_INI_TOO_MANY_CXN
#define LOGIN_STATUS_DETAIL_TGT_OUT_OF_RSRC
#define OCS_CHAP_TYPE_OUTGOING
ocs_iscsi_retry_type_e type
static void ocs_session_cmd_window_set(ocs_cxn_t *cxn, uint32_t cmd_window)
#define CONN_STATE_CLEANUP
static uint32_t ocs_session_is_window_open(ocs_cxn_t *cxn)
ocs_hal_rtn_e ocs_iscsi_login_cxn_cleanup(ocs_cxn_t *cxn)
Frees any retry objects for the connection.
Defines the iSCSI login PDU header.
#define LOGIN_STATUS_TGT_ERROR