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