iPXE
iscsi.c File Reference

iSCSI protocol More...

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

Go to the source code of this file.

Data Structures

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

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

iSCSI protocol

Definition in file iscsi.c.

Macro Definition Documentation

◆ EACCES_INCORRECT_TARGET_USERNAME

#define EACCES_INCORRECT_TARGET_USERNAME   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

Definition at line 62 of file iscsi.c.

62#define EACCES_INCORRECT_TARGET_USERNAME \
63 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

Referenced by iscsi_handle_chap_n_value().

◆ EINFO_EACCES_INCORRECT_TARGET_USERNAME

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

Definition at line 64 of file iscsi.c.

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

◆ EACCES_INCORRECT_TARGET_PASSWORD

#define EACCES_INCORRECT_TARGET_PASSWORD   __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Definition at line 66 of file iscsi.c.

66#define EACCES_INCORRECT_TARGET_PASSWORD \
67 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Referenced by iscsi_handle_chap_r_value().

◆ EINFO_EACCES_INCORRECT_TARGET_PASSWORD

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

Definition at line 68 of file iscsi.c.

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

◆ EINVAL_ROOT_PATH_TOO_SHORT

#define EINVAL_ROOT_PATH_TOO_SHORT   __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )

Definition at line 70 of file iscsi.c.

70#define EINVAL_ROOT_PATH_TOO_SHORT \
71 __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )

Referenced by iscsi_parse_root_path().

◆ EINFO_EINVAL_ROOT_PATH_TOO_SHORT

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

Definition at line 72 of file iscsi.c.

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

◆ EINVAL_BAD_CREDENTIAL_MIX

#define EINVAL_BAD_CREDENTIAL_MIX   __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

Definition at line 74 of file iscsi.c.

74#define EINVAL_BAD_CREDENTIAL_MIX \
75 __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

Referenced by iscsi_check_auth().

◆ EINFO_EINVAL_BAD_CREDENTIAL_MIX

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

Definition at line 76 of file iscsi.c.

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

◆ EINVAL_NO_ROOT_PATH

#define EINVAL_NO_ROOT_PATH   __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

Definition at line 78 of file iscsi.c.

78#define EINVAL_NO_ROOT_PATH \
79 __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

Referenced by iscsi_open().

◆ EINFO_EINVAL_NO_ROOT_PATH

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

Definition at line 80 of file iscsi.c.

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

◆ EINVAL_NO_TARGET_IQN

#define EINVAL_NO_TARGET_IQN   __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

Definition at line 82 of file iscsi.c.

82#define EINVAL_NO_TARGET_IQN \
83 __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

Referenced by iscsi_open().

◆ EINFO_EINVAL_NO_TARGET_IQN

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

Definition at line 84 of file iscsi.c.

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

◆ EINVAL_NO_INITIATOR_IQN

#define EINVAL_NO_INITIATOR_IQN   __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

Definition at line 86 of file iscsi.c.

86#define EINVAL_NO_INITIATOR_IQN \
87 __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

Referenced by iscsi_fetch_settings().

◆ EINFO_EINVAL_NO_INITIATOR_IQN

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

Definition at line 88 of file iscsi.c.

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

◆ EINVAL_MAXBURSTLENGTH

#define EINVAL_MAXBURSTLENGTH   __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Definition at line 90 of file iscsi.c.

90#define EINVAL_MAXBURSTLENGTH \
91 __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Referenced by iscsi_handle_maxburstlength_value().

◆ EINFO_EINVAL_MAXBURSTLENGTH

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

Definition at line 92 of file iscsi.c.

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

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE   __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Definition at line 94 of file iscsi.c.

94#define EIO_TARGET_UNAVAILABLE \
95 __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Referenced by iscsi_status_to_rc().

◆ EINFO_EIO_TARGET_UNAVAILABLE

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

Definition at line 96 of file iscsi.c.

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

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES   __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Definition at line 98 of file iscsi.c.

98#define EIO_TARGET_NO_RESOURCES \
99 __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Referenced by iscsi_status_to_rc().

◆ EINFO_EIO_TARGET_NO_RESOURCES

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

Definition at line 100 of file iscsi.c.

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

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS   __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 102 of file iscsi.c.

102#define ENOTSUP_INITIATOR_STATUS \
103 __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Referenced by iscsi_status_to_rc().

◆ EINFO_ENOTSUP_INITIATOR_STATUS

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

Definition at line 104 of file iscsi.c.

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

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE   __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 106 of file iscsi.c.

106#define ENOTSUP_OPCODE \
107 __einfo_error ( EINFO_ENOTSUP_OPCODE )

Referenced by iscsi_rx_data().

◆ EINFO_ENOTSUP_OPCODE

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

Definition at line 108 of file iscsi.c.

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

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY   __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 110 of file iscsi.c.

110#define ENOTSUP_DISCOVERY \
111 __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Referenced by iscsi_open().

◆ EINFO_ENOTSUP_DISCOVERY

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

Definition at line 112 of file iscsi.c.

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

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS   __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 114 of file iscsi.c.

114#define ENOTSUP_TARGET_STATUS \
115 __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Referenced by iscsi_status_to_rc().

◆ EINFO_ENOTSUP_TARGET_STATUS

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

Definition at line 116 of file iscsi.c.

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

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 118 of file iscsi.c.

118#define EPERM_INITIATOR_AUTHENTICATION \
119 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Referenced by iscsi_status_to_rc().

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

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

Definition at line 120 of file iscsi.c.

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

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION   __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 122 of file iscsi.c.

122#define EPERM_INITIATOR_AUTHORISATION \
123 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Referenced by iscsi_status_to_rc().

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

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

Definition at line 124 of file iscsi.c.

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

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Definition at line 126 of file iscsi.c.

126#define EPROTO_INVALID_CHAP_ALGORITHM \
127 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Referenced by iscsi_handle_chap_a_value().

◆ EINFO_EPROTO_INVALID_CHAP_ALGORITHM

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

Definition at line 128 of file iscsi.c.

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

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Definition at line 130 of file iscsi.c.

130#define EPROTO_INVALID_CHAP_IDENTIFIER \
131 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Referenced by iscsi_handle_chap_i_value().

◆ EINFO_EPROTO_INVALID_CHAP_IDENTIFIER

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

Definition at line 132 of file iscsi.c.

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

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY   __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Definition at line 134 of file iscsi.c.

134#define EPROTO_INVALID_LARGE_BINARY \
135 __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Referenced by iscsi_large_binary_decode().

◆ EINFO_EPROTO_INVALID_LARGE_BINARY

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

Definition at line 136 of file iscsi.c.

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

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE   __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Definition at line 138 of file iscsi.c.

138#define EPROTO_INVALID_CHAP_RESPONSE \
139 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Referenced by iscsi_handle_chap_r_value().

◆ EINFO_EPROTO_INVALID_CHAP_RESPONSE

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

Definition at line 140 of file iscsi.c.

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

◆ EPROTO_INVALID_KEY_VALUE_PAIR

#define EPROTO_INVALID_KEY_VALUE_PAIR   __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )

Definition at line 142 of file iscsi.c.

142#define EPROTO_INVALID_KEY_VALUE_PAIR \
143 __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )

Referenced by iscsi_handle_string().

◆ EINFO_EPROTO_INVALID_KEY_VALUE_PAIR

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

Definition at line 144 of file iscsi.c.

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

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED   __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 146 of file iscsi.c.

146#define EPROTO_VALUE_REJECTED \
147 __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Referenced by iscsi_handle_string().

◆ EINFO_EPROTO_VALUE_REJECTED

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

Definition at line 148 of file iscsi.c.

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

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

1983 {
1984 RP_SERVERNAME = 0,
1986 RP_PORT,
1987 RP_LUN,
1990};
@ NUM_RP_COMPONENTS
Definition iscsi.c:1989
@ RP_SERVERNAME
Definition iscsi.c:1984
@ RP_PORT
Definition iscsi.c:1986
@ RP_PROTOCOL
Definition iscsi.c:1985
@ RP_TARGETNAME
Definition iscsi.c:1988
@ RP_LUN
Definition iscsi.c:1987

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL ,
"iSCSI" ,
DHCP_EB_FEATURE_ISCSI ,
1  )

◆ iscsi_start_tx()

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

1457 {
1458
1459 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1460
1461 /* Initialise TX BHS */
1462 memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1463
1464 /* Flag TX engine to start transmitting */
1465 iscsi->tx_state = ISCSI_TX_BHS;
1466
1467 /* Start transmission process */
1468 iscsi_tx_resume ( iscsi );
1469}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void * memset(void *dest, int character, size_t len) __nonnull
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition iscsi.c:1445
@ ISCSI_TX_BHS
Sending the basic header segment.
Definition iscsi.h:525
@ ISCSI_TX_IDLE
Nothing to send.
Definition iscsi.h:523
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition iscsi.h:641
enum iscsi_tx_state tx_state
State of the TX engine.
Definition iscsi.h:643

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()

void iscsi_start_login ( struct iscsi_session * iscsi)
static

Build iSCSI login request BHS.

Parameters
iscsiiSCSI session

Definition at line 789 of file iscsi.c.

789 {
791 int len;
792
793 switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
795 DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
796 iscsi );
797 break;
799 DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
800 iscsi );
801 break;
802 default:
803 assert ( 0 );
804 }
805
806 /* Construct BHS and initiate transmission */
807 iscsi_start_tx ( iscsi );
810 request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
812 /* version_max and version_min left as zero */
814 ISCSI_SET_LENGTHS ( request->lengths, 0, len );
815 request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
817 request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
818 /* tsih left as zero */
819 request->itt = htonl ( iscsi->itt );
820 /* cid left as zero */
821 request->cmdsn = htonl ( iscsi->cmdsn );
822 request->expstatsn = htonl ( iscsi->statsn + 1 );
823}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:530
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition iscsi.c:710
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition iscsi.c:1457
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
Definition iscsi.h:185
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
Definition iscsi.h:100
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition iscsi.h:174
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition iscsi.h:685
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition iscsi.h:177
#define ISCSI_LOGIN_CSG_MASK
Definition iscsi.h:183
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
Definition iscsi.h:202
#define ISCSI_ISID_IANA
ISID IANA format marker.
Definition iscsi.h:195
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
Definition iscsi.h:184
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition iscsi.h:70
iSCSI login request basic header segment
Definition iscsi.h:142
uint32_t cmdsn
Command sequence number.
Definition iscsi.h:630
uint32_t itt
Initiator task tag.
Definition iscsi.h:604
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition iscsi.h:598
int status
Session status.
Definition iscsi.h:570
uint32_t statsn
Status sequence number.
Definition iscsi.h:638
struct iscsi_bhs_login_request login_request
Definition iscsi.h:509

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()

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

530 {
531 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
532 unsigned long offset;
533 unsigned long remaining;
534 unsigned long len;
535
536 /* We always send 512-byte Data-Out PDUs; this removes the
537 * need to worry about the target's MaxRecvDataSegmentLength.
538 */
539 offset = datasn * 512;
540 remaining = iscsi->transfer_len - offset;
541 len = remaining;
542 if ( len > 512 )
543 len = 512;
544
545 /* Construct BHS and initiate transmission */
546 iscsi_start_tx ( iscsi );
547 data_out->opcode = ISCSI_OPCODE_DATA_OUT;
548 if ( len == remaining )
549 data_out->flags = ( ISCSI_FLAG_FINAL );
550 ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
551 data_out->lun = iscsi->command->lun;
552 data_out->itt = htonl ( iscsi->itt );
553 data_out->ttt = htonl ( iscsi->ttt );
554 data_out->expstatsn = htonl ( iscsi->statsn + 1 );
555 data_out->datasn = htonl ( datasn );
556 data_out->offset = htonl ( iscsi->transfer_offset + offset );
557 DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
558 iscsi, datasn, len );
559}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition iscsi.h:435
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition iscsi.h:103
iSCSI data-out basic header segment
Definition iscsi.h:405
uint8_t opcode
Opcode.
Definition iscsi.h:407
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:413
uint32_t datasn
Data sequence number.
Definition iscsi.h:427
struct scsi_lun lun
Logical Unit Number.
Definition iscsi.h:415
uint32_t itt
Initiator Task Tag.
Definition iscsi.h:417
uint32_t expstatsn
Expected status sequence number.
Definition iscsi.h:423
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:419
uint32_t offset
Buffer offset.
Definition iscsi.h:429
uint8_t flags
Flags.
Definition iscsi.h:409
uint32_t ttt
Target transfer tag.
Definition iscsi.h:610
uint32_t transfer_len
Transfer length.
Definition iscsi.h:622
uint32_t transfer_offset
Transfer offset.
Definition iscsi.h:616
struct scsi_cmd * command
Current SCSI command, if any.
Definition iscsi.h:659
struct scsi_lun lun
LUN.
Definition scsi.h:252
struct iscsi_bhs_data_out data_out
Definition iscsi.h:514

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, iscsi_bhs_data_out::lun, scsi_cmd::lun, iscsi_bhs_data_out::offset, 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()

void iscsi_rx_buffered_data_done ( struct iscsi_session * iscsi)
static

Finish receiving PDU data into buffer.

Parameters
iscsiiSCSI session

Definition at line 161 of file iscsi.c.

161 {
162 free ( iscsi->rx_buffer );
163 iscsi->rx_buffer = NULL;
164}
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * rx_buffer
Buffer for received data (not always used).
Definition iscsi.h:656

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()

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

Receive PDU data into buffer.

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

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

Definition at line 179 of file iscsi.c.

180 {
181
182 /* Allocate buffer on first call */
183 if ( ! iscsi->rx_buffer ) {
184 iscsi->rx_buffer = malloc ( iscsi->rx_len );
185 if ( ! iscsi->rx_buffer )
186 return -ENOMEM;
187 }
188
189 /* Copy data to buffer */
190 assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
191 memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
192
193 return 0;
194}
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
size_t rx_offset
Byte offset within the current RX state.
Definition iscsi.h:652
size_t rx_len
Length of the current RX state.
Definition iscsi.h:654

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()

void iscsi_free ( struct refcnt * refcnt)
static

Free iSCSI session.

Parameters
refcntReference counter

Definition at line 201 of file iscsi.c.

201 {
202 struct iscsi_session *iscsi =
204
205 free ( iscsi->initiator_iqn );
206 free ( iscsi->target_address );
207 free ( iscsi->target_iqn );
208 free ( iscsi->initiator_username );
209 free ( iscsi->initiator_password );
210 free ( iscsi->target_username );
211 free ( iscsi->target_password );
212 chap_finish ( &iscsi->chap );
214 free ( iscsi->command );
215 free ( iscsi );
216}
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition chap.c:123
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition iscsi.c:161
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An iSCSI session.
Definition iscsi.h:545
char * target_iqn
Target IQN.
Definition iscsi.h:563
char * initiator_password
Initiator password (if any).
Definition iscsi.h:575
char * target_password
Target password (if any).
Definition iscsi.h:579
char * initiator_username
Initiator username (if any).
Definition iscsi.h:573
char * initiator_iqn
Initiator IQN.
Definition iscsi.h:557
char * target_username
Target username (if any).
Definition iscsi.h:577
struct chap_response chap
CHAP response (used for both initiator and target auth).
Definition iscsi.h:588
char * target_address
Target address.
Definition iscsi.h:559
A reference counter.
Definition refcnt.h:27

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()

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

Shut down iSCSI interface.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 224 of file iscsi.c.

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

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()

void iscsi_new_itt ( struct iscsi_session * iscsi)
static

Assign new iSCSI initiator task tag.

Parameters
iscsiiSCSI session

Definition at line 245 of file iscsi.c.

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

References ISCSI_TAG_MAGIC, and iscsi_session::itt.

Referenced by iscsi_open_connection(), and iscsi_scsi_command().

◆ iscsi_open_connection()

int iscsi_open_connection ( struct iscsi_session * iscsi)
static

Open iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 257 of file iscsi.c.

257 {
258 struct sockaddr_tcpip target;
259 int rc;
260
261 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
262 assert ( iscsi->rx_state == ISCSI_RX_BHS );
263 assert ( iscsi->rx_offset == 0 );
264
265 /* Open socket */
266 memset ( &target, 0, sizeof ( target ) );
267 target.st_port = htons ( iscsi->target_port );
268 if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
269 ( struct sockaddr * ) &target,
270 iscsi->target_address,
271 NULL ) ) != 0 ) {
272 DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
273 iscsi, strerror ( rc ) );
274 return rc;
275 }
276
277 /* Enter security negotiation phase */
280 if ( iscsi->target_username )
282
283 /* Assign new ISID */
284 iscsi->isid_iana_qual = ( random() & 0xffff );
285
286 /* Assign fresh initiator task tag */
287 iscsi_new_itt ( iscsi );
288
289 /* Set default operational parameters */
291
292 /* Initiate login */
293 iscsi_start_login ( iscsi );
294
295 return 0;
296}
#define SOCK_STREAM
Definition socket.h:25
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition iscsi.c:789
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition iscsi.c:245
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
Definition iscsi.h:670
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition iscsi.h:709
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
Definition iscsi.h:30
@ ISCSI_RX_BHS
Receiving the basic header segment.
Definition iscsi.h:535
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition iscsi.h:688
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
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:403
enum iscsi_rx_state rx_state
State of the RX engine.
Definition iscsi.h:650
size_t max_burst_len
Maximum burst length.
Definition iscsi.h:591
unsigned int target_port
Target port.
Definition iscsi.h:561
TCP/IP socket address.
Definition tcpip.h:76
Generalized socket address structure.
Definition socket.h:97

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

Referenced by iscsi_open(), and iscsi_rx_login_response().

◆ iscsi_close_connection()

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

Close iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
rcReason for close

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

Definition at line 307 of file iscsi.c.

307 {
308
309 /* Close all data transfer interfaces */
310 intf_restart ( &iscsi->socket, rc );
311
312 /* Clear connection status */
313 iscsi->status = 0;
314
315 /* Reset TX and RX state machines */
316 iscsi->tx_state = ISCSI_TX_IDLE;
317 iscsi->rx_state = ISCSI_RX_BHS;
318 iscsi->rx_offset = 0;
319
320 /* Free any temporary dynamically allocated memory */
321 chap_finish ( &iscsi->chap );
323}
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344

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()

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

Mark iSCSI SCSI operation as complete.

Parameters
iscsiiSCSI session
rcReturn status code
rspSCSI response, if any

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

Definition at line 339 of file iscsi.c.

340 {
341 uint32_t itt = iscsi->itt;
342
343 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
344
345 /* Clear command */
346 free ( iscsi->command );
347 iscsi->command = NULL;
348
349 /* Send SCSI response, if any */
350 if ( rsp )
351 scsi_response ( &iscsi->data, rsp );
352
353 /* Close SCSI command, if this is still the same command. (It
354 * is possible that the command interface has already been
355 * closed as a result of the SCSI response we sent.)
356 */
357 if ( iscsi->itt == itt )
358 intf_restart ( &iscsi->data, rc );
359}
unsigned int uint32_t
Definition stdint.h:12
uint64_t rsp
Definition librm.h:18
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition scsi.c:207

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()

void iscsi_start_command ( struct iscsi_session * iscsi)
static

Build iSCSI SCSI command BHS.

Parameters
iscsiiSCSI session

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

Definition at line 377 of file iscsi.c.

377 {
379
380 assert ( ! ( iscsi->command->data_in.len &&
381 iscsi->command->data_out.len ) );
382
383 /* Construct BHS and initiate transmission */
384 iscsi_start_tx ( iscsi );
386 command->flags = ( ISCSI_FLAG_FINAL |
388 if ( iscsi->command->data_in.len )
390 if ( iscsi->command->data_out.len )
392 /* lengths left as zero */
393 memcpy ( &command->lun, &iscsi->command->lun,
394 sizeof ( command->lun ) );
395 command->itt = htonl ( iscsi->itt );
396 command->exp_len = htonl ( iscsi->command->data_in.len |
397 iscsi->command->data_out.len );
398 command->cmdsn = htonl ( iscsi->cmdsn );
399 command->expstatsn = htonl ( iscsi->statsn + 1 );
400 memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
401 DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
402 iscsi, SCSI_CDB_DATA ( command->cdb ),
403 ( iscsi->command->data_in.len ? "in" : "out" ),
404 ( iscsi->command->data_in.len +
405 iscsi->command->data_out.len ) );
406}
#define DBGC2(...)
Definition compiler.h:547
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:224
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:220
#define ISCSI_COMMAND_ATTR_SIMPLE
Definition iscsi.h:296
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
Definition iscsi.h:289
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition iscsi.h:292
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
Definition iscsi.h:286
A command-line command.
Definition command.h:10
iSCSI SCSI command basic header segment
Definition iscsi.h:262
struct xfer_buffer data_in
Data-in buffer.
Definition scsi.h:258
union scsi_cdb cdb
CDB for this command.
Definition scsi.h:254
struct xfer_buffer data_out
Data-out buffer.
Definition scsi.h:256
size_t len
Size of data.
Definition xferbuf.h:25
struct iscsi_bhs_scsi_command scsi_command
Definition iscsi.h:511

References assert, scsi_cmd::cdb, iscsi_session::cmdsn, iscsi_session::command, scsi_cmd::data_in, scsi_cmd::data_out, 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, xfer_buffer::len, 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()

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

Receive data segment of an iSCSI SCSI response PDU.

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

Definition at line 417 of file iscsi.c.

419 {
421 = &iscsi->rx_bhs.scsi_response;
422 struct scsi_rsp rsp;
423 uint32_t residual_count;
424 size_t data_len;
425 int rc;
426
427 /* Buffer up the PDU data */
428 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
429 DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
430 iscsi, strerror ( rc ) );
431 return rc;
432 }
433 if ( remaining )
434 return 0;
435
436 /* Parse SCSI response and discard buffer */
437 memset ( &rsp, 0, sizeof ( rsp ) );
438 rsp.status = response->status;
439 residual_count = ntohl ( response->residual_count );
440 if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
441 rsp.overrun = residual_count;
442 } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
443 rsp.overrun = -(residual_count);
444 }
445 data_len = ISCSI_DATA_LEN ( response->lengths );
446 if ( data_len >= 2 ) {
447 scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
448 &rsp.sense );
449 }
451
452 /* Check for errors */
453 if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
454 return -EIO;
455
456 /* Mark as completed */
457 iscsi_scsi_done ( iscsi, 0, &rsp );
458 return 0;
459}
#define EIO
Input/output error.
Definition errno.h:434
#define ntohl(value)
Definition byteswap.h:135
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition iscsi.c:339
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition iscsi.c:179
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
Definition iscsi.h:340
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition iscsi.h:62
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
Definition iscsi.h:393
#define ISCSI_DATA_FLAG_UNDERFLOW
Data underflow occurred.
Definition iscsi.h:396
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition scsi.c:147
iSCSI SCSI response basic header segment
Definition iscsi.h:305
uint8_t status
SCSI status code.
Definition iscsi.h:313
uint32_t residual_count
Residual count.
Definition iscsi.h:333
uint8_t response
Response code.
Definition iscsi.h:311
uint8_t flags
Flags.
Definition iscsi.h:309
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:315
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition iscsi.h:648
A SCSI response information unit.
Definition scsi.h:313
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes).
Definition ucode.h:15
struct iscsi_bhs_scsi_response scsi_response
Definition iscsi.h:512

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

Referenced by iscsi_rx_data().

◆ iscsi_rx_data_in()

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

Receive data segment of an iSCSI data-in PDU.

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

Definition at line 470 of file iscsi.c.

472 {
473 struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
474 unsigned long offset;
475 int rc;
476
477 /* Copy data to data-in buffer */
478 offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
479 assert ( iscsi->command != NULL );
480 if ( ( rc = xferbuf_write ( &iscsi->command->data_in, offset,
481 data, len ) ) != 0 )
482 return rc;
483
484 /* Wait for whole SCSI response to arrive */
485 if ( remaining )
486 return 0;
487
488 /* Mark as completed if status is present */
489 if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
490 assert ( ( offset + len ) == iscsi->command->data_in.len );
491 assert ( data_in->flags & ISCSI_FLAG_FINAL );
492 /* iSCSI cannot return an error status via a data-in */
493 iscsi_scsi_done ( iscsi, 0, NULL );
494 }
495
496 return 0;
497}
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition iscsi.h:399
iSCSI data-in basic header segment
Definition iscsi.h:355
uint32_t offset
Buffer offset.
Definition iscsi.h:381
uint8_t flags
Flags.
Definition iscsi.h:359
struct iscsi_bhs_data_in data_in
Definition iscsi.h:513
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:105

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

Referenced by iscsi_rx_data().

◆ iscsi_rx_r2t()

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

510 {
511 struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
512
513 /* Record transfer parameters and trigger first data-out */
514 iscsi->ttt = ntohl ( r2t->ttt );
515 iscsi->transfer_offset = ntohl ( r2t->offset );
516 iscsi->transfer_len = ntohl ( r2t->len );
517 iscsi_start_data_out ( iscsi, 0 );
518
519 return 0;
520}
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition iscsi.c:529
iSCSI request to transfer basic header segment
Definition iscsi.h:441
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:455
uint32_t len
Desired data transfer length.
Definition iscsi.h:467
uint32_t offset
Buffer offset.
Definition iscsi.h:465
struct iscsi_bhs_r2t r2t
Definition iscsi.h:515

References __unused, data, iscsi_start_data_out(), iscsi_bhs_r2t::len, 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()

void iscsi_data_out_done ( struct iscsi_session * iscsi)
static

Complete iSCSI data-out PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 567 of file iscsi.c.

567 {
568 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
569
570 /* If we haven't reached the end of the sequence, start
571 * sending the next data-out PDU.
572 */
573 if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
574 iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
575}

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()

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

583 {
584 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
585 struct io_buffer *iobuf;
586 unsigned long offset;
587 size_t len;
588 size_t pad_len;
589 int rc;
590
591 /* Calculate offset and lengths */
592 offset = ntohl ( data_out->offset );
593 len = ISCSI_DATA_LEN ( data_out->lengths );
594 pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
595
596 /* Allocate I/O buffer */
597 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
598 if ( ! iobuf ) {
599 rc = -ENOMEM;
600 goto err_alloc;
601 }
602
603 /* Copy data to I/O buffer */
604 assert ( iscsi->command != NULL );
605 if ( ( rc = xferbuf_read ( &iscsi->command->data_out, offset,
606 iob_put ( iobuf, len ), len ) ) != 0 ) {
607 goto err_read;
608 }
609 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
610
611 /* Deliver I/O buffer */
612 if ( ( rc = xfer_deliver_iob ( &iscsi->socket,
613 iob_disown ( iobuf ) ) ) != 0 ) {
614 goto err_deliver;
615 }
616
617 return 0;
618
619 err_deliver:
620 err_read:
621 free_iob ( iobuf );
622 err_alloc:
623 return rc;
624}
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:217
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition iscsi.h:66
A persistent I/O buffer.
Definition iobuf.h:38
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition xferbuf.c:138

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

Referenced by iscsi_tx_data().

◆ iscsi_rx_nop_in()

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

637 {
638 struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in;
639
640 DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi );
641
642 /* We don't currently have the ability to respond to NOP-Ins
643 * sent as ping requests, but we can happily accept NOP-Ins
644 * sent merely to update CmdSN.
645 */
646 if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) )
647 return 0;
648
649 /* Ignore any other NOP-Ins. The target may eventually
650 * disconnect us for failing to respond, but this minimises
651 * unnecessary connection closures.
652 */
653 DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n",
654 iscsi, ntohl ( nop_in->ttt ) );
655 return 0;
656}
#define ISCSI_TAG_RESERVED
iSCSI reserved tag value
Definition iscsi.h:109
iSCSI NOP-In basic header segment
Definition iscsi.h:477
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:489
struct iscsi_nop_in nop_in
Definition iscsi.h:516

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

Referenced by iscsi_rx_data().

◆ iscsi_build_login_request_strings()

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

711 {
712 unsigned int used = 0;
713 const char *auth_method;
714
715 if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
716 /* Default to allowing no authentication */
717 auth_method = "None";
718 /* If we have a credential to supply, permit CHAP */
719 if ( iscsi->initiator_username )
720 auth_method = "CHAP,None";
721 /* If we have a credential to check, force CHAP */
722 if ( iscsi->target_username )
723 auth_method = "CHAP";
724 used += ssnprintf ( data + used, len - used,
725 "InitiatorName=%s%c"
726 "TargetName=%s%c"
727 "SessionType=Normal%c"
728 "AuthMethod=%s%c",
729 iscsi->initiator_iqn, 0,
730 iscsi->target_iqn, 0, 0,
731 auth_method, 0 );
732 }
733
735 used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
736 }
737
738 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
739 char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
740 assert ( iscsi->initiator_username != NULL );
741 base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
742 buf, sizeof ( buf ) );
743 used += ssnprintf ( data + used, len - used,
744 "CHAP_N=%s%cCHAP_R=0x%s%c",
745 iscsi->initiator_username, 0, buf, 0 );
746 }
747
748 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
749 size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
750 char buf[ base16_encoded_len ( challenge_len ) + 1 ];
751 base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
752 buf, sizeof ( buf ) );
753 used += ssnprintf ( data + used, len - used,
754 "CHAP_I=%d%cCHAP_C=0x%s%c",
755 iscsi->chap_challenge[0], 0, buf, 0 );
756 }
757
759 used += ssnprintf ( data + used, len - used,
760 "HeaderDigest=None%c"
761 "DataDigest=None%c"
762 "MaxConnections=1%c"
763 "InitialR2T=Yes%c"
764 "ImmediateData=No%c"
765 "MaxRecvDataSegmentLength=%d%c"
766 "MaxBurstLength=%d%c"
767 "FirstBurstLength=%d%c"
768 "DefaultTime2Wait=0%c"
769 "DefaultTime2Retain=0%c"
770 "MaxOutstandingR2T=1%c"
771 "DataPDUInOrder=Yes%c"
772 "DataSequenceInOrder=Yes%c"
773 "ErrorRecoveryLevel=0%c",
774 0, 0, 0, 0, 0,
778 0, 0, 0, 0, 0, 0 );
779 }
780
781 return used;
782}
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition base16.h:25
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition iscsi.h:700
#define ISCSI_FIRST_BURST_LEN
Default iSCSI first burst length.
Definition iscsi.h:27
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition iscsi.h:691
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition iscsi.h:697
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition iscsi.h:694
#define ISCSI_MAX_RECV_DATA_SEG_LEN
Default iSCSI maximum receive data segment length.
Definition iscsi.h:33
uint8_t * response
CHAP response.
Definition chap.h:25
size_t response_len
Length of CHAP response.
Definition chap.h:27
unsigned char chap_challenge[17]
CHAP challenge (for target auth only).
Definition iscsi.h:586
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition vsprintf.c:421

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

Referenced by iscsi_start_login(), and iscsi_tx_login_request().

◆ iscsi_login_request_done()

void iscsi_login_request_done ( struct iscsi_session * iscsi)
static

Complete iSCSI login request PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 831 of file iscsi.c.

831 {
832
833 /* Clear any "strings to send" flags */
835
836 /* Free any dynamically allocated storage used for login */
837 chap_finish ( &iscsi->chap );
838}
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition iscsi.h:703

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

Referenced by iscsi_tx_done().

◆ iscsi_tx_login_request()

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

848 {
850 struct io_buffer *iobuf;
851 size_t len;
852 size_t pad_len;
853
854 len = ISCSI_DATA_LEN ( request->lengths );
855 pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
856 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
857 if ( ! iobuf )
858 return -ENOMEM;
859 iob_put ( iobuf, len );
860 iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
861 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
862
863 return xfer_deliver_iob ( &iscsi->socket, iobuf );
864}
void * data
Start of data.
Definition iobuf.h:53

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()

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

875 {
876
877 /* Check for initial '0x' or '0b' and decode as appropriate */
878 if ( *(encoded++) == '0' ) {
879 switch ( tolower ( *(encoded++) ) ) {
880 case 'x' :
881 return base16_decode ( encoded, raw, len );
882 case 'b' :
883 return base64_decode ( encoded, raw, len );
884 }
885 }
886
888}
__be32 raw[7]
Definition CIB_PRM.h:0
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition base64.c:92
static int tolower(int character)
Convert character to lower case.
Definition ctype.h:109
#define EPROTO_INVALID_LARGE_BINARY
Definition iscsi.c:134

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

Referenced by iscsi_handle_chap_c_value(), and iscsi_handle_chap_r_value().

◆ iscsi_handle_targetaddress_value()

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

898 {
899 char *separator;
900
901 DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
902
903 /* Replace target address */
904 free ( iscsi->target_address );
905 iscsi->target_address = strdup ( value );
906 if ( ! iscsi->target_address )
907 return -ENOMEM;
908
909 /* Replace target port */
910 iscsi->target_port = htons ( ISCSI_PORT );
911 separator = strchr ( iscsi->target_address, ':' );
912 if ( separator ) {
913 *separator = '\0';
914 iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
915 }
916
917 return 0;
918}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define ISCSI_PORT
Default iSCSI port.
Definition iscsi.h:24
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:516
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:288
char * strdup(const char *src)
Duplicate string.
Definition string.c:425

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()

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

928 {
929
930 /* If server requests CHAP, send the CHAP_A string */
931 if ( strcmp ( value, "CHAP" ) == 0 ) {
932 DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
933 iscsi );
936 }
937
938 return 0;
939}
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition iscsi.h:706
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174

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

◆ iscsi_handle_maxburstlength_value()

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

Handle iSCSI MaxBurstLength text value.

Parameters
iscsiiSCSI session
valueMaxBurstLength value
Return values
rcReturn status code

Definition at line 948 of file iscsi.c.

949 {
950 unsigned long max_burst_len;
951 char *end;
952
953 /* Update maximum burst length */
954 max_burst_len = strtoul ( value, &end, 0 );
955 if ( *end ) {
956 DBGC ( iscsi, "iSCSI %p invalid MaxBurstLength \"%s\"\n",
957 iscsi, value );
958 return -EINVAL_MAXBURSTLENGTH;
959 }
960 if ( max_burst_len < iscsi->max_burst_len )
961 iscsi->max_burst_len = max_burst_len;
962
963 return 0;
964}
#define EINVAL_MAXBURSTLENGTH
Definition iscsi.c:90
uint32_t end
Ending offset.
Definition netvsc.h:7

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

◆ iscsi_handle_chap_a_value()

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

974 {
975
976 /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
977 * the server responds with anything else it is a protocol
978 * violation.
979 */
980 if ( strcmp ( value, "5" ) != 0 ) {
981 DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
982 iscsi, value );
984 }
985
986 return 0;
987}
#define EPROTO_INVALID_CHAP_ALGORITHM
Definition iscsi.c:126

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

◆ iscsi_handle_chap_i_value()

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

997 {
998 unsigned int identifier;
999 char *endp;
1000 int rc;
1001
1002 /* The CHAP identifier is an integer value */
1003 identifier = strtoul ( value, &endp, 0 );
1004 if ( *endp != '\0' ) {
1005 DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
1006 iscsi, value );
1008 }
1009
1010 /* Prepare for CHAP with MD5 */
1011 chap_finish ( &iscsi->chap );
1012 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1013 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1014 iscsi, strerror ( rc ) );
1015 return rc;
1016 }
1017
1018 /* Identifier and secret are the first two components of the
1019 * challenge.
1020 */
1021 chap_set_identifier ( &iscsi->chap, identifier );
1022 if ( iscsi->initiator_password ) {
1023 chap_update ( &iscsi->chap, iscsi->initiator_password,
1024 strlen ( iscsi->initiator_password ) );
1025 }
1026
1027 return 0;
1028}
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition chap.c:86
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition chap.c:52
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition chap.h:47
#define EPROTO_INVALID_CHAP_IDENTIFIER
Definition iscsi.c:130
struct digest_algorithm md5_algorithm
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

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()

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

1038 {
1039 uint8_t *buf;
1040 unsigned int i;
1041 int len;
1042 int rc;
1043
1044 /* Allocate decoding buffer */
1045 len = strlen ( value ); /* Decoding never expands data */
1046 buf = malloc ( len );
1047 if ( ! buf ) {
1048 rc = -ENOMEM;
1049 goto err_alloc;
1050 }
1051
1052 /* Process challenge */
1054 if ( len < 0 ) {
1055 rc = len;
1056 DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1057 iscsi, value, strerror ( rc ) );
1058 goto err_decode;
1059 }
1060 chap_update ( &iscsi->chap, buf, len );
1061
1062 /* Build CHAP response */
1063 DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1064 chap_respond ( &iscsi->chap );
1066
1067 /* Send CHAP challenge, if applicable */
1068 if ( iscsi->target_username ) {
1070 /* Generate CHAP challenge data */
1071 for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1072 iscsi->chap_challenge[i] = random();
1073 }
1074 }
1075
1076 /* Success */
1077 rc = 0;
1078
1079 err_decode:
1080 free ( buf );
1081 err_alloc:
1082 return rc;
1083}
unsigned char uint8_t
Definition stdint.h:10
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
Definition chap.c:105
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
Definition iscsi.c:874

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()

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

1093 {
1094
1095 /* The target username isn't actually involved at any point in
1096 * the authentication process; it merely serves to identify
1097 * which password the target is using to generate the CHAP
1098 * response. We unnecessarily verify that the username is as
1099 * expected, in order to provide mildly helpful diagnostics if
1100 * the target is supplying the wrong username/password
1101 * combination.
1102 */
1103 if ( iscsi->target_username &&
1104 ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1105 DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1106 "(wanted \"%s\")\n",
1107 iscsi, value, iscsi->target_username );
1109 }
1110
1111 return 0;
1112}
#define EACCES_INCORRECT_TARGET_USERNAME
Definition iscsi.c:62

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

◆ iscsi_handle_chap_r_value()

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

1122 {
1123 uint8_t *buf;
1124 int len;
1125 int rc;
1126
1127 /* Generate CHAP response for verification */
1128 chap_finish ( &iscsi->chap );
1129 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1130 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1131 iscsi, strerror ( rc ) );
1132 goto err_chap_init;
1133 }
1134 chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1135 if ( iscsi->target_password ) {
1136 chap_update ( &iscsi->chap, iscsi->target_password,
1137 strlen ( iscsi->target_password ) );
1138 }
1139 chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1140 ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1141 chap_respond ( &iscsi->chap );
1142
1143 /* Allocate decoding buffer */
1144 len = strlen ( value ); /* Decoding never expands data */
1145 buf = malloc ( len );
1146 if ( ! buf ) {
1147 rc = -ENOMEM;
1148 goto err_alloc;
1149 }
1150
1151 /* Process response */
1153 if ( len < 0 ) {
1154 rc = len;
1155 DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1156 iscsi, value, strerror ( rc ) );
1157 goto err_decode;
1158 }
1159
1160 /* Check CHAP response */
1161 if ( len != ( int ) iscsi->chap.response_len ) {
1162 DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1163 iscsi );
1165 goto err_response_len;
1166 }
1167 if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1168 DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1169 iscsi, value );
1171 goto err_response;
1172 }
1173
1174 /* Mark session as authenticated */
1176
1177 err_response:
1178 err_response_len:
1179 err_decode:
1180 free ( buf );
1181 err_alloc:
1182 err_chap_init:
1183 return rc;
1184}
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition iscsi.c:66
#define EPROTO_INVALID_CHAP_RESPONSE
Definition iscsi.c:138
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition iscsi.h:712
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

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()

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

1224 {
1225 struct iscsi_string_type *type;
1226 const char *separator;
1227 const char *value;
1228 size_t key_len;
1229 int rc;
1230
1231 /* Find separator */
1232 separator = strchr ( string, '=' );
1233 if ( ! separator ) {
1234 DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1235 iscsi, string );
1237 }
1238 key_len = ( separator - string );
1239 value = ( separator + 1 );
1240
1241 /* Check for rejections. Since we send only non-rejectable
1242 * values, any rejection is a fatal protocol error.
1243 */
1244 if ( strcmp ( value, "Reject" ) == 0 ) {
1245 DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1246 return -EPROTO_VALUE_REJECTED;
1247 }
1248
1249 /* Handle key/value pair */
1250 for ( type = iscsi_string_types ; type->key ; type++ ) {
1251 if ( strncmp ( string, type->key, key_len ) != 0 )
1252 continue;
1253 DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1254 if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1255 DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1256 iscsi, string, strerror ( rc ) );
1257 return rc;
1258 }
1259 return 0;
1260 }
1261 DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1262 return 0;
1263}
uint32_t type
Operating system type.
Definition ena.h:1
#define EPROTO_VALUE_REJECTED
Definition iscsi.c:146
static struct iscsi_string_type iscsi_string_types[]
iSCSI text strings that we want to handle
Definition iscsi.c:1204
#define EPROTO_INVALID_KEY_VALUE_PAIR
Definition iscsi.c:142
uint32_t string
Definition multiboot.h:2
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition string.c:187
An iSCSI text string that we want to handle.
Definition iscsi.c:1187

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()

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

1274 {
1275 size_t string_len;
1276 int rc;
1277
1278 /* Handle each string in turn, taking care not to overrun the
1279 * data buffer in case of badly-terminated data.
1280 */
1281 while ( 1 ) {
1282 string_len = ( strnlen ( strings, len ) + 1 );
1283 if ( string_len > len )
1284 break;
1285 if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1286 return rc;
1287 strings += string_len;
1288 len -= string_len;
1289 }
1290 return 0;
1291}
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition iscsi.c:1223
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition string.c:256

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

Referenced by iscsi_rx_login_response().

◆ iscsi_status_to_rc()

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

1301 {
1302 switch ( status_class ) {
1304 switch ( status_detail ) {
1311 return -ENODEV;
1312 default :
1314 }
1316 switch ( status_detail ) {
1318 return -EIO_TARGET_UNAVAILABLE;
1321 default:
1322 return -ENOTSUP_TARGET_STATUS;
1323 }
1324 default :
1325 return -EINVAL;
1326 }
1327}
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTSUP_TARGET_STATUS
Definition iscsi.c:114
#define EPERM_INITIATOR_AUTHORISATION
Definition iscsi.c:122
#define EIO_TARGET_NO_RESOURCES
Definition iscsi.c:98
#define ENOTSUP_INITIATOR_STATUS
Definition iscsi.c:102
#define EPERM_INITIATOR_AUTHENTICATION
Definition iscsi.c:118
#define EIO_TARGET_UNAVAILABLE
Definition iscsi.c:94
#define ISCSI_STATUS_TARGET_ERROR
Definition iscsi.h:254
#define ISCSI_STATUS_INITIATOR_ERROR
Definition iscsi.h:249
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition iscsi.h:255
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition iscsi.h:252
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition iscsi.h:250
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition iscsi.h:256
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition iscsi.h:251
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition iscsi.h:253

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

Referenced by iscsi_rx_login_response().

◆ iscsi_rx_login_response()

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

1340 {
1341 struct iscsi_bhs_login_response *response
1342 = &iscsi->rx_bhs.login_response;
1343 int rc;
1344
1345 /* Buffer up the PDU data */
1346 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1347 DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1348 iscsi, strerror ( rc ) );
1349 return rc;
1350 }
1351 if ( remaining )
1352 return 0;
1353
1354 /* Process string data and discard string buffer */
1355 if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1356 iscsi->rx_len ) ) != 0 )
1357 return rc;
1359
1360 /* Check for login redirection */
1361 if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1362 DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1363 iscsi_close_connection ( iscsi, 0 );
1364 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1365 DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1366 iscsi, strerror ( rc ) );
1367 return rc;
1368 }
1369 return 0;
1370 }
1371
1372 /* Check for fatal errors */
1373 if ( response->status_class != 0 ) {
1374 DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1375 response->status_class, response->status_detail );
1376 rc = iscsi_status_to_rc ( response->status_class,
1377 response->status_detail );
1378 return rc;
1379 }
1380
1381 /* Handle login transitions */
1382 if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1383 iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1385 switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1387 iscsi->status |=
1390 break;
1393 break;
1394 default:
1395 DBGC ( iscsi, "iSCSI %p got invalid response flags "
1396 "%02x\n", iscsi, response->flags );
1397 return -EIO;
1398 }
1399 }
1400
1401 /* Send next login request PDU if we haven't reached the full
1402 * feature phase yet.
1403 */
1404 if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1406 iscsi_start_login ( iscsi );
1407 return 0;
1408 }
1409
1410 /* Check that target authentication was successful (if required) */
1411 if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1412 ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1413 DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1414 "authentication\n", iscsi );
1415 return -EPROTO;
1416 }
1417
1418 /* Notify SCSI layer of window change */
1419 DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1420 xfer_window_changed ( &iscsi->control );
1421
1422 return 0;
1423}
#define EPROTO
Protocol error.
Definition errno.h:625
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition iscsi.c:1273
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:1300
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition iscsi.c:257
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
Definition iscsi.c:307
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Definition iscsi.h:677
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition iscsi.h:682
#define ISCSI_LOGIN_NSG_MASK
Definition iscsi.h:189
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
Definition iscsi.h:192
#define ISCSI_STATUS_REDIRECT
Definition iscsi.h:248
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
Definition iscsi.h:191
iSCSI login response basic header segment
Definition iscsi.h:208
uint8_t status_detail
Status detail.
Definition iscsi.h:238
uint8_t status_class
Status class.
Definition iscsi.h:236
uint8_t flags
Flags.
Definition iscsi.h:212
struct iscsi_bhs_login_response login_response
Definition iscsi.h:510
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

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()

void iscsi_tx_pause ( struct iscsi_session * iscsi)
static

Pause TX engine.

Parameters
iscsiiSCSI session

Definition at line 1436 of file iscsi.c.

1436 {
1437 process_del ( &iscsi->process );
1438}

References iscsi_session::process, and process_del().

Referenced by iscsi_tx_done(), and iscsi_tx_step().

◆ iscsi_tx_resume()

void iscsi_tx_resume ( struct iscsi_session * iscsi)
static

Resume TX engine.

Parameters
iscsiiSCSI session

Definition at line 1445 of file iscsi.c.

1445 {
1446 process_add ( &iscsi->process );
1447}
void process_add(struct process *process)
Add process to process list.
Definition process.c:60

References iscsi_session::process, and process_add().

Referenced by iscsi_start_tx().

◆ iscsi_tx_nothing()

int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused)
static

Transmit nothing.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1477 of file iscsi.c.

1477 {
1478 return 0;
1479}

References __unused.

Referenced by iscsi_tx_step().

◆ iscsi_tx_bhs()

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

1487 {
1488 return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1489 sizeof ( iscsi->tx_bhs ) );
1490}
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition xfer.c:289

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

Referenced by iscsi_tx_step().

◆ iscsi_tx_data()

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

1501 {
1502 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1503
1504 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1506 return iscsi_tx_data_out ( iscsi );
1508 return iscsi_tx_login_request ( iscsi );
1509 default:
1510 /* Nothing to send in other states */
1511 return 0;
1512 }
1513}
struct ib_cm_common common
Definition ib_mad.h:0
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
Definition iscsi.c:848
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition iscsi.c:583
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition iscsi.h:97
iSCSI basic header segment common fields
Definition iscsi.h:79
struct iscsi_bhs_common common
Definition iscsi.h:507

References common, iscsi_bhs::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()

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

1524 {
1525 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1526
1527 /* Stop transmission process */
1528 iscsi_tx_pause ( iscsi );
1529
1530 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1532 iscsi_data_out_done ( iscsi );
1533 break;
1535 iscsi_login_request_done ( iscsi );
1536 break;
1537 default:
1538 /* No action */
1539 break;
1540 }
1541}
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition iscsi.c:1436
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
Definition iscsi.c:831
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition iscsi.c:567

References common, iscsi_bhs::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()

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

1552 {
1553 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1554 int ( * tx ) ( struct iscsi_session *iscsi );
1555 enum iscsi_tx_state next_state;
1556 size_t tx_len;
1557 int rc;
1558
1559 /* Select fragment to transmit */
1560 while ( 1 ) {
1561 switch ( iscsi->tx_state ) {
1562 case ISCSI_TX_BHS:
1563 tx = iscsi_tx_bhs;
1564 tx_len = sizeof ( iscsi->tx_bhs );
1565 next_state = ISCSI_TX_AHS;
1566 break;
1567 case ISCSI_TX_AHS:
1569 tx_len = 0;
1570 next_state = ISCSI_TX_DATA;
1571 break;
1572 case ISCSI_TX_DATA:
1573 tx = iscsi_tx_data;
1574 tx_len = ISCSI_DATA_LEN ( common->lengths );
1575 next_state = ISCSI_TX_IDLE;
1576 break;
1577 case ISCSI_TX_IDLE:
1578 /* Nothing to do; pause processing */
1579 iscsi_tx_pause ( iscsi );
1580 return;
1581 default:
1582 assert ( 0 );
1583 return;
1584 }
1585
1586 /* Check for window availability, if needed */
1587 if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1588 /* Cannot transmit at this point; pause
1589 * processing and wait for window to reopen
1590 */
1591 iscsi_tx_pause ( iscsi );
1592 return;
1593 }
1594
1595 /* Transmit data */
1596 if ( ( rc = tx ( iscsi ) ) != 0 ) {
1597 DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1598 iscsi, strerror ( rc ) );
1599 /* Transmission errors are fatal */
1600 iscsi_close ( iscsi, rc );
1601 return;
1602 }
1603
1604 /* Move to next state */
1605 iscsi->tx_state = next_state;
1606
1607 /* If we have moved to the idle state, mark
1608 * transmission as complete
1609 */
1610 if ( iscsi->tx_state == ISCSI_TX_IDLE )
1611 iscsi_tx_done ( iscsi );
1612 }
1613}
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition iscsi.c:1477
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition iscsi.c:1487
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
Definition iscsi.c:1524
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition iscsi.c:224
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
Definition iscsi.c:1501
iscsi_tx_state
State of an iSCSI TX engine.
Definition iscsi.h:521
@ ISCSI_TX_AHS
Sending the additional header segment.
Definition iscsi.h:527
@ ISCSI_TX_DATA
Sending the data segment.
Definition iscsi.h:529
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

References assert, common, iscsi_bhs::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()

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

1632 {
1633 memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1634 if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1635 DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1636 iscsi, iscsi->rx_bhs.common.opcode,
1637 ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1638 }
1639 return 0;
1640}
uint8_t opcode
Opcode.
Definition iscsi.h:81
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:87
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
Definition iscsi.h:517

References __unused, 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()

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

1655 {
1656 /* Do nothing */
1657 return 0;
1658}

References __unused, data, and len.

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_data()

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

1673 {
1674 struct iscsi_bhs_common_response *response
1675 = &iscsi->rx_bhs.common_response;
1676
1677 /* Update cmdsn and statsn */
1678 iscsi->cmdsn = ntohl ( response->expcmdsn );
1679 iscsi->statsn = ntohl ( response->statsn );
1680
1681 switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1683 return iscsi_rx_login_response ( iscsi, data, len, remaining );
1685 return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1687 return iscsi_rx_data_in ( iscsi, data, len, remaining );
1688 case ISCSI_OPCODE_R2T:
1689 return iscsi_rx_r2t ( iscsi, data, len, remaining );
1691 return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1692 default:
1693 if ( remaining )
1694 return 0;
1695 DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1696 response->opcode );
1697 return -ENOTSUP_OPCODE;
1698 }
1699}
static int iscsi_rx_scsi_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI SCSI response PDU.
Definition iscsi.c:417
static int iscsi_rx_data_in(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI data-in PDU.
Definition iscsi.c:470
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:1338
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:508
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:635
#define ENOTSUP_OPCODE
Definition iscsi.c:106
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
Definition iscsi.h:244
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
Definition iscsi.h:387
#define ISCSI_OPCODE_R2T
R2T opcode.
Definition iscsi.h:471
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
Definition iscsi.h:501
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
Definition iscsi.h:337
iSCSI basic header segment common request fields
Definition iscsi.h:115
uint32_t expcmdsn
Expected command sequence number.
Definition iscsi.h:133
uint8_t opcode
Opcode.
Definition iscsi.h:117
uint32_t statsn
Status sequence number.
Definition iscsi.h:131
struct iscsi_bhs_common_response common_response
Definition iscsi.h:508

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()

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

1718 {
1719 struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1720 int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1721 size_t len, size_t remaining );
1722 enum iscsi_rx_state next_state;
1723 size_t frag_len;
1724 size_t remaining;
1725 int rc;
1726
1727 while ( 1 ) {
1728 switch ( iscsi->rx_state ) {
1729 case ISCSI_RX_BHS:
1730 rx = iscsi_rx_bhs;
1731 iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1732 next_state = ISCSI_RX_AHS;
1733 break;
1734 case ISCSI_RX_AHS:
1736 iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1737 next_state = ISCSI_RX_DATA;
1738 break;
1739 case ISCSI_RX_DATA:
1740 rx = iscsi_rx_data;
1741 iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1742 next_state = ISCSI_RX_DATA_PADDING;
1743 break;
1746 iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1747 next_state = ISCSI_RX_BHS;
1748 break;
1749 default:
1750 assert ( 0 );
1751 rc = -EINVAL;
1752 goto done;
1753 }
1754
1755 frag_len = iscsi->rx_len - iscsi->rx_offset;
1756 if ( frag_len > iob_len ( iobuf ) )
1757 frag_len = iob_len ( iobuf );
1758 remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1759 if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1760 remaining ) ) != 0 ) {
1761 DBGC ( iscsi, "iSCSI %p could not process received "
1762 "data: %s\n", iscsi, strerror ( rc ) );
1763 goto done;
1764 }
1765
1766 iscsi->rx_offset += frag_len;
1767 iob_pull ( iobuf, frag_len );
1768
1769 /* If all the data for this state has not yet been
1770 * received, stay in this state for now.
1771 */
1772 if ( iscsi->rx_offset != iscsi->rx_len ) {
1773 rc = 0;
1774 goto done;
1775 }
1776
1777 iscsi->rx_state = next_state;
1778 iscsi->rx_offset = 0;
1779 }
1780
1781 done:
1782 /* Free I/O buffer */
1783 free_iob ( iobuf );
1784
1785 /* Destroy session on error */
1786 if ( rc != 0 )
1787 iscsi_close ( iscsi, rc );
1788
1789 return rc;
1790}
struct bofm_section_header done
Definition bofm_test.c:46
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
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:1672
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:1653
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:1631
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
Definition iscsi.h:58
iscsi_rx_state
State of an iSCSI RX engine.
Definition iscsi.h:533
@ ISCSI_RX_AHS
Receiving the additional header segment.
Definition iscsi.h:537
@ ISCSI_RX_DATA
Receiving the data segment.
Definition iscsi.h:539
@ ISCSI_RX_DATA_PADDING
Receiving the data segment padding.
Definition iscsi.h:541
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1

References __unused, assert, common, iscsi_bhs::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, meta, rc, rx, iscsi_session::rx_bhs, iscsi_session::rx_len, iscsi_session::rx_offset, iscsi_session::rx_state, and strerror().

◆ iscsi_vredirect()

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

1801 {
1802 va_list tmp;
1803 struct sockaddr *peer;
1804 int rc;
1805
1806 /* Intercept redirects to a LOCATION_SOCKET and record the IP
1807 * address for the iBFT. This is a bit of a hack, but avoids
1808 * inventing an ioctl()-style call to retrieve the socket
1809 * address from a data-xfer interface.
1810 */
1811 if ( type == LOCATION_SOCKET ) {
1812 va_copy ( tmp, args );
1813 ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1814 peer = va_arg ( tmp, struct sockaddr * );
1815 memcpy ( &iscsi->target_sockaddr, peer,
1816 sizeof ( iscsi->target_sockaddr ) );
1817 va_end ( tmp );
1818 }
1819
1820 /* Redirect to new location */
1821 if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1822 goto err;
1823
1824 return 0;
1825
1826 err:
1827 iscsi_close ( iscsi, rc );
1828 return rc;
1829}
unsigned long tmp
Definition linux_pci.h:65
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition open.c:234
@ LOCATION_SOCKET
Location is a socket.
Definition open.h:44
#define va_copy(dest, src)
Definition stdarg.h:11
#define va_arg(ap, type)
Definition stdarg.h:9
#define va_end(ap)
Definition stdarg.h:10
__builtin_va_list va_list
Definition stdarg.h:7
struct sockaddr target_sockaddr
Target socket address (for boot firmware table).
Definition iscsi.h:662

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

◆ iscsi_scsi_window()

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

1856 {
1857
1858 if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1860 ( iscsi->command == NULL ) ) {
1861 /* We cannot handle concurrent commands */
1862 return 1;
1863 } else {
1864 return 0;
1865 }
1866}

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()

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

1878 {
1879
1880 /* This iSCSI implementation cannot handle multiple concurrent
1881 * commands or commands arriving before login is complete.
1882 */
1883 if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1884 DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1885 iscsi );
1886 return -EOPNOTSUPP;
1887 }
1888
1889 /* Store command */
1890 iscsi->command = malloc ( sizeof ( *command ) );
1891 if ( ! iscsi->command )
1892 return -ENOMEM;
1893 memcpy ( iscsi->command, command, sizeof ( *command ) );
1894
1895 /* Assign new ITT */
1896 iscsi_new_itt ( iscsi );
1897
1898 /* Start sending command */
1899 iscsi_start_command ( iscsi );
1900
1901 /* Attach to parent interface and return */
1902 intf_plug_plug ( &iscsi->data, parent );
1903 return iscsi->itt;
1904}
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:605
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition iscsi.c:1856
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition iscsi.c:377

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

◆ iscsi_scsi_capacity()

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

Update SCSI block device capacity.

Parameters
iscsiiSCSI session
capacityBlock device capacity

Definition at line 1912 of file iscsi.c.

1913 {
1914 unsigned int max_count;
1915
1916 /* Limit maximum number of blocks per transfer to fit MaxBurstLength */
1917 if ( capacity->blksize ) {
1918 max_count = ( iscsi->max_burst_len / capacity->blksize );
1919 if ( max_count < capacity->max_count )
1920 capacity->max_count = max_count;
1921 }
1922}
unsigned int max_count
Maximum number of blocks per single transfer.
Definition blockdev.h:24
size_t blksize
Block size.
Definition blockdev.h:22

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

◆ iscsi_describe()

struct acpi_descriptor * iscsi_describe ( struct iscsi_session * iscsi)
static

Get iSCSI ACPI descriptor.

Parameters
iscsiiSCSI session
Return values
descACPI descriptor

Definition at line 1930 of file iscsi.c.

1930 {
1931
1932 return &iscsi->desc;
1933}
struct acpi_descriptor desc
ACPI descriptor.
Definition iscsi.h:666

References iscsi_session::desc.

◆ iscsi_command_close()

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

Close iSCSI command.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 1955 of file iscsi.c.

1955 {
1956
1957 /* Restart interface */
1958 intf_restart ( &iscsi->data, rc );
1959
1960 /* Treat unsolicited command closures mid-command as fatal,
1961 * because we have no code to handle partially-completed PDUs.
1962 */
1963 if ( iscsi->command != NULL )
1964 iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1965}
#define ECANCELED
Operation canceled.
Definition errno.h:344

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

References __setting, DHCP_ISCSI_INITIATOR_IQN, and SETTING_SANBOOT_EXTRA.

◆ __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:515

iSCSI reverse username setting

iSCSI reverse password setting

References __setting, DHCP_EB_REVERSE_USERNAME, SETTING_AUTH_EXTRA, and username.

◆ iscsi_parse_root_path()

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

2027 {
2028 char *rp_copy;
2029 char *rp_comp[NUM_RP_COMPONENTS];
2030 char *rp;
2031 int skip = 0;
2032 int i = 0;
2033 int rc;
2034
2035 /* Create modifiable copy of root path */
2036 rp_copy = strdup ( root_path );
2037 if ( ! rp_copy ) {
2038 rc = -ENOMEM;
2039 goto err_strdup;
2040 }
2041 rp = rp_copy;
2042
2043 /* Split root path into component parts */
2044 while ( 1 ) {
2045 rp_comp[i++] = rp;
2046 if ( i == NUM_RP_COMPONENTS )
2047 break;
2048 for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
2049 if ( ! *rp ) {
2050 DBGC ( iscsi, "iSCSI %p root path \"%s\" "
2051 "too short\n", iscsi, root_path );
2053 goto err_split;
2054 } else if ( *rp == '[' ) {
2055 skip = 1;
2056 } else if ( *rp == ']' ) {
2057 skip = 0;
2058 }
2059 }
2060 *(rp++) = '\0';
2061 }
2062
2063 /* Use root path components to configure iSCSI session */
2064 iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
2065 if ( ! iscsi->target_address ) {
2066 rc = -ENOMEM;
2067 goto err_servername;
2068 }
2069 iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
2070 if ( ! iscsi->target_port )
2071 iscsi->target_port = ISCSI_PORT;
2072 if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
2073 DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
2074 iscsi, rp_comp[RP_LUN] );
2075 goto err_lun;
2076 }
2077 iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2078 if ( ! iscsi->target_iqn ) {
2079 rc = -ENOMEM;
2080 goto err_targetname;
2081 }
2082
2083 err_targetname:
2084 err_lun:
2085 err_servername:
2086 err_split:
2087 free ( rp_copy );
2088 err_strdup:
2089 return rc;
2090}
#define EINVAL_ROOT_PATH_TOO_SHORT
Definition iscsi.c:70
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition scsi.c:118
struct scsi_lun lun
SCSI LUN (for boot firmware table).
Definition iscsi.h:664

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()

int iscsi_fetch_settings ( struct iscsi_session * iscsi)
static

Fetch iSCSI settings.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2098 of file iscsi.c.

2098 {
2099 char *hostname;
2100 union uuid uuid;
2101 int len;
2102
2103 /* Fetch relevant settings. Don't worry about freeing on
2104 * error, since iscsi_free() will take care of that anyway.
2105 */
2106 fetch_string_setting_copy ( NULL, &username_setting,
2107 &iscsi->initiator_username );
2108 fetch_string_setting_copy ( NULL, &password_setting,
2109 &iscsi->initiator_password );
2110 fetch_string_setting_copy ( NULL, &reverse_username_setting,
2111 &iscsi->target_username );
2112 fetch_string_setting_copy ( NULL, &reverse_password_setting,
2113 &iscsi->target_password );
2114
2115 /* Use explicit initiator IQN if provided */
2116 fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2117 &iscsi->initiator_iqn );
2118 if ( iscsi->initiator_iqn )
2119 return 0;
2120
2121 /* Otherwise, try to construct an initiator IQN from the hostname */
2122 fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2123 if ( hostname ) {
2124 len = asprintf ( &iscsi->initiator_iqn,
2125 ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2126 free ( hostname );
2127 if ( len < 0 ) {
2128 DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2129 "IQN\n", iscsi );
2130 return -ENOMEM;
2131 }
2132 assert ( iscsi->initiator_iqn );
2133 return 0;
2134 }
2135
2136 /* Otherwise, try to construct an initiator IQN from the UUID */
2137 if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2138 DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2139 iscsi );
2141 }
2142 if ( ( len = asprintf ( &iscsi->initiator_iqn,
2144 uuid_ntoa ( &uuid ) ) ) < 0 ) {
2145 DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2146 iscsi );
2147 return -ENOMEM;
2148 }
2149 assert ( iscsi->initiator_iqn );
2150
2151 return 0;
2152}
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition asprintf.c:42
#define EINVAL_NO_INITIATOR_IQN
Definition iscsi.c:86
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
Definition iscsi.h:715
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition settings.c:874
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition settings.c:1085
A universally unique ID.
Definition uuid.h:16
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition uuid.c:46

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()

int iscsi_check_auth ( struct iscsi_session * iscsi)
static

Check iSCSI authentication details.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2161 of file iscsi.c.

2161 {
2162
2163 /* Check for invalid authentication combinations */
2164 if ( ( /* Initiator username without password (or vice-versa) */
2165 ( !! iscsi->initiator_username ) ^
2166 ( !! iscsi->initiator_password ) ) ||
2167 ( /* Target username without password (or vice-versa) */
2168 ( !! iscsi->target_username ) ^
2169 ( !! iscsi->target_password ) ) ||
2170 ( /* Target (reverse) without initiator (forward) */
2171 ( iscsi->target_username &&
2172 ( ! iscsi->initiator_username ) ) ) ) {
2173 DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2174 "%sname,%spw, target %sname,%spw\n", iscsi,
2175 ( iscsi->initiator_username ? "" : "no " ),
2176 ( iscsi->initiator_password ? "" : "no " ),
2177 ( iscsi->target_username ? "" : "no " ),
2178 ( iscsi->target_password ? "" : "no " ) );
2180 }
2181
2182 return 0;
2183}
#define EINVAL_BAD_CREDENTIAL_MIX
Definition iscsi.c:74

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()

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

2192 {
2193 struct iscsi_session *iscsi;
2194 int rc;
2195
2196 /* Sanity check */
2197 if ( ! uri->opaque ) {
2199 goto err_sanity_uri;
2200 }
2201
2202 /* Allocate and initialise structure */
2203 iscsi = zalloc ( sizeof ( *iscsi ) );
2204 if ( ! iscsi ) {
2205 rc = -ENOMEM;
2206 goto err_zalloc;
2207 }
2208 ref_init ( &iscsi->refcnt, iscsi_free );
2209 intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2210 intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2211 intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2213 &iscsi->refcnt );
2214 acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2215
2216 /* Parse root path */
2217 if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2218 goto err_parse_root_path;
2219 /* Set fields not specified by root path */
2220 if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2221 goto err_fetch_settings;
2222 /* Validate authentication */
2223 if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2224 goto err_check_auth;
2225
2226 /* Sanity checks */
2227 if ( ! iscsi->target_address ) {
2228 DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2229 iscsi );
2231 goto err_sanity_address;
2232 }
2233 if ( ! iscsi->target_iqn ) {
2234 DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2235 iscsi, uri->opaque );
2237 goto err_sanity_iqn;
2238 }
2239 DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2240 DBGC ( iscsi, "iSCSI %p target %s %s\n",
2241 iscsi, iscsi->target_address, iscsi->target_iqn );
2242
2243 /* Open socket */
2244 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2245 goto err_open_connection;
2246
2247 /* Attach SCSI device to parent interface */
2248 if ( ( rc = scsi_open ( parent, &iscsi->control,
2249 &iscsi->lun ) ) != 0 ) {
2250 DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2251 iscsi, strerror ( rc ) );
2252 goto err_scsi_open;
2253 }
2254
2255 /* Mortalise self, and return */
2256 ref_put ( &iscsi->refcnt );
2257 return 0;
2258
2259 err_scsi_open:
2260 err_open_connection:
2261 err_sanity_iqn:
2262 err_sanity_address:
2263 err_check_auth:
2264 err_fetch_settings:
2265 err_parse_root_path:
2266 iscsi_close ( iscsi, rc );
2267 ref_put ( &iscsi->refcnt );
2268 err_zalloc:
2269 err_sanity_uri:
2270 return rc;
2271}
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition acpi.h:312
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition iscsi.c:201
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition iscsi.c:2161
#define EINVAL_NO_TARGET_IQN
Definition iscsi.c:82
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition iscsi.c:1841
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition iscsi.c:1946
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition iscsi.c:2026
#define ENOTSUP_DISCOVERY
Definition iscsi.c:110
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition iscsi.c:2098
#define EINVAL_NO_ROOT_PATH
Definition iscsi.c:78
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition iscsi.c:1616
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition iscsi.c:1973
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
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:146
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition scsi.c:987
struct refcnt refcnt
Reference counter.
Definition iscsi.h:547
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71

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

Variable Documentation

◆ iscsi_string_types

struct iscsi_string_type iscsi_string_types[]
static
Initial value:
= {
{ "TargetAddress", iscsi_handle_targetaddress_value },
{ "MaxBurstLength", iscsi_handle_maxburstlength_value },
{ "AuthMethod", iscsi_handle_authmethod_value },
{ NULL, NULL }
}
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition iscsi.c:973
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition iscsi.c:948
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition iscsi.c:1037
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition iscsi.c:996
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition iscsi.c:927
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition iscsi.c:1121
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition iscsi.c:1092
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition iscsi.c:897

iSCSI text strings that we want to handle

Definition at line 1204 of file iscsi.c.

1204 {
1205 { "TargetAddress", iscsi_handle_targetaddress_value },
1206 { "MaxBurstLength", iscsi_handle_maxburstlength_value },
1207 { "AuthMethod", iscsi_handle_authmethod_value },
1208 { "CHAP_A", iscsi_handle_chap_a_value },
1209 { "CHAP_I", iscsi_handle_chap_i_value },
1210 { "CHAP_C", iscsi_handle_chap_c_value },
1211 { "CHAP_N", iscsi_handle_chap_n_value },
1212 { "CHAP_R", iscsi_handle_chap_r_value },
1213 { NULL, NULL }
1214};

Referenced by iscsi_handle_string().

◆ iscsi_process_desc

struct process_descriptor iscsi_process_desc
static
Initial value:
=
static void iscsi_tx_step(struct iscsi_session *iscsi)
Transmit iSCSI PDU.
Definition iscsi.c:1552
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
A process.
Definition process.h:18

iSCSI TX process descriptor

Definition at line 1616 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_socket_operations

struct interface_operation iscsi_socket_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
static int iscsi_socket_deliver(struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
Definition iscsi.c:1716
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition iscsi.c:1800
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition xfer.c:63

iSCSI socket interface operations

Definition at line 1832 of file iscsi.c.

◆ iscsi_socket_desc

struct interface_descriptor iscsi_socket_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation iscsi_socket_operations[]
iSCSI socket interface operations
Definition iscsi.c:1832

iSCSI socket interface descriptor

Definition at line 1841 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_control_op

struct interface_operation iscsi_control_op[]
static
Initial value:
= {
}
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition acpi.c:321
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition blockdev.c:130
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:945
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition efi_path.c:531
#define EFI_INTF_OP
Definition efi.h:381
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition iscsi.c:1912
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition iscsi.c:1876
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
Definition iscsi.c:1930
A SCSI command.
Definition scsi.c:263

iSCSI SCSI command-issuing interface operations

Definition at line 1936 of file iscsi.c.

◆ iscsi_control_desc

struct interface_descriptor iscsi_control_desc
static
Initial value:
=
static struct interface_operation iscsi_control_op[]
iSCSI SCSI command-issuing interface operations
Definition iscsi.c:1936
uint32_t control
Control.
Definition myson.h:3

iSCSI SCSI command-issuing interface descriptor

Definition at line 1946 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_data_op

struct interface_operation iscsi_data_op[]
static
Initial value:
= {
}
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition iscsi.c:1955

iSCSI SCSI command interface operations

Definition at line 1968 of file iscsi.c.

1968 {
1970};

◆ iscsi_data_desc

struct interface_descriptor iscsi_data_desc
static
Initial value:
=
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Definition iscsi.c:1968

iSCSI SCSI command interface descriptor

Definition at line 1973 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:2192

iSCSI URI opener

Definition at line 2274 of file iscsi.c.

2274 {
2275 .scheme = "iscsi",
2276 .open = iscsi_open,
2277};