From 3ca7dbe7cac5e2bed6fa4d48587046ac6d262608 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 19 Apr 2006 02:09:08 +0000 Subject: [PATCH] Added the concept of a network interface (a network-layer concept) as separate from a network device (a link-layer concept). --- src/include/gpxe/netdevice.h | 127 ++++++++++++++++++++++++++++------- 1 file changed, 104 insertions(+), 23 deletions(-) diff --git a/src/include/gpxe/netdevice.h b/src/include/gpxe/netdevice.h index 3a53ab67..dbb6be84 100644 --- a/src/include/gpxe/netdevice.h +++ b/src/include/gpxe/netdevice.h @@ -3,43 +3,31 @@ /** @file * - * Net device interface + * Network device and network interface * */ #include #include +#include struct net_device; +struct net_interface; struct pk_buff; /** * 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. + * * Note that this structure must represent a generic network device, * not just an Ethernet device. */ struct net_device { - /** Build media-specific link-layer header - * - * @v netdev Network device - * @v pkb Packet buffer - * @ret rc Return status code - * - * This method should convert the packet buffer's generic - * link-layer header (a struct gpxehdr) into a media-specific - * link-layer header (e.g. a struct ethhdr). The generic - * header should be removed from the buffer (via pkb_pull()) - * and the media-specific header should be prepended (via - * pkb_push()) in its place. - * - * If a link-layer header cannot be constructed (e.g. because - * of a missing ARP cache entry), then this method should - * replace the contents of the packet buffer with an - * appropriate ARP request or equivalent, and return -ENOENT. - */ - int ( * make_media_header ) ( struct net_device *netdev, - struct pk_buff *pkb ); /** Transmit packet * * @v netdev Network device @@ -72,7 +60,27 @@ struct net_device { */ int ( * poll ) ( struct net_device *netdev, int retrieve, struct pk_buff *pkb ); - /** Parse link-layer header + /** Build media-specific link-layer header + * + * @v netdev Network device + * @v pkb Packet buffer + * @ret rc Return status code + * + * This method should convert the packet buffer's generic + * link-layer header (a struct gpxehdr) into a media-specific + * link-layer header (e.g. a struct ethhdr). The generic + * header should be removed from the buffer (via pkb_pull()) + * and the media-specific header should be prepended (via + * pkb_push()) in its place. + * + * 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 ( * make_media_header ) ( struct net_device *netdev, + struct pk_buff *pkb ); + /** Build media-independent link-layer header * * @v netdev Network device * @v pkb Packet buffer @@ -91,7 +99,7 @@ struct net_device { struct pk_buff *pkb ); /** Link-layer protocol * - * This is an ARPHRD_XXX constant, in network-byte order. + * This is an ARPHRD_XXX constant, in network byte order. */ uint16_t ll_proto; /** Link-layer address length */ @@ -101,10 +109,83 @@ struct net_device { * For Ethernet, this is the MAC address. */ uint8_t ll_addr[MAX_LLH_ADDR_LEN]; + /** List of network interfaces */ + struct list_head interfaces; /** Driver private data */ void *priv; }; +/** + * A network interface + * + * This structure represents a particular network layer protocol's + * interface to a piece of network hardware (a struct @c net_device). + * + */ +struct net_interface { + /** Underlying net device */ + struct net_device *netdev; + /** Linked list of interfaces for this device */ + struct list_head list; + /** 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; + /** Network-layer address */ + uint8_t net_addr[MAX_NET_ADDR_LEN]; + /** Packet processor + * + * @v netif Network interface + * @v pkb Packet buffer + * @ret rc Return status code + * + * This method is called for packets arriving on the + * associated network device that match this interface's + * network-layer protocol. + * + * When this method is called, the link-layer header will + * already have been stripped from the packet. + */ + int ( * process ) ( struct net_interface *netif, + struct pk_buff *pkb ); + /** Add media-independent link-layer header + * + * @v netif Network interface + * @v pkb Packet buffer + * @ret rc Return status code + * + * This method should prepend a generic link-layer header (a + * struct @c gpxehdr) to the packet buffer using pkb_push(). + */ + int ( * add_generic_header ) ( struct net_interface *netif, + struct pk_buff *pkb ); +}; + +/** + * Find interface for a specific protocol + * + * @v netdev Network device + * @v net_proto Network-layer protocol, in network byte order + * @ret netif Network interface, or NULL if none found + * + */ +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, list ) { + if ( netif->net_proto == net_proto ) + return netif; + } + return NULL; +} + +extern int netdev_send ( struct net_device *netdev, struct pk_buff *pkb ); +extern int netif_send ( struct net_interface *netif, struct pk_buff *pkb ); + extern struct net_device static_single_netdev; /* Must be a macro because priv_data[] is of variable size */