Browse Source

[fc] Allow FLOGI response to be sent to newly-assigned peer port ID

The response to a received FLOGI should probably be sent to the peer
port ID assigned as a result of the WWPN comparison.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 years ago
parent
commit
654da534ad
4 changed files with 50 additions and 5 deletions
  1. 22
    0
      src/include/ipxe/fc.h
  2. 1
    0
      src/include/ipxe/socket.h
  3. 4
    1
      src/net/fc.c
  4. 23
    4
      src/net/fcels.c

+ 22
- 0
src/include/ipxe/fc.h View File

@@ -16,6 +16,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
16 16
 #include <ipxe/tables.h>
17 17
 #include <ipxe/interface.h>
18 18
 #include <ipxe/retry.h>
19
+#include <ipxe/socket.h>
19 20
 
20 21
 /******************************************************************************
21 22
  *
@@ -40,6 +41,27 @@ struct fc_port_id {
40 41
 /** Length of Fibre Channel port identifier next */
41 42
 #define FC_PORT_ID_STRLEN 9 /* "xx.xx.xx" */
42 43
 
44
+/**
45
+ * Fibre Channel socket address
46
+ */
47
+struct sockaddr_fc {
48
+	/** Socket address family (part of struct @c sockaddr)
49
+	 *
50
+	 * Always set to @c AF_FC for Fibre Channel addresses
51
+	 */
52
+	sa_family_t sfc_family;
53
+	/** Port ID */
54
+	struct fc_port_id sfc_port_id;
55
+	/** Padding
56
+	 *
57
+	 * This ensures that a struct @c sockaddr_tcpip is large
58
+	 * enough to hold a socket address for any TCP/IP address
59
+	 * family.
60
+	 */
61
+	char pad[ sizeof ( struct sockaddr ) - sizeof ( sa_family_t )
62
+					     - sizeof ( struct fc_port_id ) ];
63
+} __attribute__ (( may_alias ));
64
+
43 65
 extern struct fc_port_id fc_empty_port_id;
44 66
 extern struct fc_port_id fc_f_port_id;
45 67
 extern struct fc_port_id fc_ptp_low_port_id;

+ 1
- 0
src/include/ipxe/socket.h View File

@@ -54,6 +54,7 @@ socket_semantics_name ( int semantics ) {
54 54
  */
55 55
 #define AF_INET		1	/**< IPv4 Internet addresses */
56 56
 #define AF_INET6	2	/**< IPv6 Internet addresses */
57
+#define AF_FC		3	/**< Fibre Channel addresses */
57 58
 /** @} */
58 59
 
59 60
 /**

+ 4
- 1
src/net/fc.c View File

@@ -428,6 +428,7 @@ static struct io_buffer * fc_xchg_alloc_iob ( struct fc_exchange *xchg,
428 428
 static int fc_xchg_tx ( struct fc_exchange *xchg, struct io_buffer *iobuf,
429 429
 			struct xfer_metadata *meta ) {
430 430
 	struct fc_port *port = xchg->port;
431
+	struct sockaddr_fc *dest = ( ( struct sockaddr_fc * ) meta->dest );
431 432
 	struct fc_frame_header *fchdr;
432 433
 	unsigned int r_ctl;
433 434
 	unsigned int f_ctl_es;
@@ -484,7 +485,9 @@ static int fc_xchg_tx ( struct fc_exchange *xchg, struct io_buffer *iobuf,
484 485
 	fchdr = iob_push ( iobuf, sizeof ( *fchdr ) );
485 486
 	memset ( fchdr, 0, sizeof ( *fchdr ) );
486 487
 	fchdr->r_ctl = r_ctl;
487
-	memcpy ( &fchdr->d_id, &xchg->peer_port_id, sizeof ( fchdr->d_id ) );
488
+	memcpy ( &fchdr->d_id,
489
+		 ( dest ? &dest->sfc_port_id : &xchg->peer_port_id ),
490
+		 sizeof ( fchdr->d_id ) );
488 491
 	memcpy ( &fchdr->s_id, &port->port_id, sizeof ( fchdr->s_id ) );
489 492
 	fchdr->type = xchg->type;
490 493
 	fchdr->f_ctl_es = f_ctl_es;

+ 23
- 4
src/net/fcels.c View File

@@ -119,15 +119,26 @@ static struct fc_els_handler * fc_els_detect ( struct fc_els *els,
119 119
  * @ret rc		Return status code
120 120
  */
121 121
 int fc_els_tx ( struct fc_els *els, const void *data, size_t len ) {
122
-	struct xfer_metadata meta = {
123
-		.flags = ( fc_els_is_request ( els ) ?
124
-			   XFER_FL_OVER : ( XFER_FL_RESPONSE | XFER_FL_OUT ) ),
125
-	};
122
+	union {
123
+		struct sockaddr sa;
124
+		struct sockaddr_fc fc;
125
+	} dest;
126
+	struct xfer_metadata meta;
126 127
 	int rc;
127 128
 
128 129
 	DBGC2 ( els, FCELS_FMT " transmitting:\n", FCELS_ARGS ( els ) );
129 130
 	DBGC2_HDA ( els, 0, data, len );
130 131
 
132
+	/* Construct metadata */
133
+	memset ( &dest, 0, sizeof ( dest ) );
134
+	dest.fc.sfc_family = AF_FC;
135
+	memcpy ( &dest.fc.sfc_port_id, &els->peer_port_id,
136
+		 sizeof ( dest.fc.sfc_port_id ) );
137
+	memset ( &meta, 0, sizeof ( meta ) );
138
+	meta.flags = ( fc_els_is_request ( els ) ?
139
+		       XFER_FL_OVER : ( XFER_FL_RESPONSE | XFER_FL_OUT ) );
140
+	meta.dest = &dest.sa;
141
+
131 142
 	/* Transmit frame */
132 143
 	if ( ( rc = xfer_deliver_raw_meta ( &els->xchg, data, len,
133 144
 					    &meta ) ) != 0 ) {
@@ -524,6 +535,14 @@ static int fc_els_flogi_rx ( struct fc_els *els, const void *data,
524 535
 		return rc;
525 536
 	}
526 537
 
538
+	/* Send any responses to the newly-assigned peer port ID, if
539
+	 * applicable.
540
+	 */
541
+	if ( ! has_fabric ) {
542
+		memcpy ( &els->peer_port_id, &els->port->ptp_link_port_id,
543
+			 sizeof ( els->peer_port_id ) );
544
+	}
545
+
527 546
 	return 0;
528 547
 }
529 548
 

Loading…
Cancel
Save