diff options
author | Michael Brown <mcb30@etherboot.org> | 2006-06-16 00:19:46 +0000 |
---|---|---|
committer | Michael Brown <mcb30@etherboot.org> | 2006-06-16 00:19:46 +0000 |
commit | bbd9e2806115961a1d1d218a3eeb31924a114cfd (patch) | |
tree | 90baf335d6ee455ff30d0d4554fd89b95d288418 /src/net | |
parent | cce2e47ff4c63012810e1a3ff6f21286622631a5 (diff) | |
download | ipxe-bbd9e2806115961a1d1d218a3eeb31924a114cfd.tar.gz |
Simplify TX datapath.
Diffstat (limited to 'src/net')
-rw-r--r-- | src/net/aoe.c | 33 | ||||
-rw-r--r-- | src/net/arp.c | 65 | ||||
-rw-r--r-- | src/net/ethernet.c | 94 | ||||
-rw-r--r-- | src/net/ipv4.c | 265 | ||||
-rw-r--r-- | src/net/netdevice.c | 129 | ||||
-rw-r--r-- | src/net/tcp.c | 5 |
6 files changed, 221 insertions, 370 deletions
diff --git a/src/net/aoe.c b/src/net/aoe.c index cfb833f26..693b36050 100644 --- a/src/net/aoe.c +++ b/src/net/aoe.c @@ -24,6 +24,7 @@ #include <byteswap.h> #include <gpxe/list.h> #include <gpxe/if_ether.h> +#include <gpxe/ethernet.h> #include <gpxe/pkbuff.h> #include <gpxe/uaccess.h> #include <gpxe/ata.h> @@ -116,7 +117,7 @@ static int aoe_send_command ( struct aoe_session *aoe ) { /* Send packet */ start_timer ( &aoe->timer ); - return net_transmit_via ( pkb, aoe->netdev ); + return net_transmit ( pkb, aoe->netdev, &aoe_protocol, aoe->target ); } /** @@ -251,38 +252,11 @@ static int aoe_rx ( struct pk_buff *pkb ) { return rc; } -/** - * Perform AoE network-layer routing - * - * @v pkb Packet buffer - * @ret source Network-layer source address - * @ret dest Network-layer destination address - * @ret rc Return status code - */ -static int aoe_route ( const struct pk_buff *pkb __unused, - struct net_header *nethdr ) { - struct aoehdr *aoehdr = pkb->data; - struct aoe_session *aoe; - - list_for_each_entry ( aoe, &aoe_sessions, list ) { - if ( ( ntohs ( aoehdr->major ) == aoe->major ) && - ( aoehdr->minor == aoe->minor ) ) { - nethdr->flags = PKT_FL_RAW_ADDR; - memcpy ( nethdr->dest_net_addr, aoe->target, - sizeof ( aoe->target ) ); - return 0; - } - } - - return -EHOSTUNREACH; -} - /** AoE protocol */ struct net_protocol aoe_protocol = { .name = "AoE", .net_proto = htons ( ETH_P_AOE ), .rx_process = aoe_rx, - .route = aoe_route, }; NET_PROTOCOL ( aoe_protocol ); @@ -293,7 +267,8 @@ NET_PROTOCOL ( aoe_protocol ); * @v aoe AoE session */ void aoe_open ( struct aoe_session *aoe ) { - memset ( aoe->target, 0xff, sizeof ( aoe->target ) ); + memcpy ( aoe->target, ethernet_protocol.ll_broadcast, + sizeof ( aoe->target ) ); aoe->tag = AOE_TAG_MAGIC; aoe->timer.expired = aoe_timer_expired; list_add ( &aoe->list, &aoe_sessions ); diff --git a/src/net/arp.c b/src/net/arp.c index af7d6e122..66f9bd4cf 100644 --- a/src/net/arp.c +++ b/src/net/arp.c @@ -92,42 +92,42 @@ arp_find_entry ( struct ll_protocol *ll_protocol, * Look up media-specific link-layer address in the ARP cache * * @v netdev Network device - * @v nethdr Generic network-layer header - * @ret llhdr Generic link-layer header + * @v net_protocol Network-layer protocol + * @v dest_net_addr Destination network-layer address + * @v source_net_addr Source network-layer address + * @ret dest_ll_addr Destination link layer address * @ret rc Return status code * * This function will use the ARP cache to look up the link-layer - * address for the link-layer protocol specified in @c llhdr and the - * network-layer protocol and address as specified in @c nethdr. If + * address for the link-layer protocol associated with the network + * device and the given network-layer protocol and addresses. If * found, the destination link-layer address will be filled in in @c - * llhdr. + * dest_ll_addr. * * If no address is found in the ARP cache, an ARP request will be * transmitted on the specified network device and -ENOENT will be * returned. */ -int arp_resolve ( struct net_device *netdev, const struct net_header *nethdr, - struct ll_header *llhdr ) { - struct net_protocol *net_protocol = nethdr->net_protocol; - struct ll_protocol *ll_protocol = llhdr->ll_protocol; +int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol, + const void *dest_net_addr, const void *source_net_addr, + void *dest_ll_addr ) { + struct ll_protocol *ll_protocol = netdev->ll_protocol; const struct arp_entry *arp; struct pk_buff *pkb; struct arphdr *arphdr; int rc; /* Look for existing entry in ARP table */ - arp = arp_find_entry ( ll_protocol, net_protocol, - nethdr->dest_net_addr ); + arp = arp_find_entry ( ll_protocol, net_protocol, dest_net_addr ); if ( arp ) { DBG ( "ARP cache hit: %s %s => %s %s\n", net_protocol->name, net_protocol->ntoa ( arp->net_addr ), ll_protocol->name, ll_protocol->ntoa ( arp->ll_addr ) ); - memcpy ( llhdr->dest_ll_addr, arp->ll_addr, - sizeof ( llhdr->dest_ll_addr ) ); + memcpy ( dest_ll_addr, arp->ll_addr, ll_protocol->ll_addr_len); return 0; } DBG ( "ARP cache miss: %s %s\n", net_protocol->name, - net_protocol->ntoa ( nethdr->dest_net_addr ) ); + net_protocol->ntoa ( dest_net_addr ) ); /* Allocate ARP packet */ pkb = alloc_pkb ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) + @@ -145,16 +145,17 @@ int arp_resolve ( struct net_device *netdev, const struct net_header *nethdr, arphdr->ar_pln = net_protocol->net_addr_len; arphdr->ar_op = htons ( ARPOP_REQUEST ); memcpy ( pkb_put ( pkb, ll_protocol->ll_addr_len ), - llhdr->source_ll_addr, ll_protocol->ll_addr_len ); + netdev->ll_addr, ll_protocol->ll_addr_len ); memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ), - nethdr->source_net_addr, net_protocol->net_addr_len ); + source_net_addr, net_protocol->net_addr_len ); memset ( pkb_put ( pkb, ll_protocol->ll_addr_len ), 0, ll_protocol->ll_addr_len ); memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ), - nethdr->dest_net_addr, net_protocol->net_addr_len ); + dest_net_addr, net_protocol->net_addr_len ); /* Transmit ARP request */ - if ( ( rc = net_transmit_via ( pkb, netdev ) ) != 0 ) + if ( ( rc = net_transmit ( pkb, netdev, &arp_protocol, + ll_protocol->ll_broadcast ) ) != 0 ) return rc; return -ENOENT; @@ -235,10 +236,10 @@ static int arp_rx ( struct pk_buff *pkb ) { arphdr->ar_op = htons ( ARPOP_REPLY ); memswap ( arp_sender_ha ( arphdr ), arp_target_ha ( arphdr ), arphdr->ar_hln + arphdr->ar_pln ); - memcpy ( arp_target_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln ); + memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln ); /* Send reply */ - net_transmit_via ( pkb, netdev ); + net_transmit ( pkb, netdev, &arp_protocol, arp_target_ha (arphdr ) ); pkb = NULL; done: @@ -247,29 +248,6 @@ static int arp_rx ( struct pk_buff *pkb ) { } /** - * Perform ARP network-layer routing - * - * @v pkb Packet buffer - * @ret source Network-layer source address - * @ret dest Network-layer destination address - * @ret rc Return status code - */ -static int arp_route ( const struct pk_buff *pkb, - struct net_header *nethdr ) { - struct arphdr *arphdr = pkb->data; - - memcpy ( nethdr->source_net_addr, arp_sender_ha ( arphdr ), - arphdr->ar_hln ); - memcpy ( nethdr->dest_net_addr, arp_target_ha ( arphdr ), - arphdr->ar_hln ); - nethdr->flags = PKT_FL_RAW_ADDR; - if ( arphdr->ar_op == htons ( ARPOP_REQUEST ) ) - nethdr->flags |= PKT_FL_BROADCAST; - - return 0; -} - -/** * Transcribe ARP address * * @v net_addr ARP address @@ -287,7 +265,6 @@ struct net_protocol arp_protocol = { .name = "ARP", .net_proto = htons ( ETH_P_ARP ), .rx_process = arp_rx, - .route = arp_route, .ntoa = arp_ntoa, }; diff --git a/src/net/ethernet.c b/src/net/ethernet.c index cadcb6742..f10bc60f7 100644 --- a/src/net/ethernet.c +++ b/src/net/ethernet.c @@ -25,7 +25,6 @@ #include <gpxe/if_ether.h> #include <gpxe/netdevice.h> #include <gpxe/pkbuff.h> -#include <gpxe/arp.h> #include <gpxe/ethernet.h> /** @file @@ -38,70 +37,24 @@ static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /** - * Perform Ethernet routing + * Transmit Ethernet packet * - * @v nethdr Generic network-layer header - * @ret llhdr Generic link-layer header - * @ret rc Return status code + * @v pkb Packet buffer + * @v netdev Network device + * @v net_protocol Network-layer protocol + * @v ll_dest Link-layer destination address * - * Constructs the generic link-layer header based on the generic - * network-layer header, i.e. maps network-layer addresses (e.g. IPv4 - * addresses) to MAC addresses. - * - * If the destination MAC address cannot be determined, an ARP request - * is sent for the requested network-layer address and -ENOENT is - * returned. - */ -static int eth_route ( struct net_device *netdev, - const struct net_header *nethdr, - struct ll_header *llhdr ) { - int rc; - - /* Fill in the easy bits */ - llhdr->net_proto = nethdr->net_protocol->net_proto; - memcpy ( llhdr->source_ll_addr, netdev->ll_addr, ETH_ALEN ); - - /* Work out the destination MAC address */ - if ( nethdr->flags & PKT_FL_BROADCAST ) { - memcpy ( llhdr->dest_ll_addr, eth_broadcast, ETH_ALEN ); - } else if ( nethdr->flags & PKT_FL_RAW_ADDR ) { - memcpy ( llhdr->dest_ll_addr, nethdr->dest_net_addr, ETH_ALEN); - } else if ( nethdr->flags & PKT_FL_MULTICAST ) { - /* IP multicast is a special case; there exists a - * direct mapping from IP address to MAC address - */ - assert ( nethdr->net_protocol->net_proto == htons(ETH_P_IP) ); - llhdr->dest_ll_addr[0] = 0x01; - llhdr->dest_ll_addr[1] = 0x00; - llhdr->dest_ll_addr[2] = 0x5e; - llhdr->dest_ll_addr[3] = nethdr->dest_net_addr[1] & 0x7f; - llhdr->dest_ll_addr[4] = nethdr->dest_net_addr[2]; - llhdr->dest_ll_addr[5] = nethdr->dest_net_addr[3]; - } else { - /* Otherwise, look up the address using ARP */ - if ( ( rc = arp_resolve ( netdev, nethdr, llhdr ) ) != 0 ) - return rc; - } - - return 0; -} - -/** - * Fill in Ethernet link-layer header - * - * @v pkb Packet buffer - * @v llhdr Generic link-layer header - * - * Fills in the Ethernet link-layer header in the packet buffer based - * on information in the generic link-layer header. + * Prepends the Ethernet link-layer header and transmits the packet. */ -static void eth_fill_llh ( const struct ll_header *llhdr, - struct pk_buff *pkb ) { - struct ethhdr *ethhdr = pkb->data; - - memcpy ( ethhdr->h_dest, llhdr->dest_ll_addr, ETH_ALEN ); - memcpy ( ethhdr->h_source, llhdr->source_ll_addr, ETH_ALEN ); - ethhdr->h_protocol = llhdr->net_proto; +static int eth_transmit ( struct pk_buff *pkb, struct net_device *netdev, + struct net_protocol *net_protocol, + const void *ll_dest ) { + struct ethhdr *ethhdr = pkb_push ( pkb, ETH_HLEN ); + + memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN ); + memcpy ( ethhdr->h_source, netdev->ll_addr, ETH_ALEN ); + ethhdr->h_protocol = net_protocol->net_proto; + return netdev_transmit ( netdev, pkb ); } /** @@ -138,7 +91,7 @@ static void eth_parse_llh ( const struct pk_buff *pkb, */ static const char * eth_ntoa ( const void *ll_addr ) { static char buf[18]; /* "00:00:00:00:00:00" */ - uint8_t *eth_addr = ll_addr; + const uint8_t *eth_addr = ll_addr; sprintf ( buf, "%02x:%02x:%02x:%02x:%02x:%02x", eth_addr[0], eth_addr[1], eth_addr[2], @@ -148,14 +101,13 @@ static const char * eth_ntoa ( const void *ll_addr ) { /** Ethernet protocol */ struct ll_protocol ethernet_protocol = { - .name = "Ethernet", - .ll_proto = htons ( ARPHRD_ETHER ), - .ll_addr_len = ETH_ALEN, - .ll_header_len = ETH_HLEN, - .route = eth_route, - .fill_llh = eth_fill_llh, - .parse_llh = eth_parse_llh, - .ntoa = eth_ntoa, + .name = "Ethernet", + .ll_proto = htons ( ARPHRD_ETHER ), + .ll_addr_len = ETH_ALEN, + .ll_broadcast = eth_broadcast, + .transmit = eth_transmit, + .parse_llh = eth_parse_llh, + .ntoa = eth_ntoa, }; LL_PROTOCOL ( ethernet_protocol ); diff --git a/src/net/ipv4.c b/src/net/ipv4.c index ddc8281dd..ae3404ccc 100644 --- a/src/net/ipv4.c +++ b/src/net/ipv4.c @@ -2,9 +2,11 @@ #include <stdint.h> #include <errno.h> #include <byteswap.h> +#include <malloc.h> #include <vsprintf.h> +#include <gpxe/list.h> #include <gpxe/in.h> - +#include <gpxe/arp.h> #include <ip.h> @@ -13,6 +15,7 @@ #include <gpxe/pkbuff.h> #include <gpxe/netdevice.h> #include "uip/uip.h" +#include <gpxe/ip.h> /** @file * @@ -27,121 +30,144 @@ struct net_protocol ipv4_protocol; -/** An IPv4 routing table entry */ -struct ipv4_route { - /** Network address */ - struct in_addr network; +/** An IPv4 address/routing table entry */ +struct ipv4_miniroute { + /** List of miniroutes */ + struct list_head list; + /** Network device */ + struct net_device *netdev; + /** IPv4 address */ + struct in_addr address; /** Subnet mask */ struct in_addr netmask; /** Gateway address */ struct in_addr gateway; - /** Gateway device */ - struct in_addr gatewaydev; -}; - -enum { - STATIC_SINGLE_NETDEV_ROUTE = 0, - DEFAULT_ROUTE, - NUM_ROUTES }; -/** IPv4 routing table */ -static struct ipv4_route routing_table[NUM_ROUTES]; - -#define routing_table_end ( routing_table + NUM_ROUTES ) +/** List of IPv4 miniroutes */ +static LIST_HEAD ( miniroutes ); -#if 0 /** - * Set IP address + * Add IPv4 interface * - */ -void set_ipaddr ( struct in_addr address ) { - union { - struct in_addr address; - uint16_t uip_address[2]; - } u; - - u.address = address; - uip_sethostaddr ( u.uip_address ); -} - -/** - * Set netmask + * @v netdev Network device + * @v address IPv4 address + * @v netmask Subnet mask + * @v gateway Gateway address (or @c INADDR_NONE for no gateway) + * @ret rc Return status code * */ -void set_netmask ( struct in_addr address ) { - union { - struct in_addr address; - uint16_t uip_address[2]; - } u; - - u.address = address; - uip_setnetmask ( u.uip_address ); +int add_ipv4_address ( struct net_device *netdev, struct in_addr address, + struct in_addr netmask, struct in_addr gateway ) { + struct ipv4_miniroute *miniroute; + + /* Allocate and populate miniroute structure */ + miniroute = malloc ( sizeof ( *miniroute ) ); + if ( ! miniroute ) + return -ENOMEM; + miniroute->netdev = netdev; + miniroute->address = address; + miniroute->netmask = netmask; + miniroute->gateway = gateway; + + /* Add to end of list if we have a gateway, otherwise to start + * of list. + */ + if ( gateway.s_addr != INADDR_NONE ) { + list_add_tail ( &miniroute->list, &miniroutes ); + } else { + list_add ( &miniroute->list, &miniroutes ); + } + return 0; } /** - * Set default gateway + * Remove IPv4 interface * + * @v netdev Network device */ -void set_gateway ( struct in_addr address ) { - union { - struct in_addr address; - uint16_t uip_address[2]; - } u; +void del_ipv4_address ( struct net_device *netdev ) { + struct ipv4_miniroute *miniroute; - u.address = address; - uip_setdraddr ( u.uip_address ); + list_for_each_entry ( miniroute, &miniroutes, list ) { + if ( miniroute->netdev == netdev ) { + list_del ( &miniroute->list ); + break; + } + } } /** - * Run the TCP/IP stack - * - * Call this function in a loop in order to allow TCP/IP processing to - * take place. This call takes the stack through a single iteration; - * it will typically be used in a loop such as - * - * @code + * Transmit packet constructed by uIP * - * struct tcp_connection *my_connection; - * ... - * tcp_connect ( my_connection ); - * while ( ! my_connection->finished ) { - * run_tcpip(); - * } - * - * @endcode + * @v pkb Packet buffer + * @ret rc Return status code * - * where @c my_connection->finished is set by one of the connection's - * #tcp_operations methods to indicate completion. */ -void run_tcpip ( void ) { - void *data; - size_t len; - uint16_t type; - int i; - - if ( netdev_poll ( 1, &data, &len ) ) { - /* We have data */ - memcpy ( uip_buf, data, len ); - uip_len = len; - type = ntohs ( *( ( uint16_t * ) ( uip_buf + 12 ) ) ); - if ( type == UIP_ETHTYPE_ARP ) { - uip_arp_arpin(); - } else { - uip_arp_ipin(); - uip_input(); +int ipv4_uip_transmit ( struct pk_buff *pkb ) { + struct iphdr *iphdr = pkb->data; + struct ipv4_miniroute *miniroute; + struct net_device *netdev = NULL; + struct in_addr next_hop; + struct in_addr source; + uint8_t ll_dest_buf[MAX_LL_ADDR_LEN]; + const uint8_t *ll_dest = ll_dest_buf; + int rc; + + /* Use routing table to identify next hop and transmitting netdev */ + next_hop = iphdr->dest; + list_for_each_entry ( miniroute, &miniroutes, list ) { + if ( ( ( ( iphdr->dest.s_addr ^ miniroute->address.s_addr ) & + miniroute->netmask.s_addr ) == 0 ) || + ( miniroute->gateway.s_addr != INADDR_NONE ) ) { + netdev = miniroute->netdev; + source = miniroute->address; + if ( miniroute->gateway.s_addr != INADDR_NONE ) + next_hop = miniroute->gateway; + break; } - if ( uip_len > 0 ) - uip_transmit(); + } + + /* Abort if no network device identified */ + if ( ! netdev ) { + DBG ( "No route to %s\n", inet_ntoa ( iphdr->dest ) ); + rc = -EHOSTUNREACH; + goto err; + } + + /* Determine link-layer destination address */ + if ( next_hop.s_addr == INADDR_BROADCAST ) { + /* Broadcast address */ + ll_dest = netdev->ll_protocol->ll_broadcast; + } else if ( IN_MULTICAST ( next_hop.s_addr ) ) { + /* Special case: IPv4 multicast over Ethernet. This + * code may need to be generalised once we find out + * what happens for other link layers. + */ + uint8_t *next_hop_bytes = ( uint8_t * ) &next_hop; + ll_dest_buf[0] = 0x01; + ll_dest_buf[0] = 0x00; + ll_dest_buf[0] = 0x5e; + ll_dest_buf[3] = next_hop_bytes[1] & 0x7f; + ll_dest_buf[4] = next_hop_bytes[2]; + ll_dest_buf[5] = next_hop_bytes[3]; } else { - for ( i = 0 ; i < UIP_CONNS ; i++ ) { - uip_periodic ( i ); - if ( uip_len > 0 ) - uip_transmit(); + /* Unicast address: resolve via ARP */ + if ( ( rc = arp_resolve ( netdev, &ipv4_protocol, &next_hop, + &source, ll_dest_buf ) ) != 0 ) { + DBG ( "No ARP entry for %s\n", + inet_ntoa ( iphdr->dest ) ); + goto err; } } + + /* Hand off to link layer */ + return net_transmit ( pkb, netdev, &ipv4_protocol, ll_dest ); + + err: + free_pkb ( pkb ); + return rc; } -#endif /** * Process incoming IP packets @@ -167,51 +193,25 @@ static int ipv4_rx ( struct pk_buff *pkb ) { pkb = alloc_pkb ( MAX_LL_HEADER_LEN + uip_len ); if ( ! pkb ) return -ENOMEM; - pkb->net_protocol = &ipv4_protocol; pkb_reserve ( pkb, MAX_LL_HEADER_LEN ); memcpy ( pkb_put ( pkb, uip_len ), uip_buf, uip_len ); - net_transmit ( pkb ); + ipv4_uip_transmit ( pkb ); } return 0; } /** - * Perform IP layer routing + * Convert IPv4 address to dotted-quad notation * - * @v pkb Packet buffer - * @ret source Network-layer source address - * @ret dest Network-layer destination address - * @ret rc Return status code + * @v in IP address + * @ret string IP address in dotted-quad notation */ -static int ipv4_route ( const struct pk_buff *pkb, - struct net_header *nethdr ) { - struct iphdr *iphdr = pkb->data; - struct in_addr *source = ( struct in_addr * ) nethdr->source_net_addr; - struct in_addr *dest = ( struct in_addr * ) nethdr->dest_net_addr; - struct ipv4_route *route; - - /* Route IP packet according to routing table */ - source->s_addr = INADDR_NONE; - dest->s_addr = iphdr->dest.s_addr; - for ( route = routing_table ; route < routing_table_end ; route++ ) { - if ( ( dest->s_addr & route->netmask.s_addr ) - == route->network.s_addr ) { - source->s_addr = route->gatewaydev.s_addr; - if ( route->gateway.s_addr ) - dest->s_addr = route->gateway.s_addr; - break; - } - } - - /* Set broadcast and multicast flags as applicable */ - nethdr->flags = 0; - if ( dest->s_addr == htonl ( INADDR_BROADCAST ) ) { - nethdr->flags = PKT_FL_BROADCAST; - } else if ( IN_MULTICAST ( dest->s_addr ) ) { - nethdr->flags = PKT_FL_MULTICAST; - } - - return 0; +char * inet_ntoa ( struct in_addr in ) { + static char buf[16]; /* "xxx.xxx.xxx.xxx" */ + uint8_t *bytes = ( uint8_t * ) ∈ + + sprintf ( buf, "%d.%d.%d.%d", bytes[0], bytes[1], bytes[2], bytes[3] ); + return buf; } /** @@ -222,12 +222,7 @@ static int ipv4_route ( const struct pk_buff *pkb, * */ static const char * ipv4_ntoa ( const void *net_addr ) { - static char buf[16]; /* "xxx.xxx.xxx.xxx" */ - uint8_t *ip_addr = net_addr; - - sprintf ( buf, "%d.%d.%d.%d", ip_addr[0], ip_addr[1], ip_addr[2], - ip_addr[3] ); - return buf; + return inet_ntoa ( * ( ( struct in_addr * ) net_addr ) ); } /** IPv4 protocol */ @@ -236,7 +231,6 @@ struct net_protocol ipv4_protocol = { .net_proto = htons ( ETH_P_IP ), .net_addr_len = sizeof ( struct in_addr ), .rx_process = ipv4_rx, - .route = ipv4_route, .ntoa = ipv4_ntoa, }; @@ -251,12 +245,3 @@ struct net_address static_single_ipv4_address = { }; STATIC_SINGLE_NETDEV_ADDRESS ( static_single_ipv4_address ); - -#warning "Remove this static-IP hack" -static struct ipv4_route routing_table[NUM_ROUTES] = { - { { htonl ( 0x0afefe00 ) }, { htonl ( 0xfffffffc ) }, - { htonl ( 0x00000000 ) }, { htonl ( 0x0afefe01 ) } }, - { { htonl ( 0x00000000 ) }, { htonl ( 0x00000000 ) }, - { htonl ( 0x0afefe02 ) }, { htonl ( 0x0afefe01 ) } }, -}; - diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 3d4640a8e..1825a55b2 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -62,6 +62,50 @@ static struct net_address static_single_netdev_addresses_end[0] /** Recevied packet queue */ static LIST_HEAD ( rx_queue ); +#warning "Remove this static IP address hack" +#include <ip.h> +#include <gpxe/ip.h> + +/** + * Register network device + * + * @v netdev Network device + * @ret rc Return status code + * + * Adds the network device to the list of network devices. + */ +int register_netdev ( struct net_device *netdev ) { + +#warning "Remove this static IP address hack" + { + const struct in_addr static_address = { htonl ( 0x0afefe01 ) }; + const struct in_addr static_netmask = { htonl ( 0xffffff00 ) }; + const struct in_addr static_gateway = { INADDR_NONE }; + int rc; + + if ( ( rc = add_ipv4_address ( netdev, static_address, + static_netmask, + static_gateway ) ) != 0 ) + return rc; + } + + return 0; +} + +/** + * Unregister network device + * + * @v netdev Network device + * + * Removes the network device from the list of network devices. + */ +void unregister_netdev ( struct net_device *netdev ) { + +#warning "Remove this static IP address hack" + del_ipv4_address ( netdev ); + +} + /** * Add packet to receive queue * @@ -129,88 +173,6 @@ find_netdev_by_net_addr ( struct net_protocol *net_protocol, } /** - * Transmit packet via a network device - * - * @v pkb Packet buffer - * @v netdev Network device, or NULL - * @ret rc Return status code - * - * Transmits the packet via the specified network device. The packet - * must begin with a network-layer header, and the @c net_protocol - * field must have been filled in. If @c netdev is NULL, the network - * device is identified via the packet contents, if possible. This - * function takes ownership of the packet buffer. - */ -int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev ) { - struct net_protocol *net_protocol; - struct net_header nethdr; - struct ll_protocol *ll_protocol; - struct ll_header llhdr; - int rc; - - /* Perform network-layer routing */ - net_protocol = pkb->net_protocol; - nethdr.net_protocol = net_protocol; - if ( ( rc = net_protocol->route ( pkb, &nethdr ) ) != 0 ) { - DBG ( "Could not route to %s address %s\n", - net_protocol->name, - net_protocol->ntoa ( nethdr.dest_net_addr ) ); - free_pkb ( pkb ); - return rc; - } - - /* Identify transmitting network device, if not specified */ - if ( ! netdev ) { - netdev = find_netdev_by_net_addr ( net_protocol, - nethdr.source_net_addr ); - if ( ! netdev ) { - DBG ( "No network device for %s address %s\n", - net_protocol->name, - net_protocol->ntoa ( nethdr.source_net_addr ) ); - free_pkb ( pkb ); - return -EHOSTUNREACH; - } - } - - /* Perform link-layer routing */ - ll_protocol = netdev->ll_protocol; - llhdr.ll_protocol = ll_protocol; - if ( ( rc = ll_protocol->route ( netdev, &nethdr, &llhdr ) ) != 0 ) { - DBG ( "No link-layer route to %s address %s\n", - net_protocol->name, - net_protocol->ntoa ( nethdr.dest_net_addr ) ); - free_pkb ( pkb ); - return rc; - } - - /* Prepend link-layer header */ - pkb_push ( pkb, ll_protocol->ll_header_len ); - ll_protocol->fill_llh ( &llhdr, pkb ); - - /* Hand off packet to network device */ - if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 ) { - DBG ( "Device failed to transmit packet\n" ); - return rc; - } - - DBG ( "Packet transmitted\n" ); - return 0; -} - -/** - * Transmit packet - * - * @v pkb Packet buffer - * @ret rc Return status code - * - * Transmits the packet via the appropriate network device. This - * function takes ownership of the packet buffer. - */ -int net_transmit ( struct pk_buff *pkb ) { - return net_transmit_via ( pkb, NULL ); -} - -/** * Poll for packet on all network devices * * @ret True There are packets present in the receive queue @@ -277,7 +239,8 @@ int net_rx_process ( struct pk_buff *pkb ) { pkb->net_protocol = net_protocol; /* Strip off link-layer header */ - pkb_pull ( pkb, ll_protocol->ll_header_len ); +#warning "Temporary hack" + pkb_pull ( pkb, ETH_HLEN ); /* Hand off to network layer */ if ( ( rc = net_protocol->rx_process ( pkb ) ) != 0 ) { diff --git a/src/net/tcp.c b/src/net/tcp.c index 06ab2eea2..5027678b1 100644 --- a/src/net/tcp.c +++ b/src/net/tcp.c @@ -176,9 +176,8 @@ static void tcp_periodic ( void ) { pkb_reserve ( pkb, MAX_LL_HEADER_LEN ); pkb_put ( pkb, uip_len ); memcpy ( pkb->data, uip_buf, uip_len ); - pkb->net_protocol = &ipv4_protocol; - - net_transmit ( pkb ); + + ipv4_uip_transmit ( pkb ); } } } |