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,10 +7,12 @@
7 7
  *
8 8
  */
9 9
 
10
+struct net_device;
10 11
 struct net_header;
11 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 16
 			 struct ll_header *llhdr );
15 17
 
16 18
 #endif /* _GPXE_ARP_H */

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

@@ -11,12 +11,16 @@
11 11
 #include <gpxe/tables.h>
12 12
 
13 13
 struct pk_buff;
14
+struct net_device;
14 15
 struct net_protocol;
15 16
 struct ll_protocol;
16 17
 
17 18
 /** Maximum length of a link-layer address */
18 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 24
 /** Maximum length of a network-layer address */
21 25
 #define MAX_NET_ADDR_LEN 4
22 26
 
@@ -32,37 +36,37 @@ struct ll_protocol;
32 36
 struct net_header {
33 37
 	/** Network-layer protocol */
34 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 42
 	 * values.
39 43
 	 */
40
-	int dest_flags;
44
+	int flags;
41 45
 	/** Network-layer destination address */
42 46
 	uint8_t dest_net_addr[MAX_NET_ADDR_LEN];
43 47
 	/** Network-layer source address */
44 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 60
 /** A generic link-layer header */
57 61
 struct ll_header {
58 62
 	/** Link-layer protocol */
59 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 67
 	 * values.
64 68
 	 */
65
-	int dest_flags;
69
+	int flags;
66 70
 	/** Link-layer destination address */
67 71
 	uint8_t dest_ll_addr[MAX_LL_ADDR_LEN];
68 72
 	/** Link-layer source address */
@@ -80,21 +84,21 @@ struct ll_header {
80 84
  *
81 85
  */
82 86
 struct net_protocol {
87
+	/** Protocol name */
88
+	const char *name;
83 89
 	/**
84 90
 	 * Perform network-layer routing
85 91
 	 *
86 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 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 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 103
 	int ( * route ) ( const struct pk_buff *pkb,
100 104
 			  struct net_header *nethdr );
@@ -108,6 +112,19 @@ struct net_protocol {
108 112
 	 * the packet buffer.
109 113
 	 */
110 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 128
 	/** Network-layer protocol
112 129
 	 *
113 130
 	 * This is an ETH_P_XXX constant, in network-byte order
@@ -122,9 +139,12 @@ struct net_protocol {
122 139
  *
123 140
  */
124 141
 struct ll_protocol {
142
+	/** Protocol name */
143
+	const char *name;
125 144
 	/**
126 145
 	 * Perform link-layer routing
127 146
 	 *
147
+	 * @v netdev	Network device
128 148
 	 * @v nethdr	Generic network-layer header
129 149
 	 * @ret llhdr	Generic link-layer header
130 150
 	 * @ret rc	Return status code
@@ -137,7 +157,8 @@ struct ll_protocol {
137 157
 	 * return an error (after transmitting an ARP request, if
138 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 162
 			  struct ll_header *llhdr );
142 163
 	/**
143 164
 	 * Fill media-specific link-layer header
@@ -164,6 +185,19 @@ struct ll_protocol {
164 185
 	void ( * parse_llh ) ( const struct pk_buff *pkb,
165 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 201
 	/** Link-layer protocol
168 202
 	 *
169 203
 	 * This is an ARPHRD_XXX constant, in network byte order.
@@ -290,13 +324,30 @@ free_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
290 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 345
  * Register a link-layer protocol
295 346
  *
296 347
  * @v protocol		Link-layer protocol
297 348
  */
298 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 353
  * Register a network-layer protocol
@@ -304,7 +355,7 @@ free_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
304 355
  * @v protocol		Network-layer protocol
305 356
  */
306 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 361
  * Register a network-layer address for the static single network device
@@ -312,15 +363,17 @@ free_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
312 363
  * @v net_address	Network-layer address
313 364
  */
314 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 375
 extern int net_transmit ( struct pk_buff *pkb );
322 376
 extern int net_poll ( void );
323
-extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
324 377
 extern struct pk_buff * net_rx_dequeue ( void );
325 378
 
326 379
 #endif /* _GPXE_NETDEVICE_H */

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

@@ -91,6 +91,7 @@ arp_find_entry ( struct ll_protocol *ll_protocol,
91 91
 /**
92 92
  * Look up media-specific link-layer address in the ARP cache
93 93
  *
94
+ * @v netdev		Network device
94 95
  * @v nethdr		Generic network-layer header
95 96
  * @ret llhdr		Generic link-layer header
96 97
  * @ret rc		Return status code
@@ -102,9 +103,11 @@ arp_find_entry ( struct ll_protocol *ll_protocol,
102 103
  * llhdr.
103 104
  *
104 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 111
 	struct net_protocol *net_protocol = nethdr->net_protocol;
109 112
 	struct ll_protocol *ll_protocol = llhdr->ll_protocol;
110 113
 	const struct arp_entry *arp;
@@ -116,17 +119,23 @@ int arp_resolve ( const struct net_header *nethdr, struct ll_header *llhdr ) {
116 119
 	arp = arp_find_entry ( ll_protocol, net_protocol,
117 120
 			       nethdr->dest_net_addr );
118 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 125
 		memcpy ( llhdr->dest_ll_addr, arp->ll_addr,
120 126
 			 sizeof ( llhdr->dest_ll_addr ) );
121 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 132
 	/* Allocate ARP packet */
125
-	pkb = alloc_pkb ( sizeof ( *arphdr ) +
133
+	pkb = alloc_pkb ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
126 134
 			  2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
127 135
 	if ( ! pkb )
128 136
 		return -ENOMEM;
129 137
 	pkb->net_protocol = &arp_protocol;
138
+	pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
130 139
 
131 140
 	/* Build up ARP request */
132 141
 	arphdr = pkb_put ( pkb, sizeof ( *arphdr ) );
@@ -145,7 +154,7 @@ int arp_resolve ( const struct net_header *nethdr, struct ll_header *llhdr ) {
145 154
 		 nethdr->dest_net_addr, net_protocol->net_addr_len );
146 155
 
147 156
 	/* Transmit ARP request */
148
-	if ( ( rc = net_transmit ( pkb ) ) != 0 ) {
157
+	if ( ( rc = net_transmit_via ( pkb, netdev ) ) != 0 ) {
149 158
 		free_pkb ( pkb );
150 159
 		return rc;
151 160
 	}
@@ -175,7 +184,7 @@ static int arp_rx ( struct pk_buff *pkb ) {
175 184
 
176 185
 	/* Identify link-layer and network-layer protocols */
177 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 188
 	if ( ! net_protocol )
180 189
 		goto done;
181 190
 
@@ -192,10 +201,14 @@ static int arp_rx ( struct pk_buff *pkb ) {
192 201
 		memcpy ( arp->ll_addr, arp_sender_ha ( arphdr ),
193 202
 			 arphdr->ar_hln );
194 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 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 212
 	if ( ! netdev )
200 213
 		goto done;
201 214
 	
@@ -208,6 +221,9 @@ static int arp_rx ( struct pk_buff *pkb ) {
208 221
 			 arphdr->ar_hln );
209 222
 		memcpy ( arp->net_addr, arp_sender_pa ( arphdr ),
210 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 229
 	/* If it's not a request, there's nothing more to do */
@@ -215,11 +231,14 @@ static int arp_rx ( struct pk_buff *pkb ) {
215 231
 		goto done;
216 232
 
217 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 237
 	arphdr->ar_op = htons ( ARPOP_REPLY );
219 238
 	memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ),
220 239
 		 arphdr->ar_hln + arphdr->ar_pln );
221 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 242
 		pkb = NULL;
224 243
 
225 244
  done:
@@ -243,18 +262,33 @@ static int arp_route ( const struct pk_buff *pkb,
243 262
 		 arphdr->ar_hln );
244 263
 	memcpy ( nethdr->dest_net_addr, arp_target_ha ( arphdr ),
245 264
 		 arphdr->ar_hln );
246
-	nethdr->dest_flags = NETADDR_FL_RAW;
265
+	nethdr->flags = PKT_FL_RAW_ADDR;
247 266
 	if ( arphdr->ar_op == htons ( ARPOP_REQUEST ) )
248
-		nethdr->dest_flags |= NETADDR_FL_BROADCAST;
267
+		nethdr->flags |= PKT_FL_BROADCAST;
249 268
 	
250 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 285
 /** ARP protocol */
254 286
 struct net_protocol arp_protocol = {
287
+	.name = "ARP",
255 288
 	.net_proto = htons ( ETH_P_ARP ),
256 289
 	.rx = arp_rx,
257 290
 	.route = arp_route,
291
+	.ntoa = arp_ntoa,
258 292
 };
259 293
 
260 294
 NET_PROTOCOL ( arp_protocol );

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

@@ -51,16 +51,21 @@ static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
51 51
  * is sent for the requested network-layer address and -ENOENT is
52 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 56
 		       struct ll_header *llhdr ) {
56 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 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 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 69
 		/* IP multicast is a special case; there exists a
65 70
 		 * direct mapping from IP address to MAC address
66 71
 		 */
@@ -73,7 +78,7 @@ static int eth_route ( const struct net_header *nethdr,
73 78
 		llhdr->dest_ll_addr[5] = nethdr->dest_net_addr[3];
74 79
 	} else {
75 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 82
 			return rc;
78 83
 	}
79 84
 
@@ -116,22 +121,40 @@ static void eth_parse_llh ( const struct pk_buff *pkb,
116 121
 	llhdr->net_proto = ethhdr->h_protocol;
117 122
 
118 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 125
 	} else if ( ethhdr->h_dest[0] & 0x01 ) {
121
-		llhdr->dest_flags = NETADDR_FL_MULTICAST;
126
+		llhdr->flags = PKT_FL_MULTICAST;
122 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 148
 /** Ethernet protocol */
128 149
 struct ll_protocol ethernet_protocol = {
150
+	.name = "Ethernet",
129 151
 	.ll_proto = htons ( ARPHRD_ETHER ),
130 152
 	.ll_addr_len = ETH_ALEN,
131 153
 	.ll_header_len = ETH_HLEN,
132 154
 	.route = eth_route,
133 155
 	.fill_llh = eth_fill_llh,
134 156
 	.parse_llh = eth_parse_llh,
157
+	.ntoa = eth_ntoa,
135 158
 };
136 159
 
137 160
 LL_PROTOCOL ( ethernet_protocol );

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

@@ -1,6 +1,7 @@
1 1
 #include <string.h>
2 2
 #include <stdint.h>
3 3
 #include <byteswap.h>
4
+#include <vsprintf.h>
4 5
 #include <gpxe/in.h>
5 6
 
6 7
 
@@ -153,7 +154,8 @@ static int ipv4_rx ( struct pk_buff *pkb ) {
153 154
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
154 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 160
 	/* Hand to uIP for processing */
159 161
 	uip_input ();
@@ -198,22 +200,40 @@ static int ipv4_route ( const struct pk_buff *pkb,
198 200
 	}
199 201
 
200 202
 	/* Set broadcast and multicast flags as applicable */
201
-	nethdr->dest_flags = 0;
203
+	nethdr->flags = 0;
202 204
 	if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) {
203
-		nethdr->dest_flags = NETADDR_FL_BROADCAST;
205
+		nethdr->flags = PKT_FL_BROADCAST;
204 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 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 229
 /** IPv4 protocol */
212 230
 struct net_protocol ipv4_protocol = {
213
-	.net_proto = ETH_P_IP,
231
+	.name = "IP",
232
+	.net_proto = htons ( ETH_P_IP ),
214 233
 	.net_addr_len = sizeof ( struct in_addr ),
215 234
 	.rx = ipv4_rx,
216 235
 	.route = ipv4_route,
236
+	.ntoa = ipv4_ntoa,
217 237
 };
218 238
 
219 239
 NET_PROTOCOL ( ipv4_protocol );
@@ -221,6 +241,18 @@ NET_PROTOCOL ( ipv4_protocol );
221 241
 /** IPv4 address for the static single net device */
222 242
 struct net_address static_single_ipv4_address = {
223 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 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,6 +60,22 @@ static struct net_address static_single_netdev_addresses_end[0]
60 60
 /** Recevied packet queue */
61 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 80
  * Identify network protocol
65 81
  *
@@ -69,7 +85,7 @@ static LIST_HEAD ( rx_queue );
69 85
  * Identify a network-layer protocol from a protocol number, which
70 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 89
 	struct net_protocol *net_protocol;
74 90
 
75 91
 	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
@@ -93,8 +109,9 @@ struct net_protocol * net_find_protocol ( uint16_t net_proto ) {
93 109
  * Note that even with a static single network device, this function
94 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 115
 	struct net_address *net_address;
99 116
 	struct net_device *netdev = &static_single_netdev;
100 117
 	
@@ -106,60 +123,89 @@ struct net_device * net_find_address ( struct net_protocol *net_protocol,
106 123
 				net_protocol->net_addr_len ) == 0 ) )
107 124
 			return netdev;
108 125
 	}
126
+
109 127
 	return NULL;
110 128
 }
111 129
 
112 130
 /**
113
- * Transmit packet
131
+ * Transmit packet via a network device
114 132
  *
115 133
  * @v pkb		Packet buffer
134
+ * @v netdev		Network device, or NULL
116 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 141
  * function returns success, it has taken ownership of the packet
120 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 145
 	struct net_protocol *net_protocol;
124 146
 	struct net_header nethdr;
125 147
 	struct ll_protocol *ll_protocol;
126 148
 	struct ll_header llhdr;
127
-	struct net_device *netdev;
128 149
 	int rc;
129 150
 
130 151
 	/* Perform network-layer routing */
131 152
 	net_protocol = pkb->net_protocol;
132 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 173
 	/* Perform link-layer routing */
142 174
 	ll_protocol = netdev->ll_protocol;
143 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 183
 	/* Prepend link-layer header */
151 184
 	pkb_push ( pkb, ll_protocol->ll_header_len );
152 185
 	ll_protocol->fill_llh ( &llhdr, pkb );
153 186
 
154 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 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,26 +220,12 @@ int net_transmit ( struct pk_buff *pkb ) {
174 220
 int net_poll ( void ) {
175 221
 	struct net_device *netdev = &static_single_netdev;
176 222
 
223
+	DBG ( "Polling network\n" );
177 224
 	netdev->poll ( netdev );
178 225
 
179 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 230
  * Remove packet from receive queue
199 231
  *
@@ -225,22 +257,26 @@ void net_run ( void ) {
225 257
 		ll_protocol->parse_llh ( pkb, &llhdr );
226 258
 
227 259
 		/* Identify network-layer protocol */
228
-		net_protocol = net_find_protocol ( llhdr.net_proto );
260
+		net_protocol = find_net_protocol ( llhdr.net_proto );
229 261
 		if ( ! net_protocol ) {
230
-			DBG ( "Unknown network-layer protocol %02x\n",
262
+			DBG ( "Unknown network-layer protocol %x\n",
231 263
 			      ntohs ( llhdr.net_proto ) );
232 264
 			free_pkb ( pkb );
233 265
 			continue;
234 266
 		}
267
+		pkb->net_protocol = net_protocol;
235 268
 
236 269
 		/* Strip off link-layer header */
237 270
 		pkb_pull ( pkb, ll_protocol->ll_header_len );
238 271
 
239 272
 		/* Hand off to network layer */
240 273
 		if ( net_protocol->rx ( pkb ) != 0 ) {
274
+			DBG ( "Network-layer protocol refused packet\n" );
241 275
 			free_pkb ( pkb );
242 276
 			continue;
243 277
 		}
278
+
279
+		DBG ( "Processed received packet\n" );
244 280
 	}
245 281
 }
246 282
 

Loading…
Cancel
Save