summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorMichael Brown2006-04-24 17:33:06 +0200
committerMichael Brown2006-04-24 17:33:06 +0200
commitfdc2ee79db376b03710f9255720ce45c79022768 (patch)
treef1d8ea36b34b2490a17e40698d1c4e6741230932 /src/include
parentObviate uip_init(); our bss is zeroed at startup already. (diff)
downloadipxe-fdc2ee79db376b03710f9255720ce45c79022768.tar.gz
ipxe-fdc2ee79db376b03710f9255720ce45c79022768.tar.xz
ipxe-fdc2ee79db376b03710f9255720ce45c79022768.zip
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.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/gpxe/arp.h21
-rw-r--r--src/include/gpxe/netdevice.h373
-rw-r--r--src/include/gpxe/pkbuff.h51
3 files changed, 272 insertions, 173 deletions
diff --git a/src/include/gpxe/arp.h b/src/include/gpxe/arp.h
index f6ec47af..a2db80f1 100644
--- a/src/include/gpxe/arp.h
+++ b/src/include/gpxe/arp.h
@@ -1,5 +1,5 @@
-#ifndef _ARP_H
-#define _ARP_H
+#ifndef _GPXE_ARP_H
+#define _GPXE_ARP_H
/** @file
*
@@ -7,17 +7,10 @@
*
*/
-struct net_device;
-struct net_interface;
-struct pk_buff;
+struct net_header;
+struct ll_header;
-extern int arp_resolve ( struct net_device *netdev, struct pk_buff *pkb,
- const void **ll_addr );
+extern int arp_resolve ( const struct net_header *nethdr,
+ struct ll_header *llhdr );
-extern int arp_process ( struct net_interface *arp_netif,
- struct pk_buff *pkb );
-
-extern int arp_add_generic_header ( struct net_interface *arp_netif,
- struct pk_buff *pkb );
-
-#endif /* _ARP_H */
+#endif /* _GPXE_ARP_H */
diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h
index 93a98634..f7d78288 100644
--- a/src/include/gpxe/netdevice.h
+++ b/src/include/gpxe/netdevice.h
@@ -1,203 +1,326 @@
-#ifndef _NETDEVICE_H
-#define _NETDEVICE_H
+#ifndef _GPXE_NETDEVICE_H
+#define _GPXE_NETDEVICE_H
/** @file
*
- * Network device and network interface
+ * Network device management
*
*/
#include <stdint.h>
-#include <gpxe/list.h>
+#include <gpxe/tables.h>
-struct net_device;
-struct net_interface;
struct pk_buff;
+struct net_protocol;
+struct ll_protocol;
/** Maximum length of a link-layer address */
-#define MAX_LLH_ADDR_LEN 6
+#define MAX_LL_ADDR_LEN 6
/** Maximum length of a network-layer address */
#define MAX_NET_ADDR_LEN 4
+/* Network-layer address may be required to hold a link-layer address
+ * (if NETADDR_FL_RAW is set
+ */
+#if MAX_NET_ADDR_LEN < MAX_LL_ADDR_LEN
+#undef MAX_NET_ADDR_LEN
+#define MAX_NET_ADDR_LEN MAX_LL_ADDR_LEN
+#endif
+
+/** A generic network-layer header */
+struct net_header {
+ /** Network-layer protocol */
+ struct net_protocol *net_protocol;
+ /** Destination address flags
+ *
+ * This is the bitwise OR of zero or more NETADDR_FL_XXX
+ * values.
+ */
+ int dest_flags;
+ /** Network-layer destination address */
+ uint8_t dest_net_addr[MAX_NET_ADDR_LEN];
+ /** Network-layer source address */
+ uint8_t source_net_addr[MAX_NET_ADDR_LEN];
+};
+
+/** Address is a broadcast address */
+#define NETADDR_FL_BROADCAST 0x01
+
+/** Address is a multicast address */
+#define NETADDR_FL_MULTICAST 0x02
+
+/** Address is a raw hardware address */
+#define NETADDR_FL_RAW 0x04
+
+/** A generic link-layer header */
+struct ll_header {
+ /** Link-layer protocol */
+ struct ll_protocol *ll_protocol;
+ /** Destination address flags
+ *
+ * This is the bitwise OR of zero or more NETADDR_FL_XXX
+ * values.
+ */
+ int dest_flags;
+ /** Link-layer destination address */
+ uint8_t dest_ll_addr[MAX_LL_ADDR_LEN];
+ /** Link-layer source address */
+ uint8_t source_ll_addr[MAX_LL_ADDR_LEN];
+ /** Network-layer protocol
+ *
+ *
+ * This is an ETH_P_XXX constant, in network-byte order
+ */
+ uint16_t net_proto;
+};
+
/**
- * A network device
- *
- * This structure represents a piece of networking hardware. It has
- * properties such as a link-layer address and methods for
- * transmitting and receiving raw packets. It does not know anything
- * about network-layer protocols (e.g. IP) or their addresses; these
- * are handled by struct @c net_interface instead.
+ * A network-layer protocol
*
- * Note that this structure must represent a generic network device,
- * not just an Ethernet device.
*/
-struct net_device {
- /** Transmit packet
+struct net_protocol {
+ /**
+ * Perform network-layer routing
*
- * @v netdev Network device
* @v pkb Packet buffer
+ * @ret source Network-layer source address
+ * @ret dest Network-layer destination address
* @ret rc Return status code
*
- * This method should cause the hardware to initiate
- * transmission of the packet buffer. The buffer may be
- * reused immediately after the method returns, and so the
- * method should either wait for packet transmission to
- * complete, or take a copy of the buffer contents.
+ * This method should fill in the source and destination
+ * addresses with enough information to allow the link layer
+ * to route the packet.
+ *
+ * For example, in the case of IPv4, this method should fill
+ * in @c source with the IP addresses of the local adapter and
+ * @c dest with the next hop destination (e.g. the gateway).
*/
- int ( * transmit ) ( struct net_device *netdev,
- struct pk_buff *pkb );
- /** Poll for received packet
+ int ( * route ) ( const struct pk_buff *pkb,
+ struct net_header *nethdr );
+ /**
+ * Handle received packets
*
- * @v netdev Network device
- * @v pkb Packet buffer to contain received packet
+ * @v pkb Packet buffer
* @ret rc Return status code
*
- * This method should cause the hardware to check for a
- * received packet. If no packet is available, the method
- * should return -EAGAIN (i.e. this method is *always*
- * considered to be a non-blocking read). If a packet is
- * available, the method should fill the packet buffer and
- * return zero for success.
+ * If this method returns success, it has taken ownership of
+ * the packet buffer.
*/
- int ( * poll ) ( struct net_device *netdev, struct pk_buff *pkb );
- /** Build link-layer header
+ int ( * rx ) ( struct pk_buff *pkb );
+ /** Network-layer protocol
*
- * @v netdev Network device
- * @v pkb Packet buffer
+ * This is an ETH_P_XXX constant, in network-byte order
+ */
+ uint16_t net_proto;
+ /** Network-layer address length */
+ uint8_t net_addr_len;
+};
+
+/**
+ * A link-layer protocol
+ *
+ */
+struct ll_protocol {
+ /**
+ * Perform link-layer routing
+ *
+ * @v nethdr Generic network-layer header
+ * @ret llhdr Generic link-layer header
* @ret rc Return status code
*
- * This method should fill in the link-layer header based on
- * the metadata contained in @c pkb.
+ * This method should construct the generic link-layer header
+ * based on the generic network-layer header.
*
* If a link-layer header cannot be constructed (e.g. because
* of a missing ARP cache entry), then this method should
* return an error (after transmitting an ARP request, if
* applicable).
*/
- int ( * build_llh ) ( struct net_device *netdev, struct pk_buff *pkb );
- /** Parse link-layer header
+ int ( * route ) ( const struct net_header *nethdr,
+ struct ll_header *llhdr );
+ /**
+ * Fill media-specific link-layer header
*
- * @v netdev Network device
+ * @v llhdr Generic link-layer header
* @v pkb Packet buffer
- * @ret rc Return status code
*
- * This method should parse the link-layer header and fill in
- * the metadata in @c pkb.
+ * This method should fill in the link-layer header in the
+ * packet buffer based on information in the generic
+ * link-layer header.
+ */
+ void ( * fill_llh ) ( const struct ll_header *llhdr,
+ struct pk_buff *pkb );
+ /**
+ * Parse media-specific link-layer header
+ *
+ * @v pkb Packet buffer
+ * @v llhdr Generic link-layer header
+ *
+ * This method should fill in the generic link-layer header
+ * based on information in the link-layer header in the packet
+ * buffer.
*/
- int ( * parse_llh ) ( struct net_device *netdev, struct pk_buff *pkb );
+ void ( * parse_llh ) ( const struct pk_buff *pkb,
+ struct ll_header *llhdr );
+
/** Link-layer protocol
*
* This is an ARPHRD_XXX constant, in network byte order.
*/
uint16_t ll_proto;
- /** Link-layer header length */
- uint8_t ll_hlen;
/** Link-layer address length */
uint8_t ll_addr_len;
- /** Link-layer address
- *
- * For Ethernet, this is the MAC address.
- */
- uint8_t ll_addr[MAX_LLH_ADDR_LEN];
- /** Linked list of network devices */
- struct list_head devices;
- /** List of network interfaces */
- struct list_head interfaces;
- /** Driver private data */
- void *priv;
+ /** Link-layer header length */
+ uint8_t ll_header_len;
};
/**
- * A network interface
- *
- * This structure represents a particular network layer protocol's
- * interface to a piece of network hardware (a struct @c net_device).
+ * A network-layer address assigned to a network device
*
*/
-struct net_interface {
- /** Underlying net device */
- struct net_device *netdev;
- /** Linked list of interfaces for this device */
- struct list_head interfaces;
- /** Network-layer protocol
- *
- * This is an ETH_P_XXX constant, in network byte order.
- */
- uint16_t net_proto;
- /** Network-layer address length */
- uint8_t net_addr_len;
+struct net_address {
+ /** Network-layer protocol */
+ struct net_protocol *net_protocol;
/** Network-layer address */
uint8_t net_addr[MAX_NET_ADDR_LEN];
- /** Fill in packet metadata
+};
+
+/**
+ * A network device
+ *
+ * This structure represents a piece of networking hardware. It has
+ * properties such as a link-layer address and methods for
+ * transmitting and receiving raw packets.
+ *
+ * Note that this structure must represent a generic network device,
+ * not just an Ethernet device.
+ */
+struct net_device {
+ /** Transmit packet
*
- * @v netif Network interface
+ * @v netdev Network device
* @v pkb Packet buffer
* @ret rc Return status code
*
- * This method should fill in the @c pkb metadata with enough
- * information to enable net_device::build_llh to construct
- * the link-layer header.
+ * This method should cause the hardware to initiate
+ * transmission of the packet buffer.
+ *
+ * If the method returns success, ownership of the packet
+ * buffer is transferred to the @c net_device, which must
+ * eventually call free_pkb() to release the buffer.
*/
- int ( * add_llh_metadata ) ( struct net_interface *netif,
- struct pk_buff *pkb );
- /** Received packet processor
+ int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
+ /** Poll for received packet
*
- * @v netif Network interface
- * @v pkb Packet buffer
- * @ret rc Return status code
+ * @v netdev Network device
*
- * This method is called for packets arriving on the
- * associated network device that match this interface's
- * network-layer protocol.
+ * This method should cause the hardware to check for received
+ * packets. Any received packets should be delivered via
+ * netdev_rx().
+ */
+ void ( * poll ) ( struct net_device *netdev );
+
+ /** Link-layer protocol */
+ struct ll_protocol *ll_protocol;
+ /** Link-layer address
*
- * When this method is called, the link-layer header will
- * already have been stripped from the packet.
+ * For Ethernet, this is the MAC address.
*/
- int ( * rx_packet ) ( struct net_interface *netif,
- struct pk_buff *pkb );
+ uint8_t ll_addr[MAX_LL_ADDR_LEN];
+
+ /** Driver private data */
+ void *priv;
};
+extern struct net_device static_single_netdev;
+
+/**
+ * Allocate network device
+ *
+ * @v priv_size Size of private data area (net_device::priv)
+ * @ret netdev Network device, or NULL
+ *
+ * Allocates space for a network device and its private data area.
+ *
+ * This macro allows for a very efficient implementation in the case
+ * of a single static network device; it neatly avoids dynamic
+ * allocation and can never return failure, meaning that the failure
+ * path will be optimised away. However, driver writers should not
+ * rely on this feature; the drivers should be written to allow for
+ * multiple instances of network devices.
+ */
+#define alloc_netdev( priv_size ) ( { \
+ static char priv_data[priv_size]; \
+ static_single_netdev.priv = priv_data; \
+ &static_single_netdev; } )
+
/**
- * Find interface for a specific protocol
+ * Register network device
*
- * @v netdev Network device
- * @v net_proto Network-layer protocol, in network byte order
- * @ret netif Network interface, or NULL if none found
+ * @v netdev Network device
+ * @ret rc Return status code
*
+ * Adds the network device to the list of network devices.
*/
-static inline struct net_interface *
-netdev_find_netif ( const struct net_device *netdev, uint16_t net_proto ) {
- struct net_interface *netif;
-
- list_for_each_entry ( netif, &netdev->interfaces, interfaces ) {
- if ( netif->net_proto == net_proto )
- return netif;
- }
- return NULL;
+static inline int
+register_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
+ return 0;
}
-extern int register_netdevice ( struct net_device *netdev );
-extern void unregister_netdevice ( struct net_device *netdev );
-extern int netdev_send ( struct net_device *netdev, struct pk_buff *pkb );
-extern int netdev_poll ( struct net_device *netdev, struct pk_buff *pkb );
-extern int netif_send ( struct net_interface *netif, struct pk_buff *pkb );
-extern int netdev_rx_packet ( struct net_device *netdev, struct pk_buff *pkb );
-extern int net_poll ( struct pk_buff *pkb, struct net_device **netdev );
+/**
+ * Unregister network device
+ *
+ * @v netdev Network device
+ *
+ * Removes the network device from the list of network devices.
+ */
+static inline void
+unregister_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
+ /* Nothing to do */
+}
+/**
+ * Free network device
+ *
+ * @v netdev Network device
+ */
+static inline void
+free_netdev ( struct net_device *netdev __attribute__ (( unused )) ) {
+ /* Nothing to do */
+}
+/**
+ * Register a link-layer protocol
+ *
+ * @v protocol Link-layer protocol
+ */
+#define LL_PROTOCOL( protocol ) \
+ struct ll_protocol protocol __table ( ll_protocols, 00 )
-extern struct net_device static_single_netdev;
+/**
+ * Register a network-layer protocol
+ *
+ * @v protocol Network-layer protocol
+ */
+#define NET_PROTOCOL( protocol ) \
+ struct net_protocol protocol __table ( net_protocols, 00 )
-/* Must be a macro because priv_data[] is of variable size */
-#define alloc_netdevice( priv_size ) ( { \
- static char priv_data[priv_size]; \
- static_single_netdev.priv = priv_data; \
- &static_single_netdev; } )
+/**
+ * Register a network-layer address for the static single network device
+ *
+ * @v net_address Network-layer address
+ */
+#define STATIC_SINGLE_NETDEV_ADDRESS( address ) \
+ struct net_address address __table ( sgl_netdev_addresses, 00 )
+extern struct net_protocol *net_find_protocol ( uint16_t net_proto );
+extern struct net_device * net_find_address ( struct net_protocol *net_proto,
+ void *net_addr );
-static inline void free_netdevice ( struct net_device *netdev __unused ) {
- /* Do nothing */
-}
+extern int net_transmit ( struct pk_buff *pkb );
+extern int net_poll ( void );
+extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
+extern struct pk_buff * net_rx_dequeue ( void );
-#endif /* _NETDEVICE_H */
+#endif /* _GPXE_NETDEVICE_H */
diff --git a/src/include/gpxe/pkbuff.h b/src/include/gpxe/pkbuff.h
index f82f508a..2e3980a8 100644
--- a/src/include/gpxe/pkbuff.h
+++ b/src/include/gpxe/pkbuff.h
@@ -1,5 +1,5 @@
-#ifndef _PKBUFF_H
-#define _PKBUFF_H
+#ifndef _GPXE_PKBUFF_H
+#define _GPXE_PKBUFF_H
/** @file
*
@@ -12,6 +12,10 @@
#include <stdint.h>
#include <assert.h>
+#include <gpxe/list.h>
+
+struct net_protocol;
+struct ll_protocol;
/** A packet buffer
*
@@ -27,38 +31,14 @@ struct pk_buff {
/** End of the buffer */
void *end;
- /** The network-layer protocol
- *
- * This is the network-layer protocol expressed as an
- * ETH_P_XXX constant, in network-byte order.
- */
- uint16_t net_proto;
- /** Flags
- *
- * Filled in only on outgoing packets. Value is the
- * bitwise-OR of zero or more PKB_FL_XXX constants.
- */
- uint8_t flags;
- /** Network-layer address length
- *
- * Filled in only on outgoing packets.
- */
- uint8_t net_addr_len;
- /** Network-layer address
- *
- * Filled in only on outgoing packets.
- */
- void *net_addr;
-};
-
-/** Packet is a broadcast packet */
-#define PKB_FL_BROADCAST 0x01
+ /** List of which this buffer is a member */
+ struct list_head list;
-/** Packet is a multicast packet */
-#define PKB_FL_MULTICAST 0x02
-
-/** Network-layer address is a raw hardware address */
-#define PKB_FL_RAW_NET_ADDR 0x04
+ /** The network-layer protocol */
+ struct net_protocol *net_protocol;
+ /** The link-layer protocol */
+ struct ll_protocol *ll_protocol;
+};
/**
* Add data to start of packet buffer
@@ -130,4 +110,7 @@ static inline size_t pkb_len ( struct pk_buff *pkb ) {
return ( pkb->tail - pkb->data );
}
-#endif /* _PKBUFF_H */
+extern struct pk_buff * alloc_pkb ( size_t len );
+extern void free_pkb ( struct pk_buff *pkb );
+
+#endif /* _GPXE_PKBUFF_H */