Parcourir la source

[netdevice] Split multicast hashing out into an mc_hash method

Multicast hashing is an ugly overlap between network and link layers.
EFI requires us to provide access to this functionality, so move it
out of ipv4.c and expose it as a method of the link layer.
tags/v0.9.6
Michael Brown il y a 16 ans
Parent
révision
6b9cc25556
4 fichiers modifiés avec 57 ajouts et 14 suppressions
  1. 16
    0
      src/drivers/net/ipoib.c
  2. 10
    0
      src/include/gpxe/netdevice.h
  3. 30
    2
      src/net/ethernet.c
  4. 1
    12
      src/net/ipv4.c

+ 16
- 0
src/drivers/net/ipoib.c Voir le fichier

@@ -222,6 +222,21 @@ const char * ipoib_ntoa ( const void *ll_addr ) {
222 222
 	return buf;
223 223
 }
224 224
 
225
+/**
226
+ * Hash multicast address
227
+ *
228
+ * @v af		Address family
229
+ * @v net_addr		Network-layer address
230
+ * @v ll_addr		Link-layer address to fill in
231
+ * @ret rc		Return status code
232
+ */
233
+static int ipoib_mc_hash ( unsigned int af __unused,
234
+			   const void *net_addr __unused,
235
+			   void *ll_addr __unused ) {
236
+
237
+	return -ENOTSUP;
238
+}
239
+
225 240
 /** IPoIB protocol */
226 241
 struct ll_protocol ipoib_protocol __ll_protocol = {
227 242
 	.name		= "IPoIB",
@@ -232,6 +247,7 @@ struct ll_protocol ipoib_protocol __ll_protocol = {
232 247
 	.push		= ipoib_push,
233 248
 	.pull		= ipoib_pull,
234 249
 	.ntoa		= ipoib_ntoa,
250
+	.mc_hash	= ipoib_mc_hash,
235 251
 };
236 252
 
237 253
 /****************************************************************************

+ 10
- 0
src/include/gpxe/netdevice.h Voir le fichier

@@ -120,6 +120,16 @@ struct ll_protocol {
120 120
 	 * allocated.
121 121
 	 */
122 122
 	const char * ( * ntoa ) ( const void * ll_addr );
123
+	/**
124
+	 * Hash multicast address
125
+	 *
126
+	 * @v af	Address family
127
+	 * @v net_addr	Network-layer address
128
+	 * @v ll_addr	Link-layer address to fill in
129
+	 * @ret rc	Return status code
130
+	 */
131
+	int ( * mc_hash ) ( unsigned int af, const void *net_addr,
132
+			    void *ll_addr );
123 133
 	/** Link-layer protocol
124 134
 	 *
125 135
 	 * This is an ARPHRD_XXX constant, in network byte order.

+ 30
- 2
src/net/ethernet.c Voir le fichier

@@ -24,6 +24,7 @@
24 24
 #include <assert.h>
25 25
 #include <gpxe/if_arp.h>
26 26
 #include <gpxe/if_ether.h>
27
+#include <gpxe/in.h>
27 28
 #include <gpxe/netdevice.h>
28 29
 #include <gpxe/iobuf.h>
29 30
 #include <gpxe/ethernet.h>
@@ -92,8 +93,8 @@ static int eth_pull ( struct io_buffer *iobuf,
92 93
 /**
93 94
  * Transcribe Ethernet address
94 95
  *
95
- * @v ll_addr	Link-layer address
96
- * @ret string	Link-layer address in human-readable format
96
+ * @v ll_addr		Link-layer address
97
+ * @ret string		Link-layer address in human-readable format
97 98
  */
98 99
 const char * eth_ntoa ( const void *ll_addr ) {
99 100
 	static char buf[18]; /* "00:00:00:00:00:00" */
@@ -105,6 +106,32 @@ const char * eth_ntoa ( const void *ll_addr ) {
105 106
 	return buf;
106 107
 }
107 108
 
109
+/**
110
+ * Hash multicast address
111
+ *
112
+ * @v af		Address family
113
+ * @v net_addr		Network-layer address
114
+ * @v ll_addr		Link-layer address to fill in
115
+ * @ret rc		Return status code
116
+ */
117
+static int eth_mc_hash ( unsigned int af, const void *net_addr,
118
+			 void *ll_addr ) {
119
+	const uint8_t *net_addr_bytes = net_addr;
120
+	uint8_t *ll_addr_bytes = ll_addr;
121
+
122
+	switch ( af ) {
123
+	case AF_INET:
124
+		ll_addr_bytes[0] = 0x01;
125
+		ll_addr_bytes[1] = 0x00;
126
+		ll_addr_bytes[2] = 0x5e;
127
+		ll_addr_bytes[3] = net_addr_bytes[1] & 0x7f;
128
+		ll_addr_bytes[4] = net_addr_bytes[2];
129
+		ll_addr_bytes[5] = net_addr_bytes[3];
130
+	default:
131
+		return -ENOTSUP;
132
+	}
133
+}
134
+
108 135
 /** Ethernet protocol */
109 136
 struct ll_protocol ethernet_protocol __ll_protocol = {
110 137
 	.name		= "Ethernet",
@@ -115,4 +142,5 @@ struct ll_protocol ethernet_protocol __ll_protocol = {
115 142
 	.push		= eth_push,
116 143
 	.pull		= eth_pull,
117 144
 	.ntoa		= eth_ntoa,
145
+	.mc_hash	= eth_mc_hash,
118 146
 };

+ 1
- 12
src/net/ipv4.c Voir le fichier

@@ -266,7 +266,6 @@ static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) {
266 266
 static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
267 267
 			  struct net_device *netdev, uint8_t *ll_dest ) {
268 268
 	struct ll_protocol *ll_protocol = netdev->ll_protocol;
269
-	uint8_t *dest_bytes = ( ( uint8_t * ) &dest );
270 269
 
271 270
 	if ( dest.s_addr == INADDR_BROADCAST ) {
272 271
 		/* Broadcast address */
@@ -274,17 +273,7 @@ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
274 273
 			 ll_protocol->ll_addr_len );
275 274
 		return 0;
276 275
 	} else if ( IN_MULTICAST ( ntohl ( dest.s_addr ) ) ) {
277
-		/* Special case: IPv4 multicast over Ethernet.	This
278
-		 * code may need to be generalised once we find out
279
-		 * what happens for other link layers.
280
-		 */
281
-		ll_dest[0] = 0x01;
282
-		ll_dest[1] = 0x00;
283
-		ll_dest[2] = 0x5e;
284
-		ll_dest[3] = dest_bytes[1] & 0x7f;
285
-		ll_dest[4] = dest_bytes[2];
286
-		ll_dest[5] = dest_bytes[3];
287
-		return 0;
276
+		return ll_protocol->mc_hash ( AF_INET, &dest, ll_dest );
288 277
 	} else {
289 278
 		/* Unicast address: resolve via ARP */
290 279
 		return arp_resolve ( netdev, &ipv4_protocol, &dest,

Chargement…
Annuler
Enregistrer