From 7dbbd1aeaed98e379ee3b1589f659831dd39709c Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 22 Oct 2020 20:26:27 +0000 Subject: [PATCH] Negotiate iSCSIProtocolLevel of 2 (RFC 7144) in initiator. It does not change anything immediately, but allows further support of Command Priority, Status Qualifier and new task management functions. MFC after: 1 month Sponsored by: iXsystems, Inc. --- sys/dev/iscsi/iscsi.c | 1 + sys/dev/iscsi/iscsi.h | 3 +-- sys/dev/iscsi/iscsi_ioctl.h | 3 ++- sys/dev/iscsi/iscsi_proto.h | 6 +++++- usr.sbin/iscsid/iscsid.c | 2 ++ usr.sbin/iscsid/iscsid.h | 1 + usr.sbin/iscsid/login.c | 6 ++++++ 7 files changed, 18 insertions(+), 4 deletions(-) diff --git a/sys/dev/iscsi/iscsi.c b/sys/dev/iscsi/iscsi.c index 5fa3bdb9dff4..c0fa3115d64a 100644 --- a/sys/dev/iscsi/iscsi.c +++ b/sys/dev/iscsi/iscsi.c @@ -1427,6 +1427,7 @@ iscsi_ioctl_daemon_handoff(struct iscsi_softc *sc, sizeof(is->is_target_alias)); is->is_tsih = handoff->idh_tsih; is->is_statsn = handoff->idh_statsn; + is->is_protocol_level = handoff->idh_protocol_level; is->is_initial_r2t = handoff->idh_initial_r2t; is->is_immediate_data = handoff->idh_immediate_data; diff --git a/sys/dev/iscsi/iscsi.h b/sys/dev/iscsi/iscsi.h index b6e774f2ae97..607d0a7386f6 100644 --- a/sys/dev/iscsi/iscsi.h +++ b/sys/dev/iscsi/iscsi.h @@ -61,8 +61,7 @@ struct iscsi_session { uint32_t is_expcmdsn; uint32_t is_maxcmdsn; uint32_t is_initiator_task_tag; - int is_header_digest; - int is_data_digest; + int is_protocol_level; int is_initial_r2t; int is_max_burst_length; int is_first_burst_length; diff --git a/sys/dev/iscsi/iscsi_ioctl.h b/sys/dev/iscsi/iscsi_ioctl.h index ef31d31fe415..27c51c12736e 100644 --- a/sys/dev/iscsi/iscsi_ioctl.h +++ b/sys/dev/iscsi/iscsi_ioctl.h @@ -124,7 +124,8 @@ struct iscsi_daemon_handoff { unsigned int idh_session_id; int idh_socket; char idh_target_alias[ISCSI_ALIAS_LEN]; - uint8_t idh_spare_isid[6]; + int idh_protocol_level; + uint16_t idh_spare; uint16_t idh_tsih; uint16_t idh_spare_cid; uint32_t idh_statsn; diff --git a/sys/dev/iscsi/iscsi_proto.h b/sys/dev/iscsi/iscsi_proto.h index 9ec24f46425a..cde594f863f7 100644 --- a/sys/dev/iscsi/iscsi_proto.h +++ b/sys/dev/iscsi/iscsi_proto.h @@ -90,10 +90,14 @@ CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE); #define BHSSC_FLAGS_ATTR_HOQ 3 #define BHSSC_FLAGS_ATTR_ACA 4 +#define BHSSC_PRI_MASK 0xf0 +#define BHSSC_PRI_SHIFT 4 + struct iscsi_bhs_scsi_command { uint8_t bhssc_opcode; uint8_t bhssc_flags; - uint8_t bhssc_reserved[2]; + uint8_t bhssc_pri; + uint8_t bhssc_reserved; uint8_t bhssc_total_ahs_len; uint8_t bhssc_data_segment_len[3]; uint64_t bhssc_lun; diff --git a/usr.sbin/iscsid/iscsid.c b/usr.sbin/iscsid/iscsid.c index 5d121e83b158..92c3cddba57f 100644 --- a/usr.sbin/iscsid/iscsid.c +++ b/usr.sbin/iscsid/iscsid.c @@ -172,6 +172,7 @@ connection_new(int iscsi_fd, const struct iscsi_daemon_request *request) /* * Default values, from RFC 3720, section 12. */ + conn->conn_protocol_level = 0; conn->conn_header_digest = CONN_DIGEST_NONE; conn->conn_data_digest = CONN_DIGEST_NONE; conn->conn_initial_r2t = true; @@ -329,6 +330,7 @@ handoff(struct connection *conn) sizeof(idh.idh_target_alias)); idh.idh_tsih = conn->conn_tsih; idh.idh_statsn = conn->conn_statsn; + idh.idh_protocol_level = conn->conn_protocol_level; idh.idh_header_digest = conn->conn_header_digest; idh.idh_data_digest = conn->conn_data_digest; idh.idh_initial_r2t = conn->conn_initial_r2t; diff --git a/usr.sbin/iscsid/iscsid.h b/usr.sbin/iscsid/iscsid.h index e1a5e92113d2..93d741782520 100644 --- a/usr.sbin/iscsid/iscsid.h +++ b/usr.sbin/iscsid/iscsid.h @@ -57,6 +57,7 @@ struct connection { uint8_t conn_isid[6]; uint16_t conn_tsih; uint32_t conn_statsn; + int conn_protocol_level; int conn_header_digest; int conn_data_digest; bool conn_initial_r2t; diff --git a/usr.sbin/iscsid/login.c b/usr.sbin/iscsid/login.c index 112c97e48975..cfb370bba28d 100644 --- a/usr.sbin/iscsid/login.c +++ b/usr.sbin/iscsid/login.c @@ -341,6 +341,11 @@ login_negotiate_key(struct connection *conn, const char *name, sizeof(conn->conn_target_alias)); } else if (strcmp(value, "Irrelevant") == 0) { /* Ignore. */ + } else if (strcmp(name, "iSCSIProtocolLevel") == 0) { + tmp = strtoul(value, NULL, 10); + if (tmp < 0 || tmp > 31) + log_errx(1, "received invalid iSCSIProtocolLevel"); + conn->conn_protocol_level = tmp; } else if (strcmp(name, "HeaderDigest") == 0) { which = login_list_prefers(value, "CRC32C", "None"); switch (which) { @@ -500,6 +505,7 @@ login_negotiate(struct connection *conn) * The following keys are irrelevant for discovery sessions. */ if (conn->conn_conf.isc_discovery == 0) { + keys_add(request_keys, "iSCSIProtocolLevel", "2"); if (conn->conn_conf.isc_header_digest != 0) keys_add(request_keys, "HeaderDigest", "CRC32C"); else