62 #define EACCES_INCORRECT_TARGET_USERNAME \ 63 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME ) 64 #define EINFO_EACCES_INCORRECT_TARGET_USERNAME \ 65 __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" ) 66 #define EACCES_INCORRECT_TARGET_PASSWORD \ 67 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD ) 68 #define EINFO_EACCES_INCORRECT_TARGET_PASSWORD \ 69 __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" ) 70 #define EINVAL_ROOT_PATH_TOO_SHORT \ 71 __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT ) 72 #define EINFO_EINVAL_ROOT_PATH_TOO_SHORT \ 73 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" ) 74 #define EINVAL_BAD_CREDENTIAL_MIX \ 75 __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX ) 76 #define EINFO_EINVAL_BAD_CREDENTIAL_MIX \ 77 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" ) 78 #define EINVAL_NO_ROOT_PATH \ 79 __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH ) 80 #define EINFO_EINVAL_NO_ROOT_PATH \ 81 __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" ) 82 #define EINVAL_NO_TARGET_IQN \ 83 __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN ) 84 #define EINFO_EINVAL_NO_TARGET_IQN \ 85 __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" ) 86 #define EINVAL_NO_INITIATOR_IQN \ 87 __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN ) 88 #define EINFO_EINVAL_NO_INITIATOR_IQN \ 89 __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" ) 90 #define EINVAL_MAXBURSTLENGTH \ 91 __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH ) 92 #define EINFO_EINVAL_MAXBURSTLENGTH \ 93 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" ) 94 #define EIO_TARGET_UNAVAILABLE \ 95 __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE ) 96 #define EINFO_EIO_TARGET_UNAVAILABLE \ 97 __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" ) 98 #define EIO_TARGET_NO_RESOURCES \ 99 __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES ) 100 #define EINFO_EIO_TARGET_NO_RESOURCES \ 101 __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" ) 102 #define ENOTSUP_INITIATOR_STATUS \ 103 __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS ) 104 #define EINFO_ENOTSUP_INITIATOR_STATUS \ 105 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" ) 106 #define ENOTSUP_OPCODE \ 107 __einfo_error ( EINFO_ENOTSUP_OPCODE ) 108 #define EINFO_ENOTSUP_OPCODE \ 109 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" ) 110 #define ENOTSUP_DISCOVERY \ 111 __einfo_error ( EINFO_ENOTSUP_DISCOVERY ) 112 #define EINFO_ENOTSUP_DISCOVERY \ 113 __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" ) 114 #define ENOTSUP_TARGET_STATUS \ 115 __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS ) 116 #define EINFO_ENOTSUP_TARGET_STATUS \ 117 __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" ) 118 #define EPERM_INITIATOR_AUTHENTICATION \ 119 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION ) 120 #define EINFO_EPERM_INITIATOR_AUTHENTICATION \ 121 __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" ) 122 #define EPERM_INITIATOR_AUTHORISATION \ 123 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION ) 124 #define EINFO_EPERM_INITIATOR_AUTHORISATION \ 125 __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" ) 126 #define EPROTO_INVALID_CHAP_ALGORITHM \ 127 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM ) 128 #define EINFO_EPROTO_INVALID_CHAP_ALGORITHM \ 129 __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" ) 130 #define EPROTO_INVALID_CHAP_IDENTIFIER \ 131 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER ) 132 #define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER \ 133 __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" ) 134 #define EPROTO_INVALID_LARGE_BINARY \ 135 __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY ) 136 #define EINFO_EPROTO_INVALID_LARGE_BINARY \ 137 __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" ) 138 #define EPROTO_INVALID_CHAP_RESPONSE \ 139 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE ) 140 #define EINFO_EPROTO_INVALID_CHAP_RESPONSE \ 141 __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" ) 142 #define EPROTO_INVALID_KEY_VALUE_PAIR \ 143 __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR ) 144 #define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR \ 145 __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" ) 146 #define EPROTO_VALUE_REJECTED \ 147 __einfo_error ( EINFO_EPROTO_VALUE_REJECTED ) 148 #define EINFO_EPROTO_VALUE_REJECTED \ 149 __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" ) 154 unsigned int datasn );
180 const void *
data,
size_t len ) {
266 memset ( &target, 0,
sizeof ( target ) );
272 DBGC ( iscsi,
"iSCSI %p could not open socket: %s\n",
357 if ( iscsi->
itt == itt )
429 DBGC ( iscsi,
"iSCSI %p could not buffer SCSI response: %s\n",
441 rsp.overrun = residual_count;
443 rsp.overrun = -(residual_count);
529 unsigned int datasn ) {
532 unsigned long remaining;
547 if (
len == remaining )
556 DBGC ( iscsi,
"iSCSI %p start data out DataSN %#x len %#lx\n",
622 DBGC2 ( iscsi,
"iSCSI %p received NOP-In\n", iscsi );
635 DBGC ( iscsi,
"iSCSI %p received unsupported NOP-In with TTT %08x\n",
694 unsigned int used = 0;
695 const char *auth_method;
699 auth_method =
"None";
702 auth_method =
"CHAP,None";
705 auth_method =
"CHAP";
709 "SessionType=Normal%c" 724 buf, sizeof ( buf ) );
726 "CHAP_N=%s%cCHAP_R=0x%s%c",
734 buf, sizeof ( buf ) );
736 "CHAP_I=%d%cCHAP_C=0x%s%c",
742 "HeaderDigest=None%c" 747 "MaxRecvDataSegmentLength=%d%c" 748 "MaxBurstLength=%d%c" 749 "FirstBurstLength=%d%c" 750 "DefaultTime2Wait=0%c" 751 "DefaultTime2Retain=0%c" 752 "MaxOutstandingR2T=1%c" 753 "DataPDUInOrder=Yes%c" 754 "DataSequenceInOrder=Yes%c" 755 "ErrorRecoveryLevel=0%c",
777 DBGC ( iscsi,
"iSCSI %p entering security negotiation\n",
781 DBGC ( iscsi,
"iSCSI %p entering operational negotiation\n",
860 if ( *(encoded++) ==
'0' ) {
861 switch (
tolower ( *(encoded++) ) ) {
863 return base16_decode ( encoded,
raw,
len );
880 const char *
value ) {
883 DBGC ( iscsi,
"iSCSI %p will redirect to %s\n", iscsi,
value );
910 const char *
value ) {
914 DBGC ( iscsi,
"iSCSI %p initiating CHAP authentication\n",
931 const char *
value ) {
932 unsigned long max_burst_len;
938 DBGC ( iscsi,
"iSCSI %p invalid MaxBurstLength \"%s\"\n",
942 if ( max_burst_len < iscsi->max_burst_len )
956 const char *
value ) {
963 DBGC ( iscsi,
"iSCSI %p got invalid CHAP algorithm \"%s\"\n",
979 const char *
value ) {
980 unsigned int identifier;
986 if ( *endp !=
'\0' ) {
987 DBGC ( iscsi,
"iSCSI %p saw invalid CHAP identifier \"%s\"\n",
995 DBGC ( iscsi,
"iSCSI %p could not initialise CHAP: %s\n",
1020 const char *
value ) {
1038 DBGC ( iscsi,
"iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1045 DBGC ( iscsi,
"iSCSI %p sending CHAP response\n", iscsi );
1075 const char *
value ) {
1087 DBGC ( iscsi,
"iSCSI %p target username \"%s\" incorrect " 1088 "(wanted \"%s\")\n",
1104 const char *
value ) {
1112 DBGC ( iscsi,
"iSCSI %p could not initialise CHAP: %s\n",
1137 DBGC ( iscsi,
"iSCSI %p invalid CHAP response \"%s\": %s\n",
1144 DBGC ( iscsi,
"iSCSI %p invalid CHAP response length\n",
1147 goto err_response_len;
1150 DBGC ( iscsi,
"iSCSI %p incorrect CHAP response \"%s\"\n",
1206 const char *
string ) {
1208 const char *separator;
1214 separator =
strchr (
string,
'=' );
1215 if ( ! separator ) {
1216 DBGC ( iscsi,
"iSCSI %p malformed string %s\n",
1220 key_len = ( separator -
string );
1221 value = ( separator + 1 );
1227 DBGC ( iscsi,
"iSCSI %p rejection: %s\n", iscsi,
string );
1233 if (
strncmp (
string,
type->key, key_len ) != 0 )
1235 DBGC ( iscsi,
"iSCSI %p handling %s\n", iscsi,
string );
1236 if ( (
rc =
type->handle ( iscsi,
value ) ) != 0 ) {
1237 DBGC ( iscsi,
"iSCSI %p could not handle %s: %s\n",
1243 DBGC ( iscsi,
"iSCSI %p ignoring %s\n", iscsi,
string );
1256 const char *strings,
size_t len ) {
1264 string_len = (
strnlen ( strings,
len ) + 1 );
1265 if ( string_len >
len )
1269 strings += string_len;
1283 unsigned int status_detail ) {
1284 switch ( status_class ) {
1286 switch ( status_detail ) {
1298 switch ( status_detail ) {
1322 size_t remaining ) {
1329 DBGC ( iscsi,
"iSCSI %p could not buffer login response: %s\n",
1344 DBGC ( iscsi,
"iSCSI %p redirecting to new server\n", iscsi );
1347 DBGC ( iscsi,
"iSCSI %p could not redirect: %s\n ",
1356 DBGC ( iscsi,
"iSCSI login failure: class %02x detail %02x\n",
1377 DBGC ( iscsi,
"iSCSI %p got invalid response flags " 1378 "%02x\n", iscsi, response->
flags );
1395 DBGC ( iscsi,
"iSCSI %p nefarious target tried to bypass " 1396 "authentication\n", iscsi );
1401 DBGC ( iscsi,
"iSCSI %p entering full feature phase\n", iscsi );
1471 sizeof ( iscsi->
tx_bhs ) );
1546 tx_len =
sizeof ( iscsi->
tx_bhs );
1578 if ( (
rc =
tx ( iscsi ) ) != 0 ) {
1579 DBGC ( iscsi,
"iSCSI %p could not transmit: %s\n",
1617 DBGC2 ( iscsi,
"iSCSI %p received PDU opcode %#x len %#x\n",
1655 size_t len,
size_t remaining ) {
1677 DBGC ( iscsi,
"iSCSI %p unknown opcode %02x\n", iscsi,
1703 size_t len,
size_t remaining );
1738 if ( frag_len >
iob_len ( iobuf ) )
1741 if ( (
rc =
rx ( iscsi, iobuf->
data, frag_len,
1742 remaining ) ) != 0 ) {
1743 DBGC ( iscsi,
"iSCSI %p could not process received " 1866 DBGC ( iscsi,
"iSCSI %p cannot handle concurrent commands\n",
1896 unsigned int max_count;
1901 if ( max_count < capacity->max_count )
1914 return &iscsi->
desc;
1977 .
name =
"initiator-iqn",
1978 .description =
"iSCSI initiator name",
1980 .type = &setting_type_string,
1986 .
name =
"reverse-username",
1987 .description =
"Reverse user name",
1989 .type = &setting_type_string,
1995 .
name =
"reverse-password",
1996 .description =
"Reverse password",
1998 .type = &setting_type_string,
2009 const char *root_path ) {
2018 rp_copy =
strdup ( root_path );
2030 for ( ; ( ( *rp !=
':' ) || skip ) ; rp++ ) {
2032 DBGC ( iscsi,
"iSCSI %p root path \"%s\" " 2033 "too short\n", iscsi, root_path );
2036 }
else if ( *rp ==
'[' ) {
2038 }
else if ( *rp ==
']' ) {
2049 goto err_servername;
2055 DBGC ( iscsi,
"iSCSI %p invalid LUN \"%s\"\n",
2056 iscsi, rp_comp[
RP_LUN] );
2062 goto err_targetname;
2110 DBGC ( iscsi,
"iSCSI %p could not allocate initiator " 2120 DBGC ( iscsi,
"iSCSI %p has no suitable initiator IQN\n",
2127 DBGC ( iscsi,
"iSCSI %p could not allocate initiator IQN\n",
2155 DBGC ( iscsi,
"iSCSI %p invalid credentials: initiator " 2156 "%sname,%spw, target %sname,%spw\n", iscsi,
2181 goto err_sanity_uri;
2185 iscsi =
zalloc (
sizeof ( *iscsi ) );
2200 goto err_parse_root_path;
2203 goto err_fetch_settings;
2206 goto err_check_auth;
2210 DBGC ( iscsi,
"iSCSI %p does not yet support discovery\n",
2213 goto err_sanity_address;
2216 DBGC ( iscsi,
"iSCSI %p no target address supplied in %s\n",
2219 goto err_sanity_iqn;
2222 DBGC ( iscsi,
"iSCSI %p target %s %s\n",
2227 goto err_open_connection;
2231 &iscsi->
lun ) ) != 0 ) {
2232 DBGC ( iscsi,
"iSCSI %p could not create SCSI device: %s\n",
2242 err_open_connection:
2247 err_parse_root_path:
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
#define EINVAL_BAD_CREDENTIAL_MIX
#define iob_pull(iobuf, len)
#define EINVAL
Invalid argument.
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
An object interface operation.
iscsi_tx_state
State of an iSCSI TX engine.
#define ECONNRESET
Connection reset.
iSCSI data-in basic header segment
struct arbelprm_rc_send_wqe rc
iSCSI NOP-In basic header segment
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
void intf_close(struct interface *intf, int rc)
Close an object interface.
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
struct iscsi_bhs_login_request login_request
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
static int iscsi_rx_bhs(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining __unused)
Receive basic header segment of an iSCSI PDU.
#define iob_put(iobuf, len)
struct iscsi_bhs_scsi_command scsi_command
size_t data_out_len
Data-out buffer length.
#define SETTING_SANBOOT_EXTRA
SAN boot additional settings.
#define DHCP_EB_FEATURE_ISCSI
iSCSI protocol
unsigned int max_count
Maximum number of blocks per single transfer.
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
#define ENOTSUP_DISCOVERY
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
uint32_t expcmdsn
Expected command sequence number.
char * initiator_username
Initiator username (if any)
uint8_t * response
CHAP response.
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
struct iscsi_bhs_common common
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
uint32_t ttt
Target transfer tag.
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
#define ISCSI_LOGIN_NSG_MASK
#define FEATURE_PROTOCOL
Network protocols.
union iscsi_segment_lengths lengths
Segment lengths.
#define ref_init(refcnt, free)
Initialise a reference counter.
Receiving the data segment.
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
#define ISCSI_DATA_FLAG_UNDERFLOW
Data underflow occurred.
struct interface socket
Transport-layer socket.
uint32_t type
Operating system type.
#define EPROTO_INVALID_CHAP_ALGORITHM
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
uint32_t offset
Buffer offset.
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
const struct setting initiator_iqn_setting __setting(SETTING_SANBOOT_EXTRA, initiator-iqn)
iSCSI initiator IQN setting
#define EPROTO_INVALID_CHAP_RESPONSE
iSCSI login request basic header segment
size_t data_in_len
Data-in buffer length.
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
struct iscsi_bhs_data_out data_out
struct iscsi_bhs_common_response common_response
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
static int iscsi_rx_scsi_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI SCSI response PDU.
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
#define ISCSI_OPCODE_MASK
Opcode mask.
#define ISCSI_TAG_RESERVED
iSCSI reserved tag value
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
FEATURE(FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1)
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
static int iscsi_rx_data(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI PDU.
size_t rx_len
Length of the current RX state.
static struct iscsi_string_type iscsi_string_types[]
iSCSI text strings that we want to handle
#define va_copy(dest, src)
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
iscsi_rx_state
State of an iSCSI RX engine.
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
uint8_t response
Response code.
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
union scsi_cdb cdb
CDB for this command.
uint32_t statsn
Status sequence number.
static int iscsi_rx_login_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI login response PDU.
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Uniform Resource Identifiers.
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
#define ISCSI_STATUS_INITIATOR_ERROR
void * rx_buffer
Buffer for received data (not always used)
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
void process_del(struct process *process)
Remove process from process list.
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
#define EINVAL_NO_TARGET_IQN
Access to external ("user") memory.
size_t xfer_window(struct interface *intf)
Check flow control window.
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
uint8_t status
SCSI status code.
iSCSI SCSI command basic header segment
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
#define ECANCELED
Operation canceled.
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
static int iscsi_rx_r2t(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI R2T PDU.
uint32_t statsn
Status sequence number.
Data transfer interfaces.
unsigned int target_port
Target port.
struct scsi_lun lun
Logical Unit Number.
char * initiator_password
Initiator password (if any)
#define EACCES_INCORRECT_TARGET_USERNAME
uint8_t status_detail
Status detail.
iscsi_root_path_component
iSCSI root path components (as per RFC4173)
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
static struct interface_operation iscsi_socket_operations[]
iSCSI socket interface operations
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
#define ENOMEM
Not enough space.
size_t rx_offset
Byte offset within the current RX state.
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
struct interface control
SCSI command-issuing interface.
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
An iSCSI text string that we want to handle.
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
#define container_of(ptr, type, field)
Get containing structure.
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
uint32_t itt
Initiator task tag.
uint32_t datasn
Data sequence number.
A SCSI response information unit.
static int iscsi_open(struct interface *parent, struct uri *uri)
Open iSCSI URI.
Receiving the data segment padding.
pseudo_bit_t value[0x00020]
uint8_t status_class
Status class.
#define __unused
Declare a variable or data structure as unused.
userptr_t data_out
Data-out buffer (may be NULL)
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
int status
Session status.
static int tolower(int character)
Convert character to lower case.
const char * scheme
URI protocol name.
Transport-network layer interface.
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
uint32_t ttt
Target Transfer Tag.
struct acpi_descriptor desc
ACPI descriptor.
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
#define EACCES_INCORRECT_TARGET_PASSWORD
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
#define ISCSI_FIRST_BURST_LEN
Default iSCSI first burst length.
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
iSCSI basic header segment common request fields
#define EPROTO
Protocol error.
#define EPROTO_INVALID_KEY_VALUE_PAIR
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
void process_add(struct process *process)
Add process to process list.
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
uint16_t st_port
TCP/IP port.
Generalized socket address structure.
Receiving the additional header segment.
An object interface descriptor.
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
#define ISCSI_PORT
Default iSCSI port.
uint32_t offset
Buffer offset.
iSCSI basic header segment common fields
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
struct scsi_lun lun
SCSI LUN (for boot firmware table)
void * zalloc(size_t size)
Allocate cleared memory.
struct process process
TX process.
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
#define EINVAL_NO_INITIATOR_IQN
union iscsi_segment_lengths lengths
Segment lengths.
enum iscsi_rx_state rx_state
State of the RX engine.
char * strchr(const char *src, int character)
Find character within a string.
uint32_t offset
Buffer offset.
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
char * strdup(const char *src)
Duplicate string.
iSCSI request to transfer basic header segment
char * target_address
Target address.
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
iSCSI login response basic header segment
#define EOPNOTSUPP
Operation not supported on socket.
#define ISCSI_OPCODE_R2T
R2T opcode.
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
struct chap_response chap
CHAP response (used for both initiator and target auth)
#define ISCSI_LOGIN_CSG_MASK
static int iscsi_socket_deliver(struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
#define ENODEV
No such device.
#define EIO_TARGET_UNAVAILABLE
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
size_t strlen(const char *src)
Get length of string.
#define EINVAL_ROOT_PATH_TOO_SHORT
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Data transfer interface opening.
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
size_t response_len
Length of CHAP response.
size_t strnlen(const char *src, size_t max)
Get length of string.
int(* handle)(struct iscsi_session *iscsi, const char *value)
Handle iSCSI string value.
Sending the additional header segment.
static int iscsi_rx_nop_in(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI NOP-In.
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
struct interface data
SCSI command interface.
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
void * malloc(size_t size)
Allocate memory.
#define DHCP_EB_REVERSE_PASSWORD
Reverse password.
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
struct ib_cm_common common
static struct dynamic_item password
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
uint32_t len
Desired data transfer length.
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
size_t max_burst_len
Maximum burst length.
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
union iscsi_segment_lengths lengths
Segment lengths.
static int iscsi_status_to_rc(unsigned int status_class, unsigned int status_detail)
Convert iSCSI response status to return status code.
const char * key
String key.
uint32_t transfer_offset
Transfer offset.
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
#define ISCSI_COMMAND_ATTR_SIMPLE
#define ISCSI_STATUS_REDIRECT
A SCSI command information unit.
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
An ACPI descriptor (used to construct ACPI tables)
iSCSI data-out basic header segment
char * target_iqn
Target IQN.
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
uint32_t expstatsn
Expected status sequence number.
uint32_t transfer_len
Transfer length.
iSCSI boot firmware table
struct iscsi_nop_in nop_in
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
struct iscsi_bhs_login_response login_response
#define ISCSI_MAX_RECV_DATA_SEG_LEN
Default iSCSI maximum receive data segment length.
const char * opaque
Opaque part.
struct uri_opener iscsi_uri_opener __uri_opener
iSCSI URI opener
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
static int iscsi_rx_discard(struct iscsi_session *iscsi __unused, const void *data __unused, size_t len __unused, size_t remaining __unused)
Discard portion of an iSCSI PDU.
__builtin_va_list va_list
int strcmp(const char *first, const char *second)
Compare strings.
static int iscsi_rx_data_in(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI data-in PDU.
uint32_t cmdsn
Command sequence number.
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
uint32_t itt
Initiator Task Tag.
void * data
Start of data.
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
#define ISCSI_TAG_MAGIC
iSCSI tag magic marker
#define EIO
Input/output error.
userptr_t data_in
Data-in buffer (may be NULL)
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
u8 request[0]
List of IEs requested.
static void iscsi_tx_step(struct iscsi_session *iscsi)
Transmit iSCSI PDU.
uint32_t ttt
Target Transfer Tag.
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
#define ENOTSUP_INITIATOR_STATUS
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
#define DHCP_EB_REVERSE_USERNAME
Reverse username.
uint32_t end
Ending offset.
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
uint8_t data[48]
Additional event data.
#define ENOTSUP_TARGET_STATUS
uint32_t residual_count
Residual count.
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
static struct dynamic_item username
#define EPERM_INITIATOR_AUTHORISATION
iSCSI SCSI response basic header segment
#define EIO_TARGET_NO_RESOURCES
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
A Uniform Resource Identifier.
#define EPROTO_INVALID_CHAP_IDENTIFIER
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
uint16_t offset
Offset to command line.
char * initiator_iqn
Initiator IQN.
Sending the data segment.
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
struct mschapv2_challenge peer
Peer challenge.
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
static struct interface_operation iscsi_control_op[]
iSCSI SCSI command-issuing interface operations
struct iscsi_bhs_scsi_response scsi_response
#define SETTING_AUTH_EXTRA
Authentication additional settings.
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
#define ISCSI_ISID_IANA
ISID IANA format marker.
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
char * target_password
Target password (if any)
#define EPERM_INITIATOR_AUTHENTICATION
#define EINVAL_MAXBURSTLENGTH
struct scsi_cmd * command
Current SCSI command, if any.
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
char * target_username
Target username (if any)
Sending the basic header segment.
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Receiving the basic header segment.
uint32_t ttt
Target Transfer Tag.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
#define NULL
NULL pointer (VOID *)
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
struct iscsi_bhs_data_in data_in
struct bofm_section_header done
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
enum iscsi_tx_state tx_state
State of the TX engine.
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
struct digest_algorithm md5_algorithm
MD5 algorithm.
#define ref_put(refcnt)
Drop reference to object.
size_t blksize
Block size.
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
#define EINVAL_NO_ROOT_PATH
struct refcnt refcnt
Reference counter.
void * memset(void *dest, int character, size_t len) __nonnull
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
#define ISCSI_STATUS_TARGET_ERROR
#define EPROTO_INVALID_LARGE_BINARY
#define EPROTO_VALUE_REJECTED
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.