mirror of
				https://github.com/xcat2/xNBA.git
				synced 2025-10-31 11:22:29 +00:00 
			
		
		
		
	Simplify TX datapath.
This commit is contained in:
		| @@ -8,11 +8,12 @@ | ||||
|  */ | ||||
|  | ||||
| struct net_device; | ||||
| struct net_header; | ||||
| struct ll_header; | ||||
| struct net_protocol; | ||||
|  | ||||
| extern int arp_resolve ( struct net_device *netdev, | ||||
| 			 const struct net_header *nethdr, | ||||
| 			 struct ll_header *llhdr ); | ||||
| 			 struct net_protocol *net_protocol, | ||||
| 			 const void *dest_net_addr, | ||||
| 			 const void *source_net_addr, | ||||
| 			 void *dest_ll_addr ); | ||||
|  | ||||
| #endif /* _GPXE_ARP_H */ | ||||
|   | ||||
| @@ -11,4 +11,10 @@ struct net_protocol; | ||||
|  | ||||
| extern struct net_protocol ipv4_protocol; | ||||
|  | ||||
| extern int add_ipv4_address ( struct net_device *netdev, | ||||
| 			      struct in_addr address, struct in_addr netmask, | ||||
| 			      struct in_addr gateway ); | ||||
| extern void del_ipv4_address ( struct net_device *netdev ); | ||||
| extern int ipv4_uip_transmit ( struct pk_buff *pkb ); | ||||
|  | ||||
| #endif /* _GPXE_IP_H */ | ||||
|   | ||||
| @@ -86,22 +86,6 @@ struct ll_header { | ||||
| struct net_protocol { | ||||
| 	/** Protocol name */ | ||||
| 	const char *name; | ||||
| 	/** | ||||
| 	 * Perform network-layer routing | ||||
| 	 * | ||||
| 	 * @v pkb	Packet buffer | ||||
| 	 * @v nethdr	Generic network-layer header | ||||
| 	 * @ret rc	Return status code | ||||
| 	 * | ||||
| 	 * This method should fill in the network header with enough | ||||
| 	 * information to allow the link layer to route the packet. | ||||
| 	 * | ||||
| 	 * For example, in the case of IPv4, this method should fill | ||||
| 	 * in the IP addresses of the local adapter and the next hop | ||||
| 	 * destination (e.g. the gateway). | ||||
| 	 */ | ||||
| 	int ( * route ) ( const struct pk_buff *pkb, | ||||
| 			  struct net_header *nethdr ); | ||||
| 	/** | ||||
| 	 * Process received packet | ||||
| 	 * | ||||
| @@ -141,36 +125,21 @@ struct ll_protocol { | ||||
| 	/** Protocol name */ | ||||
| 	const char *name; | ||||
| 	/** | ||||
| 	 * Perform link-layer routing | ||||
| 	 * Transmit network-layer packet via network device | ||||
| 	 * | ||||
| 	 * @v netdev	Network device | ||||
| 	 * @v nethdr	Generic network-layer header | ||||
| 	 * @ret llhdr	Generic link-layer header | ||||
| 	 * @ret rc	Return status code | ||||
| 	 * | ||||
| 	 * This method should construct the generic link-layer header | ||||
| 	 * based on the generic network-layer header. | ||||
| 	 * @v pkb		Packet buffer | ||||
| 	 * @v netdev		Network device | ||||
| 	 * @v net_protocol	Network-layer protocol | ||||
| 	 * @v ll_dest		Link-layer destination address | ||||
| 	 * @ret rc		Return status code | ||||
| 	 * | ||||
| 	 * 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). | ||||
| 	 * This method should prepend in the link-layer header | ||||
| 	 * (e.g. the Ethernet DIX header) and transmit the packet. | ||||
| 	 */ | ||||
| 	int ( * route ) ( struct net_device *netdev, | ||||
| 			  const struct net_header *nethdr, | ||||
| 			  struct ll_header *llhdr ); | ||||
| 	/** | ||||
| 	 * Fill media-specific link-layer header | ||||
| 	 * | ||||
| 	 * @v llhdr	Generic link-layer header | ||||
| 	 * @v pkb	Packet buffer | ||||
| 	 * | ||||
| 	 * 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 ); | ||||
| 	int ( * transmit ) ( struct pk_buff *pkb, struct net_device *netdev, | ||||
| 			     struct net_protocol *net_protocol, | ||||
| 			     const void *ll_dest ); | ||||
| 	/** | ||||
| 	 * Parse media-specific link-layer header | ||||
| 	 * | ||||
| @@ -204,8 +173,8 @@ struct ll_protocol { | ||||
| 	uint16_t ll_proto; | ||||
| 	/** Link-layer address length */ | ||||
| 	uint8_t ll_addr_len; | ||||
| 	/** Link-layer header length */ | ||||
| 	uint8_t ll_header_len; | ||||
| 	/** Link-layer broadcast address */ | ||||
| 	const uint8_t *ll_broadcast; | ||||
| }; | ||||
|  | ||||
| /** | ||||
| @@ -288,31 +257,6 @@ extern struct net_device static_single_netdev; | ||||
| 	static_single_netdev.priv = priv_data;	\ | ||||
| 	&static_single_netdev; } ) | ||||
|  | ||||
| /** | ||||
|  * Register network device | ||||
|  * | ||||
|  * @v netdev		Network device | ||||
|  * @ret rc		Return status code | ||||
|  * | ||||
|  * Adds the network device to the list of network devices. | ||||
|  */ | ||||
| static inline int | ||||
| register_netdev ( struct net_device *netdev __attribute__ (( unused )) ) { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * | ||||
| @@ -339,6 +283,27 @@ static inline int netdev_transmit ( struct net_device *netdev, | ||||
| 	return netdev->transmit ( netdev, pkb ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Transmit network-layer packet | ||||
|  * | ||||
|  * @v pkb		Packet buffer | ||||
|  * @v netdev		Network device | ||||
|  * @v net_protocol	Network-layer protocol | ||||
|  * @v ll_dest		Destination link-layer address | ||||
|  * @ret rc		Return status code | ||||
|  * | ||||
|  * Prepends link-layer headers to the packet buffer and transmits the | ||||
|  * packet via the specified network device.  This function takes | ||||
|  * ownership of the packet buffer. | ||||
|  */ | ||||
| static inline int net_transmit ( struct pk_buff *pkb, | ||||
| 				 struct net_device *netdev, | ||||
| 				 struct net_protocol *net_protocol, | ||||
| 				 const void *ll_dest ) { | ||||
| 	return netdev->ll_protocol->transmit ( pkb, netdev, net_protocol, | ||||
| 					       ll_dest ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Register a link-layer protocol | ||||
|  * | ||||
| @@ -363,14 +328,14 @@ static inline int netdev_transmit ( struct net_device *netdev, | ||||
| #define STATIC_SINGLE_NETDEV_ADDRESS( address ) \ | ||||
| 	struct net_address address __table ( sgl_netdev_addresses, 01 ) | ||||
|  | ||||
| extern int register_netdev ( struct net_device *netdev ); | ||||
| extern void unregister_netdev ( struct net_device *netdev ); | ||||
| extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ); | ||||
|  | ||||
| extern struct net_protocol *find_net_protocol ( uint16_t net_proto ); | ||||
| extern struct net_device * | ||||
| find_netdev_by_net_addr ( struct net_protocol *net_protocol, void *net_addr ); | ||||
|  | ||||
| extern int net_transmit_via ( struct pk_buff *pkb, struct net_device *netdev ); | ||||
| extern int net_transmit ( struct pk_buff *pkb ); | ||||
| extern int net_poll ( void ); | ||||
| extern struct pk_buff * net_rx_dequeue ( void ); | ||||
| extern int net_rx_process ( struct pk_buff *pkb ); | ||||
|   | ||||
| @@ -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 ); | ||||
|   | ||||
| @@ -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: | ||||
| @@ -246,29 +247,6 @@ static int arp_rx ( struct pk_buff *pkb ) { | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * | ||||
| @@ -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, | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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. | ||||
|  * Prepends the Ethernet link-layer header and transmits the packet. | ||||
|  */ | ||||
| static int eth_route ( struct net_device *netdev, | ||||
| 		       const struct net_header *nethdr, | ||||
| 		       struct ll_header *llhdr ) { | ||||
| 	int rc; | ||||
| 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 ); | ||||
|  | ||||
| 	/* 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. | ||||
|  */ | ||||
| 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; | ||||
| 	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 ); | ||||
|   | ||||
							
								
								
									
										289
									
								
								src/net/ipv4.c
									
									
									
									
									
								
							
							
						
						
									
										289
									
								
								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 ) | ||||
|  | ||||
| #if 0 | ||||
| /** | ||||
|  * Set IP address | ||||
|  * | ||||
|  */ | ||||
| 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 ); | ||||
| } | ||||
| /** List of IPv4 miniroutes */ | ||||
| static LIST_HEAD ( miniroutes ); | ||||
|  | ||||
| /** | ||||
|  * Set netmask | ||||
|  * Add IPv4 interface | ||||
|  * | ||||
|  * @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; | ||||
| int add_ipv4_address ( struct net_device *netdev, struct in_addr address, | ||||
| 		       struct in_addr netmask, struct in_addr gateway ) { | ||||
| 	struct ipv4_miniroute *miniroute; | ||||
|  | ||||
| 	u.address = address; | ||||
| 	uip_setnetmask ( u.uip_address ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Set default gateway | ||||
|  * | ||||
|  */ | ||||
| void set_gateway ( struct in_addr address ) { | ||||
| 	union { | ||||
| 		struct in_addr address; | ||||
| 		uint16_t uip_address[2]; | ||||
| 	} u; | ||||
|  | ||||
| 	u.address = address; | ||||
| 	uip_setdraddr ( u.uip_address ); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * | ||||
|  * struct tcp_connection *my_connection; | ||||
|  * ... | ||||
|  * tcp_connect ( my_connection ); | ||||
|  * while ( ! my_connection->finished ) { | ||||
|  *   run_tcpip(); | ||||
|  * } | ||||
|  * | ||||
|  * @endcode | ||||
|  * | ||||
|  * 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; | ||||
| 	/* 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; | ||||
| 	 | ||||
| 	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(); | ||||
| 		} | ||||
| 		if ( uip_len > 0 ) | ||||
| 			uip_transmit(); | ||||
| 	/* 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 { | ||||
| 		for ( i = 0 ; i < UIP_CONNS ; i++ ) { | ||||
| 			uip_periodic ( i ); | ||||
| 			if ( uip_len > 0 ) | ||||
| 				uip_transmit(); | ||||
| 		list_add ( &miniroute->list, &miniroutes ); | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Remove IPv4 interface | ||||
|  * | ||||
|  * @v netdev	Network device | ||||
|  */ | ||||
| void del_ipv4_address ( struct net_device *netdev ) { | ||||
| 	struct ipv4_miniroute *miniroute; | ||||
|  | ||||
| 	list_for_each_entry ( miniroute, &miniroutes, list ) { | ||||
| 		if ( miniroute->netdev == netdev ) { | ||||
| 			list_del ( &miniroute->list ); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
|  | ||||
| /** | ||||
|  * Transmit packet constructed by uIP | ||||
|  * | ||||
|  * @v pkb		Packet buffer | ||||
|  * @ret rc		Return status code | ||||
|  * | ||||
|  */ | ||||
| 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; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/* 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 { | ||||
| 		/* 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; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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 ) } }, | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|  * | ||||
| @@ -128,88 +172,6 @@ find_netdev_by_net_addr ( struct net_protocol *net_protocol, | ||||
| 	return NULL; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 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 | ||||
|  * | ||||
| @@ -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 ) { | ||||
|   | ||||
| @@ -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 ); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user