소스 검색

[fcoe] Request SPMA iff FIP advertisement indicates support for SPMA

We currently set both the FP and SP bits in our FIP FLOGI, to allow
the FCF the choice of selecting either a fabric-provided or a server-
provided MAC address.  This complies with the FCoE specification, but
has been observed to result in an FLOGI rejection from some FCFs.

Fix by recording whether or not the FCF supports SPMA, and requesting
only one of FPMA or SPMA in our FIP FLOGI.  We choose to prefer SPMA
where available, because many iPXE drivers will not be able to receive
unicast packets sent to a non-default MAC address.

Reported-by: Hadar Hen Zion <hadarh@mellanox.co.il>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 14 년 전
부모
커밋
a9c799250f
1개의 변경된 파일18개의 추가작업 그리고 5개의 파일을 삭제
  1. 18
    5
      src/net/fcoe.c

+ 18
- 5
src/net/fcoe.c 파일 보기

@@ -101,6 +101,8 @@ enum fcoe_flags {
101 101
 	FCOE_HAVE_FCF = 0x0002,
102 102
 	/** We have a FIP-capable FCoE forwarder available to be used */
103 103
 	FCOE_HAVE_FIP_FCF = 0x0004,
104
+	/** FCoE forwarder supports server-provided MAC addresses */
105
+	FCOE_FCF_ALLOWS_SPMA = 0x0008,
104 106
 };
105 107
 
106 108
 struct net_protocol fcoe_protocol __net_protocol;
@@ -228,8 +230,10 @@ static int fcoe_deliver ( struct fcoe_port *fcoe,
228 230
 		memset ( fipmac, 0, sizeof ( *fipmac ) );
229 231
 		fipmac->type = FIP_MAC_ADDRESS;
230 232
 		fipmac->len = ( sizeof ( *fipmac ) / 4 );
231
-		memcpy ( fipmac->mac, fcoe->netdev->ll_addr,
232
-			 sizeof ( fipmac->mac ) );
233
+		if ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) {
234
+			memcpy ( fipmac->mac, fcoe->netdev->ll_addr,
235
+				 sizeof ( fipmac->mac ) );
236
+		}
233 237
 
234 238
 		/* Create FIP header */
235 239
 		fiphdr = iob_push ( iobuf, sizeof ( *fiphdr ) );
@@ -239,7 +243,8 @@ static int fcoe_deliver ( struct fcoe_port *fcoe,
239 243
 		fiphdr->subcode = FIP_ELS_REQUEST;
240 244
 		fiphdr->len =
241 245
 			htons ( ( iob_len ( iobuf ) - sizeof ( *fiphdr ) ) / 4);
242
-		fiphdr->flags = htons ( FIP_FP | FIP_SP );
246
+		fiphdr->flags = ( ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) ?
247
+				  htons ( FIP_SP ) : htons ( FIP_FP ) );
243 248
 
244 249
 		/* Send as FIP packet from netdev's own MAC address */
245 250
 		net_protocol = &fip_protocol;
@@ -636,17 +641,23 @@ static int fcoe_fip_rx_advertisement ( struct fcoe_port *fcoe,
636 641
 			} else {
637 642
 				fcoe->keepalive = ntohl ( fka_adv_p->period );
638 643
 			}
644
+			fcoe->flags &= ~FCOE_FCF_ALLOWS_SPMA;
645
+			if ( flags & FIP_SP )
646
+				fcoe->flags |= FCOE_FCF_ALLOWS_SPMA;
639 647
 			memcpy ( fcoe->fcf_mac, mac_address->mac,
640 648
 				 sizeof ( fcoe->fcf_mac ) );
641 649
 			DBGC ( fcoe, "FCoE %s selected FCF %s (priority %d, ",
642 650
 			       fcoe->netdev->name, eth_ntoa ( fcoe->fcf_mac ),
643 651
 			       fcoe->priority );
644 652
 			if ( fcoe->keepalive ) {
645
-				DBGC ( fcoe, "keepalive %dms)\n",
653
+				DBGC ( fcoe, "keepalive %dms",
646 654
 				       fcoe->keepalive );
647 655
 			} else {
648
-				DBGC ( fcoe, "no keepalive)\n" );
656
+				DBGC ( fcoe, "no keepalive" );
649 657
 			}
658
+			DBGC ( fcoe, ", %cPMA)\n",
659
+			       ( ( fcoe->flags & FCOE_FCF_ALLOWS_SPMA ) ?
660
+				 'S' : 'F' ) );
650 661
 		}
651 662
 
652 663
 	} else if ( fcoe->flags & FCOE_HAVE_FIP_FCF ) {
@@ -704,6 +715,8 @@ static int fcoe_fip_rx_els_response ( struct fcoe_port *fcoe,
704 715
 
705 716
 	/* Record local MAC address */
706 717
 	memcpy ( fcoe->local_mac, mac_address->mac, sizeof ( fcoe->local_mac ));
718
+	DBGC ( fcoe, "FCoE %s using local MAC %s\n",
719
+	       fcoe->netdev->name, eth_ntoa ( fcoe->local_mac ) );
707 720
 
708 721
 	/* Hand off via transport interface */
709 722
 	frame = &flogi->fc;

Loading…
취소
저장