Browse Source

Simplify RX data path.

Kill off the static single net device and move to proper dynamic
registration (which we need with the new device model).

Break the (flawed) assumption that all network-layer protocols can use
ARP; such network-layer protocols (i.e. IPv4) must now register as an ARP
protocol using ARP_NET_PROTOCOL() and provide a single method for checking
the existence of a local network-layer address.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
3c8aafa209

+ 2
- 9
src/core/main.c View File

145
 static int initialized;
145
 static int initialized;
146
 
146
 
147
 
147
 
148
-extern struct net_device static_single_netdev;
149
-
150
-
151
 /**************************************************************************
148
 /**************************************************************************
152
 MAIN - Kick off routine
149
 MAIN - Kick off routine
153
 **************************************************************************/
150
 **************************************************************************/
159
 	call_init_fns ();
156
 	call_init_fns ();
160
 	probe_devices();
157
 	probe_devices();
161
 
158
 
162
-	/* Quick hack until netdevice.c uses proper dynamic registration */
163
-	netdev = &static_single_netdev;
164
-	if ( ! netdev->poll )
165
-		netdev = NULL;
166
-
159
+	netdev = next_netdev ();
167
 	if ( netdev ) {
160
 	if ( netdev ) {
168
-		test_aoeboot ( &static_single_netdev );
161
+		test_aoeboot ( netdev );
169
 	} else {
162
 	} else {
170
 		printf ( "No network device found\n" );
163
 		printf ( "No network device found\n" );
171
 	}
164
 	}

+ 24
- 0
src/include/gpxe/arp.h View File

7
  *
7
  *
8
  */
8
  */
9
 
9
 
10
+#include <gpxe/tables.h>
11
+
10
 struct net_device;
12
 struct net_device;
11
 struct net_protocol;
13
 struct net_protocol;
12
 
14
 
15
+/** A network-layer protocol that relies upon ARP */
16
+struct arp_net_protocol {
17
+	/** Network-layer protocol */
18
+	struct net_protocol *net_protocol;
19
+	/** Check existence of address
20
+	 *
21
+	 * @v netdev	Network device
22
+	 * @v net_addr	Network-layer address
23
+	 * @ret rc	Return status code
24
+	 */
25
+	int ( * check ) ( struct net_device *netdev,
26
+			  const void *net_addr );
27
+};
28
+
29
+/**
30
+ * Register an ARP protocol
31
+ *
32
+ * @v protocol		ARP protocol
33
+ */
34
+#define ARP_NET_PROTOCOL( protocol ) \
35
+	struct arp_net_protocol protocol __table ( arp_net_protocols, 01 )
36
+
13
 extern int arp_resolve ( struct net_device *netdev,
37
 extern int arp_resolve ( struct net_device *netdev,
14
 			 struct net_protocol *net_protocol,
38
 			 struct net_protocol *net_protocol,
15
 			 const void *dest_net_addr,
39
 			 const void *dest_net_addr,

+ 9
- 6
src/include/gpxe/ethernet.h View File

18
  * @v priv_size		Size of driver private data
18
  * @v priv_size		Size of driver private data
19
  * @ret netdev		Network device, or NULL
19
  * @ret netdev		Network device, or NULL
20
  */
20
  */
21
-#define alloc_etherdev( priv_size ) ( {				\
22
-	struct net_device *netdev;				\
23
-	netdev = alloc_netdev ( priv_size );			\
24
-	if ( netdev )						\
25
-		netdev->ll_protocol = &ethernet_protocol;	\
26
-	netdev;	} )
21
+static inline struct net_device * alloc_etherdev ( size_t priv_size ) {
22
+	struct net_device *netdev;
23
+
24
+	netdev = alloc_netdev ( priv_size );
25
+	if ( netdev ) {
26
+		netdev->ll_protocol = &ethernet_protocol;
27
+	}
28
+	return netdev;
29
+}
27
 
30
 
28
 #endif /* _GPXE_ETHERNET_H */
31
 #endif /* _GPXE_ETHERNET_H */

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

7
  *
7
  *
8
  */
8
  */
9
 
9
 
10
+#include <ip.h>
11
+
10
 struct net_protocol;
12
 struct net_protocol;
11
 
13
 
12
 extern struct net_protocol ipv4_protocol;
14
 extern struct net_protocol ipv4_protocol;
15
 			      struct in_addr address, struct in_addr netmask,
17
 			      struct in_addr address, struct in_addr netmask,
16
 			      struct in_addr gateway );
18
 			      struct in_addr gateway );
17
 extern void del_ipv4_address ( struct net_device *netdev );
19
 extern void del_ipv4_address ( struct net_device *netdev );
18
-extern int ipv4_uip_transmit ( struct pk_buff *pkb );
20
+extern int ipv4_uip_tx ( struct pk_buff *pkb );
19
 
21
 
20
 #endif /* _GPXE_IP_H */
22
 #endif /* _GPXE_IP_H */

+ 39
- 163
src/include/gpxe/netdevice.h View File

8
  */
8
  */
9
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
+#include <gpxe/list.h>
11
 #include <gpxe/tables.h>
12
 #include <gpxe/tables.h>
12
 
13
 
13
 struct pk_buff;
14
 struct pk_buff;
24
 /** Maximum length of a network-layer address */
25
 /** Maximum length of a network-layer address */
25
 #define MAX_NET_ADDR_LEN 4
26
 #define MAX_NET_ADDR_LEN 4
26
 
27
 
27
-/* Network-layer address may be required to hold a link-layer address
28
- * (if NETADDR_FL_RAW is set
29
- */
30
-#if MAX_NET_ADDR_LEN < MAX_LL_ADDR_LEN
31
-#undef MAX_NET_ADDR_LEN
32
-#define MAX_NET_ADDR_LEN MAX_LL_ADDR_LEN
33
-#endif
34
-
35
-/** A generic network-layer header */
36
-struct net_header {
37
-	/** Network-layer protocol */
38
-	struct net_protocol *net_protocol;
39
-	/** Flags
40
-	 *
41
-	 * This is the bitwise OR of zero or more PKT_FL_XXX
42
-	 * values.
43
-	 */
44
-	int flags;
45
-	/** Network-layer destination address */
46
-	uint8_t dest_net_addr[MAX_NET_ADDR_LEN];
47
-	/** Network-layer source address */
48
-	uint8_t source_net_addr[MAX_NET_ADDR_LEN];
49
-};
50
-
51
-/** Packet is a broadcast packet */
52
-#define PKT_FL_BROADCAST 0x01
53
-
54
-/** Packet is a multicast packet */
55
-#define PKT_FL_MULTICAST 0x02
56
-
57
-/** Addresses are raw hardware addresses */
58
-#define PKT_FL_RAW_ADDR 0x04
59
-
60
-/** A generic link-layer header */
61
-struct ll_header {
62
-	/** Link-layer protocol */
63
-	struct ll_protocol *ll_protocol;
64
-	/** Flags
65
-	 *
66
-	 * This is the bitwise OR of zero or more PKT_FL_XXX
67
-	 * values.
68
-	 */
69
-	int flags;
70
-	/** Link-layer destination address */
71
-	uint8_t dest_ll_addr[MAX_LL_ADDR_LEN];
72
-	/** Link-layer source address */
73
-	uint8_t source_ll_addr[MAX_LL_ADDR_LEN];
74
-	/** Network-layer protocol
75
-	 *
76
-	 *
77
-	 * This is an ETH_P_XXX constant, in network-byte order
78
-	 */
79
-	uint16_t net_proto;
80
-};
81
-
82
 /**
28
 /**
83
  * A network-layer protocol
29
  * A network-layer protocol
84
  *
30
  *
90
 	 * Process received packet
36
 	 * Process received packet
91
 	 *
37
 	 *
92
 	 * @v pkb	Packet buffer
38
 	 * @v pkb	Packet buffer
93
-	 * @ret rc	Return status code
39
+	 * @v netdev	Network device
40
+	 * @v ll_source	Link-layer source address
94
 	 *
41
 	 *
95
 	 * This method takes ownership of the packet buffer.
42
 	 * This method takes ownership of the packet buffer.
96
 	 */
43
 	 */
97
-	int ( * rx_process ) ( struct pk_buff *pkb );
44
+	int ( * rx ) ( struct pk_buff *pkb, struct net_device *netdev,
45
+		       const void *ll_source );
98
 	/**
46
 	/**
99
 	 * Transcribe network-layer address
47
 	 * Transcribe network-layer address
100
 	 *
48
 	 *
127
 	/**
75
 	/**
128
 	 * Transmit network-layer packet via network device
76
 	 * Transmit network-layer packet via network device
129
 	 *
77
 	 *
130
-	 *
131
 	 * @v pkb		Packet buffer
78
 	 * @v pkb		Packet buffer
132
 	 * @v netdev		Network device
79
 	 * @v netdev		Network device
133
 	 * @v net_protocol	Network-layer protocol
80
 	 * @v net_protocol	Network-layer protocol
137
 	 * This method should prepend in the link-layer header
84
 	 * This method should prepend in the link-layer header
138
 	 * (e.g. the Ethernet DIX header) and transmit the packet.
85
 	 * (e.g. the Ethernet DIX header) and transmit the packet.
139
 	 */
86
 	 */
140
-	int ( * transmit ) ( struct pk_buff *pkb, struct net_device *netdev,
141
-			     struct net_protocol *net_protocol,
142
-			     const void *ll_dest );
87
+	int ( * tx ) ( struct pk_buff *pkb, struct net_device *netdev,
88
+		       struct net_protocol *net_protocol,
89
+		       const void *ll_dest );
143
 	/**
90
 	/**
144
-	 * Parse media-specific link-layer header
91
+	 * Handle received packet
145
 	 *
92
 	 *
146
 	 * @v pkb	Packet buffer
93
 	 * @v pkb	Packet buffer
147
-	 * @v llhdr	Generic link-layer header
94
+	 * @v netdev	Network device
148
 	 *
95
 	 *
149
-	 * This method should fill in the generic link-layer header
150
-	 * based on information in the link-layer header in the packet
151
-	 * buffer.
96
+	 * This method should strip off the link-layer header
97
+	 * (e.g. the Ethernet DIX header) and pass the packet to
98
+	 * net_rx().
152
 	 */
99
 	 */
153
-	void ( * parse_llh ) ( const struct pk_buff *pkb,
154
-			       struct ll_header *llhdr );
155
-
100
+	void ( * rx ) ( struct pk_buff *pkb, struct net_device *netdev );
156
 	/**
101
 	/**
157
 	 * Transcribe link-layer address
102
 	 * Transcribe link-layer address
158
 	 *
103
 	 *
165
 	 * The buffer used to hold the transcription is statically
110
 	 * The buffer used to hold the transcription is statically
166
 	 * allocated.
111
 	 * allocated.
167
 	 */
112
 	 */
168
-	const char * ( *ntoa ) ( const void * ll_addr );
113
+	const char * ( * ntoa ) ( const void * ll_addr );
169
 	/** Link-layer protocol
114
 	/** Link-layer protocol
170
 	 *
115
 	 *
171
 	 * This is an ARPHRD_XXX constant, in network byte order.
116
 	 * This is an ARPHRD_XXX constant, in network byte order.
177
 	const uint8_t *ll_broadcast;
122
 	const uint8_t *ll_broadcast;
178
 };
123
 };
179
 
124
 
180
-/**
181
- * A network-layer address assigned to a network device
182
- *
183
- */
184
-struct net_address {
185
-	/** Network-layer protocol */
186
-	struct net_protocol *net_protocol;
187
-	/** Network-layer address */
188
-	uint8_t net_addr[MAX_NET_ADDR_LEN];
189
-};
190
-
191
 /**
125
 /**
192
  * A network device
126
  * A network device
193
  *
127
  *
199
  * not just an Ethernet device.
133
  * not just an Ethernet device.
200
  */
134
  */
201
 struct net_device {
135
 struct net_device {
136
+	/** List of network devices */
137
+	struct list_head list;
202
 	/** Transmit packet
138
 	/** Transmit packet
203
 	 *
139
 	 *
204
 	 * @v netdev	Network device
140
 	 * @v netdev	Network device
231
 	 */
167
 	 */
232
 	uint8_t ll_addr[MAX_LL_ADDR_LEN];
168
 	uint8_t ll_addr[MAX_LL_ADDR_LEN];
233
 
169
 
170
+	/** Received packet queue */
171
+	struct list_head rx_queue;
172
+
234
 	/** Driver private data */
173
 	/** Driver private data */
235
 	void *priv;
174
 	void *priv;
236
 };
175
 };
237
 
176
 
238
-extern struct net_device static_single_netdev;
239
-
240
-/**
241
- * Allocate network device
242
- *
243
- * @v priv_size		Size of private data area (net_device::priv)
244
- * @ret netdev		Network device, or NULL
245
- *
246
- * Allocates space for a network device and its private data area.
247
- *
248
- * This macro allows for a very efficient implementation in the case
249
- * of a single static network device; it neatly avoids dynamic
250
- * allocation and can never return failure, meaning that the failure
251
- * path will be optimised away.  However, driver writers should not
252
- * rely on this feature; the drivers should be written to allow for
253
- * multiple instances of network devices.
254
- */
255
-#define alloc_netdev( priv_size ) ( {		\
256
-	static char priv_data[priv_size];	\
257
-	static_single_netdev.priv = priv_data;	\
258
-	&static_single_netdev; } )
259
-
260
-/**
261
- * Free network device
262
- *
263
- * @v netdev		Network device
264
- */
265
-static inline void
266
-free_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
267
-	/* Nothing to do */
268
-}
269
-
270
-/**
271
- * Transmit raw packet via network device
272
- *
273
- * @v netdev		Network device
274
- * @v pkb		Packet buffer
275
- * @ret rc		Return status code
276
- *
277
- * Transmits the packet via the specified network device.  The
278
- * link-layer header must already have been filled in.  This function
279
- * takes ownership of the packet buffer.
280
- */
281
-static inline int netdev_transmit ( struct net_device *netdev,
282
-				    struct pk_buff *pkb ) {
283
-	return netdev->transmit ( netdev, pkb );
284
-}
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
-
307
 /**
177
 /**
308
  * Register a link-layer protocol
178
  * Register a link-layer protocol
309
  *
179
  *
321
 	struct net_protocol protocol __table ( net_protocols, 01 )
191
 	struct net_protocol protocol __table ( net_protocols, 01 )
322
 
192
 
323
 /**
193
 /**
324
- * Register a network-layer address for the static single network device
194
+ * Get network device name
195
+ *
196
+ * @v netdev		Network device
197
+ * @ret name		Network device name
325
  *
198
  *
326
- * @v net_address	Network-layer address
199
+ * The name will be the device's link-layer address.
327
  */
200
  */
328
-#define STATIC_SINGLE_NETDEV_ADDRESS( address ) \
329
-	struct net_address address __table ( sgl_netdev_addresses, 01 )
201
+static inline const char * netdev_name ( struct net_device *netdev ) {
202
+	return netdev->ll_protocol->ntoa ( netdev->ll_addr );
203
+}
330
 
204
 
205
+extern int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb );
206
+extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
207
+extern int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
208
+		    struct net_protocol *net_protocol, const void *ll_dest );
209
+extern void net_rx ( struct pk_buff *pkb, struct net_device *netdev,
210
+		     uint16_t net_proto, const void *ll_source );
211
+extern int netdev_poll ( struct net_device *netdev );
212
+extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
213
+extern struct net_device * alloc_netdev ( size_t priv_size );
331
 extern int register_netdev ( struct net_device *netdev );
214
 extern int register_netdev ( struct net_device *netdev );
332
 extern void unregister_netdev ( struct net_device *netdev );
215
 extern void unregister_netdev ( struct net_device *netdev );
333
-extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
334
-
335
-extern struct net_protocol *find_net_protocol ( uint16_t net_proto );
336
-extern struct net_device *
337
-find_netdev_by_net_addr ( struct net_protocol *net_protocol, void *net_addr );
338
-
339
-extern int net_poll ( void );
340
-extern struct pk_buff * net_rx_dequeue ( void );
341
-extern int net_rx_process ( struct pk_buff *pkb );
216
+extern void free_netdev ( struct net_device *netdev );
217
+extern struct net_device * next_netdev ( void );
342
 
218
 
343
 #endif /* _GPXE_NETDEVICE_H */
219
 #endif /* _GPXE_NETDEVICE_H */

+ 3
- 11
src/include/gpxe/pkbuff.h View File

14
 #include <assert.h>
14
 #include <assert.h>
15
 #include <gpxe/list.h>
15
 #include <gpxe/list.h>
16
 
16
 
17
-struct net_protocol;
18
-struct ll_protocol;
19
-
20
 /**
17
 /**
21
  * Packet buffer alignment
18
  * Packet buffer alignment
22
  *
19
  *
42
  * This structure is used to represent a network packet within gPXE.
39
  * This structure is used to represent a network packet within gPXE.
43
  */
40
  */
44
 struct pk_buff {
41
 struct pk_buff {
42
+	/** List of which this buffer is a member */
43
+	struct list_head list;
44
+
45
 	/** Start of the buffer */
45
 	/** Start of the buffer */
46
 	void *head;
46
 	void *head;
47
 	/** Start of data */
47
 	/** Start of data */
50
 	void *tail;
50
 	void *tail;
51
 	/** End of the buffer */
51
 	/** End of the buffer */
52
         void *end;
52
         void *end;
53
-
54
-	/** List of which this buffer is a member */
55
-	struct list_head list;
56
-
57
-	/** The network-layer protocol */
58
-	struct net_protocol *net_protocol;
59
-	/** The link-layer protocol */
60
-	struct ll_protocol *ll_protocol;
61
 };
53
 };
62
 
54
 
63
 /**
55
 /**

+ 7
- 7
src/net/aoe.c View File

87
 			  data_out_len );
87
 			  data_out_len );
88
 	if ( ! pkb )
88
 	if ( ! pkb )
89
 		return -ENOMEM;
89
 		return -ENOMEM;
90
-	pkb->net_protocol = &aoe_protocol;
91
 	pkb_reserve ( pkb, ETH_HLEN );
90
 	pkb_reserve ( pkb, ETH_HLEN );
92
 	aoehdr = pkb_put ( pkb, sizeof ( *aoehdr ) );
91
 	aoehdr = pkb_put ( pkb, sizeof ( *aoehdr ) );
93
 	aoecmd = pkb_put ( pkb, sizeof ( *aoecmd ) );
92
 	aoecmd = pkb_put ( pkb, sizeof ( *aoecmd ) );
117
 
116
 
118
 	/* Send packet */
117
 	/* Send packet */
119
 	start_timer ( &aoe->timer );
118
 	start_timer ( &aoe->timer );
120
-	return net_transmit ( pkb, aoe->netdev, &aoe_protocol, aoe->target );
119
+	return net_tx ( pkb, aoe->netdev, &aoe_protocol, aoe->target );
121
 }
120
 }
122
 
121
 
123
 /**
122
 /**
209
  * Process incoming AoE packets
208
  * Process incoming AoE packets
210
  *
209
  *
211
  * @v pkb		Packet buffer
210
  * @v pkb		Packet buffer
211
+ * @v netdev		Network device
212
+ * @v ll_source		Link-layer source address
212
  * @ret rc		Return status code
213
  * @ret rc		Return status code
213
  *
214
  *
214
  */
215
  */
215
-static int aoe_rx ( struct pk_buff *pkb ) {
216
+static int aoe_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
217
+		    const void *ll_source ) {
216
 	struct aoehdr *aoehdr = pkb->data;
218
 	struct aoehdr *aoehdr = pkb->data;
217
 	unsigned int len = pkb_len ( pkb );
219
 	unsigned int len = pkb_len ( pkb );
218
-	struct ethhdr *ethhdr = pkb_push ( pkb, sizeof ( *ethhdr ) );
219
 	struct aoe_session *aoe;
220
 	struct aoe_session *aoe;
220
 	int rc = 0;
221
 	int rc = 0;
221
 
222
 
241
 			continue;
242
 			continue;
242
 		if ( ntohl ( aoehdr->tag ) != aoe->tag )
243
 		if ( ntohl ( aoehdr->tag ) != aoe->tag )
243
 			continue;
244
 			continue;
244
-		memcpy ( aoe->target, ethhdr->h_source,
245
-			 sizeof ( aoe->target ) );
245
+		memcpy ( aoe->target, ll_source, sizeof ( aoe->target ) );
246
 		rc = aoe_rx_response ( aoe, aoehdr, len );
246
 		rc = aoe_rx_response ( aoe, aoehdr, len );
247
 		break;
247
 		break;
248
 	}
248
 	}
256
 struct net_protocol aoe_protocol = {
256
 struct net_protocol aoe_protocol = {
257
 	.name = "AoE",
257
 	.name = "AoE",
258
 	.net_proto = htons ( ETH_P_AOE ),
258
 	.net_proto = htons ( ETH_P_AOE ),
259
-	.rx_process = aoe_rx,
259
+	.rx = aoe_rx,
260
 };
260
 };
261
 
261
 
262
 NET_PROTOCOL ( aoe_protocol );
262
 NET_PROTOCOL ( aoe_protocol );

+ 41
- 15
src/net/arp.c View File

36
  *
36
  *
37
  */
37
  */
38
 
38
 
39
+/** Registered ARP protocols */
40
+static struct arp_net_protocol arp_net_protocols[0]
41
+	__table_start ( arp_net_protocols );
42
+static struct arp_net_protocol arp_net_protocols_end[0]
43
+	__table_end ( arp_net_protocols );
44
+
39
 /** An ARP cache entry */
45
 /** An ARP cache entry */
40
 struct arp_entry {
46
 struct arp_entry {
41
 	/** Network-layer protocol */
47
 	/** Network-layer protocol */
134
 			  2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
140
 			  2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
135
 	if ( ! pkb )
141
 	if ( ! pkb )
136
 		return -ENOMEM;
142
 		return -ENOMEM;
137
-	pkb->net_protocol = &arp_protocol;
138
 	pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
143
 	pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
139
 
144
 
140
 	/* Build up ARP request */
145
 	/* Build up ARP request */
154
 		 dest_net_addr, net_protocol->net_addr_len );
159
 		 dest_net_addr, net_protocol->net_addr_len );
155
 
160
 
156
 	/* Transmit ARP request */
161
 	/* Transmit ARP request */
157
-	if ( ( rc = net_transmit ( pkb, netdev, &arp_protocol, 
158
-				   ll_protocol->ll_broadcast ) ) != 0 )
162
+	if ( ( rc = net_tx ( pkb, netdev, &arp_protocol, 
163
+			     ll_protocol->ll_broadcast ) ) != 0 )
159
 		return rc;
164
 		return rc;
160
 
165
 
161
 	return -ENOENT;
166
 	return -ENOENT;
162
 }
167
 }
163
 
168
 
169
+/**
170
+ * Identify ARP protocol
171
+ *
172
+ * @v net_proto			Network-layer protocol, in network-endian order
173
+ * @ret arp_net_protocol	ARP protocol, or NULL
174
+ *
175
+ */
176
+static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) {
177
+	struct arp_net_protocol *arp_net_protocol;
178
+
179
+	for ( arp_net_protocol = arp_net_protocols ;
180
+	      arp_net_protocol < arp_net_protocols_end ; arp_net_protocol++ ) {
181
+		if ( arp_net_protocol->net_protocol->net_proto == net_proto ) {
182
+			return arp_net_protocol;
183
+		}
184
+	}
185
+	return NULL;
186
+}
187
+
164
 /**
188
 /**
165
  * Process incoming ARP packets
189
  * Process incoming ARP packets
166
  *
190
  *
167
  * @v pkb		Packet buffer
191
  * @v pkb		Packet buffer
192
+ * @v netdev		Network device
193
+ * @v ll_source		Link-layer source address
168
  * @ret rc		Return status code
194
  * @ret rc		Return status code
169
  *
195
  *
170
  * This handles ARP requests and responses as detailed in RFC826.  The
196
  * This handles ARP requests and responses as detailed in RFC826.  The
173
  * avoiding the need for extraneous ARP requests; read the RFC for
199
  * avoiding the need for extraneous ARP requests; read the RFC for
174
  * details.
200
  * details.
175
  */
201
  */
176
-static int arp_rx ( struct pk_buff *pkb ) {
202
+static int arp_rx ( struct pk_buff *pkb, struct net_device *netdev,
203
+		    const void *ll_source __unused ) {
177
 	struct arphdr *arphdr = pkb->data;
204
 	struct arphdr *arphdr = pkb->data;
178
-	struct ll_protocol *ll_protocol;
205
+	struct arp_net_protocol *arp_net_protocol;
179
 	struct net_protocol *net_protocol;
206
 	struct net_protocol *net_protocol;
207
+	struct ll_protocol *ll_protocol;
180
 	struct arp_entry *arp;
208
 	struct arp_entry *arp;
181
-	struct net_device *netdev;
182
 	int merge = 0;
209
 	int merge = 0;
183
 
210
 
184
-	/* Identify link-layer and network-layer protocols */
185
-	ll_protocol = pkb->ll_protocol;
186
-	net_protocol = find_net_protocol ( arphdr->ar_pro );
187
-	if ( ! net_protocol )
211
+	/* Identify network-layer and link-layer protocols */
212
+	arp_net_protocol = arp_find_protocol ( arphdr->ar_pro );
213
+	if ( ! arp_net_protocol )
188
 		goto done;
214
 		goto done;
215
+	net_protocol = arp_net_protocol->net_protocol;
216
+	ll_protocol = netdev->ll_protocol;
189
 
217
 
190
 	/* Sanity checks */
218
 	/* Sanity checks */
191
 	if ( ( arphdr->ar_hrd != ll_protocol->ll_proto ) ||
219
 	if ( ( arphdr->ar_hrd != ll_protocol->ll_proto ) ||
206
 	}
234
 	}
207
 
235
 
208
 	/* See if we own the target protocol address */
236
 	/* See if we own the target protocol address */
209
-	netdev = find_netdev_by_net_addr ( net_protocol,
210
-					   arp_target_pa ( arphdr ) );
211
-	if ( ! netdev )
237
+	if ( arp_net_protocol->check ( netdev, arp_target_pa ( arphdr ) ) != 0)
212
 		goto done;
238
 		goto done;
213
 	
239
 	
214
 	/* Create new ARP table entry if necessary */
240
 	/* Create new ARP table entry if necessary */
239
 	memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
265
 	memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
240
 
266
 
241
 	/* Send reply */
267
 	/* Send reply */
242
-	net_transmit ( pkb, netdev, &arp_protocol, arp_target_ha (arphdr ) );
268
+	net_tx ( pkb, netdev, &arp_protocol, arp_target_ha (arphdr ) );
243
 	pkb = NULL;
269
 	pkb = NULL;
244
 
270
 
245
  done:
271
  done:
264
 struct net_protocol arp_protocol = {
290
 struct net_protocol arp_protocol = {
265
 	.name = "ARP",
291
 	.name = "ARP",
266
 	.net_proto = htons ( ETH_P_ARP ),
292
 	.net_proto = htons ( ETH_P_ARP ),
267
-	.rx_process = arp_rx,
293
+	.rx = arp_rx,
268
 	.ntoa = arp_ntoa,
294
 	.ntoa = arp_ntoa,
269
 };
295
 };
270
 
296
 

+ 24
- 22
src/net/ethernet.c View File

46
  *
46
  *
47
  * Prepends the Ethernet link-layer header and transmits the packet.
47
  * Prepends the Ethernet link-layer header and transmits the packet.
48
  */
48
  */
49
-static int eth_transmit ( struct pk_buff *pkb, struct net_device *netdev,
50
-			  struct net_protocol *net_protocol,
51
-			  const void *ll_dest ) {
49
+static int eth_tx ( struct pk_buff *pkb, struct net_device *netdev,
50
+		    struct net_protocol *net_protocol, const void *ll_dest ) {
52
 	struct ethhdr *ethhdr = pkb_push ( pkb, sizeof ( *ethhdr ) );
51
 	struct ethhdr *ethhdr = pkb_push ( pkb, sizeof ( *ethhdr ) );
53
 
52
 
53
+	/* Build Ethernet header */
54
 	memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
54
 	memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
55
 	memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
55
 	memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN );
56
 	ethhdr->h_protocol = net_protocol->net_proto;
56
 	ethhdr->h_protocol = net_protocol->net_proto;
57
-	return netdev_transmit ( netdev, pkb );
57
+
58
+	/* Hand off to network device */
59
+	return netdev_tx ( netdev, pkb );
58
 }
60
 }
59
 
61
 
60
 /**
62
 /**
61
- * Parse Ethernet link-layer header
63
+ * Process received Ethernet packet
62
  *
64
  *
63
  * @v pkb	Packet buffer
65
  * @v pkb	Packet buffer
64
- * @v llhdr	Generic link-layer header
66
+ * @v netdev	Network device
65
  *
67
  *
66
- * Fills in the generic link-layer header based on information in the
67
- * Ethernet link-layer header in the packet buffer.
68
+ * Strips off the Ethernet link-layer header and passes up to the
69
+ * network-layer protocol.
68
  */
70
  */
69
-static void eth_parse_llh ( const struct pk_buff *pkb,
70
-			    struct ll_header *llhdr ) {
71
+static void eth_rx ( struct pk_buff *pkb, struct net_device *netdev ) {
71
 	struct ethhdr *ethhdr = pkb->data;
72
 	struct ethhdr *ethhdr = pkb->data;
72
 
73
 
73
-	memcpy ( llhdr->dest_ll_addr, ethhdr->h_dest, ETH_ALEN );
74
-	memcpy ( llhdr->source_ll_addr, ethhdr->h_source, ETH_ALEN );
75
-	llhdr->net_proto = ethhdr->h_protocol;
76
-
77
-	if ( memcmp ( ethhdr->h_dest, eth_broadcast, ETH_ALEN ) == 0 ) {
78
-		llhdr->flags = PKT_FL_BROADCAST;
79
-	} else if ( ethhdr->h_dest[0] & 0x01 ) {
80
-		llhdr->flags = PKT_FL_MULTICAST;
81
-	} else {
82
-		llhdr->flags = 0;
74
+	/* Sanity check */
75
+	if ( pkb_len ( pkb ) < sizeof ( *ethhdr ) ) {
76
+		DBG ( "Ethernet packet too short (%d bytes)\n",
77
+		      pkb_len ( pkb ) );
78
+		return;
83
 	}
79
 	}
80
+
81
+	/* Strip off Ethernet header */
82
+	pkb_pull ( pkb, sizeof ( *ethhdr ) );
83
+
84
+	/* Hand off to network-layer protocol */
85
+	net_rx ( pkb, netdev, ethhdr->h_protocol, ethhdr->h_source );
84
 }
86
 }
85
 
87
 
86
 /**
88
 /**
105
 	.ll_proto	= htons ( ARPHRD_ETHER ),
107
 	.ll_proto	= htons ( ARPHRD_ETHER ),
106
 	.ll_addr_len	= ETH_ALEN,
108
 	.ll_addr_len	= ETH_ALEN,
107
 	.ll_broadcast	= eth_broadcast,
109
 	.ll_broadcast	= eth_broadcast,
108
-	.transmit	= eth_transmit,
109
-	.parse_llh	= eth_parse_llh,
110
+	.tx		= eth_tx,
111
+	.rx		= eth_rx,
110
 	.ntoa		= eth_ntoa,
112
 	.ntoa		= eth_ntoa,
111
 };
113
 };
112
 
114
 

+ 33
- 15
src/net/ipv4.c View File

7
 #include <gpxe/list.h>
7
 #include <gpxe/list.h>
8
 #include <gpxe/in.h>
8
 #include <gpxe/in.h>
9
 #include <gpxe/arp.h>
9
 #include <gpxe/arp.h>
10
-
11
-#include <ip.h>
12
-
13
-
14
 #include <gpxe/if_ether.h>
10
 #include <gpxe/if_ether.h>
15
 #include <gpxe/pkbuff.h>
11
 #include <gpxe/pkbuff.h>
16
 #include <gpxe/netdevice.h>
12
 #include <gpxe/netdevice.h>
104
  * @ret rc		Return status code
100
  * @ret rc		Return status code
105
  *
101
  *
106
  */
102
  */
107
-int ipv4_uip_transmit ( struct pk_buff *pkb ) {
103
+int ipv4_uip_tx ( struct pk_buff *pkb ) {
108
 	struct iphdr *iphdr = pkb->data;
104
 	struct iphdr *iphdr = pkb->data;
109
 	struct ipv4_miniroute *miniroute;
105
 	struct ipv4_miniroute *miniroute;
110
 	struct net_device *netdev = NULL;
106
 	struct net_device *netdev = NULL;
162
 	}
158
 	}
163
 	
159
 	
164
 	/* Hand off to link layer */
160
 	/* Hand off to link layer */
165
-	return net_transmit ( pkb, netdev, &ipv4_protocol, ll_dest );
161
+	return net_tx ( pkb, netdev, &ipv4_protocol, ll_dest );
166
 
162
 
167
  err:
163
  err:
168
 	free_pkb ( pkb );
164
 	free_pkb ( pkb );
173
  * Process incoming IP packets
169
  * Process incoming IP packets
174
  *
170
  *
175
  * @v pkb		Packet buffer
171
  * @v pkb		Packet buffer
172
+ * @v netdev		Network device
173
+ * @v ll_source		Link-layer source address
176
  * @ret rc		Return status code
174
  * @ret rc		Return status code
177
  *
175
  *
178
  * This handles IP packets by handing them off to the uIP protocol
176
  * This handles IP packets by handing them off to the uIP protocol
179
  * stack.
177
  * stack.
180
  */
178
  */
181
-static int ipv4_rx ( struct pk_buff *pkb ) {
179
+static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
180
+		     const void *ll_source __unused ) {
182
 
181
 
183
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
182
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
184
 	 * but will do as a proof-of-concept for now.
183
 	 * but will do as a proof-of-concept for now.
195
 			return -ENOMEM;
194
 			return -ENOMEM;
196
 		pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
195
 		pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
197
 		memcpy ( pkb_put ( pkb, uip_len ), uip_buf, uip_len );
196
 		memcpy ( pkb_put ( pkb, uip_len ), uip_buf, uip_len );
198
-		ipv4_uip_transmit ( pkb );
197
+		ipv4_uip_tx ( pkb );
199
 	}
198
 	}
200
 	return 0;
199
 	return 0;
201
 }
200
 }
202
 
201
 
202
+/** 
203
+ * Check existence of IPv4 address for ARP
204
+ *
205
+ * @v netdev		Network device
206
+ * @v net_addr		Network-layer address
207
+ * @ret rc		Return status code
208
+ */
209
+static int ipv4_arp_check ( struct net_device *netdev, const void *net_addr ) {
210
+	const struct in_addr *address = net_addr;
211
+	struct ipv4_miniroute *miniroute;
212
+
213
+	list_for_each_entry ( miniroute, &miniroutes, list ) {
214
+		if ( ( miniroute->netdev == netdev ) &&
215
+		     ( miniroute->address.s_addr == address->s_addr ) ) {
216
+			/* Found matching address */
217
+			return 0;
218
+		}
219
+	}
220
+	return -ENOENT;
221
+}
222
+
203
 /**
223
 /**
204
  * Convert IPv4 address to dotted-quad notation
224
  * Convert IPv4 address to dotted-quad notation
205
  *
225
  *
230
 	.name = "IP",
250
 	.name = "IP",
231
 	.net_proto = htons ( ETH_P_IP ),
251
 	.net_proto = htons ( ETH_P_IP ),
232
 	.net_addr_len = sizeof ( struct in_addr ),
252
 	.net_addr_len = sizeof ( struct in_addr ),
233
-	.rx_process = ipv4_rx,
253
+	.rx = ipv4_rx,
234
 	.ntoa = ipv4_ntoa,
254
 	.ntoa = ipv4_ntoa,
235
 };
255
 };
236
 
256
 
237
 NET_PROTOCOL ( ipv4_protocol );
257
 NET_PROTOCOL ( ipv4_protocol );
238
 
258
 
239
-/** IPv4 address for the static single net device */
240
-struct net_address static_single_ipv4_address = {
259
+/** IPv4 ARP protocol */
260
+struct arp_net_protocol ipv4_arp_protocol = {
241
 	.net_protocol = &ipv4_protocol,
261
 	.net_protocol = &ipv4_protocol,
242
-
243
-#warning "Remove this static-IP hack"
244
-	.net_addr = { 0x0a, 0xfe, 0xfe, 0x01 },
262
+	.check = ipv4_arp_check,
245
 };
263
 };
246
 
264
 
247
-STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address );
265
+ARP_NET_PROTOCOL ( ipv4_arp_protocol );

+ 154
- 146
src/net/netdevice.c View File

20
 #include <byteswap.h>
20
 #include <byteswap.h>
21
 #include <string.h>
21
 #include <string.h>
22
 #include <errno.h>
22
 #include <errno.h>
23
+#include <malloc.h>
23
 #include <gpxe/if_ether.h>
24
 #include <gpxe/if_ether.h>
24
 #include <gpxe/pkbuff.h>
25
 #include <gpxe/pkbuff.h>
25
 #include <gpxe/tables.h>
26
 #include <gpxe/tables.h>
33
  *
34
  *
34
  */
35
  */
35
 
36
 
36
-/**
37
- * Static single instance of a network device
38
- *
39
- * The gPXE API is designed to accommodate multiple network devices.
40
- * However, in the interests of code size, the implementation behind
41
- * the API supports only a single instance of a network device.
42
- *
43
- * No code outside of netdevice.c should ever refer directly to @c
44
- * static_single_netdev.
45
- *
46
- * Callers should always check the return status of alloc_netdev(),
47
- * register_netdev() etc.  In the current implementation this code
48
- * will be optimised out by the compiler, so there is no penalty.
49
- */
50
-struct net_device static_single_netdev;
51
-
52
 /** Registered network-layer protocols */
37
 /** Registered network-layer protocols */
53
 static struct net_protocol net_protocols[0] __table_start ( net_protocols );
38
 static struct net_protocol net_protocols[0] __table_start ( net_protocols );
54
 static struct net_protocol net_protocols_end[0] __table_end ( net_protocols );
39
 static struct net_protocol net_protocols_end[0] __table_end ( net_protocols );
55
 
40
 
56
-/** Network-layer addresses for @c static_single_netdev */
57
-static struct net_address static_single_netdev_addresses[0]
58
-	__table_start ( sgl_netdev_addresses );
59
-static struct net_address static_single_netdev_addresses_end[0]
60
-	__table_end ( sgl_netdev_addresses );
61
-
62
-/** Recevied packet queue */
63
-static LIST_HEAD ( rx_queue );
41
+/** List of network devices */
42
+static LIST_HEAD ( net_devices );
64
 
43
 
65
 #warning "Remove this static IP address hack"
44
 #warning "Remove this static IP address hack"
66
 #include <ip.h>
45
 #include <ip.h>
67
 #include <gpxe/ip.h>
46
 #include <gpxe/ip.h>
68
 
47
 
69
 /**
48
 /**
70
- * Register network device
49
+ * Transmit raw packet via network device
71
  *
50
  *
72
  * @v netdev		Network device
51
  * @v netdev		Network device
52
+ * @v pkb		Packet buffer
73
  * @ret rc		Return status code
53
  * @ret rc		Return status code
74
  *
54
  *
75
- * Adds the network device to the list of network devices.
55
+ * Transmits the packet via the specified network device.  This
56
+ * function takes ownership of the packet buffer.
76
  */
57
  */
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;
58
+int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
59
+	DBG ( "%s transmitting %p+%zx\n", netdev_name ( netdev ),
60
+	      pkb->data, pkb_len ( pkb ) );
61
+	return netdev->transmit ( netdev, pkb );
93
 }
62
 }
94
 
63
 
95
 /**
64
 /**
96
- * Unregister network device
65
+ * Add packet to receive queue
97
  *
66
  *
98
  * @v netdev		Network device
67
  * @v netdev		Network device
68
+ * @v pkb		Packet buffer
99
  *
69
  *
100
- * Removes the network device from the list of network devices.
70
+ * The packet is added to the network device's RX queue.  This
71
+ * function takes ownership of the packet buffer.
101
  */
72
  */
102
-void unregister_netdev ( struct net_device *netdev ) {
103
-
104
-#warning "Remove this static IP address hack"
105
-	del_ipv4_address ( netdev );
106
-
73
+void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
74
+	DBG ( "%s received %p+%zx\n", netdev_name ( netdev ),
75
+	      pkb->data, pkb_len ( pkb ) );
76
+	list_add_tail ( &pkb->list, &netdev->rx_queue );
107
 }
77
 }
108
 
78
 
109
 /**
79
 /**
110
- * Add packet to receive queue
80
+ * Transmit network-layer packet
111
  *
81
  *
112
- * @v netdev		Network device
113
  * @v pkb		Packet buffer
82
  * @v pkb		Packet buffer
83
+ * @v netdev		Network device
84
+ * @v net_protocol	Network-layer protocol
85
+ * @v ll_dest		Destination link-layer address
86
+ * @ret rc		Return status code
114
  *
87
  *
115
- * The packet is added to the RX queue.  This function takes ownership
116
- * of the packet buffer.
88
+ * Prepends link-layer headers to the packet buffer and transmits the
89
+ * packet via the specified network device.  This function takes
90
+ * ownership of the packet buffer.
117
  */
91
  */
118
-void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
119
-	DBG ( "Packet received\n" );
120
-	pkb->ll_protocol = netdev->ll_protocol;
121
-	list_add_tail ( &pkb->list, &rx_queue );
92
+int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
93
+	     struct net_protocol *net_protocol, const void *ll_dest ) {
94
+	return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
122
 }
95
 }
123
 
96
 
124
 /**
97
 /**
125
- * Identify network protocol
98
+ * Process received network-layer packet
126
  *
99
  *
100
+ * @v pkb		Packet buffer
101
+ * @v netdev		Network device
127
  * @v net_proto		Network-layer protocol, in network-byte order
102
  * @v net_proto		Network-layer protocol, in network-byte order
128
- * @ret net_protocol	Network-layer protocol, or NULL
129
- *
130
- * Identify a network-layer protocol from a protocol number, which
131
- * must be an ETH_P_XXX constant in network-byte order.
103
+ * @v ll_source		Source link-layer address
132
  */
104
  */
133
-struct net_protocol * find_net_protocol ( uint16_t net_proto ) {
105
+void net_rx ( struct pk_buff *pkb, struct net_device *netdev,
106
+	      uint16_t net_proto, const void *ll_source ) {
134
 	struct net_protocol *net_protocol;
107
 	struct net_protocol *net_protocol;
135
 
108
 
109
+	/* Hand off to network-layer protocol, if any */
136
 	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
110
 	for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
137
 	      net_protocol++ ) {
111
 	      net_protocol++ ) {
138
-		if ( net_protocol->net_proto == net_proto )
139
-			return net_protocol;
140
-	}
141
-	return NULL;
142
-}
143
-
144
-/**
145
- * Identify network device by network-layer address
146
- *
147
- * @v net_protocol	Network-layer protocol
148
- * @v net_addr		Network-layer address
149
- * @ret netdev		Network device, or NULL
150
- *
151
- * Searches through all network devices to find the device with the
152
- * specified network-layer address.
153
- *
154
- * Note that even with a static single network device, this function
155
- * can still return NULL.
156
- */
157
-struct net_device *
158
-find_netdev_by_net_addr ( struct net_protocol *net_protocol,
159
-			  void *net_addr ) {
160
-	struct net_address *net_address;
161
-	struct net_device *netdev = &static_single_netdev;
162
-	
163
-	for ( net_address = static_single_netdev_addresses ;
164
-	      net_address < static_single_netdev_addresses_end ;
165
-	      net_address ++ ) {
166
-		if ( ( net_address->net_protocol == net_protocol ) &&
167
-		     ( memcmp ( net_address->net_addr, net_addr,
168
-				net_protocol->net_addr_len ) == 0 ) )
169
-			return netdev;
112
+		if ( net_protocol->net_proto == net_proto ) {
113
+			net_protocol->rx ( pkb, netdev, ll_source );
114
+			break;
115
+		}
170
 	}
116
 	}
171
-
172
-	return NULL;
173
 }
117
 }
174
 
118
 
175
 /**
119
 /**
176
- * Poll for packet on all network devices
120
+ * Poll for packet on network device
177
  *
121
  *
122
+ * @v netdev		Network device
178
  * @ret True		There are packets present in the receive queue
123
  * @ret True		There are packets present in the receive queue
179
  * @ret False		There are no packets present in the receive queue
124
  * @ret False		There are no packets present in the receive queue
180
  *
125
  *
181
- * Polls all network devices for received packets.  Any received
126
+ * Polls the network device for received packets.  Any received
182
  * packets will be added to the RX packet queue via netdev_rx().
127
  * packets will be added to the RX packet queue via netdev_rx().
183
  */
128
  */
184
-int net_poll ( void ) {
185
-	struct net_device *netdev = &static_single_netdev;
186
-
187
-	DBG ( "Polling network\n" );
129
+int netdev_poll ( struct net_device *netdev ) {
188
 	netdev->poll ( netdev );
130
 	netdev->poll ( netdev );
189
-
190
-	return ( ! list_empty ( &rx_queue ) );
131
+	return ( ! list_empty ( &netdev->rx_queue ) );
191
 }
132
 }
192
 
133
 
193
 /**
134
 /**
194
- * Remove packet from receive queue
135
+ * Remove packet from device's receive queue
195
  *
136
  *
137
+ * @v netdev		Network device
196
  * @ret pkb		Packet buffer, or NULL
138
  * @ret pkb		Packet buffer, or NULL
197
  *
139
  *
198
- * Removes the first packet from the RX queue and returns it.
140
+ * Removes the first packet from the device's RX queue and returns it.
199
  * Ownership of the packet is transferred to the caller.
141
  * Ownership of the packet is transferred to the caller.
200
  */
142
  */
201
-struct pk_buff * net_rx_dequeue ( void ) {
143
+struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev ) {
202
 	struct pk_buff *pkb;
144
 	struct pk_buff *pkb;
203
 
145
 
204
-	list_for_each_entry ( pkb, &rx_queue, list ) {
146
+	list_for_each_entry ( pkb, &netdev->rx_queue, list ) {
205
 		list_del ( &pkb->list );
147
 		list_del ( &pkb->list );
206
 		return pkb;
148
 		return pkb;
207
 	}
149
 	}
209
 }
151
 }
210
 
152
 
211
 /**
153
 /**
212
- * Process received packet
154
+ * Allocate network device
213
  *
155
  *
214
- * @v pkb		Packet buffer
215
- * @ret rc		Return status code
156
+ * @v priv_size		Size of private data area (net_device::priv)
157
+ * @ret netdev		Network device, or NULL
216
  *
158
  *
217
- * Processes a packet received from the network (and, usually, removed
218
- * from the RX queue by net_rx_dequeue()).  This call takes ownership
219
- * of the packet buffer.
159
+ * Allocates space for a network device and its private data area.
220
  */
160
  */
221
-int net_rx_process ( struct pk_buff *pkb ) {
222
-	struct ll_protocol *ll_protocol;
223
-	struct ll_header llhdr;
224
-	struct net_protocol *net_protocol;
225
-	int rc;
161
+struct net_device * alloc_netdev ( size_t priv_size ) {
162
+	struct net_device *netdev;
226
 
163
 
227
-	/* Parse link-layer header */
228
-	ll_protocol = pkb->ll_protocol;
229
-	ll_protocol->parse_llh ( pkb, &llhdr );
230
-	
231
-	/* Identify network-layer protocol */
232
-	net_protocol = find_net_protocol ( llhdr.net_proto );
233
-	if ( ! net_protocol ) {
234
-		DBG ( "Unknown network-layer protocol %x\n",
235
-		      ntohs ( llhdr.net_proto ) );
236
-		free_pkb ( pkb );
237
-		return -EPROTONOSUPPORT;
164
+	netdev = calloc ( 1, sizeof ( *netdev ) + priv_size );
165
+	if ( netdev ) {
166
+		INIT_LIST_HEAD ( &netdev->rx_queue );
167
+		netdev->priv = ( ( ( void * ) netdev ) + sizeof ( *netdev ) );
238
 	}
168
 	}
239
-	pkb->net_protocol = net_protocol;
240
-	
241
-	/* Strip off link-layer header */
242
-#warning "Temporary hack"
243
-	pkb_pull ( pkb, ETH_HLEN );
169
+	return netdev;
170
+}
171
+
172
+/**
173
+ * Register network device
174
+ *
175
+ * @v netdev		Network device
176
+ * @ret rc		Return status code
177
+ *
178
+ * Adds the network device to the list of network devices.
179
+ */
180
+int register_netdev ( struct net_device *netdev ) {
244
 	
181
 	
245
-	/* Hand off to network layer */
246
-	if ( ( rc = net_protocol->rx_process ( pkb ) ) != 0 ) {
247
-		DBG ( "Network-layer protocol dropped packet\n" );
248
-		return rc;
182
+#warning "Remove this static IP address hack"
183
+	{
184
+		const struct in_addr static_address = { htonl ( 0x0afefe01 ) };
185
+		const struct in_addr static_netmask = { htonl ( 0xffffff00 ) };
186
+		const struct in_addr static_gateway = { INADDR_NONE };
187
+		int rc;
188
+		
189
+		if ( ( rc = add_ipv4_address ( netdev, static_address,
190
+					       static_netmask,
191
+					       static_gateway ) ) != 0 )
192
+			return rc;
249
 	}
193
 	}
250
 
194
 
195
+	/* Add to device list */
196
+	list_add_tail ( &netdev->list, &net_devices );
197
+	DBG ( "%s registered\n", netdev_name ( netdev ) );
198
+
251
 	return 0;
199
 	return 0;
252
 }
200
 }
253
 
201
 
202
+/**
203
+ * Unregister network device
204
+ *
205
+ * @v netdev		Network device
206
+ *
207
+ * Removes the network device from the list of network devices.
208
+ */
209
+void unregister_netdev ( struct net_device *netdev ) {
210
+	struct pk_buff *pkb;
211
+
212
+#warning "Remove this static IP address hack"
213
+	del_ipv4_address ( netdev );
214
+
215
+	/* Discard any packets in the RX queue */
216
+	while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
217
+		DBG ( "%s discarding %p+%zx\n", netdev_name ( netdev ),
218
+		      pkb->data, pkb_len ( pkb ) );
219
+		free_pkb ( pkb );
220
+	}
221
+
222
+	/* Remove from device list */
223
+	list_del ( &netdev->list );
224
+	DBG ( "%s unregistered\n", netdev_name ( netdev ) );
225
+}
226
+
227
+/**
228
+ * Free network device
229
+ *
230
+ * @v netdev		Network device
231
+ */
232
+void free_netdev ( struct net_device *netdev ) {
233
+	free ( netdev );
234
+}
235
+
236
+/**
237
+ * Iterate through network devices
238
+ *
239
+ * @ret netdev		Network device, or NULL
240
+ *
241
+ * This returns the registered network devices in the order of
242
+ * registration.  If no network devices are registered, it will return
243
+ * NULL.
244
+ */
245
+struct net_device * next_netdev ( void ) {
246
+	struct net_device *netdev;
247
+
248
+	list_for_each_entry ( netdev, &net_devices, list ) {
249
+		list_del ( &netdev->list );
250
+		list_add_tail ( &netdev->list, &net_devices );
251
+		return netdev;
252
+	}
253
+	return NULL;
254
+}
255
+
254
 /**
256
 /**
255
  * Single-step the network stack
257
  * Single-step the network stack
256
  *
258
  *
266
  * multiple packets are processed per poll.
268
  * multiple packets are processed per poll.
267
  */
269
  */
268
 static void net_step ( struct process *process ) {
270
 static void net_step ( struct process *process ) {
271
+	struct net_device *netdev;
269
 	struct pk_buff *pkb;
272
 	struct pk_buff *pkb;
270
 
273
 
271
-	/* Poll for new packets */
272
-	net_poll();
274
+	/* Poll and process each network device */
275
+	list_for_each_entry ( netdev, &net_devices, list ) {
276
+
277
+		/* Poll for new packets */
278
+		netdev_poll ( netdev );
273
 
279
 
274
-	/* Handle at most one received packet */
275
-	if ( ( pkb = net_rx_dequeue () ) ) {
276
-		net_rx_process ( pkb );
277
-		DBG ( "Processed received packet\n" );
280
+		/* Handle at most one received packet per poll */
281
+		if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
282
+			DBG ( "%s processing %p+%zx\n", netdev_name ( netdev ),
283
+			      pkb->data, pkb_len ( pkb ) );
284
+			netdev->ll_protocol->rx ( pkb, netdev );
285
+		}
278
 	}
286
 	}
279
 
287
 
280
 	/* Re-schedule ourself */
288
 	/* Re-schedule ourself */

+ 1
- 1
src/net/tcp.c View File

177
 			pkb_put ( pkb, uip_len );
177
 			pkb_put ( pkb, uip_len );
178
 			memcpy ( pkb->data, uip_buf, uip_len );
178
 			memcpy ( pkb->data, uip_buf, uip_len );
179
 
179
 
180
-			ipv4_uip_transmit ( pkb );
180
+			ipv4_uip_tx ( pkb );
181
 		}
181
 		}
182
 	}
182
 	}
183
 }
183
 }

Loading…
Cancel
Save