Browse Source

First sketch of a new net device API.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
6209bd873a
4 changed files with 196 additions and 25 deletions
  1. 1
    0
      src/include/errno.h
  2. 6
    5
      src/include/gpxe/if_ether.h
  3. 26
    20
      src/include/gpxe/netdevice.h
  4. 163
    0
      src/net/netdevice.c

+ 1
- 0
src/include/errno.h View File

@@ -124,6 +124,7 @@
124 124
 #define EINVAL		0xd3
125 125
 #define ENOENT		0xd4
126 126
 #define EAFNOSUPPORT	0xd5
127
+#define EAGAIN		0xd6
127 128
 
128 129
 /* Data structures and declarations */
129 130
 

+ 6
- 5
src/include/gpxe/if_ether.h View File

@@ -12,11 +12,12 @@
12 12
 #define	ETH_MAX_MTU		(ETH_FRAME_LEN-ETH_HLEN)
13 13
 #endif
14 14
 
15
-#define ETH_P_IP	0x0800		/* Internet Protocl Packet */
16
-#define ETH_P_ARP	0x0806		/* Address Resolution Protocol */
17
-#define ETH_P_RARP	0x8035		/* Reverse Address resolution Protocol */
18
-#define ETH_P_IPV6	0x86DD		/* IPv6 over blueblook */
19
-#define ETH_P_SLOW	0x8809		/* Ethernet slow protocols */
15
+#define ETH_P_RAW	0x0000	/* Raw packet */
16
+#define ETH_P_IP	0x0800	/* Internet Protocl Packet */
17
+#define ETH_P_ARP	0x0806	/* Address Resolution Protocol */
18
+#define ETH_P_RARP	0x8035	/* Reverse Address resolution Protocol */
19
+#define ETH_P_IPV6	0x86DD	/* IPv6 over blueblook */
20
+#define ETH_P_SLOW	0x8809	/* Ethernet slow protocols */
20 21
 
21 22
 /** An Ethernet link-layer header */
22 23
 struct ethhdr {

+ 26
- 20
src/include/gpxe/netdevice.h View File

@@ -100,6 +100,8 @@ struct net_device {
100 100
 	 * For Ethernet, this is the MAC address.
101 101
 	 */
102 102
 	uint8_t ll_addr[MAX_LLH_ADDR_LEN];
103
+	/** Linked list of network devices */
104
+	struct list_head devices;
103 105
 	/** List of network interfaces */
104 106
 	struct list_head interfaces;
105 107
 	/** Driver private data */
@@ -117,7 +119,7 @@ struct net_interface {
117 119
 	/** Underlying net device */
118 120
 	struct net_device *netdev;
119 121
 	/** Linked list of interfaces for this device */
120
-	struct list_head list;
122
+	struct list_head interfaces;
121 123
 	/** Network-layer protocol
122 124
 	 *
123 125
 	 * This is an ETH_P_XXX constant, in network byte order.
@@ -127,21 +129,6 @@ struct net_interface {
127 129
 	uint8_t net_addr_len;
128 130
 	/** Network-layer address */
129 131
 	uint8_t net_addr[MAX_NET_ADDR_LEN];
130
-	/** Packet processor
131
-	 *
132
-	 * @v netif	Network interface
133
-	 * @v pkb	Packet buffer
134
-	 * @ret rc	Return status code
135
-	 *
136
-	 * This method is called for packets arriving on the
137
-	 * associated network device that match this interface's
138
-	 * network-layer protocol.
139
-	 *
140
-	 * When this method is called, the link-layer header will
141
-	 * already have been stripped from the packet.
142
-	 */
143
-	int ( * process ) ( struct net_interface *netif,
144
-			    struct pk_buff *pkb );
145 132
 	/** Fill in packet metadata
146 133
 	 *
147 134
 	 * @v netif	Network interface
@@ -154,6 +141,21 @@ struct net_interface {
154 141
 	 */
155 142
 	int ( * add_llh_metadata ) ( struct net_interface *netif,
156 143
 				     struct pk_buff *pkb );
144
+	/** Received packet processor
145
+	 *
146
+	 * @v netif	Network interface
147
+	 * @v pkb	Packet buffer
148
+	 * @ret rc	Return status code
149
+	 *
150
+	 * This method is called for packets arriving on the
151
+	 * associated network device that match this interface's
152
+	 * network-layer protocol.
153
+	 *
154
+	 * When this method is called, the link-layer header will
155
+	 * already have been stripped from the packet.
156
+	 */
157
+	int ( * rx_packet ) ( struct net_interface *netif,
158
+			      struct pk_buff *pkb );
157 159
 };
158 160
 
159 161
 /**
@@ -168,15 +170,22 @@ static inline struct net_interface *
168 170
 netdev_find_netif ( const struct net_device *netdev, uint16_t net_proto ) {
169 171
 	struct net_interface *netif;
170 172
 
171
-	list_for_each_entry ( netif, &netdev->interfaces, list ) {
173
+	list_for_each_entry ( netif, &netdev->interfaces, interfaces ) {
172 174
 		if ( netif->net_proto == net_proto )
173 175
 			return netif;
174 176
 	}
175 177
 	return NULL;
176 178
 }
177 179
 
180
+extern int register_netdevice ( struct net_device *netdev );
181
+extern void unregister_netdevice ( struct net_device *netdev );
178 182
 extern int netdev_send ( struct net_device *netdev, struct pk_buff *pkb );
183
+extern int netdev_poll ( struct net_device *netdev, struct pk_buff *pkb );
179 184
 extern int netif_send ( struct net_interface *netif, struct pk_buff *pkb );
185
+extern int netdev_rx_packet ( struct net_device *netdev, struct pk_buff *pkb );
186
+extern int net_poll ( struct pk_buff *pkb, struct net_device **netdev );
187
+
188
+
180 189
 
181 190
 extern struct net_device static_single_netdev;
182 191
 
@@ -186,9 +195,6 @@ extern struct net_device static_single_netdev;
186 195
 	static_single_netdev.priv = priv_data;	\
187 196
 	&static_single_netdev; } )
188 197
 
189
-extern int register_netdevice ( struct net_device *netdev );
190
-
191
-extern void unregister_netdevice ( struct net_device *netdev );
192 198
 
193 199
 static inline void free_netdevice ( struct net_device *netdev __unused ) {
194 200
 	/* Do nothing */

+ 163
- 0
src/net/netdevice.c View File

@@ -0,0 +1,163 @@
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 <byteswap.h>
21
+#include <errno.h>
22
+#include <gpxe/if_ether.h>
23
+#include <gpxe/pkbuff.h>
24
+#include <gpxe/netdevice.h>
25
+
26
+/** @file
27
+ *
28
+ * Network devices and network interfaces
29
+ *
30
+ */
31
+
32
+/** List of all registered network devices */
33
+static LIST_HEAD ( net_devices );
34
+
35
+/**
36
+ * Register network device
37
+ *
38
+ * @v netdev	Network device
39
+ * @ret rc	Return status code
40
+ *
41
+ * Adds the network device to the list of network devices.
42
+ */
43
+int register_netdevice ( struct net_device *netdev ) {
44
+	list_add ( &netdev->devices, &net_devices );
45
+	return 0;
46
+}
47
+
48
+/**
49
+ * Unregister network device
50
+ *
51
+ * @v netdev	Network device
52
+ *
53
+ * Removes the network device from the list of network devices.
54
+ */
55
+void unregister_netdevice ( struct net_device *netdev ) {
56
+	list_del ( &netdev->devices );
57
+}
58
+
59
+/**
60
+ * Transmit packet via network device
61
+ *
62
+ * @v netdev	Network device
63
+ * @v pkb	Packet buffer
64
+ * @ret rc	Return status code
65
+ *
66
+ * Transmits the packet via the network device.  The @c pkb link-layer
67
+ * metadata must already have been filled in, and space for the
68
+ * link-layer header must already be present in the packet buffer.
69
+ */
70
+int netdev_send ( struct net_device *netdev, struct pk_buff *pkb ) {
71
+	int rc;
72
+
73
+	if ( pkb->net_proto != ETH_P_RAW ) {
74
+		if ( ( rc = netdev->build_llh ( netdev, pkb ) ) != 0 )
75
+			return rc;
76
+	}
77
+	return netdev->transmit ( netdev, pkb );
78
+}
79
+
80
+/**
81
+ * Poll for packet on network device
82
+ *
83
+ * @v netdev	Network device
84
+ * @v pkb	Packet buffer
85
+ * @ret rc	Return status code
86
+ *
87
+ * Polls the network device for a packet.  If a packet is available,
88
+ * it will be added to the packet buffer, and the link-layer metadata
89
+ * fields in @c pkb will be filled in.
90
+ */
91
+int netdev_poll ( struct net_device *netdev, struct pk_buff *pkb ) {
92
+	int rc;
93
+
94
+	if ( ( rc = netdev->poll ( netdev, pkb ) ) != 0 )
95
+		return rc;
96
+	return netdev->parse_llh ( netdev, pkb );
97
+}
98
+
99
+/**
100
+ * Transmit packet via network interface
101
+ *
102
+ * @v netif	Network interface
103
+ * @v pkb	Packet buffer
104
+ * @ret rc	Return status code
105
+ *
106
+ * Transmits the packet via the network interface.  The packet must
107
+ * start with a network-layer header (e.g. an IP header, for an IP
108
+ * interface).  The packet contents are undefined on return.
109
+ */
110
+int netif_send ( struct net_interface *netif, struct pk_buff *pkb ) {
111
+	struct net_device *netdev = netif->netdev;
112
+	int rc;
113
+
114
+	if ( ( rc = netif->add_llh_metadata ( netif, pkb ) ) != 0 )
115
+		return rc;
116
+	pkb_push ( pkb, netdev->ll_hlen );
117
+	return netdev_send ( netdev, pkb );
118
+}
119
+
120
+/**
121
+ * Process received packet
122
+ *
123
+ * @v netif	Network interface
124
+ * @v pkb	Packet buffer
125
+ * @ret rc	Return status code
126
+ *
127
+ * Processes a packet received via netdev_poll().  The interface
128
+ * corresponding to the network-layer protocol is identified, the
129
+ * link-layer header is stripped from the packet and the packet is
130
+ * passed to the net_interface::rx_packet() method.
131
+ */
132
+int netdev_rx_packet ( struct net_device *netdev, struct pk_buff *pkb ) {
133
+	struct net_interface *netif;
134
+
135
+	netif = netdev_find_netif ( netdev, pkb->net_proto );
136
+	if ( ! netif )
137
+		return -EAFNOSUPPORT;
138
+
139
+	pkb_pull ( pkb, netdev->ll_hlen );
140
+	return netif->rx_packet ( netif, pkb );
141
+}
142
+
143
+/**
144
+ * Poll for packet on all network devices
145
+ *
146
+ * @v pkb	Packet buffer
147
+ * @ret netdev	Network device
148
+ * @ret rc	Return status code
149
+ *
150
+ * Polls all network devices for a packet.  If a packet is available
151
+ * on any interface, @c netdev will be filled in and the packet will
152
+ * be received as per netdev_poll().
153
+ */
154
+int net_poll ( struct pk_buff *pkb, struct net_device **netdev ) {
155
+	int rc;
156
+
157
+	list_for_each_entry ( (*netdev), &net_devices, devices ) {
158
+		if ( ( rc = netdev_poll ( *netdev, pkb ) ) == 0 )
159
+			return rc;
160
+	}
161
+
162
+	return -EAGAIN;
163
+}

Loading…
Cancel
Save