Make iSCSI initiator keep Initiator Session ID (ISID) across reconnects.
Previously ISID was changed every time, that made impossible correct persistent reservation, because reconnected session was identified as completely new one. Reviewed by: trasz MFC after: 1 week
This commit is contained in:
parent
0558e4bb2b
commit
ffe82e05b3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268326
@ -1221,6 +1221,9 @@ iscsi_ioctl_daemon_wait(struct iscsi_softc *sc,
|
|||||||
ISCSI_SESSION_UNLOCK(is);
|
ISCSI_SESSION_UNLOCK(is);
|
||||||
|
|
||||||
request->idr_session_id = is->is_id;
|
request->idr_session_id = is->is_id;
|
||||||
|
memcpy(&request->idr_isid, &is->is_isid,
|
||||||
|
sizeof(request->idr_isid));
|
||||||
|
request->idr_tsih = 0; /* New or reinstated session. */
|
||||||
memcpy(&request->idr_conf, &is->is_conf,
|
memcpy(&request->idr_conf, &is->is_conf,
|
||||||
sizeof(request->idr_conf));
|
sizeof(request->idr_conf));
|
||||||
|
|
||||||
@ -1270,7 +1273,7 @@ iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc,
|
|||||||
|
|
||||||
strlcpy(is->is_target_alias, handoff->idh_target_alias,
|
strlcpy(is->is_target_alias, handoff->idh_target_alias,
|
||||||
sizeof(is->is_target_alias));
|
sizeof(is->is_target_alias));
|
||||||
memcpy(is->is_isid, handoff->idh_isid, sizeof(is->is_isid));
|
is->is_tsih = handoff->idh_tsih;
|
||||||
is->is_statsn = handoff->idh_statsn;
|
is->is_statsn = handoff->idh_statsn;
|
||||||
is->is_initial_r2t = handoff->idh_initial_r2t;
|
is->is_initial_r2t = handoff->idh_initial_r2t;
|
||||||
is->is_immediate_data = handoff->idh_immediate_data;
|
is->is_immediate_data = handoff->idh_immediate_data;
|
||||||
@ -1663,6 +1666,9 @@ iscsi_ioctl_session_add(struct iscsi_softc *sc, struct iscsi_session_add *isa)
|
|||||||
is->is_softc = sc;
|
is->is_softc = sc;
|
||||||
sc->sc_last_session_id++;
|
sc->sc_last_session_id++;
|
||||||
is->is_id = sc->sc_last_session_id;
|
is->is_id = sc->sc_last_session_id;
|
||||||
|
is->is_isid[0] = 0x80; /* RFC 3720, 10.12.5: 10b, "Random" ISID. */
|
||||||
|
arc4rand(&is->is_isid[1], 5, 0);
|
||||||
|
is->is_tsih = 0;
|
||||||
callout_init(&is->is_callout, 1);
|
callout_init(&is->is_callout, 1);
|
||||||
callout_reset(&is->is_callout, 1 * hz, iscsi_callout, is);
|
callout_reset(&is->is_callout, 1 * hz, iscsi_callout, is);
|
||||||
TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next);
|
TAILQ_INSERT_TAIL(&sc->sc_sessions, is, is_next);
|
||||||
|
@ -64,6 +64,7 @@ struct iscsi_session {
|
|||||||
size_t is_max_burst_length;
|
size_t is_max_burst_length;
|
||||||
size_t is_first_burst_length;
|
size_t is_first_burst_length;
|
||||||
uint8_t is_isid[6];
|
uint8_t is_isid[6];
|
||||||
|
uint16_t is_tsih;
|
||||||
bool is_immediate_data;
|
bool is_immediate_data;
|
||||||
size_t is_max_data_segment_length;
|
size_t is_max_data_segment_length;
|
||||||
char is_target_alias[ISCSI_ALIAS_LEN];
|
char is_target_alias[ISCSI_ALIAS_LEN];
|
||||||
|
@ -91,8 +91,8 @@ struct iscsi_session_state {
|
|||||||
struct iscsi_daemon_request {
|
struct iscsi_daemon_request {
|
||||||
unsigned int idr_session_id;
|
unsigned int idr_session_id;
|
||||||
struct iscsi_session_conf idr_conf;
|
struct iscsi_session_conf idr_conf;
|
||||||
uint8_t idr_spare_isid[6];
|
uint8_t idr_isid[6];
|
||||||
uint16_t idr_spare_tsih;
|
uint16_t idr_tsih;
|
||||||
uint16_t idr_spare_cid;
|
uint16_t idr_spare_cid;
|
||||||
int idr_spare[4];
|
int idr_spare[4];
|
||||||
};
|
};
|
||||||
@ -101,9 +101,9 @@ struct iscsi_daemon_handoff {
|
|||||||
unsigned int idh_session_id;
|
unsigned int idh_session_id;
|
||||||
int idh_socket;
|
int idh_socket;
|
||||||
char idh_target_alias[ISCSI_ALIAS_LEN];
|
char idh_target_alias[ISCSI_ALIAS_LEN];
|
||||||
uint8_t idh_isid[6];
|
uint8_t idh_spare_isid[6];
|
||||||
uint16_t idr_spare_tsih;
|
uint16_t idh_tsih;
|
||||||
uint16_t idr_spare_cid;
|
uint16_t idh_spare_cid;
|
||||||
uint32_t idh_statsn;
|
uint32_t idh_statsn;
|
||||||
int idh_header_digest;
|
int idh_header_digest;
|
||||||
int idh_data_digest;
|
int idh_data_digest;
|
||||||
|
@ -149,8 +149,8 @@ resolve_addr(const struct connection *conn, const char *address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct connection *
|
static struct connection *
|
||||||
connection_new(unsigned int session_id, const struct iscsi_session_conf *conf,
|
connection_new(unsigned int session_id, const uint8_t isid[8], uint16_t tsih,
|
||||||
int iscsi_fd)
|
const struct iscsi_session_conf *conf, int iscsi_fd)
|
||||||
{
|
{
|
||||||
struct connection *conn;
|
struct connection *conn;
|
||||||
struct addrinfo *from_ai, *to_ai;
|
struct addrinfo *from_ai, *to_ai;
|
||||||
@ -176,6 +176,8 @@ connection_new(unsigned int session_id, const struct iscsi_session_conf *conf,
|
|||||||
conn->conn_first_burst_length = 65536;
|
conn->conn_first_burst_length = 65536;
|
||||||
|
|
||||||
conn->conn_session_id = session_id;
|
conn->conn_session_id = session_id;
|
||||||
|
memcpy(&conn->conn_isid, isid, sizeof(conn->conn_isid));
|
||||||
|
conn->conn_tsih = tsih;
|
||||||
conn->conn_iscsi_fd = iscsi_fd;
|
conn->conn_iscsi_fd = iscsi_fd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -264,7 +266,7 @@ handoff(struct connection *conn)
|
|||||||
idh.idh_socket = conn->conn_socket;
|
idh.idh_socket = conn->conn_socket;
|
||||||
strlcpy(idh.idh_target_alias, conn->conn_target_alias,
|
strlcpy(idh.idh_target_alias, conn->conn_target_alias,
|
||||||
sizeof(idh.idh_target_alias));
|
sizeof(idh.idh_target_alias));
|
||||||
memcpy(idh.idh_isid, conn->conn_isid, sizeof(idh.idh_isid));
|
idh.idh_tsih = conn->conn_tsih;
|
||||||
idh.idh_statsn = conn->conn_statsn;
|
idh.idh_statsn = conn->conn_statsn;
|
||||||
idh.idh_header_digest = conn->conn_header_digest;
|
idh.idh_header_digest = conn->conn_header_digest;
|
||||||
idh.idh_data_digest = conn->conn_data_digest;
|
idh.idh_data_digest = conn->conn_data_digest;
|
||||||
@ -430,7 +432,8 @@ handle_request(int iscsi_fd, const struct iscsi_daemon_request *request, int tim
|
|||||||
setproctitle("%s", request->idr_conf.isc_target_addr);
|
setproctitle("%s", request->idr_conf.isc_target_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
conn = connection_new(request->idr_session_id, &request->idr_conf, iscsi_fd);
|
conn = connection_new(request->idr_session_id, request->idr_isid,
|
||||||
|
request->idr_tsih, &request->idr_conf, iscsi_fd);
|
||||||
set_timeout(timeout);
|
set_timeout(timeout);
|
||||||
capsicate(conn);
|
capsicate(conn);
|
||||||
login(conn);
|
login(conn);
|
||||||
|
@ -51,6 +51,7 @@ struct connection {
|
|||||||
struct iscsi_session_conf conn_conf;
|
struct iscsi_session_conf conn_conf;
|
||||||
char conn_target_alias[ISCSI_ADDR_LEN];
|
char conn_target_alias[ISCSI_ADDR_LEN];
|
||||||
uint8_t conn_isid[6];
|
uint8_t conn_isid[6];
|
||||||
|
uint16_t conn_tsih;
|
||||||
uint32_t conn_statsn;
|
uint32_t conn_statsn;
|
||||||
int conn_header_digest;
|
int conn_header_digest;
|
||||||
int conn_data_digest;
|
int conn_data_digest;
|
||||||
|
@ -260,6 +260,7 @@ login_receive(struct connection *conn)
|
|||||||
"is %d, should be %d", ntohl(bhslr->bhslr_statsn),
|
"is %d, should be %d", ntohl(bhslr->bhslr_statsn),
|
||||||
conn->conn_statsn + 1);
|
conn->conn_statsn + 1);
|
||||||
}
|
}
|
||||||
|
conn->conn_tsih = ntohs(bhslr->bhslr_tsih);
|
||||||
conn->conn_statsn = ntohl(bhslr->bhslr_statsn);
|
conn->conn_statsn = ntohl(bhslr->bhslr_statsn);
|
||||||
|
|
||||||
initial = false;
|
initial = false;
|
||||||
@ -295,6 +296,7 @@ login_new_request(struct connection *conn, int csg)
|
|||||||
login_set_nsg(request, nsg);
|
login_set_nsg(request, nsg);
|
||||||
|
|
||||||
memcpy(bhslr->bhslr_isid, &conn->conn_isid, sizeof(bhslr->bhslr_isid));
|
memcpy(bhslr->bhslr_isid, &conn->conn_isid, sizeof(bhslr->bhslr_isid));
|
||||||
|
bhslr->bhslr_tsih = htons(conn->conn_tsih);
|
||||||
bhslr->bhslr_initiator_task_tag = 0;
|
bhslr->bhslr_initiator_task_tag = 0;
|
||||||
bhslr->bhslr_cmdsn = 0;
|
bhslr->bhslr_cmdsn = 0;
|
||||||
bhslr->bhslr_expstatsn = htonl(conn->conn_statsn + 1);
|
bhslr->bhslr_expstatsn = htonl(conn->conn_statsn + 1);
|
||||||
@ -824,24 +826,6 @@ login_chap(struct connection *conn)
|
|||||||
log_debugx("CHAP authentication done");
|
log_debugx("CHAP authentication done");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
login_create_isid(struct connection *conn)
|
|
||||||
{
|
|
||||||
int rv;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* RFC 3720, 10.12.5: 10b, "Random" ISID.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
conn->conn_isid[0] = 0x80;
|
|
||||||
|
|
||||||
rv = RAND_bytes(&conn->conn_isid[1], 3);
|
|
||||||
if (rv != 1) {
|
|
||||||
log_errx(1, "RAND_bytes failed: %s",
|
|
||||||
ERR_error_string(ERR_get_error(), NULL));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
login(struct connection *conn)
|
login(struct connection *conn)
|
||||||
{
|
{
|
||||||
@ -851,8 +835,6 @@ login(struct connection *conn)
|
|||||||
const char *auth_method;
|
const char *auth_method;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
login_create_isid(conn);
|
|
||||||
|
|
||||||
log_debugx("beginning Login phase; sending Login PDU");
|
log_debugx("beginning Login phase; sending Login PDU");
|
||||||
request = login_new_request(conn, BHSLR_STAGE_SECURITY_NEGOTIATION);
|
request = login_new_request(conn, BHSLR_STAGE_SECURITY_NEGOTIATION);
|
||||||
request_keys = keys_new();
|
request_keys = keys_new();
|
||||||
|
Loading…
Reference in New Issue
Block a user