Browse Source

Network layer now works as a proof of concept

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
129c6c3968
6 changed files with 272 additions and 92 deletions
  1. 3
    1
      src/include/gpxe/arp.h
  2. 80
    27
      src/include/gpxe/netdevice.h
  3. 43
    9
      src/net/arp.c
  4. 32
    9
      src/net/ethernet.c
  5. 37
    5
      src/net/ipv4.c
  6. 77
    41
      src/net/netdevice.c

+ 3
- 1
src/include/gpxe/arp.h View File

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

+ 80
- 27
src/include/gpxe/netdevice.h View File

11
 #include <gpxe/tables.h>
11
 #include <gpxe/tables.h>
12
 
12
 
13
 struct pk_buff;
13
 struct pk_buff;
14
+struct net_device;
14
 struct net_protocol;
15
 struct net_protocol;
15
 struct ll_protocol;
16
 struct ll_protocol;
16
 
17
 
17
 /** Maximum length of a link-layer address */
18
 /** Maximum length of a link-layer address */
18
 #define MAX_LL_ADDR_LEN 6
19
 #define MAX_LL_ADDR_LEN 6
19
 
20
 
21
+/** Maximum length of a link-layer header */
22
+#define MAX_LL_HEADER_LEN 16
23
+
20
 /** Maximum length of a network-layer address */
24
 /** Maximum length of a network-layer address */
21
 #define MAX_NET_ADDR_LEN 4
25
 #define MAX_NET_ADDR_LEN 4
22
 
26
 
32
 struct net_header {
36
 struct net_header {
33
 	/** Network-layer protocol */
37
 	/** Network-layer protocol */
34
 	struct net_protocol *net_protocol;
38
 	struct net_protocol *net_protocol;
35
-	/** Destination address flags
39
+	/** Flags
36
 	 *
40
 	 *
37
-	 * This is the bitwise OR of zero or more NETADDR_FL_XXX
41
+	 * This is the bitwise OR of zero or more PKT_FL_XXX
38
 	 * values.
42
 	 * values.
39
 	 */
43
 	 */
40
-	int dest_flags;
44
+	int flags;
41
 	/** Network-layer destination address */
45
 	/** Network-layer destination address */
42
 	uint8_t dest_net_addr[MAX_NET_ADDR_LEN];
46
 	uint8_t dest_net_addr[MAX_NET_ADDR_LEN];
43
 	/** Network-layer source address */
47
 	/** Network-layer source address */
44
 	uint8_t source_net_addr[MAX_NET_ADDR_LEN];
48
 	uint8_t source_net_addr[MAX_NET_ADDR_LEN];
45
 };
49
 };
46
 
50
 
47
-/** Address is a broadcast address */
48
-#define NETADDR_FL_BROADCAST 0x01
51
+/** Packet is a broadcast packet */
52
+#define PKT_FL_BROADCAST 0x01
49
 
53
 
50
-/** Address is a multicast address */
51
-#define NETADDR_FL_MULTICAST 0x02
54
+/** Packet is a multicast packet */
55
+#define PKT_FL_MULTICAST 0x02
52
 
56
 
53
-/** Address is a raw hardware address */
54
-#define NETADDR_FL_RAW 0x04
57
+/** Addresses are raw hardware addresses */
58
+#define PKT_FL_RAW_ADDR 0x04
55
 
59
 
56
 /** A generic link-layer header */
60
 /** A generic link-layer header */
57
 struct ll_header {
61
 struct ll_header {
58
 	/** Link-layer protocol */
62
 	/** Link-layer protocol */
59
 	struct ll_protocol *ll_protocol;
63
 	struct ll_protocol *ll_protocol;
60
-	/** Destination address flags
64
+	/** Flags
61
 	 *
65
 	 *
62
-	 * This is the bitwise OR of zero or more NETADDR_FL_XXX
66
+	 * This is the bitwise OR of zero or more PKT_FL_XXX
63
 	 * values.
67
 	 * values.
64
 	 */
68
 	 */
65
-	int dest_flags;
69
+	int flags;
66
 	/** Link-layer destination address */
70
 	/** Link-layer destination address */
67
 	uint8_t dest_ll_addr[MAX_LL_ADDR_LEN];
71
 	uint8_t dest_ll_addr[MAX_LL_ADDR_LEN];
68
 	/** Link-layer source address */
72
 	/** Link-layer source address */
80
  *
84
  *
81
  */
85
  */
82
 struct net_protocol {
86
 struct net_protocol {
87
+	/** Protocol name */
88
+	const char *name;
83
 	/**
89
 	/**
84
 	 * Perform network-layer routing
90
 	 * Perform network-layer routing
85
 	 *
91
 	 *
86
 	 * @v pkb	Packet buffer
92
 	 * @v pkb	Packet buffer
87
-	 * @ret source	Network-layer source address
88
-	 * @ret dest	Network-layer destination address
93
+	 * @v nethdr	Generic network-layer header
89
 	 * @ret rc	Return status code
94
 	 * @ret rc	Return status code
90
 	 *
95
 	 *
91
-	 * This method should fill in the source and destination
92
-	 * addresses with enough information to allow the link layer
93
-	 * to route the packet.
96
+	 * This method should fill in the network header with enough
97
+	 * information to allow the link layer to route the packet.
94
 	 *
98
 	 *
95
 	 * For example, in the case of IPv4, this method should fill
99
 	 * For example, in the case of IPv4, this method should fill
96
-	 * in @c source with the IP addresses of the local adapter and
97
-	 * @c dest with the next hop destination (e.g. the gateway).
100
+	 * in the IP addresses of the local adapter and the next hop
101
+	 * destination (e.g. the gateway).
98
 	 */
102
 	 */
99
 	int ( * route ) ( const struct pk_buff *pkb,
103
 	int ( * route ) ( const struct pk_buff *pkb,
100
 			  struct net_header *nethdr );
104
 			  struct net_header *nethdr );
108
 	 * the packet buffer.
112
 	 * the packet buffer.
109
 	 */
113
 	 */
110
 	int ( * rx ) ( struct pk_buff *pkb );
114
 	int ( * rx ) ( struct pk_buff *pkb );
115
+	/**
116
+	 * Transcribe network-layer address
117
+	 *
118
+	 * @v net_addr	Network-layer address
119
+	 * @ret string	Human-readable transcription of address
120
+	 *
121
+	 * This method should convert the network-layer address into a
122
+	 * human-readable format (e.g. dotted quad notation for IPv4).
123
+	 *
124
+	 * The buffer used to hold the transcription is statically
125
+	 * allocated.
126
+	 */
127
+	const char * ( *ntoa ) ( const void * net_addr );
111
 	/** Network-layer protocol
128
 	/** Network-layer protocol
112
 	 *
129
 	 *
113
 	 * This is an ETH_P_XXX constant, in network-byte order
130
 	 * This is an ETH_P_XXX constant, in network-byte order
122
  *
139
  *
123
  */
140
  */
124
 struct ll_protocol {
141
 struct ll_protocol {
142
+	/** Protocol name */
143
+	const char *name;
125
 	/**
144
 	/**
126
 	 * Perform link-layer routing
145
 	 * Perform link-layer routing
127
 	 *
146
 	 *
147
+	 * @v netdev	Network device
128
 	 * @v nethdr	Generic network-layer header
148
 	 * @v nethdr	Generic network-layer header
129
 	 * @ret llhdr	Generic link-layer header
149
 	 * @ret llhdr	Generic link-layer header
130
 	 * @ret rc	Return status code
150
 	 * @ret rc	Return status code
137
 	 * return an error (after transmitting an ARP request, if
157
 	 * return an error (after transmitting an ARP request, if
138
 	 * applicable).
158
 	 * applicable).
139
 	 */
159
 	 */
140
-	int ( * route ) ( const struct net_header *nethdr,
160
+	int ( * route ) ( struct net_device *netdev,
161
+			  const struct net_header *nethdr,
141
 			  struct ll_header *llhdr );
162
 			  struct ll_header *llhdr );
142
 	/**
163
 	/**
143
 	 * Fill media-specific link-layer header
164
 	 * Fill media-specific link-layer header
164
 	void ( * parse_llh ) ( const struct pk_buff *pkb,
185
 	void ( * parse_llh ) ( const struct pk_buff *pkb,
165
 			       struct ll_header *llhdr );
186
 			       struct ll_header *llhdr );
166
 
187
 
188
+	/**
189
+	 * Transcribe link-layer address
190
+	 *
191
+	 * @v ll_addr	Link-layer address
192
+	 * @ret string	Human-readable transcription of address
193
+	 *
194
+	 * This method should convert the link-layer address into a
195
+	 * human-readable format.
196
+	 *
197
+	 * The buffer used to hold the transcription is statically
198
+	 * allocated.
199
+	 */
200
+	const char * ( *ntoa ) ( const void * ll_addr );
167
 	/** Link-layer protocol
201
 	/** Link-layer protocol
168
 	 *
202
 	 *
169
 	 * This is an ARPHRD_XXX constant, in network byte order.
203
 	 * This is an ARPHRD_XXX constant, in network byte order.
290
 	/* Nothing to do */
324
 	/* Nothing to do */
291
 }
325
 }
292
 
326
 
327
+/**
328
+ * Transmit raw packet via network device
329
+ *
330
+ * @v netdev		Network device
331
+ * @v pkb		Packet buffer
332
+ * @ret rc		Return status code
333
+ *
334
+ * Transmits the packet via the specified network device.  The
335
+ * link-layer header must already have been filled in.  If this
336
+ * function returns success, it has taken ownership of the packet
337
+ * buffer.
338
+ */
339
+static inline int netdev_transmit ( struct net_device *netdev,
340
+				    struct pk_buff *pkb ) {
341
+	return netdev->transmit ( netdev, pkb );
342
+}
343
+
293
 /**
344
 /**
294
  * Register a link-layer protocol
345
  * Register a link-layer protocol
295
  *
346
  *
296
  * @v protocol		Link-layer protocol
347
  * @v protocol		Link-layer protocol
297
  */
348
  */
298
 #define LL_PROTOCOL( protocol ) \
349
 #define LL_PROTOCOL( protocol ) \
299
-	struct ll_protocol protocol __table ( ll_protocols, 00 )
350
+	struct ll_protocol protocol __table ( ll_protocols, 01 )
300
 
351
 
301
 /**
352
 /**
302
  * Register a network-layer protocol
353
  * Register a network-layer protocol
304
  * @v protocol		Network-layer protocol
355
  * @v protocol		Network-layer protocol
305
  */
356
  */
306
 #define NET_PROTOCOL( protocol ) \
357
 #define NET_PROTOCOL( protocol ) \
307
-	struct net_protocol protocol __table ( net_protocols, 00 )
358
+	struct net_protocol protocol __table ( net_protocols, 01 )
308
 
359
 
309
 /**
360
 /**
310
  * Register a network-layer address for the static single network device
361
  * Register a network-layer address for the static single network device
312
  * @v net_address	Network-layer address
363
  * @v net_address	Network-layer address
313
  */
364
  */
314
 #define STATIC_SINGLE_NETDEV_ADDRESS( address ) \
365
 #define STATIC_SINGLE_NETDEV_ADDRESS( address ) \
315
-	struct net_address address __table ( sgl_netdev_addresses, 00 )
366
+	struct net_address address __table ( sgl_netdev_addresses, 01 )
316
 
367
 
317
-extern struct net_protocol *net_find_protocol ( uint16_t net_proto );
318
-extern struct net_device * net_find_address ( struct net_protocol *net_proto,
319
-					      void *net_addr );
368
+extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
369
+
370
+extern struct net_protocol *find_net_protocol ( uint16_t net_proto );
371
+extern struct net_device *
372
+find_netdev_by_net_addr ( struct net_protocol *net_protocol, void *net_addr );
320
 
373
 
374
+extern int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev );
321
 extern int net_transmit ( struct pk_buff *pkb );
375
 extern int net_transmit ( struct pk_buff *pkb );
322
 extern int net_poll ( void );
376
 extern int net_poll ( void );
323
-extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
324
 extern struct pk_buff * net_rx_dequeue ( void );
377
 extern struct pk_buff * net_rx_dequeue ( void );
325
 
378
 
326
 #endif /* _GPXE_NETDEVICE_H */
379
 #endif /* _GPXE_NETDEVICE_H */

+ 43
- 9
src/net/arp.c View File

91
 /**
91
 /**
92
  * Look up media-specific link-layer address in the ARP cache
92
  * Look up media-specific link-layer address in the ARP cache
93
  *
93
  *
94
+ * @v netdev		Network device
94
  * @v nethdr		Generic network-layer header
95
  * @v nethdr		Generic network-layer header
95
  * @ret llhdr		Generic link-layer header
96
  * @ret llhdr		Generic link-layer header
96
  * @ret rc		Return status code
97
  * @ret rc		Return status code
102
  * llhdr.
103
  * llhdr.
103
  *
104
  *
104
  * If no address is found in the ARP cache, an ARP request will be
105
  * If no address is found in the ARP cache, an ARP request will be
105
- * transmitted and -ENOENT will be returned.
106
+ * transmitted on the specified network device and -ENOENT will be
107
+ * returned.
106
  */
108
  */
107
-int arp_resolve ( const struct net_header *nethdr, struct ll_header *llhdr ) {
109
+int arp_resolve ( struct net_device *netdev, const struct net_header *nethdr,
110
+		  struct ll_header *llhdr ) {
108
 	struct net_protocol *net_protocol = nethdr->net_protocol;
111
 	struct net_protocol *net_protocol = nethdr->net_protocol;
109
 	struct ll_protocol *ll_protocol = llhdr->ll_protocol;
112
 	struct ll_protocol *ll_protocol = llhdr->ll_protocol;
110
 	const struct arp_entry *arp;
113
 	const struct arp_entry *arp;
116
 	arp = arp_find_entry ( ll_protocol, net_protocol,
119
 	arp = arp_find_entry ( ll_protocol, net_protocol,
117
 			       nethdr->dest_net_addr );
120
 			       nethdr->dest_net_addr );
118
 	if ( arp ) {
121
 	if ( arp ) {
122
+		DBG ( "ARP cache hit: %s %s => %s %s\n",
123
+		      net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
124
+		      ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
119
 		memcpy ( llhdr->dest_ll_addr, arp->ll_addr,
125
 		memcpy ( llhdr->dest_ll_addr, arp->ll_addr,
120
 			 sizeof ( llhdr->dest_ll_addr ) );
126
 			 sizeof ( llhdr->dest_ll_addr ) );
121
 		return 0;
127
 		return 0;
122
 	}
128
 	}
129
+	DBG ( "ARP cache miss: %s %s\n", net_protocol->name,
130
+	      net_protocol->ntoa ( nethdr->dest_net_addr ) );
123
 
131
 
124
 	/* Allocate ARP packet */
132
 	/* Allocate ARP packet */
125
-	pkb = alloc_pkb ( sizeof ( *arphdr ) +
133
+	pkb = alloc_pkb ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
126
 			  2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
134
 			  2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
127
 	if ( ! pkb )
135
 	if ( ! pkb )
128
 		return -ENOMEM;
136
 		return -ENOMEM;
129
 	pkb->net_protocol = &arp_protocol;
137
 	pkb->net_protocol = &arp_protocol;
138
+	pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
130
 
139
 
131
 	/* Build up ARP request */
140
 	/* Build up ARP request */
132
 	arphdr = pkb_put ( pkb, sizeof ( *arphdr ) );
141
 	arphdr = pkb_put ( pkb, sizeof ( *arphdr ) );
145
 		 nethdr->dest_net_addr, net_protocol->net_addr_len );
154
 		 nethdr->dest_net_addr, net_protocol->net_addr_len );
146
 
155
 
147
 	/* Transmit ARP request */
156
 	/* Transmit ARP request */
148
-	if ( ( rc = net_transmit ( pkb ) ) != 0 ) {
157
+	if ( ( rc = net_transmit_via ( pkb, netdev ) ) != 0 ) {
149
 		free_pkb ( pkb );
158
 		free_pkb ( pkb );
150
 		return rc;
159
 		return rc;
151
 	}
160
 	}
175
 
184
 
176
 	/* Identify link-layer and network-layer protocols */
185
 	/* Identify link-layer and network-layer protocols */
177
 	ll_protocol = pkb->ll_protocol;
186
 	ll_protocol = pkb->ll_protocol;
178
-	net_protocol = net_find_protocol ( arphdr->ar_pro );
187
+	net_protocol = find_net_protocol ( arphdr->ar_pro );
179
 	if ( ! net_protocol )
188
 	if ( ! net_protocol )
180
 		goto done;
189
 		goto done;
181
 
190
 
192
 		memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ),
201
 		memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ),
193
 			 arphdr->ar_hln );
202
 			 arphdr->ar_hln );
194
 		merge = 1;
203
 		merge = 1;
204
+		DBG ( "ARP cache update: %s %s => %s %s\n",
205
+		      net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
206
+		      ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
195
 	}
207
 	}
196
 
208
 
197
 	/* See if we own the target protocol address */
209
 	/* See if we own the target protocol address */
198
-	netdev = net_find_address ( net_protocol, arp_target_pa ( arphdr ) );
210
+	netdev = find_netdev_by_net_addr ( net_protocol,
211
+					   arp_target_pa ( arphdr ) );
199
 	if ( ! netdev )
212
 	if ( ! netdev )
200
 		goto done;
213
 		goto done;
201
 	
214
 	
208
 			 arphdr->ar_hln );
221
 			 arphdr->ar_hln );
209
 		memcpy ( arp->net_addr, arp_sender_pa ( arphdr ),
222
 		memcpy ( arp->net_addr, arp_sender_pa ( arphdr ),
210
 			 arphdr->ar_pln);
223
 			 arphdr->ar_pln);
224
+		DBG ( "ARP cache add: %s %s => %s %s\n",
225
+		      net_protocol->name, net_protocol->ntoa ( arp->net_addr ),
226
+		      ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) );
211
 	}
227
 	}
212
 
228
 
213
 	/* If it's not a request, there's nothing more to do */
229
 	/* If it's not a request, there's nothing more to do */
215
 		goto done;
231
 		goto done;
216
 
232
 
217
 	/* Change request to a reply, and send it */
233
 	/* Change request to a reply, and send it */
234
+	DBG ( "ARP reply: %s %s => %s %s\n", net_protocol->name,
235
+	      net_protocol->ntoa ( arp_target_pa ( arphdr ) ),
236
+	      ll_protocol->name, ll_protocol->ntoa ( netdev->ll_addr ) );
218
 	arphdr->ar_op = htons ( ARPOP_REPLY );
237
 	arphdr->ar_op = htons ( ARPOP_REPLY );
219
 	memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ),
238
 	memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ),
220
 		 arphdr->ar_hln + arphdr->ar_pln );
239
 		 arphdr->ar_hln + arphdr->ar_pln );
221
 	memcpy ( arp_target_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
240
 	memcpy ( arp_target_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
222
-	if ( net_transmit ( pkb ) == 0 )
241
+	if ( net_transmit_via ( pkb, netdev ) == 0 )
223
 		pkb = NULL;
242
 		pkb = NULL;
224
 
243
 
225
  done:
244
  done:
243
 		 arphdr->ar_hln );
262
 		 arphdr->ar_hln );
244
 	memcpy ( nethdr->dest_net_addr, arp_target_ha ( arphdr ),
263
 	memcpy ( nethdr->dest_net_addr, arp_target_ha ( arphdr ),
245
 		 arphdr->ar_hln );
264
 		 arphdr->ar_hln );
246
-	nethdr->dest_flags = NETADDR_FL_RAW;
265
+	nethdr->flags = PKT_FL_RAW_ADDR;
247
 	if ( arphdr->ar_op == htons ( ARPOP_REQUEST ) )
266
 	if ( arphdr->ar_op == htons ( ARPOP_REQUEST ) )
248
-		nethdr->dest_flags |= NETADDR_FL_BROADCAST;
267
+		nethdr->flags |= PKT_FL_BROADCAST;
249
 	
268
 	
250
 	return 0;
269
 	return 0;
251
 }
270
 }
252
 
271
 
272
+/**
273
+ * Transcribe ARP address
274
+ *
275
+ * @v net_addr	ARP address
276
+ * @ret string	"<ARP>"
277
+ *
278
+ * This operation is meaningless for the ARP protocol.
279
+ */
280
+static const char *
281
+arp_ntoa ( const void *net_addr __attribute__ (( unused )) ) {
282
+	return "<ARP>";
283
+}
284
+
253
 /** ARP protocol */
285
 /** ARP protocol */
254
 struct net_protocol arp_protocol = {
286
 struct net_protocol arp_protocol = {
287
+	.name = "ARP",
255
 	.net_proto = htons ( ETH_P_ARP ),
288
 	.net_proto = htons ( ETH_P_ARP ),
256
 	.rx = arp_rx,
289
 	.rx = arp_rx,
257
 	.route = arp_route,
290
 	.route = arp_route,
291
+	.ntoa = arp_ntoa,
258
 };
292
 };
259
 
293
 
260
 NET_PROTOCOL ( arp_protocol );
294
 NET_PROTOCOL ( arp_protocol );

+ 32
- 9
src/net/ethernet.c View File

51
  * is sent for the requested network-layer address and -ENOENT is
51
  * is sent for the requested network-layer address and -ENOENT is
52
  * returned.
52
  * returned.
53
  */
53
  */
54
-static int eth_route ( const struct net_header *nethdr,
54
+static int eth_route ( struct net_device *netdev,
55
+		       const struct net_header *nethdr,
55
 		       struct ll_header *llhdr ) {
56
 		       struct ll_header *llhdr ) {
56
 	int rc;
57
 	int rc;
57
 
58
 
59
+	/* Fill in the easy bits */
60
+	llhdr->net_proto = nethdr->net_protocol->net_proto;
61
+	memcpy ( llhdr->source_ll_addr, netdev->ll_addr, ETH_ALEN );
62
+
58
 	/* Work out the destination MAC address */
63
 	/* Work out the destination MAC address */
59
-	if ( nethdr->dest_flags & NETADDR_FL_RAW ) {
60
-		memcpy ( llhdr->dest_ll_addr, nethdr->dest_net_addr, ETH_ALEN);
61
-	} else if ( nethdr->dest_flags & NETADDR_FL_BROADCAST ) {
64
+	if ( nethdr->flags & PKT_FL_BROADCAST ) {
62
 		memcpy ( llhdr->dest_ll_addr, eth_broadcast, ETH_ALEN );
65
 		memcpy ( llhdr->dest_ll_addr, eth_broadcast, ETH_ALEN );
63
-	} else if ( nethdr->dest_flags & NETADDR_FL_MULTICAST ) {
66
+	} else if ( nethdr->flags & PKT_FL_RAW_ADDR ) {
67
+		memcpy ( llhdr->dest_ll_addr, nethdr->dest_net_addr, ETH_ALEN);
68
+	} else if ( nethdr->flags & PKT_FL_MULTICAST ) {
64
 		/* IP multicast is a special case; there exists a
69
 		/* IP multicast is a special case; there exists a
65
 		 * direct mapping from IP address to MAC address
70
 		 * direct mapping from IP address to MAC address
66
 		 */
71
 		 */
73
 		llhdr->dest_ll_addr[5] = nethdr->dest_net_addr[3];
78
 		llhdr->dest_ll_addr[5] = nethdr->dest_net_addr[3];
74
 	} else {
79
 	} else {
75
 		/* Otherwise, look up the address using ARP */
80
 		/* Otherwise, look up the address using ARP */
76
-		if ( ( rc = arp_resolve ( nethdr, llhdr ) ) != 0 )
81
+		if ( ( rc = arp_resolve ( netdev, nethdr, llhdr ) ) != 0 )
77
 			return rc;
82
 			return rc;
78
 	}
83
 	}
79
 
84
 
116
 	llhdr->net_proto = ethhdr->h_protocol;
121
 	llhdr->net_proto = ethhdr->h_protocol;
117
 
122
 
118
 	if ( memcmp ( ethhdr->h_dest, eth_broadcast, ETH_ALEN ) == 0 ) {
123
 	if ( memcmp ( ethhdr->h_dest, eth_broadcast, ETH_ALEN ) == 0 ) {
119
-		llhdr->dest_flags = NETADDR_FL_BROADCAST;
124
+		llhdr->flags = PKT_FL_BROADCAST;
120
 	} else if ( ethhdr->h_dest[0] & 0x01 ) {
125
 	} else if ( ethhdr->h_dest[0] & 0x01 ) {
121
-		llhdr->dest_flags = NETADDR_FL_MULTICAST;
126
+		llhdr->flags = PKT_FL_MULTICAST;
122
 	} else {
127
 	} else {
123
-		llhdr->dest_flags = 0;
128
+		llhdr->flags = 0;
124
 	}
129
 	}
125
 }
130
 }
126
 
131
 
132
+/**
133
+ * Transcribe Ethernet address
134
+ *
135
+ * @v ll_addr	Link-layer address
136
+ * @ret string	Link-layer address in human-readable format
137
+ */
138
+static const char * eth_ntoa ( const void *ll_addr ) {
139
+	static char buf[18]; /* "00:00:00:00:00:00" */
140
+	uint8_t *eth_addr = ll_addr;
141
+
142
+	sprintf ( buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
143
+		  eth_addr[0], eth_addr[1], eth_addr[2],
144
+		  eth_addr[3], eth_addr[4], eth_addr[5] );
145
+	return buf;
146
+}
147
+
127
 /** Ethernet protocol */
148
 /** Ethernet protocol */
128
 struct ll_protocol ethernet_protocol = {
149
 struct ll_protocol ethernet_protocol = {
150
+	.name = "Ethernet",
129
 	.ll_proto = htons ( ARPHRD_ETHER ),
151
 	.ll_proto = htons ( ARPHRD_ETHER ),
130
 	.ll_addr_len = ETH_ALEN,
152
 	.ll_addr_len = ETH_ALEN,
131
 	.ll_header_len = ETH_HLEN,
153
 	.ll_header_len = ETH_HLEN,
132
 	.route = eth_route,
154
 	.route = eth_route,
133
 	.fill_llh = eth_fill_llh,
155
 	.fill_llh = eth_fill_llh,
134
 	.parse_llh = eth_parse_llh,
156
 	.parse_llh = eth_parse_llh,
157
+	.ntoa = eth_ntoa,
135
 };
158
 };
136
 
159
 
137
 LL_PROTOCOL ( ethernet_protocol );
160
 LL_PROTOCOL ( ethernet_protocol );

+ 37
- 5
src/net/ipv4.c View File

1
 #include <string.h>
1
 #include <string.h>
2
 #include <stdint.h>
2
 #include <stdint.h>
3
 #include <byteswap.h>
3
 #include <byteswap.h>
4
+#include <vsprintf.h>
4
 #include <gpxe/in.h>
5
 #include <gpxe/in.h>
5
 
6
 
6
 
7
 
153
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
154
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
154
 	 * but will do as a proof-of-concept for now.
155
 	 * but will do as a proof-of-concept for now.
155
 	 */
156
 	 */
156
-	memcpy ( uip_buf, pkb->data, pkb_len ( pkb ) );
157
+	uip_len = pkb_len ( pkb );
158
+	memcpy ( uip_buf, pkb->data, uip_len );
157
 
159
 
158
 	/* Hand to uIP for processing */
160
 	/* Hand to uIP for processing */
159
 	uip_input ();
161
 	uip_input ();
198
 	}
200
 	}
199
 
201
 
200
 	/* Set broadcast and multicast flags as applicable */
202
 	/* Set broadcast and multicast flags as applicable */
201
-	nethdr->dest_flags = 0;
203
+	nethdr->flags = 0;
202
 	if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) {
204
 	if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) {
203
-		nethdr->dest_flags = NETADDR_FL_BROADCAST;
205
+		nethdr->flags = PKT_FL_BROADCAST;
204
 	} else if ( IN_MULTICAST ( dest->s_addr ) ) {
206
 	} else if ( IN_MULTICAST ( dest->s_addr ) ) {
205
-		nethdr->dest_flags = NETADDR_FL_MULTICAST;
207
+		nethdr->flags = PKT_FL_MULTICAST;
206
 	}
208
 	}
207
 
209
 
208
 	return 0;
210
 	return 0;
209
 }
211
 }
210
 
212
 
213
+/**
214
+ * Transcribe IP address
215
+ *
216
+ * @v net_addr	IP address
217
+ * @ret string	IP address in dotted-quad notation
218
+ *
219
+ */
220
+static const char * ipv4_ntoa ( const void *net_addr ) {
221
+	static char buf[16]; /* "xxx.xxx.xxx.xxx" */
222
+	uint8_t *ip_addr = net_addr;
223
+
224
+	sprintf ( buf, "%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2],
225
+		  ip_addr[3] );
226
+	return buf;
227
+}
228
+
211
 /** IPv4 protocol */
229
 /** IPv4 protocol */
212
 struct net_protocol ipv4_protocol = {
230
 struct net_protocol ipv4_protocol = {
213
-	.net_proto = ETH_P_IP,
231
+	.name = "IP",
232
+	.net_proto = htons ( ETH_P_IP ),
214
 	.net_addr_len = sizeof ( struct in_addr ),
233
 	.net_addr_len = sizeof ( struct in_addr ),
215
 	.rx = ipv4_rx,
234
 	.rx = ipv4_rx,
216
 	.route = ipv4_route,
235
 	.route = ipv4_route,
236
+	.ntoa = ipv4_ntoa,
217
 };
237
 };
218
 
238
 
219
 NET_PROTOCOL ( ipv4_protocol );
239
 NET_PROTOCOL ( ipv4_protocol );
221
 /** IPv4 address for the static single net device */
241
 /** IPv4 address for the static single net device */
222
 struct net_address static_single_ipv4_address = {
242
 struct net_address static_single_ipv4_address = {
223
 	.net_protocol = &ipv4_protocol,
243
 	.net_protocol = &ipv4_protocol,
244
+
245
+#warning "Remove this static-IP hack"
246
+	.net_addr = { 0x0a, 0xfe, 0xfe, 0x01 },
224
 };
247
 };
225
 
248
 
226
 STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address );
249
 STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address );
250
+
251
+#warning "Remove this static-IP hack"
252
+static struct ipv4_route routing_table[NUM_ROUTES] = {
253
+	{ { htonl ( 0x0afefe00 ) }, { htonl ( 0xfffffffc ) },
254
+	  { htonl ( 0x00000000 ) }, { htonl ( 0x0afefe01 ) } },
255
+	{ { htonl ( 0x00000000 ) }, { htonl ( 0x00000000 ) },
256
+	  { htonl ( 0x0afefe02 ) }, { htonl ( 0x0afefe01 ) } },
257
+};
258
+

+ 77
- 41
src/net/netdevice.c View File

60
 /** Recevied packet queue */
60
 /** Recevied packet queue */
61
 static LIST_HEAD ( rx_queue );
61
 static LIST_HEAD ( rx_queue );
62
 
62
 
63
+/**
64
+ * Add packet to receive queue
65
+ *
66
+ * @v netdev		Network device
67
+ * @v pkb		Packet buffer
68
+ *
69
+ * The packet is added to the RX queue.  Ownership of the packet is
70
+ * transferred to the RX queue; the caller must not touch the packet
71
+ * buffer after calling netdev_rx().
72
+ */
73
+void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
74
+	DBG ( "Packet received\n" );
75
+	pkb->ll_protocol = netdev->ll_protocol;
76
+	list_add_tail ( &pkb->list, &rx_queue );
77
+}
78
+
63
 /**
79
 /**
64
  * Identify network protocol
80
  * Identify network protocol
65
  *
81
  *
69
  * Identify a network-layer protocol from a protocol number, which
85
  * Identify a network-layer protocol from a protocol number, which
70
  * must be an ETH_P_XXX constant in network-byte order.
86
  * must be an ETH_P_XXX constant in network-byte order.
71
  */
87
  */
72
-struct net_protocol * net_find_protocol ( uint16_t net_proto ) {
88
+struct net_protocol * find_net_protocol ( uint16_t net_proto ) {
73
 	struct net_protocol *net_protocol;
89
 	struct net_protocol *net_protocol;
74
 
90
 
75
 	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
91
 	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
93
  * Note that even with a static single network device, this function
109
  * Note that even with a static single network device, this function
94
  * can still return NULL.
110
  * can still return NULL.
95
  */
111
  */
96
-struct net_device * net_find_address ( struct net_protocol *net_protocol,
97
-				       void *net_addr ) {
112
+struct net_device *
113
+find_netdev_by_net_addr ( struct net_protocol *net_protocol,
114
+			  void *net_addr ) {
98
 	struct net_address *net_address;
115
 	struct net_address *net_address;
99
 	struct net_device *netdev = &static_single_netdev;
116
 	struct net_device *netdev = &static_single_netdev;
100
 	
117
 	
106
 				net_protocol->net_addr_len ) == 0 ) )
123
 				net_protocol->net_addr_len ) == 0 ) )
107
 			return netdev;
124
 			return netdev;
108
 	}
125
 	}
126
+
109
 	return NULL;
127
 	return NULL;
110
 }
128
 }
111
 
129
 
112
 /**
130
 /**
113
- * Transmit packet
131
+ * Transmit packet via a network device
114
  *
132
  *
115
  * @v pkb		Packet buffer
133
  * @v pkb		Packet buffer
134
+ * @v netdev		Network device, or NULL
116
  * @ret rc		Return status code
135
  * @ret rc		Return status code
117
  *
136
  *
118
- * Transmits the packet via the appropriate network device.  If this
137
+ * Transmits the packet via the specified network device.  The packet
138
+ * must begin with a network-layer header, and the @c net_protocol
139
+ * field must have been filled in.  If @c netdev is NULL, the network
140
+ * device is identified via the packet contents, if possible.  If this
119
  * function returns success, it has taken ownership of the packet
141
  * function returns success, it has taken ownership of the packet
120
  * buffer.
142
  * buffer.
121
  */
143
  */
122
-int net_transmit ( struct pk_buff *pkb ) {
144
+int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev ) {
123
 	struct net_protocol *net_protocol;
145
 	struct net_protocol *net_protocol;
124
 	struct net_header nethdr;
146
 	struct net_header nethdr;
125
 	struct ll_protocol *ll_protocol;
147
 	struct ll_protocol *ll_protocol;
126
 	struct ll_header llhdr;
148
 	struct ll_header llhdr;
127
-	struct net_device *netdev;
128
 	int rc;
149
 	int rc;
129
 
150
 
130
 	/* Perform network-layer routing */
151
 	/* Perform network-layer routing */
131
 	net_protocol = pkb->net_protocol;
152
 	net_protocol = pkb->net_protocol;
132
 	nethdr.net_protocol = net_protocol;
153
 	nethdr.net_protocol = net_protocol;
133
-	if ( ( rc = net_protocol->route ( pkb, &nethdr ) ) != 0 )
134
-		goto err;
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
+		return rc;
159
+	}
135
 
160
 
136
-	/* Identify transmitting network device */
137
-	netdev = net_find_address ( net_protocol, nethdr.source_net_addr );
138
-	if ( ! netdev )
139
-		goto err;
161
+	/* Identify transmitting network device, if not specified */
162
+	if ( ! netdev ) {
163
+		netdev = find_netdev_by_net_addr ( net_protocol,
164
+						   nethdr.source_net_addr );
165
+		if ( ! netdev ) {
166
+			DBG ( "No network device for %s address %s\n",
167
+			      net_protocol->name,
168
+			      net_protocol->ntoa ( nethdr.source_net_addr ) );
169
+			return -EHOSTUNREACH;
170
+		}
171
+	}
140
 
172
 
141
 	/* Perform link-layer routing */
173
 	/* Perform link-layer routing */
142
 	ll_protocol = netdev->ll_protocol;
174
 	ll_protocol = netdev->ll_protocol;
143
 	llhdr.ll_protocol = ll_protocol;
175
 	llhdr.ll_protocol = ll_protocol;
144
-	llhdr.net_proto = net_protocol->net_proto;
145
-	memcpy ( llhdr.source_ll_addr, netdev->ll_addr,
146
-		 ll_protocol->ll_addr_len);
147
-	if ( ( rc = ll_protocol->route ( &nethdr, &llhdr ) ) != 0 )
148
-		goto err;
176
+	if ( ( rc = ll_protocol->route ( netdev, &nethdr, &llhdr ) ) != 0 ) {
177
+		DBG ( "No link-layer route to %s address %s\n",
178
+		      net_protocol->name,
179
+		      net_protocol->ntoa ( nethdr.dest_net_addr ) );
180
+		return rc;
181
+	}
149
 
182
 
150
 	/* Prepend link-layer header */
183
 	/* Prepend link-layer header */
151
 	pkb_push ( pkb, ll_protocol->ll_header_len );
184
 	pkb_push ( pkb, ll_protocol->ll_header_len );
152
 	ll_protocol->fill_llh ( &llhdr, pkb );
185
 	ll_protocol->fill_llh ( &llhdr, pkb );
153
 
186
 
154
 	/* Transmit packet */
187
 	/* Transmit packet */
155
-	if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 )
156
-		goto err;
157
-
188
+	if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 ) {
189
+		DBG ( "Device failed to transmit packet\n" );
190
+		return rc;
191
+	}
192
+	
193
+	DBG ( "Packet transmitted\n" );
158
 	return 0;
194
 	return 0;
195
+}
159
 
196
 
160
- err:
161
-	free_pkb ( pkb );
162
-	return rc;
197
+/**
198
+ * Transmit packet
199
+ *
200
+ * @v pkb		Packet buffer
201
+ * @ret rc		Return status code
202
+ *
203
+ * Transmits the packet via the appropriate network device.  If this
204
+ * function returns success, it has taken ownership of the packet
205
+ * buffer.
206
+ */
207
+int net_transmit ( struct pk_buff *pkb ) {
208
+	return net_transmit_via ( pkb, NULL );
163
 }
209
 }
164
 
210
 
165
 /**
211
 /**
174
 int net_poll ( void ) {
220
 int net_poll ( void ) {
175
 	struct net_device *netdev = &static_single_netdev;
221
 	struct net_device *netdev = &static_single_netdev;
176
 
222
 
223
+	DBG ( "Polling network\n" );
177
 	netdev->poll ( netdev );
224
 	netdev->poll ( netdev );
178
 
225
 
179
 	return ( ! list_empty ( &rx_queue ) );
226
 	return ( ! list_empty ( &rx_queue ) );
180
 }
227
 }
181
 
228
 
182
-/**
183
- * Add packet to receive queue
184
- *
185
- * @v netdev		Network device
186
- * @v pkb		Packet buffer
187
- *
188
- * The packet is added to the RX queue.  Ownership of the packet is
189
- * transferred to the RX queue; the caller must not touch the packet
190
- * buffer after calling netdev_rx().
191
- */
192
-void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
193
-	pkb->ll_protocol = netdev->ll_protocol;
194
-	list_add_tail ( &pkb->list, &rx_queue );
195
-}
196
-
197
 /**
229
 /**
198
  * Remove packet from receive queue
230
  * Remove packet from receive queue
199
  *
231
  *
225
 		ll_protocol->parse_llh ( pkb, &llhdr );
257
 		ll_protocol->parse_llh ( pkb, &llhdr );
226
 
258
 
227
 		/* Identify network-layer protocol */
259
 		/* Identify network-layer protocol */
228
-		net_protocol = net_find_protocol ( llhdr.net_proto );
260
+		net_protocol = find_net_protocol ( llhdr.net_proto );
229
 		if ( ! net_protocol ) {
261
 		if ( ! net_protocol ) {
230
-			DBG ( "Unknown network-layer protocol %02x\n",
262
+			DBG ( "Unknown network-layer protocol %x\n",
231
 			      ntohs ( llhdr.net_proto ) );
263
 			      ntohs ( llhdr.net_proto ) );
232
 			free_pkb ( pkb );
264
 			free_pkb ( pkb );
233
 			continue;
265
 			continue;
234
 		}
266
 		}
267
+		pkb->net_protocol = net_protocol;
235
 
268
 
236
 		/* Strip off link-layer header */
269
 		/* Strip off link-layer header */
237
 		pkb_pull ( pkb, ll_protocol->ll_header_len );
270
 		pkb_pull ( pkb, ll_protocol->ll_header_len );
238
 
271
 
239
 		/* Hand off to network layer */
272
 		/* Hand off to network layer */
240
 		if ( net_protocol->rx ( pkb ) != 0 ) {
273
 		if ( net_protocol->rx ( pkb ) != 0 ) {
274
+			DBG ( "Network-layer protocol refused packet\n" );
241
 			free_pkb ( pkb );
275
 			free_pkb ( pkb );
242
 			continue;
276
 			continue;
243
 		}
277
 		}
278
+
279
+		DBG ( "Processed received packet\n" );
244
 	}
280
 	}
245
 }
281
 }
246
 
282
 

Loading…
Cancel
Save