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/blockdev.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/iscsi.h>

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

iSCSI protocol

Definition in file iscsi.c.

Macro Definition Documentation

◆ EACCES_INCORRECT_TARGET_USERNAME

#define EACCES_INCORRECT_TARGET_USERNAME   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

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

◆ EACCES_INCORRECT_TARGET_PASSWORD

#define EACCES_INCORRECT_TARGET_PASSWORD   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Definition at line 66 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 68 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 70 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 72 of file iscsi.c.

◆ EINVAL_BAD_CREDENTIAL_MIX

#define EINVAL_BAD_CREDENTIAL_MIX   __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

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

◆ EINVAL_NO_ROOT_PATH

#define EINVAL_NO_ROOT_PATH   __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

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

◆ EINVAL_NO_TARGET_IQN

#define EINVAL_NO_TARGET_IQN   __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

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

◆ EINVAL_NO_INITIATOR_IQN

#define EINVAL_NO_INITIATOR_IQN   __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

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

◆ EINVAL_MAXBURSTLENGTH

#define EINVAL_MAXBURSTLENGTH   __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Definition at line 90 of file iscsi.c.

◆ EINFO_EINVAL_MAXBURSTLENGTH

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

Definition at line 92 of file iscsi.c.

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

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

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

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

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 102 of file iscsi.c.

◆ EINFO_ENOTSUP_INITIATOR_STATUS

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

Definition at line 104 of file iscsi.c.

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 106 of file iscsi.c.

◆ EINFO_ENOTSUP_OPCODE

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

Definition at line 108 of file iscsi.c.

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 110 of file iscsi.c.

◆ EINFO_ENOTSUP_DISCOVERY

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

Definition at line 112 of file iscsi.c.

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 114 of file iscsi.c.

◆ EINFO_ENOTSUP_TARGET_STATUS

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

Definition at line 116 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 118 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

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

Definition at line 120 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 122 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

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

Definition at line 124 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

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

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

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

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

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

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Definition at line 138 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 140 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 142 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 144 of file iscsi.c.

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 146 of file iscsi.c.

◆ EINFO_EPROTO_VALUE_REJECTED

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

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

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

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

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

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

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

◆ iscsi_start_login()

static void iscsi_start_login ( struct iscsi_session iscsi)
static

Build iSCSI login request BHS.

Parameters
iscsiiSCSI session

Definition at line 771 of file iscsi.c.

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

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

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

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

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

References free, NULL, and iscsi_session::rx_buffer.

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

◆ iscsi_rx_buffered_data()

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

Receive PDU data into buffer.

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

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

Definition at line 179 of file iscsi.c.

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

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

Referenced by iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_free()

static void iscsi_free ( struct refcnt refcnt)
static

Free iSCSI session.

Parameters
refcntReference counter

Definition at line 201 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_close()

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

Shut down iSCSI interface.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 224 of file iscsi.c.

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

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

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

◆ iscsi_new_itt()

static void iscsi_new_itt ( struct iscsi_session iscsi)
static

Assign new iSCSI initiator task tag.

Parameters
iscsiiSCSI session

Definition at line 245 of file iscsi.c.

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

References ISCSI_TAG_MAGIC, and iscsi_session::itt.

Referenced by iscsi_open_connection(), and iscsi_scsi_command().

◆ iscsi_open_connection()

static int iscsi_open_connection ( struct iscsi_session iscsi)
static

Open iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 257 of file iscsi.c.

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

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

Referenced by iscsi_open(), and iscsi_rx_login_response().

◆ iscsi_close_connection()

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

Close iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
rcReason for close

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

Definition at line 307 of file iscsi.c.

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

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

Referenced by iscsi_rx_login_response().

◆ iscsi_scsi_done()

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

Mark iSCSI SCSI operation as complete.

Parameters
iscsiiSCSI session
rcReturn status code
rspSCSI response, if any

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

Definition at line 339 of file iscsi.c.

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

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

Referenced by iscsi_rx_data_in(), and iscsi_rx_scsi_response().

◆ iscsi_start_command()

static void iscsi_start_command ( struct iscsi_session iscsi)
static

Build iSCSI SCSI command BHS.

Parameters
iscsiiSCSI session

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

Definition at line 377 of file iscsi.c.

377  {
379 
380  assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
381 
382  /* Construct BHS and initiate transmission */
383  iscsi_start_tx ( iscsi );
385  command->flags = ( ISCSI_FLAG_FINAL |
387  if ( iscsi->command->data_in )
389  if ( iscsi->command->data_out )
391  /* lengths left as zero */
392  memcpy ( &command->lun, &iscsi->command->lun,
393  sizeof ( command->lun ) );
394  command->itt = htonl ( iscsi->itt );
395  command->exp_len = htonl ( iscsi->command->data_in_len |
396  iscsi->command->data_out_len );
397  command->cmdsn = htonl ( iscsi->cmdsn );
398  command->expstatsn = htonl ( iscsi->statsn + 1 );
399  memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
400  DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
401  iscsi, SCSI_CDB_DATA ( command->cdb ),
402  ( iscsi->command->data_in ? "in" : "out" ),
403  ( iscsi->command->data_in ?
404  iscsi->command->data_in_len :
405  iscsi->command->data_out_len ) );
406 }
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition: iscsi.h:291
struct iscsi_bhs_scsi_command scsi_command
Definition: iscsi.h:510
size_t data_out_len
Data-out buffer length.
Definition: scsi.h: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:288
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:261
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
void * memcpy(void *dest, const void *src, size_t len) __nonnull
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
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:102
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
struct scsi_lun lun
LUN.
Definition: scsi.h: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:295
#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:629
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:285
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1439

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

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

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

Referenced by iscsi_rx_data().

◆ iscsi_rx_data_in()

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

Receive data segment of an iSCSI data-in PDU.

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

Definition at line 470 of file iscsi.c.

472  {
473  struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
474  unsigned long offset;
475 
476  /* Copy data to data-in buffer */
477  offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
478  assert ( iscsi->command != NULL );
479  assert ( iscsi->command->data_in );
480  assert ( ( offset + len ) <= iscsi->command->data_in_len );
481  copy_to_user ( iscsi->command->data_in, offset, data, len );
482 
483  /* Wait for whole SCSI response to arrive */
484  if ( remaining )
485  return 0;
486 
487  /* Mark as completed if status is present */
488  if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
489  assert ( ( offset + len ) == iscsi->command->data_in_len );
490  assert ( data_in->flags & ISCSI_FLAG_FINAL );
491  /* iSCSI cannot return an error status via a data-in */
492  iscsi_scsi_done ( iscsi, 0, NULL );
493  }
494 
495  return 0;
496 }
iSCSI data-in basic header segment
Definition: iscsi.h:354
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition: iscsi.h:398
uint32_t offset
Buffer offset.
Definition: iscsi.h:380
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:267
#define ntohl(value)
Definition: byteswap.h:134
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
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:102
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:339
uint8_t flags
Flags.
Definition: iscsi.h:358
uint32_t len
Length.
Definition: ena.h:14
userptr_t data_in
Data-in buffer (may be NULL)
Definition: scsi.h:262
uint8_t data[48]
Additional event data.
Definition: ena.h:22
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
struct iscsi_bhs_data_in data_in
Definition: iscsi.h:512

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

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

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

Referenced by iscsi_rx_data().

◆ iscsi_data_out_done()

static void iscsi_data_out_done ( struct iscsi_session iscsi)
static

Complete iSCSI data-out PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 566 of file iscsi.c.

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

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

Referenced by iscsi_tx_done().

◆ iscsi_tx_data_out()

static int iscsi_tx_data_out ( struct iscsi_session iscsi)
static

Send iSCSI data-out data segment.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 582 of file iscsi.c.

582  {
583  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
584  struct io_buffer *iobuf;
585  unsigned long offset;
586  size_t len;
587  size_t pad_len;
588 
589  offset = ntohl ( data_out->offset );
590  len = ISCSI_DATA_LEN ( data_out->lengths );
591  pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
592 
593  assert ( iscsi->command != NULL );
594  assert ( iscsi->command->data_out );
595  assert ( ( offset + len ) <= iscsi->command->data_out_len );
596 
597  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
598  if ( ! iobuf )
599  return -ENOMEM;
600 
601  copy_from_user ( iob_put ( iobuf, len ),
602  iscsi->command->data_out, offset, len );
603  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
604 
605  return xfer_deliver_iob ( &iscsi->socket, iobuf );
606 }
#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:255
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:412
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
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:513
#define ntohl(value)
Definition: byteswap.h:134
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
#define ENOMEM
Not enough space.
Definition: errno.h:534
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:640
uint32_t offset
Buffer offset.
Definition: iscsi.h:428
long pad_len
Definition: bigint.h:30
iSCSI data-out basic header segment
Definition: iscsi.h:404
uint32_t len
Length.
Definition: ena.h:14
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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, pad_len, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_rx_nop_in()

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

Receive data segment of an iSCSI NOP-In.

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

Definition at line 617 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_build_login_request_strings()

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

Build iSCSI login request strings.

Parameters
iscsiiSCSI session

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

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

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

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

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

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

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

Definition at line 692 of file iscsi.c.

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

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

Referenced by iscsi_start_login(), and iscsi_tx_login_request().

◆ iscsi_login_request_done()

static void iscsi_login_request_done ( struct iscsi_session iscsi)
static

Complete iSCSI login request PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 813 of file iscsi.c.

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

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

Referenced by iscsi_tx_done().

◆ iscsi_tx_login_request()

static int iscsi_tx_login_request ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI login request PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

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

Definition at line 830 of file iscsi.c.

830  {
832  struct io_buffer *iobuf;
833  size_t len;
834  size_t pad_len;
835 
836  len = ISCSI_DATA_LEN ( request->lengths );
837  pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
838  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
839  if ( ! iobuf )
840  return -ENOMEM;
841  iob_put ( iobuf, len );
842  iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
843  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
844 
845  return xfer_deliver_iob ( &iscsi->socket, iobuf );
846 }
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:508
#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:255
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
iSCSI login request basic header segment
Definition: iscsi.h:141
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
#define ENOMEM
Not enough space.
Definition: errno.h:534
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
long pad_len
Definition: bigint.h:30
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:692
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(), pad_len, request, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_large_binary_decode()

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

Decode large binary value.

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

Definition at line 856 of file iscsi.c.

857  {
858 
859  /* Check for initial '0x' or '0b' and decode as appropriate */
860  if ( *(encoded++) == '0' ) {
861  switch ( tolower ( *(encoded++) ) ) {
862  case 'x' :
863  return base16_decode ( encoded, raw, len );
864  case 'b' :
865  return base64_decode ( encoded, raw, len );
866  }
867  }
868 
870 }
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:108
uint32_t len
Length.
Definition: ena.h:14
__be32 raw[7]
Definition: CIB_PRM.h:28
#define EPROTO_INVALID_LARGE_BINARY
Definition: iscsi.c:134

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

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

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

◆ iscsi_handle_authmethod_value()

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

Handle iSCSI AuthMethod text value.

Parameters
iscsiiSCSI session
valueAuthMethod value
Return values
rcReturn status code

Definition at line 909 of file iscsi.c.

910  {
911 
912  /* If server requests CHAP, send the CHAP_A string */
913  if ( strcmp ( value, "CHAP" ) == 0 ) {
914  DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
915  iscsi );
918  }
919 
920  return 0;
921 }
#define DBGC(...)
Definition: compiler.h:505
int status
Session status.
Definition: iscsi.h:569
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:690
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition: iscsi.h:705

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

◆ iscsi_handle_maxburstlength_value()

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

Handle iSCSI MaxBurstLength text value.

Parameters
iscsiiSCSI session
valueMaxBurstLength value
Return values
rcReturn status code

Definition at line 930 of file iscsi.c.

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

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

◆ iscsi_handle_chap_a_value()

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

Handle iSCSI CHAP_A text value.

Parameters
iscsiiSCSI session
valueCHAP_A value
Return values
rcReturn status code

Definition at line 955 of file iscsi.c.

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

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

◆ iscsi_handle_chap_i_value()

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

Handle iSCSI CHAP_I text value.

Parameters
iscsiiSCSI session
valueCHAP_I value
Return values
rcReturn status code

Definition at line 978 of file iscsi.c.

979  {
980  unsigned int identifier;
981  char *endp;
982  int rc;
983 
984  /* The CHAP identifier is an integer value */
985  identifier = strtoul ( value, &endp, 0 );
986  if ( *endp != '\0' ) {
987  DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
988  iscsi, value );
990  }
991 
992  /* Prepare for CHAP with MD5 */
993  chap_finish ( &iscsi->chap );
994  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
995  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
996  iscsi, strerror ( rc ) );
997  return rc;
998  }
999 
1000  /* Identifier and secret are the first two components of the
1001  * challenge.
1002  */
1003  chap_set_identifier ( &iscsi->chap, identifier );
1004  if ( iscsi->initiator_password ) {
1005  chap_update ( &iscsi->chap, iscsi->initiator_password,
1006  strlen ( iscsi->initiator_password ) );
1007  }
1008 
1009  return 0;
1010 }
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:471
#define DBGC(...)
Definition: compiler.h:505
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
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:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define EPROTO_INVALID_CHAP_IDENTIFIER
Definition: iscsi.c:130
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 1019 of file iscsi.c.

1020  {
1021  uint8_t *buf;
1022  unsigned int i;
1023  int len;
1024  int rc;
1025 
1026  /* Allocate decoding buffer */
1027  len = strlen ( value ); /* Decoding never expands data */
1028  buf = malloc ( len );
1029  if ( ! buf ) {
1030  rc = -ENOMEM;
1031  goto err_alloc;
1032  }
1033 
1034  /* Process challenge */
1035  len = iscsi_large_binary_decode ( value, buf, len );
1036  if ( len < 0 ) {
1037  rc = len;
1038  DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1039  iscsi, value, strerror ( rc ) );
1040  goto err_decode;
1041  }
1042  chap_update ( &iscsi->chap, buf, len );
1043 
1044  /* Build CHAP response */
1045  DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1046  chap_respond ( &iscsi->chap );
1048 
1049  /* Send CHAP challenge, if applicable */
1050  if ( iscsi->target_username ) {
1052  /* Generate CHAP challenge data */
1053  for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1054  iscsi->chap_challenge[i] = random();
1055  }
1056  }
1057 
1058  /* Success */
1059  rc = 0;
1060 
1061  err_decode:
1062  free ( buf );
1063  err_alloc:
1064  return rc;
1065 }
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:856
#define ENOMEM
Not enough space.
Definition: errno.h:534
int status
Session status.
Definition: iscsi.h:569
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:31
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition: iscsi.h:696
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition: iscsi.h:693
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
uint32_t len
Length.
Definition: ena.h:14
char * target_username
Target username (if any)
Definition: iscsi.h:576
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85

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

◆ iscsi_handle_chap_n_value()

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

Handle iSCSI CHAP_N text value.

Parameters
iscsiiSCSI session
valueCHAP_N value
Return values
rcReturn status code

Definition at line 1074 of file iscsi.c.

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

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

◆ iscsi_handle_chap_r_value()

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

Handle iSCSI CHAP_R text value.

Parameters
iscsiiSCSI session
valueCHAP_R value
Return values
rcReturn status code

Definition at line 1103 of file iscsi.c.

1104  {
1105  uint8_t *buf;
1106  int len;
1107  int rc;
1108 
1109  /* Generate CHAP response for verification */
1110  chap_finish ( &iscsi->chap );
1111  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1112  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1113  iscsi, strerror ( rc ) );
1114  goto err_chap_init;
1115  }
1116  chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1117  if ( iscsi->target_password ) {
1118  chap_update ( &iscsi->chap, iscsi->target_password,
1119  strlen ( iscsi->target_password ) );
1120  }
1121  chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1122  ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1123  chap_respond ( &iscsi->chap );
1124 
1125  /* Allocate decoding buffer */
1126  len = strlen ( value ); /* Decoding never expands data */
1127  buf = malloc ( len );
1128  if ( ! buf ) {
1129  rc = -ENOMEM;
1130  goto err_alloc;
1131  }
1132 
1133  /* Process response */
1134  len = iscsi_large_binary_decode ( value, buf, len );
1135  if ( len < 0 ) {
1136  rc = len;
1137  DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1138  iscsi, value, strerror ( rc ) );
1139  goto err_decode;
1140  }
1141 
1142  /* Check CHAP response */
1143  if ( len != ( int ) iscsi->chap.response_len ) {
1144  DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1145  iscsi );
1147  goto err_response_len;
1148  }
1149  if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1150  DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1151  iscsi, value );
1153  goto err_response;
1154  }
1155 
1156  /* Mark session as authenticated */
1158 
1159  err_response:
1160  err_response_len:
1161  err_decode:
1162  free ( buf );
1163  err_alloc:
1164  err_chap_init:
1165  return rc;
1166 }
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:138
#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:856
#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:569
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition: iscsi.c:66
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:587
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
unsigned char uint8_t
Definition: stdint.h:10
size_t response_len
Length of CHAP response.
Definition: chap.h:26
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:711
uint32_t len
Length.
Definition: ena.h:14
char * target_password
Target password (if any)
Definition: iscsi.h:578
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286

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

◆ iscsi_handle_string()

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

Handle iSCSI string.

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

Definition at line 1205 of file iscsi.c.

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

References DBGC, EPROTO_INVALID_KEY_VALUE_PAIR, EPROTO_VALUE_REJECTED, iscsi_string_types, key_len, 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 1255 of file iscsi.c.

1256  {
1257  size_t string_len;
1258  int rc;
1259 
1260  /* Handle each string in turn, taking care not to overrun the
1261  * data buffer in case of badly-terminated data.
1262  */
1263  while ( 1 ) {
1264  string_len = ( strnlen ( strings, len ) + 1 );
1265  if ( string_len > len )
1266  break;
1267  if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1268  return rc;
1269  strings += string_len;
1270  len -= string_len;
1271  }
1272  return 0;
1273 }
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:1205
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:255
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 1282 of file iscsi.c.

1283  {
1284  switch ( status_class ) {
1286  switch ( status_detail ) {
1293  return -ENODEV;
1294  default :
1295  return -ENOTSUP_INITIATOR_STATUS;
1296  }
1298  switch ( status_detail ) {
1300  return -EIO_TARGET_UNAVAILABLE;
1302  return -EIO_TARGET_NO_RESOURCES;
1303  default:
1304  return -ENOTSUP_TARGET_STATUS;
1305  }
1306  default :
1307  return -EINVAL;
1308  }
1309 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition: iscsi.h:249
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition: iscsi.h:252
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition: iscsi.h:255
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition: iscsi.h:254
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition: iscsi.h:251
#define ISCSI_STATUS_INITIATOR_ERROR
Definition: iscsi.h:248
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition: iscsi.h:250
#define ENODEV
No such device.
Definition: errno.h:509
#define EIO_TARGET_UNAVAILABLE
Definition: iscsi.c:94
#define ENOTSUP_INITIATOR_STATUS
Definition: iscsi.c:102
#define ENOTSUP_TARGET_STATUS
Definition: iscsi.c:114
#define EPERM_INITIATOR_AUTHORISATION
Definition: iscsi.c:122
#define EIO_TARGET_NO_RESOURCES
Definition: iscsi.c:98
#define EPERM_INITIATOR_AUTHENTICATION
Definition: iscsi.c:118
#define ISCSI_STATUS_TARGET_ERROR
Definition: iscsi.h:253

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

Referenced by iscsi_rx_login_response().

◆ iscsi_rx_login_response()

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

Receive data segment of an iSCSI login response PDU.

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

Definition at line 1320 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_tx_pause()

static void iscsi_tx_pause ( struct iscsi_session iscsi)
static

Pause TX engine.

Parameters
iscsiiSCSI session

Definition at line 1418 of file iscsi.c.

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

References iscsi_session::process, and process_del().

Referenced by iscsi_tx_done(), and iscsi_tx_step().

◆ iscsi_tx_resume()

static void iscsi_tx_resume ( struct iscsi_session iscsi)
static

Resume TX engine.

Parameters
iscsiiSCSI session

Definition at line 1427 of file iscsi.c.

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

References iscsi_session::process, and process_add().

Referenced by iscsi_start_tx().

◆ iscsi_tx_nothing()

static int iscsi_tx_nothing ( struct iscsi_session *iscsi  __unused)
static

Transmit nothing.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1459 of file iscsi.c.

1459  {
1460  return 0;
1461 }

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

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_data()

static int iscsi_tx_data ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

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

Definition at line 1483 of file iscsi.c.

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_done()

static void iscsi_tx_done ( struct iscsi_session iscsi)
static

Complete iSCSI PDU transmission.

Parameters
iscsiiSCSI session

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

Definition at line 1506 of file iscsi.c.

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_step()

static void iscsi_tx_step ( struct iscsi_session iscsi)
static

Transmit iSCSI PDU.

Parameters
iscsiiSCSI session
bufTemporary data buffer
lenLength of temporary data buffer

Constructs data to be sent for the current TX state

Definition at line 1534 of file iscsi.c.

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

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

◆ iscsi_rx_bhs()

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

Receive basic header segment of an iSCSI PDU.

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

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

Definition at line 1613 of file iscsi.c.

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

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

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_discard()

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

Discard portion of an iSCSI PDU.

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

This discards data from a portion of a received PDU.

Definition at line 1635 of file iscsi.c.

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

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

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

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

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

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

◆ iscsi_vredirect()

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

Handle redirection event.

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

Definition at line 1782 of file iscsi.c.

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

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

◆ iscsi_scsi_window()

static size_t iscsi_scsi_window ( struct iscsi_session iscsi)
static

Check iSCSI flow-control window.

Parameters
iscsiiSCSI session
Return values
lenLength of window

Definition at line 1838 of file iscsi.c.

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

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

Referenced by iscsi_scsi_command().

◆ iscsi_scsi_command()

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

Issue iSCSI SCSI command.

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

Definition at line 1858 of file iscsi.c.

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

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

◆ iscsi_scsi_capacity()

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

Update SCSI block device capacity.

Parameters
iscsiiSCSI session
capacityBlock device capacity

Definition at line 1894 of file iscsi.c.

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

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

◆ iscsi_describe()

static struct acpi_descriptor* iscsi_describe ( struct iscsi_session iscsi)
static

Get iSCSI ACPI descriptor.

Parameters
iscsiiSCSI session
Return values
descACPI descriptor

Definition at line 1912 of file iscsi.c.

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

References iscsi_session::desc.

◆ iscsi_command_close()

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

Close iSCSI command.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 1937 of file iscsi.c.

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

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

◆ __setting() [1/2]

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

iSCSI initiator IQN setting

◆ __setting() [2/2]

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

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

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

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

Referenced by iscsi_open().

◆ iscsi_fetch_settings()

static int iscsi_fetch_settings ( struct iscsi_session iscsi)
static

Fetch iSCSI settings.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2080 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_check_auth()

static int iscsi_check_auth ( struct iscsi_session iscsi)
static

Check iSCSI authentication details.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2143 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_open()

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

Open iSCSI URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 2174 of file iscsi.c.

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

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

Variable Documentation

◆ iscsi_string_types

struct iscsi_string_type iscsi_string_types[]
static
Initial value:
= {
{ "TargetAddress", iscsi_handle_targetaddress_value },
{ "MaxBurstLength", iscsi_handle_maxburstlength_value },
{ "AuthMethod", iscsi_handle_authmethod_value },
{ NULL, NULL }
}
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition: iscsi.c:955
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition: iscsi.c:1019
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition: iscsi.c:1074
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition: iscsi.c:909
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition: iscsi.c:1103
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition: iscsi.c:879
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition: iscsi.c:978
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition: iscsi.c:930
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321

iSCSI text strings that we want to handle

Definition at line 1186 of file iscsi.c.

Referenced by iscsi_handle_string().

◆ iscsi_process_desc

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

iSCSI TX process descriptor

Definition at line 1598 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_socket_operations

struct interface_operation iscsi_socket_operations[]
static
Initial value:
= {
}
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition: xfer.c:62
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition: iscsi.c:1782
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:224
#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:1698
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1427

iSCSI socket interface operations

Definition at line 1814 of file iscsi.c.

◆ iscsi_socket_desc

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

iSCSI socket interface descriptor

Definition at line 1823 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_control_op

struct interface_operation iscsi_control_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:129
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
A SCSI command.
Definition: scsi.c:262
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:224
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition: iscsi.c:1894
#define EFI_INTF_OP
Definition: efi.h:350
#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:1912
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:313
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition: efi_path.c:433
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:680
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1838
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition: iscsi.c:1858

iSCSI SCSI command-issuing interface operations

Definition at line 1918 of file iscsi.c.

◆ iscsi_control_desc

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

iSCSI SCSI command-issuing interface descriptor

Definition at line 1928 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_data_op

struct interface_operation iscsi_data_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
An iSCSI session.
Definition: iscsi.h:544
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition: iscsi.c:1937
#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 1950 of file iscsi.c.

◆ iscsi_data_desc

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

iSCSI SCSI command interface descriptor

Definition at line 1955 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:2174

iSCSI URI opener

Definition at line 2256 of file iscsi.c.