ソースを参照

Simplify TX datapath.

tags/v0.9.3
Michael Brown 18年前
コミット
bbd9e28061
9個のファイルの変更268行の追加445行の削除
  1. 5
    4
      src/include/gpxe/arp.h
  2. 6
    0
      src/include/gpxe/ip.h
  3. 36
    71
      src/include/gpxe/netdevice.h
  4. 4
    29
      src/net/aoe.c
  5. 21
    44
      src/net/arp.c
  6. 23
    71
      src/net/ethernet.c
  7. 125
    140
      src/net/ipv4.c
  8. 46
    83
      src/net/netdevice.c
  9. 2
    3
      src/net/tcp.c

+ 5
- 4
src/include/gpxe/arp.h ファイルの表示

@@ -8,11 +8,12 @@
8 8
  */
9 9
 
10 10
 struct net_device;
11
-struct net_header;
12
-struct ll_header;
11
+struct net_protocol;
13 12
 
14 13
 extern int arp_resolve ( struct net_device *netdev,
15
-			 const struct net_header *nethdr,
16
-			 struct ll_header *llhdr );
14
+			 struct net_protocol *net_protocol,
15
+			 const void *dest_net_addr,
16
+			 const void *source_net_addr,
17
+			 void *dest_ll_addr );
17 18
 
18 19
 #endif /* _GPXE_ARP_H */

+ 6
- 0
src/include/gpxe/ip.h ファイルの表示

@@ -11,4 +11,10 @@ struct net_protocol;
11 11
 
12 12
 extern struct net_protocol ipv4_protocol;
13 13
 
14
+extern int add_ipv4_address ( struct net_device *netdev,
15
+			      struct in_addr address, struct in_addr netmask,
16
+			      struct in_addr gateway );
17
+extern void del_ipv4_address ( struct net_device *netdev );
18
+extern int ipv4_uip_transmit ( struct pk_buff *pkb );
19
+
14 20
 #endif /* _GPXE_IP_H */

+ 36
- 71
src/include/gpxe/netdevice.h ファイルの表示

@@ -86,22 +86,6 @@ struct ll_header {
86 86
 struct net_protocol {
87 87
 	/** Protocol name */
88 88
 	const char *name;
89
-	/**
90
-	 * Perform network-layer routing
91
-	 *
92
-	 * @v pkb	Packet buffer
93
-	 * @v nethdr	Generic network-layer header
94
-	 * @ret rc	Return status code
95
-	 *
96
-	 * This method should fill in the network header with enough
97
-	 * information to allow the link layer to route the packet.
98
-	 *
99
-	 * For example, in the case of IPv4, this method should fill
100
-	 * in the IP addresses of the local adapter and the next hop
101
-	 * destination (e.g. the gateway).
102
-	 */
103
-	int ( * route ) ( const struct pk_buff *pkb,
104
-			  struct net_header *nethdr );
105 89
 	/**
106 90
 	 * Process received packet
107 91
 	 *
@@ -141,36 +125,21 @@ struct ll_protocol {
141 125
 	/** Protocol name */
142 126
 	const char *name;
143 127
 	/**
144
-	 * Perform link-layer routing
145
-	 *
146
-	 * @v netdev	Network device
147
-	 * @v nethdr	Generic network-layer header
148
-	 * @ret llhdr	Generic link-layer header
149
-	 * @ret rc	Return status code
128
+	 * Transmit network-layer packet via network device
150 129
 	 *
151
-	 * This method should construct the generic link-layer header
152
-	 * based on the generic network-layer header.
153 130
 	 *
154
-	 * If a link-layer header cannot be constructed (e.g. because
155
-	 * of a missing ARP cache entry), then this method should
156
-	 * return an error (after transmitting an ARP request, if
157
-	 * applicable).
158
-	 */
159
-	int ( * route ) ( struct net_device *netdev,
160
-			  const struct net_header *nethdr,
161
-			  struct ll_header *llhdr );
162
-	/**
163
-	 * Fill media-specific link-layer header
164
-	 *
165
-	 * @v llhdr	Generic link-layer header
166
-	 * @v pkb	Packet buffer
131
+	 * @v pkb		Packet buffer
132
+	 * @v netdev		Network device
133
+	 * @v net_protocol	Network-layer protocol
134
+	 * @v ll_dest		Link-layer destination address
135
+	 * @ret rc		Return status code
167 136
 	 *
168
-	 * This method should fill in the link-layer header in the
169
-	 * packet buffer based on information in the generic
170
-	 * link-layer header.
137
+	 * This method should prepend in the link-layer header
138
+	 * (e.g. the Ethernet DIX header) and transmit the packet.
171 139
 	 */
172
-	void ( * fill_llh ) ( const struct ll_header *llhdr,
173
-			      struct pk_buff *pkb );
140
+	int ( * transmit ) ( struct pk_buff *pkb, struct net_device *netdev,
141
+			     struct net_protocol *net_protocol,
142
+			     const void *ll_dest );
174 143
 	/**
175 144
 	 * Parse media-specific link-layer header
176 145
 	 *
@@ -204,8 +173,8 @@ struct ll_protocol {
204 173
 	uint16_t ll_proto;
205 174
 	/** Link-layer address length */
206 175
 	uint8_t ll_addr_len;
207
-	/** Link-layer header length */
208
-	uint8_t ll_header_len;
176
+	/** Link-layer broadcast address */
177
+	const uint8_t *ll_broadcast;
209 178
 };
210 179
 
211 180
 /**
@@ -288,31 +257,6 @@ extern struct net_device static_single_netdev;
288 257
 	static_single_netdev.priv = priv_data;	\
289 258
 	&static_single_netdev; } )
290 259
 
291
-/**
292
- * Register network device
293
- *
294
- * @v netdev		Network device
295
- * @ret rc		Return status code
296
- *
297
- * Adds the network device to the list of network devices.
298
- */
299
-static inline int
300
-register_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
301
-	return 0;
302
-}
303
-
304
-/**
305
- * Unregister network device
306
- *
307
- * @v netdev		Network device
308
- *
309
- * Removes the network device from the list of network devices.
310
- */
311
-static inline void 
312
-unregister_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
313
-	/* Nothing to do */
314
-}
315
-
316 260
 /**
317 261
  * Free network device
318 262
  *
@@ -339,6 +283,27 @@ static inline int netdev_transmit ( struct net_device *netdev,
339 283
 	return netdev->transmit ( netdev, pkb );
340 284
 }
341 285
 
286
+/**
287
+ * Transmit network-layer packet
288
+ *
289
+ * @v pkb		Packet buffer
290
+ * @v netdev		Network device
291
+ * @v net_protocol	Network-layer protocol
292
+ * @v ll_dest		Destination link-layer address
293
+ * @ret rc		Return status code
294
+ *
295
+ * Prepends link-layer headers to the packet buffer and transmits the
296
+ * packet via the specified network device.  This function takes
297
+ * ownership of the packet buffer.
298
+ */
299
+static inline int net_transmit ( struct pk_buff *pkb,
300
+				 struct net_device *netdev,
301
+				 struct net_protocol *net_protocol,
302
+				 const void *ll_dest ) {
303
+	return netdev->ll_protocol->transmit ( pkb, netdev, net_protocol,
304
+					       ll_dest );
305
+}
306
+
342 307
 /**
343 308
  * Register a link-layer protocol
344 309
  *
@@ -363,14 +328,14 @@ static inline int netdev_transmit ( struct net_device *netdev,
363 328
 #define STATIC_SINGLE_NETDEV_ADDRESS( address ) \
364 329
 	struct net_address address __table ( sgl_netdev_addresses, 01 )
365 330
 
331
+extern int register_netdev ( struct net_device *netdev );
332
+extern void unregister_netdev ( struct net_device *netdev );
366 333
 extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
367 334
 
368 335
 extern struct net_protocol *find_net_protocol ( uint16_t net_proto );
369 336
 extern struct net_device *
370 337
 find_netdev_by_net_addr ( struct net_protocol *net_protocol, void *net_addr );
371 338
 
372
-extern int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev );
373
-extern int net_transmit ( struct pk_buff *pkb );
374 339
 extern int net_poll ( void );
375 340
 extern struct pk_buff * net_rx_dequeue ( void );
376 341
 extern int net_rx_process ( struct pk_buff *pkb );

+ 4
- 29
src/net/aoe.c ファイルの表示

@@ -24,6 +24,7 @@
24 24
 #include <byteswap.h>
25 25
 #include <gpxe/list.h>
26 26
 #include <gpxe/if_ether.h>
27
+#include <gpxe/ethernet.h>
27 28
 #include <gpxe/pkbuff.h>
28 29
 #include <gpxe/uaccess.h>
29 30
 #include <gpxe/ata.h>
@@ -116,7 +117,7 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
116 117
 
117 118
 	/* Send packet */
118 119
 	start_timer ( &aoe->timer );
119
-	return net_transmit_via ( pkb, aoe->netdev );
120
+	return net_transmit ( pkb, aoe->netdev, &aoe_protocol, aoe->target );
120 121
 }
121 122
 
122 123
 /**
@@ -251,38 +252,11 @@ static int aoe_rx ( struct pk_buff *pkb ) {
251 252
 	return rc;
252 253
 }
253 254
 
254
-/**
255
- * Perform AoE network-layer routing
256
- *
257
- * @v pkb	Packet buffer
258
- * @ret source	Network-layer source address
259
- * @ret dest	Network-layer destination address
260
- * @ret rc	Return status code
261
- */
262
-static int aoe_route ( const struct pk_buff *pkb __unused,
263
-		       struct net_header *nethdr ) {
264
-	struct aoehdr *aoehdr = pkb->data;
265
-	struct aoe_session *aoe;
266
-
267
-	list_for_each_entry ( aoe, &aoe_sessions, list ) {
268
-		if ( ( ntohs ( aoehdr->major ) == aoe->major ) &&
269
-		     ( aoehdr->minor == aoe->minor ) ) {
270
-			nethdr->flags = PKT_FL_RAW_ADDR;
271
-			memcpy ( nethdr->dest_net_addr, aoe->target,
272
-				 sizeof ( aoe->target ) );
273
-			return 0;
274
-		}
275
-	}
276
-		
277
-	return -EHOSTUNREACH;
278
-}
279
-
280 255
 /** AoE protocol */
281 256
 struct net_protocol aoe_protocol = {
282 257
 	.name = "AoE",
283 258
 	.net_proto = htons ( ETH_P_AOE ),
284 259
 	.rx_process = aoe_rx,
285
-	.route = aoe_route,
286 260
 };
287 261
 
288 262
 NET_PROTOCOL ( aoe_protocol );
@@ -293,7 +267,8 @@ NET_PROTOCOL ( aoe_protocol );
293 267
  * @v aoe		AoE session
294 268
  */
295 269
 void aoe_open ( struct aoe_session *aoe ) {
296
-	memset ( aoe->target, 0xff, sizeof ( aoe->target ) );
270
+	memcpy ( aoe->target, ethernet_protocol.ll_broadcast,
271
+		 sizeof ( aoe->target ) );
297 272
 	aoe->tag = AOE_TAG_MAGIC;
298 273
 	aoe->timer.expired = aoe_timer_expired;
299 274
 	list_add ( &aoe->list, &aoe_sessions );

+ 21
- 44
src/net/arp.c ファイルの表示

@@ -92,42 +92,42 @@ arp_find_entry ( struct ll_protocol *ll_protocol,
92 92
  * Look up media-specific link-layer address in the ARP cache
93 93
  *
94 94
  * @v netdev		Network device
95
- * @v nethdr		Generic network-layer header
96
- * @ret llhdr		Generic link-layer header
95
+ * @v net_protocol	Network-layer protocol
96
+ * @v dest_net_addr	Destination network-layer address
97
+ * @v source_net_addr	Source network-layer address
98
+ * @ret dest_ll_addr	Destination link layer address
97 99
  * @ret rc		Return status code
98 100
  *
99 101
  * This function will use the ARP cache to look up the link-layer
100
- * address for the link-layer protocol specified in @c llhdr and the
101
- * network-layer protocol and address as specified in @c nethdr.  If
102
+ * address for the link-layer protocol associated with the network
103
+ * device and the given network-layer protocol and addresses.  If
102 104
  * found, the destination link-layer address will be filled in in @c
103
- * llhdr.
105
+ * dest_ll_addr.
104 106
  *
105 107
  * If no address is found in the ARP cache, an ARP request will be
106 108
  * transmitted on the specified network device and -ENOENT will be
107 109
  * returned.
108 110
  */
109
-int arp_resolve ( struct net_device *netdev, const struct net_header *nethdr,
110
-		  struct ll_header *llhdr ) {
111
-	struct net_protocol *net_protocol = nethdr->net_protocol;
112
-	struct ll_protocol *ll_protocol = llhdr->ll_protocol;
111
+int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol,
112
+		  const void *dest_net_addr, const void *source_net_addr,
113
+		  void *dest_ll_addr ) {
114
+	struct ll_protocol *ll_protocol = netdev->ll_protocol;
113 115
 	const struct arp_entry *arp;
114 116
 	struct pk_buff *pkb;
115 117
 	struct arphdr *arphdr;
116 118
 	int rc;
117 119
 
118 120
 	/* Look for existing entry in ARP table */
119
-	arp = arp_find_entry ( ll_protocol, net_protocol,
120
-			       nethdr->dest_net_addr );
121
+	arp = arp_find_entry ( ll_protocol, net_protocol, dest_net_addr );
121 122
 	if ( arp ) {
122 123
 		DBG ( "ARP cache hit: %s %s => %s %s\n",
123 124
 		      net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
124 125
 		      ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
125
-		memcpy ( llhdr->dest_ll_addr, arp->ll_addr,
126
-			 sizeof ( llhdr->dest_ll_addr ) );
126
+		memcpy ( dest_ll_addr, arp->ll_addr, ll_protocol->ll_addr_len);
127 127
 		return 0;
128 128
 	}
129 129
 	DBG ( "ARP cache miss: %s %s\n", net_protocol->name,
130
-	      net_protocol->ntoa ( nethdr->dest_net_addr ) );
130
+	      net_protocol->ntoa ( dest_net_addr ) );
131 131
 
132 132
 	/* Allocate ARP packet */
133 133
 	pkb = alloc_pkb ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
@@ -145,16 +145,17 @@ int arp_resolve ( struct net_device *netdev, const struct net_header *nethdr,
145 145
 	arphdr->ar_pln = net_protocol->net_addr_len;
146 146
 	arphdr->ar_op = htons ( ARPOP_REQUEST );
147 147
 	memcpy ( pkb_put ( pkb, ll_protocol->ll_addr_len ),
148
-		 llhdr->source_ll_addr, ll_protocol->ll_addr_len );
148
+		 netdev->ll_addr, ll_protocol->ll_addr_len );
149 149
 	memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ),
150
-		 nethdr->source_net_addr, net_protocol->net_addr_len );
150
+		 source_net_addr, net_protocol->net_addr_len );
151 151
 	memset ( pkb_put ( pkb, ll_protocol->ll_addr_len ),
152 152
 		 0, ll_protocol->ll_addr_len );
153 153
 	memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ),
154
-		 nethdr->dest_net_addr, net_protocol->net_addr_len );
154
+		 dest_net_addr, net_protocol->net_addr_len );
155 155
 
156 156
 	/* Transmit ARP request */
157
-	if ( ( rc = net_transmit_via ( pkb, netdev ) ) != 0 )
157
+	if ( ( rc = net_transmit ( pkb, netdev, &arp_protocol, 
158
+				   ll_protocol->ll_broadcast ) ) != 0 )
158 159
 		return rc;
159 160
 
160 161
 	return -ENOENT;
@@ -235,10 +236,10 @@ static int arp_rx ( struct pk_buff *pkb ) {
235 236
 	arphdr->ar_op = htons ( ARPOP_REPLY );
236 237
 	memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ),
237 238
 		 arphdr->ar_hln + arphdr->ar_pln );
238
-	memcpy ( arp_target_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
239
+	memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
239 240
 
240 241
 	/* Send reply */
241
-	net_transmit_via ( pkb, netdev );
242
+	net_transmit ( pkb, netdev, &arp_protocol, arp_target_ha (arphdr ) );
242 243
 	pkb = NULL;
243 244
 
244 245
  done:
@@ -246,29 +247,6 @@ static int arp_rx ( struct pk_buff *pkb ) {
246 247
 	return 0;
247 248
 }
248 249
 
249
-/**
250
- * Perform ARP network-layer routing
251
- *
252
- * @v pkb	Packet buffer
253
- * @ret source	Network-layer source address
254
- * @ret dest	Network-layer destination address
255
- * @ret rc	Return status code
256
- */
257
-static int arp_route ( const struct pk_buff *pkb,
258
-		       struct net_header *nethdr ) {
259
-	struct arphdr *arphdr = pkb->data;
260
-
261
-	memcpy ( nethdr->source_net_addr, arp_sender_ha ( arphdr ),
262
-		 arphdr->ar_hln );
263
-	memcpy ( nethdr->dest_net_addr, arp_target_ha ( arphdr ),
264
-		 arphdr->ar_hln );
265
-	nethdr->flags = PKT_FL_RAW_ADDR;
266
-	if ( arphdr->ar_op == htons ( ARPOP_REQUEST ) )
267
-		nethdr->flags |= PKT_FL_BROADCAST;
268
-	
269
-	return 0;
270
-}
271
-
272 250
 /**
273 251
  * Transcribe ARP address
274 252
  *
@@ -287,7 +265,6 @@ struct net_protocol arp_protocol = {
287 265
 	.name = "ARP",
288 266
 	.net_proto = htons ( ETH_P_ARP ),
289 267
 	.rx_process = arp_rx,
290
-	.route = arp_route,
291 268
 	.ntoa = arp_ntoa,
292 269
 };
293 270
 

+ 23
- 71
src/net/ethernet.c ファイルの表示

@@ -25,7 +25,6 @@
25 25
 #include <gpxe/if_ether.h>
26 26
 #include <gpxe/netdevice.h>
27 27
 #include <gpxe/pkbuff.h>
28
-#include <gpxe/arp.h>
29 28
 #include <gpxe/ethernet.h>
30 29
 
31 30
 /** @file
@@ -38,70 +37,24 @@
38 37
 static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
39 38
 
40 39
 /**
41
- * Perform Ethernet routing
40
+ * Transmit Ethernet packet
42 41
  *
43
- * @v nethdr	Generic network-layer header
44
- * @ret llhdr	Generic link-layer header
45
- * @ret rc	Return status code
42
+ * @v pkb		Packet buffer
43
+ * @v netdev		Network device
44
+ * @v net_protocol	Network-layer protocol
45
+ * @v ll_dest		Link-layer destination address
46 46
  *
47
- * Constructs the generic link-layer header based on the generic
48
- * network-layer header, i.e. maps network-layer addresses (e.g. IPv4
49
- * addresses) to MAC addresses.
50
- *
51
- * If the destination MAC address cannot be determined, an ARP request
52
- * is sent for the requested network-layer address and -ENOENT is
53
- * returned.
54
- */
55
-static int eth_route ( struct net_device *netdev,
56
-		       const struct net_header *nethdr,
57
-		       struct ll_header *llhdr ) {
58
-	int rc;
59
-
60
-	/* Fill in the easy bits */
61
-	llhdr->net_proto = nethdr->net_protocol->net_proto;
62
-	memcpy ( llhdr->source_ll_addr, netdev->ll_addr, ETH_ALEN );
63
-
64
-	/* Work out the destination MAC address */
65
-	if ( nethdr->flags & PKT_FL_BROADCAST ) {
66
-		memcpy ( llhdr->dest_ll_addr, eth_broadcast, ETH_ALEN );
67
-	} else if ( nethdr->flags & PKT_FL_RAW_ADDR ) {
68
-		memcpy ( llhdr->dest_ll_addr, nethdr->dest_net_addr, ETH_ALEN);
69
-	} else if ( nethdr->flags & PKT_FL_MULTICAST ) {
70
-		/* IP multicast is a special case; there exists a
71
-		 * direct mapping from IP address to MAC address
72
-		 */
73
-		assert ( nethdr->net_protocol->net_proto == htons(ETH_P_IP) );
74
-		llhdr->dest_ll_addr[0] = 0x01;
75
-		llhdr->dest_ll_addr[1] = 0x00;
76
-		llhdr->dest_ll_addr[2] = 0x5e;
77
-		llhdr->dest_ll_addr[3] = nethdr->dest_net_addr[1] & 0x7f;
78
-		llhdr->dest_ll_addr[4] = nethdr->dest_net_addr[2];
79
-		llhdr->dest_ll_addr[5] = nethdr->dest_net_addr[3];
80
-	} else {
81
-		/* Otherwise, look up the address using ARP */
82
-		if ( ( rc = arp_resolve ( netdev, nethdr, llhdr ) ) != 0 )
83
-			return rc;
84
-	}
85
-
86
-	return 0;
87
-}
88
-
89
-/**
90
- * Fill in Ethernet link-layer header
91
- *
92
- * @v pkb	Packet buffer
93
- * @v llhdr	Generic link-layer header
94
- *
95
- * Fills in the Ethernet link-layer header in the packet buffer based
96
- * on information in the generic link-layer header.
47
+ * Prepends the Ethernet link-layer header and transmits the packet.
97 48
  */
98
-static void eth_fill_llh ( const struct ll_header *llhdr,
99
-			   struct pk_buff *pkb ) {
100
-	struct ethhdr *ethhdr = pkb->data;
101
-
102
-	memcpy ( ethhdr->h_dest, llhdr->dest_ll_addr, ETH_ALEN );
103
-	memcpy ( ethhdr->h_source, llhdr->source_ll_addr, ETH_ALEN );
104
-	ethhdr->h_protocol = llhdr->net_proto;
49
+static int eth_transmit ( struct pk_buff *pkb, struct net_device *netdev,
50
+			  struct net_protocol *net_protocol,
51
+			  const void *ll_dest ) {
52
+	struct ethhdr *ethhdr = pkb_push ( pkb, ETH_HLEN );
53
+
54
+	memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
55
+	memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
56
+	ethhdr->h_protocol = net_protocol->net_proto;
57
+	return netdev_transmit ( netdev, pkb );
105 58
 }
106 59
 
107 60
 /**
@@ -138,7 +91,7 @@ static void eth_parse_llh ( const struct pk_buff *pkb,
138 91
  */
139 92
 static const char * eth_ntoa ( const void *ll_addr ) {
140 93
 	static char buf[18]; /* "00:00:00:00:00:00" */
141
-	uint8_t *eth_addr = ll_addr;
94
+	const uint8_t *eth_addr = ll_addr;
142 95
 
143 96
 	sprintf ( buf, "%02x:%02x:%02x:%02x:%02x:%02x",
144 97
 		  eth_addr[0], eth_addr[1], eth_addr[2],
@@ -148,14 +101,13 @@ static const char * eth_ntoa ( const void *ll_addr ) {
148 101
 
149 102
 /** Ethernet protocol */
150 103
 struct ll_protocol ethernet_protocol = {
151
-	.name = "Ethernet",
152
-	.ll_proto = htons ( ARPHRD_ETHER ),
153
-	.ll_addr_len = ETH_ALEN,
154
-	.ll_header_len = ETH_HLEN,
155
-	.route = eth_route,
156
-	.fill_llh = eth_fill_llh,
157
-	.parse_llh = eth_parse_llh,
158
-	.ntoa = eth_ntoa,
104
+	.name		= "Ethernet",
105
+	.ll_proto	= htons ( ARPHRD_ETHER ),
106
+	.ll_addr_len	= ETH_ALEN,
107
+	.ll_broadcast	= eth_broadcast,
108
+	.transmit	= eth_transmit,
109
+	.parse_llh	= eth_parse_llh,
110
+	.ntoa		= eth_ntoa,
159 111
 };
160 112
 
161 113
 LL_PROTOCOL ( ethernet_protocol );

+ 125
- 140
src/net/ipv4.c ファイルの表示

@@ -2,9 +2,11 @@
2 2
 #include <stdint.h>
3 3
 #include <errno.h>
4 4
 #include <byteswap.h>
5
+#include <malloc.h>
5 6
 #include <vsprintf.h>
7
+#include <gpxe/list.h>
6 8
 #include <gpxe/in.h>
7
-
9
+#include <gpxe/arp.h>
8 10
 
9 11
 #include <ip.h>
10 12
 
@@ -13,6 +15,7 @@
13 15
 #include <gpxe/pkbuff.h>
14 16
 #include <gpxe/netdevice.h>
15 17
 #include "uip/uip.h"
18
+#include <gpxe/ip.h>
16 19
 
17 20
 /** @file
18 21
  *
@@ -27,121 +30,144 @@
27 30
 
28 31
 struct net_protocol ipv4_protocol;
29 32
 
30
-/** An IPv4 routing table entry */
31
-struct ipv4_route {
32
-	/** Network address */
33
-	struct in_addr network;
33
+/** An IPv4 address/routing table entry */
34
+struct ipv4_miniroute {
35
+	/** List of miniroutes */
36
+	struct list_head list;
37
+	/** Network device */
38
+	struct net_device *netdev;
39
+	/** IPv4 address */
40
+	struct in_addr address;
34 41
 	/** Subnet mask */
35 42
 	struct in_addr netmask;
36 43
 	/** Gateway address */
37 44
 	struct in_addr gateway;
38
-	/** Gateway device */
39
-	struct in_addr gatewaydev;
40
-};
41
-
42
-enum {
43
-	STATIC_SINGLE_NETDEV_ROUTE = 0,
44
-	DEFAULT_ROUTE,
45
-	NUM_ROUTES
46 45
 };
47 46
 
48
-/** IPv4 routing table */
49
-static struct ipv4_route routing_table[NUM_ROUTES];
50
-
51
-#define routing_table_end ( routing_table + NUM_ROUTES )
47
+/** List of IPv4 miniroutes */
48
+static LIST_HEAD ( miniroutes );
52 49
 
53
-#if 0
54 50
 /**
55
- * Set IP address
51
+ * Add IPv4 interface
56 52
  *
57
- */
58
-void set_ipaddr ( struct in_addr address ) {
59
-	union {
60
-		struct in_addr address;
61
-		uint16_t uip_address[2];
62
-	} u;
63
-
64
-	u.address = address;
65
-	uip_sethostaddr ( u.uip_address );
66
-}
67
-
68
-/**
69
- * Set netmask
53
+ * @v netdev	Network device
54
+ * @v address	IPv4 address
55
+ * @v netmask	Subnet mask
56
+ * @v gateway	Gateway address (or @c INADDR_NONE for no gateway)
57
+ * @ret rc	Return status code
70 58
  *
71 59
  */
72
-void set_netmask ( struct in_addr address ) {
73
-	union {
74
-		struct in_addr address;
75
-		uint16_t uip_address[2];
76
-	} u;
77
-
78
-	u.address = address;
79
-	uip_setnetmask ( u.uip_address );
60
+int add_ipv4_address ( struct net_device *netdev, struct in_addr address,
61
+		       struct in_addr netmask, struct in_addr gateway ) {
62
+	struct ipv4_miniroute *miniroute;
63
+
64
+	/* Allocate and populate miniroute structure */
65
+	miniroute = malloc ( sizeof ( *miniroute ) );
66
+	if ( ! miniroute )
67
+		return -ENOMEM;
68
+	miniroute->netdev = netdev;
69
+	miniroute->address = address;
70
+	miniroute->netmask = netmask;
71
+	miniroute->gateway = gateway;
72
+	
73
+	/* Add to end of list if we have a gateway, otherwise to start
74
+	 * of list.
75
+	 */
76
+	if ( gateway.s_addr != INADDR_NONE ) {
77
+		list_add_tail ( &miniroute->list, &miniroutes );
78
+	} else {
79
+		list_add ( &miniroute->list, &miniroutes );
80
+	}
81
+	return 0;
80 82
 }
81 83
 
82 84
 /**
83
- * Set default gateway
85
+ * Remove IPv4 interface
84 86
  *
87
+ * @v netdev	Network device
85 88
  */
86
-void set_gateway ( struct in_addr address ) {
87
-	union {
88
-		struct in_addr address;
89
-		uint16_t uip_address[2];
90
-	} u;
89
+void del_ipv4_address ( struct net_device *netdev ) {
90
+	struct ipv4_miniroute *miniroute;
91 91
 
92
-	u.address = address;
93
-	uip_setdraddr ( u.uip_address );
92
+	list_for_each_entry ( miniroute, &miniroutes, list ) {
93
+		if ( miniroute->netdev == netdev ) {
94
+			list_del ( &miniroute->list );
95
+			break;
96
+		}
97
+	}
94 98
 }
95 99
 
96 100
 /**
97
- * Run the TCP/IP stack
98
- *
99
- * Call this function in a loop in order to allow TCP/IP processing to
100
- * take place.  This call takes the stack through a single iteration;
101
- * it will typically be used in a loop such as
102
- *
103
- * @code
101
+ * Transmit packet constructed by uIP
104 102
  *
105
- * struct tcp_connection *my_connection;
106
- * ...
107
- * tcp_connect ( my_connection );
108
- * while ( ! my_connection->finished ) {
109
- *   run_tcpip();
110
- * }
111
- *
112
- * @endcode
103
+ * @v pkb		Packet buffer
104
+ * @ret rc		Return status code
113 105
  *
114
- * where @c my_connection->finished is set by one of the connection's
115
- * #tcp_operations methods to indicate completion.
116 106
  */
117
-void run_tcpip ( void ) {
118
-	void *data;
119
-	size_t len;
120
-	uint16_t type;
121
-	int i;
122
-	
123
-	if ( netdev_poll ( 1, &data, &len ) ) {
124
-		/* We have data */
125
-		memcpy ( uip_buf, data, len );
126
-		uip_len = len;
127
-		type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) );
128
-		if ( type == UIP_ETHTYPE_ARP ) {
129
-			uip_arp_arpin();
130
-		} else {
131
-			uip_arp_ipin();
132
-			uip_input();
107
+int ipv4_uip_transmit ( struct pk_buff *pkb ) {
108
+	struct iphdr *iphdr = pkb->data;
109
+	struct ipv4_miniroute *miniroute;
110
+	struct net_device *netdev = NULL;
111
+	struct in_addr next_hop;
112
+	struct in_addr source;
113
+	uint8_t ll_dest_buf[MAX_LL_ADDR_LEN];
114
+	const uint8_t *ll_dest = ll_dest_buf;
115
+	int rc;
116
+
117
+	/* Use routing table to identify next hop and transmitting netdev */
118
+	next_hop = iphdr->dest;
119
+	list_for_each_entry ( miniroute, &miniroutes, list ) {
120
+		if ( ( ( ( iphdr->dest.s_addr ^ miniroute->address.s_addr ) &
121
+			 miniroute->netmask.s_addr ) == 0 ) ||
122
+		     ( miniroute->gateway.s_addr != INADDR_NONE ) ) {
123
+			netdev = miniroute->netdev;
124
+			source = miniroute->address;
125
+			if ( miniroute->gateway.s_addr != INADDR_NONE )
126
+				next_hop = miniroute->gateway;
127
+			break;
133 128
 		}
134
-		if ( uip_len > 0 )
135
-			uip_transmit();
129
+	}
130
+
131
+	/* Abort if no network device identified */
132
+	if ( ! netdev ) {
133
+		DBG ( "No route to %s\n", inet_ntoa ( iphdr->dest ) );
134
+		rc = -EHOSTUNREACH;
135
+		goto err;
136
+	}
137
+
138
+	/* Determine link-layer destination address */
139
+	if ( next_hop.s_addr == INADDR_BROADCAST ) {
140
+		/* Broadcast address */
141
+		ll_dest = netdev->ll_protocol->ll_broadcast;
142
+	} else if ( IN_MULTICAST ( next_hop.s_addr ) ) {
143
+		/* Special case: IPv4 multicast over Ethernet.  This
144
+		 * code may need to be generalised once we find out
145
+		 * what happens for other link layers.
146
+		 */
147
+		uint8_t *next_hop_bytes = ( uint8_t * ) &next_hop;
148
+		ll_dest_buf[0] = 0x01;
149
+		ll_dest_buf[0] = 0x00;
150
+		ll_dest_buf[0] = 0x5e;
151
+		ll_dest_buf[3] = next_hop_bytes[1] & 0x7f;
152
+		ll_dest_buf[4] = next_hop_bytes[2];
153
+		ll_dest_buf[5] = next_hop_bytes[3];
136 154
 	} else {
137
-		for ( i = 0 ; i < UIP_CONNS ; i++ ) {
138
-			uip_periodic ( i );
139
-			if ( uip_len > 0 )
140
-				uip_transmit();
155
+		/* Unicast address: resolve via ARP */
156
+		if ( ( rc = arp_resolve ( netdev, &ipv4_protocol, &next_hop,
157
+					  &source, ll_dest_buf ) ) != 0 ) {
158
+			DBG ( "No ARP entry for %s\n",
159
+			      inet_ntoa ( iphdr->dest ) );
160
+			goto err;
141 161
 		}
142 162
 	}
163
+	
164
+	/* Hand off to link layer */
165
+	return net_transmit ( pkb, netdev, &ipv4_protocol, ll_dest );
166
+
167
+ err:
168
+	free_pkb ( pkb );
169
+	return rc;
143 170
 }
144
-#endif
145 171
 
146 172
 /**
147 173
  * Process incoming IP packets
@@ -167,51 +193,25 @@ static int ipv4_rx ( struct pk_buff *pkb ) {
167 193
 		pkb = alloc_pkb ( MAX_LL_HEADER_LEN + uip_len );
168 194
 		if ( ! pkb )
169 195
 			return -ENOMEM;
170
-		pkb->net_protocol = &ipv4_protocol;
171 196
 		pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
172 197
 		memcpy ( pkb_put ( pkb, uip_len ), uip_buf, uip_len );
173
-		net_transmit ( pkb );
198
+		ipv4_uip_transmit ( pkb );
174 199
 	}
175 200
 	return 0;
176 201
 }
177 202
 
178 203
 /**
179
- * Perform IP layer routing
204
+ * Convert IPv4 address to dotted-quad notation
180 205
  *
181
- * @v pkb	Packet buffer
182
- * @ret source	Network-layer source address
183
- * @ret dest	Network-layer destination address
184
- * @ret rc	Return status code
206
+ * @v in	IP address
207
+ * @ret string	IP address in dotted-quad notation
185 208
  */
186
-static int ipv4_route ( const struct pk_buff *pkb,
187
-			struct net_header *nethdr ) {
188
-	struct iphdr *iphdr = pkb->data;
189
-	struct in_addr *source = ( struct in_addr * ) nethdr->source_net_addr;
190
-	struct in_addr *dest = ( struct in_addr * ) nethdr->dest_net_addr;
191
-	struct ipv4_route *route;
192
-
193
-	/* Route IP packet according to routing table */
194
-	source->s_addr = INADDR_NONE;
195
-	dest->s_addr = iphdr->dest.s_addr;
196
-	for ( route = routing_table ; route < routing_table_end ; route++ ) {
197
-		if ( ( dest->s_addr & route->netmask.s_addr )
198
-		     == route->network.s_addr ) {
199
-			source->s_addr = route->gatewaydev.s_addr;
200
-			if ( route->gateway.s_addr )
201
-				dest->s_addr = route->gateway.s_addr;
202
-			break;
203
-		}
204
-	}
205
-
206
-	/* Set broadcast and multicast flags as applicable */
207
-	nethdr->flags = 0;
208
-	if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) {
209
-		nethdr->flags = PKT_FL_BROADCAST;
210
-	} else if ( IN_MULTICAST ( dest->s_addr ) ) {
211
-		nethdr->flags = PKT_FL_MULTICAST;
212
-	}
213
-
214
-	return 0;
209
+char * inet_ntoa ( struct in_addr in ) {
210
+	static char buf[16]; /* "xxx.xxx.xxx.xxx" */
211
+	uint8_t *bytes = ( uint8_t * ) &in;
212
+	
213
+	sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] );
214
+	return buf;
215 215
 }
216 216
 
217 217
 /**
@@ -222,12 +222,7 @@ static int ipv4_route ( const struct pk_buff *pkb,
222 222
  *
223 223
  */
224 224
 static const char * ipv4_ntoa ( const void *net_addr ) {
225
-	static char buf[16]; /* "xxx.xxx.xxx.xxx" */
226
-	uint8_t *ip_addr = net_addr;
227
-
228
-	sprintf ( buf, "%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2],
229
-		  ip_addr[3] );
230
-	return buf;
225
+	return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) );
231 226
 }
232 227
 
233 228
 /** IPv4 protocol */
@@ -236,7 +231,6 @@ struct net_protocol ipv4_protocol = {
236 231
 	.net_proto = htons ( ETH_P_IP ),
237 232
 	.net_addr_len = sizeof ( struct in_addr ),
238 233
 	.rx_process = ipv4_rx,
239
-	.route = ipv4_route,
240 234
 	.ntoa = ipv4_ntoa,
241 235
 };
242 236
 
@@ -251,12 +245,3 @@ struct net_address static_single_ipv4_address = {
251 245
 };
252 246
 
253 247
 STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address );
254
-
255
-#warning "Remove this static-IP hack"
256
-static struct ipv4_route routing_table[NUM_ROUTES] = {
257
-	{ { htonl ( 0x0afefe00 ) }, { htonl ( 0xfffffffc ) },
258
-	  { htonl ( 0x00000000 ) }, { htonl ( 0x0afefe01 ) } },
259
-	{ { htonl ( 0x00000000 ) }, { htonl ( 0x00000000 ) },
260
-	  { htonl ( 0x0afefe02 ) }, { htonl ( 0x0afefe01 ) } },
261
-};
262
-

+ 46
- 83
src/net/netdevice.c ファイルの表示

@@ -62,6 +62,50 @@ static struct net_address static_single_netdev_addresses_end[0]
62 62
 /** Recevied packet queue */
63 63
 static LIST_HEAD ( rx_queue );
64 64
 
65
+#warning "Remove this static IP address hack"
66
+#include <ip.h>
67
+#include <gpxe/ip.h>
68
+
69
+/**
70
+ * Register network device
71
+ *
72
+ * @v netdev		Network device
73
+ * @ret rc		Return status code
74
+ *
75
+ * Adds the network device to the list of network devices.
76
+ */
77
+int register_netdev ( struct net_device *netdev ) {
78
+	
79
+#warning "Remove this static IP address hack"
80
+	{
81
+		const struct in_addr static_address = { htonl ( 0x0afefe01 ) };
82
+		const struct in_addr static_netmask = { htonl ( 0xffffff00 ) };
83
+		const struct in_addr static_gateway = { INADDR_NONE };
84
+		int rc;
85
+		
86
+		if ( ( rc = add_ipv4_address ( netdev, static_address,
87
+					       static_netmask,
88
+					       static_gateway ) ) != 0 )
89
+			return rc;
90
+	}
91
+
92
+	return 0;
93
+}
94
+
95
+/**
96
+ * Unregister network device
97
+ *
98
+ * @v netdev		Network device
99
+ *
100
+ * Removes the network device from the list of network devices.
101
+ */
102
+void unregister_netdev ( struct net_device *netdev ) {
103
+
104
+#warning "Remove this static IP address hack"
105
+	del_ipv4_address ( netdev );
106
+
107
+}
108
+
65 109
 /**
66 110
  * Add packet to receive queue
67 111
  *
@@ -128,88 +172,6 @@ find_netdev_by_net_addr ( struct net_protocol *net_protocol,
128 172
 	return NULL;
129 173
 }
130 174
 
131
-/**
132
- * Transmit packet via a network device
133
- *
134
- * @v pkb		Packet buffer
135
- * @v netdev		Network device, or NULL
136
- * @ret rc		Return status code
137
- *
138
- * Transmits the packet via the specified network device.  The packet
139
- * must begin with a network-layer header, and the @c net_protocol
140
- * field must have been filled in.  If @c netdev is NULL, the network
141
- * device is identified via the packet contents, if possible.  This
142
- * function takes ownership of the packet buffer.
143
- */
144
-int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev ) {
145
-	struct net_protocol *net_protocol;
146
-	struct net_header nethdr;
147
-	struct ll_protocol *ll_protocol;
148
-	struct ll_header llhdr;
149
-	int rc;
150
-
151
-	/* Perform network-layer routing */
152
-	net_protocol = pkb->net_protocol;
153
-	nethdr.net_protocol = net_protocol;
154
-	if ( ( rc = net_protocol->route ( pkb, &nethdr ) ) != 0 ) {
155
-		DBG ( "Could not route to %s address %s\n",
156
-		      net_protocol->name,
157
-		      net_protocol->ntoa ( nethdr.dest_net_addr ) );
158
-		free_pkb ( pkb );
159
-		return rc;
160
-	}
161
-
162
-	/* Identify transmitting network device, if not specified */
163
-	if ( ! netdev ) {
164
-		netdev = find_netdev_by_net_addr ( net_protocol,
165
-						   nethdr.source_net_addr );
166
-		if ( ! netdev ) {
167
-			DBG ( "No network device for %s address %s\n",
168
-			      net_protocol->name,
169
-			      net_protocol->ntoa ( nethdr.source_net_addr ) );
170
-			free_pkb ( pkb );
171
-			return -EHOSTUNREACH;
172
-		}
173
-	}
174
-
175
-	/* Perform link-layer routing */
176
-	ll_protocol = netdev->ll_protocol;
177
-	llhdr.ll_protocol = ll_protocol;
178
-	if ( ( rc = ll_protocol->route ( netdev, &nethdr, &llhdr ) ) != 0 ) {
179
-		DBG ( "No link-layer route to %s address %s\n",
180
-		      net_protocol->name,
181
-		      net_protocol->ntoa ( nethdr.dest_net_addr ) );
182
-		free_pkb ( pkb );
183
-		return rc;
184
-	}
185
-
186
-	/* Prepend link-layer header */
187
-	pkb_push ( pkb, ll_protocol->ll_header_len );
188
-	ll_protocol->fill_llh ( &llhdr, pkb );
189
-
190
-	/* Hand off packet to network device */
191
-	if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 ) {
192
-		DBG ( "Device failed to transmit packet\n" );
193
-		return rc;
194
-	}
195
-	
196
-	DBG ( "Packet transmitted\n" );
197
-	return 0;
198
-}
199
-
200
-/**
201
- * Transmit packet
202
- *
203
- * @v pkb		Packet buffer
204
- * @ret rc		Return status code
205
- *
206
- * Transmits the packet via the appropriate network device.  This
207
- * function takes ownership of the packet buffer.
208
- */
209
-int net_transmit ( struct pk_buff *pkb ) {
210
-	return net_transmit_via ( pkb, NULL );
211
-}
212
-
213 175
 /**
214 176
  * Poll for packet on all network devices
215 177
  *
@@ -277,7 +239,8 @@ int net_rx_process ( struct pk_buff *pkb ) {
277 239
 	pkb->net_protocol = net_protocol;
278 240
 	
279 241
 	/* Strip off link-layer header */
280
-	pkb_pull ( pkb, ll_protocol->ll_header_len );
242
+#warning "Temporary hack"
243
+	pkb_pull ( pkb, ETH_HLEN );
281 244
 	
282 245
 	/* Hand off to network layer */
283 246
 	if ( ( rc = net_protocol->rx_process ( pkb ) ) != 0 ) {

+ 2
- 3
src/net/tcp.c ファイルの表示

@@ -176,9 +176,8 @@ static void tcp_periodic ( void ) {
176 176
 			pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
177 177
 			pkb_put ( pkb, uip_len );
178 178
 			memcpy ( pkb->data, uip_buf, uip_len );
179
-			pkb->net_protocol = &ipv4_protocol;
180
-			
181
-			net_transmit ( pkb );
179
+
180
+			ipv4_uip_transmit ( pkb );
182 181
 		}
183 182
 	}
184 183
 }

読み込み中…
キャンセル
保存