diff options
author | Michael Brown | 2006-04-24 17:33:06 +0200 |
---|---|---|
committer | Michael Brown | 2006-04-24 17:33:06 +0200 |
commit | fdc2ee79db376b03710f9255720ce45c79022768 (patch) | |
tree | f1d8ea36b34b2490a17e40698d1c4e6741230932 /src/include | |
parent | Obviate uip_init(); our bss is zeroed at startup already. (diff) | |
download | ipxe-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.h | 21 | ||||
-rw-r--r-- | src/include/gpxe/netdevice.h | 373 | ||||
-rw-r--r-- | src/include/gpxe/pkbuff.h | 51 |
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 */ |