Quellcode durchsuchen

Remove the concept of the media-independent link-layer header and replace

it with metadata in the pkb structure.  This is required since UNDI will
want to be able to parse the link-layer header without destroying it.
tags/v0.9.3
Michael Brown vor 18 Jahren
Ursprung
Commit
bdc8190c8d
6 geänderte Dateien mit 195 neuen und 127 gelöschten Zeilen
  1. 1
    1
      src/include/gpxe/arp.h
  2. 0
    63
      src/include/gpxe/llh.h
  3. 26
    36
      src/include/gpxe/netdevice.h
  4. 32
    0
      src/include/gpxe/pkbuff.h
  5. 20
    27
      src/net/arp.c
  6. 116
    0
      src/net/ethernet.c

+ 1
- 1
src/include/gpxe/arp.h Datei anzeigen

@@ -12,7 +12,7 @@ struct net_interface;
12 12
 struct pk_buff;
13 13
 
14 14
 extern int arp_resolve ( struct net_device *netdev, struct pk_buff *pkb,
15
-			 void *ll_addr );
15
+			 const void **ll_addr );
16 16
 
17 17
 extern int arp_process ( struct net_interface *arp_netif,
18 18
 			 struct pk_buff *pkb );

+ 0
- 63
src/include/gpxe/llh.h Datei anzeigen

@@ -1,63 +0,0 @@
1
-#ifndef _LLH_H
2
-#define _LLH_H
3
-
4
-/** @file
5
- *
6
- * Link-layer headers
7
- *
8
- * This file defines a media-independent link-layer header, used for
9
- * communication between the network and link layers of the stack.
10
- *
11
- */
12
-
13
-#include <stdint.h>
14
-
15
-/** Maximum length of a link-layer address */
16
-#define MAX_LLH_ADDR_LEN 6
17
-
18
-/** Maximum length of a network-layer address */
19
-#define MAX_NET_ADDR_LEN 4
20
-
21
-/* Network-layer address may be required to contain a raw link-layer address */
22
-#if MAX_NET_ADDR_LEN < MAX_LLH_ADDR_LEN
23
-#undef MAX_NET_ADDR_LEN
24
-#define MAX_NET_ADDR_LEN MAX_LLH_ADDR_LEN
25
-#endif
26
-
27
-/** A media-independent link-layer header
28
- *
29
- * This structure represents a generic link-layer header.  It never
30
- * appears on the wire, but is used to communicate between different
31
- * layers within the gPXE protocol stack.
32
- */
33
-struct gpxehdr {
34
-	/** The network-layer protocol
35
-	 *
36
-	 * This is the network-layer protocol expressed as an
37
-	 * ETH_P_XXX constant, in network-byte order.
38
-	 */
39
-	uint16_t net_proto;
40
-	/** Flags
41
-	 *
42
-	 * Filled in only on outgoing packets.  Value is the
43
-	 * bitwise-OR of zero or more GPXE_FL_XXX constants.
44
-	 */
45
-	uint8_t flags;
46
-	/** Network-layer address length 
47
-	 *
48
-	 * Filled in only on outgoing packets.
49
-	 */
50
-	uint8_t net_addr_len;
51
-	/** Network-layer address
52
-	 *
53
-	 * Filled in only on outgoing packets.
54
-	 */
55
-	uint8_t net_addr[MAX_NET_ADDR_LEN];
56
-} __attribute__ (( packed ));
57
-
58
-/* Media-independent link-layer header flags */
59
-#define GPXE_FL_BROADCAST	0x01
60
-#define GPXE_FL_MULTICAST	0x02
61
-#define GPXE_FL_RAW		0x04
62
-
63
-#endif /* _LLH_H */

+ 26
- 36
src/include/gpxe/netdevice.h Datei anzeigen

@@ -8,13 +8,18 @@
8 8
  */
9 9
 
10 10
 #include <stdint.h>
11
-#include <gpxe/llh.h>
12 11
 #include <gpxe/list.h>
13 12
 
14 13
 struct net_device;
15 14
 struct net_interface;
16 15
 struct pk_buff;
17 16
 
17
+/** Maximum length of a link-layer address */
18
+#define MAX_LLH_ADDR_LEN 6
19
+
20
+/** Maximum length of a network-layer address */
21
+#define MAX_NET_ADDR_LEN 4
22
+
18 23
 /**
19 24
  * A network device
20 25
  *
@@ -45,7 +50,6 @@ struct net_device {
45 50
 	/** Poll for received packet
46 51
 	 *
47 52
 	 * @v netdev	Network device
48
-	 * @v retrieve	Flag indicating whether or not to retrieve packet
49 53
 	 * @v pkb	Packet buffer to contain received packet
50 54
 	 * @ret rc	Return status code
51 55
 	 *
@@ -53,55 +57,42 @@ struct net_device {
53 57
 	 * received packet.  If no packet is available, the method
54 58
 	 * should return -EAGAIN (i.e. this method is *always*
55 59
 	 * considered to be a non-blocking read).  If a packet is
56
-	 * available, but @c retrieve is false, the method should
57
-	 * return zero for success.  If a packet is available and @c
58
-	 * retrieve is true, the method should fill the packet buffer
59
-	 * and return zero for success.
60
+	 * available, the method should fill the packet buffer and
61
+	 * return zero for success.
60 62
 	 */
61
-	int ( * poll ) ( struct net_device *netdev, int retrieve,
62
-			 struct pk_buff *pkb );
63
-	/** Build media-specific link-layer header
63
+	int ( * poll ) ( struct net_device *netdev, struct pk_buff *pkb );
64
+	/** Build link-layer header
64 65
 	 *
65 66
 	 * @v netdev	Network device
66 67
 	 * @v pkb	Packet buffer
67 68
 	 * @ret rc	Return status code
68 69
 	 *
69
-	 * This method should convert the packet buffer's generic
70
-	 * link-layer header (a struct gpxehdr) into a media-specific
71
-	 * link-layer header (e.g. a struct ethhdr).  The generic
72
-	 * header should be removed from the buffer (via pkb_pull())
73
-	 * and the media-specific header should be prepended (via
74
-	 * pkb_push()) in its place.
70
+	 * This method should fill in the link-layer header based on
71
+	 * the metadata contained in @c pkb.
75 72
 	 *
76 73
 	 * If a link-layer header cannot be constructed (e.g. because
77 74
 	 * of a missing ARP cache entry), then this method should
78 75
 	 * return an error (after transmitting an ARP request, if
79 76
 	 * applicable).
80 77
 	 */
81
-	int ( * make_media_header ) ( struct net_device *netdev,
82
-				      struct pk_buff *pkb );
83
-	/** Build media-independent link-layer header
78
+	int ( * build_llh ) ( struct net_device *netdev, struct pk_buff *pkb );
79
+	/** Parse link-layer header
84 80
 	 *
85 81
 	 * @v netdev	Network device
86 82
 	 * @v pkb	Packet buffer
87 83
 	 * @ret rc	Return status code
88 84
 	 *
89
-	 * This method should convert the packet buffer's
90
-	 * media-specific link-layer header (e.g. a struct ethhdr)
91
-	 * into a generic link-layer header (a struct gpxehdr).  It
92
-	 * performs the converse function of make_media_header().
93
-	 *
94
-	 * Note that the gpxehdr::addr and gpxehdr::addrlen fields
95
-	 * will not be filled in by this function, since doing so
96
-	 * would require understanding the network-layer header.
85
+	 * This method should parse the link-layer header and fill in
86
+	 * the metadata in @c pkb.
97 87
 	 */
98
-	int ( * make_generic_header ) ( struct net_device *netdev,
99
-					struct pk_buff *pkb );
88
+	int ( * parse_llh ) ( struct net_device *netdev, struct pk_buff *pkb );
100 89
 	/** Link-layer protocol
101 90
 	 *
102 91
 	 * This is an ARPHRD_XXX constant, in network byte order.
103 92
 	 */
104 93
 	uint16_t ll_proto;
94
+	/** Link-layer header length */
95
+	uint8_t ll_hlen;
105 96
 	/** Link-layer address length */
106 97
 	uint8_t ll_addr_len;
107 98
 	/** Link-layer address
@@ -151,17 +142,18 @@ struct net_interface {
151 142
 	 */
152 143
 	int ( * process ) ( struct net_interface *netif,
153 144
 			    struct pk_buff *pkb );
154
-	/** Add media-independent link-layer header
145
+	/** Fill in packet metadata
155 146
 	 *
156 147
 	 * @v netif	Network interface
157 148
 	 * @v pkb	Packet buffer
158 149
 	 * @ret rc	Return status code
159 150
 	 *
160
-	 * This method should prepend a generic link-layer header (a
161
-	 * struct @c gpxehdr) to the packet buffer using pkb_push().
151
+	 * This method should fill in the @c pkb metadata with enough
152
+	 * information to enable net_device::build_llh to construct
153
+	 * the link-layer header.
162 154
 	 */
163
-	int ( * add_generic_header ) ( struct net_interface *netif,
164
-				       struct pk_buff *pkb );
155
+	int ( * add_llh_metadata ) ( struct net_interface *netif,
156
+				     struct pk_buff *pkb );
165 157
 };
166 158
 
167 159
 /**
@@ -196,9 +188,7 @@ extern struct net_device static_single_netdev;
196 188
 
197 189
 extern int register_netdevice ( struct net_device *netdev );
198 190
 
199
-static inline void unregister_netdevice ( struct net_device *netdev __unused ){
200
-	/* Do nothing */
201
-}
191
+extern void unregister_netdevice ( struct net_device *netdev );
202 192
 
203 193
 static inline void free_netdevice ( struct net_device *netdev __unused ) {
204 194
 	/* Do nothing */

+ 32
- 0
src/include/gpxe/pkbuff.h Datei anzeigen

@@ -26,8 +26,40 @@ struct pk_buff {
26 26
 	void *tail;
27 27
 	/** End of the buffer */
28 28
         void *end;
29
+
30
+	/** The network-layer protocol
31
+	 *
32
+	 * This is the network-layer protocol expressed as an
33
+	 * ETH_P_XXX constant, in network-byte order.
34
+	 */
35
+	uint16_t net_proto;
36
+	/** Flags
37
+	 *
38
+	 * Filled in only on outgoing packets.  Value is the
39
+	 * bitwise-OR of zero or more PKB_FL_XXX constants.
40
+	 */
41
+	uint8_t flags;
42
+	/** Network-layer address length 
43
+	 *
44
+	 * Filled in only on outgoing packets.
45
+	 */
46
+	uint8_t net_addr_len;
47
+	/** Network-layer address
48
+	 *
49
+	 * Filled in only on outgoing packets.
50
+	 */
51
+	void *net_addr;
29 52
 };
30 53
 
54
+/** Packet is a broadcast packet */
55
+#define PKB_FL_BROADCAST 0x01
56
+
57
+/** Packet is a multicast packet */
58
+#define PKB_FL_MULTICAST 0x02
59
+
60
+/** Network-layer address is a raw hardware address */
61
+#define PKB_FL_RAW_NET_ADDR 0x04
62
+
31 63
 /**
32 64
  * Add data to start of packet buffer
33 65
  *

+ 20
- 27
src/net/arp.c Datei anzeigen

@@ -23,7 +23,6 @@
23 23
 #include <gpxe/if_ether.h>
24 24
 #include <gpxe/if_arp.h>
25 25
 #include <gpxe/pkbuff.h>
26
-#include <gpxe/llh.h>
27 26
 #include <gpxe/netdevice.h>
28 27
 #include <gpxe/arp.h>
29 28
 
@@ -91,45 +90,43 @@ arp_find_entry ( uint16_t ll_proto, uint16_t net_proto, const void *net_addr,
91 90
  *
92 91
  * @v netdev		Network device
93 92
  * @v pkb		Packet buffer
94
- * @v ll_addr		Buffer to contain link-layer address
93
+ * @ret ll_addr		Pointer to link-layer address
95 94
  * @ret rc		Return status code
96 95
  *
97
- * The packet buffer must start with a media-independent link-layer
98
- * header (a struct @c gpxehdr).  This function will use the ARP cache
99
- * to look up the link-layer address for the media corresponding to
100
- * @c netdev and the network-layer address as specified in @c gpxehdr.
96
+ * This function will use the ARP cache to look up the link-layer
97
+ * address for the media corresponding to @c netdev and the
98
+ * network-layer address as specified in the @c pkb metadata.
101 99
  *
102 100
  * If no address is found in the ARP cache, an ARP request will be
103 101
  * transmitted, -ENOENT will be returned, and the packet buffer
104 102
  * contents will be undefined.
105 103
  */
106 104
 int arp_resolve ( struct net_device *netdev, struct pk_buff *pkb,
107
-		  void *ll_addr ) {
108
-	struct gpxehdr *gpxehdr = pkb->data;
105
+		  const void **ll_addr ) {
109 106
 	const struct arp_entry *arp;
110 107
 	struct net_interface *netif;
111 108
 	struct arphdr *arphdr;
112 109
 
113 110
 	/* Look for existing entry in ARP table */
114
-	arp = arp_find_entry ( netdev->ll_proto, gpxehdr->net_proto,
115
-			       gpxehdr->net_addr, gpxehdr->net_addr_len );
111
+	arp = arp_find_entry ( netdev->ll_proto, pkb->net_proto,
112
+			       pkb->net_addr, pkb->net_addr_len );
116 113
 	if ( arp ) {
117
-		memcpy ( ll_addr, arp->ll_addr, netdev->ll_addr_len );
114
+		*ll_addr = arp->ll_addr;
118 115
 		return 0;
119 116
 	}
120 117
 
121 118
 	/* Find interface for this protocol */
122
-	netif = netdev_find_netif ( netdev, gpxehdr->net_proto );
119
+	netif = netdev_find_netif ( netdev, pkb->net_proto );
123 120
 	if ( ! netif )
124 121
 		return -EAFNOSUPPORT;
125 122
 
126 123
 	/* Build up ARP request */
127
-	pkb_unput ( pkb, pkb_len ( pkb ) - sizeof ( *gpxehdr ) );
124
+	pkb_empty ( pkb );
128 125
 	arphdr = pkb_put ( pkb, sizeof ( *arphdr ) );
129 126
 	arphdr->ar_hrd = netdev->ll_proto;
130 127
 	arphdr->ar_hln = netdev->ll_addr_len;
131
-	arphdr->ar_pro = gpxehdr->net_proto;
132
-	arphdr->ar_pln = gpxehdr->net_addr_len;
128
+	arphdr->ar_pro = pkb->net_proto;
129
+	arphdr->ar_pln = pkb->net_addr_len;
133 130
 	arphdr->ar_op = htons ( ARPOP_REQUEST );
134 131
 	memcpy ( pkb_put ( pkb, netdev->ll_addr_len ),
135 132
 		 netdev->ll_addr, netdev->ll_addr_len );
@@ -138,8 +135,7 @@ int arp_resolve ( struct net_device *netdev, struct pk_buff *pkb,
138 135
 	memset ( pkb_put ( pkb, netdev->ll_addr_len ),
139 136
 		 0xff, netdev->ll_addr_len );
140 137
 	memcpy ( pkb_put ( pkb, netif->net_addr_len ),
141
-		 gpxehdr->net_addr, netif->net_addr_len );
142
-	pkb_pull ( pkb, sizeof ( *gpxehdr ) );
138
+		 pkb->net_addr, netif->net_addr_len );
143 139
 
144 140
 	/* Locate ARP interface and send ARP request */
145 141
 	netif = netdev_find_netif ( netdev, htons ( ETH_P_ARP ) );
@@ -228,17 +224,14 @@ int arp_process ( struct net_interface *arp_netif, struct pk_buff *pkb ) {
228 224
  * @v pkb		Packet buffer
229 225
  * @ret rc		Return status code
230 226
  */
231
-int arp_add_generic_header ( struct net_interface *arp_netif __unused,
232
-			     struct pk_buff *pkb ) {
227
+int arp_add_llh_metadata ( struct net_interface *arp_netif __unused,
228
+			   struct pk_buff *pkb ) {
233 229
 	struct arphdr *arphdr = pkb->data;
234
-	struct gpxehdr *gpxehdr;
235
-
236
-	/* We're ARP; we always know the raw link-layer address we want */
237
-	gpxehdr = pkb_push ( pkb, sizeof ( *gpxehdr ) );
238
-	gpxehdr->net_proto = htons ( ETH_P_ARP );
239
-	gpxehdr->flags = GPXE_FL_RAW;
240
-	gpxehdr->net_addr_len = arphdr->ar_hln;
241
-	memcpy ( gpxehdr->net_addr, arp_target_ha ( arphdr ), arphdr->ar_hln );
230
+
231
+	pkb->net_proto = htons ( ETH_P_ARP );
232
+	pkb->flags = PKB_FL_RAW_NET_ADDR;
233
+	pkb->net_addr_len = arphdr->ar_hln;
234
+	pkb->net_addr = arp_target_ha ( arphdr );
242 235
 	
243 236
 	return 0;
244 237
 }

+ 116
- 0
src/net/ethernet.c Datei anzeigen

@@ -0,0 +1,116 @@
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 <string.h>
21
+#include <byteswap.h>
22
+#include <assert.h>
23
+#include <gpxe/if_ether.h>
24
+#include <gpxe/netdevice.h>
25
+#include <gpxe/pkbuff.h>
26
+#include <gpxe/arp.h>
27
+
28
+/** @file
29
+ *
30
+ * Ethernet protocol
31
+ *
32
+ */
33
+
34
+/** Ethernet broadcast MAC address */
35
+static uint8_t eth_broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
36
+
37
+/**
38
+ * Build Ethernet link-layer header
39
+ *
40
+ * @v netdev	Network device
41
+ * @v pkb	Packet buffer
42
+ * @ret rc	Return status code
43
+ *
44
+ * This constructs the Ethernet link-layer header (destination MAC,
45
+ * source MAC, network-layer protocol) based on the metadata found in
46
+ * @c pkb.
47
+ *
48
+ * If the destination MAC address cannot be determined, an ARP request
49
+ * is sent for the requested network-layer address instead.
50
+ */
51
+int eth_build_llh ( struct net_device *netdev, struct pk_buff *pkb ) {
52
+	struct ethhdr *ethhdr = pkb->data;
53
+	const void *eth_dest;
54
+	int rc;
55
+
56
+	/* Do the easy bits */
57
+	ethhdr->h_protocol = pkb->net_proto;
58
+	memcpy ( ethhdr->h_source, netdev->ll_addr,
59
+		 sizeof ( ethhdr->h_source ) );
60
+
61
+	/* Work out the destination MAC address */
62
+	if ( pkb->flags & PKB_FL_RAW_NET_ADDR ) {
63
+		eth_dest = pkb->net_addr;
64
+	} else if ( pkb->flags & PKB_FL_BROADCAST ) {
65
+		eth_dest = eth_broadcast;
66
+	} else if ( pkb->flags & PKB_FL_MULTICAST ) {
67
+		/* IP multicast is a special case; there exists a
68
+		 * direct mapping from IP address to MAC address
69
+		 */
70
+		assert ( pkb->net_proto == htons ( ETH_P_IP ) );
71
+		ethhdr->h_dest[0] = 0x01;
72
+		ethhdr->h_dest[1] = 0x00;
73
+		ethhdr->h_dest[2] = 0x5e;
74
+		ethhdr->h_dest[3] = *( ( char * ) pkb->net_addr + 1 ) & 0x7f;
75
+		ethhdr->h_dest[4] = *( ( char * ) pkb->net_addr + 2 );
76
+		ethhdr->h_dest[5] = *( ( char * ) pkb->net_addr + 3 );
77
+		eth_dest = ethhdr->h_dest;
78
+	} else {
79
+		/* Otherwise, look up the address using ARP */
80
+		if ( ( rc = arp_resolve ( netdev, pkb, &eth_dest ) ) != 0 )
81
+			return rc;
82
+	}
83
+
84
+	/* Fill in destination MAC address */
85
+	memcpy ( ethhdr->h_dest, eth_dest, sizeof ( ethhdr->h_dest ) );
86
+
87
+	return 0;
88
+}
89
+
90
+/**
91
+ * Parse Ethernet link-layer header
92
+ *
93
+ * @v netdev	Network device
94
+ * @v pkb	Packet buffer
95
+ * @ret rc	Return status code
96
+ *
97
+ * This parses the Ethernet link-layer header (destination MAC, source
98
+ * MAC, network-layer protocol) and fills in the metadata in @c pkb.
99
+ */
100
+int eth_parse_llh ( struct net_device *netdev __unused, struct pk_buff *pkb ) {
101
+	struct ethhdr *ethhdr = pkb->data;
102
+
103
+	pkb->net_proto = ethhdr->h_protocol;
104
+	pkb->flags = PKB_FL_RAW_NET_ADDR;
105
+	pkb->net_addr_len = sizeof ( ethhdr->h_dest );
106
+	pkb->net_addr = ethhdr->h_dest;
107
+
108
+	if ( memcmp ( ethhdr->h_dest, eth_broadcast,
109
+		      sizeof ( ethhdr->h_dest ) ) == 0 ) {
110
+		pkb->flags |= PKB_FL_BROADCAST;
111
+	} else if ( ethhdr->h_dest[0] & 0x01 ) {
112
+		pkb->flags |= PKB_FL_MULTICAST;
113
+	}
114
+
115
+	return 0;
116
+}

Laden…
Abbrechen
Speichern