Browse Source

[netdevice] Allow the hardware and link-layer addresses to differ in size

IPoIB has a 20-byte link-layer address, of which only eight bytes
represent anything relating to a "hardware address".

The PXE and EFI SNP APIs expect the permanent address to be the same
size as the link-layer address, so fill in the "permanent address"
field with the initial link layer address (as generated by
register_netdev() based upon the real hardware address).
tags/v0.9.8
Michael Brown 15 years ago
parent
commit
4eab5bc8ca

+ 6
- 4
src/arch/i386/interface/pxe/pxe_undi.c View File

412
 					  *undi_get_information ) {
412
 					  *undi_get_information ) {
413
 	struct device *dev = pxe_netdev->dev;
413
 	struct device *dev = pxe_netdev->dev;
414
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
414
 	struct ll_protocol *ll_protocol = pxe_netdev->ll_protocol;
415
+	size_t ll_addr_len = ll_protocol->ll_addr_len;
415
 
416
 
416
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
417
 	DBG ( "PXENV_UNDI_GET_INFORMATION" );
417
 
418
 
420
 	/* Cheat: assume all cards can cope with this */
421
 	/* Cheat: assume all cards can cope with this */
421
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
422
 	undi_get_information->MaxTranUnit = ETH_MAX_MTU;
422
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
423
 	undi_get_information->HwType = ntohs ( ll_protocol->ll_proto );
423
-	undi_get_information->HwAddrLen = ll_protocol->ll_addr_len;
424
+	undi_get_information->HwAddrLen = ll_addr_len;
425
+	assert ( ll_addr_len <=
426
+		 sizeof ( undi_get_information->CurrentNodeAddress ) );
424
 	memcpy ( &undi_get_information->CurrentNodeAddress,
427
 	memcpy ( &undi_get_information->CurrentNodeAddress,
425
 		 pxe_netdev->ll_addr,
428
 		 pxe_netdev->ll_addr,
426
 		 sizeof ( undi_get_information->CurrentNodeAddress ) );
429
 		 sizeof ( undi_get_information->CurrentNodeAddress ) );
427
-	memcpy ( &undi_get_information->PermNodeAddress,
428
-		 pxe_netdev->hw_addr,
429
-		 sizeof ( undi_get_information->PermNodeAddress ) );
430
+	ll_protocol->init_addr ( pxe_netdev->hw_addr,
431
+				 &undi_get_information->PermNodeAddress );
430
 	undi_get_information->ROMAddress = 0;
432
 	undi_get_information->ROMAddress = 0;
431
 		/* nic.rom_info->rom_segment; */
433
 		/* nic.rom_info->rom_segment; */
432
 	/* We only provide the ability to receive or transmit a single
434
 	/* We only provide the ability to receive or transmit a single

+ 19
- 5
src/drivers/net/ipoib.c View File

250
 }
250
 }
251
 
251
 
252
 /**
252
 /**
253
- * Transcribe IPoIB address
253
+ * Initialise IPoIB link-layer address
254
+ *
255
+ * @v hw_addr		Hardware address
256
+ * @v ll_addr		Link-layer address
257
+ */
258
+static void ipoib_init_addr ( const void *hw_addr, void *ll_addr ) {
259
+	const struct ib_gid_half *guid = hw_addr;
260
+	struct ipoib_mac *mac = ll_addr;
261
+
262
+	memset ( mac, 0, sizeof ( *mac ) );
263
+	memcpy ( &mac->gid.u.half[1], guid, sizeof ( mac->gid.u.half[1] ) );
264
+}
265
+
266
+/**
267
+ * Transcribe IPoIB link-layer address
254
  *
268
  *
255
  * @v ll_addr	Link-layer address
269
  * @v ll_addr	Link-layer address
256
  * @ret string	Link-layer address in human-readable format
270
  * @ret string	Link-layer address in human-readable format
286
 struct ll_protocol ipoib_protocol __ll_protocol = {
300
 struct ll_protocol ipoib_protocol __ll_protocol = {
287
 	.name		= "IPoIB",
301
 	.name		= "IPoIB",
288
 	.ll_proto	= htons ( ARPHRD_INFINIBAND ),
302
 	.ll_proto	= htons ( ARPHRD_INFINIBAND ),
303
+	.hw_addr_len	= sizeof ( struct ib_gid_half ),
289
 	.ll_addr_len	= IPOIB_ALEN,
304
 	.ll_addr_len	= IPOIB_ALEN,
290
 	.ll_header_len	= IPOIB_HLEN,
305
 	.ll_header_len	= IPOIB_HLEN,
291
 	.push		= ipoib_push,
306
 	.push		= ipoib_push,
292
 	.pull		= ipoib_pull,
307
 	.pull		= ipoib_pull,
308
+	.init_addr	= ipoib_init_addr,
293
 	.ntoa		= ipoib_ntoa,
309
 	.ntoa		= ipoib_ntoa,
294
 	.mc_hash	= ipoib_mc_hash,
310
 	.mc_hash	= ipoib_mc_hash,
295
 };
311
 };
653
 int ipoib_probe ( struct ib_device *ibdev ) {
669
 int ipoib_probe ( struct ib_device *ibdev ) {
654
 	struct net_device *netdev;
670
 	struct net_device *netdev;
655
 	struct ipoib_device *ipoib;
671
 	struct ipoib_device *ipoib;
656
-	struct ipoib_mac *mac;
657
 	int rc;
672
 	int rc;
658
 
673
 
659
 	/* Allocate network device */
674
 	/* Allocate network device */
669
 	ipoib->ibdev = ibdev;
684
 	ipoib->ibdev = ibdev;
670
 
685
 
671
 	/* Extract hardware address */
686
 	/* Extract hardware address */
672
-	mac = ( ( struct ipoib_mac * ) netdev->hw_addr );
673
-	memcpy ( &mac->gid.u.half[1], &ibdev->gid.u.half[1],
674
-		 sizeof ( mac->gid.u.half[1] ) );
687
+	memcpy ( netdev->hw_addr, &ibdev->gid.u.half[1],
688
+		 sizeof ( ibdev->gid.u.half[1] ) );
675
 
689
 
676
 	/* Set default broadcast address */
690
 	/* Set default broadcast address */
677
 	memcpy ( &ipoib->broadcast, &ipoib_broadcast,
691
 	memcpy ( &ipoib->broadcast, &ipoib_broadcast,

+ 1
- 0
src/include/gpxe/ethernet.h View File

11
 
11
 
12
 #include <stdint.h>
12
 #include <stdint.h>
13
 
13
 
14
+extern void eth_init_addr ( const void *hw_addr, void *ll_addr );
14
 extern const char * eth_ntoa ( const void *ll_addr );
15
 extern const char * eth_ntoa ( const void *ll_addr );
15
 extern struct net_device * alloc_etherdev ( size_t priv_size );
16
 extern struct net_device * alloc_etherdev ( size_t priv_size );
16
 
17
 

+ 20
- 2
src/include/gpxe/netdevice.h View File

21
 struct ll_protocol;
21
 struct ll_protocol;
22
 struct device;
22
 struct device;
23
 
23
 
24
+/** Maximum length of a hardware address
25
+ *
26
+ * The longest currently-supported link-layer address is for IPoIB.
27
+ */
28
+#define MAX_HW_ADDR_LEN 8
29
+
24
 /** Maximum length of a link-layer address
30
 /** Maximum length of a link-layer address
25
  *
31
  *
26
  * The longest currently-supported link-layer address is for IPoIB.
32
  * The longest currently-supported link-layer address is for IPoIB.
112
 	int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf,
118
 	int ( * pull ) ( struct net_device *netdev, struct io_buffer *iobuf,
113
 			 const void **ll_dest, const void **ll_source,
119
 			 const void **ll_dest, const void **ll_source,
114
 			 uint16_t *net_proto );
120
 			 uint16_t *net_proto );
121
+	/**
122
+	 * Initialise link-layer address
123
+	 *
124
+	 * @v hw_addr		Hardware address
125
+	 * @v ll_addr		Link-layer address to fill in
126
+	 */
127
+	void ( * init_addr ) ( const void *hw_addr, void *ll_addr );
115
 	/**
128
 	/**
116
 	 * Transcribe link-layer address
129
 	 * Transcribe link-layer address
117
 	 *
130
 	 *
124
 	 * The buffer used to hold the transcription is statically
137
 	 * The buffer used to hold the transcription is statically
125
 	 * allocated.
138
 	 * allocated.
126
 	 */
139
 	 */
127
-	const char * ( * ntoa ) ( const void * ll_addr );
140
+	const char * ( * ntoa ) ( const void *ll_addr );
128
 	/**
141
 	/**
129
 	 * Hash multicast address
142
 	 * Hash multicast address
130
 	 *
143
 	 *
140
 	 * This is an ARPHRD_XXX constant, in network byte order.
153
 	 * This is an ARPHRD_XXX constant, in network byte order.
141
 	 */
154
 	 */
142
 	uint16_t ll_proto;
155
 	uint16_t ll_proto;
156
+	/** Hardware address length */
157
+	uint8_t hw_addr_len;
143
 	/** Link-layer address length */
158
 	/** Link-layer address length */
144
 	uint8_t ll_addr_len;
159
 	uint8_t ll_addr_len;
145
 	/** Link-layer header length */
160
 	/** Link-layer header length */
258
 	 *
273
 	 *
259
 	 * This is an address which is an intrinsic property of the
274
 	 * This is an address which is an intrinsic property of the
260
 	 * hardware, e.g. an address held in EEPROM.
275
 	 * hardware, e.g. an address held in EEPROM.
276
+	 *
277
+	 * Note that the hardware address may not be the same length
278
+	 * as the link-layer address.
261
 	 */
279
 	 */
262
-	uint8_t hw_addr[MAX_LL_ADDR_LEN];
280
+	uint8_t hw_addr[MAX_HW_ADDR_LEN];
263
 	/** Link-layer address
281
 	/** Link-layer address
264
 	 *
282
 	 *
265
 	 * This is the current link-layer address assigned to the
283
 	 * This is the current link-layer address assigned to the

+ 5
- 4
src/interface/efi/efi_snp.c View File

119
 static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
119
 static void efi_snp_set_mode ( struct efi_snp_device *snpdev ) {
120
 	struct net_device *netdev = snpdev->netdev;
120
 	struct net_device *netdev = snpdev->netdev;
121
 	EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
121
 	EFI_SIMPLE_NETWORK_MODE *mode = &snpdev->mode;
122
-	unsigned int ll_addr_len = netdev->ll_protocol->ll_addr_len;
122
+	struct ll_protocol *ll_protocol = netdev->ll_protocol;
123
+	unsigned int ll_addr_len = ll_protocol->ll_addr_len;
123
 
124
 
124
 	mode->HwAddressSize = ll_addr_len;
125
 	mode->HwAddressSize = ll_addr_len;
125
-	mode->MediaHeaderSize = netdev->ll_protocol->ll_header_len;
126
+	mode->MediaHeaderSize = ll_protocol->ll_header_len;
126
 	mode->MaxPacketSize = netdev->max_pkt_len;
127
 	mode->MaxPacketSize = netdev->max_pkt_len;
127
 	mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
128
 	mode->ReceiveFilterMask = ( EFI_SIMPLE_NETWORK_RECEIVE_UNICAST |
128
 				    EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
129
 				    EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST |
130
 	assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
131
 	assert ( ll_addr_len <= sizeof ( mode->CurrentAddress ) );
131
 	memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
132
 	memcpy ( &mode->CurrentAddress, netdev->ll_addr, ll_addr_len );
132
 	memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
133
 	memcpy ( &mode->BroadcastAddress, netdev->ll_broadcast, ll_addr_len );
133
-	memcpy ( &mode->PermanentAddress, netdev->hw_addr, ll_addr_len );
134
-	mode->IfType = ntohs ( netdev->ll_protocol->ll_proto );
134
+	ll_protocol->init_addr ( netdev->hw_addr, &mode->PermanentAddress );
135
+	mode->IfType = ntohs ( ll_protocol->ll_proto );
135
 	mode->MacAddressChangeable = TRUE;
136
 	mode->MacAddressChangeable = TRUE;
136
 	mode->MediaPresentSupported = TRUE;
137
 	mode->MediaPresentSupported = TRUE;
137
 	mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );
138
 	mode->MediaPresent = ( netdev_link_ok ( netdev ) ? TRUE : FALSE );

+ 2
- 0
src/net/80211/net80211.c View File

602
 	.name = "802.11",
602
 	.name = "802.11",
603
 	.push = net80211_ll_push,
603
 	.push = net80211_ll_push,
604
 	.pull = net80211_ll_pull,
604
 	.pull = net80211_ll_pull,
605
+	.init_addr = eth_init_addr,
605
 	.ntoa = eth_ntoa,
606
 	.ntoa = eth_ntoa,
606
 	.mc_hash = net80211_ll_mc_hash,
607
 	.mc_hash = net80211_ll_mc_hash,
607
 	.ll_proto = htons ( ARPHRD_ETHER ),	/* "encapsulated Ethernet" */
608
 	.ll_proto = htons ( ARPHRD_ETHER ),	/* "encapsulated Ethernet" */
609
+	.hw_addr_len = ETH_ALEN,
608
 	.ll_addr_len = ETH_ALEN,
610
 	.ll_addr_len = ETH_ALEN,
609
 	.ll_header_len = IEEE80211_TYP_FRAME_HEADER_LEN +
611
 	.ll_header_len = IEEE80211_TYP_FRAME_HEADER_LEN +
610
 				IEEE80211_LLC_HEADER_LEN,
612
 				IEEE80211_LLC_HEADER_LEN,

+ 12
- 0
src/net/ethernet.c View File

96
 	return 0;
96
 	return 0;
97
 }
97
 }
98
 
98
 
99
+/**
100
+ * Initialise Ethernet address
101
+ *
102
+ * @v hw_addr		Hardware address
103
+ * @v ll_addr		Link-layer address
104
+ */
105
+void eth_init_addr ( const void *hw_addr, void *ll_addr ) {
106
+	memcpy ( ll_addr, hw_addr, ETH_ALEN );
107
+}
108
+
99
 /**
109
 /**
100
  * Transcribe Ethernet address
110
  * Transcribe Ethernet address
101
  *
111
  *
143
 struct ll_protocol ethernet_protocol __ll_protocol = {
153
 struct ll_protocol ethernet_protocol __ll_protocol = {
144
 	.name		= "Ethernet",
154
 	.name		= "Ethernet",
145
 	.ll_proto	= htons ( ARPHRD_ETHER ),
155
 	.ll_proto	= htons ( ARPHRD_ETHER ),
156
+	.hw_addr_len	= ETH_ALEN,
146
 	.ll_addr_len	= ETH_ALEN,
157
 	.ll_addr_len	= ETH_ALEN,
147
 	.ll_header_len	= ETH_HLEN,
158
 	.ll_header_len	= ETH_HLEN,
148
 	.push		= eth_push,
159
 	.push		= eth_push,
149
 	.pull		= eth_pull,
160
 	.pull		= eth_pull,
161
+	.init_addr	= eth_init_addr,
150
 	.ntoa		= eth_ntoa,
162
 	.ntoa		= eth_ntoa,
151
 	.mc_hash	= eth_mc_hash,
163
 	.mc_hash	= eth_mc_hash,
152
 };
164
 };

+ 1
- 2
src/net/netdevice.c View File

358
 		   ifindex++ );
358
 		   ifindex++ );
359
 
359
 
360
 	/* Set initial link-layer address */
360
 	/* Set initial link-layer address */
361
-	memcpy ( netdev->ll_addr, netdev->hw_addr,
362
-		 netdev->ll_protocol->ll_addr_len );
361
+	netdev->ll_protocol->init_addr ( netdev->hw_addr, netdev->ll_addr );
363
 
362
 
364
 	/* Register per-netdev configuration settings */
363
 	/* Register per-netdev configuration settings */
365
 	if ( ( rc = register_settings ( netdev_settings ( netdev ),
364
 	if ( ( rc = register_settings ( netdev_settings ( netdev ),

Loading…
Cancel
Save