iPXE
Data Structures | Macros | Enumerations | Functions | Variables
iscsi.c File Reference

iSCSI protocol More...

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/vsprintf.h>
#include <ipxe/socket.h>
#include <ipxe/iobuf.h>
#include <ipxe/uri.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/scsi.h>
#include <ipxe/process.h>
#include <ipxe/tcpip.h>
#include <ipxe/settings.h>
#include <ipxe/features.h>
#include <ipxe/base16.h>
#include <ipxe/base64.h>
#include <ipxe/ibft.h>
#include <ipxe/blockdev.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/iscsi.h>

Go to the source code of this file.

Data Structures

struct  iscsi_string_type
 An iSCSI text string that we want to handle. More...
 

Macros

#define EACCES_INCORRECT_TARGET_USERNAME   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )
 
#define EINFO_EACCES_INCORRECT_TARGET_USERNAME   __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )
 
#define EACCES_INCORRECT_TARGET_PASSWORD   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )
 
#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD   __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )
 
#define EINVAL_ROOT_PATH_TOO_SHORT   __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )
 
#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )
 
#define EINVAL_BAD_CREDENTIAL_MIX   __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )
 
#define EINFO_EINVAL_BAD_CREDENTIAL_MIX   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )
 
#define EINVAL_NO_ROOT_PATH   __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )
 
#define EINFO_EINVAL_NO_ROOT_PATH   __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )
 
#define EINVAL_NO_TARGET_IQN   __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )
 
#define EINFO_EINVAL_NO_TARGET_IQN   __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )
 
#define EINVAL_NO_INITIATOR_IQN   __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )
 
#define EINFO_EINVAL_NO_INITIATOR_IQN   __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )
 
#define EINVAL_MAXBURSTLENGTH   __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )
 
#define EINFO_EINVAL_MAXBURSTLENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )
 
#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )
 
#define EINFO_EIO_TARGET_UNAVAILABLE   __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )
 
#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )
 
#define EINFO_EIO_TARGET_NO_RESOURCES   __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )
 
#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )
 
#define EINFO_ENOTSUP_INITIATOR_STATUS   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )
 
#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )
 
#define EINFO_ENOTSUP_OPCODE   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )
 
#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )
 
#define EINFO_ENOTSUP_DISCOVERY   __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )
 
#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )
 
#define EINFO_ENOTSUP_TARGET_STATUS   __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )
 
#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )
 
#define EINFO_EPERM_INITIATOR_AUTHENTICATION   __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )
 
#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )
 
#define EINFO_EPERM_INITIATOR_AUTHORISATION   __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )
 
#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )
 
#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM   __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )
 
#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )
 
#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )
 
#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )
 
#define EINFO_EPROTO_INVALID_LARGE_BINARY   __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )
 
#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )
 
#define EINFO_EPROTO_INVALID_CHAP_RESPONSE   __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )
 
#define EPROTO_INVALID_KEY_VALUE_PAIR   __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )
 
#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR   __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )
 
#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )
 
#define EINFO_EPROTO_VALUE_REJECTED   __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )
 

Enumerations

enum  iscsi_root_path_component {
  RP_SERVERNAME = 0, RP_PROTOCOL, RP_PORT, RP_LUN,
  RP_TARGETNAME, NUM_RP_COMPONENTS
}
 iSCSI root path components (as per RFC4173) More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 FEATURE (FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1)
 
static void iscsi_start_tx (struct iscsi_session *iscsi)
 Start up a new TX PDU. More...
 
static void iscsi_start_login (struct iscsi_session *iscsi)
 Build iSCSI login request BHS. More...
 
static void iscsi_start_data_out (struct iscsi_session *iscsi, unsigned int datasn)
 Build iSCSI data-out BHS. More...
 
static void iscsi_rx_buffered_data_done (struct iscsi_session *iscsi)
 Finish receiving PDU data into buffer. More...
 
static int iscsi_rx_buffered_data (struct iscsi_session *iscsi, const void *data, size_t len)
 Receive PDU data into buffer. More...
 
static void iscsi_free (struct refcnt *refcnt)
 Free iSCSI session. More...
 
static void iscsi_close (struct iscsi_session *iscsi, int rc)
 Shut down iSCSI interface. More...
 
static void iscsi_new_itt (struct iscsi_session *iscsi)
 Assign new iSCSI initiator task tag. More...
 
static int iscsi_open_connection (struct iscsi_session *iscsi)
 Open iSCSI transport-layer connection. More...
 
static void iscsi_close_connection (struct iscsi_session *iscsi, int rc)
 Close iSCSI transport-layer connection. More...
 
static void iscsi_scsi_done (struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
 Mark iSCSI SCSI operation as complete. More...
 
static void iscsi_start_command (struct iscsi_session *iscsi)
 Build iSCSI SCSI command BHS. More...
 
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. More...
 
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. More...
 
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. More...
 
static void iscsi_data_out_done (struct iscsi_session *iscsi)
 Complete iSCSI data-out PDU transmission. More...
 
static int iscsi_tx_data_out (struct iscsi_session *iscsi)
 Send iSCSI data-out data segment. More...
 
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. More...
 
static int iscsi_build_login_request_strings (struct iscsi_session *iscsi, void *data, size_t len)
 Build iSCSI login request strings. More...
 
static void iscsi_login_request_done (struct iscsi_session *iscsi)
 Complete iSCSI login request PDU transmission. More...
 
static int iscsi_tx_login_request (struct iscsi_session *iscsi)
 Transmit data segment of an iSCSI login request PDU. More...
 
static int iscsi_large_binary_decode (const char *encoded, uint8_t *raw, size_t len)
 Decode large binary value. More...
 
static int iscsi_handle_targetaddress_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI TargetAddress text value. More...
 
static int iscsi_handle_authmethod_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI AuthMethod text value. More...
 
static int iscsi_handle_maxburstlength_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI MaxBurstLength text value. More...
 
static int iscsi_handle_chap_a_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_A text value. More...
 
static int iscsi_handle_chap_i_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_I text value. More...
 
static int iscsi_handle_chap_c_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_C text value. More...
 
static int iscsi_handle_chap_n_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_N text value. More...
 
static int iscsi_handle_chap_r_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_R text value. More...
 
static int iscsi_handle_string (struct iscsi_session *iscsi, const char *string)
 Handle iSCSI string. More...
 
static int iscsi_handle_strings (struct iscsi_session *iscsi, const char *strings, size_t len)
 Handle iSCSI strings. More...
 
static int iscsi_status_to_rc (unsigned int status_class, unsigned int status_detail)
 Convert iSCSI response status to return status code. More...
 
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. More...
 
static void iscsi_tx_pause (struct iscsi_session *iscsi)
 Pause TX engine. More...
 
static void iscsi_tx_resume (struct iscsi_session *iscsi)
 Resume TX engine. More...
 
static int iscsi_tx_nothing (struct iscsi_session *iscsi __unused)
 Transmit nothing. More...
 
static int iscsi_tx_bhs (struct iscsi_session *iscsi)
 Transmit basic header segment of an iSCSI PDU. More...
 
static int iscsi_tx_data (struct iscsi_session *iscsi)
 Transmit data segment of an iSCSI PDU. More...
 
static void iscsi_tx_done (struct iscsi_session *iscsi)
 Complete iSCSI PDU transmission. More...
 
static void iscsi_tx_step (struct iscsi_session *iscsi)
 Transmit iSCSI PDU. More...
 
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. More...
 
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. More...
 
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. More...
 
static int iscsi_socket_deliver (struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Receive new data. More...
 
static int iscsi_vredirect (struct iscsi_session *iscsi, int type, va_list args)
 Handle redirection event. More...
 
static size_t iscsi_scsi_window (struct iscsi_session *iscsi)
 Check iSCSI flow-control window. More...
 
static int iscsi_scsi_command (struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
 Issue iSCSI SCSI command. More...
 
static void iscsi_scsi_capacity (struct iscsi_session *iscsi, struct block_device_capacity *capacity)
 Update SCSI block device capacity. More...
 
static struct acpi_descriptoriscsi_describe (struct iscsi_session *iscsi)
 Get iSCSI ACPI descriptor. More...
 
static void iscsi_command_close (struct iscsi_session *iscsi, int rc)
 Close iSCSI command. More...
 
const struct setting initiator_iqn_setting __setting (SETTING_SANBOOT_EXTRA, initiator-iqn)
 iSCSI initiator IQN setting More...
 
const struct setting reverse_username_setting __setting (SETTING_AUTH_EXTRA, reverse-username)
 iSCSI reverse username setting More...
 
static int iscsi_parse_root_path (struct iscsi_session *iscsi, const char *root_path)
 Parse iSCSI root path. More...
 
static int iscsi_fetch_settings (struct iscsi_session *iscsi)
 Fetch iSCSI settings. More...
 
static int iscsi_check_auth (struct iscsi_session *iscsi)
 Check iSCSI authentication details. More...
 
static int iscsi_open (struct interface *parent, struct uri *uri)
 Open iSCSI URI. More...
 

Variables

static struct iscsi_string_type iscsi_string_types []
 iSCSI text strings that we want to handle More...
 
static struct process_descriptor iscsi_process_desc
 iSCSI TX process descriptor More...
 
static struct interface_operation iscsi_socket_operations []
 iSCSI socket interface operations More...
 
static struct interface_descriptor iscsi_socket_desc
 iSCSI socket interface descriptor More...
 
static struct interface_operation iscsi_control_op []
 iSCSI SCSI command-issuing interface operations More...
 
static struct interface_descriptor iscsi_control_desc
 iSCSI SCSI command-issuing interface descriptor More...
 
static struct interface_operation iscsi_data_op []
 iSCSI SCSI command interface operations More...
 
static struct interface_descriptor iscsi_data_desc
 iSCSI SCSI command interface descriptor More...
 
struct uri_opener iscsi_uri_opener __uri_opener
 iSCSI URI opener More...
 

Detailed Description

iSCSI protocol

Definition in file iscsi.c.

Macro Definition Documentation

◆ EACCES_INCORRECT_TARGET_USERNAME

#define EACCES_INCORRECT_TARGET_USERNAME   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

Definition at line 61 of file iscsi.c.

◆ EINFO_EACCES_INCORRECT_TARGET_USERNAME

#define EINFO_EACCES_INCORRECT_TARGET_USERNAME   __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )

Definition at line 63 of file iscsi.c.

◆ EACCES_INCORRECT_TARGET_PASSWORD

#define EACCES_INCORRECT_TARGET_PASSWORD   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Definition at line 65 of file iscsi.c.

◆ EINFO_EACCES_INCORRECT_TARGET_PASSWORD

#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD   __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )

Definition at line 67 of file iscsi.c.

◆ EINVAL_ROOT_PATH_TOO_SHORT

#define EINVAL_ROOT_PATH_TOO_SHORT   __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )

Definition at line 69 of file iscsi.c.

◆ EINFO_EINVAL_ROOT_PATH_TOO_SHORT

#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )

Definition at line 71 of file iscsi.c.

◆ EINVAL_BAD_CREDENTIAL_MIX

#define EINVAL_BAD_CREDENTIAL_MIX   __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

Definition at line 73 of file iscsi.c.

◆ EINFO_EINVAL_BAD_CREDENTIAL_MIX

#define EINFO_EINVAL_BAD_CREDENTIAL_MIX   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )

Definition at line 75 of file iscsi.c.

◆ EINVAL_NO_ROOT_PATH

#define EINVAL_NO_ROOT_PATH   __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

Definition at line 77 of file iscsi.c.

◆ EINFO_EINVAL_NO_ROOT_PATH

#define EINFO_EINVAL_NO_ROOT_PATH   __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )

Definition at line 79 of file iscsi.c.

◆ EINVAL_NO_TARGET_IQN

#define EINVAL_NO_TARGET_IQN   __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

Definition at line 81 of file iscsi.c.

◆ EINFO_EINVAL_NO_TARGET_IQN

#define EINFO_EINVAL_NO_TARGET_IQN   __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )

Definition at line 83 of file iscsi.c.

◆ EINVAL_NO_INITIATOR_IQN

#define EINVAL_NO_INITIATOR_IQN   __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

Definition at line 85 of file iscsi.c.

◆ EINFO_EINVAL_NO_INITIATOR_IQN

#define EINFO_EINVAL_NO_INITIATOR_IQN   __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )

Definition at line 87 of file iscsi.c.

◆ EINVAL_MAXBURSTLENGTH

#define EINVAL_MAXBURSTLENGTH   __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Definition at line 89 of file iscsi.c.

◆ EINFO_EINVAL_MAXBURSTLENGTH

#define EINFO_EINVAL_MAXBURSTLENGTH   __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )

Definition at line 91 of file iscsi.c.

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Definition at line 93 of file iscsi.c.

◆ EINFO_EIO_TARGET_UNAVAILABLE

#define EINFO_EIO_TARGET_UNAVAILABLE   __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )

Definition at line 95 of file iscsi.c.

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Definition at line 97 of file iscsi.c.

◆ EINFO_EIO_TARGET_NO_RESOURCES

#define EINFO_EIO_TARGET_NO_RESOURCES   __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )

Definition at line 99 of file iscsi.c.

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 101 of file iscsi.c.

◆ EINFO_ENOTSUP_INITIATOR_STATUS

#define EINFO_ENOTSUP_INITIATOR_STATUS   __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )

Definition at line 103 of file iscsi.c.

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 105 of file iscsi.c.

◆ EINFO_ENOTSUP_OPCODE

#define EINFO_ENOTSUP_OPCODE   __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )

Definition at line 107 of file iscsi.c.

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 109 of file iscsi.c.

◆ EINFO_ENOTSUP_DISCOVERY

#define EINFO_ENOTSUP_DISCOVERY   __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )

Definition at line 111 of file iscsi.c.

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 113 of file iscsi.c.

◆ EINFO_ENOTSUP_TARGET_STATUS

#define EINFO_ENOTSUP_TARGET_STATUS   __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )

Definition at line 115 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 117 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

#define EINFO_EPERM_INITIATOR_AUTHENTICATION   __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )

Definition at line 119 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 121 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

#define EINFO_EPERM_INITIATOR_AUTHORISATION   __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )

Definition at line 123 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Definition at line 125 of file iscsi.c.

◆ EINFO_EPROTO_INVALID_CHAP_ALGORITHM

#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM   __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )

Definition at line 127 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Definition at line 129 of file iscsi.c.

◆ EINFO_EPROTO_INVALID_CHAP_IDENTIFIER

#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )

Definition at line 131 of file iscsi.c.

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Definition at line 133 of file iscsi.c.

◆ EINFO_EPROTO_INVALID_LARGE_BINARY

#define EINFO_EPROTO_INVALID_LARGE_BINARY   __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )

Definition at line 135 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Definition at line 137 of file iscsi.c.

◆ EINFO_EPROTO_INVALID_CHAP_RESPONSE

#define EINFO_EPROTO_INVALID_CHAP_RESPONSE   __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )

Definition at line 139 of file iscsi.c.

◆ EPROTO_INVALID_KEY_VALUE_PAIR

#define EPROTO_INVALID_KEY_VALUE_PAIR   __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )

Definition at line 141 of file iscsi.c.

◆ EINFO_EPROTO_INVALID_KEY_VALUE_PAIR

#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR   __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )

Definition at line 143 of file iscsi.c.

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 145 of file iscsi.c.

◆ EINFO_EPROTO_VALUE_REJECTED

#define EINFO_EPROTO_VALUE_REJECTED   __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )

Definition at line 147 of file iscsi.c.

Enumeration Type Documentation

◆ iscsi_root_path_component

iSCSI root path components (as per RFC4173)

Enumerator
RP_SERVERNAME 
RP_PROTOCOL 
RP_PORT 
RP_LUN 
RP_TARGETNAME 
NUM_RP_COMPONENTS 

Definition at line 1964 of file iscsi.c.

1964  {
1965  RP_SERVERNAME = 0,
1966  RP_PROTOCOL,
1967  RP_PORT,
1968  RP_LUN,
1969  RP_TARGETNAME,
1971 };
Definition: iscsi.c:1968

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL  ,
"iSCSI"  ,
DHCP_EB_FEATURE_ISCSI  ,
 
)

◆ iscsi_start_tx()

static void iscsi_start_tx ( struct iscsi_session iscsi)
static

Start up a new TX PDU.

Parameters
iscsiiSCSI session

This initiates the process of sending a new PDU. Only one PDU may be in transit at any one time.

Definition at line 1438 of file iscsi.c.

1438  {
1439 
1440  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1441 
1442  /* Initialise TX BHS */
1443  memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1444 
1445  /* Flag TX engine to start transmitting */
1446  iscsi->tx_state = ISCSI_TX_BHS;
1447 
1448  /* Start transmission process */
1449  iscsi_tx_resume ( iscsi );
1450 }
Nothing to send.
Definition: iscsi.h:522
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1426
Sending the basic header segment.
Definition: iscsi.h:524
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), ISCSI_TX_BHS, ISCSI_TX_IDLE, iscsi_tx_resume(), memset(), iscsi_session::tx_bhs, and iscsi_session::tx_state.

Referenced by iscsi_start_command(), iscsi_start_data_out(), and iscsi_start_login().

◆ iscsi_start_login()

static void iscsi_start_login ( struct iscsi_session iscsi)
static

Build iSCSI login request BHS.

Parameters
iscsiiSCSI session

Definition at line 770 of file iscsi.c.

770  {
772  int len;
773 
774  switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
776  DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
777  iscsi );
778  break;
780  DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
781  iscsi );
782  break;
783  default:
784  assert ( 0 );
785  }
786 
787  /* Construct BHS and initiate transmission */
788  iscsi_start_tx ( iscsi );
789  request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
791  request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
793  /* version_max and version_min left as zero */
795  ISCSI_SET_LENGTHS ( request->lengths, 0, len );
796  request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
798  request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
799  /* tsih left as zero */
800  request->itt = htonl ( iscsi->itt );
801  /* cid left as zero */
802  request->cmdsn = htonl ( iscsi->cmdsn );
803  request->expstatsn = htonl ( iscsi->statsn + 1 );
804 }
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:508
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:184
iSCSI login request basic header segment
Definition: iscsi.h:141
#define DBGC(...)
Definition: compiler.h:505
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:173
#define htonl(value)
Definition: byteswap.h:133
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition: iscsi.h:176
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:684
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
Definition: iscsi.h:201
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
Definition: iscsi.h:183
#define ISCSI_LOGIN_CSG_MASK
Definition: iscsi.h:182
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition: iscsi.h:597
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
Definition: iscsi.h:99
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:629
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition: iscsi.h:69
#define ISCSI_ISID_IANA
ISID IANA format marker.
Definition: iscsi.h:194
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition: iscsi.c:691
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1438

References assert(), iscsi_session::cmdsn, DBGC, htonl, htons, IANA_EN_FEN_SYSTEMS, iscsi_build_login_request_strings(), ISCSI_FLAG_IMMEDIATE, ISCSI_ISID_IANA, ISCSI_LOGIN_CSG_MASK, ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION, ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION, ISCSI_LOGIN_FLAG_TRANSITION, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_SET_LENGTHS, iscsi_start_tx(), ISCSI_STATUS_PHASE_MASK, iscsi_session::isid_iana_qual, iscsi_session::itt, len, iscsi_bhs::login_request, NULL, request, iscsi_session::statsn, iscsi_session::status, and iscsi_session::tx_bhs.

Referenced by iscsi_open_connection(), and iscsi_rx_login_response().

◆ iscsi_start_data_out()

static void iscsi_start_data_out ( struct iscsi_session iscsi,
unsigned int  datasn 
)
static

Build iSCSI data-out BHS.

Parameters
iscsiiSCSI session
datasnData sequence number within the transfer

Definition at line 527 of file iscsi.c.

528  {
529  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
530  unsigned long offset;
531  unsigned long remaining;
532  unsigned long len;
533 
534  /* We always send 512-byte Data-Out PDUs; this removes the
535  * need to worry about the target's MaxRecvDataSegmentLength.
536  */
537  offset = datasn * 512;
538  remaining = iscsi->transfer_len - offset;
539  len = remaining;
540  if ( len > 512 )
541  len = 512;
542 
543  /* Construct BHS and initiate transmission */
544  iscsi_start_tx ( iscsi );
545  data_out->opcode = ISCSI_OPCODE_DATA_OUT;
546  if ( len == remaining )
547  data_out->flags = ( ISCSI_FLAG_FINAL );
548  ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
549  data_out->lun = iscsi->command->lun;
550  data_out->itt = htonl ( iscsi->itt );
551  data_out->ttt = htonl ( iscsi->ttt );
552  data_out->expstatsn = htonl ( iscsi->statsn + 1 );
553  data_out->datasn = htonl ( datasn );
554  data_out->offset = htonl ( iscsi->transfer_offset + offset );
555  DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
556  iscsi, datasn, len );
557 }
uint32_t ttt
Target transfer tag.
Definition: iscsi.h:609
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:412
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:513
#define DBGC(...)
Definition: compiler.h:505
#define htonl(value)
Definition: byteswap.h:133
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
struct scsi_lun lun
Logical Unit Number.
Definition: iscsi.h:414
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
uint32_t datasn
Data sequence number.
Definition: iscsi.h:426
ring len
Length.
Definition: dwmac.h:231
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:102
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:418
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
struct scsi_lun lun
LUN.
Definition: scsi.h:250
uint32_t offset
Buffer offset.
Definition: iscsi.h:428
uint8_t flags
Flags.
Definition: iscsi.h:408
uint32_t transfer_offset
Transfer offset.
Definition: iscsi.h:615
iSCSI data-out basic header segment
Definition: iscsi.h:404
uint32_t expstatsn
Expected status sequence number.
Definition: iscsi.h:422
uint32_t transfer_len
Transfer length.
Definition: iscsi.h:621
uint32_t itt
Initiator Task Tag.
Definition: iscsi.h:416
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition: iscsi.h:69
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:434
uint8_t opcode
Opcode.
Definition: iscsi.h:406
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1438

References iscsi_session::command, iscsi_bhs::data_out, iscsi_bhs_data_out::datasn, DBGC, iscsi_bhs_data_out::expstatsn, iscsi_bhs_data_out::flags, htonl, ISCSI_FLAG_FINAL, ISCSI_OPCODE_DATA_OUT, ISCSI_SET_LENGTHS, iscsi_start_tx(), iscsi_bhs_data_out::itt, iscsi_session::itt, len, iscsi_bhs_data_out::lengths, scsi_cmd::lun, iscsi_bhs_data_out::lun, offset, iscsi_bhs_data_out::offset, iscsi_bhs_data_out::opcode, iscsi_session::statsn, iscsi_session::transfer_len, iscsi_session::transfer_offset, iscsi_bhs_data_out::ttt, iscsi_session::ttt, and iscsi_session::tx_bhs.

Referenced by iscsi_data_out_done(), and iscsi_rx_r2t().

◆ iscsi_rx_buffered_data_done()

static void iscsi_rx_buffered_data_done ( struct iscsi_session iscsi)
static

Finish receiving PDU data into buffer.

Parameters
iscsiiSCSI session

Definition at line 160 of file iscsi.c.

160  {
161  free ( iscsi->rx_buffer );
162  iscsi->rx_buffer = NULL;
163 }
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:655
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References free, NULL, and iscsi_session::rx_buffer.

Referenced by iscsi_close_connection(), iscsi_free(), iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_rx_buffered_data()

static int iscsi_rx_buffered_data ( struct iscsi_session iscsi,
const void *  data,
size_t  len 
)
static

Receive PDU data into buffer.

Parameters
iscsiiSCSI session
dataData to receive
lenLength of data
Return values
rcReturn status code

This can be used when the RX PDU type handler wishes to buffer up all received data and process the PDU as a single unit. The caller is repsonsible for calling iscsi_rx_buffered_data_done() after processing the data.

Definition at line 178 of file iscsi.c.

179  {
180 
181  /* Allocate buffer on first call */
182  if ( ! iscsi->rx_buffer ) {
183  iscsi->rx_buffer = malloc ( iscsi->rx_len );
184  if ( ! iscsi->rx_buffer )
185  return -ENOMEM;
186  }
187 
188  /* Copy data to buffer */
189  assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
190  memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
191 
192  return 0;
193 }
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:653
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:655
#define ENOMEM
Not enough space.
Definition: errno.h:534
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
uint8_t data[48]
Additional event data.
Definition: ena.h:22

References assert(), data, ENOMEM, len, malloc(), memcpy(), iscsi_session::rx_buffer, iscsi_session::rx_len, and iscsi_session::rx_offset.

Referenced by iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_free()

static void iscsi_free ( struct refcnt refcnt)
static

Free iSCSI session.

Parameters
refcntReference counter

Definition at line 200 of file iscsi.c.

200  {
201  struct iscsi_session *iscsi =
203 
204  free ( iscsi->initiator_iqn );
205  free ( iscsi->target_address );
206  free ( iscsi->target_iqn );
207  free ( iscsi->initiator_username );
208  free ( iscsi->initiator_password );
209  free ( iscsi->target_username );
210  free ( iscsi->target_password );
211  chap_finish ( &iscsi->chap );
212  iscsi_rx_buffered_data_done ( iscsi );
213  free ( iscsi->command );
214  free ( iscsi );
215 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:572
An iSCSI session.
Definition: iscsi.h:544
A reference counter.
Definition: refcnt.h:26
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:160
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
char * target_address
Target address.
Definition: iscsi.h:558
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
char * target_iqn
Target IQN.
Definition: iscsi.h:562
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:556
char * target_password
Target password (if any)
Definition: iscsi.h:578
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
char * target_username
Target username (if any)
Definition: iscsi.h:576

References iscsi_session::chap, chap_finish(), iscsi_session::command, container_of, free, iscsi_session::initiator_iqn, iscsi_session::initiator_password, iscsi_session::initiator_username, iscsi_rx_buffered_data_done(), iscsi_session::target_address, iscsi_session::target_iqn, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by iscsi_open().

◆ iscsi_close()

static void iscsi_close ( struct iscsi_session iscsi,
int  rc 
)
static

Shut down iSCSI interface.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 223 of file iscsi.c.

223  {
224 
225  /* A TCP graceful close is still an error from our point of view */
226  if ( rc == 0 )
227  rc = -ECONNRESET;
228 
229  DBGC ( iscsi, "iSCSI %p closed: %s\n", iscsi, strerror ( rc ) );
230 
231  /* Stop transmission process */
232  process_del ( &iscsi->process );
233 
234  /* Shut down interfaces */
235  intfs_shutdown ( rc, &iscsi->socket, &iscsi->control, &iscsi->data,
236  NULL );
237 }
#define ECONNRESET
Connection reset.
Definition: errno.h:363
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
#define DBGC(...)
Definition: compiler.h:505
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition: interface.c:326
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:549
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct process process
TX process.
Definition: iscsi.h:644
struct interface data
SCSI command interface.
Definition: iscsi.h:551
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References iscsi_session::control, iscsi_session::data, DBGC, ECONNRESET, intfs_shutdown(), NULL, iscsi_session::process, process_del(), rc, iscsi_session::socket, and strerror().

Referenced by iscsi_command_close(), iscsi_open(), iscsi_socket_deliver(), iscsi_tx_step(), and iscsi_vredirect().

◆ iscsi_new_itt()

static void iscsi_new_itt ( struct iscsi_session iscsi)
static

Assign new iSCSI initiator task tag.

Parameters
iscsiiSCSI session

Definition at line 244 of file iscsi.c.

244  {
245  static uint16_t itt_idx;
246 
247  iscsi->itt = ( ISCSI_TAG_MAGIC | (++itt_idx) );
248 }
unsigned short uint16_t
Definition: stdint.h:11
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
#define ISCSI_TAG_MAGIC
iSCSI tag magic marker
Definition: iscsi.h:105

References ISCSI_TAG_MAGIC, and iscsi_session::itt.

Referenced by iscsi_open_connection(), and iscsi_scsi_command().

◆ iscsi_open_connection()

static int iscsi_open_connection ( struct iscsi_session iscsi)
static

Open iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 256 of file iscsi.c.

256  {
257  struct sockaddr_tcpip target;
258  int rc;
259 
260  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
261  assert ( iscsi->rx_state == ISCSI_RX_BHS );
262  assert ( iscsi->rx_offset == 0 );
263 
264  /* Open socket */
265  memset ( &target, 0, sizeof ( target ) );
266  target.st_port = htons ( iscsi->target_port );
267  if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
268  ( struct sockaddr * ) &target,
269  iscsi->target_address,
270  NULL ) ) != 0 ) {
271  DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
272  iscsi, strerror ( rc ) );
273  return rc;
274  }
275 
276  /* Enter security negotiation phase */
279  if ( iscsi->target_username )
281 
282  /* Assign new ISID */
283  iscsi->isid_iana_qual = ( random() & 0xffff );
284 
285  /* Assign fresh initiator task tag */
286  iscsi_new_itt ( iscsi );
287 
288  /* Set default operational parameters */
290 
291  /* Initiate login */
292  iscsi_start_login ( iscsi );
293 
294  return 0;
295 }
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition: iscsi.h:708
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition: iscsi.c:244
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
#define DBGC(...)
Definition: compiler.h:505
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition: iscsi.c:770
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
Definition: iscsi.h:669
unsigned int target_port
Target port.
Definition: iscsi.h:560
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
Nothing to send.
Definition: iscsi.h:522
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
Definition: iscsi.h:29
int status
Session status.
Definition: iscsi.h:569
Generalized socket address structure.
Definition: socket.h:96
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
enum iscsi_rx_state rx_state
State of the RX engine.
Definition: iscsi.h:649
char * target_address
Target address.
Definition: iscsi.h:558
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
#define SOCK_STREAM
Definition: socket.h:24
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition: iscsi.h:597
size_t max_burst_len
Maximum burst length.
Definition: iscsi.h:590
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition: iscsi.h:687
char * target_username
Target username (if any)
Definition: iscsi.h:576
Receiving the basic header segment.
Definition: iscsi.h:534
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition: resolv.c:402
void * memset(void *dest, int character, size_t len) __nonnull

References assert(), DBGC, htons, ISCSI_MAX_BURST_LEN, iscsi_new_itt(), ISCSI_RX_BHS, iscsi_start_login(), ISCSI_STATUS_AUTH_REVERSE_REQUIRED, ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE, ISCSI_STATUS_STRINGS_SECURITY, ISCSI_TX_IDLE, iscsi_session::isid_iana_qual, iscsi_session::max_burst_len, memset(), NULL, random(), rc, iscsi_session::rx_offset, iscsi_session::rx_state, SOCK_STREAM, iscsi_session::socket, sockaddr_tcpip::st_port, iscsi_session::status, strerror(), iscsi_session::target_address, iscsi_session::target_port, iscsi_session::target_username, iscsi_session::tx_state, and xfer_open_named_socket().

Referenced by iscsi_open(), and iscsi_rx_login_response().

◆ iscsi_close_connection()

static void iscsi_close_connection ( struct iscsi_session iscsi,
int  rc 
)
static

Close iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
rcReason for close

Closes the transport-layer connection and resets the session state ready to attempt a fresh login.

Definition at line 306 of file iscsi.c.

306  {
307 
308  /* Close all data transfer interfaces */
309  intf_restart ( &iscsi->socket, rc );
310 
311  /* Clear connection status */
312  iscsi->status = 0;
313 
314  /* Reset TX and RX state machines */
315  iscsi->tx_state = ISCSI_TX_IDLE;
316  iscsi->rx_state = ISCSI_RX_BHS;
317  iscsi->rx_offset = 0;
318 
319  /* Free any temporary dynamically allocated memory */
320  chap_finish ( &iscsi->chap );
321  iscsi_rx_buffered_data_done ( iscsi );
322 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
Nothing to send.
Definition: iscsi.h:522
int status
Session status.
Definition: iscsi.h:569
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:160
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
enum iscsi_rx_state rx_state
State of the RX engine.
Definition: iscsi.h:649
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
Receiving the basic header segment.
Definition: iscsi.h:534
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642

References iscsi_session::chap, chap_finish(), intf_restart(), ISCSI_RX_BHS, iscsi_rx_buffered_data_done(), ISCSI_TX_IDLE, rc, iscsi_session::rx_offset, iscsi_session::rx_state, iscsi_session::socket, iscsi_session::status, and iscsi_session::tx_state.

Referenced by iscsi_rx_login_response().

◆ iscsi_scsi_done()

static void iscsi_scsi_done ( struct iscsi_session iscsi,
int  rc,
struct scsi_rsp rsp 
)
static

Mark iSCSI SCSI operation as complete.

Parameters
iscsiiSCSI session
rcReturn status code
rspSCSI response, if any

Note that iscsi_scsi_done() will not close the connection, and must therefore be called only when the internal state machines are in an appropriate state, otherwise bad things may happen on the next call to iscsi_scsi_command(). The general rule is to call iscsi_scsi_done() only at the end of receiving a PDU; at this point the TX and RX engines should both be idle.

Definition at line 338 of file iscsi.c.

339  {
340  uint32_t itt = iscsi->itt;
341 
342  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
343 
344  /* Clear command */
345  free ( iscsi->command );
346  iscsi->command = NULL;
347 
348  /* Send SCSI response, if any */
349  if ( rsp )
350  scsi_response ( &iscsi->data, rsp );
351 
352  /* Close SCSI command, if this is still the same command. (It
353  * is possible that the command interface has already been
354  * closed as a result of the SCSI response we sent.)
355  */
356  if ( iscsi->itt == itt )
357  intf_restart ( &iscsi->data, rc );
358 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
Nothing to send.
Definition: iscsi.h:522
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
uint64_t rsp
Definition: librm.h:153
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface data
SCSI command interface.
Definition: iscsi.h:551
unsigned int uint32_t
Definition: stdint.h:12
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition: scsi.c:206
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642

References assert(), iscsi_session::command, iscsi_session::data, free, intf_restart(), ISCSI_TX_IDLE, iscsi_session::itt, NULL, rc, rsp, scsi_response(), and iscsi_session::tx_state.

Referenced by iscsi_rx_data_in(), and iscsi_rx_scsi_response().

◆ iscsi_start_command()

static void iscsi_start_command ( struct iscsi_session iscsi)
static

Build iSCSI SCSI command BHS.

Parameters
iscsiiSCSI session

We don't currently support bidirectional commands (i.e. with both Data-In and Data-Out segments); these would require providing code to generate an AHS, and there doesn't seem to be any need for it at the moment.

Definition at line 376 of file iscsi.c.

376  {
378 
379  assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
380 
381  /* Construct BHS and initiate transmission */
382  iscsi_start_tx ( iscsi );
384  command->flags = ( ISCSI_FLAG_FINAL |
386  if ( iscsi->command->data_in )
388  if ( iscsi->command->data_out )
390  /* lengths left as zero */
391  memcpy ( &command->lun, &iscsi->command->lun,
392  sizeof ( command->lun ) );
393  command->itt = htonl ( iscsi->itt );
394  command->exp_len = htonl ( iscsi->command->data_in_len |
395  iscsi->command->data_out_len );
396  command->cmdsn = htonl ( iscsi->cmdsn );
397  command->expstatsn = htonl ( iscsi->statsn + 1 );
398  memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
399  DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
400  iscsi, SCSI_CDB_DATA ( command->cdb ),
401  ( iscsi->command->data_in ? "in" : "out" ),
402  ( iscsi->command->data_in ?
403  iscsi->command->data_in_len :
404  iscsi->command->data_out_len ) );
405 }
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition: iscsi.h:291
struct iscsi_bhs_scsi_command scsi_command
Definition: iscsi.h:510
size_t data_out_len
Data-out buffer length.
Definition: scsi.h:259
void * data_in
Data-in buffer (may be NULL)
Definition: scsi.h:261
A command-line command.
Definition: command.h:9
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:266
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
Definition: iscsi.h:288
union scsi_cdb cdb
CDB for this command.
Definition: scsi.h:252
#define htonl(value)
Definition: byteswap.h:133
iSCSI SCSI command basic header segment
Definition: iscsi.h:261
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:102
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
struct scsi_lun lun
LUN.
Definition: scsi.h:250
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition: scsi.h:222
#define ISCSI_COMMAND_ATTR_SIMPLE
Definition: iscsi.h:295
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition: scsi.h:218
#define DBGC2(...)
Definition: compiler.h:522
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:629
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
Definition: iscsi.h:285
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1438
void * data_out
Data-out buffer (may be NULL)
Definition: scsi.h:254

References assert(), scsi_cmd::cdb, iscsi_session::cmdsn, iscsi_session::command, scsi_cmd::data_in, scsi_cmd::data_in_len, scsi_cmd::data_out, scsi_cmd::data_out_len, DBGC2, htonl, ISCSI_COMMAND_ATTR_SIMPLE, ISCSI_COMMAND_FLAG_READ, ISCSI_COMMAND_FLAG_WRITE, ISCSI_FLAG_FINAL, ISCSI_OPCODE_SCSI_COMMAND, iscsi_start_tx(), iscsi_session::itt, scsi_cmd::lun, memcpy(), SCSI_CDB_DATA, SCSI_CDB_FORMAT, iscsi_bhs::scsi_command, iscsi_session::statsn, and iscsi_session::tx_bhs.

Referenced by iscsi_scsi_command().

◆ iscsi_rx_scsi_response()

static int iscsi_rx_scsi_response ( struct iscsi_session iscsi,
const void *  data,
size_t  len,
size_t  remaining 
)
static

Receive data segment of an iSCSI SCSI response PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 416 of file iscsi.c.

418  {
420  = &iscsi->rx_bhs.scsi_response;
421  struct scsi_rsp rsp;
422  uint32_t residual_count;
423  size_t data_len;
424  int rc;
425 
426  /* Buffer up the PDU data */
427  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
428  DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
429  iscsi, strerror ( rc ) );
430  return rc;
431  }
432  if ( remaining )
433  return 0;
434 
435  /* Parse SCSI response and discard buffer */
436  memset ( &rsp, 0, sizeof ( rsp ) );
437  rsp.status = response->status;
438  residual_count = ntohl ( response->residual_count );
439  if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
440  rsp.overrun = residual_count;
441  } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
442  rsp.overrun = -(residual_count);
443  }
444  data_len = ISCSI_DATA_LEN ( response->lengths );
445  if ( data_len ) {
446  scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
447  &rsp.sense );
448  }
449  iscsi_rx_buffered_data_done ( iscsi );
450 
451  /* Check for errors */
452  if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
453  return -EIO;
454 
455  /* Mark as completed */
456  iscsi_scsi_done ( iscsi, 0, &rsp );
457  return 0;
458 }
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition: scsi.c:146
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ISCSI_DATA_FLAG_UNDERFLOW
Data underflow occurred.
Definition: iscsi.h:395
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
Definition: iscsi.h:392
#define DBGC(...)
Definition: compiler.h:505
uint8_t flags
Flags.
Definition: iscsi.h:308
#define ntohl(value)
Definition: byteswap.h:134
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
uint8_t response
Response code.
Definition: iscsi.h:310
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:655
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
uint8_t status
SCSI status code.
Definition: iscsi.h:312
A SCSI response information unit.
Definition: scsi.h:321
ring len
Length.
Definition: dwmac.h:231
uint64_t rsp
Definition: librm.h:153
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition: iscsi.c:178
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:160
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:314
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition: iscsi.c:338
unsigned int uint32_t
Definition: stdint.h:12
#define EIO
Input/output error.
Definition: errno.h:433
uint8_t data[48]
Additional event data.
Definition: ena.h:22
uint32_t residual_count
Residual count.
Definition: iscsi.h:332
iSCSI SCSI response basic header segment
Definition: iscsi.h:304
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
Definition: iscsi.h:339
struct iscsi_bhs_scsi_response scsi_response
Definition: iscsi.h:511
void * memset(void *dest, int character, size_t len) __nonnull

References data, data_len, DBGC, EIO, iscsi_bhs_scsi_response::flags, ISCSI_DATA_FLAG_OVERFLOW, ISCSI_DATA_FLAG_UNDERFLOW, ISCSI_DATA_LEN, ISCSI_RESPONSE_COMMAND_COMPLETE, iscsi_rx_buffered_data(), iscsi_rx_buffered_data_done(), iscsi_scsi_done(), len, iscsi_bhs_scsi_response::lengths, memset(), ntohl, rc, iscsi_bhs_scsi_response::residual_count, iscsi_bhs_scsi_response::response, rsp, iscsi_session::rx_bhs, iscsi_session::rx_buffer, scsi_parse_sense(), iscsi_bhs::scsi_response, iscsi_bhs_scsi_response::status, and strerror().

Referenced by iscsi_rx_data().

◆ iscsi_rx_data_in()

static int iscsi_rx_data_in ( struct iscsi_session iscsi,
const void *  data,
size_t  len,
size_t  remaining 
)
static

Receive data segment of an iSCSI data-in PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 469 of file iscsi.c.

471  {
472  struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
473  unsigned long offset;
474 
475  /* Copy data to data-in buffer */
476  offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
477  assert ( iscsi->command != NULL );
478  assert ( iscsi->command->data_in );
479  assert ( ( offset + len ) <= iscsi->command->data_in_len );
480  memcpy ( ( iscsi->command->data_in + offset ), data, len );
481 
482  /* Wait for whole SCSI response to arrive */
483  if ( remaining )
484  return 0;
485 
486  /* Mark as completed if status is present */
487  if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
488  assert ( ( offset + len ) == iscsi->command->data_in_len );
489  assert ( data_in->flags & ISCSI_FLAG_FINAL );
490  /* iSCSI cannot return an error status via a data-in */
491  iscsi_scsi_done ( iscsi, 0, NULL );
492  }
493 
494  return 0;
495 }
iSCSI data-in basic header segment
Definition: iscsi.h:354
void * data_in
Data-in buffer (may be NULL)
Definition: scsi.h:261
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition: iscsi.h:398
uint32_t offset
Buffer offset.
Definition: iscsi.h:380
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:266
#define ntohl(value)
Definition: byteswap.h:134
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:102
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition: iscsi.c:338
uint8_t flags
Flags.
Definition: iscsi.h:358
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct iscsi_bhs_data_in data_in
Definition: iscsi.h:512

References assert(), iscsi_session::command, data, scsi_cmd::data_in, iscsi_bhs::data_in, scsi_cmd::data_in_len, iscsi_bhs_data_in::flags, ISCSI_DATA_FLAG_STATUS, ISCSI_FLAG_FINAL, iscsi_scsi_done(), len, memcpy(), ntohl, NULL, offset, iscsi_bhs_data_in::offset, iscsi_session::rx_bhs, and iscsi_session::rx_offset.

Referenced by iscsi_rx_data().

◆ iscsi_rx_r2t()

static int iscsi_rx_r2t ( struct iscsi_session iscsi,
const void *data  __unused,
size_t len  __unused,
size_t remaining  __unused 
)
static

Receive data segment of an iSCSI R2T PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 506 of file iscsi.c.

508  {
509  struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
510 
511  /* Record transfer parameters and trigger first data-out */
512  iscsi->ttt = ntohl ( r2t->ttt );
513  iscsi->transfer_offset = ntohl ( r2t->offset );
514  iscsi->transfer_len = ntohl ( r2t->len );
515  iscsi_start_data_out ( iscsi, 0 );
516 
517  return 0;
518 }
uint32_t ttt
Target transfer tag.
Definition: iscsi.h:609
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition: iscsi.c:527
#define ntohl(value)
Definition: byteswap.h:134
struct iscsi_bhs_r2t r2t
Definition: iscsi.h:514
uint32_t offset
Buffer offset.
Definition: iscsi.h:464
iSCSI request to transfer basic header segment
Definition: iscsi.h:440
uint32_t len
Desired data transfer length.
Definition: iscsi.h:466
uint32_t transfer_offset
Transfer offset.
Definition: iscsi.h:615
uint32_t transfer_len
Transfer length.
Definition: iscsi.h:621
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:454
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647

References iscsi_start_data_out(), iscsi_bhs_r2t::len, ntohl, iscsi_bhs_r2t::offset, iscsi_bhs::r2t, iscsi_session::rx_bhs, iscsi_session::transfer_len, iscsi_session::transfer_offset, iscsi_bhs_r2t::ttt, and iscsi_session::ttt.

Referenced by iscsi_rx_data().

◆ iscsi_data_out_done()

static void iscsi_data_out_done ( struct iscsi_session iscsi)
static

Complete iSCSI data-out PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 565 of file iscsi.c.

565  {
566  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
567 
568  /* If we haven't reached the end of the sequence, start
569  * sending the next data-out PDU.
570  */
571  if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
572  iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
573 }
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:513
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition: iscsi.c:527
#define ntohl(value)
Definition: byteswap.h:134
uint32_t datasn
Data sequence number.
Definition: iscsi.h:426
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:102
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
uint8_t flags
Flags.
Definition: iscsi.h:408
iSCSI data-out basic header segment
Definition: iscsi.h:404

References iscsi_bhs::data_out, iscsi_bhs_data_out::datasn, iscsi_bhs_data_out::flags, ISCSI_FLAG_FINAL, iscsi_start_data_out(), ntohl, and iscsi_session::tx_bhs.

Referenced by iscsi_tx_done().

◆ iscsi_tx_data_out()

static int iscsi_tx_data_out ( struct iscsi_session iscsi)
static

Send iSCSI data-out data segment.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 581 of file iscsi.c.

581  {
582  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
583  struct io_buffer *iobuf;
584  unsigned long offset;
585  size_t len;
586  size_t pad_len;
587 
588  offset = ntohl ( data_out->offset );
589  len = ISCSI_DATA_LEN ( data_out->lengths );
590  pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
591 
592  assert ( iscsi->command != NULL );
593  assert ( iscsi->command->data_out );
594  assert ( ( offset + len ) <= iscsi->command->data_out_len );
595 
596  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
597  if ( ! iobuf )
598  return -ENOMEM;
599 
600  memcpy ( iob_put ( iobuf, len ),
601  ( iscsi->command->data_out + offset ), len );
602  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
603 
604  return xfer_deliver_iob ( &iscsi->socket, iobuf );
605 }
#define iob_put(iobuf, len)
Definition: iobuf.h:124
size_t data_out_len
Data-out buffer length.
Definition: scsi.h:259
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:412
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:513
#define ntohl(value)
Definition: byteswap.h:134
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
uint32_t offset
Buffer offset.
Definition: iscsi.h:428
long pad_len
Definition: bigint.h:30
iSCSI data-out basic header segment
Definition: iscsi.h:404
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
void * data_out
Data-out buffer (may be NULL)
Definition: scsi.h:254
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:37

References assert(), iscsi_session::command, scsi_cmd::data_out, iscsi_bhs::data_out, scsi_cmd::data_out_len, ENOMEM, iob_put, ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, len, iscsi_bhs_data_out::lengths, memcpy(), memset(), ntohl, NULL, offset, iscsi_bhs_data_out::offset, pad_len, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_rx_nop_in()

static int iscsi_rx_nop_in ( struct iscsi_session iscsi,
const void *data  __unused,
size_t len  __unused,
size_t remaining  __unused 
)
static

Receive data segment of an iSCSI NOP-In.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 616 of file iscsi.c.

618  {
619  struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in;
620 
621  DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi );
622 
623  /* We don't currently have the ability to respond to NOP-Ins
624  * sent as ping requests, but we can happily accept NOP-Ins
625  * sent merely to update CmdSN.
626  */
627  if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) )
628  return 0;
629 
630  /* Ignore any other NOP-Ins. The target may eventually
631  * disconnect us for failing to respond, but this minimises
632  * unnecessary connection closures.
633  */
634  DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n",
635  iscsi, ntohl ( nop_in->ttt ) );
636  return 0;
637 }
iSCSI NOP-In basic header segment
Definition: iscsi.h:476
#define DBGC(...)
Definition: compiler.h:505
#define ntohl(value)
Definition: byteswap.h:134
#define ISCSI_TAG_RESERVED
iSCSI reserved tag value
Definition: iscsi.h:108
#define htonl(value)
Definition: byteswap.h:133
struct iscsi_nop_in nop_in
Definition: iscsi.h:515
#define DBGC2(...)
Definition: compiler.h:522
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:488

References DBGC, DBGC2, htonl, ISCSI_TAG_RESERVED, iscsi_bhs::nop_in, ntohl, iscsi_session::rx_bhs, and iscsi_nop_in::ttt.

Referenced by iscsi_rx_data().

◆ iscsi_build_login_request_strings()

static int iscsi_build_login_request_strings ( struct iscsi_session iscsi,
void *  data,
size_t  len 
)
static

Build iSCSI login request strings.

Parameters
iscsiiSCSI session

These are the initial set of strings sent in the first login request PDU. We want the following settings:

HeaderDigest=None
DataDigest=None
MaxConnections=1 (irrelevant; we make only one connection anyway) [4]
InitialR2T=Yes [1]
ImmediateData=No (irrelevant; we never send immediate data) [4]
MaxRecvDataSegmentLength=8192 (default; we don't care) [3]
MaxBurstLength=262144 (default; we don't care) [3]
FirstBurstLength=65536 (irrelevant due to other settings) [5]
DefaultTime2Wait=0 [2]
DefaultTime2Retain=0 [2]
MaxOutstandingR2T=1
DataPDUInOrder=Yes
DataSequenceInOrder=Yes
ErrorRecoveryLevel=0

[1] InitialR2T has an OR resolution function, so the target may force us to use it. We therefore simplify our logic by always using it.

[2] These ensure that we can safely start a new task once we have reconnected after a failure, without having to manually tidy up after the old one.

[3] We are quite happy to use the RFC-defined default values for these parameters, but some targets (notably OpenSolaris) incorrectly assume a default value of zero, so we explicitly specify the default values.

[4] We are quite happy to use the RFC-defined default values for these parameters, but some targets (notably a QNAP TS-639Pro) fail unless they are supplied, so we explicitly specify the default values.

[5] FirstBurstLength is defined to be irrelevant since we already force InitialR2T=Yes and ImmediateData=No, but some targets (notably LIO as of kernel 4.11) fail unless it is specified, so we explicitly specify the default value.

Definition at line 691 of file iscsi.c.

692  {
693  unsigned int used = 0;
694  const char *auth_method;
695 
696  if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
697  /* Default to allowing no authentication */
698  auth_method = "None";
699  /* If we have a credential to supply, permit CHAP */
700  if ( iscsi->initiator_username )
701  auth_method = "CHAP,None";
702  /* If we have a credential to check, force CHAP */
703  if ( iscsi->target_username )
704  auth_method = "CHAP";
705  used += ssnprintf ( data + used, len - used,
706  "InitiatorName=%s%c"
707  "TargetName=%s%c"
708  "SessionType=Normal%c"
709  "AuthMethod=%s%c",
710  iscsi->initiator_iqn, 0,
711  iscsi->target_iqn, 0, 0,
712  auth_method, 0 );
713  }
714 
716  used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
717  }
718 
719  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
720  char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
721  assert ( iscsi->initiator_username != NULL );
722  base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
723  buf, sizeof ( buf ) );
724  used += ssnprintf ( data + used, len - used,
725  "CHAP_N=%s%cCHAP_R=0x%s%c",
726  iscsi->initiator_username, 0, buf, 0 );
727  }
728 
729  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
730  size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
731  char buf[ base16_encoded_len ( challenge_len ) + 1 ];
732  base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
733  buf, sizeof ( buf ) );
734  used += ssnprintf ( data + used, len - used,
735  "CHAP_I=%d%cCHAP_C=0x%s%c",
736  iscsi->chap_challenge[0], 0, buf, 0 );
737  }
738 
739  if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) {
740  used += ssnprintf ( data + used, len - used,
741  "HeaderDigest=None%c"
742  "DataDigest=None%c"
743  "MaxConnections=1%c"
744  "InitialR2T=Yes%c"
745  "ImmediateData=No%c"
746  "MaxRecvDataSegmentLength=%d%c"
747  "MaxBurstLength=%d%c"
748  "FirstBurstLength=%d%c"
749  "DefaultTime2Wait=0%c"
750  "DefaultTime2Retain=0%c"
751  "MaxOutstandingR2T=1%c"
752  "DataPDUInOrder=Yes%c"
753  "DataSequenceInOrder=Yes%c"
754  "ErrorRecoveryLevel=0%c",
755  0, 0, 0, 0, 0,
759  0, 0, 0, 0, 0, 0 );
760  }
761 
762  return used;
763 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:572
uint8_t * response
CHAP response.
Definition: chap.h:24
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:24
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
Definition: iscsi.h:29
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
#define ISCSI_FIRST_BURST_LEN
Default iSCSI first burst length.
Definition: iscsi.h:26
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition: iscsi.h:690
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition: iscsi.h:696
size_t response_len
Length of CHAP response.
Definition: chap.h:26
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition: iscsi.h:693
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
char * target_iqn
Target IQN.
Definition: iscsi.h:562
#define ISCSI_MAX_RECV_DATA_SEG_LEN
Default iSCSI maximum receive data segment length.
Definition: iscsi.h:32
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition: iscsi.h:687
uint8_t data[48]
Additional event data.
Definition: ena.h:22
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:556
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition: iscsi.h:699
char * target_username
Target username (if any)
Definition: iscsi.h:576
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References assert(), base16_encoded_len(), iscsi_session::chap, iscsi_session::chap_challenge, data, iscsi_session::initiator_iqn, iscsi_session::initiator_username, ISCSI_FIRST_BURST_LEN, ISCSI_MAX_BURST_LEN, ISCSI_MAX_RECV_DATA_SEG_LEN, ISCSI_STATUS_STRINGS_CHAP_ALGORITHM, ISCSI_STATUS_STRINGS_CHAP_CHALLENGE, ISCSI_STATUS_STRINGS_CHAP_RESPONSE, ISCSI_STATUS_STRINGS_OPERATIONAL, ISCSI_STATUS_STRINGS_SECURITY, len, NULL, chap_response::response, chap_response::response_len, ssnprintf(), iscsi_session::status, iscsi_session::target_iqn, and iscsi_session::target_username.

Referenced by iscsi_start_login(), and iscsi_tx_login_request().

◆ iscsi_login_request_done()

static void iscsi_login_request_done ( struct iscsi_session iscsi)
static

Complete iSCSI login request PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 812 of file iscsi.c.

812  {
813 
814  /* Clear any "strings to send" flags */
816 
817  /* Free any dynamically allocated storage used for login */
818  chap_finish ( &iscsi->chap );
819 }
int status
Session status.
Definition: iscsi.h:569
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition: iscsi.h:702
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587

References iscsi_session::chap, chap_finish(), ISCSI_STATUS_STRINGS_MASK, and iscsi_session::status.

Referenced by iscsi_tx_done().

◆ iscsi_tx_login_request()

static int iscsi_tx_login_request ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI login request PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

For login requests, the data segment consists of the login strings.

Definition at line 829 of file iscsi.c.

829  {
831  struct io_buffer *iobuf;
832  size_t len;
833  size_t pad_len;
834 
835  len = ISCSI_DATA_LEN ( request->lengths );
836  pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
837  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
838  if ( ! iobuf )
839  return -ENOMEM;
840  iob_put ( iobuf, len );
841  iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
842  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
843 
844  return xfer_deliver_iob ( &iscsi->socket, iobuf );
845 }
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:508
#define iob_put(iobuf, len)
Definition: iobuf.h:124
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
iSCSI login request basic header segment
Definition: iscsi.h:141
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
#define ENOMEM
Not enough space.
Definition: errno.h:534
ring len
Length.
Definition: dwmac.h:231
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
long pad_len
Definition: bigint.h:30
void * data
Start of data.
Definition: iobuf.h:52
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition: iscsi.c:691
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:37

References io_buffer::data, ENOMEM, iob_put, iscsi_build_login_request_strings(), ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, len, iscsi_bhs::login_request, memset(), pad_len, request, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_large_binary_decode()

static int iscsi_large_binary_decode ( const char *  encoded,
uint8_t raw,
size_t  len 
)
static

Decode large binary value.

Parameters
encodedEncoded large binary value
rawRaw data
lenLength of data buffer
Return values
lenLength of raw data, or negative error

Definition at line 855 of file iscsi.c.

856  {
857 
858  /* Check for initial '0x' or '0b' and decode as appropriate */
859  if ( *(encoded++) == '0' ) {
860  switch ( tolower ( *(encoded++) ) ) {
861  case 'x' :
862  return base16_decode ( encoded, raw, len );
863  case 'b' :
864  return base64_decode ( encoded, raw, len );
865  }
866  }
867 
869 }
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition: base64.c:91
ring len
Length.
Definition: dwmac.h:231
static int tolower(int character)
Convert character to lower case.
Definition: ctype.h:108
__be32 raw[7]
Definition: CIB_PRM.h:28
#define EPROTO_INVALID_LARGE_BINARY
Definition: iscsi.c:133

References base64_decode(), EPROTO_INVALID_LARGE_BINARY, len, raw, and tolower().

Referenced by iscsi_handle_chap_c_value(), and iscsi_handle_chap_r_value().

◆ iscsi_handle_targetaddress_value()

static int iscsi_handle_targetaddress_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI TargetAddress text value.

Parameters
iscsiiSCSI session
valueTargetAddress value
Return values
rcReturn status code

Definition at line 878 of file iscsi.c.

879  {
880  char *separator;
881 
882  DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
883 
884  /* Replace target address */
885  free ( iscsi->target_address );
886  iscsi->target_address = strdup ( value );
887  if ( ! iscsi->target_address )
888  return -ENOMEM;
889 
890  /* Replace target port */
891  iscsi->target_port = htons ( ISCSI_PORT );
892  separator = strchr ( iscsi->target_address, ':' );
893  if ( separator ) {
894  *separator = '\0';
895  iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
896  }
897 
898  return 0;
899 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
#define DBGC(...)
Definition: compiler.h:505
unsigned int target_port
Target port.
Definition: iscsi.h:560
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define ISCSI_PORT
Default iSCSI port.
Definition: iscsi.h:23
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:271
char * strdup(const char *src)
Duplicate string.
Definition: string.c:393
char * target_address
Target address.
Definition: iscsi.h:558
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
#define htons(value)
Definition: byteswap.h:135

References DBGC, ENOMEM, free, htons, ISCSI_PORT, NULL, strchr(), strdup(), strtoul(), iscsi_session::target_address, iscsi_session::target_port, and value.

◆ iscsi_handle_authmethod_value()

static int iscsi_handle_authmethod_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI AuthMethod text value.

Parameters
iscsiiSCSI session
valueAuthMethod value
Return values
rcReturn status code

Definition at line 908 of file iscsi.c.

909  {
910 
911  /* If server requests CHAP, send the CHAP_A string */
912  if ( strcmp ( value, "CHAP" ) == 0 ) {
913  DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
914  iscsi );
917  }
918 
919  return 0;
920 }
#define DBGC(...)
Definition: compiler.h:505
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int status
Session status.
Definition: iscsi.h:569
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition: iscsi.h:690
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition: iscsi.h:705

References DBGC, ISCSI_STATUS_AUTH_FORWARD_REQUIRED, ISCSI_STATUS_STRINGS_CHAP_ALGORITHM, iscsi_session::status, strcmp(), and value.

◆ iscsi_handle_maxburstlength_value()

static int iscsi_handle_maxburstlength_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI MaxBurstLength text value.

Parameters
iscsiiSCSI session
valueMaxBurstLength value
Return values
rcReturn status code

Definition at line 929 of file iscsi.c.

930  {
931  unsigned long max_burst_len;
932  char *end;
933 
934  /* Update maximum burst length */
935  max_burst_len = strtoul ( value, &end, 0 );
936  if ( *end ) {
937  DBGC ( iscsi, "iSCSI %p invalid MaxBurstLength \"%s\"\n",
938  iscsi, value );
939  return -EINVAL_MAXBURSTLENGTH;
940  }
941  if ( max_burst_len < iscsi->max_burst_len )
942  iscsi->max_burst_len = max_burst_len;
943 
944  return 0;
945 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
#define DBGC(...)
Definition: compiler.h:505
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
size_t max_burst_len
Maximum burst length.
Definition: iscsi.h:590
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define EINVAL_MAXBURSTLENGTH
Definition: iscsi.c:89

References DBGC, EINVAL_MAXBURSTLENGTH, end, iscsi_session::max_burst_len, strtoul(), and value.

◆ iscsi_handle_chap_a_value()

static int iscsi_handle_chap_a_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI CHAP_A text value.

Parameters
iscsiiSCSI session
valueCHAP_A value
Return values
rcReturn status code

Definition at line 954 of file iscsi.c.

955  {
956 
957  /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
958  * the server responds with anything else it is a protocol
959  * violation.
960  */
961  if ( strcmp ( value, "5" ) != 0 ) {
962  DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
963  iscsi, value );
965  }
966 
967  return 0;
968 }
#define EPROTO_INVALID_CHAP_ALGORITHM
Definition: iscsi.c:125
#define DBGC(...)
Definition: compiler.h:505
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173

References DBGC, EPROTO_INVALID_CHAP_ALGORITHM, strcmp(), and value.

◆ iscsi_handle_chap_i_value()

static int iscsi_handle_chap_i_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI CHAP_I text value.

Parameters
iscsiiSCSI session
valueCHAP_I value
Return values
rcReturn status code

Definition at line 977 of file iscsi.c.

978  {
979  unsigned int identifier;
980  char *endp;
981  int rc;
982 
983  /* The CHAP identifier is an integer value */
984  identifier = strtoul ( value, &endp, 0 );
985  if ( *endp != '\0' ) {
986  DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
987  iscsi, value );
989  }
990 
991  /* Prepare for CHAP with MD5 */
992  chap_finish ( &iscsi->chap );
993  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
994  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
995  iscsi, strerror ( rc ) );
996  return rc;
997  }
998 
999  /* Identifier and secret are the first two components of the
1000  * challenge.
1001  */
1002  chap_set_identifier ( &iscsi->chap, identifier );
1003  if ( iscsi->initiator_password ) {
1004  chap_update ( &iscsi->chap, iscsi->initiator_password,
1005  strlen ( iscsi->initiator_password ) );
1006  }
1007 
1008  return 0;
1009 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition: chap.c:51
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define EPROTO_INVALID_CHAP_IDENTIFIER
Definition: iscsi.c:129
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References iscsi_session::chap, chap_finish(), chap_init(), chap_set_identifier(), chap_update(), DBGC, EPROTO_INVALID_CHAP_IDENTIFIER, iscsi_session::initiator_password, md5_algorithm, rc, strerror(), strlen(), strtoul(), and value.

◆ iscsi_handle_chap_c_value()

static int iscsi_handle_chap_c_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI CHAP_C text value.

Parameters
iscsiiSCSI session
valueCHAP_C value
Return values
rcReturn status code

Definition at line 1018 of file iscsi.c.

1019  {
1020  uint8_t *buf;
1021  unsigned int i;
1022  int len;
1023  int rc;
1024 
1025  /* Allocate decoding buffer */
1026  len = strlen ( value ); /* Decoding never expands data */
1027  buf = malloc ( len );
1028  if ( ! buf ) {
1029  rc = -ENOMEM;
1030  goto err_alloc;
1031  }
1032 
1033  /* Process challenge */
1034  len = iscsi_large_binary_decode ( value, buf, len );
1035  if ( len < 0 ) {
1036  rc = len;
1037  DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1038  iscsi, value, strerror ( rc ) );
1039  goto err_decode;
1040  }
1041  chap_update ( &iscsi->chap, buf, len );
1042 
1043  /* Build CHAP response */
1044  DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1045  chap_respond ( &iscsi->chap );
1047 
1048  /* Send CHAP challenge, if applicable */
1049  if ( iscsi->target_username ) {
1051  /* Generate CHAP challenge data */
1052  for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1053  iscsi->chap_challenge[i] = random();
1054  }
1055  }
1056 
1057  /* Success */
1058  rc = 0;
1059 
1060  err_decode:
1061  free ( buf );
1062  err_alloc:
1063  return rc;
1064 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
Definition: chap.c:104
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
Definition: iscsi.c:855
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition: iscsi.h:696
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition: iscsi.h:693
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
char * target_username
Target username (if any)
Definition: iscsi.h:576
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85

References iscsi_session::chap, iscsi_session::chap_challenge, chap_respond(), chap_update(), DBGC, ENOMEM, free, iscsi_large_binary_decode(), ISCSI_STATUS_STRINGS_CHAP_CHALLENGE, ISCSI_STATUS_STRINGS_CHAP_RESPONSE, len, malloc(), random(), rc, iscsi_session::status, strerror(), strlen(), iscsi_session::target_username, and value.

◆ iscsi_handle_chap_n_value()

static int iscsi_handle_chap_n_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI CHAP_N text value.

Parameters
iscsiiSCSI session
valueCHAP_N value
Return values
rcReturn status code

Definition at line 1073 of file iscsi.c.

1074  {
1075 
1076  /* The target username isn't actually involved at any point in
1077  * the authentication process; it merely serves to identify
1078  * which password the target is using to generate the CHAP
1079  * response. We unnecessarily verify that the username is as
1080  * expected, in order to provide mildly helpful diagnostics if
1081  * the target is supplying the wrong username/password
1082  * combination.
1083  */
1084  if ( iscsi->target_username &&
1085  ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1086  DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1087  "(wanted \"%s\")\n",
1088  iscsi, value, iscsi->target_username );
1090  }
1091 
1092  return 0;
1093 }
#define DBGC(...)
Definition: compiler.h:505
#define EACCES_INCORRECT_TARGET_USERNAME
Definition: iscsi.c:61
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
char * target_username
Target username (if any)
Definition: iscsi.h:576

References DBGC, EACCES_INCORRECT_TARGET_USERNAME, strcmp(), iscsi_session::target_username, and value.

◆ iscsi_handle_chap_r_value()

static int iscsi_handle_chap_r_value ( struct iscsi_session iscsi,
const char *  value 
)
static

Handle iSCSI CHAP_R text value.

Parameters
iscsiiSCSI session
valueCHAP_R value
Return values
rcReturn status code

Definition at line 1102 of file iscsi.c.

1103  {
1104  uint8_t *buf;
1105  int len;
1106  int rc;
1107 
1108  /* Generate CHAP response for verification */
1109  chap_finish ( &iscsi->chap );
1110  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1111  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1112  iscsi, strerror ( rc ) );
1113  goto err_chap_init;
1114  }
1115  chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1116  if ( iscsi->target_password ) {
1117  chap_update ( &iscsi->chap, iscsi->target_password,
1118  strlen ( iscsi->target_password ) );
1119  }
1120  chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1121  ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1122  chap_respond ( &iscsi->chap );
1123 
1124  /* Allocate decoding buffer */
1125  len = strlen ( value ); /* Decoding never expands data */
1126  buf = malloc ( len );
1127  if ( ! buf ) {
1128  rc = -ENOMEM;
1129  goto err_alloc;
1130  }
1131 
1132  /* Process response */
1133  len = iscsi_large_binary_decode ( value, buf, len );
1134  if ( len < 0 ) {
1135  rc = len;
1136  DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1137  iscsi, value, strerror ( rc ) );
1138  goto err_decode;
1139  }
1140 
1141  /* Check CHAP response */
1142  if ( len != ( int ) iscsi->chap.response_len ) {
1143  DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1144  iscsi );
1146  goto err_response_len;
1147  }
1148  if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1149  DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1150  iscsi, value );
1152  goto err_response;
1153  }
1154 
1155  /* Mark session as authenticated */
1157 
1158  err_response:
1159  err_response_len:
1160  err_decode:
1161  free ( buf );
1162  err_alloc:
1163  err_chap_init:
1164  return rc;
1165 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t * response
CHAP response.
Definition: chap.h:24
#define EPROTO_INVALID_CHAP_RESPONSE
Definition: iscsi.c:137
#define DBGC(...)
Definition: compiler.h:505
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
Definition: chap.c:104
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
Definition: iscsi.c:855
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition: chap.c:51
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition: iscsi.c:65
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
size_t response_len
Length of CHAP response.
Definition: chap.h:26
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:711
char * target_password
Target password (if any)
Definition: iscsi.h:578
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

References iscsi_session::chap, iscsi_session::chap_challenge, chap_finish(), chap_init(), chap_respond(), chap_set_identifier(), chap_update(), DBGC, EACCES_INCORRECT_TARGET_PASSWORD, ENOMEM, EPROTO_INVALID_CHAP_RESPONSE, free, iscsi_large_binary_decode(), ISCSI_STATUS_AUTH_REVERSE_OK, len, malloc(), md5_algorithm, memcmp(), rc, chap_response::response, chap_response::response_len, iscsi_session::status, strerror(), strlen(), iscsi_session::target_password, and value.

◆ iscsi_handle_string()

static int iscsi_handle_string ( struct iscsi_session iscsi,
const char *  string 
)
static

Handle iSCSI string.

Parameters
iscsiiSCSI session
stringiSCSI string (in "key=value" format)
Return values
rcReturn status code

Definition at line 1204 of file iscsi.c.

1205  {
1206  struct iscsi_string_type *type;
1207  const char *separator;
1208  const char *value;
1209  size_t key_len;
1210  int rc;
1211 
1212  /* Find separator */
1213  separator = strchr ( string, '=' );
1214  if ( ! separator ) {
1215  DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1216  iscsi, string );
1218  }
1219  key_len = ( separator - string );
1220  value = ( separator + 1 );
1221 
1222  /* Check for rejections. Since we send only non-rejectable
1223  * values, any rejection is a fatal protocol error.
1224  */
1225  if ( strcmp ( value, "Reject" ) == 0 ) {
1226  DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1227  return -EPROTO_VALUE_REJECTED;
1228  }
1229 
1230  /* Handle key/value pair */
1231  for ( type = iscsi_string_types ; type->key ; type++ ) {
1232  if ( strncmp ( string, type->key, key_len ) != 0 )
1233  continue;
1234  DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1235  if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1236  DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1237  iscsi, string, strerror ( rc ) );
1238  return rc;
1239  }
1240  return 0;
1241  }
1242  DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1243  return 0;
1244 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t type
Operating system type.
Definition: ena.h:12
#define DBGC(...)
Definition: compiler.h:505
uint32_t string
Definition: multiboot.h:14
static struct iscsi_string_type iscsi_string_types[]
iSCSI text strings that we want to handle
Definition: iscsi.c:1185
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition: string.c:186
An iSCSI text string that we want to handle.
Definition: iscsi.c:1168
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define EPROTO_INVALID_KEY_VALUE_PAIR
Definition: iscsi.c:141
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:271
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
#define EPROTO_VALUE_REJECTED
Definition: iscsi.c:145

References DBGC, EPROTO_INVALID_KEY_VALUE_PAIR, EPROTO_VALUE_REJECTED, iscsi_string_types, rc, strchr(), strcmp(), strerror(), string, strncmp(), type, and value.

Referenced by iscsi_handle_strings().

◆ iscsi_handle_strings()

static int iscsi_handle_strings ( struct iscsi_session iscsi,
const char *  strings,
size_t  len 
)
static

Handle iSCSI strings.

Parameters
iscsiiSCSI session
stringiSCSI string buffer
lenLength of string buffer
Return values
rcReturn status code

Definition at line 1254 of file iscsi.c.

1255  {
1256  size_t string_len;
1257  int rc;
1258 
1259  /* Handle each string in turn, taking care not to overrun the
1260  * data buffer in case of badly-terminated data.
1261  */
1262  while ( 1 ) {
1263  string_len = ( strnlen ( strings, len ) + 1 );
1264  if ( string_len > len )
1265  break;
1266  if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1267  return rc;
1268  strings += string_len;
1269  len -= string_len;
1270  }
1271  return 0;
1272 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
ring len
Length.
Definition: dwmac.h:231
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition: iscsi.c:1204
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:255

References iscsi_handle_string(), len, rc, and strnlen().

Referenced by iscsi_rx_login_response().

◆ iscsi_status_to_rc()

static int iscsi_status_to_rc ( unsigned int  status_class,
unsigned int  status_detail 
)
static

Convert iSCSI response status to return status code.

Parameters
status_classiSCSI status class
status_detailiSCSI status detail
Return values
rcReturn status code

Definition at line 1281 of file iscsi.c.

1282  {
1283  switch ( status_class ) {
1285  switch ( status_detail ) {
1292  return -ENODEV;
1293  default :
1294  return -ENOTSUP_INITIATOR_STATUS;
1295  }
1297  switch ( status_detail ) {
1299  return -EIO_TARGET_UNAVAILABLE;
1301  return -EIO_TARGET_NO_RESOURCES;
1302  default:
1303  return -ENOTSUP_TARGET_STATUS;
1304  }
1305  default :
1306  return -EINVAL;
1307  }
1308 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition: iscsi.h:249
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition: iscsi.h:252
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition: iscsi.h:255
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition: iscsi.h:254
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition: iscsi.h:251
#define ISCSI_STATUS_INITIATOR_ERROR
Definition: iscsi.h:248
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition: iscsi.h:250
#define ENODEV
No such device.
Definition: errno.h:509
#define EIO_TARGET_UNAVAILABLE
Definition: iscsi.c:93
#define ENOTSUP_INITIATOR_STATUS
Definition: iscsi.c:101
#define ENOTSUP_TARGET_STATUS
Definition: iscsi.c:113
#define EPERM_INITIATOR_AUTHORISATION
Definition: iscsi.c:121
#define EIO_TARGET_NO_RESOURCES
Definition: iscsi.c:97
#define EPERM_INITIATOR_AUTHENTICATION
Definition: iscsi.c:117
#define ISCSI_STATUS_TARGET_ERROR
Definition: iscsi.h:253

References EINVAL, EIO_TARGET_NO_RESOURCES, EIO_TARGET_UNAVAILABLE, ENODEV, ENOTSUP_INITIATOR_STATUS, ENOTSUP_TARGET_STATUS, EPERM_INITIATOR_AUTHENTICATION, EPERM_INITIATOR_AUTHORISATION, ISCSI_STATUS_INITIATOR_ERROR, ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION, ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION, ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND, ISCSI_STATUS_INITIATOR_ERROR_REMOVED, ISCSI_STATUS_TARGET_ERROR, ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES, and ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE.

Referenced by iscsi_rx_login_response().

◆ iscsi_rx_login_response()

static int iscsi_rx_login_response ( struct iscsi_session iscsi,
const void *  data,
size_t  len,
size_t  remaining 
)
static

Receive data segment of an iSCSI login response PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 1319 of file iscsi.c.

1321  {
1322  struct iscsi_bhs_login_response *response
1323  = &iscsi->rx_bhs.login_response;
1324  int rc;
1325 
1326  /* Buffer up the PDU data */
1327  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1328  DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1329  iscsi, strerror ( rc ) );
1330  return rc;
1331  }
1332  if ( remaining )
1333  return 0;
1334 
1335  /* Process string data and discard string buffer */
1336  if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1337  iscsi->rx_len ) ) != 0 )
1338  return rc;
1339  iscsi_rx_buffered_data_done ( iscsi );
1340 
1341  /* Check for login redirection */
1342  if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1343  DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1344  iscsi_close_connection ( iscsi, 0 );
1345  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1346  DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1347  iscsi, strerror ( rc ) );
1348  return rc;
1349  }
1350  return 0;
1351  }
1352 
1353  /* Check for fatal errors */
1354  if ( response->status_class != 0 ) {
1355  DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1356  response->status_class, response->status_detail );
1357  rc = iscsi_status_to_rc ( response->status_class,
1358  response->status_detail );
1359  return rc;
1360  }
1361 
1362  /* Handle login transitions */
1363  if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1364  iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1366  switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1368  iscsi->status |=
1371  break;
1374  break;
1375  default:
1376  DBGC ( iscsi, "iSCSI %p got invalid response flags "
1377  "%02x\n", iscsi, response->flags );
1378  return -EIO;
1379  }
1380  }
1381 
1382  /* Send next login request PDU if we haven't reached the full
1383  * feature phase yet.
1384  */
1385  if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1387  iscsi_start_login ( iscsi );
1388  return 0;
1389  }
1390 
1391  /* Check that target authentication was successful (if required) */
1392  if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1393  ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1394  DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1395  "authentication\n", iscsi );
1396  return -EPROTO;
1397  }
1398 
1399  /* Notify SCSI layer of window change */
1400  DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1401  xfer_window_changed ( &iscsi->control );
1402 
1403  return 0;
1404 }
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition: iscsi.h:708
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition: iscsi.h:681
#define ISCSI_LOGIN_NSG_MASK
Definition: iscsi.h:188
#define DBGC(...)
Definition: compiler.h:505
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:653
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Definition: iscsi.h:676
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:655
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition: iscsi.c:770
uint8_t status_detail
Status detail.
Definition: iscsi.h:237
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition: iscsi.h:176
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:684
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:549
uint8_t status_class
Status class.
Definition: iscsi.h:235
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
Definition: iscsi.c:306
#define EPROTO
Protocol error.
Definition: errno.h:624
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition: iscsi.c:178
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:160
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition: iscsi.h:702
iSCSI login response basic header segment
Definition: iscsi.h:207
uint8_t flags
Flags.
Definition: iscsi.h:211
static int iscsi_status_to_rc(unsigned int status_class, unsigned int status_detail)
Convert iSCSI response status to return status code.
Definition: iscsi.c:1281
#define ISCSI_STATUS_REDIRECT
Definition: iscsi.h:247
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:190
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:711
struct iscsi_bhs_login_response login_response
Definition: iscsi.h:509
#define EIO
Input/output error.
Definition: errno.h:433
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition: iscsi.c:256
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition: iscsi.h:699
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition: iscsi.c:1254
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
Definition: iscsi.h:191

References iscsi_session::control, data, DBGC, EIO, EPROTO, iscsi_bhs_login_response::flags, iscsi_close_connection(), iscsi_handle_strings(), ISCSI_LOGIN_FLAG_TRANSITION, ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE, ISCSI_LOGIN_NSG_MASK, ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION, iscsi_open_connection(), iscsi_rx_buffered_data(), iscsi_rx_buffered_data_done(), iscsi_start_login(), ISCSI_STATUS_AUTH_REVERSE_OK, ISCSI_STATUS_AUTH_REVERSE_REQUIRED, ISCSI_STATUS_FULL_FEATURE_PHASE, ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE, ISCSI_STATUS_PHASE_MASK, ISCSI_STATUS_REDIRECT, ISCSI_STATUS_STRINGS_MASK, ISCSI_STATUS_STRINGS_OPERATIONAL, iscsi_status_to_rc(), len, iscsi_bhs::login_response, rc, iscsi_session::rx_bhs, iscsi_session::rx_buffer, iscsi_session::rx_len, iscsi_session::status, iscsi_bhs_login_response::status_class, iscsi_bhs_login_response::status_detail, strerror(), and xfer_window_changed().

Referenced by iscsi_rx_data().

◆ iscsi_tx_pause()

static void iscsi_tx_pause ( struct iscsi_session iscsi)
static

Pause TX engine.

Parameters
iscsiiSCSI session

Definition at line 1417 of file iscsi.c.

1417  {
1418  process_del ( &iscsi->process );
1419 }
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct process process
TX process.
Definition: iscsi.h:644

References iscsi_session::process, and process_del().

Referenced by iscsi_tx_done(), and iscsi_tx_step().

◆ iscsi_tx_resume()

static void iscsi_tx_resume ( struct iscsi_session iscsi)
static

Resume TX engine.

Parameters
iscsiiSCSI session

Definition at line 1426 of file iscsi.c.

1426  {
1427  process_add ( &iscsi->process );
1428 }
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct process process
TX process.
Definition: iscsi.h:644

References iscsi_session::process, and process_add().

Referenced by iscsi_start_tx().

◆ iscsi_tx_nothing()

static int iscsi_tx_nothing ( struct iscsi_session *iscsi  __unused)
static

Transmit nothing.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1458 of file iscsi.c.

1458  {
1459  return 0;
1460 }

Referenced by iscsi_tx_step().

◆ iscsi_tx_bhs()

static int iscsi_tx_bhs ( struct iscsi_session iscsi)
static

Transmit basic header segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1468 of file iscsi.c.

1468  {
1469  return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1470  sizeof ( iscsi->tx_bhs ) );
1471 }
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition: xfer.c:288
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640

References iscsi_session::socket, iscsi_session::tx_bhs, and xfer_deliver_raw().

Referenced by iscsi_tx_step().

◆ iscsi_tx_data()

static int iscsi_tx_data ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Handle transmission of part of a PDU data segment. iscsi::tx_bhs will be valid when this is called.

Definition at line 1482 of file iscsi.c.

1482  {
1483  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1484 
1485  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1486  case ISCSI_OPCODE_DATA_OUT:
1487  return iscsi_tx_data_out ( iscsi );
1489  return iscsi_tx_login_request ( iscsi );
1490  default:
1491  /* Nothing to send in other states */
1492  return 0;
1493  }
1494 }
struct iscsi_bhs_common common
Definition: iscsi.h:506
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition: iscsi.c:581
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:96
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:173
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
Definition: iscsi.c:829
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
iSCSI basic header segment common fields
Definition: iscsi.h:78
struct ib_cm_common common
Definition: ib_mad.h:11
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:434

References iscsi_bhs::common, common, ISCSI_OPCODE_DATA_OUT, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_OPCODE_MASK, iscsi_tx_data_out(), iscsi_tx_login_request(), and iscsi_session::tx_bhs.

Referenced by iscsi_tx_step().

◆ iscsi_tx_done()

static void iscsi_tx_done ( struct iscsi_session iscsi)
static

Complete iSCSI PDU transmission.

Parameters
iscsiiSCSI session

Called when a PDU has been completely transmitted and the TX state machine is about to enter the idle state. iscsi::tx_bhs will be valid for the just-completed PDU when this is called.

Definition at line 1505 of file iscsi.c.

1505  {
1506  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1507 
1508  /* Stop transmission process */
1509  iscsi_tx_pause ( iscsi );
1510 
1511  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1512  case ISCSI_OPCODE_DATA_OUT:
1513  iscsi_data_out_done ( iscsi );
1514  break;
1516  iscsi_login_request_done ( iscsi );
1517  break;
1518  default:
1519  /* No action */
1520  break;
1521  }
1522 }
struct iscsi_bhs_common common
Definition: iscsi.h:506
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:96
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:173
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition: iscsi.c:1417
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition: iscsi.c:565
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
iSCSI basic header segment common fields
Definition: iscsi.h:78
struct ib_cm_common common
Definition: ib_mad.h:11
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
Definition: iscsi.c:812
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:434

References iscsi_bhs::common, common, iscsi_data_out_done(), iscsi_login_request_done(), ISCSI_OPCODE_DATA_OUT, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_OPCODE_MASK, iscsi_tx_pause(), and iscsi_session::tx_bhs.

Referenced by iscsi_tx_step().

◆ iscsi_tx_step()

static void iscsi_tx_step ( struct iscsi_session iscsi)
static

Transmit iSCSI PDU.

Parameters
iscsiiSCSI session
bufTemporary data buffer
lenLength of temporary data buffer

Constructs data to be sent for the current TX state

Definition at line 1533 of file iscsi.c.

1533  {
1534  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1535  int ( * tx ) ( struct iscsi_session *iscsi );
1536  enum iscsi_tx_state next_state;
1537  size_t tx_len;
1538  int rc;
1539 
1540  /* Select fragment to transmit */
1541  while ( 1 ) {
1542  switch ( iscsi->tx_state ) {
1543  case ISCSI_TX_BHS:
1544  tx = iscsi_tx_bhs;
1545  tx_len = sizeof ( iscsi->tx_bhs );
1546  next_state = ISCSI_TX_AHS;
1547  break;
1548  case ISCSI_TX_AHS:
1549  tx = iscsi_tx_nothing;
1550  tx_len = 0;
1551  next_state = ISCSI_TX_DATA;
1552  break;
1553  case ISCSI_TX_DATA:
1554  tx = iscsi_tx_data;
1555  tx_len = ISCSI_DATA_LEN ( common->lengths );
1556  next_state = ISCSI_TX_IDLE;
1557  break;
1558  case ISCSI_TX_IDLE:
1559  /* Nothing to do; pause processing */
1560  iscsi_tx_pause ( iscsi );
1561  return;
1562  default:
1563  assert ( 0 );
1564  return;
1565  }
1566 
1567  /* Check for window availability, if needed */
1568  if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1569  /* Cannot transmit at this point; pause
1570  * processing and wait for window to reopen
1571  */
1572  iscsi_tx_pause ( iscsi );
1573  return;
1574  }
1575 
1576  /* Transmit data */
1577  if ( ( rc = tx ( iscsi ) ) != 0 ) {
1578  DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1579  iscsi, strerror ( rc ) );
1580  /* Transmission errors are fatal */
1581  iscsi_close ( iscsi, rc );
1582  return;
1583  }
1584 
1585  /* Move to next state */
1586  iscsi->tx_state = next_state;
1587 
1588  /* If we have moved to the idle state, mark
1589  * transmission as complete
1590  */
1591  if ( iscsi->tx_state == ISCSI_TX_IDLE )
1592  iscsi_tx_done ( iscsi );
1593  }
1594 }
iscsi_tx_state
State of an iSCSI TX engine.
Definition: iscsi.h:520
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
Definition: iscsi.c:1505
An iSCSI session.
Definition: iscsi.h:544
struct iscsi_bhs_common common
Definition: iscsi.h:506
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
#define DBGC(...)
Definition: compiler.h:505
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition: iscsi.c:1458
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition: iscsi.c:1468
Nothing to send.
Definition: iscsi.h:522
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
Definition: iscsi.c:1482
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition: iscsi.c:1417
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
iSCSI basic header segment common fields
Definition: iscsi.h:78
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Sending the additional header segment.
Definition: iscsi.h:526
struct ib_cm_common common
Definition: ib_mad.h:11
Sending the data segment.
Definition: iscsi.h:528
Sending the basic header segment.
Definition: iscsi.h:524
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition: wpa.h:237

References assert(), iscsi_bhs::common, common, DBGC, iscsi_close(), ISCSI_DATA_LEN, ISCSI_TX_AHS, ISCSI_TX_BHS, iscsi_tx_bhs(), ISCSI_TX_DATA, iscsi_tx_data(), iscsi_tx_done(), ISCSI_TX_IDLE, iscsi_tx_nothing(), iscsi_tx_pause(), rc, iscsi_session::socket, strerror(), tx, iscsi_session::tx_bhs, iscsi_session::tx_state, and xfer_window().

◆ iscsi_rx_bhs()

static int iscsi_rx_bhs ( struct iscsi_session iscsi,
const void *  data,
size_t  len,
size_t remaining  __unused 
)
static

Receive basic header segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

This fills in iscsi::rx_bhs with the data from the BHS portion of the received PDU.

Definition at line 1612 of file iscsi.c.

1613  {
1614  memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1615  if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1616  DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1617  iscsi, iscsi->rx_bhs.common.opcode,
1618  ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1619  }
1620  return 0;
1621 }
struct iscsi_bhs_common common
Definition: iscsi.h:506
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
Definition: iscsi.h:516
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:86
uint8_t opcode
Opcode.
Definition: iscsi.h:80
#define DBGC2(...)
Definition: compiler.h:522
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647

References iscsi_bhs::bytes, iscsi_bhs::common, data, DBGC2, ISCSI_DATA_LEN, len, iscsi_bhs_common::lengths, memcpy(), iscsi_bhs_common::opcode, iscsi_session::rx_bhs, and iscsi_session::rx_offset.

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_discard()

static int iscsi_rx_discard ( struct iscsi_session *iscsi  __unused,
const void *data  __unused,
size_t len  __unused,
size_t remaining  __unused 
)
static

Discard portion of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

This discards data from a portion of a received PDU.

Definition at line 1634 of file iscsi.c.

1636  {
1637  /* Do nothing */
1638  return 0;
1639 }

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_data()

static int iscsi_rx_data ( struct iscsi_session iscsi,
const void *  data,
size_t  len,
size_t  remaining 
)
static

Receive data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Handle processing of part of a PDU data segment. iscsi::rx_bhs will be valid when this is called.

Definition at line 1653 of file iscsi.c.

1654  {
1655  struct iscsi_bhs_common_response *response
1656  = &iscsi->rx_bhs.common_response;
1657 
1658  /* Update cmdsn and statsn */
1659  iscsi->cmdsn = ntohl ( response->expcmdsn );
1660  iscsi->statsn = ntohl ( response->statsn );
1661 
1662  switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1664  return iscsi_rx_login_response ( iscsi, data, len, remaining );
1666  return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1667  case ISCSI_OPCODE_DATA_IN:
1668  return iscsi_rx_data_in ( iscsi, data, len, remaining );
1669  case ISCSI_OPCODE_R2T:
1670  return iscsi_rx_r2t ( iscsi, data, len, remaining );
1671  case ISCSI_OPCODE_NOP_IN:
1672  return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1673  default:
1674  if ( remaining )
1675  return 0;
1676  DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1677  response->opcode );
1678  return -ENOTSUP_OPCODE;
1679  }
1680 }
uint32_t expcmdsn
Expected command sequence number.
Definition: iscsi.h:132
uint8_t opcode
Opcode.
Definition: iscsi.h:116
struct iscsi_bhs_common_response common_response
Definition: iscsi.h:507
#define DBGC(...)
Definition: compiler.h:505
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
Definition: iscsi.h:336
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.
Definition: iscsi.c:416
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:96
#define ntohl(value)
Definition: byteswap.h:134
uint32_t statsn
Status sequence number.
Definition: iscsi.h:130
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.
Definition: iscsi.c:1319
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
Definition: iscsi.h:386
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.
Definition: iscsi.c:506
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
ring len
Length.
Definition: dwmac.h:231
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
Definition: iscsi.h:500
iSCSI basic header segment common request fields
Definition: iscsi.h:114
#define ISCSI_OPCODE_R2T
R2T opcode.
Definition: iscsi.h:470
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.
Definition: iscsi.c:616
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.
Definition: iscsi.c:469
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:629
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
Definition: iscsi.h:243
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
#define ENOTSUP_OPCODE
Definition: iscsi.c:105

References iscsi_session::cmdsn, iscsi_bhs::common_response, data, DBGC, ENOTSUP_OPCODE, iscsi_bhs_common_response::expcmdsn, ISCSI_OPCODE_DATA_IN, ISCSI_OPCODE_LOGIN_RESPONSE, ISCSI_OPCODE_MASK, ISCSI_OPCODE_NOP_IN, ISCSI_OPCODE_R2T, ISCSI_OPCODE_SCSI_RESPONSE, iscsi_rx_data_in(), iscsi_rx_login_response(), iscsi_rx_nop_in(), iscsi_rx_r2t(), iscsi_rx_scsi_response(), len, ntohl, iscsi_bhs_common_response::opcode, iscsi_session::rx_bhs, iscsi_bhs_common_response::statsn, and iscsi_session::statsn.

Referenced by iscsi_socket_deliver().

◆ iscsi_socket_deliver()

static int iscsi_socket_deliver ( struct iscsi_session iscsi,
struct io_buffer iobuf,
struct xfer_metadata *meta  __unused 
)
static

Receive new data.

Parameters
iscsiiSCSI session
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

This handles received PDUs. The receive strategy is to fill in iscsi::rx_bhs with the contents of the BHS portion of the PDU, throw away any AHS portion, and then process each part of the data portion as it arrives. The data processing routine therefore always has a full copy of the BHS available, even for portions of the data in different packets to the BHS.

Definition at line 1697 of file iscsi.c.

1699  {
1700  struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1701  int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1702  size_t len, size_t remaining );
1703  enum iscsi_rx_state next_state;
1704  size_t frag_len;
1705  size_t remaining;
1706  int rc;
1707 
1708  while ( 1 ) {
1709  switch ( iscsi->rx_state ) {
1710  case ISCSI_RX_BHS:
1711  rx = iscsi_rx_bhs;
1712  iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1713  next_state = ISCSI_RX_AHS;
1714  break;
1715  case ISCSI_RX_AHS:
1716  rx = iscsi_rx_discard;
1717  iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1718  next_state = ISCSI_RX_DATA;
1719  break;
1720  case ISCSI_RX_DATA:
1721  rx = iscsi_rx_data;
1722  iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1723  next_state = ISCSI_RX_DATA_PADDING;
1724  break;
1725  case ISCSI_RX_DATA_PADDING:
1726  rx = iscsi_rx_discard;
1727  iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1728  next_state = ISCSI_RX_BHS;
1729  break;
1730  default:
1731  assert ( 0 );
1732  rc = -EINVAL;
1733  goto done;
1734  }
1735 
1736  frag_len = iscsi->rx_len - iscsi->rx_offset;
1737  if ( frag_len > iob_len ( iobuf ) )
1738  frag_len = iob_len ( iobuf );
1739  remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1740  if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1741  remaining ) ) != 0 ) {
1742  DBGC ( iscsi, "iSCSI %p could not process received "
1743  "data: %s\n", iscsi, strerror ( rc ) );
1744  goto done;
1745  }
1746 
1747  iscsi->rx_offset += frag_len;
1748  iob_pull ( iobuf, frag_len );
1749 
1750  /* If all the data for this state has not yet been
1751  * received, stay in this state for now.
1752  */
1753  if ( iscsi->rx_offset != iscsi->rx_len ) {
1754  rc = 0;
1755  goto done;
1756  }
1757 
1758  iscsi->rx_state = next_state;
1759  iscsi->rx_offset = 0;
1760  }
1761 
1762  done:
1763  /* Free I/O buffer */
1764  free_iob ( iobuf );
1765 
1766  /* Destroy session on error */
1767  if ( rc != 0 )
1768  iscsi_close ( iscsi, rc );
1769 
1770  return rc;
1771 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
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.
Definition: iscsi.c:1612
An iSCSI session.
Definition: iscsi.h:544
struct iscsi_bhs_common common
Definition: iscsi.h:506
Receiving the data segment.
Definition: iscsi.h:538
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
#define DBGC(...)
Definition: compiler.h:505
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.
Definition: iscsi.c:1653
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:653
iscsi_rx_state
State of an iSCSI RX engine.
Definition: iscsi.h:532
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Receiving the data segment padding.
Definition: iscsi.h:540
ring len
Length.
Definition: dwmac.h:231
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
Receiving the additional header segment.
Definition: iscsi.h:536
iSCSI basic header segment common fields
Definition: iscsi.h:78
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
enum iscsi_rx_state rx_state
State of the RX engine.
Definition: iscsi.h:649
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
Definition: iscsi.h:57
struct ib_cm_common common
Definition: ib_mad.h:11
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.
Definition: iscsi.c:1634
void * data
Start of data.
Definition: iobuf.h:52
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
Receiving the basic header segment.
Definition: iscsi.h:534
struct bofm_section_header done
Definition: bofm_test.c:46

References assert(), iscsi_bhs::common, common, data, io_buffer::data, DBGC, done, EINVAL, free_iob(), iob_len(), iob_pull, ISCSI_AHS_LEN, iscsi_close(), ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, ISCSI_RX_AHS, ISCSI_RX_BHS, iscsi_rx_bhs(), ISCSI_RX_DATA, iscsi_rx_data(), ISCSI_RX_DATA_PADDING, iscsi_rx_discard(), len, rc, rx, iscsi_session::rx_bhs, iscsi_session::rx_len, iscsi_session::rx_offset, iscsi_session::rx_state, and strerror().

◆ iscsi_vredirect()

static int iscsi_vredirect ( struct iscsi_session iscsi,
int  type,
va_list  args 
)
static

Handle redirection event.

Parameters
iscsiiSCSI session
typeLocation type
argsRemaining arguments depend upon location type
Return values
rcReturn status code

Definition at line 1781 of file iscsi.c.

1782  {
1783  va_list tmp;
1784  struct sockaddr *peer;
1785  int rc;
1786 
1787  /* Intercept redirects to a LOCATION_SOCKET and record the IP
1788  * address for the iBFT. This is a bit of a hack, but avoids
1789  * inventing an ioctl()-style call to retrieve the socket
1790  * address from a data-xfer interface.
1791  */
1792  if ( type == LOCATION_SOCKET ) {
1793  va_copy ( tmp, args );
1794  ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1795  peer = va_arg ( tmp, struct sockaddr * );
1796  memcpy ( &iscsi->target_sockaddr, peer,
1797  sizeof ( iscsi->target_sockaddr ) );
1798  va_end ( tmp );
1799  }
1800 
1801  /* Redirect to new location */
1802  if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1803  goto err;
1804 
1805  return 0;
1806 
1807  err:
1808  iscsi_close ( iscsi, rc );
1809  return rc;
1810 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define va_end(ap)
Definition: stdarg.h:9
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
Definition: iscsi.h:661
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
uint32_t type
Operating system type.
Definition: ena.h:12
#define va_copy(dest, src)
Definition: stdarg.h:10
unsigned long tmp
Definition: linux_pci.h:64
Location is a socket.
Definition: open.h:43
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define va_arg(ap, type)
Definition: stdarg.h:8
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
Generalized socket address structure.
Definition: socket.h:96
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:224
__builtin_va_list va_list
Definition: stdarg.h:6
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12

References iscsi_close(), LOCATION_SOCKET, memcpy(), peer, rc, iscsi_session::socket, iscsi_session::target_sockaddr, tmp, type, va_arg, va_copy, va_end, and xfer_vreopen().

◆ iscsi_scsi_window()

static size_t iscsi_scsi_window ( struct iscsi_session iscsi)
static

Check iSCSI flow-control window.

Parameters
iscsiiSCSI session
Return values
lenLength of window

Definition at line 1837 of file iscsi.c.

1837  {
1838 
1839  if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1841  ( iscsi->command == NULL ) ) {
1842  /* We cannot handle concurrent commands */
1843  return 1;
1844  } else {
1845  return 0;
1846  }
1847 }
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition: iscsi.h:681
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:684
int status
Session status.
Definition: iscsi.h:569
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References iscsi_session::command, ISCSI_STATUS_FULL_FEATURE_PHASE, ISCSI_STATUS_PHASE_MASK, NULL, and iscsi_session::status.

Referenced by iscsi_scsi_command().

◆ iscsi_scsi_command()

static int iscsi_scsi_command ( struct iscsi_session iscsi,
struct interface parent,
struct scsi_cmd command 
)
static

Issue iSCSI SCSI command.

Parameters
iscsiiSCSI session
parentParent interface
commandSCSI command
Return values
tagCommand tag, or negative error

Definition at line 1857 of file iscsi.c.

1859  {
1860 
1861  /* This iSCSI implementation cannot handle multiple concurrent
1862  * commands or commands arriving before login is complete.
1863  */
1864  if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1865  DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1866  iscsi );
1867  return -EOPNOTSUPP;
1868  }
1869 
1870  /* Store command */
1871  iscsi->command = malloc ( sizeof ( *command ) );
1872  if ( ! iscsi->command )
1873  return -ENOMEM;
1874  memcpy ( iscsi->command, command, sizeof ( *command ) );
1875 
1876  /* Assign new ITT */
1877  iscsi_new_itt ( iscsi );
1878 
1879  /* Start sending command */
1880  iscsi_start_command ( iscsi );
1881 
1882  /* Attach to parent interface and return */
1883  intf_plug_plug ( &iscsi->data, parent );
1884  return iscsi->itt;
1885 }
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition: iscsi.c:244
A command-line command.
Definition: command.h:9
#define DBGC(...)
Definition: compiler.h:505
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
#define EOPNOTSUPP
Operation not supported on socket.
Definition: errno.h:604
struct interface data
SCSI command interface.
Definition: iscsi.h:551
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition: iscsi.c:376
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1837

References iscsi_session::command, iscsi_session::data, DBGC, ENOMEM, EOPNOTSUPP, intf_plug_plug(), iscsi_new_itt(), iscsi_scsi_window(), iscsi_start_command(), iscsi_session::itt, malloc(), and memcpy().

◆ iscsi_scsi_capacity()

static void iscsi_scsi_capacity ( struct iscsi_session iscsi,
struct block_device_capacity capacity 
)
static

Update SCSI block device capacity.

Parameters
iscsiiSCSI session
capacityBlock device capacity

Definition at line 1893 of file iscsi.c.

1894  {
1895  unsigned int max_count;
1896 
1897  /* Limit maximum number of blocks per transfer to fit MaxBurstLength */
1898  if ( capacity->blksize ) {
1899  max_count = ( iscsi->max_burst_len / capacity->blksize );
1900  if ( max_count < capacity->max_count )
1901  capacity->max_count = max_count;
1902  }
1903 }
unsigned int max_count
Maximum number of blocks per single transfer.
Definition: blockdev.h:23
size_t max_burst_len
Maximum burst length.
Definition: iscsi.h:590
size_t blksize
Block size.
Definition: blockdev.h:21

References block_device_capacity::blksize, iscsi_session::max_burst_len, and block_device_capacity::max_count.

◆ iscsi_describe()

static struct acpi_descriptor* iscsi_describe ( struct iscsi_session iscsi)
static

Get iSCSI ACPI descriptor.

Parameters
iscsiiSCSI session
Return values
descACPI descriptor

Definition at line 1911 of file iscsi.c.

1911  {
1912 
1913  return &iscsi->desc;
1914 }
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:665

References iscsi_session::desc.

◆ iscsi_command_close()

static void iscsi_command_close ( struct iscsi_session iscsi,
int  rc 
)
static

Close iSCSI command.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 1936 of file iscsi.c.

1936  {
1937 
1938  /* Restart interface */
1939  intf_restart ( &iscsi->data, rc );
1940 
1941  /* Treat unsolicited command closures mid-command as fatal,
1942  * because we have no code to handle partially-completed PDUs.
1943  */
1944  if ( iscsi->command != NULL )
1945  iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1946 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
#define ECANCELED
Operation canceled.
Definition: errno.h:343
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
struct interface data
SCSI command interface.
Definition: iscsi.h:551
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References iscsi_session::command, iscsi_session::data, ECANCELED, intf_restart(), iscsi_close(), NULL, and rc.

◆ __setting() [1/2]

const struct setting initiator_iqn_setting __setting ( SETTING_SANBOOT_EXTRA  ,
initiator-  iqn 
)

iSCSI initiator IQN setting

◆ __setting() [2/2]

const struct setting reverse_password_setting __setting ( SETTING_AUTH_EXTRA  ,
reverse-  username 
)
Initial value:
= {
.name = "reverse-password",
.description = "Reverse password",
.type = &setting_type_string,
}
#define DHCP_EB_REVERSE_PASSWORD
Reverse password.
Definition: dhcp.h:514

iSCSI reverse username setting

iSCSI reverse password setting

◆ iscsi_parse_root_path()

static int iscsi_parse_root_path ( struct iscsi_session iscsi,
const char *  root_path 
)
static

Parse iSCSI root path.

Parameters
iscsiiSCSI session
root_pathiSCSI root path (as per RFC4173)
Return values
rcReturn status code

Definition at line 2007 of file iscsi.c.

2008  {
2009  char *rp_copy;
2010  char *rp_comp[NUM_RP_COMPONENTS];
2011  char *rp;
2012  int skip = 0;
2013  int i = 0;
2014  int rc;
2015 
2016  /* Create modifiable copy of root path */
2017  rp_copy = strdup ( root_path );
2018  if ( ! rp_copy ) {
2019  rc = -ENOMEM;
2020  goto err_strdup;
2021  }
2022  rp = rp_copy;
2023 
2024  /* Split root path into component parts */
2025  while ( 1 ) {
2026  rp_comp[i++] = rp;
2027  if ( i == NUM_RP_COMPONENTS )
2028  break;
2029  for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
2030  if ( ! *rp ) {
2031  DBGC ( iscsi, "iSCSI %p root path \"%s\" "
2032  "too short\n", iscsi, root_path );
2034  goto err_split;
2035  } else if ( *rp == '[' ) {
2036  skip = 1;
2037  } else if ( *rp == ']' ) {
2038  skip = 0;
2039  }
2040  }
2041  *(rp++) = '\0';
2042  }
2043 
2044  /* Use root path components to configure iSCSI session */
2045  iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
2046  if ( ! iscsi->target_address ) {
2047  rc = -ENOMEM;
2048  goto err_servername;
2049  }
2050  iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
2051  if ( ! iscsi->target_port )
2052  iscsi->target_port = ISCSI_PORT;
2053  if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
2054  DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
2055  iscsi, rp_comp[RP_LUN] );
2056  goto err_lun;
2057  }
2058  iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2059  if ( ! iscsi->target_iqn ) {
2060  rc = -ENOMEM;
2061  goto err_targetname;
2062  }
2063 
2064  err_targetname:
2065  err_lun:
2066  err_servername:
2067  err_split:
2068  free ( rp_copy );
2069  err_strdup:
2070  return rc;
2071 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
#define DBGC(...)
Definition: compiler.h:505
Definition: iscsi.c:1968
unsigned int target_port
Target port.
Definition: iscsi.h:560
#define ENOMEM
Not enough space.
Definition: errno.h:534
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition: scsi.c:117
#define ISCSI_PORT
Default iSCSI port.
Definition: iscsi.h:23
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: iscsi.h:663
char * strdup(const char *src)
Duplicate string.
Definition: string.c:393
char * target_address
Target address.
Definition: iscsi.h:558
#define EINVAL_ROOT_PATH_TOO_SHORT
Definition: iscsi.c:69
char * target_iqn
Target IQN.
Definition: iscsi.h:562
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References DBGC, EINVAL_ROOT_PATH_TOO_SHORT, ENOMEM, free, ISCSI_PORT, iscsi_session::lun, NULL, NUM_RP_COMPONENTS, rc, RP_LUN, RP_PORT, RP_SERVERNAME, RP_TARGETNAME, scsi_parse_lun(), strdup(), strtoul(), iscsi_session::target_address, iscsi_session::target_iqn, and iscsi_session::target_port.

Referenced by iscsi_open().

◆ iscsi_fetch_settings()

static int iscsi_fetch_settings ( struct iscsi_session iscsi)
static

Fetch iSCSI settings.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2079 of file iscsi.c.

2079  {
2080  char *hostname;
2081  union uuid uuid;
2082  int len;
2083 
2084  /* Fetch relevant settings. Don't worry about freeing on
2085  * error, since iscsi_free() will take care of that anyway.
2086  */
2087  fetch_string_setting_copy ( NULL, &username_setting,
2088  &iscsi->initiator_username );
2089  fetch_string_setting_copy ( NULL, &password_setting,
2090  &iscsi->initiator_password );
2091  fetch_string_setting_copy ( NULL, &reverse_username_setting,
2092  &iscsi->target_username );
2093  fetch_string_setting_copy ( NULL, &reverse_password_setting,
2094  &iscsi->target_password );
2095 
2096  /* Use explicit initiator IQN if provided */
2097  fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2098  &iscsi->initiator_iqn );
2099  if ( iscsi->initiator_iqn )
2100  return 0;
2101 
2102  /* Otherwise, try to construct an initiator IQN from the hostname */
2103  fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2104  if ( hostname ) {
2105  len = asprintf ( &iscsi->initiator_iqn,
2106  ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2107  free ( hostname );
2108  if ( len < 0 ) {
2109  DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2110  "IQN\n", iscsi );
2111  return -ENOMEM;
2112  }
2113  assert ( iscsi->initiator_iqn );
2114  return 0;
2115  }
2116 
2117  /* Otherwise, try to construct an initiator IQN from the UUID */
2118  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2119  DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2120  iscsi );
2121  return -EINVAL_NO_INITIATOR_IQN;
2122  }
2123  if ( ( len = asprintf ( &iscsi->initiator_iqn,
2125  uuid_ntoa ( &uuid ) ) ) < 0 ) {
2126  DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2127  iscsi );
2128  return -ENOMEM;
2129  }
2130  assert ( iscsi->initiator_iqn );
2131 
2132  return 0;
2133 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:572
A universally unique ID.
Definition: uuid.h:15
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:873
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EINVAL_NO_INITIATOR_IQN
Definition: iscsi.c:85
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:45
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1084
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:556
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
Definition: iscsi.h:714
char * target_password
Target password (if any)
Definition: iscsi.h:578
char * target_username
Target username (if any)
Definition: iscsi.h:576
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

References asprintf(), assert(), DBGC, EINVAL_NO_INITIATOR_IQN, ENOMEM, fetch_string_setting_copy(), fetch_uuid_setting(), free, iscsi_session::initiator_iqn, iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_DEFAULT_IQN_PREFIX, len, NULL, iscsi_session::target_password, iscsi_session::target_username, and uuid_ntoa().

Referenced by iscsi_open().

◆ iscsi_check_auth()

static int iscsi_check_auth ( struct iscsi_session iscsi)
static

Check iSCSI authentication details.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2142 of file iscsi.c.

2142  {
2143 
2144  /* Check for invalid authentication combinations */
2145  if ( ( /* Initiator username without password (or vice-versa) */
2146  ( !! iscsi->initiator_username ) ^
2147  ( !! iscsi->initiator_password ) ) ||
2148  ( /* Target username without password (or vice-versa) */
2149  ( !! iscsi->target_username ) ^
2150  ( !! iscsi->target_password ) ) ||
2151  ( /* Target (reverse) without initiator (forward) */
2152  ( iscsi->target_username &&
2153  ( ! iscsi->initiator_username ) ) ) ) {
2154  DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2155  "%sname,%spw, target %sname,%spw\n", iscsi,
2156  ( iscsi->initiator_username ? "" : "no " ),
2157  ( iscsi->initiator_password ? "" : "no " ),
2158  ( iscsi->target_username ? "" : "no " ),
2159  ( iscsi->target_password ? "" : "no " ) );
2160  return -EINVAL_BAD_CREDENTIAL_MIX;
2161  }
2162 
2163  return 0;
2164 }
#define EINVAL_BAD_CREDENTIAL_MIX
Definition: iscsi.c:73
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:572
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
char * target_password
Target password (if any)
Definition: iscsi.h:578
char * target_username
Target username (if any)
Definition: iscsi.h:576

References DBGC, EINVAL_BAD_CREDENTIAL_MIX, iscsi_session::initiator_password, iscsi_session::initiator_username, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by iscsi_open().

◆ iscsi_open()

static int iscsi_open ( struct interface parent,
struct uri uri 
)
static

Open iSCSI URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 2173 of file iscsi.c.

2173  {
2174  struct iscsi_session *iscsi;
2175  int rc;
2176 
2177  /* Sanity check */
2178  if ( ! uri->opaque ) {
2180  goto err_sanity_uri;
2181  }
2182 
2183  /* Allocate and initialise structure */
2184  iscsi = zalloc ( sizeof ( *iscsi ) );
2185  if ( ! iscsi ) {
2186  rc = -ENOMEM;
2187  goto err_zalloc;
2188  }
2189  ref_init ( &iscsi->refcnt, iscsi_free );
2190  intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2191  intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2192  intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2194  &iscsi->refcnt );
2195  acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2196 
2197  /* Parse root path */
2198  if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2199  goto err_parse_root_path;
2200  /* Set fields not specified by root path */
2201  if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2202  goto err_fetch_settings;
2203  /* Validate authentication */
2204  if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2205  goto err_check_auth;
2206 
2207  /* Sanity checks */
2208  if ( ! iscsi->target_address ) {
2209  DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2210  iscsi );
2211  rc = -ENOTSUP_DISCOVERY;
2212  goto err_sanity_address;
2213  }
2214  if ( ! iscsi->target_iqn ) {
2215  DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2216  iscsi, uri->opaque );
2218  goto err_sanity_iqn;
2219  }
2220  DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2221  DBGC ( iscsi, "iSCSI %p target %s %s\n",
2222  iscsi, iscsi->target_address, iscsi->target_iqn );
2223 
2224  /* Open socket */
2225  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2226  goto err_open_connection;
2227 
2228  /* Attach SCSI device to parent interface */
2229  if ( ( rc = scsi_open ( parent, &iscsi->control,
2230  &iscsi->lun ) ) != 0 ) {
2231  DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2232  iscsi, strerror ( rc ) );
2233  goto err_scsi_open;
2234  }
2235 
2236  /* Mortalise self, and return */
2237  ref_put ( &iscsi->refcnt );
2238  return 0;
2239 
2240  err_scsi_open:
2241  err_open_connection:
2242  err_sanity_iqn:
2243  err_sanity_address:
2244  err_check_auth:
2245  err_fetch_settings:
2246  err_parse_root_path:
2247  iscsi_close ( iscsi, rc );
2248  ref_put ( &iscsi->refcnt );
2249  err_zalloc:
2250  err_sanity_uri:
2251  return rc;
2252 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTSUP_DISCOVERY
Definition: iscsi.c:109
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition: iscsi.c:2079
An iSCSI session.
Definition: iscsi.h:544
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition: iscsi.c:2007
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
#define DBGC(...)
Definition: compiler.h:505
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition: scsi.c:984
#define EINVAL_NO_TARGET_IQN
Definition: iscsi.c:81
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:549
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:665
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition: iscsi.c:1927
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition: iscsi.c:1597
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: iscsi.h:663
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
struct process process
TX process.
Definition: iscsi.h:644
char * target_address
Target address.
Definition: iscsi.h:558
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition: iscsi.c:2142
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct interface data
SCSI command interface.
Definition: iscsi.h:551
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition: iscsi.c:200
char * target_iqn
Target IQN.
Definition: iscsi.h:562
const char * opaque
Opaque part.
Definition: uri.h:70
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition: iscsi.c:256
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition: iscsi.c:1822
A Uniform Resource Identifier.
Definition: uri.h:64
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:556
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition: acpi.h:311
#define EINVAL_NO_ROOT_PATH
Definition: iscsi.c:77
struct refcnt refcnt
Reference counter.
Definition: iscsi.h:546
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition: iscsi.c:1954

References acpi_init(), iscsi_session::control, iscsi_session::data, DBGC, iscsi_session::desc, EINVAL_NO_ROOT_PATH, EINVAL_NO_TARGET_IQN, ENOMEM, ENOTSUP_DISCOVERY, iscsi_session::initiator_iqn, intf_init(), iscsi_check_auth(), iscsi_close(), iscsi_control_desc, iscsi_data_desc, iscsi_fetch_settings(), iscsi_free(), iscsi_open_connection(), iscsi_parse_root_path(), iscsi_process_desc, iscsi_socket_desc, iscsi_session::lun, uri::opaque, iscsi_session::process, process_init_stopped(), rc, ref_init, ref_put, iscsi_session::refcnt, scsi_open(), iscsi_session::socket, strerror(), iscsi_session::target_address, iscsi_session::target_iqn, and zalloc().

Variable Documentation

◆ iscsi_string_types

struct iscsi_string_type iscsi_string_types[]
static
Initial value:
= {
{ "TargetAddress", iscsi_handle_targetaddress_value },
{ "MaxBurstLength", iscsi_handle_maxburstlength_value },
{ "AuthMethod", iscsi_handle_authmethod_value },
{ NULL, NULL }
}
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition: iscsi.c:954
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition: iscsi.c:1018
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition: iscsi.c:1073
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition: iscsi.c:908
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition: iscsi.c:1102
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition: iscsi.c:878
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition: iscsi.c:977
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition: iscsi.c:929
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

iSCSI text strings that we want to handle

Definition at line 1185 of file iscsi.c.

Referenced by iscsi_handle_string().

◆ iscsi_process_desc

struct process_descriptor iscsi_process_desc
static
Initial value:
=
A process.
Definition: process.h:17
An iSCSI session.
Definition: iscsi.h:544
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82
static void iscsi_tx_step(struct iscsi_session *iscsi)
Transmit iSCSI PDU.
Definition: iscsi.c:1533

iSCSI TX process descriptor

Definition at line 1597 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_socket_operations

struct interface_operation iscsi_socket_operations[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition: xfer.c:62
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition: iscsi.c:1781
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static int iscsi_socket_deliver(struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
Definition: iscsi.c:1697
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1426

iSCSI socket interface operations

Definition at line 1813 of file iscsi.c.

◆ iscsi_socket_desc

struct interface_descriptor iscsi_socket_desc
static
Initial value:
=
An iSCSI session.
Definition: iscsi.h:544
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
static struct interface_operation iscsi_socket_operations[]
iSCSI socket interface operations
Definition: iscsi.c:1813
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80

iSCSI socket interface descriptor

Definition at line 1822 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_control_op

struct interface_operation iscsi_control_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:129
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
A SCSI command.
Definition: scsi.c:262
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition: iscsi.c:1893
#define EFI_INTF_OP
Definition: efi.h:373
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
Definition: iscsi.c:1911
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:320
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition: efi_path.c:505
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:919
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1837
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition: iscsi.c:1857

iSCSI SCSI command-issuing interface operations

Definition at line 1917 of file iscsi.c.

◆ iscsi_control_desc

struct interface_descriptor iscsi_control_desc
static
Initial value:
=
An iSCSI session.
Definition: iscsi.h:544
uint32_t control
Control.
Definition: myson.h:14
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
static struct interface_operation iscsi_control_op[]
iSCSI SCSI command-issuing interface operations
Definition: iscsi.c:1917

iSCSI SCSI command-issuing interface descriptor

Definition at line 1927 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_data_op

struct interface_operation iscsi_data_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition: iscsi.c:1936
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32

iSCSI SCSI command interface operations

Definition at line 1949 of file iscsi.c.

◆ iscsi_data_desc

struct interface_descriptor iscsi_data_desc
static
Initial value:
=
An iSCSI session.
Definition: iscsi.h:544
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
uint8_t data[48]
Additional event data.
Definition: ena.h:22
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Definition: iscsi.c:1949

iSCSI SCSI command interface descriptor

Definition at line 1954 of file iscsi.c.

Referenced by iscsi_open().

◆ __uri_opener

struct uri_opener iscsi_uri_opener __uri_opener
Initial value:
= {
.scheme = "iscsi",
.open = iscsi_open,
}
static int iscsi_open(struct interface *parent, struct uri *uri)
Open iSCSI URI.
Definition: iscsi.c:2173

iSCSI URI opener

Definition at line 2255 of file iscsi.c.