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/iscsi.h>

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

iSCSI protocol

Definition in file iscsi.c.

Macro Definition Documentation

◆ EACCES_INCORRECT_TARGET_USERNAME

#define EACCES_INCORRECT_TARGET_USERNAME   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

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

◆ EACCES_INCORRECT_TARGET_PASSWORD

#define EACCES_INCORRECT_TARGET_PASSWORD   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

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

◆ EINVAL_BAD_CREDENTIAL_MIX

#define EINVAL_BAD_CREDENTIAL_MIX   __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

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

◆ EINVAL_NO_ROOT_PATH

#define EINVAL_NO_ROOT_PATH   __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

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

◆ EINVAL_NO_TARGET_IQN

#define EINVAL_NO_TARGET_IQN   __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

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

◆ EINVAL_NO_INITIATOR_IQN

#define EINVAL_NO_INITIATOR_IQN   __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

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

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

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

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

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

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 96 of file iscsi.c.

◆ EINFO_ENOTSUP_INITIATOR_STATUS

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

Definition at line 98 of file iscsi.c.

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 100 of file iscsi.c.

◆ EINFO_ENOTSUP_OPCODE

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

Definition at line 102 of file iscsi.c.

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 104 of file iscsi.c.

◆ EINFO_ENOTSUP_DISCOVERY

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

Definition at line 106 of file iscsi.c.

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 108 of file iscsi.c.

◆ EINFO_ENOTSUP_TARGET_STATUS

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

Definition at line 110 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 112 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

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

Definition at line 114 of file iscsi.c.

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 116 of file iscsi.c.

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

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

Definition at line 118 of file iscsi.c.

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

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

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

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

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

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

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

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

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 140 of file iscsi.c.

◆ EINFO_EPROTO_VALUE_REJECTED

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

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

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

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

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

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

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

◆ iscsi_start_login()

static void iscsi_start_login ( struct iscsi_session iscsi)
static

Build iSCSI login request BHS.

Parameters
iscsiiSCSI session

Definition at line 758 of file iscsi.c.

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

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

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

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

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

References free, NULL, and iscsi_session::rx_buffer.

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

◆ iscsi_rx_buffered_data()

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

Receive PDU data into buffer.

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

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

Definition at line 173 of file iscsi.c.

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

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

Referenced by iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_free()

static void iscsi_free ( struct refcnt refcnt)
static

Free iSCSI session.

Parameters
refcntReference counter

Definition at line 195 of file iscsi.c.

195  {
196  struct iscsi_session *iscsi =
198 
199  free ( iscsi->initiator_iqn );
200  free ( iscsi->target_address );
201  free ( iscsi->target_iqn );
202  free ( iscsi->initiator_username );
203  free ( iscsi->initiator_password );
204  free ( iscsi->target_username );
205  free ( iscsi->target_password );
206  chap_finish ( &iscsi->chap );
207  iscsi_rx_buffered_data_done ( iscsi );
208  free ( iscsi->command );
209  free ( iscsi );
210 }
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:563
An iSCSI session.
Definition: iscsi.h:535
A reference counter.
Definition: refcnt.h:26
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:565
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:155
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
char * target_address
Target address.
Definition: iscsi.h:549
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
char * target_iqn
Target IQN.
Definition: iscsi.h:553
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
char * target_password
Target password (if any)
Definition: iscsi.h:569
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
char * target_username
Target username (if any)
Definition: iscsi.h:567

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

Referenced by iscsi_open().

◆ iscsi_close()

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

Shut down iSCSI interface.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 218 of file iscsi.c.

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

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

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

◆ iscsi_new_itt()

static void iscsi_new_itt ( struct iscsi_session iscsi)
static

Assign new iSCSI initiator task tag.

Parameters
iscsiiSCSI session

Definition at line 239 of file iscsi.c.

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

References ISCSI_TAG_MAGIC, and iscsi_session::itt.

Referenced by iscsi_open_connection(), and iscsi_scsi_command().

◆ iscsi_open_connection()

static int iscsi_open_connection ( struct iscsi_session iscsi)
static

Open iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 251 of file iscsi.c.

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

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

Referenced by iscsi_open(), and iscsi_rx_login_response().

◆ iscsi_close_connection()

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

Close iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
rcReason for close

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

Definition at line 298 of file iscsi.c.

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

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

Referenced by iscsi_rx_login_response().

◆ iscsi_scsi_done()

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

Mark iSCSI SCSI operation as complete.

Parameters
iscsiiSCSI session
rcReturn status code
rspSCSI response, if any

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

Definition at line 330 of file iscsi.c.

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

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

Referenced by iscsi_rx_data_in(), and iscsi_rx_scsi_response().

◆ iscsi_start_command()

static void iscsi_start_command ( struct iscsi_session iscsi)
static

Build iSCSI SCSI command BHS.

Parameters
iscsiiSCSI session

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

Definition at line 368 of file iscsi.c.

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

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

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

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

Referenced by iscsi_rx_data().

◆ iscsi_rx_data_in()

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

Receive data segment of an iSCSI data-in PDU.

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

Definition at line 461 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_rx_r2t()

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

Receive data segment of an iSCSI R2T PDU.

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

Definition at line 498 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_data_out_done()

static void iscsi_data_out_done ( struct iscsi_session iscsi)
static

Complete iSCSI data-out PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 557 of file iscsi.c.

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

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

Referenced by iscsi_tx_done().

◆ iscsi_tx_data_out()

static int iscsi_tx_data_out ( struct iscsi_session iscsi)
static

Send iSCSI data-out data segment.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 573 of file iscsi.c.

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

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

Referenced by iscsi_tx_data().

◆ iscsi_rx_nop_in()

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

Receive data segment of an iSCSI NOP-In.

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

Definition at line 608 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_build_login_request_strings()

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

Build iSCSI login request strings.

Parameters
iscsiiSCSI session

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

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

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

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

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

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

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

Definition at line 683 of file iscsi.c.

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

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

Referenced by iscsi_start_login(), and iscsi_tx_login_request().

◆ iscsi_login_request_done()

static void iscsi_login_request_done ( struct iscsi_session iscsi)
static

Complete iSCSI login request PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 800 of file iscsi.c.

800  {
801 
802  /* Clear any "strings to send" flags */
804 
805  /* Free any dynamically allocated storage used for login */
806  chap_finish ( &iscsi->chap );
807 }
int status
Session status.
Definition: iscsi.h:560
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition: iscsi.h:690
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578

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

Referenced by iscsi_tx_done().

◆ iscsi_tx_login_request()

static int iscsi_tx_login_request ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI login request PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

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

Definition at line 817 of file iscsi.c.

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

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

Referenced by iscsi_tx_data().

◆ iscsi_large_binary_decode()

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

Decode large binary value.

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

Definition at line 843 of file iscsi.c.

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

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

867  {
868  char *separator;
869 
870  DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
871 
872  /* Replace target address */
873  free ( iscsi->target_address );
874  iscsi->target_address = strdup ( value );
875  if ( ! iscsi->target_address )
876  return -ENOMEM;
877 
878  /* Replace target port */
879  iscsi->target_port = htons ( ISCSI_PORT );
880  separator = strchr ( iscsi->target_address, ':' );
881  if ( separator ) {
882  *separator = '\0';
883  iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
884  }
885 
886  return 0;
887 }
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:441
#define DBGC(...)
Definition: compiler.h:505
unsigned int target_port
Target port.
Definition: iscsi.h:551
#define ENOMEM
Not enough space.
Definition: errno.h:534
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
#define ISCSI_PORT
Default iSCSI port.
Definition: iscsi.h:23
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:241
char * strdup(const char *src)
Duplicate string.
Definition: string.c:350
char * target_address
Target address.
Definition: iscsi.h:549
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
#define htons(value)
Definition: byteswap.h:135

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

◆ iscsi_handle_authmethod_value()

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

Handle iSCSI AuthMethod text value.

Parameters
iscsiiSCSI session
valueAuthMethod value
Return values
rcReturn status code

Definition at line 896 of file iscsi.c.

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

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

◆ iscsi_handle_chap_a_value()

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

Handle iSCSI CHAP_A text value.

Parameters
iscsiiSCSI session
valueCHAP_A value
Return values
rcReturn status code

Definition at line 917 of file iscsi.c.

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

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

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

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

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

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

◆ iscsi_handle_chap_n_value()

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

Handle iSCSI CHAP_N text value.

Parameters
iscsiiSCSI session
valueCHAP_N value
Return values
rcReturn status code

Definition at line 1036 of file iscsi.c.

1037  {
1038 
1039  /* The target username isn't actually involved at any point in
1040  * the authentication process; it merely serves to identify
1041  * which password the target is using to generate the CHAP
1042  * response. We unnecessarily verify that the username is as
1043  * expected, in order to provide mildly helpful diagnostics if
1044  * the target is supplying the wrong username/password
1045  * combination.
1046  */
1047  if ( iscsi->target_username &&
1048  ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1049  DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1050  "(wanted \"%s\")\n",
1051  iscsi, value, iscsi->target_username );
1053  }
1054 
1055  return 0;
1056 }
#define DBGC(...)
Definition: compiler.h:505
#define EACCES_INCORRECT_TARGET_USERNAME
Definition: iscsi.c:60
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:157
char * target_username
Target username (if any)
Definition: iscsi.h:567

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

◆ iscsi_handle_chap_r_value()

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

Handle iSCSI CHAP_R text value.

Parameters
iscsiiSCSI session
valueCHAP_R value
Return values
rcReturn status code

Definition at line 1065 of file iscsi.c.

1066  {
1067  uint8_t *buf;
1068  int len;
1069  int rc;
1070 
1071  /* Generate CHAP response for verification */
1072  chap_finish ( &iscsi->chap );
1073  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1074  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1075  iscsi, strerror ( rc ) );
1076  goto err_chap_init;
1077  }
1078  chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1079  if ( iscsi->target_password ) {
1080  chap_update ( &iscsi->chap, iscsi->target_password,
1081  strlen ( iscsi->target_password ) );
1082  }
1083  chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1084  ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1085  chap_respond ( &iscsi->chap );
1086 
1087  /* Allocate decoding buffer */
1088  len = strlen ( value ); /* Decoding never expands data */
1089  buf = malloc ( len );
1090  if ( ! buf ) {
1091  rc = -ENOMEM;
1092  goto err_alloc;
1093  }
1094 
1095  /* Process response */
1096  len = iscsi_large_binary_decode ( value, buf, len );
1097  if ( len < 0 ) {
1098  rc = len;
1099  DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1100  iscsi, value, strerror ( rc ) );
1101  goto err_decode;
1102  }
1103 
1104  /* Check CHAP response */
1105  if ( len != ( int ) iscsi->chap.response_len ) {
1106  DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1107  iscsi );
1109  goto err_response_len;
1110  }
1111  if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1112  DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1113  iscsi, value );
1115  goto err_response;
1116  }
1117 
1118  /* Mark session as authenticated */
1120 
1121  err_response:
1122  err_response_len:
1123  err_decode:
1124  free ( buf );
1125  err_alloc:
1126  err_chap_init:
1127  return rc;
1128 }
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:132
#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:843
#define ENOMEM
Not enough space.
Definition: errno.h:534
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition: chap.c:51
int status
Session status.
Definition: iscsi.h:560
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition: iscsi.c:64
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:578
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
unsigned char uint8_t
Definition: stdint.h:10
size_t response_len
Length of CHAP response.
Definition: chap.h:26
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:576
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:699
uint32_t len
Length.
Definition: ena.h:14
char * target_password
Target password (if any)
Definition: iscsi.h:569
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
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:287

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

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

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

Referenced by iscsi_handle_strings().

◆ iscsi_handle_strings()

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

Handle iSCSI strings.

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

Definition at line 1216 of file iscsi.c.

1217  {
1218  size_t string_len;
1219  int rc;
1220 
1221  /* Handle each string in turn, taking care not to overrun the
1222  * data buffer in case of badly-terminated data.
1223  */
1224  while ( 1 ) {
1225  string_len = ( strnlen ( strings, len ) + 1 );
1226  if ( string_len > len )
1227  break;
1228  if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1229  return rc;
1230  strings += string_len;
1231  len -= string_len;
1232  }
1233  return 0;
1234 }
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:1166
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:225
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 1243 of file iscsi.c.

1244  {
1245  switch ( status_class ) {
1247  switch ( status_detail ) {
1254  return -ENODEV;
1255  default :
1256  return -ENOTSUP_INITIATOR_STATUS;
1257  }
1259  switch ( status_detail ) {
1261  return -EIO_TARGET_UNAVAILABLE;
1263  return -EIO_TARGET_NO_RESOURCES;
1264  default:
1265  return -ENOTSUP_TARGET_STATUS;
1266  }
1267  default :
1268  return -EINVAL;
1269  }
1270 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition: iscsi.h:240
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition: iscsi.h:243
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition: iscsi.h:246
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition: iscsi.h:245
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition: iscsi.h:242
#define ISCSI_STATUS_INITIATOR_ERROR
Definition: iscsi.h:239
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition: iscsi.h:241
#define ENODEV
No such device.
Definition: errno.h:509
#define EIO_TARGET_UNAVAILABLE
Definition: iscsi.c:88
#define ENOTSUP_INITIATOR_STATUS
Definition: iscsi.c:96
#define ENOTSUP_TARGET_STATUS
Definition: iscsi.c:108
#define EPERM_INITIATOR_AUTHORISATION
Definition: iscsi.c:116
#define EIO_TARGET_NO_RESOURCES
Definition: iscsi.c:92
#define EPERM_INITIATOR_AUTHENTICATION
Definition: iscsi.c:112
#define ISCSI_STATUS_TARGET_ERROR
Definition: iscsi.h:244

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

Referenced by iscsi_rx_login_response().

◆ iscsi_rx_login_response()

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

Receive data segment of an iSCSI login response PDU.

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

Definition at line 1281 of file iscsi.c.

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

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

Referenced by iscsi_rx_data().

◆ iscsi_tx_pause()

static void iscsi_tx_pause ( struct iscsi_session iscsi)
static

Pause TX engine.

Parameters
iscsiiSCSI session

Definition at line 1379 of file iscsi.c.

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

References iscsi_session::process, and process_del().

Referenced by iscsi_tx_done(), and iscsi_tx_step().

◆ iscsi_tx_resume()

static void iscsi_tx_resume ( struct iscsi_session iscsi)
static

Resume TX engine.

Parameters
iscsiiSCSI session

Definition at line 1388 of file iscsi.c.

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

References iscsi_session::process, and process_add().

Referenced by iscsi_start_tx().

◆ iscsi_tx_nothing()

static int iscsi_tx_nothing ( struct iscsi_session *iscsi  __unused)
static

Transmit nothing.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1420 of file iscsi.c.

1420  {
1421  return 0;
1422 }

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

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_data()

static int iscsi_tx_data ( struct iscsi_session iscsi)
static

Transmit data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

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

Definition at line 1444 of file iscsi.c.

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_done()

static void iscsi_tx_done ( struct iscsi_session iscsi)
static

Complete iSCSI PDU transmission.

Parameters
iscsiiSCSI session

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

Definition at line 1467 of file iscsi.c.

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

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_step()

static void iscsi_tx_step ( struct iscsi_session iscsi)
static

Transmit iSCSI PDU.

Parameters
iscsiiSCSI session
bufTemporary data buffer
lenLength of temporary data buffer

Constructs data to be sent for the current TX state

Definition at line 1495 of file iscsi.c.

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

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

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

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

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_discard()

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

Discard portion of an iSCSI PDU.

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

This discards data from a portion of a received PDU.

Definition at line 1596 of file iscsi.c.

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

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

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

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

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

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

◆ iscsi_vredirect()

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

Handle redirection event.

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

Definition at line 1743 of file iscsi.c.

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

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

◆ iscsi_scsi_window()

static size_t iscsi_scsi_window ( struct iscsi_session iscsi)
static

Check iSCSI flow-control window.

Parameters
iscsiiSCSI session
Return values
lenLength of window

Definition at line 1799 of file iscsi.c.

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

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

Referenced by iscsi_scsi_command().

◆ iscsi_scsi_command()

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

Issue iSCSI SCSI command.

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

Definition at line 1819 of file iscsi.c.

1821  {
1822 
1823  /* This iSCSI implementation cannot handle multiple concurrent
1824  * commands or commands arriving before login is complete.
1825  */
1826  if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1827  DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1828  iscsi );
1829  return -EOPNOTSUPP;
1830  }
1831 
1832  /* Store command */
1833  iscsi->command = malloc ( sizeof ( *command ) );
1834  if ( ! iscsi->command )
1835  return -ENOMEM;
1836  memcpy ( iscsi->command, command, sizeof ( *command ) );
1837 
1838  /* Assign new ITT */
1839  iscsi_new_itt ( iscsi );
1840 
1841  /* Start sending command */
1842  iscsi_start_command ( iscsi );
1843 
1844  /* Attach to parent interface and return */
1845  intf_plug_plug ( &iscsi->data, parent );
1846  return iscsi->itt;
1847 }
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition: iscsi.c:239
A command-line command.
Definition: command.h:9
#define DBGC(...)
Definition: compiler.h:505
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:102
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
uint32_t itt
Initiator task tag.
Definition: iscsi.h:591
#define EOPNOTSUPP
Operation not supported on socket.
Definition: errno.h:604
struct interface data
SCSI command interface.
Definition: iscsi.h:542
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition: iscsi.c:368
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1799

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

◆ iscsi_describe()

static struct acpi_descriptor* iscsi_describe ( struct iscsi_session iscsi)
static

Get iSCSI ACPI descriptor.

Parameters
iscsiiSCSI session
Return values
descACPI descriptor

Definition at line 1855 of file iscsi.c.

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

References iscsi_session::desc.

◆ iscsi_command_close()

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

Close iSCSI command.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 1878 of file iscsi.c.

1878  {
1879 
1880  /* Restart interface */
1881  intf_restart ( &iscsi->data, rc );
1882 
1883  /* Treat unsolicited command closures mid-command as fatal,
1884  * because we have no code to handle partially-completed PDUs.
1885  */
1886  if ( iscsi->command != NULL )
1887  iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1888 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:337
#define ECANCELED
Operation canceled.
Definition: errno.h:343
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:218
struct interface data
SCSI command interface.
Definition: iscsi.h:542
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:646
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

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

◆ __setting() [1/2]

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

iSCSI initiator IQN setting

◆ __setting() [2/2]

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

iSCSI reverse username setting

iSCSI reverse password setting

◆ iscsi_parse_root_path()

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

Parse iSCSI root path.

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

Definition at line 1949 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_fetch_settings()

static int iscsi_fetch_settings ( struct iscsi_session iscsi)
static

Fetch iSCSI settings.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2021 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_check_auth()

static int iscsi_check_auth ( struct iscsi_session iscsi)
static

Check iSCSI authentication details.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2084 of file iscsi.c.

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

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

Referenced by iscsi_open().

◆ iscsi_open()

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

Open iSCSI URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 2115 of file iscsi.c.

2115  {
2116  struct iscsi_session *iscsi;
2117  int rc;
2118 
2119  /* Sanity check */
2120  if ( ! uri->opaque ) {
2122  goto err_sanity_uri;
2123  }
2124 
2125  /* Allocate and initialise structure */
2126  iscsi = zalloc ( sizeof ( *iscsi ) );
2127  if ( ! iscsi ) {
2128  rc = -ENOMEM;
2129  goto err_zalloc;
2130  }
2131  ref_init ( &iscsi->refcnt, iscsi_free );
2132  intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2133  intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2134  intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2136  &iscsi->refcnt );
2137  acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2138 
2139  /* Parse root path */
2140  if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2141  goto err_parse_root_path;
2142  /* Set fields not specified by root path */
2143  if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2144  goto err_fetch_settings;
2145  /* Validate authentication */
2146  if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2147  goto err_check_auth;
2148 
2149  /* Sanity checks */
2150  if ( ! iscsi->target_address ) {
2151  DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2152  iscsi );
2153  rc = -ENOTSUP_DISCOVERY;
2154  goto err_sanity_address;
2155  }
2156  if ( ! iscsi->target_iqn ) {
2157  DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2158  iscsi, uri->opaque );
2160  goto err_sanity_iqn;
2161  }
2162  DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2163  DBGC ( iscsi, "iSCSI %p target %s %s\n",
2164  iscsi, iscsi->target_address, iscsi->target_iqn );
2165 
2166  /* Open socket */
2167  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2168  goto err_open_connection;
2169 
2170  /* Attach SCSI device to parent interface */
2171  if ( ( rc = scsi_open ( parent, &iscsi->control,
2172  &iscsi->lun ) ) != 0 ) {
2173  DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2174  iscsi, strerror ( rc ) );
2175  goto err_scsi_open;
2176  }
2177 
2178  /* Mortalise self, and return */
2179  ref_put ( &iscsi->refcnt );
2180  return 0;
2181 
2182  err_scsi_open:
2183  err_open_connection:
2184  err_sanity_iqn:
2185  err_sanity_address:
2186  err_check_auth:
2187  err_fetch_settings:
2188  err_parse_root_path:
2189  iscsi_close ( iscsi, rc );
2190  ref_put ( &iscsi->refcnt );
2191  err_zalloc:
2192  err_sanity_uri:
2193  return rc;
2194 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define ENOTSUP_DISCOVERY
Definition: iscsi.c:104
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition: iscsi.c:2021
An iSCSI session.
Definition: iscsi.h:535
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition: iscsi.c:1949
struct interface socket
Transport-layer socket.
Definition: iscsi.h:544
#define DBGC(...)
Definition: compiler.h:505
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition: scsi.c:980
#define EINVAL_NO_TARGET_IQN
Definition: iscsi.c:80
#define ENOMEM
Not enough space.
Definition: errno.h:534
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:540
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:653
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:218
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition: iscsi.c:1869
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition: iscsi.c:1559
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: iscsi.h:651
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
struct process process
TX process.
Definition: iscsi.h:632
char * target_address
Target address.
Definition: iscsi.h:549
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition: iscsi.c:2084
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
struct interface data
SCSI command interface.
Definition: iscsi.h:542
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition: iscsi.c:195
char * target_iqn
Target IQN.
Definition: iscsi.h:553
const char * opaque
Opaque part.
Definition: uri.h:56
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition: iscsi.c:251
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition: iscsi.c:1784
A Uniform Resource Identifier.
Definition: uri.h:50
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:547
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:173
#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:160
#define EINVAL_NO_ROOT_PATH
Definition: iscsi.c:76
struct refcnt refcnt
Reference counter.
Definition: iscsi.h:537
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition: iscsi.c:1896

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

Variable Documentation

◆ iscsi_string_types

struct iscsi_string_type iscsi_string_types[]
static
Initial value:
= {
{ "TargetAddress", iscsi_handle_targetaddress_value },
{ "AuthMethod", iscsi_handle_authmethod_value },
{ NULL, NULL }
}
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition: iscsi.c:917
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition: iscsi.c:981
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition: iscsi.c:1036
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition: iscsi.c:896
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition: iscsi.c:1065
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition: iscsi.c:866
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition: iscsi.c:940
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

iSCSI text strings that we want to handle

Definition at line 1148 of file iscsi.c.

Referenced by iscsi_handle_string().

◆ iscsi_process_desc

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

iSCSI TX process descriptor

Definition at line 1559 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_socket_operations

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

iSCSI socket interface operations

Definition at line 1775 of file iscsi.c.

◆ iscsi_socket_desc

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

iSCSI socket interface descriptor

Definition at line 1784 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_control_op

struct interface_operation iscsi_control_op[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:244
An iSCSI session.
Definition: iscsi.h:535
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:115
A SCSI command.
Definition: scsi.c:262
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:218
#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:1855
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:334
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1799
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition: iscsi.c:1819

iSCSI SCSI command-issuing interface operations

Definition at line 1861 of file iscsi.c.

◆ iscsi_control_desc

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

iSCSI SCSI command-issuing interface descriptor

Definition at line 1869 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_data_op

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

◆ iscsi_data_desc

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

iSCSI SCSI command interface descriptor

Definition at line 1896 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:2115

iSCSI URI opener

Definition at line 2197 of file iscsi.c.