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/uaccess.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/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 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_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 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.

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Definition at line 89 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 91 of file iscsi.c.

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Definition at line 93 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 95 of file iscsi.c.

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 97 of file iscsi.c.

◆ EINFO_ENOTSUP_INITIATOR_STATUS

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

Definition at line 99 of file iscsi.c.

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 101 of file iscsi.c.

◆ EINFO_ENOTSUP_OPCODE

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

Definition at line 103 of file iscsi.c.

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 105 of file iscsi.c.

◆ EINFO_ENOTSUP_DISCOVERY

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

Definition at line 107 of file iscsi.c.

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 109 of file iscsi.c.

◆ EINFO_ENOTSUP_TARGET_STATUS

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

Definition at line 111 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 113 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

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

Definition at line 115 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 117 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

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

Definition at line 119 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Definition at line 121 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 123 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Definition at line 125 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 127 of file iscsi.c.

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Definition at line 129 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 131 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Definition at line 133 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 135 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 137 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 139 of file iscsi.c.

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 141 of file iscsi.c.

◆ EINFO_EPROTO_VALUE_REJECTED

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

Definition at line 143 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 1908 of file iscsi.c.

1908  {
1909  RP_SERVERNAME = 0,
1910  RP_PROTOCOL,
1911  RP_PORT,
1912  RP_LUN,
1913  RP_TARGETNAME,
1915 };
Definition: iscsi.c:1912

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 1401 of file iscsi.c.

1401  {
1402 
1403  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1404 
1405  /* Initialise TX BHS */
1406  memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1407 
1408  /* Flag TX engine to start transmitting */
1409  iscsi->tx_state = ISCSI_TX_BHS;
1410 
1411  /* Start transmission process */
1412  iscsi_tx_resume ( iscsi );
1413 }
Nothing to send.
Definition: iscsi.h:513
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1389
Sending the basic header segment.
Definition: iscsi.h:515
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:630
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 759 of file iscsi.c.

759  {
761  int len;
762 
763  switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
765  DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
766  iscsi );
767  break;
769  DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
770  iscsi );
771  break;
772  default:
773  assert ( 0 );
774  }
775 
776  /* Construct BHS and initiate transmission */
777  iscsi_start_tx ( iscsi );
778  request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
780  request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
782  /* version_max and version_min left as zero */
784  ISCSI_SET_LENGTHS ( request->lengths, 0, len );
785  request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
787  request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
788  /* tsih left as zero */
789  request->itt = htonl ( iscsi->itt );
790  /* cid left as zero */
791  request->cmdsn = htonl ( iscsi->cmdsn );
792  request->expstatsn = htonl ( iscsi->statsn + 1 );
793 }
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:499
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:175
iSCSI login request basic header segment
Definition: iscsi.h:132
#define DBGC(...)
Definition: compiler.h:505
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:164
#define htonl(value)
Definition: byteswap.h:133
uint32_t statsn
Status sequence number.
Definition: iscsi.h:625
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition: iscsi.h:167
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:672
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
Definition: iscsi.h:192
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:591
int status
Session status.
Definition: iscsi.h:560
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
Definition: iscsi.h:174
#define ISCSI_LOGIN_CSG_MASK
Definition: iscsi.h:173
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition: iscsi.h:585
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
Definition: iscsi.h:90
uint32_t len
Length.
Definition: ena.h:14
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:617
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:60
#define ISCSI_ISID_IANA
ISID IANA format marker.
Definition: iscsi.h:185
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition: iscsi.c:684
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#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:1401

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 520 of file iscsi.c.

521  {
522  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
523  unsigned long offset;
524  unsigned long remaining;
525  unsigned long len;
526 
527  /* We always send 512-byte Data-Out PDUs; this removes the
528  * need to worry about the target's MaxRecvDataSegmentLength.
529  */
530  offset = datasn * 512;
531  remaining = iscsi->transfer_len - offset;
532  len = remaining;
533  if ( len > 512 )
534  len = 512;
535 
536  /* Construct BHS and initiate transmission */
537  iscsi_start_tx ( iscsi );
538  data_out->opcode = ISCSI_OPCODE_DATA_OUT;
539  if ( len == remaining )
540  data_out->flags = ( ISCSI_FLAG_FINAL );
541  ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
542  data_out->lun = iscsi->command->lun;
543  data_out->itt = htonl ( iscsi->itt );
544  data_out->ttt = htonl ( iscsi->ttt );
545  data_out->expstatsn = htonl ( iscsi->statsn + 1 );
546  data_out->datasn = htonl ( datasn );
547  data_out->offset = htonl ( iscsi->transfer_offset + offset );
548  DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
549  iscsi, datasn, len );
550 }
uint32_t ttt
Target transfer tag.
Definition: iscsi.h:597
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:403
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:504
#define DBGC(...)
Definition: compiler.h:505
#define htonl(value)
Definition: byteswap.h:133
uint32_t statsn
Status sequence number.
Definition: iscsi.h:625
struct scsi_lun lun
Logical Unit Number.
Definition: iscsi.h:405
uint32_t itt
Initiator task tag.
Definition: iscsi.h:591
uint32_t datasn
Data sequence number.
Definition: iscsi.h:417
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:93
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:409
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
struct scsi_lun lun
LUN.
Definition: scsi.h:251
uint32_t offset
Buffer offset.
Definition: iscsi.h:419
uint8_t flags
Flags.
Definition: iscsi.h:399
uint32_t transfer_offset
Transfer offset.
Definition: iscsi.h:603
iSCSI data-out basic header segment
Definition: iscsi.h:395
uint32_t expstatsn
Expected status sequence number.
Definition: iscsi.h:413
uint32_t transfer_len
Transfer length.
Definition: iscsi.h:609
uint32_t len
Length.
Definition: ena.h:14
uint32_t itt
Initiator Task Tag.
Definition: iscsi.h:407
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition: iscsi.h:60
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:425
uint8_t opcode
Opcode.
Definition: iscsi.h:397
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1401

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 156 of file iscsi.c.

156  {
157  free ( iscsi->rx_buffer );
158  iscsi->rx_buffer = NULL;
159 }
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:643
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 174 of file iscsi.c.

175  {
176 
177  /* Allocate buffer on first call */
178  if ( ! iscsi->rx_buffer ) {
179  iscsi->rx_buffer = malloc ( iscsi->rx_len );
180  if ( ! iscsi->rx_buffer )
181  return -ENOMEM;
182  }
183 
184  /* Copy data to buffer */
185  assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
186  memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
187 
188  return 0;
189 }
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:641
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:643
#define ENOMEM
Not enough space.
Definition: errno.h:534
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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 196 of file iscsi.c.

196  {
197  struct iscsi_session *iscsi =
199 
200  free ( iscsi->initiator_iqn );
201  free ( iscsi->target_address );
202  free ( iscsi->target_iqn );
203  free ( iscsi->initiator_username );
204  free ( iscsi->initiator_password );
205  free ( iscsi->target_username );
206  free ( iscsi->target_password );
207  chap_finish ( &iscsi->chap );
208  iscsi_rx_buffered_data_done ( iscsi );
209  free ( iscsi->command );
210  free ( iscsi );
211 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:563
An iSCSI session.
Definition: iscsi.h:535
A reference counter.
Definition: refcnt.h:26
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:565
#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:156
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:549
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
char * target_iqn
Target IQN.
Definition: iscsi.h:553
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
char * target_password
Target password (if any)
Definition: iscsi.h:569
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
char * target_username
Target username (if any)
Definition: iscsi.h:567

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 219 of file iscsi.c.

219  {
220 
221  /* A TCP graceful close is still an error from our point of view */
222  if ( rc == 0 )
223  rc = -ECONNRESET;
224 
225  DBGC ( iscsi, "iSCSI %p closed: %s\n", iscsi, strerror ( rc ) );
226 
227  /* Stop transmission process */
228  process_del ( &iscsi->process );
229 
230  /* Shut down interfaces */
231  intfs_shutdown ( rc, &iscsi->socket, &iscsi->control, &iscsi->data,
232  NULL );
233 }
#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:544
#define DBGC(...)
Definition: compiler.h:505
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition: interface.c:320
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:540
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct process process
TX process.
Definition: iscsi.h:632
struct interface data
SCSI command interface.
Definition: iscsi.h:542
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 240 of file iscsi.c.

240  {
241  static uint16_t itt_idx;
242 
243  iscsi->itt = ( ISCSI_TAG_MAGIC | (++itt_idx) );
244 }
unsigned short uint16_t
Definition: stdint.h:11
uint32_t itt
Initiator task tag.
Definition: iscsi.h:591
#define ISCSI_TAG_MAGIC
iSCSI tag magic marker
Definition: iscsi.h:96

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 252 of file iscsi.c.

252  {
253  struct sockaddr_tcpip target;
254  int rc;
255 
256  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
257  assert ( iscsi->rx_state == ISCSI_RX_BHS );
258  assert ( iscsi->rx_offset == 0 );
259 
260  /* Open socket */
261  memset ( &target, 0, sizeof ( target ) );
262  target.st_port = htons ( iscsi->target_port );
263  if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
264  ( struct sockaddr * ) &target,
265  iscsi->target_address,
266  NULL ) ) != 0 ) {
267  DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
268  iscsi, strerror ( rc ) );
269  return rc;
270  }
271 
272  /* Enter security negotiation phase */
275  if ( iscsi->target_username )
277 
278  /* Assign new ISID */
279  iscsi->isid_iana_qual = ( random() & 0xffff );
280 
281  /* Assign fresh initiator task tag */
282  iscsi_new_itt ( iscsi );
283 
284  /* Initiate login */
285  iscsi_start_login ( iscsi );
286 
287  return 0;
288 }
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition: iscsi.h:696
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:240
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
#define DBGC(...)
Definition: compiler.h:505
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition: iscsi.c:759
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
Definition: iscsi.h:657
unsigned int target_port
Target port.
Definition: iscsi.h:551
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
Nothing to send.
Definition: iscsi.h:513
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int status
Session status.
Definition: iscsi.h:560
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:637
char * target_address
Target address.
Definition: iscsi.h:549
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:30
#define SOCK_STREAM
Definition: socket.h:24
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition: iscsi.h:585
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition: iscsi.h:675
char * target_username
Target username (if any)
Definition: iscsi.h:567
Receiving the basic header segment.
Definition: iscsi.h:525
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:630
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_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, 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 299 of file iscsi.c.

299  {
300 
301  /* Close all data transfer interfaces */
302  intf_restart ( &iscsi->socket, rc );
303 
304  /* Clear connection status */
305  iscsi->status = 0;
306 
307  /* Reset TX and RX state machines */
308  iscsi->tx_state = ISCSI_TX_IDLE;
309  iscsi->rx_state = ISCSI_RX_BHS;
310  iscsi->rx_offset = 0;
311 
312  /* Free any temporary dynamically allocated memory */
313  chap_finish ( &iscsi->chap );
314  iscsi_rx_buffered_data_done ( iscsi );
315 }
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:337
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
Nothing to send.
Definition: iscsi.h:513
int status
Session status.
Definition: iscsi.h:560
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:156
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:637
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
Receiving the basic header segment.
Definition: iscsi.h:525
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:630

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 331 of file iscsi.c.

332  {
333  uint32_t itt = iscsi->itt;
334 
335  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
336 
337  /* Clear command */
338  free ( iscsi->command );
339  iscsi->command = NULL;
340 
341  /* Send SCSI response, if any */
342  if ( rsp )
343  scsi_response ( &iscsi->data, rsp );
344 
345  /* Close SCSI command, if this is still the same command. (It
346  * is possible that the command interface has already been
347  * closed as a result of the SCSI response we sent.)
348  */
349  if ( iscsi->itt == itt )
350  intf_restart ( &iscsi->data, rc );
351 }
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:337
Nothing to send.
Definition: iscsi.h:513
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:591
uint64_t rsp
Definition: librm.h:267
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
struct interface data
SCSI command interface.
Definition: iscsi.h:542
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:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:630

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 369 of file iscsi.c.

369  {
371 
372  assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
373 
374  /* Construct BHS and initiate transmission */
375  iscsi_start_tx ( iscsi );
377  command->flags = ( ISCSI_FLAG_FINAL |
379  if ( iscsi->command->data_in )
381  if ( iscsi->command->data_out )
383  /* lengths left as zero */
384  memcpy ( &command->lun, &iscsi->command->lun,
385  sizeof ( command->lun ) );
386  command->itt = htonl ( iscsi->itt );
387  command->exp_len = htonl ( iscsi->command->data_in_len |
388  iscsi->command->data_out_len );
389  command->cmdsn = htonl ( iscsi->cmdsn );
390  command->expstatsn = htonl ( iscsi->statsn + 1 );
391  memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
392  DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
393  iscsi, SCSI_CDB_DATA ( command->cdb ),
394  ( iscsi->command->data_in ? "in" : "out" ),
395  ( iscsi->command->data_in ?
396  iscsi->command->data_in_len :
397  iscsi->command->data_out_len ) );
398 }
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition: iscsi.h:282
struct iscsi_bhs_scsi_command scsi_command
Definition: iscsi.h:501
size_t data_out_len
Data-out buffer length.
Definition: scsi.h:260
A command-line command.
Definition: command.h:9
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:267
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
Definition: iscsi.h:279
union scsi_cdb cdb
CDB for this command.
Definition: scsi.h:253
#define htonl(value)
Definition: byteswap.h:133
iSCSI SCSI command basic header segment
Definition: iscsi.h:252
uint32_t statsn
Status sequence number.
Definition: iscsi.h:625
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:591
userptr_t data_out
Data-out buffer (may be NULL)
Definition: scsi.h:255
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:93
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
struct scsi_lun lun
LUN.
Definition: scsi.h:251
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition: scsi.h:223
#define ISCSI_COMMAND_ATTR_SIMPLE
Definition: iscsi.h:286
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition: scsi.h:219
#define DBGC2(...)
Definition: compiler.h:522
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:617
userptr_t data_in
Data-in buffer (may be NULL)
Definition: scsi.h:262
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
Definition: iscsi.h:276
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1401

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 409 of file iscsi.c.

411  {
413  = &iscsi->rx_bhs.scsi_response;
414  struct scsi_rsp rsp;
415  uint32_t residual_count;
416  size_t data_len;
417  int rc;
418 
419  /* Buffer up the PDU data */
420  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
421  DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
422  iscsi, strerror ( rc ) );
423  return rc;
424  }
425  if ( remaining )
426  return 0;
427 
428  /* Parse SCSI response and discard buffer */
429  memset ( &rsp, 0, sizeof ( rsp ) );
430  rsp.status = response->status;
431  residual_count = ntohl ( response->residual_count );
432  if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
433  rsp.overrun = residual_count;
434  } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
435  rsp.overrun = -(residual_count);
436  }
437  data_len = ISCSI_DATA_LEN ( response->lengths );
438  if ( data_len ) {
439  scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
440  &rsp.sense );
441  }
442  iscsi_rx_buffered_data_done ( iscsi );
443 
444  /* Check for errors */
445  if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
446  return -EIO;
447 
448  /* Mark as completed */
449  iscsi_scsi_done ( iscsi, 0, &rsp );
450  return 0;
451 }
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:386
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
Definition: iscsi.h:383
#define DBGC(...)
Definition: compiler.h:505
uint8_t flags
Flags.
Definition: iscsi.h:299
#define ntohl(value)
Definition: byteswap.h:134
uint8_t response
Response code.
Definition: iscsi.h:301
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:643
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
uint8_t status
SCSI status code.
Definition: iscsi.h:303
A SCSI response information unit.
Definition: scsi.h:322
uint64_t rsp
Definition: librm.h:267
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition: iscsi.c:174
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:156
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:305
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition: iscsi.c:331
unsigned int uint32_t
Definition: stdint.h:12
uint32_t len
Length.
Definition: ena.h:14
#define EIO
Input/output error.
Definition: errno.h:433
uint32_t residual_count
Residual count.
Definition: iscsi.h:323
iSCSI SCSI response basic header segment
Definition: iscsi.h:295
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
Definition: iscsi.h:330
struct iscsi_bhs_scsi_response scsi_response
Definition: iscsi.h:502
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
void * memset(void *dest, int character, size_t len) __nonnull

References data, 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 462 of file iscsi.c.

464  {
465  struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
466  unsigned long offset;
467 
468  /* Copy data to data-in buffer */
469  offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
470  assert ( iscsi->command != NULL );
471  assert ( iscsi->command->data_in );
472  assert ( ( offset + len ) <= iscsi->command->data_in_len );
473  copy_to_user ( iscsi->command->data_in, offset, data, len );
474 
475  /* Wait for whole SCSI response to arrive */
476  if ( remaining )
477  return 0;
478 
479  /* Mark as completed if status is present */
480  if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
481  assert ( ( offset + len ) == iscsi->command->data_in_len );
482  assert ( data_in->flags & ISCSI_FLAG_FINAL );
483  /* iSCSI cannot return an error status via a data-in */
484  iscsi_scsi_done ( iscsi, 0, NULL );
485  }
486 
487  return 0;
488 }
iSCSI data-in basic header segment
Definition: iscsi.h:345
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition: iscsi.h:389
uint32_t offset
Buffer offset.
Definition: iscsi.h:371
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:267
#define ntohl(value)
Definition: byteswap.h:134
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:93
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition: iscsi.c:331
uint8_t flags
Flags.
Definition: iscsi.h:349
uint32_t len
Length.
Definition: ena.h:14
userptr_t data_in
Data-in buffer (may be NULL)
Definition: scsi.h:262
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct iscsi_bhs_data_in data_in
Definition: iscsi.h:503

References assert(), iscsi_session::command, copy_to_user(), 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, 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 499 of file iscsi.c.

501  {
502  struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
503 
504  /* Record transfer parameters and trigger first data-out */
505  iscsi->ttt = ntohl ( r2t->ttt );
506  iscsi->transfer_offset = ntohl ( r2t->offset );
507  iscsi->transfer_len = ntohl ( r2t->len );
508  iscsi_start_data_out ( iscsi, 0 );
509 
510  return 0;
511 }
uint32_t ttt
Target transfer tag.
Definition: iscsi.h:597
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition: iscsi.c:520
#define ntohl(value)
Definition: byteswap.h:134
struct iscsi_bhs_r2t r2t
Definition: iscsi.h:505
uint32_t offset
Buffer offset.
Definition: iscsi.h:455
iSCSI request to transfer basic header segment
Definition: iscsi.h:431
uint32_t len
Desired data transfer length.
Definition: iscsi.h:457
uint32_t transfer_offset
Transfer offset.
Definition: iscsi.h:603
uint32_t transfer_len
Transfer length.
Definition: iscsi.h:609
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:445
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635

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 558 of file iscsi.c.

558  {
559  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
560 
561  /* If we haven't reached the end of the sequence, start
562  * sending the next data-out PDU.
563  */
564  if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
565  iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
566 }
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:504
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition: iscsi.c:520
#define ntohl(value)
Definition: byteswap.h:134
uint32_t datasn
Data sequence number.
Definition: iscsi.h:417
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:93
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
uint8_t flags
Flags.
Definition: iscsi.h:399
iSCSI data-out basic header segment
Definition: iscsi.h:395

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 574 of file iscsi.c.

574  {
575  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
576  struct io_buffer *iobuf;
577  unsigned long offset;
578  size_t len;
579  size_t pad_len;
580 
581  offset = ntohl ( data_out->offset );
582  len = ISCSI_DATA_LEN ( data_out->lengths );
583  pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
584 
585  assert ( iscsi->command != NULL );
586  assert ( iscsi->command->data_out );
587  assert ( ( offset + len ) <= iscsi->command->data_out_len );
588 
589  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
590  if ( ! iobuf )
591  return -ENOMEM;
592 
593  copy_from_user ( iob_put ( iobuf, len ),
594  iscsi->command->data_out, offset, len );
595  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
596 
597  return xfer_deliver_iob ( &iscsi->socket, iobuf );
598 }
#define iob_put(iobuf, len)
Definition: iobuf.h:120
size_t data_out_len
Data-out buffer length.
Definition: scsi.h:260
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:403
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:56
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:504
#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:157
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
userptr_t data_out
Data-out buffer (may be NULL)
Definition: scsi.h:255
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
uint32_t offset
Buffer offset.
Definition: iscsi.h:419
iSCSI data-out basic header segment
Definition: iscsi.h:395
uint32_t len
Length.
Definition: ena.h:14
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

References assert(), iscsi_session::command, copy_from_user(), 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, memset(), ntohl, NULL, offset, iscsi_bhs_data_out::offset, 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 609 of file iscsi.c.

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

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 684 of file iscsi.c.

685  {
686  unsigned int used = 0;
687  const char *auth_method;
688 
689  if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
690  /* Default to allowing no authentication */
691  auth_method = "None";
692  /* If we have a credential to supply, permit CHAP */
693  if ( iscsi->initiator_username )
694  auth_method = "CHAP,None";
695  /* If we have a credential to check, force CHAP */
696  if ( iscsi->target_username )
697  auth_method = "CHAP";
698  used += ssnprintf ( data + used, len - used,
699  "InitiatorName=%s%c"
700  "TargetName=%s%c"
701  "SessionType=Normal%c"
702  "AuthMethod=%s%c",
703  iscsi->initiator_iqn, 0,
704  iscsi->target_iqn, 0, 0,
705  auth_method, 0 );
706  }
707 
709  used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
710  }
711 
712  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
713  char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
714  assert ( iscsi->initiator_username != NULL );
715  base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
716  buf, sizeof ( buf ) );
717  used += ssnprintf ( data + used, len - used,
718  "CHAP_N=%s%cCHAP_R=0x%s%c",
719  iscsi->initiator_username, 0, buf, 0 );
720  }
721 
722  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
723  size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
724  char buf[ base16_encoded_len ( challenge_len ) + 1 ];
725  base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
726  buf, sizeof ( buf ) );
727  used += ssnprintf ( data + used, len - used,
728  "CHAP_I=%d%cCHAP_C=0x%s%c",
729  iscsi->chap_challenge[0], 0, buf, 0 );
730  }
731 
732  if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) {
733  used += ssnprintf ( data + used, len - used,
734  "HeaderDigest=None%c"
735  "DataDigest=None%c"
736  "MaxConnections=1%c"
737  "InitialR2T=Yes%c"
738  "ImmediateData=No%c"
739  "MaxRecvDataSegmentLength=8192%c"
740  "MaxBurstLength=262144%c"
741  "FirstBurstLength=65536%c"
742  "DefaultTime2Wait=0%c"
743  "DefaultTime2Retain=0%c"
744  "MaxOutstandingR2T=1%c"
745  "DataPDUInOrder=Yes%c"
746  "DataSequenceInOrder=Yes%c"
747  "ErrorRecoveryLevel=0%c",
748  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
749  }
750 
751  return used;
752 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:563
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:21
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)
int status
Session status.
Definition: iscsi.h:560
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition: iscsi.h:678
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition: iscsi.h:684
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:681
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:576
char * target_iqn
Target IQN.
Definition: iscsi.h:553
uint32_t len
Length.
Definition: ena.h:14
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition: iscsi.h:675
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition: iscsi.h:687
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
char * target_username
Target username (if any)
Definition: iscsi.h:567
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References assert(), base16_encoded_len(), iscsi_session::chap, iscsi_session::chap_challenge, data, iscsi_session::initiator_iqn, iscsi_session::initiator_username, 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 801 of file iscsi.c.

801  {
802 
803  /* Clear any "strings to send" flags */
805 
806  /* Free any dynamically allocated storage used for login */
807  chap_finish ( &iscsi->chap );
808 }
int status
Session status.
Definition: iscsi.h:560
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:690
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578

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 818 of file iscsi.c.

818  {
820  struct io_buffer *iobuf;
821  size_t len;
822  size_t pad_len;
823 
824  len = ISCSI_DATA_LEN ( request->lengths );
825  pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
826  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
827  if ( ! iobuf )
828  return -ENOMEM;
829  iob_put ( iobuf, len );
830  iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
831  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
832 
833  return xfer_deliver_iob ( &iscsi->socket, iobuf );
834 }
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:499
#define iob_put(iobuf, len)
Definition: iobuf.h:120
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:254
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:56
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
iSCSI login request basic header segment
Definition: iscsi.h:132
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:157
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
#define ENOMEM
Not enough space.
Definition: errno.h:534
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
uint32_t len
Length.
Definition: ena.h:14
void * data
Start of data.
Definition: iobuf.h:48
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:684
void * memset(void *dest, int character, size_t len) __nonnull
A persistent I/O buffer.
Definition: iobuf.h:33

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(), 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 844 of file iscsi.c.

845  {
846 
847  /* Check for initial '0x' or '0b' and decode as appropriate */
848  if ( *(encoded++) == '0' ) {
849  switch ( tolower ( *(encoded++) ) ) {
850  case 'x' :
851  return base16_decode ( encoded, raw, len );
852  case 'b' :
853  return base64_decode ( encoded, raw, len );
854  }
855  }
856 
858 }
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition: base64.c:91
static int tolower(int character)
Convert character to lower case.
Definition: ctype.h:97
uint32_t len
Length.
Definition: ena.h:14
__be32 raw[7]
Definition: CIB_PRM.h:28
#define EPROTO_INVALID_LARGE_BINARY
Definition: iscsi.c:129

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 867 of file iscsi.c.

868  {
869  char *separator;
870 
871  DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
872 
873  /* Replace target address */
874  free ( iscsi->target_address );
875  iscsi->target_address = strdup ( value );
876  if ( ! iscsi->target_address )
877  return -ENOMEM;
878 
879  /* Replace target port */
880  iscsi->target_port = htons ( ISCSI_PORT );
881  separator = strchr ( iscsi->target_address, ':' );
882  if ( separator ) {
883  *separator = '\0';
884  iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
885  }
886 
887  return 0;
888 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:456
#define DBGC(...)
Definition: compiler.h:505
unsigned int target_port
Target port.
Definition: iscsi.h:551
#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:256
char * strdup(const char *src)
Duplicate string.
Definition: string.c:365
char * target_address
Target address.
Definition: iscsi.h:549
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#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 897 of file iscsi.c.

898  {
899 
900  /* If server requests CHAP, send the CHAP_A string */
901  if ( strcmp ( value, "CHAP" ) == 0 ) {
902  DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
903  iscsi );
906  }
907 
908  return 0;
909 }
#define DBGC(...)
Definition: compiler.h:505
int status
Session status.
Definition: iscsi.h:560
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition: iscsi.h:678
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:172
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition: iscsi.h:693

References DBGC, ISCSI_STATUS_AUTH_FORWARD_REQUIRED, ISCSI_STATUS_STRINGS_CHAP_ALGORITHM, iscsi_session::status, strcmp(), 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 918 of file iscsi.c.

919  {
920 
921  /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
922  * the server responds with anything else it is a protocol
923  * violation.
924  */
925  if ( strcmp ( value, "5" ) != 0 ) {
926  DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
927  iscsi, value );
929  }
930 
931  return 0;
932 }
#define EPROTO_INVALID_CHAP_ALGORITHM
Definition: iscsi.c:121
#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:172

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 941 of file iscsi.c.

942  {
943  unsigned int identifier;
944  char *endp;
945  int rc;
946 
947  /* The CHAP identifier is an integer value */
948  identifier = strtoul ( value, &endp, 0 );
949  if ( *endp != '\0' ) {
950  DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
951  iscsi, value );
953  }
954 
955  /* Prepare for CHAP with MD5 */
956  chap_finish ( &iscsi->chap );
957  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
958  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
959  iscsi, strerror ( rc ) );
960  return rc;
961  }
962 
963  /* Identifier and secret are the first two components of the
964  * challenge.
965  */
966  chap_set_identifier ( &iscsi->chap, identifier );
967  if ( iscsi->initiator_password ) {
968  chap_update ( &iscsi->chap, iscsi->initiator_password,
969  strlen ( iscsi->initiator_password ) );
970  }
971 
972  return 0;
973 }
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:456
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:565
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition: chap.c:51
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
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:578
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
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:125
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 982 of file iscsi.c.

983  {
984  uint8_t *buf;
985  unsigned int i;
986  int len;
987  int rc;
988 
989  /* Allocate decoding buffer */
990  len = strlen ( value ); /* Decoding never expands data */
991  buf = malloc ( len );
992  if ( ! buf ) {
993  rc = -ENOMEM;
994  goto err_alloc;
995  }
996 
997  /* Process challenge */
999  if ( len < 0 ) {
1000  rc = len;
1001  DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1002  iscsi, value, strerror ( rc ) );
1003  goto err_decode;
1004  }
1005  chap_update ( &iscsi->chap, buf, len );
1006 
1007  /* Build CHAP response */
1008  DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1009  chap_respond ( &iscsi->chap );
1011 
1012  /* Send CHAP challenge, if applicable */
1013  if ( iscsi->target_username ) {
1015  /* Generate CHAP challenge data */
1016  for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1017  iscsi->chap_challenge[i] = random();
1018  }
1019  }
1020 
1021  /* Success */
1022  rc = 0;
1023 
1024  err_decode:
1025  free ( buf );
1026  err_alloc:
1027  return rc;
1028 }
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:844
#define ENOMEM
Not enough space.
Definition: errno.h:534
int status
Session status.
Definition: iscsi.h:560
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
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:30
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
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:684
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition: iscsi.h:681
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:576
uint32_t len
Length.
Definition: ena.h:14
char * target_username
Target username (if any)
Definition: iscsi.h:567
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 1037 of file iscsi.c.

1038  {
1039 
1040  /* The target username isn't actually involved at any point in
1041  * the authentication process; it merely serves to identify
1042  * which password the target is using to generate the CHAP
1043  * response. We unnecessarily verify that the username is as
1044  * expected, in order to provide mildly helpful diagnostics if
1045  * the target is supplying the wrong username/password
1046  * combination.
1047  */
1048  if ( iscsi->target_username &&
1049  ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1050  DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1051  "(wanted \"%s\")\n",
1052  iscsi, value, iscsi->target_username );
1054  }
1055 
1056  return 0;
1057 }
#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:172
char * target_username
Target username (if any)
Definition: iscsi.h:567

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 1066 of file iscsi.c.

1067  {
1068  uint8_t *buf;
1069  int len;
1070  int rc;
1071 
1072  /* Generate CHAP response for verification */
1073  chap_finish ( &iscsi->chap );
1074  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1075  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1076  iscsi, strerror ( rc ) );
1077  goto err_chap_init;
1078  }
1079  chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1080  if ( iscsi->target_password ) {
1081  chap_update ( &iscsi->chap, iscsi->target_password,
1082  strlen ( iscsi->target_password ) );
1083  }
1084  chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1085  ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1086  chap_respond ( &iscsi->chap );
1087 
1088  /* Allocate decoding buffer */
1089  len = strlen ( value ); /* Decoding never expands data */
1090  buf = malloc ( len );
1091  if ( ! buf ) {
1092  rc = -ENOMEM;
1093  goto err_alloc;
1094  }
1095 
1096  /* Process response */
1097  len = iscsi_large_binary_decode ( value, buf, len );
1098  if ( len < 0 ) {
1099  rc = len;
1100  DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1101  iscsi, value, strerror ( rc ) );
1102  goto err_decode;
1103  }
1104 
1105  /* Check CHAP response */
1106  if ( len != ( int ) iscsi->chap.response_len ) {
1107  DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1108  iscsi );
1110  goto err_response_len;
1111  }
1112  if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1113  DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1114  iscsi, value );
1116  goto err_response;
1117  }
1118 
1119  /* Mark session as authenticated */
1121 
1122  err_response:
1123  err_response_len:
1124  err_decode:
1125  free ( buf );
1126  err_alloc:
1127  err_chap_init:
1128  return rc;
1129 }
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:133
#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:844
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:560
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition: iscsi.c:65
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
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:578
size_t strlen(const char *src)
Get length of string.
Definition: string.c:228
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:583
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:576
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:699
uint32_t len
Length.
Definition: ena.h:14
char * target_password
Target password (if any)
Definition: iscsi.h:569
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:113
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 1167 of file iscsi.c.

1168  {
1169  struct iscsi_string_type *type;
1170  const char *separator;
1171  const char *value;
1172  size_t key_len;
1173  int rc;
1174 
1175  /* Find separator */
1176  separator = strchr ( string, '=' );
1177  if ( ! separator ) {
1178  DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1179  iscsi, string );
1181  }
1182  key_len = ( separator - string );
1183  value = ( separator + 1 );
1184 
1185  /* Check for rejections. Since we send only non-rejectable
1186  * values, any rejection is a fatal protocol error.
1187  */
1188  if ( strcmp ( value, "Reject" ) == 0 ) {
1189  DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1190  return -EPROTO_VALUE_REJECTED;
1191  }
1192 
1193  /* Handle key/value pair */
1194  for ( type = iscsi_string_types ; type->key ; type++ ) {
1195  if ( strncmp ( string, type->key, key_len ) != 0 )
1196  continue;
1197  DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1198  if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1199  DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1200  iscsi, string, strerror ( rc ) );
1201  return rc;
1202  }
1203  return 0;
1204  }
1205  DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1206  return 0;
1207 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint8_t type
Type.
Definition: ena.h:16
#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:1149
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition: string.c:185
An iSCSI text string that we want to handle.
Definition: iscsi.c:1132
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define EPROTO_INVALID_KEY_VALUE_PAIR
Definition: iscsi.c:137
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:256
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:172
#define EPROTO_VALUE_REJECTED
Definition: iscsi.c:141

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 1217 of file iscsi.c.

1218  {
1219  size_t string_len;
1220  int rc;
1221 
1222  /* Handle each string in turn, taking care not to overrun the
1223  * data buffer in case of badly-terminated data.
1224  */
1225  while ( 1 ) {
1226  string_len = ( strnlen ( strings, len ) + 1 );
1227  if ( string_len > len )
1228  break;
1229  if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1230  return rc;
1231  strings += string_len;
1232  len -= string_len;
1233  }
1234  return 0;
1235 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition: iscsi.c:1167
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:240
uint32_t len
Length.
Definition: ena.h:14

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 1244 of file iscsi.c.

1245  {
1246  switch ( status_class ) {
1248  switch ( status_detail ) {
1255  return -ENODEV;
1256  default :
1257  return -ENOTSUP_INITIATOR_STATUS;
1258  }
1260  switch ( status_detail ) {
1262  return -EIO_TARGET_UNAVAILABLE;
1264  return -EIO_TARGET_NO_RESOURCES;
1265  default:
1266  return -ENOTSUP_TARGET_STATUS;
1267  }
1268  default :
1269  return -EINVAL;
1270  }
1271 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition: iscsi.h:240
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition: iscsi.h:243
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition: iscsi.h:246
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition: iscsi.h:245
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition: iscsi.h:242
#define ISCSI_STATUS_INITIATOR_ERROR
Definition: iscsi.h:239
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition: iscsi.h:241
#define ENODEV
No such device.
Definition: errno.h:509
#define EIO_TARGET_UNAVAILABLE
Definition: iscsi.c:89
#define ENOTSUP_INITIATOR_STATUS
Definition: iscsi.c:97
#define ENOTSUP_TARGET_STATUS
Definition: iscsi.c:109
#define EPERM_INITIATOR_AUTHORISATION
Definition: iscsi.c:117
#define EIO_TARGET_NO_RESOURCES
Definition: iscsi.c:93
#define EPERM_INITIATOR_AUTHENTICATION
Definition: iscsi.c:113
#define ISCSI_STATUS_TARGET_ERROR
Definition: iscsi.h:244

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 1282 of file iscsi.c.

1284  {
1285  struct iscsi_bhs_login_response *response
1286  = &iscsi->rx_bhs.login_response;
1287  int rc;
1288 
1289  /* Buffer up the PDU data */
1290  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1291  DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1292  iscsi, strerror ( rc ) );
1293  return rc;
1294  }
1295  if ( remaining )
1296  return 0;
1297 
1298  /* Process string data and discard string buffer */
1299  if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1300  iscsi->rx_len ) ) != 0 )
1301  return rc;
1302  iscsi_rx_buffered_data_done ( iscsi );
1303 
1304  /* Check for login redirection */
1305  if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1306  DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1307  iscsi_close_connection ( iscsi, 0 );
1308  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1309  DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1310  iscsi, strerror ( rc ) );
1311  return rc;
1312  }
1313  return 0;
1314  }
1315 
1316  /* Check for fatal errors */
1317  if ( response->status_class != 0 ) {
1318  DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1319  response->status_class, response->status_detail );
1320  rc = iscsi_status_to_rc ( response->status_class,
1321  response->status_detail );
1322  return rc;
1323  }
1324 
1325  /* Handle login transitions */
1326  if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1327  iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1329  switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1331  iscsi->status |=
1334  break;
1337  break;
1338  default:
1339  DBGC ( iscsi, "iSCSI %p got invalid response flags "
1340  "%02x\n", iscsi, response->flags );
1341  return -EIO;
1342  }
1343  }
1344 
1345  /* Send next login request PDU if we haven't reached the full
1346  * feature phase yet.
1347  */
1348  if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1350  iscsi_start_login ( iscsi );
1351  return 0;
1352  }
1353 
1354  /* Check that target authentication was successful (if required) */
1355  if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1356  ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1357  DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1358  "authentication\n", iscsi );
1359  return -EPROTO;
1360  }
1361 
1362  /* Notify SCSI layer of window change */
1363  DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1364  xfer_window_changed ( &iscsi->control );
1365 
1366  return 0;
1367 }
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition: iscsi.h:696
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:145
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition: iscsi.h:669
#define ISCSI_LOGIN_NSG_MASK
Definition: iscsi.h:179
#define DBGC(...)
Definition: compiler.h:505
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:641
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Definition: iscsi.h:664
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:643
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition: iscsi.c:759
uint8_t status_detail
Status detail.
Definition: iscsi.h:228
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition: iscsi.h:167
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:672
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:540
uint8_t status_class
Status class.
Definition: iscsi.h:226
int status
Session status.
Definition: iscsi.h:560
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
Definition: iscsi.c:299
#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:174
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:156
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:690
iSCSI login response basic header segment
Definition: iscsi.h:198
uint8_t flags
Flags.
Definition: iscsi.h:202
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:1244
#define ISCSI_STATUS_REDIRECT
Definition: iscsi.h:238
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:181
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:699
struct iscsi_bhs_login_response login_response
Definition: iscsi.h:500
uint32_t len
Length.
Definition: ena.h:14
#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:252
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition: iscsi.h:687
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition: iscsi.c:1217
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
Definition: iscsi.h:182

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 1380 of file iscsi.c.

1380  {
1381  process_del ( &iscsi->process );
1382 }
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
struct process process
TX process.
Definition: iscsi.h:632

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 1389 of file iscsi.c.

1389  {
1390  process_add ( &iscsi->process );
1391 }
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
struct process process
TX process.
Definition: iscsi.h:632

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 1421 of file iscsi.c.

1421  {
1422  return 0;
1423 }

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 1431 of file iscsi.c.

1431  {
1432  return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1433  sizeof ( iscsi->tx_bhs ) );
1434 }
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition: xfer.c:287
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628

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 1445 of file iscsi.c.

1445  {
1446  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1447 
1448  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1449  case ISCSI_OPCODE_DATA_OUT:
1450  return iscsi_tx_data_out ( iscsi );
1452  return iscsi_tx_login_request ( iscsi );
1453  default:
1454  /* Nothing to send in other states */
1455  return 0;
1456  }
1457 }
struct iscsi_bhs_common common
Definition: iscsi.h:497
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition: iscsi.c:574
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:87
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:164
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
Definition: iscsi.c:818
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
iSCSI basic header segment common fields
Definition: iscsi.h:69
struct ib_cm_common common
Definition: ib_mad.h:11
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:425

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 1468 of file iscsi.c.

1468  {
1469  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1470 
1471  /* Stop transmission process */
1472  iscsi_tx_pause ( iscsi );
1473 
1474  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1475  case ISCSI_OPCODE_DATA_OUT:
1476  iscsi_data_out_done ( iscsi );
1477  break;
1479  iscsi_login_request_done ( iscsi );
1480  break;
1481  default:
1482  /* No action */
1483  break;
1484  }
1485 }
struct iscsi_bhs_common common
Definition: iscsi.h:497
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:87
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:164
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition: iscsi.c:1380
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition: iscsi.c:558
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
iSCSI basic header segment common fields
Definition: iscsi.h:69
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:801
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:425

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 1496 of file iscsi.c.

1496  {
1497  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1498  int ( * tx ) ( struct iscsi_session *iscsi );
1499  enum iscsi_tx_state next_state;
1500  size_t tx_len;
1501  int rc;
1502 
1503  /* Select fragment to transmit */
1504  while ( 1 ) {
1505  switch ( iscsi->tx_state ) {
1506  case ISCSI_TX_BHS:
1507  tx = iscsi_tx_bhs;
1508  tx_len = sizeof ( iscsi->tx_bhs );
1509  next_state = ISCSI_TX_AHS;
1510  break;
1511  case ISCSI_TX_AHS:
1512  tx = iscsi_tx_nothing;
1513  tx_len = 0;
1514  next_state = ISCSI_TX_DATA;
1515  break;
1516  case ISCSI_TX_DATA:
1517  tx = iscsi_tx_data;
1518  tx_len = ISCSI_DATA_LEN ( common->lengths );
1519  next_state = ISCSI_TX_IDLE;
1520  break;
1521  case ISCSI_TX_IDLE:
1522  /* Nothing to do; pause processing */
1523  iscsi_tx_pause ( iscsi );
1524  return;
1525  default:
1526  assert ( 0 );
1527  return;
1528  }
1529 
1530  /* Check for window availability, if needed */
1531  if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1532  /* Cannot transmit at this point; pause
1533  * processing and wait for window to reopen
1534  */
1535  iscsi_tx_pause ( iscsi );
1536  return;
1537  }
1538 
1539  /* Transmit data */
1540  if ( ( rc = tx ( iscsi ) ) != 0 ) {
1541  DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1542  iscsi, strerror ( rc ) );
1543  /* Transmission errors are fatal */
1544  iscsi_close ( iscsi, rc );
1545  return;
1546  }
1547 
1548  /* Move to next state */
1549  iscsi->tx_state = next_state;
1550 
1551  /* If we have moved to the idle state, mark
1552  * transmission as complete
1553  */
1554  if ( iscsi->tx_state == ISCSI_TX_IDLE )
1555  iscsi_tx_done ( iscsi );
1556  }
1557 }
iscsi_tx_state
State of an iSCSI TX engine.
Definition: iscsi.h:511
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:1468
An iSCSI session.
Definition: iscsi.h:535
struct iscsi_bhs_common common
Definition: iscsi.h:497
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
#define DBGC(...)
Definition: compiler.h:505
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition: iscsi.c:1421
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition: iscsi.c:1431
Nothing to send.
Definition: iscsi.h:513
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
Definition: iscsi.c:1445
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition: iscsi.c:1380
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:219
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:628
iSCSI basic header segment common fields
Definition: iscsi.h:69
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
Sending the additional header segment.
Definition: iscsi.h:517
struct ib_cm_common common
Definition: ib_mad.h:11
Sending the data segment.
Definition: iscsi.h:519
Sending the basic header segment.
Definition: iscsi.h:515
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:630
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 1575 of file iscsi.c.

1576  {
1577  memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1578  if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1579  DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1580  iscsi, iscsi->rx_bhs.common.opcode,
1581  ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1582  }
1583  return 0;
1584 }
struct iscsi_bhs_common common
Definition: iscsi.h:497
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
Definition: iscsi.h:507
void * memcpy(void *dest, const void *src, size_t len) __nonnull
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:77
uint8_t opcode
Opcode.
Definition: iscsi.h:71
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

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 1597 of file iscsi.c.

1599  {
1600  /* Do nothing */
1601  return 0;
1602 }

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 1616 of file iscsi.c.

1617  {
1618  struct iscsi_bhs_common_response *response
1619  = &iscsi->rx_bhs.common_response;
1620 
1621  /* Update cmdsn and statsn */
1622  iscsi->cmdsn = ntohl ( response->expcmdsn );
1623  iscsi->statsn = ntohl ( response->statsn );
1624 
1625  switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1627  return iscsi_rx_login_response ( iscsi, data, len, remaining );
1629  return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1630  case ISCSI_OPCODE_DATA_IN:
1631  return iscsi_rx_data_in ( iscsi, data, len, remaining );
1632  case ISCSI_OPCODE_R2T:
1633  return iscsi_rx_r2t ( iscsi, data, len, remaining );
1634  case ISCSI_OPCODE_NOP_IN:
1635  return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1636  default:
1637  if ( remaining )
1638  return 0;
1639  DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1640  response->opcode );
1641  return -ENOTSUP_OPCODE;
1642  }
1643 }
uint32_t expcmdsn
Expected command sequence number.
Definition: iscsi.h:123
uint8_t opcode
Opcode.
Definition: iscsi.h:107
struct iscsi_bhs_common_response common_response
Definition: iscsi.h:498
#define DBGC(...)
Definition: compiler.h:505
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
Definition: iscsi.h:327
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:409
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:87
#define ntohl(value)
Definition: byteswap.h:134
uint32_t statsn
Status sequence number.
Definition: iscsi.h:121
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:1282
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
Definition: iscsi.h:377
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:499
uint32_t statsn
Status sequence number.
Definition: iscsi.h:625
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
Definition: iscsi.h:491
iSCSI basic header segment common request fields
Definition: iscsi.h:105
#define ISCSI_OPCODE_R2T
R2T opcode.
Definition: iscsi.h:461
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:609
uint32_t len
Length.
Definition: ena.h:14
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:462
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:617
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
Definition: iscsi.h:234
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define ENOTSUP_OPCODE
Definition: iscsi.c:101

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 1660 of file iscsi.c.

1662  {
1663  struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1664  int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1665  size_t len, size_t remaining );
1666  enum iscsi_rx_state next_state;
1667  size_t frag_len;
1668  size_t remaining;
1669  int rc;
1670 
1671  while ( 1 ) {
1672  switch ( iscsi->rx_state ) {
1673  case ISCSI_RX_BHS:
1674  rx = iscsi_rx_bhs;
1675  iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1676  next_state = ISCSI_RX_AHS;
1677  break;
1678  case ISCSI_RX_AHS:
1679  rx = iscsi_rx_discard;
1680  iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1681  next_state = ISCSI_RX_DATA;
1682  break;
1683  case ISCSI_RX_DATA:
1684  rx = iscsi_rx_data;
1685  iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1686  next_state = ISCSI_RX_DATA_PADDING;
1687  break;
1688  case ISCSI_RX_DATA_PADDING:
1689  rx = iscsi_rx_discard;
1690  iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1691  next_state = ISCSI_RX_BHS;
1692  break;
1693  default:
1694  assert ( 0 );
1695  rc = -EINVAL;
1696  goto done;
1697  }
1698 
1699  frag_len = iscsi->rx_len - iscsi->rx_offset;
1700  if ( frag_len > iob_len ( iobuf ) )
1701  frag_len = iob_len ( iobuf );
1702  remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1703  if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1704  remaining ) ) != 0 ) {
1705  DBGC ( iscsi, "iSCSI %p could not process received "
1706  "data: %s\n", iscsi, strerror ( rc ) );
1707  goto done;
1708  }
1709 
1710  iscsi->rx_offset += frag_len;
1711  iob_pull ( iobuf, frag_len );
1712 
1713  /* If all the data for this state has not yet been
1714  * received, stay in this state for now.
1715  */
1716  if ( iscsi->rx_offset != iscsi->rx_len ) {
1717  rc = 0;
1718  goto done;
1719  }
1720 
1721  iscsi->rx_state = next_state;
1722  iscsi->rx_offset = 0;
1723  }
1724 
1725  done:
1726  /* Free I/O buffer */
1727  free_iob ( iobuf );
1728 
1729  /* Destroy session on error */
1730  if ( rc != 0 )
1731  iscsi_close ( iscsi, rc );
1732 
1733  return rc;
1734 }
#define iob_pull(iobuf, len)
Definition: iobuf.h:102
#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:1575
An iSCSI session.
Definition: iscsi.h:535
struct iscsi_bhs_common common
Definition: iscsi.h:497
Receiving the data segment.
Definition: iscsi.h:529
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:56
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:146
#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:1616
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:641
iscsi_rx_state
State of an iSCSI RX engine.
Definition: iscsi.h:523
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:52
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:639
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
Receiving the data segment padding.
Definition: iscsi.h:531
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:219
Receiving the additional header segment.
Definition: iscsi.h:527
iSCSI basic header segment common fields
Definition: iscsi.h:69
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:637
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:155
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
Definition: iscsi.h:48
struct ib_cm_common common
Definition: ib_mad.h:11
uint32_t len
Length.
Definition: ena.h:14
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:1597
void * data
Start of data.
Definition: iobuf.h:48
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:635
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
Receiving the basic header segment.
Definition: iscsi.h:525
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 1744 of file iscsi.c.

1745  {
1746  va_list tmp;
1747  struct sockaddr *peer;
1748  int rc;
1749 
1750  /* Intercept redirects to a LOCATION_SOCKET and record the IP
1751  * address for the iBFT. This is a bit of a hack, but avoids
1752  * inventing an ioctl()-style call to retrieve the socket
1753  * address from a data-xfer interface.
1754  */
1755  if ( type == LOCATION_SOCKET ) {
1756  va_copy ( tmp, args );
1757  ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1758  peer = va_arg ( tmp, struct sockaddr * );
1759  memcpy ( &iscsi->target_sockaddr, peer,
1760  sizeof ( iscsi->target_sockaddr ) );
1761  va_end ( tmp );
1762  }
1763 
1764  /* Redirect to new location */
1765  if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1766  goto err;
1767 
1768  return 0;
1769 
1770  err:
1771  iscsi_close ( iscsi, rc );
1772  return rc;
1773 }
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:649
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
uint8_t type
Type.
Definition: ena.h:16
Location is a socket.
Definition: open.h:43
#define va_copy(dest, src)
Definition: stdarg.h:10
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:219
Generalized socket address structure.
Definition: socket.h:96
uint8_t * tmp
Definition: entropy.h:156
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:223
__builtin_va_list va_list
Definition: stdarg.h:6

References iscsi_close(), LOCATION_SOCKET, memcpy(), 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 1800 of file iscsi.c.

1800  {
1801 
1802  if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1804  ( iscsi->command == NULL ) ) {
1805  /* We cannot handle concurrent commands */
1806  return 1;
1807  } else {
1808  return 0;
1809  }
1810 }
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition: iscsi.h:669
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:672
int status
Session status.
Definition: iscsi.h:560
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 1820 of file iscsi.c.

1822  {
1823 
1824  /* This iSCSI implementation cannot handle multiple concurrent
1825  * commands or commands arriving before login is complete.
1826  */
1827  if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1828  DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1829  iscsi );
1830  return -EOPNOTSUPP;
1831  }
1832 
1833  /* Store command */
1834  iscsi->command = malloc ( sizeof ( *command ) );
1835  if ( ! iscsi->command )
1836  return -ENOMEM;
1837  memcpy ( iscsi->command, command, sizeof ( *command ) );
1838 
1839  /* Assign new ITT */
1840  iscsi_new_itt ( iscsi );
1841 
1842  /* Start sending command */
1843  iscsi_start_command ( iscsi );
1844 
1845  /* Attach to parent interface and return */
1846  intf_plug_plug ( &iscsi->data, parent );
1847  return iscsi->itt;
1848 }
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition: iscsi.c:240
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:102
#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:591
#define EOPNOTSUPP
Operation not supported on socket.
Definition: errno.h:604
struct interface data
SCSI command interface.
Definition: iscsi.h:542
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition: iscsi.c:369
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1800

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_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 1856 of file iscsi.c.

1856  {
1857 
1858  return &iscsi->desc;
1859 }
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:653

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 1880 of file iscsi.c.

1880  {
1881 
1882  /* Restart interface */
1883  intf_restart ( &iscsi->data, rc );
1884 
1885  /* Treat unsolicited command closures mid-command as fatal,
1886  * because we have no code to handle partially-completed PDUs.
1887  */
1888  if ( iscsi->command != NULL )
1889  iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1890 }
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:337
#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:219
struct interface data
SCSI command interface.
Definition: iscsi.h:542
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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:490

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 1951 of file iscsi.c.

1952  {
1953  char *rp_copy;
1954  char *rp_comp[NUM_RP_COMPONENTS];
1955  char *rp;
1956  int skip = 0;
1957  int i = 0;
1958  int rc;
1959 
1960  /* Create modifiable copy of root path */
1961  rp_copy = strdup ( root_path );
1962  if ( ! rp_copy ) {
1963  rc = -ENOMEM;
1964  goto err_strdup;
1965  }
1966  rp = rp_copy;
1967 
1968  /* Split root path into component parts */
1969  while ( 1 ) {
1970  rp_comp[i++] = rp;
1971  if ( i == NUM_RP_COMPONENTS )
1972  break;
1973  for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
1974  if ( ! *rp ) {
1975  DBGC ( iscsi, "iSCSI %p root path \"%s\" "
1976  "too short\n", iscsi, root_path );
1978  goto err_split;
1979  } else if ( *rp == '[' ) {
1980  skip = 1;
1981  } else if ( *rp == ']' ) {
1982  skip = 0;
1983  }
1984  }
1985  *(rp++) = '\0';
1986  }
1987 
1988  /* Use root path components to configure iSCSI session */
1989  iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
1990  if ( ! iscsi->target_address ) {
1991  rc = -ENOMEM;
1992  goto err_servername;
1993  }
1994  iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
1995  if ( ! iscsi->target_port )
1996  iscsi->target_port = ISCSI_PORT;
1997  if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
1998  DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
1999  iscsi, rp_comp[RP_LUN] );
2000  goto err_lun;
2001  }
2002  iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2003  if ( ! iscsi->target_iqn ) {
2004  rc = -ENOMEM;
2005  goto err_targetname;
2006  }
2007 
2008  err_targetname:
2009  err_lun:
2010  err_servername:
2011  err_split:
2012  free ( rp_copy );
2013  err_strdup:
2014  return rc;
2015 }
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:456
#define DBGC(...)
Definition: compiler.h:505
Definition: iscsi.c:1912
unsigned int target_port
Target port.
Definition: iscsi.h:551
#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:651
char * strdup(const char *src)
Duplicate string.
Definition: string.c:365
char * target_address
Target address.
Definition: iscsi.h:549
#define EINVAL_ROOT_PATH_TOO_SHORT
Definition: iscsi.c:69
char * target_iqn
Target IQN.
Definition: iscsi.h:553
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 2023 of file iscsi.c.

2023  {
2024  char *hostname;
2025  union uuid uuid;
2026  int len;
2027 
2028  /* Fetch relevant settings. Don't worry about freeing on
2029  * error, since iscsi_free() will take care of that anyway.
2030  */
2031  fetch_string_setting_copy ( NULL, &username_setting,
2032  &iscsi->initiator_username );
2033  fetch_string_setting_copy ( NULL, &password_setting,
2034  &iscsi->initiator_password );
2035  fetch_string_setting_copy ( NULL, &reverse_username_setting,
2036  &iscsi->target_username );
2037  fetch_string_setting_copy ( NULL, &reverse_password_setting,
2038  &iscsi->target_password );
2039 
2040  /* Use explicit initiator IQN if provided */
2041  fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2042  &iscsi->initiator_iqn );
2043  if ( iscsi->initiator_iqn )
2044  return 0;
2045 
2046  /* Otherwise, try to construct an initiator IQN from the hostname */
2047  fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2048  if ( hostname ) {
2049  len = asprintf ( &iscsi->initiator_iqn,
2050  ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2051  free ( hostname );
2052  if ( len < 0 ) {
2053  DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2054  "IQN\n", iscsi );
2055  return -ENOMEM;
2056  }
2057  assert ( iscsi->initiator_iqn );
2058  return 0;
2059  }
2060 
2061  /* Otherwise, try to construct an initiator IQN from the UUID */
2062  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2063  DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2064  iscsi );
2065  return -EINVAL_NO_INITIATOR_IQN;
2066  }
2067  if ( ( len = asprintf ( &iscsi->initiator_iqn,
2069  uuid_ntoa ( &uuid ) ) ) < 0 ) {
2070  DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2071  iscsi );
2072  return -ENOMEM;
2073  }
2074  assert ( iscsi->initiator_iqn );
2075 
2076  return 0;
2077 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:563
A universally unique ID.
Definition: uuid.h:15
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:565
#define ENOMEM
Not enough space.
Definition: errno.h:534
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:877
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:43
uint32_t len
Length.
Definition: ena.h:14
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1088
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
Definition: iscsi.h:702
char * target_password
Target password (if any)
Definition: iscsi.h:569
char * target_username
Target username (if any)
Definition: iscsi.h:567
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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 2086 of file iscsi.c.

2086  {
2087 
2088  /* Check for invalid authentication combinations */
2089  if ( ( /* Initiator username without password (or vice-versa) */
2090  ( !! iscsi->initiator_username ) ^
2091  ( !! iscsi->initiator_password ) ) ||
2092  ( /* Target username without password (or vice-versa) */
2093  ( !! iscsi->target_username ) ^
2094  ( !! iscsi->target_password ) ) ||
2095  ( /* Target (reverse) without initiator (forward) */
2096  ( iscsi->target_username &&
2097  ( ! iscsi->initiator_username ) ) ) ) {
2098  DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2099  "%sname,%spw, target %sname,%spw\n", iscsi,
2100  ( iscsi->initiator_username ? "" : "no " ),
2101  ( iscsi->initiator_password ? "" : "no " ),
2102  ( iscsi->target_username ? "" : "no " ),
2103  ( iscsi->target_password ? "" : "no " ) );
2104  return -EINVAL_BAD_CREDENTIAL_MIX;
2105  }
2106 
2107  return 0;
2108 }
#define EINVAL_BAD_CREDENTIAL_MIX
Definition: iscsi.c:73
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:563
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:565
char * target_password
Target password (if any)
Definition: iscsi.h:569
char * target_username
Target username (if any)
Definition: iscsi.h:567

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 2117 of file iscsi.c.

2117  {
2118  struct iscsi_session *iscsi;
2119  int rc;
2120 
2121  /* Sanity check */
2122  if ( ! uri->opaque ) {
2124  goto err_sanity_uri;
2125  }
2126 
2127  /* Allocate and initialise structure */
2128  iscsi = zalloc ( sizeof ( *iscsi ) );
2129  if ( ! iscsi ) {
2130  rc = -ENOMEM;
2131  goto err_zalloc;
2132  }
2133  ref_init ( &iscsi->refcnt, iscsi_free );
2134  intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2135  intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2136  intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2138  &iscsi->refcnt );
2139  acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2140 
2141  /* Parse root path */
2142  if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2143  goto err_parse_root_path;
2144  /* Set fields not specified by root path */
2145  if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2146  goto err_fetch_settings;
2147  /* Validate authentication */
2148  if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2149  goto err_check_auth;
2150 
2151  /* Sanity checks */
2152  if ( ! iscsi->target_address ) {
2153  DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2154  iscsi );
2155  rc = -ENOTSUP_DISCOVERY;
2156  goto err_sanity_address;
2157  }
2158  if ( ! iscsi->target_iqn ) {
2159  DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2160  iscsi, uri->opaque );
2162  goto err_sanity_iqn;
2163  }
2164  DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2165  DBGC ( iscsi, "iSCSI %p target %s %s\n",
2166  iscsi, iscsi->target_address, iscsi->target_iqn );
2167 
2168  /* Open socket */
2169  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2170  goto err_open_connection;
2171 
2172  /* Attach SCSI device to parent interface */
2173  if ( ( rc = scsi_open ( parent, &iscsi->control,
2174  &iscsi->lun ) ) != 0 ) {
2175  DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2176  iscsi, strerror ( rc ) );
2177  goto err_scsi_open;
2178  }
2179 
2180  /* Mortalise self, and return */
2181  ref_put ( &iscsi->refcnt );
2182  return 0;
2183 
2184  err_scsi_open:
2185  err_open_connection:
2186  err_sanity_iqn:
2187  err_sanity_address:
2188  err_check_auth:
2189  err_fetch_settings:
2190  err_parse_root_path:
2191  iscsi_close ( iscsi, rc );
2192  ref_put ( &iscsi->refcnt );
2193  err_zalloc:
2194  err_sanity_uri:
2195  return rc;
2196 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTSUP_DISCOVERY
Definition: iscsi.c:105
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition: iscsi.c:2023
An iSCSI session.
Definition: iscsi.h:535
#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:1951
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
#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:980
#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:540
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:653
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:219
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition: iscsi.c:1871
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition: iscsi.c:1560
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:651
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct process process
TX process.
Definition: iscsi.h:632
char * target_address
Target address.
Definition: iscsi.h:549
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition: iscsi.c:2086
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:542
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition: iscsi.c:196
char * target_iqn
Target IQN.
Definition: iscsi.h:553
const char * opaque
Opaque part.
Definition: uri.h:56
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition: iscsi.c:252
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition: iscsi.c:1785
A Uniform Resource Identifier.
Definition: uri.h:50
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:188
#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:292
#define EINVAL_NO_ROOT_PATH
Definition: iscsi.c:77
struct refcnt refcnt
Reference counter.
Definition: iscsi.h:537
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition: iscsi.c:1898

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 },
{ "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:918
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition: iscsi.c:982
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition: iscsi.c:1037
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition: iscsi.c:897
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition: iscsi.c:1066
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition: iscsi.c:867
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition: iscsi.c:941
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

iSCSI text strings that we want to handle

Definition at line 1149 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:535
#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:1496

iSCSI TX process descriptor

Definition at line 1560 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:145
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
An iSCSI session.
Definition: iscsi.h:535
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:1744
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:219
#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:1660
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:193
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1389

iSCSI socket interface operations

Definition at line 1776 of file iscsi.c.

◆ iscsi_socket_desc

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

iSCSI socket interface descriptor

Definition at line 1785 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:244
An iSCSI session.
Definition: iscsi.h:535
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
A SCSI command.
Definition: scsi.c:262
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:219
#define EFI_INTF_OP
Definition: efi.h:291
#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:1856
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:334
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition: efi_path.c:234
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:491
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1800
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition: iscsi.c:1820

iSCSI SCSI command-issuing interface operations

Definition at line 1862 of file iscsi.c.

◆ iscsi_control_desc

struct interface_descriptor iscsi_control_desc
static
Initial value:
=
An iSCSI session.
Definition: iscsi.h:535
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:1862

iSCSI SCSI command-issuing interface descriptor

Definition at line 1871 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:244
An iSCSI session.
Definition: iscsi.h:535
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition: iscsi.c:1880
#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 1893 of file iscsi.c.

◆ iscsi_data_desc

struct interface_descriptor iscsi_data_desc
static
Initial value:
=
An iSCSI session.
Definition: iscsi.h:535
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Definition: iscsi.c:1893

iSCSI SCSI command interface descriptor

Definition at line 1898 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:2117

iSCSI URI opener

Definition at line 2199 of file iscsi.c.