Sfoglia il codice sorgente

Network API now allows for multiple network devices (although the

implementation allows for only one, and does so without compromising on
the efficiency of static allocation).

Link-layer protocols are cleanly separated from the device drivers.

Network-layer protocols are cleanly separated from individual network
devices.

Link-layer and network-layer protocols are cleanly separated from each
other.
tags/v0.9.3
Michael Brown 19 anni fa
parent
commit
53f78346bf
4 ha cambiato i file con 319 aggiunte e 137 eliminazioni
  1. 28
    0
      src/include/gpxe/ethernet.h
  2. 226
    0
      src/net/ipv4.c
  3. 65
    0
      src/net/pkbuff.c
  4. 0
    137
      src/proto/ip.c

+ 28
- 0
src/include/gpxe/ethernet.h Vedi File

@@ -0,0 +1,28 @@
1
+#ifndef _GPXE_ETHERNET_H
2
+#define _GPXE_ETHERNET_H
3
+
4
+/** @file
5
+ *
6
+ * Ethernet protocol
7
+ *
8
+ */
9
+
10
+#include <stdint.h>
11
+#include <gpxe/netdevice.h>
12
+
13
+extern struct ll_protocol ethernet_protocol;
14
+
15
+/**
16
+ * Allocate Ethernet device
17
+ *
18
+ * @v priv_size		Size of driver private data
19
+ * @ret netdev		Network device, or NULL
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;	} )
27
+
28
+#endif /* _GPXE_ETHERNET_H */

+ 226
- 0
src/net/ipv4.c Vedi File

@@ -0,0 +1,226 @@
1
+#include <string.h>
2
+#include <stdint.h>
3
+#include <byteswap.h>
4
+#include <gpxe/in.h>
5
+
6
+
7
+#include <ip.h>
8
+
9
+
10
+#include <gpxe/if_ether.h>
11
+#include <gpxe/pkbuff.h>
12
+#include <gpxe/netdevice.h>
13
+#include "../proto/uip/uip.h"
14
+
15
+/** @file
16
+ *
17
+ * IPv4 protocol
18
+ *
19
+ * The gPXE IP stack is currently implemented on top of the uIP
20
+ * protocol stack.  This file provides wrappers around uIP so that
21
+ * higher-level protocol implementations do not need to talk directly
22
+ * to uIP (which has a somewhat baroque API).
23
+ *
24
+ */
25
+
26
+/** An IPv4 routing table entry */
27
+struct ipv4_route {
28
+	/** Network address */
29
+	struct in_addr network;
30
+	/** Subnet mask */
31
+	struct in_addr netmask;
32
+	/** Gateway address */
33
+	struct in_addr gateway;
34
+	/** Gateway device */
35
+	struct in_addr gatewaydev;
36
+};
37
+
38
+enum {
39
+	STATIC_SINGLE_NETDEV_ROUTE = 0,
40
+	DEFAULT_ROUTE,
41
+	NUM_ROUTES
42
+};
43
+
44
+/** IPv4 routing table */
45
+static struct ipv4_route routing_table[NUM_ROUTES];
46
+
47
+#define routing_table_end ( routing_table + NUM_ROUTES )
48
+
49
+#if 0
50
+/**
51
+ * Set IP address
52
+ *
53
+ */
54
+void set_ipaddr ( struct in_addr address ) {
55
+	union {
56
+		struct in_addr address;
57
+		uint16_t uip_address[2];
58
+	} u;
59
+
60
+	u.address = address;
61
+	uip_sethostaddr ( u.uip_address );
62
+}
63
+
64
+/**
65
+ * Set netmask
66
+ *
67
+ */
68
+void set_netmask ( struct in_addr address ) {
69
+	union {
70
+		struct in_addr address;
71
+		uint16_t uip_address[2];
72
+	} u;
73
+
74
+	u.address = address;
75
+	uip_setnetmask ( u.uip_address );
76
+}
77
+
78
+/**
79
+ * Set default gateway
80
+ *
81
+ */
82
+void set_gateway ( struct in_addr address ) {
83
+	union {
84
+		struct in_addr address;
85
+		uint16_t uip_address[2];
86
+	} u;
87
+
88
+	u.address = address;
89
+	uip_setdraddr ( u.uip_address );
90
+}
91
+
92
+/**
93
+ * Run the TCP/IP stack
94
+ *
95
+ * Call this function in a loop in order to allow TCP/IP processing to
96
+ * take place.  This call takes the stack through a single iteration;
97
+ * it will typically be used in a loop such as
98
+ *
99
+ * @code
100
+ *
101
+ * struct tcp_connection *my_connection;
102
+ * ...
103
+ * tcp_connect ( my_connection );
104
+ * while ( ! my_connection->finished ) {
105
+ *   run_tcpip();
106
+ * }
107
+ *
108
+ * @endcode
109
+ *
110
+ * where @c my_connection->finished is set by one of the connection's
111
+ * #tcp_operations methods to indicate completion.
112
+ */
113
+void run_tcpip ( void ) {
114
+	void *data;
115
+	size_t len;
116
+	uint16_t type;
117
+	int i;
118
+	
119
+	if ( netdev_poll ( 1, &data, &len ) ) {
120
+		/* We have data */
121
+		memcpy ( uip_buf, data, len );
122
+		uip_len = len;
123
+		type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) );
124
+		if ( type == UIP_ETHTYPE_ARP ) {
125
+			uip_arp_arpin();
126
+		} else {
127
+			uip_arp_ipin();
128
+			uip_input();
129
+		}
130
+		if ( uip_len > 0 )
131
+			uip_transmit();
132
+	} else {
133
+		for ( i = 0 ; i < UIP_CONNS ; i++ ) {
134
+			uip_periodic ( i );
135
+			if ( uip_len > 0 )
136
+				uip_transmit();
137
+		}
138
+	}
139
+}
140
+#endif
141
+
142
+/**
143
+ * Process incoming IP packets
144
+ *
145
+ * @v pkb		Packet buffer
146
+ * @ret rc		Return status code
147
+ *
148
+ * This handles IP packets by handing them off to the uIP protocol
149
+ * stack.
150
+ */
151
+static int ipv4_rx ( struct pk_buff *pkb ) {
152
+
153
+	/* Transfer to uIP buffer.  Horrendously space-inefficient,
154
+	 * but will do as a proof-of-concept for now.
155
+	 */
156
+	memcpy ( uip_buf, pkb->data, pkb_len ( pkb ) );
157
+
158
+	/* Hand to uIP for processing */
159
+	uip_input ();
160
+	if ( uip_len > 0 ) {
161
+		pkb_empty ( pkb );
162
+		pkb_put ( pkb, uip_len );
163
+		memcpy ( pkb->data, uip_buf, uip_len );
164
+		if ( net_transmit ( pkb ) != 0 )
165
+			free_pkb ( pkb );
166
+	} else {
167
+		free_pkb ( pkb );
168
+	}
169
+	return 0;
170
+}
171
+
172
+/**
173
+ * Perform IP layer routing
174
+ *
175
+ * @v pkb	Packet buffer
176
+ * @ret source	Network-layer source address
177
+ * @ret dest	Network-layer destination address
178
+ * @ret rc	Return status code
179
+ */
180
+static int ipv4_route ( const struct pk_buff *pkb,
181
+			struct net_header *nethdr ) {
182
+	struct iphdr *iphdr = pkb->data;
183
+	struct in_addr *source = ( struct in_addr * ) nethdr->source_net_addr;
184
+	struct in_addr *dest = ( struct in_addr * ) nethdr->dest_net_addr;
185
+	struct ipv4_route *route;
186
+
187
+	/* Route IP packet according to routing table */
188
+	source->s_addr = INADDR_NONE;
189
+	dest->s_addr = iphdr->dest.s_addr;
190
+	for ( route = routing_table ; route < routing_table_end ; route++ ) {
191
+		if ( ( dest->s_addr & route->netmask.s_addr )
192
+		     == route->network.s_addr ) {
193
+			source->s_addr = route->gatewaydev.s_addr;
194
+			if ( route->gateway.s_addr )
195
+				dest->s_addr = route->gateway.s_addr;
196
+			break;
197
+		}
198
+	}
199
+
200
+	/* Set broadcast and multicast flags as applicable */
201
+	nethdr->dest_flags = 0;
202
+	if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) {
203
+		nethdr->dest_flags = NETADDR_FL_BROADCAST;
204
+	} else if ( IN_MULTICAST ( dest->s_addr ) ) {
205
+		nethdr->dest_flags = NETADDR_FL_MULTICAST;
206
+	}
207
+
208
+	return 0;
209
+}
210
+
211
+/** IPv4 protocol */
212
+struct net_protocol ipv4_protocol = {
213
+	.net_proto = ETH_P_IP,
214
+	.net_addr_len = sizeof ( struct in_addr ),
215
+	.rx = ipv4_rx,
216
+	.route = ipv4_route,
217
+};
218
+
219
+NET_PROTOCOL ( ipv4_protocol );
220
+
221
+/** IPv4 address for the static single net device */
222
+struct net_address static_single_ipv4_address = {
223
+	.net_protocol = &ipv4_protocol,
224
+};
225
+
226
+STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address );

+ 65
- 0
src/net/pkbuff.c Vedi File

@@ -0,0 +1,65 @@
1
+/*
2
+ * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
+ */
18
+
19
+#include <stdint.h>
20
+#include <gpxe/malloc.h>
21
+#include <gpxe/pkbuff.h>
22
+
23
+/** @file
24
+ *
25
+ * Packet buffers
26
+ *
27
+ */
28
+
29
+/**
30
+ * Allocate packet buffer
31
+ *
32
+ * @v len	Required length of buffer
33
+ * @ret pkb	Packet buffer, or NULL if none available
34
+ *
35
+ * The packet buffer will be aligned as per gmalloc().
36
+ */
37
+struct pk_buff * alloc_pkb ( size_t len ) {
38
+	struct pk_buff *pkb = NULL;
39
+	void *data;
40
+
41
+	/* Align buffer length */
42
+	len = ( len + __alignof__ ( *pkb ) - 1 ) & ~ __alignof__ ( *pkb );
43
+	
44
+	/* Allocate memory for buffer plus descriptor */
45
+	data = gmalloc ( len + sizeof ( *pkb ) );
46
+	if ( ! data )
47
+		return NULL;
48
+
49
+	pkb = ( struct pk_buff * ) ( data + len );
50
+	pkb->head = pkb->data = pkb->tail = data;
51
+	pkb->end = pkb;
52
+	return pkb;
53
+}
54
+
55
+/**
56
+ * Free packet buffer
57
+ *
58
+ * @v pkb	Packet buffer
59
+ */
60
+void free_pkb ( struct pk_buff *pkb ) {
61
+	if ( pkb ) {
62
+		gfree ( pkb->head,
63
+			( pkb->end - pkb->head ) + sizeof ( *pkb ) );
64
+	}
65
+}

+ 0
- 137
src/proto/ip.c Vedi File

@@ -1,137 +0,0 @@
1
-#include <string.h>
2
-#include <stdint.h>
3
-#include <byteswap.h>
4
-#include <gpxe/in.h>
5
-#include <gpxe/ip.h>
6
-#include "uip/uip.h"
7
-#include "uip/uip_arp.h"
8
-
9
-/** @file
10
- *
11
- * IP protocol
12
- *
13
- * The gPXE IP stack is currently implemented on top of the uIP
14
- * protocol stack.  This file provides wrappers around uIP so that
15
- * higher-level protocol implementations do not need to talk directly
16
- * to uIP (which has a somewhat baroque API).
17
- *
18
- */
19
-
20
-/**
21
- * Set IP address
22
- *
23
- */
24
-void set_ipaddr ( struct in_addr address ) {
25
-	union {
26
-		struct in_addr address;
27
-		uint16_t uip_address[2];
28
-	} u;
29
-
30
-	u.address = address;
31
-	uip_sethostaddr ( u.uip_address );
32
-}
33
-
34
-/**
35
- * Set netmask
36
- *
37
- */
38
-void set_netmask ( struct in_addr address ) {
39
-	union {
40
-		struct in_addr address;
41
-		uint16_t uip_address[2];
42
-	} u;
43
-
44
-	u.address = address;
45
-	uip_setnetmask ( u.uip_address );
46
-}
47
-
48
-/**
49
- * Set default gateway
50
- *
51
- */
52
-void set_gateway ( struct in_addr address ) {
53
-	union {
54
-		struct in_addr address;
55
-		uint16_t uip_address[2];
56
-	} u;
57
-
58
-	u.address = address;
59
-	uip_setdraddr ( u.uip_address );
60
-}
61
-
62
-/**
63
- * Initialise TCP/IP stack
64
- *
65
- */
66
-void init_tcpip ( void ) {
67
-	uip_init();
68
-	uip_arp_init();
69
-}
70
-
71
-#define UIP_HLEN ( 40 + UIP_LLH_LEN )
72
-
73
-/**
74
- * Transmit TCP data
75
- *
76
- * This is a wrapper around netdev_transmit().  It gathers up the
77
- * packet produced by uIP, and then passes it to netdev_transmit() as
78
- * a single buffer.
79
- */
80
-static void uip_transmit ( void ) {
81
-	uip_arp_out();
82
-	if ( uip_len > UIP_HLEN ) {
83
-		memcpy ( uip_buf + UIP_HLEN, ( void * ) uip_appdata,
84
-			 uip_len - UIP_HLEN );
85
-	}
86
-	netdev_transmit ( uip_buf, uip_len );
87
-	uip_len = 0;
88
-}
89
-
90
-/**
91
- * Run the TCP/IP stack
92
- *
93
- * Call this function in a loop in order to allow TCP/IP processing to
94
- * take place.  This call takes the stack through a single iteration;
95
- * it will typically be used in a loop such as
96
- *
97
- * @code
98
- *
99
- * struct tcp_connection *my_connection;
100
- * ...
101
- * tcp_connect ( my_connection );
102
- * while ( ! my_connection->finished ) {
103
- *   run_tcpip();
104
- * }
105
- *
106
- * @endcode
107
- *
108
- * where @c my_connection->finished is set by one of the connection's
109
- * #tcp_operations methods to indicate completion.
110
- */
111
-void run_tcpip ( void ) {
112
-	void *data;
113
-	size_t len;
114
-	uint16_t type;
115
-	int i;
116
-	
117
-	if ( netdev_poll ( 1, &data, &len ) ) {
118
-		/* We have data */
119
-		memcpy ( uip_buf, data, len );
120
-		uip_len = len;
121
-		type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) );
122
-		if ( type == UIP_ETHTYPE_ARP ) {
123
-			uip_arp_arpin();
124
-		} else {
125
-			uip_arp_ipin();
126
-			uip_input();
127
-		}
128
-		if ( uip_len > 0 )
129
-			uip_transmit();
130
-	} else {
131
-		for ( i = 0 ; i < UIP_CONNS ; i++ ) {
132
-			uip_periodic ( i );
133
-			if ( uip_len > 0 )
134
-				uip_transmit();
135
-		}
136
-	}
137
-}

Loading…
Annulla
Salva