[iscsi] Allow base64 encoding in large binary values
[people/meteger/gpxe.git] / src / net / tcp / iscsi.c
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., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18
19 FILE_LICENCE ( GPL2_OR_LATER );
20
21 #include <stddef.h>
22 #include <string.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <errno.h>
26 #include <assert.h>
27 #include <byteswap.h>
28 #include <gpxe/vsprintf.h>
29 #include <gpxe/socket.h>
30 #include <gpxe/xfer.h>
31 #include <gpxe/open.h>
32 #include <gpxe/scsi.h>
33 #include <gpxe/process.h>
34 #include <gpxe/uaccess.h>
35 #include <gpxe/tcpip.h>
36 #include <gpxe/settings.h>
37 #include <gpxe/features.h>
38 #include <gpxe/base16.h>
39 #include <gpxe/base64.h>
40 #include <gpxe/iscsi.h>
41
42 /** @file
43  *
44  * iSCSI protocol
45  *
46  */
47
48 FEATURE ( FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1 );
49
50 /* Disambiguate the various error causes */
51 #define EACCES_INCORRECT_TARGET_USERNAME ( EACCES | EUNIQ_01 )
52 #define EACCES_INCORRECT_TARGET_PASSWORD ( EACCES | EUNIQ_02 )
53 #define ENOTSUP_INITIATOR_STATUS ( ENOTSUP | EUNIQ_01 )
54 #define ENOTSUP_OPCODE ( ENOTSUP | EUNIQ_02 )
55 #define ENOTSUP_DISCOVERY ( ENOTSUP | EUNIQ_03 )
56 #define EPERM_INITIATOR_AUTHENTICATION ( EPERM | EUNIQ_01 )
57 #define EPERM_INITIATOR_AUTHORISATION ( EPERM | EUNIQ_02 )
58 #define EPROTO_INVALID_CHAP_ALGORITHM ( EPROTO | EUNIQ_01 )
59 #define EPROTO_INVALID_CHAP_IDENTIFIER ( EPROTO | EUNIQ_02 )
60 #define EPROTO_INVALID_LARGE_BINARY ( EPROTO | EUNIQ_03 )
61 #define EPROTO_INVALID_CHAP_RESPONSE ( EPROTO | EUNIQ_04 )
62
63 /** iSCSI initiator name (explicitly specified) */
64 static char *iscsi_explicit_initiator_iqn;
65
66 /** Default iSCSI initiator name (constructed from hostname) */
67 static char *iscsi_default_initiator_iqn;
68
69 /** iSCSI initiator username */
70 static char *iscsi_initiator_username;
71
72 /** iSCSI initiator password */
73 static char *iscsi_initiator_password;
74
75 /** iSCSI target username */
76 static char *iscsi_target_username;
77
78 /** iSCSI target password */
79 static char *iscsi_target_password;
80
81 static void iscsi_start_tx ( struct iscsi_session *iscsi );
82 static void iscsi_start_login ( struct iscsi_session *iscsi );
83 static void iscsi_start_data_out ( struct iscsi_session *iscsi,
84                                    unsigned int datasn );
85
86 /**
87  * Finish receiving PDU data into buffer
88  *
89  * @v iscsi             iSCSI session
90  */
91 static void iscsi_rx_buffered_data_done ( struct iscsi_session *iscsi ) {
92         free ( iscsi->rx_buffer );
93         iscsi->rx_buffer = NULL;
94 }
95
96 /**
97  * Free iSCSI session
98  *
99  * @v refcnt            Reference counter
100  */
101 static void iscsi_free ( struct refcnt *refcnt ) {
102         struct iscsi_session *iscsi =
103                 container_of ( refcnt, struct iscsi_session, refcnt );
104
105         free ( iscsi->target_address );
106         free ( iscsi->target_iqn );
107         free ( iscsi->initiator_username );
108         free ( iscsi->initiator_password );
109         free ( iscsi->target_username );
110         free ( iscsi->target_password );
111         chap_finish ( &iscsi->chap );
112         iscsi_rx_buffered_data_done ( iscsi );
113         free ( iscsi );
114 }
115
116 /**
117  * Open iSCSI transport-layer connection
118  *
119  * @v iscsi             iSCSI session
120  * @ret rc              Return status code
121  */
122 static int iscsi_open_connection ( struct iscsi_session *iscsi ) {
123         struct sockaddr_tcpip target;
124         int rc;
125
126         assert ( iscsi->tx_state == ISCSI_TX_IDLE );
127         assert ( iscsi->rx_state == ISCSI_RX_BHS );
128         assert ( iscsi->rx_offset == 0 );
129
130         /* Open socket */
131         memset ( &target, 0, sizeof ( target ) );
132         target.st_port = htons ( iscsi->target_port );
133         if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
134                                              ( struct sockaddr * ) &target,
135                                              iscsi->target_address,
136                                              NULL ) ) != 0 ) {
137                 DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
138                        iscsi, strerror ( rc ) );
139                 return rc;
140         }
141
142         /* Enter security negotiation phase */
143         iscsi->status = ( ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE |
144                           ISCSI_STATUS_STRINGS_SECURITY );
145         if ( iscsi->target_username )
146                 iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_REQUIRED;
147
148         /* Assign fresh initiator task tag */
149         iscsi->itt++;
150
151         /* Initiate login */
152         iscsi_start_login ( iscsi );
153
154         return 0;
155 }
156
157 /**
158  * Close iSCSI transport-layer connection
159  *
160  * @v iscsi             iSCSI session
161  * @v rc                Reason for close
162  *
163  * Closes the transport-layer connection and resets the session state
164  * ready to attempt a fresh login.
165  */
166 static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) {
167
168         /* Close all data transfer interfaces */
169         xfer_close ( &iscsi->socket, rc );
170
171         /* Clear connection status */
172         iscsi->status = 0;
173
174         /* Reset TX and RX state machines */
175         iscsi->tx_state = ISCSI_TX_IDLE;
176         iscsi->rx_state = ISCSI_RX_BHS;
177         iscsi->rx_offset = 0;
178
179         /* Free any temporary dynamically allocated memory */
180         chap_finish ( &iscsi->chap );
181         iscsi_rx_buffered_data_done ( iscsi );
182 }
183
184 /**
185  * Mark iSCSI SCSI operation as complete
186  *
187  * @v iscsi             iSCSI session
188  * @v rc                Return status code
189  *
190  * Note that iscsi_scsi_done() will not close the connection, and must
191  * therefore be called only when the internal state machines are in an
192  * appropriate state, otherwise bad things may happen on the next call
193  * to iscsi_issue().  The general rule is to call iscsi_scsi_done()
194  * only at the end of receiving a PDU; at this point the TX and RX
195  * engines should both be idle.
196  */
197 static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc ) {
198
199         assert ( iscsi->tx_state == ISCSI_TX_IDLE );
200         assert ( iscsi->command != NULL );
201
202         iscsi->command->rc = rc;
203         iscsi->command = NULL;
204 }
205
206 /****************************************************************************
207  *
208  * iSCSI SCSI command issuing
209  *
210  */
211
212 /**
213  * Build iSCSI SCSI command BHS
214  *
215  * @v iscsi             iSCSI session
216  *
217  * We don't currently support bidirectional commands (i.e. with both
218  * Data-In and Data-Out segments); these would require providing code
219  * to generate an AHS, and there doesn't seem to be any need for it at
220  * the moment.
221  */
222 static void iscsi_start_command ( struct iscsi_session *iscsi ) {
223         struct iscsi_bhs_scsi_command *command = &iscsi->tx_bhs.scsi_command;
224
225         assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
226
227         /* Construct BHS and initiate transmission */
228         iscsi_start_tx ( iscsi );
229         command->opcode = ISCSI_OPCODE_SCSI_COMMAND;
230         command->flags = ( ISCSI_FLAG_FINAL |
231                            ISCSI_COMMAND_ATTR_SIMPLE );
232         if ( iscsi->command->data_in )
233                 command->flags |= ISCSI_COMMAND_FLAG_READ;
234         if ( iscsi->command->data_out )
235                 command->flags |= ISCSI_COMMAND_FLAG_WRITE;
236         /* lengths left as zero */
237         command->lun = iscsi->lun;
238         command->itt = htonl ( ++iscsi->itt );
239         command->exp_len = htonl ( iscsi->command->data_in_len |
240                                    iscsi->command->data_out_len );
241         command->cmdsn = htonl ( iscsi->cmdsn );
242         command->expstatsn = htonl ( iscsi->statsn + 1 );
243         memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
244         DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
245                 iscsi, SCSI_CDB_DATA ( command->cdb ),
246                 ( iscsi->command->data_in ? "in" : "out" ),
247                 ( iscsi->command->data_in ?
248                   iscsi->command->data_in_len :
249                   iscsi->command->data_out_len ) );
250 }
251
252 /**
253  * Receive data segment of an iSCSI SCSI response PDU
254  *
255  * @v iscsi             iSCSI session
256  * @v data              Received data
257  * @v len               Length of received data
258  * @v remaining         Data remaining after this data
259  * @ret rc              Return status code
260  */
261 static int iscsi_rx_scsi_response ( struct iscsi_session *iscsi,
262                                     const void *data, size_t len,
263                                     size_t remaining ) {
264         struct iscsi_bhs_scsi_response *response
265                 = &iscsi->rx_bhs.scsi_response;
266         int sense_offset;
267
268         /* Capture the sense response code as it floats past, if present */
269         sense_offset = ISCSI_SENSE_RESPONSE_CODE_OFFSET - iscsi->rx_offset;
270         if ( ( sense_offset >= 0 ) && len ) {
271                 iscsi->command->sense_response =
272                         * ( ( char * ) data + sense_offset );
273         }
274
275         /* Wait for whole SCSI response to arrive */
276         if ( remaining )
277                 return 0;
278         
279         /* Record SCSI status code */
280         iscsi->command->status = response->status;
281
282         /* Check for errors */
283         if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
284                 return -EIO;
285
286         /* Mark as completed */
287         iscsi_scsi_done ( iscsi, 0 );
288         return 0;
289 }
290
291 /**
292  * Receive data segment of an iSCSI data-in PDU
293  *
294  * @v iscsi             iSCSI session
295  * @v data              Received data
296  * @v len               Length of received data
297  * @v remaining         Data remaining after this data
298  * @ret rc              Return status code
299  */
300 static int iscsi_rx_data_in ( struct iscsi_session *iscsi,
301                               const void *data, size_t len,
302                               size_t remaining ) {
303         struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
304         unsigned long offset;
305
306         /* Copy data to data-in buffer */
307         offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
308         assert ( iscsi->command != NULL );
309         assert ( iscsi->command->data_in );
310         assert ( ( offset + len ) <= iscsi->command->data_in_len );
311         copy_to_user ( iscsi->command->data_in, offset, data, len );
312
313         /* Wait for whole SCSI response to arrive */
314         if ( remaining )
315                 return 0;
316
317         /* Mark as completed if status is present */
318         if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
319                 assert ( ( offset + len ) == iscsi->command->data_in_len );
320                 assert ( data_in->flags & ISCSI_FLAG_FINAL );
321                 iscsi->command->status = data_in->status;
322                 /* iSCSI cannot return an error status via a data-in */
323                 iscsi_scsi_done ( iscsi, 0 );
324         }
325
326         return 0;
327 }
328
329 /**
330  * Receive data segment of an iSCSI R2T PDU
331  *
332  * @v iscsi             iSCSI session
333  * @v data              Received data
334  * @v len               Length of received data
335  * @v remaining         Data remaining after this data
336  * @ret rc              Return status code
337  */
338 static int iscsi_rx_r2t ( struct iscsi_session *iscsi,
339                           const void *data __unused, size_t len __unused,
340                           size_t remaining __unused ) {
341         struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
342
343         /* Record transfer parameters and trigger first data-out */
344         iscsi->ttt = ntohl ( r2t->ttt );
345         iscsi->transfer_offset = ntohl ( r2t->offset );
346         iscsi->transfer_len = ntohl ( r2t->len );
347         iscsi_start_data_out ( iscsi, 0 );
348
349         return 0;
350 }
351
352 /**
353  * Build iSCSI data-out BHS
354  *
355  * @v iscsi             iSCSI session
356  * @v datasn            Data sequence number within the transfer
357  *
358  */
359 static void iscsi_start_data_out ( struct iscsi_session *iscsi,
360                                    unsigned int datasn ) {
361         struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
362         unsigned long offset;
363         unsigned long remaining;
364         unsigned long len;
365
366         /* We always send 512-byte Data-Out PDUs; this removes the
367          * need to worry about the target's MaxRecvDataSegmentLength.
368          */
369         offset = datasn * 512;
370         remaining = iscsi->transfer_len - offset;
371         len = remaining;
372         if ( len > 512 )
373                 len = 512;
374
375         /* Construct BHS and initiate transmission */
376         iscsi_start_tx ( iscsi );
377         data_out->opcode = ISCSI_OPCODE_DATA_OUT;
378         if ( len == remaining )
379                 data_out->flags = ( ISCSI_FLAG_FINAL );
380         ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
381         data_out->lun = iscsi->lun;
382         data_out->itt = htonl ( iscsi->itt );
383         data_out->ttt = htonl ( iscsi->ttt );
384         data_out->expstatsn = htonl ( iscsi->statsn + 1 );
385         data_out->datasn = htonl ( datasn );
386         data_out->offset = htonl ( iscsi->transfer_offset + offset );
387         DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
388                iscsi, datasn, len );
389 }
390
391 /**
392  * Complete iSCSI data-out PDU transmission
393  *
394  * @v iscsi             iSCSI session
395  *
396  */
397 static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
398         struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
399
400         /* If we haven't reached the end of the sequence, start
401          * sending the next data-out PDU.
402          */
403         if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
404                 iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
405 }
406
407 /**
408  * Send iSCSI data-out data segment
409  *
410  * @v iscsi             iSCSI session
411  * @ret rc              Return status code
412  */
413 static int iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
414         struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
415         struct io_buffer *iobuf;
416         unsigned long offset;
417         size_t len;
418
419         offset = ntohl ( data_out->offset );
420         len = ISCSI_DATA_LEN ( data_out->lengths );
421
422         assert ( iscsi->command != NULL );
423         assert ( iscsi->command->data_out );
424         assert ( ( offset + len ) <= iscsi->command->data_out_len );
425
426         iobuf = xfer_alloc_iob ( &iscsi->socket, len );
427         if ( ! iobuf )
428                 return -ENOMEM;
429         
430         copy_from_user ( iob_put ( iobuf, len ),
431                          iscsi->command->data_out, offset, len );
432
433         return xfer_deliver_iob ( &iscsi->socket, iobuf );
434 }
435
436 /****************************************************************************
437  *
438  * iSCSI login
439  *
440  */
441
442 /**
443  * Build iSCSI login request strings
444  *
445  * @v iscsi             iSCSI session
446  *
447  * These are the initial set of strings sent in the first login
448  * request PDU.  We want the following settings:
449  *
450  *     HeaderDigest=None
451  *     DataDigest=None
452  *     MaxConnections is irrelevant; we make only one connection anyway [4]
453  *     InitialR2T=Yes [1]
454  *     ImmediateData is irrelevant; we never send immediate data [4]
455  *     MaxRecvDataSegmentLength=8192 (default; we don't care) [3]
456  *     MaxBurstLength=262144 (default; we don't care) [3]
457  *     FirstBurstLength=262144 (default; we don't care)
458  *     DefaultTime2Wait=0 [2]
459  *     DefaultTime2Retain=0 [2]
460  *     MaxOutstandingR2T=1
461  *     DataPDUInOrder=Yes
462  *     DataSequenceInOrder=Yes
463  *     ErrorRecoveryLevel=0
464  *
465  * [1] InitialR2T has an OR resolution function, so the target may
466  * force us to use it.  We therefore simplify our logic by always
467  * using it.
468  *
469  * [2] These ensure that we can safely start a new task once we have
470  * reconnected after a failure, without having to manually tidy up
471  * after the old one.
472  *
473  * [3] We are quite happy to use the RFC-defined default values for
474  * these parameters, but some targets (notably OpenSolaris)
475  * incorrectly assume a default value of zero, so we explicitly
476  * specify the default values.
477  *
478  * [4] We are quite happy to use the RFC-defined default values for
479  * these parameters, but some targets (notably a QNAP TS-639Pro) fail
480  * unless they are supplied, so we explicitly specify the default
481  * values.
482  */
483 static int iscsi_build_login_request_strings ( struct iscsi_session *iscsi,
484                                                void *data, size_t len ) {
485         unsigned int used = 0;
486         const char *auth_method;
487
488         if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
489                 /* Default to allowing no authentication */
490                 auth_method = "None";
491                 /* If we have a credential to supply, permit CHAP */
492                 if ( iscsi->initiator_username )
493                         auth_method = "CHAP,None";
494                 /* If we have a credential to check, force CHAP */
495                 if ( iscsi->target_username )
496                         auth_method = "CHAP";
497                 used += ssnprintf ( data + used, len - used,
498                                     "InitiatorName=%s%c"
499                                     "TargetName=%s%c"
500                                     "SessionType=Normal%c"
501                                     "AuthMethod=%s%c",
502                                     iscsi_initiator_iqn(), 0,
503                                     iscsi->target_iqn, 0, 0,
504                                     auth_method, 0 );
505         }
506
507         if ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_ALGORITHM ) {
508                 used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
509         }
510         
511         if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
512                 char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
513                 assert ( iscsi->initiator_username != NULL );
514                 base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
515                                 buf );
516                 used += ssnprintf ( data + used, len - used,
517                                     "CHAP_N=%s%cCHAP_R=0x%s%c",
518                                     iscsi->initiator_username, 0, buf, 0 );
519         }
520
521         if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
522                 size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
523                 char buf[ base16_encoded_len ( challenge_len ) + 1 ];
524                 base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
525                                 buf );
526                 used += ssnprintf ( data + used, len - used,
527                                     "CHAP_I=%d%cCHAP_C=0x%s%c",
528                                     iscsi->chap_challenge[0], 0, buf, 0 );
529         }
530
531         if ( iscsi->status & ISCSI_STATUS_STRINGS_OPERATIONAL ) {
532                 used += ssnprintf ( data + used, len - used,
533                                     "HeaderDigest=None%c"
534                                     "DataDigest=None%c"
535                                     "MaxConnections=1%c"
536                                     "InitialR2T=Yes%c"
537                                     "ImmediateData=No%c"
538                                     "MaxRecvDataSegmentLength=8192%c"
539                                     "MaxBurstLength=262144%c"
540                                     "DefaultTime2Wait=0%c"
541                                     "DefaultTime2Retain=0%c"
542                                     "MaxOutstandingR2T=1%c"
543                                     "DataPDUInOrder=Yes%c"
544                                     "DataSequenceInOrder=Yes%c"
545                                     "ErrorRecoveryLevel=0%c",
546                                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );
547         }
548
549         return used;
550 }
551
552 /**
553  * Build iSCSI login request BHS
554  *
555  * @v iscsi             iSCSI session
556  */
557 static void iscsi_start_login ( struct iscsi_session *iscsi ) {
558         struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
559         int len;
560
561         /* Construct BHS and initiate transmission */
562         iscsi_start_tx ( iscsi );
563         request->opcode = ( ISCSI_OPCODE_LOGIN_REQUEST |
564                             ISCSI_FLAG_IMMEDIATE );
565         request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
566                            ISCSI_LOGIN_FLAG_TRANSITION );
567         /* version_max and version_min left as zero */
568         len = iscsi_build_login_request_strings ( iscsi, NULL, 0 );
569         ISCSI_SET_LENGTHS ( request->lengths, 0, len );
570         request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
571                                         IANA_EN_FEN_SYSTEMS );
572         /* isid_iana_qual left as zero */
573         request->tsih = htons ( iscsi->tsih );
574         request->itt = htonl ( iscsi->itt );
575         /* cid left as zero */
576         request->cmdsn = htonl ( iscsi->cmdsn );
577         request->expstatsn = htonl ( iscsi->statsn + 1 );
578 }
579
580 /**
581  * Complete iSCSI login request PDU transmission
582  *
583  * @v iscsi             iSCSI session
584  *
585  */
586 static void iscsi_login_request_done ( struct iscsi_session *iscsi ) {
587
588         /* Clear any "strings to send" flags */
589         iscsi->status &= ~ISCSI_STATUS_STRINGS_MASK;
590
591         /* Free any dynamically allocated storage used for login */
592         chap_finish ( &iscsi->chap );
593 }
594
595 /**
596  * Transmit data segment of an iSCSI login request PDU
597  *
598  * @v iscsi             iSCSI session
599  * @ret rc              Return status code
600  *
601  * For login requests, the data segment consists of the login strings.
602  */
603 static int iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
604         struct iscsi_bhs_login_request *request = &iscsi->tx_bhs.login_request;
605         struct io_buffer *iobuf;
606         size_t len;
607
608         len = ISCSI_DATA_LEN ( request->lengths );
609         iobuf = xfer_alloc_iob ( &iscsi->socket, len );
610         if ( ! iobuf )
611                 return -ENOMEM;
612         iob_put ( iobuf, len );
613         iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
614         return xfer_deliver_iob ( &iscsi->socket, iobuf );
615 }
616
617 /**
618  * Calculate maximum length of decoded large binary value
619  *
620  * @v encoded           Encoded large binary value
621  * @v max_raw_len       Maximum length of raw data
622  */
623 static inline size_t
624 iscsi_large_binary_decoded_max_len ( const char *encoded ) {
625         return ( strlen ( encoded ) ); /* Decoding never expands data */
626 }
627
628 /**
629  * Decode large binary value
630  *
631  * @v encoded           Encoded large binary value
632  * @v raw               Raw data
633  * @ret len             Length of raw data, or negative error
634  */
635 static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw ) {
636
637         if ( encoded[0] != '0' )
638                 return -EPROTO_INVALID_LARGE_BINARY;
639
640         switch ( encoded[1] ) {
641         case 'x' :
642         case 'X' :
643                 return base16_decode ( ( encoded + 2 ), raw );
644         case 'b' :
645         case 'B' :
646                 return base64_decode ( ( encoded + 2 ), raw );
647         default:
648                 return -EPROTO_INVALID_LARGE_BINARY;
649         }
650 }
651
652 /**
653  * Handle iSCSI TargetAddress text value
654  *
655  * @v iscsi             iSCSI session
656  * @v value             TargetAddress value
657  * @ret rc              Return status code
658  */
659 static int iscsi_handle_targetaddress_value ( struct iscsi_session *iscsi,
660                                               const char *value ) {
661         char *separator;
662
663         DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
664
665         /* Replace target address */
666         free ( iscsi->target_address );
667         iscsi->target_address = strdup ( value );
668         if ( ! iscsi->target_address )
669                 return -ENOMEM;
670
671         /* Replace target port */
672         iscsi->target_port = htons ( ISCSI_PORT );
673         separator = strchr ( iscsi->target_address, ':' );
674         if ( separator ) {
675                 *separator = '\0';
676                 iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
677         }
678
679         return 0;
680 }
681
682 /**
683  * Handle iSCSI AuthMethod text value
684  *
685  * @v iscsi             iSCSI session
686  * @v value             AuthMethod value
687  * @ret rc              Return status code
688  */
689 static int iscsi_handle_authmethod_value ( struct iscsi_session *iscsi,
690                                            const char *value ) {
691
692         /* If server requests CHAP, send the CHAP_A string */
693         if ( strcmp ( value, "CHAP" ) == 0 ) {
694                 DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
695                        iscsi );
696                 iscsi->status |= ( ISCSI_STATUS_STRINGS_CHAP_ALGORITHM |
697                                    ISCSI_STATUS_AUTH_FORWARD_REQUIRED );
698         }
699
700         return 0;
701 }
702
703 /**
704  * Handle iSCSI CHAP_A text value
705  *
706  * @v iscsi             iSCSI session
707  * @v value             CHAP_A value
708  * @ret rc              Return status code
709  */
710 static int iscsi_handle_chap_a_value ( struct iscsi_session *iscsi,
711                                        const char *value ) {
712
713         /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
714          * the server responds with anything else it is a protocol
715          * violation.
716          */
717         if ( strcmp ( value, "5" ) != 0 ) {
718                 DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
719                        iscsi, value );
720                 return -EPROTO_INVALID_CHAP_ALGORITHM;
721         }
722
723         return 0;
724 }
725
726 /**
727  * Handle iSCSI CHAP_I text value
728  *
729  * @v iscsi             iSCSI session
730  * @v value             CHAP_I value
731  * @ret rc              Return status code
732  */
733 static int iscsi_handle_chap_i_value ( struct iscsi_session *iscsi,
734                                        const char *value ) {
735         unsigned int identifier;
736         char *endp;
737         int rc;
738
739         /* The CHAP identifier is an integer value */
740         identifier = strtoul ( value, &endp, 0 );
741         if ( *endp != '\0' ) {
742                 DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
743                        iscsi, value );
744                 return -EPROTO_INVALID_CHAP_IDENTIFIER;
745         }
746
747         /* Prepare for CHAP with MD5 */
748         chap_finish ( &iscsi->chap );
749         if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
750                 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
751                        iscsi, strerror ( rc ) );
752                 return rc;
753         }
754
755         /* Identifier and secret are the first two components of the
756          * challenge.
757          */
758         chap_set_identifier ( &iscsi->chap, identifier );
759         if ( iscsi->initiator_password ) {
760                 chap_update ( &iscsi->chap, iscsi->initiator_password,
761                               strlen ( iscsi->initiator_password ) );
762         }
763
764         return 0;
765 }
766
767 /**
768  * Handle iSCSI CHAP_C text value
769  *
770  * @v iscsi             iSCSI session
771  * @v value             CHAP_C value
772  * @ret rc              Return status code
773  */
774 static int iscsi_handle_chap_c_value ( struct iscsi_session *iscsi,
775                                        const char *value ) {
776         uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
777         unsigned int i;
778         size_t len;
779         int rc;
780
781         /* Process challenge */
782         rc = iscsi_large_binary_decode ( value, buf );
783         if ( rc < 0 ) {
784                 DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
785                        iscsi, value, strerror ( rc ) );
786                 return rc;
787         }
788         len = rc;
789         chap_update ( &iscsi->chap, buf, len );
790
791         /* Build CHAP response */
792         DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
793         chap_respond ( &iscsi->chap );
794         iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_RESPONSE;
795
796         /* Send CHAP challenge, if applicable */
797         if ( iscsi->target_username ) {
798                 iscsi->status |= ISCSI_STATUS_STRINGS_CHAP_CHALLENGE;
799                 /* Generate CHAP challenge data */
800                 for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
801                         iscsi->chap_challenge[i] = random();
802                 }
803         }
804
805         return 0;
806 }
807
808 /**
809  * Handle iSCSI CHAP_N text value
810  *
811  * @v iscsi             iSCSI session
812  * @v value             CHAP_N value
813  * @ret rc              Return status code
814  */
815 static int iscsi_handle_chap_n_value ( struct iscsi_session *iscsi,
816                                        const char *value ) {
817
818         /* The target username isn't actually involved at any point in
819          * the authentication process; it merely serves to identify
820          * which password the target is using to generate the CHAP
821          * response.  We unnecessarily verify that the username is as
822          * expected, in order to provide mildly helpful diagnostics if
823          * the target is supplying the wrong username/password
824          * combination.
825          */
826         if ( iscsi->target_username &&
827              ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
828                 DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
829                        "(wanted \"%s\")\n",
830                        iscsi, value, iscsi->target_username );
831                 return -EACCES_INCORRECT_TARGET_USERNAME;
832         }
833
834         return 0;
835 }
836
837 /**
838  * Handle iSCSI CHAP_R text value
839  *
840  * @v iscsi             iSCSI session
841  * @v value             CHAP_R value
842  * @ret rc              Return status code
843  */
844 static int iscsi_handle_chap_r_value ( struct iscsi_session *iscsi,
845                                        const char *value ) {
846         uint8_t buf[ iscsi_large_binary_decoded_max_len ( value ) ];
847         size_t len;
848         int rc;
849
850         /* Generate CHAP response for verification */
851         chap_finish ( &iscsi->chap );
852         if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
853                 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
854                        iscsi, strerror ( rc ) );
855                 return rc;
856         }
857         chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
858         if ( iscsi->target_password ) {
859                 chap_update ( &iscsi->chap, iscsi->target_password,
860                               strlen ( iscsi->target_password ) );
861         }
862         chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
863                       ( sizeof ( iscsi->chap_challenge ) - 1 ) );
864         chap_respond ( &iscsi->chap );
865
866         /* Process response */
867         rc = iscsi_large_binary_decode ( value, buf );
868         if ( rc < 0 ) {
869                 DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
870                        iscsi, value, strerror ( rc ) );
871                 return rc;
872         }
873         len = rc;
874
875         /* Check CHAP response */
876         if ( len != iscsi->chap.response_len ) {
877                 DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
878                        iscsi );
879                 return -EPROTO_INVALID_CHAP_RESPONSE;
880         }
881         if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
882                 DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
883                        iscsi, value );
884                 return -EACCES_INCORRECT_TARGET_PASSWORD;
885         }
886
887         /* Mark session as authenticated */
888         iscsi->status |= ISCSI_STATUS_AUTH_REVERSE_OK;
889
890         return 0;
891 }
892
893 /** An iSCSI text string that we want to handle */
894 struct iscsi_string_type {
895         /** String key
896          *
897          * This is the portion up to and including the "=" sign,
898          * e.g. "InitiatorName=", "CHAP_A=", etc.
899          */
900         const char *key;
901         /** Handle iSCSI string value
902          *
903          * @v iscsi             iSCSI session
904          * @v value             iSCSI string value
905          * @ret rc              Return status code
906          */
907         int ( * handle ) ( struct iscsi_session *iscsi, const char *value );
908 };
909
910 /** iSCSI text strings that we want to handle */
911 static struct iscsi_string_type iscsi_string_types[] = {
912         { "TargetAddress=", iscsi_handle_targetaddress_value },
913         { "AuthMethod=", iscsi_handle_authmethod_value },
914         { "CHAP_A=", iscsi_handle_chap_a_value },
915         { "CHAP_I=", iscsi_handle_chap_i_value },
916         { "CHAP_C=", iscsi_handle_chap_c_value },
917         { "CHAP_N=", iscsi_handle_chap_n_value },
918         { "CHAP_R=", iscsi_handle_chap_r_value },
919         { NULL, NULL }
920 };
921
922 /**
923  * Handle iSCSI string
924  *
925  * @v iscsi             iSCSI session
926  * @v string            iSCSI string (in "key=value" format)
927  * @ret rc              Return status code
928  */
929 static int iscsi_handle_string ( struct iscsi_session *iscsi,
930                                  const char *string ) {
931         struct iscsi_string_type *type;
932         size_t key_len;
933         int rc;
934
935         for ( type = iscsi_string_types ; type->key ; type++ ) {
936                 key_len = strlen ( type->key );
937                 if ( strncmp ( string, type->key, key_len ) != 0 )
938                         continue;
939                 DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
940                 if ( ( rc = type->handle ( iscsi,
941                                            ( string + key_len ) ) ) != 0 ) {
942                         DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
943                                iscsi, string, strerror ( rc ) );
944                         return rc;
945                 }
946                 return 0;
947         }
948         DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
949         return 0;
950 }
951
952 /**
953  * Handle iSCSI strings
954  *
955  * @v iscsi             iSCSI session
956  * @v string            iSCSI string buffer
957  * @v len               Length of string buffer
958  * @ret rc              Return status code
959  */
960 static int iscsi_handle_strings ( struct iscsi_session *iscsi,
961                                   const char *strings, size_t len ) {
962         size_t string_len;
963         int rc;
964
965         /* Handle each string in turn, taking care not to overrun the
966          * data buffer in case of badly-terminated data.
967          */
968         while ( 1 ) {
969                 string_len = ( strnlen ( strings, len ) + 1 );
970                 if ( string_len > len )
971                         break;
972                 if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
973                         return rc;
974                 strings += string_len;
975                 len -= string_len;
976         }
977         return 0;
978 }
979
980 /**
981  * Receive PDU data into buffer
982  *
983  * @v iscsi             iSCSI session
984  * @v data              Data to receive
985  * @v len               Length of data
986  * @ret rc              Return status code
987  *
988  * This can be used when the RX PDU type handler wishes to buffer up
989  * all received data and process the PDU as a single unit.  The caller
990  * is repsonsible for calling iscsi_rx_buffered_data_done() after
991  * processing the data.
992  */
993 static int iscsi_rx_buffered_data ( struct iscsi_session *iscsi,
994                                     const void *data, size_t len ) {
995
996         /* Allocate buffer on first call */
997         if ( ! iscsi->rx_buffer ) {
998                 iscsi->rx_buffer = malloc ( iscsi->rx_len );
999                 if ( ! iscsi->rx_buffer )
1000                         return -ENOMEM;
1001         }
1002
1003         /* Copy data to buffer */
1004         assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
1005         memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
1006
1007         return 0;
1008 }
1009
1010 /**
1011  * Convert iSCSI response status to return status code
1012  *
1013  * @v status_class      iSCSI status class
1014  * @v status_detail     iSCSI status detail
1015  * @ret rc              Return status code
1016  */
1017 static int iscsi_status_to_rc ( unsigned int status_class,
1018                                 unsigned int status_detail ) {
1019         switch ( status_class ) {
1020         case ISCSI_STATUS_INITIATOR_ERROR :
1021                 switch ( status_detail ) {
1022                 case ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION :
1023                         return -EPERM_INITIATOR_AUTHENTICATION;
1024                 case ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION :
1025                         return -EPERM_INITIATOR_AUTHORISATION;
1026                 case ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND :
1027                 case ISCSI_STATUS_INITIATOR_ERROR_REMOVED :
1028                         return -ENODEV;
1029                 default :
1030                         return -ENOTSUP_INITIATOR_STATUS;
1031                 }
1032         case ISCSI_STATUS_TARGET_ERROR :
1033                 return -EIO;
1034         default :
1035                 return -EINVAL;
1036         }
1037 }
1038
1039 /**
1040  * Receive data segment of an iSCSI login response PDU
1041  *
1042  * @v iscsi             iSCSI session
1043  * @v data              Received data
1044  * @v len               Length of received data
1045  * @v remaining         Data remaining after this data
1046  * @ret rc              Return status code
1047  */
1048 static int iscsi_rx_login_response ( struct iscsi_session *iscsi,
1049                                      const void *data, size_t len,
1050                                      size_t remaining ) {
1051         struct iscsi_bhs_login_response *response
1052                 = &iscsi->rx_bhs.login_response;
1053         int rc;
1054
1055         /* Buffer up the PDU data */
1056         if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1057                 DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1058                        iscsi, strerror ( rc ) );
1059                 return rc;
1060         }
1061         if ( remaining )
1062                 return 0;
1063
1064         /* Process string data and discard string buffer */
1065         if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1066                                            iscsi->rx_len ) ) != 0 )
1067                 return rc;
1068         iscsi_rx_buffered_data_done ( iscsi );
1069
1070         /* Check for login redirection */
1071         if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1072                 DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1073                 iscsi_close_connection ( iscsi, 0 );
1074                 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1075                         DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1076                                iscsi, strerror ( rc ) );
1077                         return rc;
1078                 }
1079                 return 0;
1080         }
1081
1082         /* Check for fatal errors */
1083         if ( response->status_class != 0 ) {
1084                 DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1085                        response->status_class, response->status_detail );
1086                 rc = iscsi_status_to_rc ( response->status_class,
1087                                           response->status_detail );
1088                 iscsi->instant_rc = rc;
1089                 return rc;
1090         }
1091
1092         /* Handle login transitions */
1093         if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1094                 iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1095                                     ISCSI_STATUS_STRINGS_MASK );
1096                 switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1097                 case ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION:
1098                         iscsi->status |=
1099                                 ( ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE |
1100                                   ISCSI_STATUS_STRINGS_OPERATIONAL );
1101                         break;
1102                 case ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE:
1103                         iscsi->status |= ISCSI_STATUS_FULL_FEATURE_PHASE;
1104                         break;
1105                 default:
1106                         DBGC ( iscsi, "iSCSI %p got invalid response flags "
1107                                "%02x\n", iscsi, response->flags );
1108                         return -EIO;
1109                 }
1110         }
1111
1112         /* Send next login request PDU if we haven't reached the full
1113          * feature phase yet.
1114          */
1115         if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1116              ISCSI_STATUS_FULL_FEATURE_PHASE ) {
1117                 iscsi_start_login ( iscsi );
1118                 return 0;
1119         }
1120
1121         /* Check that target authentication was successful (if required) */
1122         if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1123              ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1124                 DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1125                        "authentication\n", iscsi );
1126                 return -EPROTO;
1127         }
1128
1129         /* Reset retry count */
1130         iscsi->retry_count = 0;
1131
1132         /* Record TSIH for future reference */
1133         iscsi->tsih = ntohl ( response->tsih );
1134         
1135         /* Send the actual SCSI command */
1136         iscsi_start_command ( iscsi );
1137
1138         return 0;
1139 }
1140
1141 /****************************************************************************
1142  *
1143  * iSCSI to socket interface
1144  *
1145  */
1146
1147 /**
1148  * Start up a new TX PDU
1149  *
1150  * @v iscsi             iSCSI session
1151  *
1152  * This initiates the process of sending a new PDU.  Only one PDU may
1153  * be in transit at any one time.
1154  */
1155 static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
1156         assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1157         
1158         /* Initialise TX BHS */
1159         memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1160
1161         /* Flag TX engine to start transmitting */
1162         iscsi->tx_state = ISCSI_TX_BHS;
1163 }
1164
1165 /**
1166  * Transmit nothing
1167  *
1168  * @v iscsi             iSCSI session
1169  * @ret rc              Return status code
1170  */
1171 static int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused ) {
1172         return 0;
1173 }
1174
1175 /**
1176  * Transmit basic header segment of an iSCSI PDU
1177  *
1178  * @v iscsi             iSCSI session
1179  * @ret rc              Return status code
1180  */
1181 static int iscsi_tx_bhs ( struct iscsi_session *iscsi ) {
1182         return xfer_deliver_raw ( &iscsi->socket,  &iscsi->tx_bhs,
1183                                   sizeof ( iscsi->tx_bhs ) );
1184 }
1185
1186 /**
1187  * Transmit data segment of an iSCSI PDU
1188  *
1189  * @v iscsi             iSCSI session
1190  * @ret rc              Return status code
1191  * 
1192  * Handle transmission of part of a PDU data segment.  iscsi::tx_bhs
1193  * will be valid when this is called.
1194  */
1195 static int iscsi_tx_data ( struct iscsi_session *iscsi ) {
1196         struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1197
1198         switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1199         case ISCSI_OPCODE_DATA_OUT:
1200                 return iscsi_tx_data_out ( iscsi );
1201         case ISCSI_OPCODE_LOGIN_REQUEST:
1202                 return iscsi_tx_login_request ( iscsi );
1203         default:
1204                 /* Nothing to send in other states */
1205                 return 0;
1206         }
1207 }
1208
1209 /**
1210  * Transmit data padding of an iSCSI PDU
1211  *
1212  * @v iscsi             iSCSI session
1213  * @ret rc              Return status code
1214  * 
1215  * Handle transmission of any data padding in a PDU data segment.
1216  * iscsi::tx_bhs will be valid when this is called.
1217  */
1218 static int iscsi_tx_data_padding ( struct iscsi_session *iscsi ) {
1219         static const char pad[] = { '\0', '\0', '\0' };
1220         struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1221         size_t pad_len;
1222         
1223         pad_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1224         if ( ! pad_len )
1225                 return 0;
1226
1227         return xfer_deliver_raw ( &iscsi->socket, pad, pad_len );
1228 }
1229
1230 /**
1231  * Complete iSCSI PDU transmission
1232  *
1233  * @v iscsi             iSCSI session
1234  *
1235  * Called when a PDU has been completely transmitted and the TX state
1236  * machine is about to enter the idle state.  iscsi::tx_bhs will be
1237  * valid for the just-completed PDU when this is called.
1238  */
1239 static void iscsi_tx_done ( struct iscsi_session *iscsi ) {
1240         struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1241
1242         switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1243         case ISCSI_OPCODE_DATA_OUT:
1244                 iscsi_data_out_done ( iscsi );
1245         case ISCSI_OPCODE_LOGIN_REQUEST:
1246                 iscsi_login_request_done ( iscsi );
1247         default:
1248                 /* No action */
1249                 break;
1250         }
1251 }
1252
1253 /**
1254  * Transmit iSCSI PDU
1255  *
1256  * @v iscsi             iSCSI session
1257  * @v buf               Temporary data buffer
1258  * @v len               Length of temporary data buffer
1259  * 
1260  * Constructs data to be sent for the current TX state
1261  */
1262 static void iscsi_tx_step ( struct process *process ) {
1263         struct iscsi_session *iscsi =
1264                 container_of ( process, struct iscsi_session, process );
1265         struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1266         int ( * tx ) ( struct iscsi_session *iscsi );
1267         enum iscsi_tx_state next_state;
1268         size_t tx_len;
1269         int rc;
1270
1271         /* Select fragment to transmit */
1272         while ( 1 ) {
1273                 switch ( iscsi->tx_state ) {
1274                 case ISCSI_TX_IDLE:
1275                         /* Stop processing */
1276                         return;
1277                 case ISCSI_TX_BHS:
1278                         tx = iscsi_tx_bhs;
1279                         tx_len = sizeof ( iscsi->tx_bhs );
1280                         next_state = ISCSI_TX_AHS;
1281                         break;
1282                 case ISCSI_TX_AHS:
1283                         tx = iscsi_tx_nothing;
1284                         tx_len = 0;
1285                         next_state = ISCSI_TX_DATA;
1286                         break;
1287                 case ISCSI_TX_DATA:
1288                         tx = iscsi_tx_data;
1289                         tx_len = ISCSI_DATA_LEN ( common->lengths );
1290                         next_state = ISCSI_TX_DATA_PADDING;
1291                         break;
1292                 case ISCSI_TX_DATA_PADDING:
1293                         tx = iscsi_tx_data_padding;
1294                         tx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1295                         next_state = ISCSI_TX_IDLE;
1296                         break;
1297                 default:
1298                         assert ( 0 );
1299                         return;
1300                 }
1301
1302                 /* Check for window availability, if needed */
1303                 if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1304                         /* Cannot transmit at this point; stop processing */
1305                         return;
1306                 }
1307
1308                 /* Transmit data */
1309                 if ( ( rc = tx ( iscsi ) ) != 0 ) {
1310                         DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1311                                iscsi, strerror ( rc ) );
1312                         return;
1313                 }
1314
1315                 /* Move to next state */
1316                 iscsi->tx_state = next_state;
1317                 if ( next_state == ISCSI_TX_IDLE )
1318                         iscsi_tx_done ( iscsi );
1319         }
1320 }
1321
1322 /**
1323  * Receive basic header segment of an iSCSI PDU
1324  *
1325  * @v iscsi             iSCSI session
1326  * @v data              Received data
1327  * @v len               Length of received data
1328  * @v remaining         Data remaining after this data
1329  * @ret rc              Return status code
1330  *
1331  * This fills in iscsi::rx_bhs with the data from the BHS portion of
1332  * the received PDU.
1333  */
1334 static int iscsi_rx_bhs ( struct iscsi_session *iscsi, const void *data,
1335                           size_t len, size_t remaining __unused ) {
1336         memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1337         if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1338                 DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1339                         iscsi, iscsi->rx_bhs.common.opcode,
1340                         ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1341         }
1342         return 0;
1343 }
1344
1345 /**
1346  * Discard portion of an iSCSI PDU.
1347  *
1348  * @v iscsi             iSCSI session
1349  * @v data              Received data
1350  * @v len               Length of received data
1351  * @v remaining         Data remaining after this data
1352  * @ret rc              Return status code
1353  *
1354  * This discards data from a portion of a received PDU.
1355  */
1356 static int iscsi_rx_discard ( struct iscsi_session *iscsi __unused,
1357                               const void *data __unused, size_t len __unused,
1358                               size_t remaining __unused ) {
1359         /* Do nothing */
1360         return 0;
1361 }
1362
1363 /**
1364  * Receive data segment of an iSCSI PDU
1365  *
1366  * @v iscsi             iSCSI session
1367  * @v data              Received data
1368  * @v len               Length of received data
1369  * @v remaining         Data remaining after this data
1370  * @ret rc              Return status code
1371  *
1372  * Handle processing of part of a PDU data segment.  iscsi::rx_bhs
1373  * will be valid when this is called.
1374  */
1375 static int iscsi_rx_data ( struct iscsi_session *iscsi, const void *data,
1376                            size_t len, size_t remaining ) {
1377         struct iscsi_bhs_common_response *response
1378                 = &iscsi->rx_bhs.common_response;
1379
1380         /* Update cmdsn and statsn */
1381         iscsi->cmdsn = ntohl ( response->expcmdsn );
1382         iscsi->statsn = ntohl ( response->statsn );
1383
1384         switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1385         case ISCSI_OPCODE_LOGIN_RESPONSE:
1386                 return iscsi_rx_login_response ( iscsi, data, len, remaining );
1387         case ISCSI_OPCODE_SCSI_RESPONSE:
1388                 return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1389         case ISCSI_OPCODE_DATA_IN:
1390                 return iscsi_rx_data_in ( iscsi, data, len, remaining );
1391         case ISCSI_OPCODE_R2T:
1392                 return iscsi_rx_r2t ( iscsi, data, len, remaining );
1393         default:
1394                 if ( remaining )
1395                         return 0;
1396                 DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1397                        response->opcode );
1398                 return -ENOTSUP_OPCODE;
1399         }
1400 }
1401
1402 /**
1403  * Receive new data
1404  *
1405  * @v socket            Transport layer interface
1406  * @v data              Received data
1407  * @v len               Length of received data
1408  * @ret rc              Return status code
1409  *
1410  * This handles received PDUs.  The receive strategy is to fill in
1411  * iscsi::rx_bhs with the contents of the BHS portion of the PDU,
1412  * throw away any AHS portion, and then process each part of the data
1413  * portion as it arrives.  The data processing routine therefore
1414  * always has a full copy of the BHS available, even for portions of
1415  * the data in different packets to the BHS.
1416  */
1417 static int iscsi_socket_deliver_raw ( struct xfer_interface *socket,
1418                                       const void *data, size_t len ) {
1419         struct iscsi_session *iscsi =
1420                 container_of ( socket, struct iscsi_session, socket );
1421         struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1422         int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1423                        size_t len, size_t remaining );
1424         enum iscsi_rx_state next_state;
1425         size_t frag_len;
1426         size_t remaining;
1427         int rc;
1428
1429         while ( 1 ) {
1430                 switch ( iscsi->rx_state ) {
1431                 case ISCSI_RX_BHS:
1432                         rx = iscsi_rx_bhs;
1433                         iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1434                         next_state = ISCSI_RX_AHS;                      
1435                         break;
1436                 case ISCSI_RX_AHS:
1437                         rx = iscsi_rx_discard;
1438                         iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1439                         next_state = ISCSI_RX_DATA;
1440                         break;
1441                 case ISCSI_RX_DATA:
1442                         rx = iscsi_rx_data;
1443                         iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1444                         next_state = ISCSI_RX_DATA_PADDING;
1445                         break;
1446                 case ISCSI_RX_DATA_PADDING:
1447                         rx = iscsi_rx_discard;
1448                         iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1449                         next_state = ISCSI_RX_BHS;
1450                         break;
1451                 default:
1452                         assert ( 0 );
1453                         return -EINVAL;
1454                 }
1455
1456                 frag_len = iscsi->rx_len - iscsi->rx_offset;
1457                 if ( frag_len > len )
1458                         frag_len = len;
1459                 remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1460                 if ( ( rc = rx ( iscsi, data, frag_len, remaining ) ) != 0 ) {
1461                         DBGC ( iscsi, "iSCSI %p could not process received "
1462                                "data: %s\n", iscsi, strerror ( rc ) );
1463                         iscsi_close_connection ( iscsi, rc );
1464                         iscsi_scsi_done ( iscsi, rc );
1465                         return rc;
1466                 }
1467
1468                 iscsi->rx_offset += frag_len;
1469                 data += frag_len;
1470                 len -= frag_len;
1471
1472                 /* If all the data for this state has not yet been
1473                  * received, stay in this state for now.
1474                  */
1475                 if ( iscsi->rx_offset != iscsi->rx_len )
1476                         return 0;
1477
1478                 iscsi->rx_state = next_state;
1479                 iscsi->rx_offset = 0;
1480         }
1481
1482         return 0;
1483 }
1484
1485 /**
1486  * Handle stream connection closure
1487  *
1488  * @v socket            Transport layer interface
1489  * @v rc                Reason for close
1490  *
1491  */
1492 static void iscsi_socket_close ( struct xfer_interface *socket, int rc ) {
1493         struct iscsi_session *iscsi =
1494                 container_of ( socket, struct iscsi_session, socket );
1495
1496         /* Even a graceful close counts as an error for iSCSI */
1497         if ( ! rc )
1498                 rc = -ECONNRESET;
1499
1500         /* Close session cleanly */
1501         iscsi_close_connection ( iscsi, rc );
1502
1503         /* Retry connection if within the retry limit, otherwise fail */
1504         if ( ++iscsi->retry_count <= ISCSI_MAX_RETRIES ) {
1505                 DBGC ( iscsi, "iSCSI %p retrying connection (retry #%d)\n",
1506                        iscsi, iscsi->retry_count );
1507                 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1508                         DBGC ( iscsi, "iSCSI %p could not reconnect: %s\n",
1509                                iscsi, strerror ( rc ) );
1510                         iscsi_scsi_done ( iscsi, rc );
1511                 }
1512         } else {
1513                 DBGC ( iscsi, "iSCSI %p retry count exceeded\n", iscsi );
1514                 iscsi->instant_rc = rc;
1515                 iscsi_scsi_done ( iscsi, rc );
1516         }
1517 }
1518
1519 /**
1520  * Handle redirection event
1521  *
1522  * @v socket            Transport layer interface
1523  * @v type              Location type
1524  * @v args              Remaining arguments depend upon location type
1525  * @ret rc              Return status code
1526  */
1527 static int iscsi_vredirect ( struct xfer_interface *socket, int type,
1528                              va_list args ) {
1529         struct iscsi_session *iscsi =
1530                 container_of ( socket, struct iscsi_session, socket );
1531         va_list tmp;
1532         struct sockaddr *peer;
1533
1534         /* Intercept redirects to a LOCATION_SOCKET and record the IP
1535          * address for the iBFT.  This is a bit of a hack, but avoids
1536          * inventing an ioctl()-style call to retrieve the socket
1537          * address from a data-xfer interface.
1538          */
1539         if ( type == LOCATION_SOCKET ) {
1540                 va_copy ( tmp, args );
1541                 ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1542                 peer = va_arg ( tmp, struct sockaddr * );
1543                 memcpy ( &iscsi->target_sockaddr, peer,
1544                          sizeof ( iscsi->target_sockaddr ) );
1545                 va_end ( tmp );
1546         }
1547
1548         return xfer_vreopen ( socket, type, args );
1549 }
1550                              
1551
1552 /** iSCSI socket operations */
1553 static struct xfer_interface_operations iscsi_socket_operations = {
1554         .close          = iscsi_socket_close,
1555         .vredirect      = iscsi_vredirect,
1556         .window         = unlimited_xfer_window,
1557         .alloc_iob      = default_xfer_alloc_iob,
1558         .deliver_iob    = xfer_deliver_as_raw,
1559         .deliver_raw    = iscsi_socket_deliver_raw,
1560 };
1561
1562
1563 /****************************************************************************
1564  *
1565  * iSCSI command issuing
1566  *
1567  */
1568
1569 /**
1570  * Issue SCSI command
1571  *
1572  * @v scsi              SCSI device
1573  * @v command           SCSI command
1574  * @ret rc              Return status code
1575  */
1576 static int iscsi_command ( struct scsi_device *scsi,
1577                            struct scsi_command *command ) {
1578         struct iscsi_session *iscsi =
1579                 container_of ( scsi->backend, struct iscsi_session, refcnt );
1580         int rc;
1581
1582         /* Abort immediately if we have a recorded permanent failure */
1583         if ( iscsi->instant_rc )
1584                 return iscsi->instant_rc;
1585
1586         /* Record SCSI command */
1587         iscsi->command = command;
1588
1589         /* Issue command or open connection as appropriate */
1590         if ( iscsi->status ) {
1591                 iscsi_start_command ( iscsi );
1592         } else {
1593                 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1594                         iscsi->command = NULL;
1595                         return rc;
1596                 }
1597         }
1598
1599         return 0;
1600 }
1601
1602 /**
1603  * Shut down iSCSI interface
1604  *
1605  * @v scsi              SCSI device
1606  */
1607 void iscsi_detach ( struct scsi_device *scsi ) {
1608         struct iscsi_session *iscsi =
1609                 container_of ( scsi->backend, struct iscsi_session, refcnt );
1610
1611         xfer_nullify ( &iscsi->socket );
1612         iscsi_close_connection ( iscsi, 0 );
1613         process_del ( &iscsi->process );
1614         scsi->command = scsi_detached_command;
1615         ref_put ( scsi->backend );
1616         scsi->backend = NULL;
1617 }
1618
1619 /****************************************************************************
1620  *
1621  * Instantiator
1622  *
1623  */
1624
1625 /** iSCSI root path components (as per RFC4173) */
1626 enum iscsi_root_path_component {
1627         RP_LITERAL = 0,
1628         RP_SERVERNAME,
1629         RP_PROTOCOL,
1630         RP_PORT,
1631         RP_LUN,
1632         RP_TARGETNAME,
1633         NUM_RP_COMPONENTS
1634 };
1635
1636 /**
1637  * Parse iSCSI root path
1638  *
1639  * @v iscsi             iSCSI session
1640  * @v root_path         iSCSI root path (as per RFC4173)
1641  * @ret rc              Return status code
1642  */
1643 static int iscsi_parse_root_path ( struct iscsi_session *iscsi,
1644                                    const char *root_path ) {
1645         char rp_copy[ strlen ( root_path ) + 1 ];
1646         char *rp_comp[NUM_RP_COMPONENTS];
1647         char *rp = rp_copy;
1648         int i = 0;
1649         int rc;
1650
1651         /* Split root path into component parts */
1652         strcpy ( rp_copy, root_path );
1653         while ( 1 ) {
1654                 rp_comp[i++] = rp;
1655                 if ( i == NUM_RP_COMPONENTS )
1656                         break;
1657                 for ( ; *rp != ':' ; rp++ ) {
1658                         if ( ! *rp ) {
1659                                 DBGC ( iscsi, "iSCSI %p root path \"%s\" "
1660                                        "too short\n", iscsi, root_path );
1661                                 return -EINVAL;
1662                         }
1663                 }
1664                 *(rp++) = '\0';
1665         }
1666
1667         /* Use root path components to configure iSCSI session */
1668         iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
1669         if ( ! iscsi->target_address )
1670                 return -ENOMEM;
1671         iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
1672         if ( ! iscsi->target_port )
1673                 iscsi->target_port = ISCSI_PORT;
1674         if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
1675                 DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
1676                        iscsi, rp_comp[RP_LUN] );
1677                 return rc;
1678         }
1679         iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
1680         if ( ! iscsi->target_iqn )
1681                 return -ENOMEM;
1682
1683         return 0;
1684 }
1685
1686 /**
1687  * Set iSCSI authentication details
1688  *
1689  * @v iscsi             iSCSI session
1690  * @v initiator_username Initiator username, if any
1691  * @v initiator_password Initiator password, if any
1692  * @v target_username   Target username, if any
1693  * @v target_password   Target password, if any
1694  * @ret rc              Return status code
1695  */
1696 static int iscsi_set_auth ( struct iscsi_session *iscsi,
1697                             const char *initiator_username,
1698                             const char *initiator_password,
1699                             const char *target_username,
1700                             const char *target_password ) {
1701
1702         /* Check for initiator or target credentials */
1703         if ( initiator_username || initiator_password ||
1704              target_username || target_password ) {
1705
1706                 /* We must have at least an initiator username+password */
1707                 if ( ! ( initiator_username && initiator_password ) )
1708                         goto invalid_auth;
1709
1710                 /* Store initiator credentials */
1711                 iscsi->initiator_username = strdup ( initiator_username );
1712                 if ( ! iscsi->initiator_username )
1713                         return -ENOMEM;
1714                 iscsi->initiator_password = strdup ( initiator_password );
1715                 if ( ! iscsi->initiator_password )
1716                         return -ENOMEM;
1717
1718                 /* Check for target credentials */
1719                 if ( target_username || target_password ) {
1720
1721                         /* We must have target username+password */
1722                         if ( ! ( target_username && target_password ) )
1723                                 goto invalid_auth;
1724
1725                         /* Store target credentials */
1726                         iscsi->target_username = strdup ( target_username );
1727                         if ( ! iscsi->target_username )
1728                                 return -ENOMEM;
1729                         iscsi->target_password = strdup ( target_password );
1730                         if ( ! iscsi->target_password )
1731                                 return -ENOMEM;
1732                 }
1733         }
1734
1735         return 0;
1736
1737  invalid_auth:
1738         DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
1739                "%sname,%spw, target %sname,%spw\n", iscsi,
1740                ( initiator_username ? "" : "no " ),
1741                ( initiator_password ? "" : "no " ),
1742                ( target_username ? "" : "no " ),
1743                ( target_password ? "" : "no " ) );
1744         return -EINVAL;
1745 }
1746
1747 /**
1748  * Attach iSCSI interface
1749  *
1750  * @v scsi              SCSI device
1751  * @v root_path         iSCSI root path (as per RFC4173)
1752  * @ret rc              Return status code
1753  */
1754 int iscsi_attach ( struct scsi_device *scsi, const char *root_path ) {
1755         struct iscsi_session *iscsi;
1756         int rc;
1757
1758         /* Allocate and initialise structure */
1759         iscsi = zalloc ( sizeof ( *iscsi ) );
1760         if ( ! iscsi )
1761                 return -ENOMEM;
1762         iscsi->refcnt.free = iscsi_free;
1763         xfer_init ( &iscsi->socket, &iscsi_socket_operations, &iscsi->refcnt );
1764         process_init ( &iscsi->process, iscsi_tx_step, &iscsi->refcnt );
1765
1766         /* Parse root path */
1767         if ( ( rc = iscsi_parse_root_path ( iscsi, root_path ) ) != 0 )
1768                 goto err;
1769         /* Set fields not specified by root path */
1770         if ( ( rc = iscsi_set_auth ( iscsi,
1771                                      iscsi_initiator_username,
1772                                      iscsi_initiator_password,
1773                                      iscsi_target_username,
1774                                      iscsi_target_password ) ) != 0 )
1775                 goto err;
1776
1777         /* Sanity checks */
1778         if ( ! iscsi->target_address ) {
1779                 DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
1780                        iscsi );
1781                 rc = -ENOTSUP_DISCOVERY;
1782                 goto err;
1783         }
1784         if ( ! iscsi->target_iqn ) {
1785                 DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
1786                        iscsi, root_path );
1787                 rc = -EINVAL;
1788                 goto err;
1789         }
1790
1791         /* Attach parent interface, mortalise self, and return */
1792         scsi->backend = ref_get ( &iscsi->refcnt );
1793         scsi->command = iscsi_command;
1794         ref_put ( &iscsi->refcnt );
1795         return 0;
1796         
1797  err:
1798         ref_put ( &iscsi->refcnt );
1799         return rc;
1800 }
1801
1802 /****************************************************************************
1803  *
1804  * Settings
1805  *
1806  */
1807
1808 /** iSCSI initiator IQN setting */
1809 struct setting initiator_iqn_setting __setting = {
1810         .name = "initiator-iqn",
1811         .description = "iSCSI initiator name",
1812         .tag = DHCP_ISCSI_INITIATOR_IQN,
1813         .type = &setting_type_string,
1814 };
1815
1816 /** iSCSI reverse username setting */
1817 struct setting reverse_username_setting __setting = {
1818         .name = "reverse-username",
1819         .description = "Reverse user name",
1820         .tag = DHCP_EB_REVERSE_USERNAME,
1821         .type = &setting_type_string,
1822 };
1823
1824 /** iSCSI reverse password setting */
1825 struct setting reverse_password_setting __setting = {
1826         .name = "reverse-password",
1827         .description = "Reverse password",
1828         .tag = DHCP_EB_REVERSE_PASSWORD,
1829         .type = &setting_type_string,
1830 };
1831
1832 /** An iSCSI string setting */
1833 struct iscsi_string_setting {
1834         /** Setting */
1835         struct setting *setting;
1836         /** String to update */
1837         char **string;
1838         /** String prefix */
1839         const char *prefix;
1840 };
1841
1842 /** iSCSI string settings */
1843 static struct iscsi_string_setting iscsi_string_settings[] = {
1844         {
1845                 .setting = &initiator_iqn_setting,
1846                 .string = &iscsi_explicit_initiator_iqn,
1847                 .prefix = "",
1848         },
1849         {
1850                 .setting = &username_setting,
1851                 .string = &iscsi_initiator_username,
1852                 .prefix = "",
1853         },
1854         {
1855                 .setting = &password_setting,
1856                 .string = &iscsi_initiator_password,
1857                 .prefix = "",
1858         },
1859         {
1860                 .setting = &reverse_username_setting,
1861                 .string = &iscsi_target_username,
1862                 .prefix = "",
1863         },
1864         {
1865                 .setting = &reverse_password_setting,
1866                 .string = &iscsi_target_password,
1867                 .prefix = "",
1868         },
1869         {
1870                 .setting = &hostname_setting,
1871                 .string = &iscsi_default_initiator_iqn,
1872                 .prefix = "iqn.2000-01.org.etherboot:",
1873         },
1874 };
1875
1876 /**
1877  * Apply iSCSI setting
1878  *
1879  * @v setting           iSCSI string setting
1880  * @ret rc              Return status code
1881  */
1882 static int apply_iscsi_string_setting ( struct iscsi_string_setting *setting ){
1883         size_t prefix_len;
1884         int setting_len;
1885         size_t len;
1886         int check_len;
1887         char *p;
1888
1889         /* Free old string */
1890         free ( *setting->string );
1891         *setting->string = NULL;
1892
1893         /* Allocate new string */
1894         prefix_len = strlen ( setting->prefix );
1895         setting_len = fetch_setting_len ( NULL, setting->setting );
1896         if ( setting_len < 0 ) {
1897                 /* Missing settings are not errors; leave strings as NULL */
1898                 return 0;
1899         }
1900         len = ( prefix_len + setting_len + 1 );
1901         p = *setting->string = malloc ( len );
1902         if ( ! p )
1903                 return -ENOMEM;
1904
1905         /* Fill new string */
1906         strcpy ( p, setting->prefix );
1907         check_len = fetch_string_setting ( NULL, setting->setting,
1908                                            ( p + prefix_len ),
1909                                            ( len - prefix_len ) );
1910         assert ( check_len == setting_len );
1911
1912         return 0;
1913 }
1914
1915 /**
1916  * Apply iSCSI settings
1917  *
1918  * @ret rc              Return status code
1919  */
1920 static int apply_iscsi_settings ( void ) {
1921         struct iscsi_string_setting *setting;
1922         unsigned int i;
1923         int rc;
1924
1925         for ( i = 0 ; i < ( sizeof ( iscsi_string_settings ) /
1926                             sizeof ( iscsi_string_settings[0] ) ) ; i++ ) {
1927                 setting = &iscsi_string_settings[i];
1928                 if ( ( rc = apply_iscsi_string_setting ( setting ) ) != 0 ) {
1929                         DBG ( "iSCSI could not apply setting %s\n",
1930                               setting->setting->name );
1931                         return rc;
1932                 }
1933         }
1934
1935         return 0;
1936 }
1937
1938 /** iSCSI settings applicator */
1939 struct settings_applicator iscsi_settings_applicator __settings_applicator = {
1940         .apply = apply_iscsi_settings,
1941 };
1942
1943 /****************************************************************************
1944  *
1945  * Initiator name
1946  *
1947  */
1948
1949 /**
1950  * Get iSCSI initiator IQN
1951  *
1952  * @v iscsi             iSCSI session
1953  * @ret rc              Return status code
1954  */
1955 const char * iscsi_initiator_iqn ( void ) {
1956
1957         if ( iscsi_explicit_initiator_iqn )
1958                 return iscsi_explicit_initiator_iqn;
1959         if ( iscsi_default_initiator_iqn )
1960                 return iscsi_default_initiator_iqn;
1961         return "iqn.2000-09.org.etherboot:UNKNOWN";
1962 }