iPXE
iscsi.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 #include <stddef.h>
27 #include <string.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <errno.h>
32 #include <assert.h>
33 #include <byteswap.h>
34 #include <ipxe/vsprintf.h>
35 #include <ipxe/socket.h>
36 #include <ipxe/iobuf.h>
37 #include <ipxe/uri.h>
38 #include <ipxe/xfer.h>
39 #include <ipxe/open.h>
40 #include <ipxe/scsi.h>
41 #include <ipxe/process.h>
42 #include <ipxe/tcpip.h>
43 #include <ipxe/settings.h>
44 #include <ipxe/features.h>
45 #include <ipxe/base16.h>
46 #include <ipxe/base64.h>
47 #include <ipxe/ibft.h>
48 #include <ipxe/blockdev.h>
49 #include <ipxe/efi/efi_path.h>
50 #include <ipxe/iscsi.h>
51 
52 /** @file
53  *
54  * iSCSI protocol
55  *
56  */
57 
59 
60 /* Disambiguate the various error causes */
61 #define EACCES_INCORRECT_TARGET_USERNAME \
62  __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )
63 #define EINFO_EACCES_INCORRECT_TARGET_USERNAME \
64  __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )
65 #define EACCES_INCORRECT_TARGET_PASSWORD \
66  __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )
67 #define EINFO_EACCES_INCORRECT_TARGET_PASSWORD \
68  __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )
69 #define EINVAL_ROOT_PATH_TOO_SHORT \
70  __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )
71 #define EINFO_EINVAL_ROOT_PATH_TOO_SHORT \
72  __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )
73 #define EINVAL_BAD_CREDENTIAL_MIX \
74  __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )
75 #define EINFO_EINVAL_BAD_CREDENTIAL_MIX \
76  __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )
77 #define EINVAL_NO_ROOT_PATH \
78  __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )
79 #define EINFO_EINVAL_NO_ROOT_PATH \
80  __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )
81 #define EINVAL_NO_TARGET_IQN \
82  __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )
83 #define EINFO_EINVAL_NO_TARGET_IQN \
84  __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )
85 #define EINVAL_NO_INITIATOR_IQN \
86  __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )
87 #define EINFO_EINVAL_NO_INITIATOR_IQN \
88  __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )
89 #define EINVAL_MAXBURSTLENGTH \
90  __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )
91 #define EINFO_EINVAL_MAXBURSTLENGTH \
92  __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )
93 #define EIO_TARGET_UNAVAILABLE \
94  __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )
95 #define EINFO_EIO_TARGET_UNAVAILABLE \
96  __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )
97 #define EIO_TARGET_NO_RESOURCES \
98  __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )
99 #define EINFO_EIO_TARGET_NO_RESOURCES \
100  __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )
101 #define ENOTSUP_INITIATOR_STATUS \
102  __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )
103 #define EINFO_ENOTSUP_INITIATOR_STATUS \
104  __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )
105 #define ENOTSUP_OPCODE \
106  __einfo_error ( EINFO_ENOTSUP_OPCODE )
107 #define EINFO_ENOTSUP_OPCODE \
108  __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )
109 #define ENOTSUP_DISCOVERY \
110  __einfo_error ( EINFO_ENOTSUP_DISCOVERY )
111 #define EINFO_ENOTSUP_DISCOVERY \
112  __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )
113 #define ENOTSUP_TARGET_STATUS \
114  __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )
115 #define EINFO_ENOTSUP_TARGET_STATUS \
116  __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )
117 #define EPERM_INITIATOR_AUTHENTICATION \
118  __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )
119 #define EINFO_EPERM_INITIATOR_AUTHENTICATION \
120  __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )
121 #define EPERM_INITIATOR_AUTHORISATION \
122  __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )
123 #define EINFO_EPERM_INITIATOR_AUTHORISATION \
124  __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )
125 #define EPROTO_INVALID_CHAP_ALGORITHM \
126  __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )
127 #define EINFO_EPROTO_INVALID_CHAP_ALGORITHM \
128  __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )
129 #define EPROTO_INVALID_CHAP_IDENTIFIER \
130  __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )
131 #define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER \
132  __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )
133 #define EPROTO_INVALID_LARGE_BINARY \
134  __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )
135 #define EINFO_EPROTO_INVALID_LARGE_BINARY \
136  __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )
137 #define EPROTO_INVALID_CHAP_RESPONSE \
138  __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )
139 #define EINFO_EPROTO_INVALID_CHAP_RESPONSE \
140  __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )
141 #define EPROTO_INVALID_KEY_VALUE_PAIR \
142  __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )
143 #define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR \
144  __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )
145 #define EPROTO_VALUE_REJECTED \
146  __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )
147 #define EINFO_EPROTO_VALUE_REJECTED \
148  __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )
149 
150 static void iscsi_start_tx ( struct iscsi_session *iscsi );
151 static void iscsi_start_login ( struct iscsi_session *iscsi );
152 static void iscsi_start_data_out ( struct iscsi_session *iscsi,
153  unsigned int datasn );
154 
155 /**
156  * Finish receiving PDU data into buffer
157  *
158  * @v iscsi iSCSI session
159  */
160 static void iscsi_rx_buffered_data_done ( struct iscsi_session *iscsi ) {
161  free ( iscsi->rx_buffer );
162  iscsi->rx_buffer = NULL;
163 }
164 
165 /**
166  * Receive PDU data into buffer
167  *
168  * @v iscsi iSCSI session
169  * @v data Data to receive
170  * @v len Length of data
171  * @ret rc Return status code
172  *
173  * This can be used when the RX PDU type handler wishes to buffer up
174  * all received data and process the PDU as a single unit. The caller
175  * is repsonsible for calling iscsi_rx_buffered_data_done() after
176  * processing the data.
177  */
178 static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi,
179  const void *data, size_t len ) {
180 
181  /* Allocate buffer on first call */
182  if ( ! iscsi->rx_buffer ) {
183  iscsi->rx_buffer = malloc ( iscsi->rx_len );
184  if ( ! iscsi->rx_buffer )
185  return -ENOMEM;
186  }
187 
188  /* Copy data to buffer */
189  assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
190  memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
191 
192  return 0;
193 }
194 
195 /**
196  * Free iSCSI session
197  *
198  * @v refcnt Reference counter
199  */
200 static void iscsi_free ( struct refcnt *refcnt ) {
201  struct iscsi_session *iscsi =
203 
204  free ( iscsi->initiator_iqn );
205  free ( iscsi->target_address );
206  free ( iscsi->target_iqn );
207  free ( iscsi->initiator_username );
208  free ( iscsi->initiator_password );
209  free ( iscsi->target_username );
210  free ( iscsi->target_password );
211  chap_finish ( &iscsi->chap );
212  iscsi_rx_buffered_data_done ( iscsi );
213  free ( iscsi->command );
214  free ( iscsi );
215 }
216 
217 /**
218  * Shut down iSCSI interface
219  *
220  * @v iscsi iSCSI session
221  * @v rc Reason for close
222  */
223 static void iscsi_close ( struct iscsi_session *iscsi, int rc ) {
224 
225  /* A TCP graceful close is still an error from our point of view */
226  if ( rc == 0 )
227  rc = -ECONNRESET;
228 
229  DBGC ( iscsi, "iSCSI %p closed: %s\n", iscsi, strerror ( rc ) );
230 
231  /* Stop transmission process */
232  process_del ( &iscsi->process );
233 
234  /* Shut down interfaces */
235  intfs_shutdown ( rc, &iscsi->socket, &iscsi->control, &iscsi->data,
236  NULL );
237 }
238 
239 /**
240  * Assign new iSCSI initiator task tag
241  *
242  * @v iscsi iSCSI session
243  */
244 static void iscsi_new_itt ( struct iscsi_session *iscsi ) {
245  static uint16_t itt_idx;
246 
247  iscsi->itt = ( ISCSI_TAG_MAGIC | (++itt_idx) );
248 }
249 
250 /**
251  * Open iSCSI transport-layer connection
252  *
253  * @v iscsi iSCSI session
254  * @ret rc Return status code
255  */
256 static int iscsi_open_connection ( struct iscsi_session *iscsi ) {
257  struct sockaddr_tcpip target;
258  int rc;
259 
260  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
261  assert ( iscsi->rx_state == ISCSI_RX_BHS );
262  assert ( iscsi->rx_offset == 0 );
263 
264  /* Open socket */
265  memset ( &target, 0, sizeof ( target ) );
266  target.st_port = htons ( iscsi->target_port );
267  if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
268  ( struct sockaddr * ) &target,
269  iscsi->target_address,
270  NULL ) ) != 0 ) {
271  DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
272  iscsi, strerror ( rc ) );
273  return rc;
274  }
275 
276  /* Enter security negotiation phase */
279  if ( iscsi->target_username )
281 
282  /* Assign new ISID */
283  iscsi->isid_iana_qual = ( random() & 0xffff );
284 
285  /* Assign fresh initiator task tag */
286  iscsi_new_itt ( iscsi );
287 
288  /* Set default operational parameters */
290 
291  /* Initiate login */
292  iscsi_start_login ( iscsi );
293 
294  return 0;
295 }
296 
297 /**
298  * Close iSCSI transport-layer connection
299  *
300  * @v iscsi iSCSI session
301  * @v rc Reason for close
302  *
303  * Closes the transport-layer connection and resets the session state
304  * ready to attempt a fresh login.
305  */
306 static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) {
307 
308  /* Close all data transfer interfaces */
309  intf_restart ( &iscsi->socket, rc );
310 
311  /* Clear connection status */
312  iscsi->status = 0;
313 
314  /* Reset TX and RX state machines */
315  iscsi->tx_state = ISCSI_TX_IDLE;
316  iscsi->rx_state = ISCSI_RX_BHS;
317  iscsi->rx_offset = 0;
318 
319  /* Free any temporary dynamically allocated memory */
320  chap_finish ( &iscsi->chap );
321  iscsi_rx_buffered_data_done ( iscsi );
322 }
323 
324 /**
325  * Mark iSCSI SCSI operation as complete
326  *
327  * @v iscsi iSCSI session
328  * @v rc Return status code
329  * @v rsp SCSI response, if any
330  *
331  * Note that iscsi_scsi_done() will not close the connection, and must
332  * therefore be called only when the internal state machines are in an
333  * appropriate state, otherwise bad things may happen on the next call
334  * to iscsi_scsi_command(). The general rule is to call
335  * iscsi_scsi_done() only at the end of receiving a PDU; at this point
336  * the TX and RX engines should both be idle.
337  */
338 static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc,
339  struct scsi_rsp *rsp ) {
340  uint32_t itt = iscsi->itt;
341 
342  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
343 
344  /* Clear command */
345  free ( iscsi->command );
346  iscsi->command = NULL;
347 
348  /* Send SCSI response, if any */
349  if ( rsp )
350  scsi_response ( &iscsi->data, rsp );
351 
352  /* Close SCSI command, if this is still the same command. (It
353  * is possible that the command interface has already been
354  * closed as a result of the SCSI response we sent.)
355  */
356  if ( iscsi->itt == itt )
357  intf_restart ( &iscsi->data, rc );
358 }
359 
360 /****************************************************************************
361  *
362  * iSCSI SCSI command issuing
363  *
364  */
365 
366 /**
367  * Build iSCSI SCSI command BHS
368  *
369  * @v iscsi iSCSI session
370  *
371  * We don't currently support bidirectional commands (i.e. with both
372  * Data-In and Data-Out segments); these would require providing code
373  * to generate an AHS, and there doesn't seem to be any need for it at
374  * the moment.
375  */
376 static void iscsi_start_command ( struct iscsi_session *iscsi ) {
378 
379  assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
380 
381  /* Construct BHS and initiate transmission */
382  iscsi_start_tx ( iscsi );
384  command->flags = ( ISCSI_FLAG_FINAL |
386  if ( iscsi->command->data_in )
388  if ( iscsi->command->data_out )
390  /* lengths left as zero */
391  memcpy ( &command->lun, &iscsi->command->lun,
392  sizeof ( command->lun ) );
393  command->itt = htonl ( iscsi->itt );
394  command->exp_len = htonl ( iscsi->command->data_in_len |
395  iscsi->command->data_out_len );
396  command->cmdsn = htonl ( iscsi->cmdsn );
397  command->expstatsn = htonl ( iscsi->statsn + 1 );
398  memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
399  DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
400  iscsi, SCSI_CDB_DATA ( command->cdb ),
401  ( iscsi->command->data_in ? "in" : "out" ),
402  ( iscsi->command->data_in ?
403  iscsi->command->data_in_len :
404  iscsi->command->data_out_len ) );
405 }
406 
407 /**
408  * Receive data segment of an iSCSI SCSI response PDU
409  *
410  * @v iscsi iSCSI session
411  * @v data Received data
412  * @v len Length of received data
413  * @v remaining Data remaining after this data
414  * @ret rc Return status code
415  */
416 static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi,
417  const void *data, size_t len,
418  size_t remaining ) {
420  = &iscsi->rx_bhs.scsi_response;
421  struct scsi_rsp rsp;
422  uint32_t residual_count;
423  size_t data_len;
424  int rc;
425 
426  /* Buffer up the PDU data */
427  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
428  DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
429  iscsi, strerror ( rc ) );
430  return rc;
431  }
432  if ( remaining )
433  return 0;
434 
435  /* Parse SCSI response and discard buffer */
436  memset ( &rsp, 0, sizeof ( rsp ) );
437  rsp.status = response->status;
438  residual_count = ntohl ( response->residual_count );
439  if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
440  rsp.overrun = residual_count;
441  } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
442  rsp.overrun = -(residual_count);
443  }
444  data_len = ISCSI_DATA_LEN ( response->lengths );
445  if ( data_len ) {
446  scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
447  &rsp.sense );
448  }
449  iscsi_rx_buffered_data_done ( iscsi );
450 
451  /* Check for errors */
452  if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
453  return -EIO;
454 
455  /* Mark as completed */
456  iscsi_scsi_done ( iscsi, 0, &rsp );
457  return 0;
458 }
459 
460 /**
461  * Receive data segment of an iSCSI data-in PDU
462  *
463  * @v iscsi iSCSI session
464  * @v data Received data
465  * @v len Length of received data
466  * @v remaining Data remaining after this data
467  * @ret rc Return status code
468  */
469 static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
470  const void *data, size_t len,
471  size_t remaining ) {
472  struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
473  unsigned long offset;
474 
475  /* Copy data to data-in buffer */
476  offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
477  assert ( iscsi->command != NULL );
478  assert ( iscsi->command->data_in );
479  assert ( ( offset + len ) <= iscsi->command->data_in_len );
480  memcpy ( ( iscsi->command->data_in + offset ), data, len );
481 
482  /* Wait for whole SCSI response to arrive */
483  if ( remaining )
484  return 0;
485 
486  /* Mark as completed if status is present */
487  if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
488  assert ( ( offset + len ) == iscsi->command->data_in_len );
489  assert ( data_in->flags & ISCSI_FLAG_FINAL );
490  /* iSCSI cannot return an error status via a data-in */
491  iscsi_scsi_done ( iscsi, 0, NULL );
492  }
493 
494  return 0;
495 }
496 
497 /**
498  * Receive data segment of an iSCSI R2T PDU
499  *
500  * @v iscsi iSCSI session
501  * @v data Received data
502  * @v len Length of received data
503  * @v remaining Data remaining after this data
504  * @ret rc Return status code
505  */
506 static int iscsi_rx_r2t ( struct iscsi_session *iscsi,
507  const void *data __unused, size_t len __unused,
508  size_t remaining __unused ) {
509  struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
510 
511  /* Record transfer parameters and trigger first data-out */
512  iscsi->ttt = ntohl ( r2t->ttt );
513  iscsi->transfer_offset = ntohl ( r2t->offset );
514  iscsi->transfer_len = ntohl ( r2t->len );
515  iscsi_start_data_out ( iscsi, 0 );
516 
517  return 0;
518 }
519 
520 /**
521  * Build iSCSI data-out BHS
522  *
523  * @v iscsi iSCSI session
524  * @v datasn Data sequence number within the transfer
525  *
526  */
527 static void iscsi_start_data_out ( struct iscsi_session *iscsi,
528  unsigned int datasn ) {
529  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
530  unsigned long offset;
531  unsigned long remaining;
532  unsigned long len;
533 
534  /* We always send 512-byte Data-Out PDUs; this removes the
535  * need to worry about the target's MaxRecvDataSegmentLength.
536  */
537  offset = datasn * 512;
538  remaining = iscsi->transfer_len - offset;
539  len = remaining;
540  if ( len > 512 )
541  len = 512;
542 
543  /* Construct BHS and initiate transmission */
544  iscsi_start_tx ( iscsi );
545  data_out->opcode = ISCSI_OPCODE_DATA_OUT;
546  if ( len == remaining )
547  data_out->flags = ( ISCSI_FLAG_FINAL );
548  ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
549  data_out->lun = iscsi->command->lun;
550  data_out->itt = htonl ( iscsi->itt );
551  data_out->ttt = htonl ( iscsi->ttt );
552  data_out->expstatsn = htonl ( iscsi->statsn + 1 );
553  data_out->datasn = htonl ( datasn );
554  data_out->offset = htonl ( iscsi->transfer_offset + offset );
555  DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
556  iscsi, datasn, len );
557 }
558 
559 /**
560  * Complete iSCSI data-out PDU transmission
561  *
562  * @v iscsi iSCSI session
563  *
564  */
565 static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
566  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
567 
568  /* If we haven't reached the end of the sequence, start
569  * sending the next data-out PDU.
570  */
571  if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
572  iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
573 }
574 
575 /**
576  * Send iSCSI data-out data segment
577  *
578  * @v iscsi iSCSI session
579  * @ret rc Return status code
580  */
581 static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
582  struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
583  struct io_buffer *iobuf;
584  unsigned long offset;
585  size_t len;
586  size_t pad_len;
587 
588  offset = ntohl ( data_out->offset );
589  len = ISCSI_DATA_LEN ( data_out->lengths );
590  pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
591 
592  assert ( iscsi->command != NULL );
593  assert ( iscsi->command->data_out );
594  assert ( ( offset + len ) <= iscsi->command->data_out_len );
595 
596  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
597  if ( ! iobuf )
598  return -ENOMEM;
599 
600  memcpy ( iob_put ( iobuf, len ),
601  ( iscsi->command->data_out + offset ), len );
602  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
603 
604  return xfer_deliver_iob ( &iscsi->socket, iobuf );
605 }
606 
607 /**
608  * Receive data segment of an iSCSI NOP-In
609  *
610  * @v iscsi iSCSI session
611  * @v data Received data
612  * @v len Length of received data
613  * @v remaining Data remaining after this data
614  * @ret rc Return status code
615  */
616 static int iscsi_rx_nop_in ( struct iscsi_session *iscsi,
617  const void *data __unused, size_t len __unused,
618  size_t remaining __unused ) {
619  struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in;
620 
621  DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi );
622 
623  /* We don't currently have the ability to respond to NOP-Ins
624  * sent as ping requests, but we can happily accept NOP-Ins
625  * sent merely to update CmdSN.
626  */
627  if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) )
628  return 0;
629 
630  /* Ignore any other NOP-Ins. The target may eventually
631  * disconnect us for failing to respond, but this minimises
632  * unnecessary connection closures.
633  */
634  DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n",
635  iscsi, ntohl ( nop_in->ttt ) );
636  return 0;
637 }
638 
639 /****************************************************************************
640  *
641  * iSCSI login
642  *
643  */
644 
645 /**
646  * Build iSCSI login request strings
647  *
648  * @v iscsi iSCSI session
649  *
650  * These are the initial set of strings sent in the first login
651  * request PDU. We want the following settings:
652  *
653  * HeaderDigest=None
654  * DataDigest=None
655  * MaxConnections=1 (irrelevant; we make only one connection anyway) [4]
656  * InitialR2T=Yes [1]
657  * ImmediateData=No (irrelevant; we never send immediate data) [4]
658  * MaxRecvDataSegmentLength=8192 (default; we don't care) [3]
659  * MaxBurstLength=262144 (default; we don't care) [3]
660  * FirstBurstLength=65536 (irrelevant due to other settings) [5]
661  * DefaultTime2Wait=0 [2]
662  * DefaultTime2Retain=0 [2]
663  * MaxOutstandingR2T=1
664  * DataPDUInOrder=Yes
665  * DataSequenceInOrder=Yes
666  * ErrorRecoveryLevel=0
667  *
668  * [1] InitialR2T has an OR resolution function, so the target may
669  * force us to use it. We therefore simplify our logic by always
670  * using it.
671  *
672  * [2] These ensure that we can safely start a new task once we have
673  * reconnected after a failure, without having to manually tidy up
674  * after the old one.
675  *
676  * [3] We are quite happy to use the RFC-defined default values for
677  * these parameters, but some targets (notably OpenSolaris)
678  * incorrectly assume a default value of zero, so we explicitly
679  * specify the default values.
680  *
681  * [4] We are quite happy to use the RFC-defined default values for
682  * these parameters, but some targets (notably a QNAP TS-639Pro) fail
683  * unless they are supplied, so we explicitly specify the default
684  * values.
685  *
686  * [5] FirstBurstLength is defined to be irrelevant since we already
687  * force InitialR2T=Yes and ImmediateData=No, but some targets
688  * (notably LIO as of kernel 4.11) fail unless it is specified, so we
689  * explicitly specify the default value.
690  */
692  void *data, size_t len ) {
693  unsigned int used = 0;
694  const char *auth_method;
695 
696  if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
697  /* Default to allowing no authentication */
698  auth_method = "None";
699  /* If we have a credential to supply, permit CHAP */
700  if ( iscsi->initiator_username )
701  auth_method = "CHAP,None";
702  /* If we have a credential to check, force CHAP */
703  if ( iscsi->target_username )
704  auth_method = "CHAP";
705  used += ssnprintf ( data + used, len - used,
706  "InitiatorName=%s%c"
707  "TargetName=%s%c"
708  "SessionType=Normal%c"
709  "AuthMethod=%s%c",
710  iscsi->initiator_iqn, 0,
711  iscsi->target_iqn, 0, 0,
712  auth_method, 0 );
713  }
714 
716  used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
717  }
718 
719  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
720  char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
721  assert ( iscsi->initiator_username != NULL );
722  base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
723  buf, sizeof ( buf ) );
724  used += ssnprintf ( data + used, len - used,
725  "CHAP_N=%s%cCHAP_R=0x%s%c",
726  iscsi->initiator_username, 0, buf, 0 );
727  }
728 
729  if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
730  size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
731  char buf[ base16_encoded_len ( challenge_len ) + 1 ];
732  base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
733  buf, sizeof ( buf ) );
734  used += ssnprintf ( data + used, len - used,
735  "CHAP_I=%d%cCHAP_C=0x%s%c",
736  iscsi->chap_challenge[0], 0, buf, 0 );
737  }
738 
739  if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) {
740  used += ssnprintf ( data + used, len - used,
741  "HeaderDigest=None%c"
742  "DataDigest=None%c"
743  "MaxConnections=1%c"
744  "InitialR2T=Yes%c"
745  "ImmediateData=No%c"
746  "MaxRecvDataSegmentLength=%d%c"
747  "MaxBurstLength=%d%c"
748  "FirstBurstLength=%d%c"
749  "DefaultTime2Wait=0%c"
750  "DefaultTime2Retain=0%c"
751  "MaxOutstandingR2T=1%c"
752  "DataPDUInOrder=Yes%c"
753  "DataSequenceInOrder=Yes%c"
754  "ErrorRecoveryLevel=0%c",
755  0, 0, 0, 0, 0,
759  0, 0, 0, 0, 0, 0 );
760  }
761 
762  return used;
763 }
764 
765 /**
766  * Build iSCSI login request BHS
767  *
768  * @v iscsi iSCSI session
769  */
770 static void iscsi_start_login ( struct iscsi_session *iscsi ) {
772  int len;
773 
774  switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
776  DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
777  iscsi );
778  break;
780  DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
781  iscsi );
782  break;
783  default:
784  assert ( 0 );
785  }
786 
787  /* Construct BHS and initiate transmission */
788  iscsi_start_tx ( iscsi );
789  request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
791  request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
793  /* version_max and version_min left as zero */
795  ISCSI_SET_LENGTHS ( request->lengths, 0, len );
796  request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
798  request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
799  /* tsih left as zero */
800  request->itt = htonl ( iscsi->itt );
801  /* cid left as zero */
802  request->cmdsn = htonl ( iscsi->cmdsn );
803  request->expstatsn = htonl ( iscsi->statsn + 1 );
804 }
805 
806 /**
807  * Complete iSCSI login request PDU transmission
808  *
809  * @v iscsi iSCSI session
810  *
811  */
812 static void iscsi_login_request_done ( struct iscsi_session *iscsi ) {
813 
814  /* Clear any "strings to send" flags */
816 
817  /* Free any dynamically allocated storage used for login */
818  chap_finish ( &iscsi->chap );
819 }
820 
821 /**
822  * Transmit data segment of an iSCSI login request PDU
823  *
824  * @v iscsi iSCSI session
825  * @ret rc Return status code
826  *
827  * For login requests, the data segment consists of the login strings.
828  */
829 static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
831  struct io_buffer *iobuf;
832  size_t len;
833  size_t pad_len;
834 
835  len = ISCSI_DATA_LEN ( request->lengths );
836  pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
837  iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
838  if ( ! iobuf )
839  return -ENOMEM;
840  iob_put ( iobuf, len );
841  iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
842  memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
843 
844  return xfer_deliver_iob ( &iscsi->socket, iobuf );
845 }
846 
847 /**
848  * Decode large binary value
849  *
850  * @v encoded Encoded large binary value
851  * @v raw Raw data
852  * @v len Length of data buffer
853  * @ret len Length of raw data, or negative error
854  */
855 static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw,
856  size_t len ) {
857 
858  /* Check for initial '0x' or '0b' and decode as appropriate */
859  if ( *(encoded++) == '0' ) {
860  switch ( tolower ( *(encoded++) ) ) {
861  case 'x' :
862  return base16_decode ( encoded, raw, len );
863  case 'b' :
864  return base64_decode ( encoded, raw, len );
865  }
866  }
867 
869 }
870 
871 /**
872  * Handle iSCSI TargetAddress text value
873  *
874  * @v iscsi iSCSI session
875  * @v value TargetAddress value
876  * @ret rc Return status code
877  */
879  const char *value ) {
880  char *separator;
881 
882  DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
883 
884  /* Replace target address */
885  free ( iscsi->target_address );
886  iscsi->target_address = strdup ( value );
887  if ( ! iscsi->target_address )
888  return -ENOMEM;
889 
890  /* Replace target port */
891  iscsi->target_port = htons ( ISCSI_PORT );
892  separator = strchr ( iscsi->target_address, ':' );
893  if ( separator ) {
894  *separator = '\0';
895  iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
896  }
897 
898  return 0;
899 }
900 
901 /**
902  * Handle iSCSI AuthMethod text value
903  *
904  * @v iscsi iSCSI session
905  * @v value AuthMethod value
906  * @ret rc Return status code
907  */
908 static int iscsi_handle_authmethod_value ( struct iscsi_session *iscsi,
909  const char *value ) {
910 
911  /* If server requests CHAP, send the CHAP_A string */
912  if ( strcmp ( value, "CHAP" ) == 0 ) {
913  DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
914  iscsi );
917  }
918 
919  return 0;
920 }
921 
922 /**
923  * Handle iSCSI MaxBurstLength text value
924  *
925  * @v iscsi iSCSI session
926  * @v value MaxBurstLength value
927  * @ret rc Return status code
928  */
930  const char *value ) {
931  unsigned long max_burst_len;
932  char *end;
933 
934  /* Update maximum burst length */
935  max_burst_len = strtoul ( value, &end, 0 );
936  if ( *end ) {
937  DBGC ( iscsi, "iSCSI %p invalid MaxBurstLength \"%s\"\n",
938  iscsi, value );
939  return -EINVAL_MAXBURSTLENGTH;
940  }
941  if ( max_burst_len < iscsi->max_burst_len )
942  iscsi->max_burst_len = max_burst_len;
943 
944  return 0;
945 }
946 
947 /**
948  * Handle iSCSI CHAP_A text value
949  *
950  * @v iscsi iSCSI session
951  * @v value CHAP_A value
952  * @ret rc Return status code
953  */
954 static int iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
955  const char *value ) {
956 
957  /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
958  * the server responds with anything else it is a protocol
959  * violation.
960  */
961  if ( strcmp ( value, "5" ) != 0 ) {
962  DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
963  iscsi, value );
965  }
966 
967  return 0;
968 }
969 
970 /**
971  * Handle iSCSI CHAP_I text value
972  *
973  * @v iscsi iSCSI session
974  * @v value CHAP_I value
975  * @ret rc Return status code
976  */
977 static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
978  const char *value ) {
979  unsigned int identifier;
980  char *endp;
981  int rc;
982 
983  /* The CHAP identifier is an integer value */
984  identifier = strtoul ( value, &endp, 0 );
985  if ( *endp != '\0' ) {
986  DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
987  iscsi, value );
989  }
990 
991  /* Prepare for CHAP with MD5 */
992  chap_finish ( &iscsi->chap );
993  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
994  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
995  iscsi, strerror ( rc ) );
996  return rc;
997  }
998 
999  /* Identifier and secret are the first two components of the
1000  * challenge.
1001  */
1002  chap_set_identifier ( &iscsi->chap, identifier );
1003  if ( iscsi->initiator_password ) {
1004  chap_update ( &iscsi->chap, iscsi->initiator_password,
1005  strlen ( iscsi->initiator_password ) );
1006  }
1007 
1008  return 0;
1009 }
1010 
1011 /**
1012  * Handle iSCSI CHAP_C text value
1013  *
1014  * @v iscsi iSCSI session
1015  * @v value CHAP_C value
1016  * @ret rc Return status code
1017  */
1018 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
1019  const char *value ) {
1020  uint8_t *buf;
1021  unsigned int i;
1022  int len;
1023  int rc;
1024 
1025  /* Allocate decoding buffer */
1026  len = strlen ( value ); /* Decoding never expands data */
1027  buf = malloc ( len );
1028  if ( ! buf ) {
1029  rc = -ENOMEM;
1030  goto err_alloc;
1031  }
1032 
1033  /* Process challenge */
1034  len = iscsi_large_binary_decode ( value, buf, len );
1035  if ( len < 0 ) {
1036  rc = len;
1037  DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1038  iscsi, value, strerror ( rc ) );
1039  goto err_decode;
1040  }
1041  chap_update ( &iscsi->chap, buf, len );
1042 
1043  /* Build CHAP response */
1044  DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1045  chap_respond ( &iscsi->chap );
1047 
1048  /* Send CHAP challenge, if applicable */
1049  if ( iscsi->target_username ) {
1051  /* Generate CHAP challenge data */
1052  for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1053  iscsi->chap_challenge[i] = random();
1054  }
1055  }
1056 
1057  /* Success */
1058  rc = 0;
1059 
1060  err_decode:
1061  free ( buf );
1062  err_alloc:
1063  return rc;
1064 }
1065 
1066 /**
1067  * Handle iSCSI CHAP_N text value
1068  *
1069  * @v iscsi iSCSI session
1070  * @v value CHAP_N value
1071  * @ret rc Return status code
1072  */
1073 static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
1074  const char *value ) {
1075 
1076  /* The target username isn't actually involved at any point in
1077  * the authentication process; it merely serves to identify
1078  * which password the target is using to generate the CHAP
1079  * response. We unnecessarily verify that the username is as
1080  * expected, in order to provide mildly helpful diagnostics if
1081  * the target is supplying the wrong username/password
1082  * combination.
1083  */
1084  if ( iscsi->target_username &&
1085  ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1086  DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1087  "(wanted \"%s\")\n",
1088  iscsi, value, iscsi->target_username );
1090  }
1091 
1092  return 0;
1093 }
1094 
1095 /**
1096  * Handle iSCSI CHAP_R text value
1097  *
1098  * @v iscsi iSCSI session
1099  * @v value CHAP_R value
1100  * @ret rc Return status code
1101  */
1102 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
1103  const char *value ) {
1104  uint8_t *buf;
1105  int len;
1106  int rc;
1107 
1108  /* Generate CHAP response for verification */
1109  chap_finish ( &iscsi->chap );
1110  if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1111  DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1112  iscsi, strerror ( rc ) );
1113  goto err_chap_init;
1114  }
1115  chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1116  if ( iscsi->target_password ) {
1117  chap_update ( &iscsi->chap, iscsi->target_password,
1118  strlen ( iscsi->target_password ) );
1119  }
1120  chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1121  ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1122  chap_respond ( &iscsi->chap );
1123 
1124  /* Allocate decoding buffer */
1125  len = strlen ( value ); /* Decoding never expands data */
1126  buf = malloc ( len );
1127  if ( ! buf ) {
1128  rc = -ENOMEM;
1129  goto err_alloc;
1130  }
1131 
1132  /* Process response */
1133  len = iscsi_large_binary_decode ( value, buf, len );
1134  if ( len < 0 ) {
1135  rc = len;
1136  DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1137  iscsi, value, strerror ( rc ) );
1138  goto err_decode;
1139  }
1140 
1141  /* Check CHAP response */
1142  if ( len != ( int ) iscsi->chap.response_len ) {
1143  DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1144  iscsi );
1146  goto err_response_len;
1147  }
1148  if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1149  DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1150  iscsi, value );
1152  goto err_response;
1153  }
1154 
1155  /* Mark session as authenticated */
1157 
1158  err_response:
1159  err_response_len:
1160  err_decode:
1161  free ( buf );
1162  err_alloc:
1163  err_chap_init:
1164  return rc;
1165 }
1166 
1167 /** An iSCSI text string that we want to handle */
1169  /** String key
1170  *
1171  * This is the portion preceding the "=" sign,
1172  * e.g. "InitiatorName", "CHAP_A", etc.
1173  */
1174  const char *key;
1175  /** Handle iSCSI string value
1176  *
1177  * @v iscsi iSCSI session
1178  * @v value iSCSI string value
1179  * @ret rc Return status code
1180  */
1181  int ( * handle ) ( struct iscsi_session *iscsi, const char *value );
1182 };
1183 
1184 /** iSCSI text strings that we want to handle */
1186  { "TargetAddress", iscsi_handle_targetaddress_value },
1187  { "MaxBurstLength", iscsi_handle_maxburstlength_value },
1188  { "AuthMethod", iscsi_handle_authmethod_value },
1189  { "CHAP_A", iscsi_handle_chap_a_value },
1190  { "CHAP_I", iscsi_handle_chap_i_value },
1191  { "CHAP_C", iscsi_handle_chap_c_value },
1192  { "CHAP_N", iscsi_handle_chap_n_value },
1193  { "CHAP_R", iscsi_handle_chap_r_value },
1194  { NULL, NULL }
1195 };
1196 
1197 /**
1198  * Handle iSCSI string
1199  *
1200  * @v iscsi iSCSI session
1201  * @v string iSCSI string (in "key=value" format)
1202  * @ret rc Return status code
1203  */
1204 static int iscsi_handle_string ( struct iscsi_session *iscsi,
1205  const char *string ) {
1206  struct iscsi_string_type *type;
1207  const char *separator;
1208  const char *value;
1209  size_t key_len;
1210  int rc;
1211 
1212  /* Find separator */
1213  separator = strchr ( string, '=' );
1214  if ( ! separator ) {
1215  DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1216  iscsi, string );
1218  }
1219  key_len = ( separator - string );
1220  value = ( separator + 1 );
1221 
1222  /* Check for rejections. Since we send only non-rejectable
1223  * values, any rejection is a fatal protocol error.
1224  */
1225  if ( strcmp ( value, "Reject" ) == 0 ) {
1226  DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1227  return -EPROTO_VALUE_REJECTED;
1228  }
1229 
1230  /* Handle key/value pair */
1231  for ( type = iscsi_string_types ; type->key ; type++ ) {
1232  if ( strncmp ( string, type->key, key_len ) != 0 )
1233  continue;
1234  DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1235  if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1236  DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1237  iscsi, string, strerror ( rc ) );
1238  return rc;
1239  }
1240  return 0;
1241  }
1242  DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1243  return 0;
1244 }
1245 
1246 /**
1247  * Handle iSCSI strings
1248  *
1249  * @v iscsi iSCSI session
1250  * @v string iSCSI string buffer
1251  * @v len Length of string buffer
1252  * @ret rc Return status code
1253  */
1254 static int iscsi_handle_strings ( struct iscsi_session *iscsi,
1255  const char *strings, size_t len ) {
1256  size_t string_len;
1257  int rc;
1258 
1259  /* Handle each string in turn, taking care not to overrun the
1260  * data buffer in case of badly-terminated data.
1261  */
1262  while ( 1 ) {
1263  string_len = ( strnlen ( strings, len ) + 1 );
1264  if ( string_len > len )
1265  break;
1266  if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1267  return rc;
1268  strings += string_len;
1269  len -= string_len;
1270  }
1271  return 0;
1272 }
1273 
1274 /**
1275  * Convert iSCSI response status to return status code
1276  *
1277  * @v status_class iSCSI status class
1278  * @v status_detail iSCSI status detail
1279  * @ret rc Return status code
1280  */
1281 static int iscsi_status_to_rc ( unsigned int status_class,
1282  unsigned int status_detail ) {
1283  switch ( status_class ) {
1285  switch ( status_detail ) {
1292  return -ENODEV;
1293  default :
1294  return -ENOTSUP_INITIATOR_STATUS;
1295  }
1297  switch ( status_detail ) {
1299  return -EIO_TARGET_UNAVAILABLE;
1301  return -EIO_TARGET_NO_RESOURCES;
1302  default:
1303  return -ENOTSUP_TARGET_STATUS;
1304  }
1305  default :
1306  return -EINVAL;
1307  }
1308 }
1309 
1310 /**
1311  * Receive data segment of an iSCSI login response PDU
1312  *
1313  * @v iscsi iSCSI session
1314  * @v data Received data
1315  * @v len Length of received data
1316  * @v remaining Data remaining after this data
1317  * @ret rc Return status code
1318  */
1319 static int iscsi_rx_login_response ( struct iscsi_session *iscsi,
1320  const void *data, size_t len,
1321  size_t remaining ) {
1322  struct iscsi_bhs_login_response *response
1323  = &iscsi->rx_bhs.login_response;
1324  int rc;
1325 
1326  /* Buffer up the PDU data */
1327  if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1328  DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1329  iscsi, strerror ( rc ) );
1330  return rc;
1331  }
1332  if ( remaining )
1333  return 0;
1334 
1335  /* Process string data and discard string buffer */
1336  if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1337  iscsi->rx_len ) ) != 0 )
1338  return rc;
1339  iscsi_rx_buffered_data_done ( iscsi );
1340 
1341  /* Check for login redirection */
1342  if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1343  DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1344  iscsi_close_connection ( iscsi, 0 );
1345  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1346  DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1347  iscsi, strerror ( rc ) );
1348  return rc;
1349  }
1350  return 0;
1351  }
1352 
1353  /* Check for fatal errors */
1354  if ( response->status_class != 0 ) {
1355  DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1356  response->status_class, response->status_detail );
1357  rc = iscsi_status_to_rc ( response->status_class,
1358  response->status_detail );
1359  return rc;
1360  }
1361 
1362  /* Handle login transitions */
1363  if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1364  iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1366  switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1368  iscsi->status |=
1371  break;
1374  break;
1375  default:
1376  DBGC ( iscsi, "iSCSI %p got invalid response flags "
1377  "%02x\n", iscsi, response->flags );
1378  return -EIO;
1379  }
1380  }
1381 
1382  /* Send next login request PDU if we haven't reached the full
1383  * feature phase yet.
1384  */
1385  if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1387  iscsi_start_login ( iscsi );
1388  return 0;
1389  }
1390 
1391  /* Check that target authentication was successful (if required) */
1392  if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1393  ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1394  DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1395  "authentication\n", iscsi );
1396  return -EPROTO;
1397  }
1398 
1399  /* Notify SCSI layer of window change */
1400  DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1401  xfer_window_changed ( &iscsi->control );
1402 
1403  return 0;
1404 }
1405 
1406 /****************************************************************************
1407  *
1408  * iSCSI to socket interface
1409  *
1410  */
1411 
1412 /**
1413  * Pause TX engine
1414  *
1415  * @v iscsi iSCSI session
1416  */
1417 static void iscsi_tx_pause ( struct iscsi_session *iscsi ) {
1418  process_del ( &iscsi->process );
1419 }
1420 
1421 /**
1422  * Resume TX engine
1423  *
1424  * @v iscsi iSCSI session
1425  */
1426 static void iscsi_tx_resume ( struct iscsi_session *iscsi ) {
1427  process_add ( &iscsi->process );
1428 }
1429 
1430 /**
1431  * Start up a new TX PDU
1432  *
1433  * @v iscsi iSCSI session
1434  *
1435  * This initiates the process of sending a new PDU. Only one PDU may
1436  * be in transit at any one time.
1437  */
1438 static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
1439 
1440  assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1441 
1442  /* Initialise TX BHS */
1443  memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1444 
1445  /* Flag TX engine to start transmitting */
1446  iscsi->tx_state = ISCSI_TX_BHS;
1447 
1448  /* Start transmission process */
1449  iscsi_tx_resume ( iscsi );
1450 }
1451 
1452 /**
1453  * Transmit nothing
1454  *
1455  * @v iscsi iSCSI session
1456  * @ret rc Return status code
1457  */
1458 static int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused ) {
1459  return 0;
1460 }
1461 
1462 /**
1463  * Transmit basic header segment of an iSCSI PDU
1464  *
1465  * @v iscsi iSCSI session
1466  * @ret rc Return status code
1467  */
1468 static int iscsi_tx_bhs ( struct iscsi_session *iscsi ) {
1469  return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1470  sizeof ( iscsi->tx_bhs ) );
1471 }
1472 
1473 /**
1474  * Transmit data segment of an iSCSI PDU
1475  *
1476  * @v iscsi iSCSI session
1477  * @ret rc Return status code
1478  *
1479  * Handle transmission of part of a PDU data segment. iscsi::tx_bhs
1480  * will be valid when this is called.
1481  */
1482 static int iscsi_tx_data ( struct iscsi_session *iscsi ) {
1483  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1484 
1485  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1486  case ISCSI_OPCODE_DATA_OUT:
1487  return iscsi_tx_data_out ( iscsi );
1489  return iscsi_tx_login_request ( iscsi );
1490  default:
1491  /* Nothing to send in other states */
1492  return 0;
1493  }
1494 }
1495 
1496 /**
1497  * Complete iSCSI PDU transmission
1498  *
1499  * @v iscsi iSCSI session
1500  *
1501  * Called when a PDU has been completely transmitted and the TX state
1502  * machine is about to enter the idle state. iscsi::tx_bhs will be
1503  * valid for the just-completed PDU when this is called.
1504  */
1505 static void iscsi_tx_done ( struct iscsi_session *iscsi ) {
1506  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1507 
1508  /* Stop transmission process */
1509  iscsi_tx_pause ( iscsi );
1510 
1511  switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1512  case ISCSI_OPCODE_DATA_OUT:
1513  iscsi_data_out_done ( iscsi );
1514  break;
1516  iscsi_login_request_done ( iscsi );
1517  break;
1518  default:
1519  /* No action */
1520  break;
1521  }
1522 }
1523 
1524 /**
1525  * Transmit iSCSI PDU
1526  *
1527  * @v iscsi iSCSI session
1528  * @v buf Temporary data buffer
1529  * @v len Length of temporary data buffer
1530  *
1531  * Constructs data to be sent for the current TX state
1532  */
1533 static void iscsi_tx_step ( struct iscsi_session *iscsi ) {
1534  struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1535  int ( * tx ) ( struct iscsi_session *iscsi );
1536  enum iscsi_tx_state next_state;
1537  size_t tx_len;
1538  int rc;
1539 
1540  /* Select fragment to transmit */
1541  while ( 1 ) {
1542  switch ( iscsi->tx_state ) {
1543  case ISCSI_TX_BHS:
1544  tx = iscsi_tx_bhs;
1545  tx_len = sizeof ( iscsi->tx_bhs );
1546  next_state = ISCSI_TX_AHS;
1547  break;
1548  case ISCSI_TX_AHS:
1549  tx = iscsi_tx_nothing;
1550  tx_len = 0;
1551  next_state = ISCSI_TX_DATA;
1552  break;
1553  case ISCSI_TX_DATA:
1554  tx = iscsi_tx_data;
1555  tx_len = ISCSI_DATA_LEN ( common->lengths );
1556  next_state = ISCSI_TX_IDLE;
1557  break;
1558  case ISCSI_TX_IDLE:
1559  /* Nothing to do; pause processing */
1560  iscsi_tx_pause ( iscsi );
1561  return;
1562  default:
1563  assert ( 0 );
1564  return;
1565  }
1566 
1567  /* Check for window availability, if needed */
1568  if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1569  /* Cannot transmit at this point; pause
1570  * processing and wait for window to reopen
1571  */
1572  iscsi_tx_pause ( iscsi );
1573  return;
1574  }
1575 
1576  /* Transmit data */
1577  if ( ( rc = tx ( iscsi ) ) != 0 ) {
1578  DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1579  iscsi, strerror ( rc ) );
1580  /* Transmission errors are fatal */
1581  iscsi_close ( iscsi, rc );
1582  return;
1583  }
1584 
1585  /* Move to next state */
1586  iscsi->tx_state = next_state;
1587 
1588  /* If we have moved to the idle state, mark
1589  * transmission as complete
1590  */
1591  if ( iscsi->tx_state == ISCSI_TX_IDLE )
1592  iscsi_tx_done ( iscsi );
1593  }
1594 }
1595 
1596 /** iSCSI TX process descriptor */
1599 
1600 /**
1601  * Receive basic header segment of an iSCSI PDU
1602  *
1603  * @v iscsi iSCSI session
1604  * @v data Received data
1605  * @v len Length of received data
1606  * @v remaining Data remaining after this data
1607  * @ret rc Return status code
1608  *
1609  * This fills in iscsi::rx_bhs with the data from the BHS portion of
1610  * the received PDU.
1611  */
1612 static int iscsi_rx_bhs ( struct iscsi_session *iscsi, const void *data,
1613  size_t len, size_t remaining __unused ) {
1614  memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1615  if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1616  DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1617  iscsi, iscsi->rx_bhs.common.opcode,
1618  ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1619  }
1620  return 0;
1621 }
1622 
1623 /**
1624  * Discard portion of an iSCSI PDU.
1625  *
1626  * @v iscsi iSCSI session
1627  * @v data Received data
1628  * @v len Length of received data
1629  * @v remaining Data remaining after this data
1630  * @ret rc Return status code
1631  *
1632  * This discards data from a portion of a received PDU.
1633  */
1634 static int iscsi_rx_discard ( struct iscsi_session *iscsi __unused,
1635  const void *data __unused, size_t len __unused,
1636  size_t remaining __unused ) {
1637  /* Do nothing */
1638  return 0;
1639 }
1640 
1641 /**
1642  * Receive data segment of an iSCSI PDU
1643  *
1644  * @v iscsi iSCSI session
1645  * @v data Received data
1646  * @v len Length of received data
1647  * @v remaining Data remaining after this data
1648  * @ret rc Return status code
1649  *
1650  * Handle processing of part of a PDU data segment. iscsi::rx_bhs
1651  * will be valid when this is called.
1652  */
1653 static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data,
1654  size_t len, size_t remaining ) {
1655  struct iscsi_bhs_common_response *response
1656  = &iscsi->rx_bhs.common_response;
1657 
1658  /* Update cmdsn and statsn */
1659  iscsi->cmdsn = ntohl ( response->expcmdsn );
1660  iscsi->statsn = ntohl ( response->statsn );
1661 
1662  switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1664  return iscsi_rx_login_response ( iscsi, data, len, remaining );
1666  return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1667  case ISCSI_OPCODE_DATA_IN:
1668  return iscsi_rx_data_in ( iscsi, data, len, remaining );
1669  case ISCSI_OPCODE_R2T:
1670  return iscsi_rx_r2t ( iscsi, data, len, remaining );
1671  case ISCSI_OPCODE_NOP_IN:
1672  return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1673  default:
1674  if ( remaining )
1675  return 0;
1676  DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1677  response->opcode );
1678  return -ENOTSUP_OPCODE;
1679  }
1680 }
1681 
1682 /**
1683  * Receive new data
1684  *
1685  * @v iscsi iSCSI session
1686  * @v iobuf I/O buffer
1687  * @v meta Data transfer metadata
1688  * @ret rc Return status code
1689  *
1690  * This handles received PDUs. The receive strategy is to fill in
1691  * iscsi::rx_bhs with the contents of the BHS portion of the PDU,
1692  * throw away any AHS portion, and then process each part of the data
1693  * portion as it arrives. The data processing routine therefore
1694  * always has a full copy of the BHS available, even for portions of
1695  * the data in different packets to the BHS.
1696  */
1697 static int iscsi_socket_deliver ( struct iscsi_session *iscsi,
1698  struct io_buffer *iobuf,
1699  struct xfer_metadata *meta __unused ) {
1700  struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1701  int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1702  size_t len, size_t remaining );
1703  enum iscsi_rx_state next_state;
1704  size_t frag_len;
1705  size_t remaining;
1706  int rc;
1707 
1708  while ( 1 ) {
1709  switch ( iscsi->rx_state ) {
1710  case ISCSI_RX_BHS:
1711  rx = iscsi_rx_bhs;
1712  iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1713  next_state = ISCSI_RX_AHS;
1714  break;
1715  case ISCSI_RX_AHS:
1716  rx = iscsi_rx_discard;
1717  iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1718  next_state = ISCSI_RX_DATA;
1719  break;
1720  case ISCSI_RX_DATA:
1721  rx = iscsi_rx_data;
1722  iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1723  next_state = ISCSI_RX_DATA_PADDING;
1724  break;
1725  case ISCSI_RX_DATA_PADDING:
1726  rx = iscsi_rx_discard;
1727  iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1728  next_state = ISCSI_RX_BHS;
1729  break;
1730  default:
1731  assert ( 0 );
1732  rc = -EINVAL;
1733  goto done;
1734  }
1735 
1736  frag_len = iscsi->rx_len - iscsi->rx_offset;
1737  if ( frag_len > iob_len ( iobuf ) )
1738  frag_len = iob_len ( iobuf );
1739  remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1740  if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1741  remaining ) ) != 0 ) {
1742  DBGC ( iscsi, "iSCSI %p could not process received "
1743  "data: %s\n", iscsi, strerror ( rc ) );
1744  goto done;
1745  }
1746 
1747  iscsi->rx_offset += frag_len;
1748  iob_pull ( iobuf, frag_len );
1749 
1750  /* If all the data for this state has not yet been
1751  * received, stay in this state for now.
1752  */
1753  if ( iscsi->rx_offset != iscsi->rx_len ) {
1754  rc = 0;
1755  goto done;
1756  }
1757 
1758  iscsi->rx_state = next_state;
1759  iscsi->rx_offset = 0;
1760  }
1761 
1762  done:
1763  /* Free I/O buffer */
1764  free_iob ( iobuf );
1765 
1766  /* Destroy session on error */
1767  if ( rc != 0 )
1768  iscsi_close ( iscsi, rc );
1769 
1770  return rc;
1771 }
1772 
1773 /**
1774  * Handle redirection event
1775  *
1776  * @v iscsi iSCSI session
1777  * @v type Location type
1778  * @v args Remaining arguments depend upon location type
1779  * @ret rc Return status code
1780  */
1781 static int iscsi_vredirect ( struct iscsi_session *iscsi, int type,
1782  va_list args ) {
1783  va_list tmp;
1784  struct sockaddr *peer;
1785  int rc;
1786 
1787  /* Intercept redirects to a LOCATION_SOCKET and record the IP
1788  * address for the iBFT. This is a bit of a hack, but avoids
1789  * inventing an ioctl()-style call to retrieve the socket
1790  * address from a data-xfer interface.
1791  */
1792  if ( type == LOCATION_SOCKET ) {
1793  va_copy ( tmp, args );
1794  ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1795  peer = va_arg ( tmp, struct sockaddr * );
1796  memcpy ( &iscsi->target_sockaddr, peer,
1797  sizeof ( iscsi->target_sockaddr ) );
1798  va_end ( tmp );
1799  }
1800 
1801  /* Redirect to new location */
1802  if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1803  goto err;
1804 
1805  return 0;
1806 
1807  err:
1808  iscsi_close ( iscsi, rc );
1809  return rc;
1810 }
1811 
1812 /** iSCSI socket interface operations */
1816  iscsi_tx_resume ),
1819 };
1820 
1821 /** iSCSI socket interface descriptor */
1823  INTF_DESC ( struct iscsi_session, socket, iscsi_socket_operations );
1824 
1825 /****************************************************************************
1826  *
1827  * iSCSI command issuing
1828  *
1829  */
1830 
1831 /**
1832  * Check iSCSI flow-control window
1833  *
1834  * @v iscsi iSCSI session
1835  * @ret len Length of window
1836  */
1837 static size_t iscsi_scsi_window ( struct iscsi_session *iscsi ) {
1838 
1839  if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1841  ( iscsi->command == NULL ) ) {
1842  /* We cannot handle concurrent commands */
1843  return 1;
1844  } else {
1845  return 0;
1846  }
1847 }
1848 
1849 /**
1850  * Issue iSCSI SCSI command
1851  *
1852  * @v iscsi iSCSI session
1853  * @v parent Parent interface
1854  * @v command SCSI command
1855  * @ret tag Command tag, or negative error
1856  */
1857 static int iscsi_scsi_command ( struct iscsi_session *iscsi,
1858  struct interface *parent,
1859  struct scsi_cmd *command ) {
1860 
1861  /* This iSCSI implementation cannot handle multiple concurrent
1862  * commands or commands arriving before login is complete.
1863  */
1864  if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1865  DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1866  iscsi );
1867  return -EOPNOTSUPP;
1868  }
1869 
1870  /* Store command */
1871  iscsi->command = malloc ( sizeof ( *command ) );
1872  if ( ! iscsi->command )
1873  return -ENOMEM;
1874  memcpy ( iscsi->command, command, sizeof ( *command ) );
1875 
1876  /* Assign new ITT */
1877  iscsi_new_itt ( iscsi );
1878 
1879  /* Start sending command */
1880  iscsi_start_command ( iscsi );
1881 
1882  /* Attach to parent interface and return */
1883  intf_plug_plug ( &iscsi->data, parent );
1884  return iscsi->itt;
1885 }
1886 
1887 /**
1888  * Update SCSI block device capacity
1889  *
1890  * @v iscsi iSCSI session
1891  * @v capacity Block device capacity
1892  */
1893 static void iscsi_scsi_capacity ( struct iscsi_session *iscsi,
1894  struct block_device_capacity *capacity ) {
1895  unsigned int max_count;
1896 
1897  /* Limit maximum number of blocks per transfer to fit MaxBurstLength */
1898  if ( capacity->blksize ) {
1899  max_count = ( iscsi->max_burst_len / capacity->blksize );
1900  if ( max_count < capacity->max_count )
1901  capacity->max_count = max_count;
1902  }
1903 }
1904 
1905 /**
1906  * Get iSCSI ACPI descriptor
1907  *
1908  * @v iscsi iSCSI session
1909  * @ret desc ACPI descriptor
1910  */
1911 static struct acpi_descriptor * iscsi_describe ( struct iscsi_session *iscsi ) {
1912 
1913  return &iscsi->desc;
1914 }
1915 
1916 /** iSCSI SCSI command-issuing interface operations */
1924 };
1925 
1926 /** iSCSI SCSI command-issuing interface descriptor */
1929 
1930 /**
1931  * Close iSCSI command
1932  *
1933  * @v iscsi iSCSI session
1934  * @v rc Reason for close
1935  */
1936 static void iscsi_command_close ( struct iscsi_session *iscsi, int rc ) {
1937 
1938  /* Restart interface */
1939  intf_restart ( &iscsi->data, rc );
1940 
1941  /* Treat unsolicited command closures mid-command as fatal,
1942  * because we have no code to handle partially-completed PDUs.
1943  */
1944  if ( iscsi->command != NULL )
1945  iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1946 }
1947 
1948 /** iSCSI SCSI command interface operations */
1951 };
1952 
1953 /** iSCSI SCSI command interface descriptor */
1956 
1957 /****************************************************************************
1958  *
1959  * Instantiator
1960  *
1961  */
1962 
1963 /** iSCSI root path components (as per RFC4173) */
1971 };
1972 
1973 /** iSCSI initiator IQN setting */
1974 const struct setting initiator_iqn_setting __setting ( SETTING_SANBOOT_EXTRA,
1975  initiator-iqn ) = {
1976  .name = "initiator-iqn",
1977  .description = "iSCSI initiator name",
1978  .tag = DHCP_ISCSI_INITIATOR_IQN,
1979  .type = &setting_type_string,
1980 };
1981 
1982 /** iSCSI reverse username setting */
1983 const struct setting reverse_username_setting __setting ( SETTING_AUTH_EXTRA,
1984  reverse-username ) = {
1985  .name = "reverse-username",
1986  .description = "Reverse user name",
1987  .tag = DHCP_EB_REVERSE_USERNAME,
1988  .type = &setting_type_string,
1989 };
1990 
1991 /** iSCSI reverse password setting */
1992 const struct setting reverse_password_setting __setting ( SETTING_AUTH_EXTRA,
1993  reverse-password ) = {
1994  .name = "reverse-password",
1995  .description = "Reverse password",
1996  .tag = DHCP_EB_REVERSE_PASSWORD,
1997  .type = &setting_type_string,
1998 };
1999 
2000 /**
2001  * Parse iSCSI root path
2002  *
2003  * @v iscsi iSCSI session
2004  * @v root_path iSCSI root path (as per RFC4173)
2005  * @ret rc Return status code
2006  */
2007 static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
2008  const char *root_path ) {
2009  char *rp_copy;
2010  char *rp_comp[NUM_RP_COMPONENTS];
2011  char *rp;
2012  int skip = 0;
2013  int i = 0;
2014  int rc;
2015 
2016  /* Create modifiable copy of root path */
2017  rp_copy = strdup ( root_path );
2018  if ( ! rp_copy ) {
2019  rc = -ENOMEM;
2020  goto err_strdup;
2021  }
2022  rp = rp_copy;
2023 
2024  /* Split root path into component parts */
2025  while ( 1 ) {
2026  rp_comp[i++] = rp;
2027  if ( i == NUM_RP_COMPONENTS )
2028  break;
2029  for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
2030  if ( ! *rp ) {
2031  DBGC ( iscsi, "iSCSI %p root path \"%s\" "
2032  "too short\n", iscsi, root_path );
2034  goto err_split;
2035  } else if ( *rp == '[' ) {
2036  skip = 1;
2037  } else if ( *rp == ']' ) {
2038  skip = 0;
2039  }
2040  }
2041  *(rp++) = '\0';
2042  }
2043 
2044  /* Use root path components to configure iSCSI session */
2045  iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
2046  if ( ! iscsi->target_address ) {
2047  rc = -ENOMEM;
2048  goto err_servername;
2049  }
2050  iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
2051  if ( ! iscsi->target_port )
2052  iscsi->target_port = ISCSI_PORT;
2053  if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
2054  DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
2055  iscsi, rp_comp[RP_LUN] );
2056  goto err_lun;
2057  }
2058  iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2059  if ( ! iscsi->target_iqn ) {
2060  rc = -ENOMEM;
2061  goto err_targetname;
2062  }
2063 
2064  err_targetname:
2065  err_lun:
2066  err_servername:
2067  err_split:
2068  free ( rp_copy );
2069  err_strdup:
2070  return rc;
2071 }
2072 
2073 /**
2074  * Fetch iSCSI settings
2075  *
2076  * @v iscsi iSCSI session
2077  * @ret rc Return status code
2078  */
2079 static int iscsi_fetch_settings ( struct iscsi_session *iscsi ) {
2080  char *hostname;
2081  union uuid uuid;
2082  int len;
2083 
2084  /* Fetch relevant settings. Don't worry about freeing on
2085  * error, since iscsi_free() will take care of that anyway.
2086  */
2087  fetch_string_setting_copy ( NULL, &username_setting,
2088  &iscsi->initiator_username );
2089  fetch_string_setting_copy ( NULL, &password_setting,
2090  &iscsi->initiator_password );
2091  fetch_string_setting_copy ( NULL, &reverse_username_setting,
2092  &iscsi->target_username );
2093  fetch_string_setting_copy ( NULL, &reverse_password_setting,
2094  &iscsi->target_password );
2095 
2096  /* Use explicit initiator IQN if provided */
2097  fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2098  &iscsi->initiator_iqn );
2099  if ( iscsi->initiator_iqn )
2100  return 0;
2101 
2102  /* Otherwise, try to construct an initiator IQN from the hostname */
2103  fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2104  if ( hostname ) {
2105  len = asprintf ( &iscsi->initiator_iqn,
2106  ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2107  free ( hostname );
2108  if ( len < 0 ) {
2109  DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2110  "IQN\n", iscsi );
2111  return -ENOMEM;
2112  }
2113  assert ( iscsi->initiator_iqn );
2114  return 0;
2115  }
2116 
2117  /* Otherwise, try to construct an initiator IQN from the UUID */
2118  if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2119  DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2120  iscsi );
2121  return -EINVAL_NO_INITIATOR_IQN;
2122  }
2123  if ( ( len = asprintf ( &iscsi->initiator_iqn,
2125  uuid_ntoa ( &uuid ) ) ) < 0 ) {
2126  DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2127  iscsi );
2128  return -ENOMEM;
2129  }
2130  assert ( iscsi->initiator_iqn );
2131 
2132  return 0;
2133 }
2134 
2135 
2136 /**
2137  * Check iSCSI authentication details
2138  *
2139  * @v iscsi iSCSI session
2140  * @ret rc Return status code
2141  */
2142 static int iscsi_check_auth ( struct iscsi_session *iscsi ) {
2143 
2144  /* Check for invalid authentication combinations */
2145  if ( ( /* Initiator username without password (or vice-versa) */
2146  ( !! iscsi->initiator_username ) ^
2147  ( !! iscsi->initiator_password ) ) ||
2148  ( /* Target username without password (or vice-versa) */
2149  ( !! iscsi->target_username ) ^
2150  ( !! iscsi->target_password ) ) ||
2151  ( /* Target (reverse) without initiator (forward) */
2152  ( iscsi->target_username &&
2153  ( ! iscsi->initiator_username ) ) ) ) {
2154  DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2155  "%sname,%spw, target %sname,%spw\n", iscsi,
2156  ( iscsi->initiator_username ? "" : "no " ),
2157  ( iscsi->initiator_password ? "" : "no " ),
2158  ( iscsi->target_username ? "" : "no " ),
2159  ( iscsi->target_password ? "" : "no " ) );
2160  return -EINVAL_BAD_CREDENTIAL_MIX;
2161  }
2162 
2163  return 0;
2164 }
2165 
2166 /**
2167  * Open iSCSI URI
2168  *
2169  * @v parent Parent interface
2170  * @v uri URI
2171  * @ret rc Return status code
2172  */
2173 static int iscsi_open ( struct interface *parent, struct uri *uri ) {
2174  struct iscsi_session *iscsi;
2175  int rc;
2176 
2177  /* Sanity check */
2178  if ( ! uri->opaque ) {
2180  goto err_sanity_uri;
2181  }
2182 
2183  /* Allocate and initialise structure */
2184  iscsi = zalloc ( sizeof ( *iscsi ) );
2185  if ( ! iscsi ) {
2186  rc = -ENOMEM;
2187  goto err_zalloc;
2188  }
2189  ref_init ( &iscsi->refcnt, iscsi_free );
2190  intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2191  intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2192  intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2194  &iscsi->refcnt );
2195  acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2196 
2197  /* Parse root path */
2198  if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2199  goto err_parse_root_path;
2200  /* Set fields not specified by root path */
2201  if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2202  goto err_fetch_settings;
2203  /* Validate authentication */
2204  if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2205  goto err_check_auth;
2206 
2207  /* Sanity checks */
2208  if ( ! iscsi->target_address ) {
2209  DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2210  iscsi );
2211  rc = -ENOTSUP_DISCOVERY;
2212  goto err_sanity_address;
2213  }
2214  if ( ! iscsi->target_iqn ) {
2215  DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2216  iscsi, uri->opaque );
2218  goto err_sanity_iqn;
2219  }
2220  DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2221  DBGC ( iscsi, "iSCSI %p target %s %s\n",
2222  iscsi, iscsi->target_address, iscsi->target_iqn );
2223 
2224  /* Open socket */
2225  if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2226  goto err_open_connection;
2227 
2228  /* Attach SCSI device to parent interface */
2229  if ( ( rc = scsi_open ( parent, &iscsi->control,
2230  &iscsi->lun ) ) != 0 ) {
2231  DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2232  iscsi, strerror ( rc ) );
2233  goto err_scsi_open;
2234  }
2235 
2236  /* Mortalise self, and return */
2237  ref_put ( &iscsi->refcnt );
2238  return 0;
2239 
2240  err_scsi_open:
2241  err_open_connection:
2242  err_sanity_iqn:
2243  err_sanity_address:
2244  err_check_auth:
2245  err_fetch_settings:
2246  err_parse_root_path:
2247  iscsi_close ( iscsi, rc );
2248  ref_put ( &iscsi->refcnt );
2249  err_zalloc:
2250  err_sanity_uri:
2251  return rc;
2252 }
2253 
2254 /** iSCSI URI opener */
2255 struct uri_opener iscsi_uri_opener __uri_opener = {
2256  .scheme = "iscsi",
2257  .open = iscsi_open,
2258 };
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition: iscsi.h:708
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition: scsi.c:146
#define EINVAL_BAD_CREDENTIAL_MIX
Definition: iscsi.c:73
A process.
Definition: process.h:17
#define iob_pull(iobuf, len)
Definition: iobuf.h:106
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition: iscsi.h:291
An object interface operation.
Definition: interface.h:17
iscsi_tx_state
State of an iSCSI TX engine.
Definition: iscsi.h:520
#define ECONNRESET
Connection reset.
Definition: errno.h:363
iSCSI data-in basic header segment
Definition: iscsi.h:354
TCP/IP socket address.
Definition: tcpip.h:75
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
iSCSI NOP-In basic header segment
Definition: iscsi.h:476
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition: xfer.c:146
unsigned short uint16_t
Definition: stdint.h:11
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:249
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition: iscsi.h:681
struct iscsi_bhs_login_request login_request
Definition: iscsi.h:508
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition: interface.c:343
static int iscsi_rx_bhs(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining __unused)
Receive basic header segment of an iSCSI PDU.
Definition: iscsi.c:1612
#define iob_put(iobuf, len)
Definition: iobuf.h:124
#define va_end(ap)
Definition: stdarg.h:9
struct iscsi_bhs_scsi_command scsi_command
Definition: iscsi.h:510
Data transfer metadata.
Definition: xfer.h:22
size_t data_out_len
Data-out buffer length.
Definition: scsi.h:259
#define SETTING_SANBOOT_EXTRA
SAN boot additional settings.
Definition: settings.h:74
void * data_in
Data-in buffer (may be NULL)
Definition: scsi.h:261
#define DHCP_EB_FEATURE_ISCSI
iSCSI protocol
Definition: features.h:37
unsigned int max_count
Maximum number of blocks per single transfer.
Definition: blockdev.h:23
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition: xfer.c:255
#define ENOTSUP_DISCOVERY
Definition: iscsi.c:109
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition: iscsi.c:2079
uint32_t expcmdsn
Expected command sequence number.
Definition: iscsi.h:132
char * initiator_username
Initiator username (if any)
Definition: iscsi.h:572
uint8_t * response
CHAP response.
Definition: chap.h:24
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:484
uint8_t opcode
Opcode.
Definition: iscsi.h:116
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
Definition: iscsi.c:1505
An iSCSI session.
Definition: iscsi.h:544
struct iscsi_bhs_common common
Definition: iscsi.h:506
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
Definition: iscsi.h:661
uint32_t ttt
Target transfer tag.
Definition: iscsi.h:609
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition: iscsi.h:249
#define ISCSI_LOGIN_NSG_MASK
Definition: iscsi.h:188
#define FEATURE_PROTOCOL
Network protocols.
Definition: features.h:21
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:412
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition: refcnt.h:64
Error codes.
A universally unique ID.
Definition: uuid.h:15
Receiving the data segment.
Definition: iscsi.h:538
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition: iscsi.c:244
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition: iscsi.h:65
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition: iscsi.h:398
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition: iscsi.c:954
A command-line command.
Definition: command.h:9
#define DHCP_ISCSI_INITIATOR_IQN
iSCSI initiator IQN
Definition: dhcp.h:538
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:152
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:184
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition: blockdev.c:129
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition: iscsi.c:2007
#define ISCSI_DATA_FLAG_UNDERFLOW
Data underflow occurred.
Definition: iscsi.h:395
struct interface socket
Transport-layer socket.
Definition: iscsi.h:553
uint32_t type
Operating system type.
Definition: ena.h:12
#define EPROTO_INVALID_CHAP_ALGORITHM
Definition: iscsi.c:125
uint32_t offset
Buffer offset.
Definition: iscsi.h:380
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition: iscsi.c:1018
const struct setting initiator_iqn_setting __setting(SETTING_SANBOOT_EXTRA, initiator-iqn)
iSCSI initiator IQN setting
printf() and friends
#define EPROTO_INVALID_CHAP_RESPONSE
Definition: iscsi.c:137
iSCSI login request basic header segment
Definition: iscsi.h:141
size_t data_in_len
Data-in buffer length.
Definition: scsi.h:266
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
Definition: iscsi.h:392
struct iscsi_bhs_data_out data_out
Definition: iscsi.h:513
struct iscsi_bhs_common_response common_response
Definition: iscsi.h:507
#define DBGC(...)
Definition: compiler.h:505
A process descriptor.
Definition: process.h:31
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition: iscsi.h:252
uint8_t flags
Flags.
Definition: iscsi.h:308
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition: iscsi.c:527
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
Definition: chap.c:104
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
Definition: iscsi.h:336
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
Definition: iscsi.h:288
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition: iscsi.c:581
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition: xfer.c:62
static int iscsi_rx_scsi_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI SCSI response PDU.
Definition: iscsi.c:416
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition: interface.c:107
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition: iscsi.h:255
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition: iscsi.h:96
Definition: iscsi.c:1968
uint32_t string
Definition: multiboot.h:14
#define ntohl(value)
Definition: byteswap.h:134
#define ISCSI_TAG_RESERVED
iSCSI reserved tag value
Definition: iscsi.h:108
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition: xfer.c:158
FEATURE(FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1)
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition: ucode.h:26
static int iscsi_rx_data(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI PDU.
Definition: iscsi.c:1653
size_t rx_len
Length of the current RX state.
Definition: iscsi.h:653
static struct iscsi_string_type iscsi_string_types[]
iSCSI text strings that we want to handle
Definition: iscsi.c:1185
#define va_copy(dest, src)
Definition: stdarg.h:10
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition: base64.c:91
iscsi_rx_state
State of an iSCSI RX engine.
Definition: iscsi.h:532
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition: iscsi.h:254
uint8_t response
Response code.
Definition: iscsi.h:310
Character types.
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition: interface.c:326
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
Definition: iscsi.c:855
union scsi_cdb cdb
CDB for this command.
Definition: scsi.h:252
uint32_t statsn
Status sequence number.
Definition: iscsi.h:130
static int iscsi_rx_login_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI login response PDU.
Definition: iscsi.c:1319
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition: scsi.c:984
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Definition: iscsi.h:676
Uniform Resource Identifiers.
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition: iscsi.h:251
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
Definition: iscsi.h:386
#define ISCSI_STATUS_INITIATOR_ERROR
Definition: iscsi.h:248
void * rx_buffer
Buffer for received data (not always used)
Definition: iscsi.h:655
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition: string.c:186
void process_del(struct process *process)
Remove process from process list.
Definition: process.c:79
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition: iscsi.h:173
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition: iscsi.c:770
#define EINVAL_NO_TARGET_IQN
Definition: iscsi.c:81
#define htonl(value)
Definition: byteswap.h:133
struct iscsi_bhs_r2t r2t
Definition: iscsi.h:514
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition: xfer.c:116
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition: iscsi.h:61
uint8_t status
SCSI status code.
Definition: iscsi.h:312
iSCSI SCSI command basic header segment
Definition: iscsi.h:261
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
Definition: iscsi.h:669
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition: iscsi.c:1073
#define ECANCELED
Operation canceled.
Definition: errno.h:343
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition: xfer.c:288
static int iscsi_rx_r2t(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI R2T PDU.
Definition: iscsi.c:506
uint32_t statsn
Status sequence number.
Definition: iscsi.h:637
Data transfer interfaces.
A reference counter.
Definition: refcnt.h:26
unsigned int target_port
Target port.
Definition: iscsi.h:560
struct scsi_lun lun
Logical Unit Number.
Definition: iscsi.h:414
char * initiator_password
Initiator password (if any)
Definition: iscsi.h:574
const char * name
Name.
Definition: settings.h:28
#define EACCES_INCORRECT_TARGET_USERNAME
Definition: iscsi.c:61
uint8_t status_detail
Status detail.
Definition: iscsi.h:237
iscsi_root_path_component
iSCSI root path components (as per RFC4173)
Definition: iscsi.c:1964
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition: base16.h:24
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition: vsprintf.c:420
unsigned long tmp
Definition: linux_pci.h:64
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition: iscsi.c:1781
static struct interface_operation iscsi_socket_operations[]
iSCSI socket interface operations
Definition: iscsi.c:1813
Location is a socket.
Definition: open.h:43
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition: iscsi.h:176
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
Definition: iscsi.c:829
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition: iscsi.h:684
#define ENOMEM
Not enough space.
Definition: errno.h:534
size_t rx_offset
Byte offset within the current RX state.
Definition: iscsi.h:651
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
Definition: iscsi.h:516
void * memcpy(void *dest, const void *src, size_t len) __nonnull
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition: iscsi.c:1458
#define va_arg(ap, type)
Definition: stdarg.h:8
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition: iscsi.c:1468
Nothing to send.
Definition: iscsi.h:522
struct interface control
SCSI command-issuing interface.
Definition: iscsi.h:549
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
Definition: iscsi.c:1482
An iSCSI text string that we want to handle.
Definition: iscsi.c:1168
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
Definition: iscsi.h:201
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition: iscsi.c:1417
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
A SCSI command.
Definition: scsi.c:262
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
Definition: iscsi.h:29
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition: iscsi.h:250
An object interface.
Definition: interface.h:124
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition: scsi.c:117
uint32_t itt
Initiator task tag.
Definition: iscsi.h:603
uint32_t datasn
Data sequence number.
Definition: iscsi.h:426
A SCSI response information unit.
Definition: scsi.h:321
static int iscsi_open(struct interface *parent, struct uri *uri)
Open iSCSI URI.
Definition: iscsi.c:2173
Receiving the data segment padding.
Definition: iscsi.h:540
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
uint8_t status_class
Status class.
Definition: iscsi.h:235
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition: iscsi.c:565
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition: iscsi.c:1936
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition: chap.c:51
int status
Session status.
Definition: iscsi.h:569
ring len
Length.
Definition: dwmac.h:231
iSCSI protocol
static int tolower(int character)
Convert character to lower case.
Definition: ctype.h:108
const char * scheme
URI protocol name.
Definition: open.h:53
Transport-network layer interface.
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition: iscsi.h:102
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
Definition: iscsi.c:306
Feature list.
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:418
struct acpi_descriptor desc
ACPI descriptor.
Definition: iscsi.h:665
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition: iscsi.c:223
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition: iscsi.c:65
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition: iscsi.h:640
struct scsi_lun lun
LUN.
Definition: scsi.h:250
#define ISCSI_FIRST_BURST_LEN
Default iSCSI first burst length.
Definition: iscsi.h:26
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition: settings.c:873
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
Definition: iscsi.h:500
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
Definition: iscsi.h:183
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition: iscsi.c:1893
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition: iscsi.c:908
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition: iscsi.c:1927
iSCSI basic header segment common request fields
Definition: iscsi.h:114
#define EPROTO
Protocol error.
Definition: errno.h:624
#define EPROTO_INVALID_KEY_VALUE_PAIR
Definition: iscsi.c:141
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition: iscsi.h:690
void process_add(struct process *process)
Add process to process list.
Definition: process.c:59
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition: iscsi.c:1102
Configuration settings.
#define EFI_INTF_OP
Definition: efi.h:373
uint16_t st_port
TCP/IP port.
Definition: tcpip.h:81
Generalized socket address structure.
Definition: socket.h:96
uint64_t rsp
Definition: librm.h:153
Receiving the additional header segment.
Definition: iscsi.h:536
An object interface descriptor.
Definition: interface.h:55
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition: iscsi.c:178
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition: iscsi.c:1597
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition: iscsi.c:160
#define ISCSI_PORT
Default iSCSI port.
Definition: iscsi.h:23
uint32_t offset
Buffer offset.
Definition: iscsi.h:464
iSCSI basic header segment common fields
Definition: iscsi.h:78
Block devices.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition: chap.c:122
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition: iscsi.h:663
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:661
struct process process
TX process.
Definition: iscsi.h:644
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition: iscsi.c:1204
#define EINVAL_NO_INITIATOR_IQN
Definition: iscsi.c:85
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:314
enum iscsi_rx_state rx_state
State of the RX engine.
Definition: iscsi.h:649
char * strchr(const char *src, int character)
Find character within a string.
Definition: string.c:271
uint32_t offset
Buffer offset.
Definition: iscsi.h:428
uint8_t flags
Flags.
Definition: iscsi.h:408
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:159
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:32
char * strdup(const char *src)
Duplicate string.
Definition: string.c:393
uint32_t control
Control.
Definition: myson.h:14
iSCSI request to transfer basic header segment
Definition: iscsi.h:440
char * target_address
Target address.
Definition: iscsi.h:558
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition: iscsi.h:702
iSCSI login response basic header segment
Definition: iscsi.h:207
#define EOPNOTSUPP
Operation not supported on socket.
Definition: errno.h:604
#define ISCSI_OPCODE_R2T
R2T opcode.
Definition: iscsi.h:470
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
Definition: iscsi.h:57
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition: random.c:31
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition: iscsi.h:587
#define ISCSI_LOGIN_CSG_MASK
Definition: iscsi.h:182
static int iscsi_socket_deliver(struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
Definition: iscsi.c:1697
#define ENODEV
No such device.
Definition: errno.h:509
#define SOCK_STREAM
Definition: socket.h:24
#define EIO_TARGET_UNAVAILABLE
Definition: iscsi.c:93
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:194
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
#define EINVAL_ROOT_PATH_TOO_SHORT
Definition: iscsi.c:69
Processes.
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition: iscsi.c:338
unsigned char uint8_t
Definition: stdint.h:10
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition: iscsi.h:696
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition: scsi.h:222
Data transfer interface opening.
EFI device paths.
uint8_t flags
Flags.
Definition: iscsi.h:211
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition: iscsi.c:2142
size_t response_len
Length of CHAP response.
Definition: chap.h:26
uint8_t flags
Flags.
Definition: iscsi.h:358
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition: string.c:255
int(* handle)(struct iscsi_session *iscsi, const char *value)
Handle iSCSI string value.
Definition: iscsi.c:1181
Sending the additional header segment.
Definition: iscsi.h:526
static int iscsi_rx_nop_in(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI NOP-In.
Definition: iscsi.c:616
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition: process.h:145
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
Definition: iscsi.c:1911
struct interface data
SCSI command interface.
Definition: iscsi.h:551
unsigned int uint32_t
Definition: stdint.h:12
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition: acpi.c:320
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
#define DHCP_EB_REVERSE_PASSWORD
Reverse password.
Definition: dhcp.h:514
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition: iscsi.h:597
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:45
struct ib_cm_common common
Definition: ib_mad.h:11
static struct dynamic_item password
Definition: login_ui.c:36
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition: iscsi.h:693
uint32_t len
Desired data transfer length.
Definition: iscsi.h:466
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition: efi_path.c:505
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition: iscsi.h:585
size_t max_burst_len
Maximum burst length.
Definition: iscsi.h:590
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition: open.c:224
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition: iscsi.c:200
A setting.
Definition: settings.h:23
union iscsi_segment_lengths lengths
Segment lengths.
Definition: iscsi.h:86
static int iscsi_status_to_rc(unsigned int status_class, unsigned int status_detail)
Convert iSCSI response status to return status code.
Definition: iscsi.c:1281
const char * key
String key.
Definition: iscsi.c:1174
Base64 encoding.
uint32_t transfer_offset
Transfer offset.
Definition: iscsi.h:615
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition: scsi.c:206
#define ISCSI_COMMAND_ATTR_SIMPLE
Definition: iscsi.h:295
#define ISCSI_STATUS_REDIRECT
Definition: iscsi.h:247
long pad_len
Definition: bigint.h:30
SCSI devices.
A SCSI command information unit.
Definition: scsi.h:248
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:80
An ACPI descriptor (used to construct ACPI tables)
Definition: acpi.h:294
uint8_t opcode
Opcode.
Definition: iscsi.h:80
iSCSI data-out basic header segment
Definition: iscsi.h:404
char * target_iqn
Target IQN.
Definition: iscsi.h:562
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
Definition: iscsi.h:190
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
Definition: iscsi.h:99
uint32_t expstatsn
Expected status sequence number.
Definition: iscsi.h:422
uint32_t transfer_len
Transfer length.
Definition: iscsi.h:621
iSCSI boot firmware table
struct iscsi_nop_in nop_in
Definition: iscsi.h:515
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:919
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition: chap.h:46
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition: scsi.h:218
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition: iscsi.h:711
struct iscsi_bhs_login_response login_response
Definition: iscsi.h:509
Block device capacity.
Definition: blockdev.h:17
#define ISCSI_MAX_RECV_DATA_SEG_LEN
Default iSCSI maximum receive data segment length.
Definition: iscsi.h:32
const char * opaque
Opaque part.
Definition: uri.h:70
#define DBGC2(...)
Definition: compiler.h:522
struct uri_opener iscsi_uri_opener __uri_opener
iSCSI URI opener
Definition: iscsi.c:2255
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition: iscsi.h:687
static int iscsi_rx_discard(struct iscsi_session *iscsi __unused, const void *data __unused, size_t len __unused, size_t remaining __unused)
Discard portion of an iSCSI PDU.
Definition: iscsi.c:1634
__builtin_va_list va_list
Definition: stdarg.h:6
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
static int iscsi_rx_data_in(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI data-in PDU.
Definition: iscsi.c:469
uint32_t cmdsn
Command sequence number.
Definition: iscsi.h:629
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
Definition: iscsi.c:812
uint32_t itt
Initiator Task Tag.
Definition: iscsi.h:416
void * data
Start of data.
Definition: iobuf.h:52
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition: process.h:82
#define ISCSI_TAG_MAGIC
iSCSI tag magic marker
Definition: iscsi.h:105
#define EIO
Input/output error.
Definition: errno.h:433
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition: wpa.h:234
u8 request[0]
List of IEs requested.
Definition: ieee80211.h:16
static void iscsi_tx_step(struct iscsi_session *iscsi)
Transmit iSCSI PDU.
Definition: iscsi.c:1533
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:454
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition: iscsi.c:878
#define ENOTSUP_INITIATOR_STATUS
Definition: iscsi.c:101
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
Definition: iscsi.h:243
#define DHCP_EB_REVERSE_USERNAME
Reverse username.
Definition: dhcp.h:505
uint32_t end
Ending offset.
Definition: netvsc.h:18
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition: iscsi.c:256
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define ENOTSUP_TARGET_STATUS
Definition: iscsi.c:113
uint32_t residual_count
Residual count.
Definition: iscsi.h:332
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition: iscsi.h:69
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition: iscsi.c:977
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition: iscsi.h:434
static struct dynamic_item username
Definition: login_ui.c:35
#define EPERM_INITIATOR_AUTHORISATION
Definition: iscsi.c:121
iSCSI SCSI response basic header segment
Definition: iscsi.h:304
#define EIO_TARGET_NO_RESOURCES
Definition: iscsi.c:97
__be32 raw[7]
Definition: CIB_PRM.h:28
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition: iscsi.c:1822
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition: iscsi.h:647
A Uniform Resource Identifier.
Definition: uri.h:64
uint8_t opcode
Opcode.
Definition: iscsi.h:406
#define EPROTO_INVALID_CHAP_IDENTIFIER
Definition: iscsi.c:129
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
Definition: iscsi.h:339
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition: settings.c:1084
char * initiator_iqn
Initiator IQN.
Definition: iscsi.h:556
Sending the data segment.
Definition: iscsi.h:528
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
Definition: iscsi.h:714
struct mschapv2_challenge peer
Peer challenge.
Definition: mschapv2.h:12
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition: iscsi.c:929
static struct interface_operation iscsi_control_op[]
iSCSI SCSI command-issuing interface operations
Definition: iscsi.c:1917
struct iscsi_bhs_scsi_response scsi_response
Definition: iscsi.h:511
#define SETTING_AUTH_EXTRA
Authentication additional settings.
Definition: settings.h:78
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition: iscsi.h:699
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition: iscsi.c:1426
#define ISCSI_ISID_IANA
ISID IANA format marker.
Definition: iscsi.h:194
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
Definition: iscsi.h:285
uint16_t offset
Offset to command line.
Definition: bzimage.h:8
uint8_t meta
Metadata flags.
Definition: ena.h:14
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition: iscsi.c:1254
char * target_password
Target password (if any)
Definition: iscsi.h:578
#define EPERM_INITIATOR_AUTHENTICATION
Definition: iscsi.c:117
#define EINVAL_MAXBURSTLENGTH
Definition: iscsi.c:89
struct scsi_cmd * command
Current SCSI command, if any.
Definition: iscsi.h:658
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:203
Socket addresses.
A URI opener.
Definition: open.h:47
char * target_username
Target username (if any)
Definition: iscsi.h:576
Sending the basic header segment.
Definition: iscsi.h:524
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Definition: iscsi.c:1949
Receiving the basic header segment.
Definition: iscsi.h:534
uint32_t ttt
Target Transfer Tag.
Definition: iscsi.h:488
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:114
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition: iscsi.h:705
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition: chap.c:85
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition: iscsi.c:691
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition: iscsi.c:376
struct iscsi_bhs_data_in data_in
Definition: iscsi.h:512
String functions.
#define htons(value)
Definition: byteswap.h:135
struct bofm_section_header done
Definition: bofm_test.c:46
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition: iscsi.c:1438
void * data_out
Data-out buffer (may be NULL)
Definition: scsi.h:254
enum iscsi_tx_state tx_state
State of the TX engine.
Definition: iscsi.h:642
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition: resolv.c:402
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition: md5.c:286
#define ref_put(refcnt)
Drop reference to object.
Definition: refcnt.h:106
size_t blksize
Block size.
Definition: blockdev.h:21
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition: acpi.h:311
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition: wpa.h:237
#define EINVAL_NO_ROOT_PATH
Definition: iscsi.c:77
#define ENOTSUP_OPCODE
Definition: iscsi.c:105
struct refcnt refcnt
Reference counter.
Definition: iscsi.h:546
void * memset(void *dest, int character, size_t len) __nonnull
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
Definition: iscsi.h:191
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition: iscsi.c:1954
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition: iscsi.c:1837
#define ISCSI_STATUS_TARGET_ERROR
Definition: iscsi.h:253
Base16 encoding.
A persistent I/O buffer.
Definition: iobuf.h:37
#define EPROTO_INVALID_LARGE_BINARY
Definition: iscsi.c:133
#define EPROTO_VALUE_REJECTED
Definition: iscsi.c:145
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition: iscsi.c:1857