aboutsummaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorMichael Brown <mcb30@etherboot.org>2006-06-16 00:19:46 +0000
committerMichael Brown <mcb30@etherboot.org>2006-06-16 00:19:46 +0000
commitbbd9e2806115961a1d1d218a3eeb31924a114cfd (patch)
tree90baf335d6ee455ff30d0d4554fd89b95d288418 /src/net
parentcce2e47ff4c63012810e1a3ff6f21286622631a5 (diff)
downloadipxe-bbd9e2806115961a1d1d218a3eeb31924a114cfd.tar.gz
Simplify TX datapath.
Diffstat (limited to 'src/net')
-rw-r--r--src/net/aoe.c33
-rw-r--r--src/net/arp.c65
-rw-r--r--src/net/ethernet.c94
-rw-r--r--src/net/ipv4.c265
-rw-r--r--src/net/netdevice.c129
-rw-r--r--src/net/tcp.c5
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 * ) &in;
+
+ 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 );
}
}
}