pkbuff->iobuf changeover
Achieved via Perl using: perl -pi -e 's/pk_buff/io_buffer/g; s/Packet buffer/I\/O buffer/ig; ' \ -e 's/pkbuff\.h/iobuf.h/g; s/pkb_/iob_/g; s/_pkb/_iob/g; ' \ -e 's/pkb/iobuf/g; s/PKB/IOB/g;'
This commit is contained in:
parent
7c0a069f42
commit
3e2c6b6736
@ -22,7 +22,7 @@
|
||||
#include <pic8259.h>
|
||||
#include <biosint.h>
|
||||
#include <pnpbios.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
@ -315,11 +315,11 @@ static int undinet_isr_triggered ( void ) {
|
||||
*/
|
||||
|
||||
/** Maximum length of a packet transmitted via the UNDI API */
|
||||
#define UNDI_PKB_LEN 1514
|
||||
#define UNDI_IOB_LEN 1514
|
||||
|
||||
/** UNDI packet buffer */
|
||||
static char __data16_array ( undinet_pkb, [UNDI_PKB_LEN] );
|
||||
#define undinet_pkb __use_data16 ( undinet_pkb )
|
||||
/** UNDI I/O buffer */
|
||||
static char __data16_array ( undinet_iob, [UNDI_IOB_LEN] );
|
||||
#define undinet_iob __use_data16 ( undinet_iob )
|
||||
|
||||
/** UNDI transmit buffer descriptor */
|
||||
static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
|
||||
@ -329,20 +329,20 @@ static struct s_PXENV_UNDI_TBD __data16 ( undinet_tbd );
|
||||
* Transmit packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int undinet_transmit ( struct net_device *netdev,
|
||||
struct pk_buff *pkb ) {
|
||||
struct io_buffer *iobuf ) {
|
||||
struct undi_nic *undinic = netdev->priv;
|
||||
struct s_PXENV_UNDI_TRANSMIT undi_transmit;
|
||||
size_t len = pkb_len ( pkb );
|
||||
size_t len = iob_len ( iobuf );
|
||||
int rc;
|
||||
|
||||
/* Copy packet to UNDI packet buffer */
|
||||
if ( len > sizeof ( undinet_pkb ) )
|
||||
len = sizeof ( undinet_pkb );
|
||||
memcpy ( &undinet_pkb, pkb->data, len );
|
||||
/* Copy packet to UNDI I/O buffer */
|
||||
if ( len > sizeof ( undinet_iob ) )
|
||||
len = sizeof ( undinet_iob );
|
||||
memcpy ( &undinet_iob, iobuf->data, len );
|
||||
|
||||
/* Create PXENV_UNDI_TRANSMIT data structure */
|
||||
memset ( &undi_transmit, 0, sizeof ( undi_transmit ) );
|
||||
@ -357,7 +357,7 @@ static int undinet_transmit ( struct net_device *netdev,
|
||||
undinet_tbd.ImmedLength = len;
|
||||
undinet_tbd.Xmit.segment = rm_ds;
|
||||
undinet_tbd.Xmit.offset
|
||||
= ( ( unsigned ) & __from_data16 ( undinet_pkb ) );
|
||||
= ( ( unsigned ) & __from_data16 ( undinet_iob ) );
|
||||
|
||||
/* Issue PXE API call */
|
||||
if ( ( rc = undinet_call ( undinic, PXENV_UNDI_TRANSMIT,
|
||||
@ -365,8 +365,8 @@ static int undinet_transmit ( struct net_device *netdev,
|
||||
sizeof ( undi_transmit ) ) ) != 0 )
|
||||
goto done;
|
||||
|
||||
/* Free packet buffer */
|
||||
netdev_tx_complete ( netdev, pkb );
|
||||
/* Free I/O buffer */
|
||||
netdev_tx_complete ( netdev, iobuf );
|
||||
|
||||
done:
|
||||
return rc;
|
||||
@ -397,7 +397,7 @@ static int undinet_transmit ( struct net_device *netdev,
|
||||
static void undinet_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
struct undi_nic *undinic = netdev->priv;
|
||||
struct s_PXENV_UNDI_ISR undi_isr;
|
||||
struct pk_buff *pkb = NULL;
|
||||
struct io_buffer *iobuf = NULL;
|
||||
size_t len;
|
||||
size_t frag_len;
|
||||
int rc;
|
||||
@ -448,26 +448,26 @@ static void undinet_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
/* Packet fragment received */
|
||||
len = undi_isr.FrameLength;
|
||||
frag_len = undi_isr.BufferLength;
|
||||
if ( ! pkb )
|
||||
pkb = alloc_pkb ( len );
|
||||
if ( ! pkb ) {
|
||||
if ( ! iobuf )
|
||||
iobuf = alloc_iob ( len );
|
||||
if ( ! iobuf ) {
|
||||
DBGC ( undinic, "UNDINIC %p could not "
|
||||
"allocate %zd bytes for RX buffer\n",
|
||||
undinic, len );
|
||||
/* Fragment will be dropped */
|
||||
goto done;
|
||||
}
|
||||
if ( frag_len > pkb_tailroom ( pkb ) ) {
|
||||
if ( frag_len > iob_tailroom ( iobuf ) ) {
|
||||
DBGC ( undinic, "UNDINIC %p fragment too "
|
||||
"large\n", undinic );
|
||||
frag_len = pkb_tailroom ( pkb );
|
||||
frag_len = iob_tailroom ( iobuf );
|
||||
}
|
||||
copy_from_real ( pkb_put ( pkb, frag_len ),
|
||||
copy_from_real ( iob_put ( iobuf, frag_len ),
|
||||
undi_isr.Frame.segment,
|
||||
undi_isr.Frame.offset, frag_len );
|
||||
if ( pkb_len ( pkb ) == len ) {
|
||||
netdev_rx ( netdev, pkb );
|
||||
pkb = NULL;
|
||||
if ( iob_len ( iobuf ) == len ) {
|
||||
netdev_rx ( netdev, iobuf );
|
||||
iobuf = NULL;
|
||||
--rx_quota;
|
||||
}
|
||||
break;
|
||||
@ -486,10 +486,10 @@ static void undinet_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
}
|
||||
|
||||
done:
|
||||
if ( pkb ) {
|
||||
if ( iobuf ) {
|
||||
DBGC ( undinic, "UNDINIC %p returned incomplete packet\n",
|
||||
undinic );
|
||||
netdev_rx ( netdev, pkb );
|
||||
netdev_rx ( netdev, iobuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <nic.h>
|
||||
|
||||
/*
|
||||
@ -21,38 +21,38 @@ struct nic nic;
|
||||
|
||||
static int legacy_registered = 0;
|
||||
|
||||
static int legacy_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
static int legacy_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
struct nic *nic = netdev->priv;
|
||||
struct ethhdr *ethhdr = pkb->data;
|
||||
struct ethhdr *ethhdr = iobuf->data;
|
||||
|
||||
DBG ( "Transmitting %d bytes\n", pkb_len ( pkb ) );
|
||||
pkb_pad ( pkb, ETH_ZLEN );
|
||||
pkb_pull ( pkb, sizeof ( *ethhdr ) );
|
||||
DBG ( "Transmitting %d bytes\n", iob_len ( iobuf ) );
|
||||
iob_pad ( iobuf, ETH_ZLEN );
|
||||
iob_pull ( iobuf, sizeof ( *ethhdr ) );
|
||||
nic->nic_op->transmit ( nic, ( const char * ) ethhdr->h_dest,
|
||||
ntohs ( ethhdr->h_protocol ),
|
||||
pkb_len ( pkb ), pkb->data );
|
||||
netdev_tx_complete ( netdev, pkb );
|
||||
iob_len ( iobuf ), iobuf->data );
|
||||
netdev_tx_complete ( netdev, iobuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void legacy_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
struct nic *nic = netdev->priv;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
if ( ! rx_quota )
|
||||
return;
|
||||
|
||||
pkb = alloc_pkb ( ETH_FRAME_LEN );
|
||||
if ( ! pkb )
|
||||
iobuf = alloc_iob ( ETH_FRAME_LEN );
|
||||
if ( ! iobuf )
|
||||
return;
|
||||
|
||||
nic->packet = pkb->data;
|
||||
nic->packet = iobuf->data;
|
||||
if ( nic->nic_op->poll ( nic, 1 ) ) {
|
||||
DBG ( "Received %d bytes\n", nic->packetlen );
|
||||
pkb_put ( pkb, nic->packetlen );
|
||||
netdev_rx ( netdev, pkb );
|
||||
iob_put ( iobuf, nic->packetlen );
|
||||
netdev_rx ( netdev, iobuf );
|
||||
} else {
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ Bochs Pseudo NIC driver for Etherboot
|
||||
#include <gpxe/pci.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
|
||||
#include "pnic_api.h"
|
||||
@ -114,7 +114,7 @@ POLL - Wait for a frame
|
||||
***************************************************************************/
|
||||
static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
struct pnic *pnic = netdev->priv;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
uint16_t length;
|
||||
uint16_t qlen;
|
||||
|
||||
@ -126,19 +126,19 @@ static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
break;
|
||||
if ( qlen == 0 )
|
||||
break;
|
||||
pkb = alloc_pkb ( ETH_FRAME_LEN );
|
||||
if ( ! pkb ) {
|
||||
iobuf = alloc_iob ( ETH_FRAME_LEN );
|
||||
if ( ! iobuf ) {
|
||||
printf ( "could not allocate buffer\n" );
|
||||
break;
|
||||
}
|
||||
if ( pnic_command ( pnic, PNIC_CMD_RECV, NULL, 0,
|
||||
pkb->data, ETH_FRAME_LEN, &length )
|
||||
iobuf->data, ETH_FRAME_LEN, &length )
|
||||
!= PNIC_STATUS_OK ) {
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
break;
|
||||
}
|
||||
pkb_put ( pkb, length );
|
||||
netdev_rx ( netdev, pkb );
|
||||
iob_put ( iobuf, length );
|
||||
netdev_rx ( netdev, iobuf );
|
||||
--rx_quota;
|
||||
}
|
||||
}
|
||||
@ -146,17 +146,17 @@ static void pnic_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
/**************************************************************************
|
||||
TRANSMIT - Transmit a frame
|
||||
***************************************************************************/
|
||||
static int pnic_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
static int pnic_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
struct pnic *pnic = netdev->priv;
|
||||
|
||||
/* Pad the packet */
|
||||
pkb_pad ( pkb, ETH_ZLEN );
|
||||
iob_pad ( iobuf, ETH_ZLEN );
|
||||
|
||||
/* Send packet */
|
||||
pnic_command ( pnic, PNIC_CMD_XMIT, pkb->data, pkb_len ( pkb ),
|
||||
pnic_command ( pnic, PNIC_CMD_XMIT, iobuf->data, iob_len ( iobuf ),
|
||||
NULL, 0, NULL );
|
||||
|
||||
netdev_tx_complete ( netdev, pkb );
|
||||
netdev_tx_complete ( netdev, iobuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,7 @@
|
||||
#include <gpxe/pci.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/spi_bit.h>
|
||||
#include <gpxe/threewire.h>
|
||||
@ -86,7 +86,7 @@
|
||||
|
||||
struct rtl8139_tx {
|
||||
unsigned int next;
|
||||
struct pk_buff *pkb[TX_RING_SIZE];
|
||||
struct io_buffer *iobuf[TX_RING_SIZE];
|
||||
};
|
||||
|
||||
struct rtl8139_rx {
|
||||
@ -363,28 +363,28 @@ static void rtl_close ( struct net_device *netdev ) {
|
||||
* Transmit packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
static int rtl_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
struct rtl8139_nic *rtl = netdev->priv;
|
||||
|
||||
/* Check for space in TX ring */
|
||||
if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
|
||||
if ( rtl->tx.iobuf[rtl->tx.next] != NULL ) {
|
||||
printf ( "TX overflow\n" );
|
||||
return -ENOBUFS;
|
||||
}
|
||||
|
||||
/* Pad and align packet */
|
||||
pkb_pad ( pkb, ETH_ZLEN );
|
||||
iob_pad ( iobuf, ETH_ZLEN );
|
||||
|
||||
/* Add to TX ring */
|
||||
DBG ( "TX id %d at %lx+%x\n", rtl->tx.next,
|
||||
virt_to_bus ( pkb->data ), pkb_len ( pkb ) );
|
||||
rtl->tx.pkb[rtl->tx.next] = pkb;
|
||||
outl ( virt_to_bus ( pkb->data ),
|
||||
virt_to_bus ( iobuf->data ), iob_len ( iobuf ) );
|
||||
rtl->tx.iobuf[rtl->tx.next] = iobuf;
|
||||
outl ( virt_to_bus ( iobuf->data ),
|
||||
rtl->ioaddr + TxAddr0 + 4 * rtl->tx.next );
|
||||
outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | pkb_len ( pkb ) ),
|
||||
outl ( ( ( ( TX_FIFO_THRESH & 0x7e0 ) << 11 ) | iob_len ( iobuf ) ),
|
||||
rtl->ioaddr + TxStatus0 + 4 * rtl->tx.next );
|
||||
rtl->tx.next = ( rtl->tx.next + 1 ) % TX_RING_SIZE;
|
||||
|
||||
@ -403,7 +403,7 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
unsigned int tsad;
|
||||
unsigned int rx_status;
|
||||
unsigned int rx_len;
|
||||
struct pk_buff *rx_pkb;
|
||||
struct io_buffer *rx_iob;
|
||||
int wrapped_len;
|
||||
int i;
|
||||
|
||||
@ -416,10 +416,10 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
/* Handle TX completions */
|
||||
tsad = inw ( rtl->ioaddr + TxSummary );
|
||||
for ( i = 0 ; i < TX_RING_SIZE ; i++ ) {
|
||||
if ( ( rtl->tx.pkb[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
|
||||
if ( ( rtl->tx.iobuf[i] != NULL ) && ( tsad & ( 1 << i ) ) ) {
|
||||
DBG ( "TX id %d complete\n", i );
|
||||
netdev_tx_complete ( netdev, rtl->tx.pkb[i] );
|
||||
rtl->tx.pkb[i] = NULL;
|
||||
netdev_tx_complete ( netdev, rtl->tx.iobuf[i] );
|
||||
rtl->tx.iobuf[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -433,8 +433,8 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
DBG ( "RX packet at offset %x+%x\n", rtl->rx.offset,
|
||||
rx_len );
|
||||
|
||||
rx_pkb = alloc_pkb ( rx_len );
|
||||
if ( ! rx_pkb ) {
|
||||
rx_iob = alloc_iob ( rx_len );
|
||||
if ( ! rx_iob ) {
|
||||
/* Leave packet for next call to poll() */
|
||||
break;
|
||||
}
|
||||
@ -444,13 +444,13 @@ static void rtl_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
if ( wrapped_len < 0 )
|
||||
wrapped_len = 0;
|
||||
|
||||
memcpy ( pkb_put ( rx_pkb, rx_len - wrapped_len ),
|
||||
memcpy ( iob_put ( rx_iob, rx_len - wrapped_len ),
|
||||
rtl->rx.ring + rtl->rx.offset + 4,
|
||||
rx_len - wrapped_len );
|
||||
memcpy ( pkb_put ( rx_pkb, wrapped_len ),
|
||||
memcpy ( iob_put ( rx_iob, wrapped_len ),
|
||||
rtl->rx.ring, wrapped_len );
|
||||
|
||||
netdev_rx ( netdev, rx_pkb );
|
||||
netdev_rx ( netdev, rx_iob );
|
||||
rx_quota--;
|
||||
} else {
|
||||
DBG ( "RX bad packet (status %#04x len %d)\n",
|
||||
|
@ -25,7 +25,7 @@
|
||||
#define IP_TOS 0
|
||||
#define IP_TTL 64
|
||||
|
||||
#define IP_FRAG_PKB_SIZE 1500
|
||||
#define IP_FRAG_IOB_SIZE 1500
|
||||
#define IP_FRAG_TIMEOUT 50
|
||||
|
||||
/* IP4 pseudo header */
|
||||
@ -63,15 +63,15 @@ struct frag_buffer {
|
||||
struct in_addr src;
|
||||
/* Destination network address */
|
||||
struct in_addr dest;
|
||||
/* Reassembled packet buffer */
|
||||
struct pk_buff *frag_pkb;
|
||||
/* Reassembled I/O buffer */
|
||||
struct io_buffer *frag_iob;
|
||||
/* Reassembly timer */
|
||||
struct retry_timer frag_timer;
|
||||
/* List of fragment reassembly buffers */
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct pk_buff;
|
||||
struct io_buffer;
|
||||
struct net_device;
|
||||
struct net_protocol;
|
||||
struct tcpip_protocol;
|
||||
|
@ -16,12 +16,12 @@
|
||||
#define IP6_HOP_LIMIT 255
|
||||
|
||||
/**
|
||||
* Packet buffer contents
|
||||
* This is duplicated in tcp.h and here. Ideally it should go into pkbuff.h
|
||||
* I/O buffer contents
|
||||
* This is duplicated in tcp.h and here. Ideally it should go into iobuf.h
|
||||
*/
|
||||
#define MAX_HDR_LEN 100
|
||||
#define MAX_PKB_LEN 1500
|
||||
#define MIN_PKB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */
|
||||
#define MAX_IOB_LEN 1500
|
||||
#define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */
|
||||
|
||||
#define IP6_EQUAL( in6_addr1, in6_addr2 ) \
|
||||
( strncmp ( ( char* ) &( in6_addr1 ), ( char* ) &( in6_addr2 ),\
|
||||
@ -61,7 +61,7 @@ struct ipv6_pseudo_header {
|
||||
#define IP6_ICMP6 0x58
|
||||
#define IP6_NO_HEADER 0x59
|
||||
|
||||
struct pk_buff;
|
||||
struct io_buffer;
|
||||
struct net_device;
|
||||
struct net_protocol;
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <gpxe/ip6.h>
|
||||
#include <gpxe/in.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
|
||||
#define NDP_STATE_INVALID 0
|
||||
@ -19,5 +19,5 @@
|
||||
static struct ndp_entry * ndp_find_entry ( struct in6_addr *in6 );
|
||||
int ndp_resolve ( struct net_device *netdev, struct in6_addr *src,
|
||||
struct in6_addr *dest, void *dest_ll_addr );
|
||||
int ndp_process_advert ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
int ndp_process_advert ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest );
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <gpxe/tables.h>
|
||||
#include <gpxe/hotplug.h>
|
||||
|
||||
struct pk_buff;
|
||||
struct io_buffer;
|
||||
struct net_device;
|
||||
struct net_protocol;
|
||||
struct ll_protocol;
|
||||
@ -37,13 +37,13 @@ struct net_protocol {
|
||||
/**
|
||||
* Process received packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v ll_source Link-layer source address
|
||||
*
|
||||
* This method takes ownership of the packet buffer.
|
||||
* This method takes ownership of the I/O buffer.
|
||||
*/
|
||||
int ( * rx ) ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
const void *ll_source );
|
||||
/**
|
||||
* Transcribe network-layer address
|
||||
@ -77,7 +77,7 @@ struct ll_protocol {
|
||||
/**
|
||||
* Transmit network-layer packet via network device
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v net_protocol Network-layer protocol
|
||||
* @v ll_dest Link-layer destination address
|
||||
@ -85,15 +85,15 @@ struct ll_protocol {
|
||||
*
|
||||
* This method should prepend in the link-layer header
|
||||
* (e.g. the Ethernet DIX header) and transmit the packet.
|
||||
* This method takes ownership of the packet buffer.
|
||||
* This method takes ownership of the I/O buffer.
|
||||
*/
|
||||
int ( * tx ) ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
int ( * tx ) ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
struct net_protocol *net_protocol,
|
||||
const void *ll_dest );
|
||||
/**
|
||||
* Handle received packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
*
|
||||
* This method should strip off the link-layer header
|
||||
@ -101,7 +101,7 @@ struct ll_protocol {
|
||||
* net_rx(). This method takes ownership of the packet
|
||||
* buffer.
|
||||
*/
|
||||
int ( * rx ) ( struct pk_buff *pkb, struct net_device *netdev );
|
||||
int ( * rx ) ( struct io_buffer *iobuf, struct net_device *netdev );
|
||||
/**
|
||||
* Transcribe link-layer address
|
||||
*
|
||||
@ -151,7 +151,7 @@ struct net_device {
|
||||
* @v netdev Network device
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This method should allocate RX packet buffers and enable
|
||||
* This method should allocate RX I/O buffers and enable
|
||||
* the hardware to start transmitting and receiving packets.
|
||||
*/
|
||||
int ( * open ) ( struct net_device *netdev );
|
||||
@ -166,22 +166,22 @@ struct net_device {
|
||||
/** Transmit packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This method should cause the hardware to initiate
|
||||
* transmission of the packet buffer.
|
||||
* transmission of the I/O buffer.
|
||||
*
|
||||
* If this method returns success, the packet buffer remains
|
||||
* If this method returns success, the I/O buffer remains
|
||||
* owned by the net device's TX queue, and the net device must
|
||||
* eventually call netdev_tx_complete() to free the buffer.
|
||||
* If this method returns failure, the packet buffer is
|
||||
* If this method returns failure, the I/O buffer is
|
||||
* immediately released.
|
||||
*
|
||||
* This method is guaranteed to be called only when the device
|
||||
* is open.
|
||||
*/
|
||||
int ( * transmit ) ( struct net_device *netdev, struct pk_buff *pkb );
|
||||
int ( * transmit ) ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||
/** Poll for received packet
|
||||
*
|
||||
* @v netdev Network device
|
||||
@ -251,12 +251,12 @@ static inline int have_netdevs ( void ) {
|
||||
return ( ! list_empty ( &net_devices ) );
|
||||
}
|
||||
|
||||
extern int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb );
|
||||
void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb );
|
||||
extern int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||
void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||
void netdev_tx_complete_next ( struct net_device *netdev );
|
||||
extern void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb );
|
||||
extern void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf );
|
||||
extern int netdev_poll ( struct net_device *netdev, unsigned int rx_quota );
|
||||
extern struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev );
|
||||
extern struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev );
|
||||
extern struct net_device * alloc_netdev ( size_t priv_size );
|
||||
extern int register_netdev ( struct net_device *netdev );
|
||||
extern int netdev_open ( struct net_device *netdev );
|
||||
@ -266,9 +266,9 @@ extern void free_netdev ( struct net_device *netdev );
|
||||
struct net_device * find_netdev ( const char *name );
|
||||
struct net_device * find_pci_netdev ( unsigned int busdevfn );
|
||||
|
||||
extern int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
extern int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
struct net_protocol *net_protocol, const void *ll_dest );
|
||||
extern int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
extern int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
uint16_t net_proto, const void *ll_source );
|
||||
|
||||
#endif /* _GPXE_NETDEVICE_H */
|
||||
|
@ -1,163 +0,0 @@
|
||||
#ifndef _GPXE_PKBUFF_H
|
||||
#define _GPXE_PKBUFF_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Packet buffers
|
||||
*
|
||||
* Packet buffers are used to contain network packets. Methods are
|
||||
* provided for appending, prepending, etc. data.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <gpxe/list.h>
|
||||
|
||||
/**
|
||||
* Packet buffer alignment
|
||||
*
|
||||
* Packet buffers allocated via alloc_pkb() are guaranteed to be
|
||||
* physically aligned to this boundary. Some cards cannot DMA across
|
||||
* a 4kB boundary. With a standard Ethernet MTU, aligning to a 2kB
|
||||
* boundary is sufficient to guarantee no 4kB boundary crossings. For
|
||||
* a jumbo Ethernet MTU, a packet may be larger than 4kB anyway.
|
||||
*/
|
||||
#define PKBUFF_ALIGN 2048
|
||||
|
||||
/**
|
||||
* Minimum packet buffer length
|
||||
*
|
||||
* alloc_pkb() will round up the allocated length to this size if
|
||||
* necessary. This is used on behalf of hardware that is not capable
|
||||
* of auto-padding.
|
||||
*/
|
||||
#define PKB_ZLEN 64
|
||||
|
||||
/** A packet buffer
|
||||
*
|
||||
* This structure is used to represent a network packet within gPXE.
|
||||
*/
|
||||
struct pk_buff {
|
||||
/** List of which this buffer is a member */
|
||||
struct list_head list;
|
||||
|
||||
/** Start of the buffer */
|
||||
void *head;
|
||||
/** Start of data */
|
||||
void *data;
|
||||
/** End of data */
|
||||
void *tail;
|
||||
/** End of the buffer */
|
||||
void *end;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reserve space at start of packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v len Length to reserve
|
||||
* @ret data Pointer to new start of buffer
|
||||
*/
|
||||
static inline void * pkb_reserve ( struct pk_buff *pkb, size_t len ) {
|
||||
pkb->data += len;
|
||||
pkb->tail += len;
|
||||
assert ( pkb->tail <= pkb->end );
|
||||
return pkb->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to start of packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v len Length to add
|
||||
* @ret data Pointer to new start of buffer
|
||||
*/
|
||||
static inline void * pkb_push ( struct pk_buff *pkb, size_t len ) {
|
||||
pkb->data -= len;
|
||||
assert ( pkb->data >= pkb->head );
|
||||
return pkb->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove data from start of packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v len Length to remove
|
||||
* @ret data Pointer to new start of buffer
|
||||
*/
|
||||
static inline void * pkb_pull ( struct pk_buff *pkb, size_t len ) {
|
||||
pkb->data += len;
|
||||
assert ( pkb->data <= pkb->tail );
|
||||
return pkb->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add data to end of packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v len Length to add
|
||||
* @ret data Pointer to newly added space
|
||||
*/
|
||||
static inline void * pkb_put ( struct pk_buff *pkb, size_t len ) {
|
||||
void *old_tail = pkb->tail;
|
||||
pkb->tail += len;
|
||||
assert ( pkb->tail <= pkb->end );
|
||||
return old_tail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove data from end of packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v len Length to remove
|
||||
*/
|
||||
static inline void pkb_unput ( struct pk_buff *pkb, size_t len ) {
|
||||
pkb->tail -= len;
|
||||
assert ( pkb->tail >= pkb->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty a packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
*/
|
||||
static inline void pkb_empty ( struct pk_buff *pkb ) {
|
||||
pkb->tail = pkb->data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate length of data in a packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @ret len Length of data in buffer
|
||||
*/
|
||||
static inline size_t pkb_len ( struct pk_buff *pkb ) {
|
||||
return ( pkb->tail - pkb->data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate available space at start of a packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @ret len Length of data available at start of buffer
|
||||
*/
|
||||
static inline size_t pkb_headroom ( struct pk_buff *pkb ) {
|
||||
return ( pkb->data - pkb->head );
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate available space at end of a packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @ret len Length of data available at end of buffer
|
||||
*/
|
||||
static inline size_t pkb_tailroom ( struct pk_buff *pkb ) {
|
||||
return ( pkb->end - pkb->tail );
|
||||
}
|
||||
|
||||
extern struct pk_buff * alloc_pkb ( size_t len );
|
||||
extern void free_pkb ( struct pk_buff *pkb );
|
||||
extern void pkb_pad ( struct pk_buff *pkb, size_t min_len );
|
||||
|
||||
#endif /* _GPXE_PKBUFF_H */
|
@ -206,10 +206,10 @@ struct tcp_mss_option {
|
||||
/** Smallest port number on which a TCP connection can listen */
|
||||
#define TCP_MIN_PORT 1
|
||||
|
||||
/* Some PKB constants */
|
||||
/* Some IOB constants */
|
||||
#define MAX_HDR_LEN 100
|
||||
#define MAX_PKB_LEN 1500
|
||||
#define MIN_PKB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */
|
||||
#define MAX_IOB_LEN 1500
|
||||
#define MIN_IOB_LEN MAX_HDR_LEN + 100 /* To account for padding by LL */
|
||||
|
||||
/**
|
||||
* Maxmimum advertised TCP window size
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include <gpxe/in.h>
|
||||
#include <gpxe/tables.h>
|
||||
|
||||
struct pk_buff;
|
||||
struct io_buffer;
|
||||
struct net_device;
|
||||
|
||||
/** Empty checksum value
|
||||
@ -51,15 +51,15 @@ struct tcpip_protocol {
|
||||
/**
|
||||
* Process received packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v st_src Partially-filled source address
|
||||
* @v st_dest Partially-filled destination address
|
||||
* @v pshdr_csum Pseudo-header checksum
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This method takes ownership of the packet buffer.
|
||||
* This method takes ownership of the I/O buffer.
|
||||
*/
|
||||
int ( * rx ) ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
int ( * rx ) ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum );
|
||||
/**
|
||||
* Transport-layer protocol number
|
||||
@ -80,16 +80,16 @@ struct tcpip_net_protocol {
|
||||
/**
|
||||
* Transmit packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v tcpip_protocol Transport-layer protocol
|
||||
* @v st_dest Destination address
|
||||
* @v netdev Network device (or NULL to route automatically)
|
||||
* @v trans_csum Transport-layer checksum to complete, or NULL
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This function takes ownership of the packet buffer.
|
||||
* This function takes ownership of the I/O buffer.
|
||||
*/
|
||||
int ( * tx ) ( struct pk_buff *pkb,
|
||||
int ( * tx ) ( struct io_buffer *iobuf,
|
||||
struct tcpip_protocol *tcpip_protocol,
|
||||
struct sockaddr_tcpip *st_dest,
|
||||
struct net_device *netdev,
|
||||
@ -104,10 +104,10 @@ struct tcpip_net_protocol {
|
||||
#define __tcpip_net_protocol \
|
||||
__table ( struct tcpip_net_protocol, tcpip_net_protocols, 01 )
|
||||
|
||||
extern int tcpip_rx ( struct pk_buff *pkb, uint8_t tcpip_proto,
|
||||
extern int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto,
|
||||
struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum );
|
||||
extern int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip,
|
||||
extern int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip,
|
||||
struct sockaddr_tcpip *st_dest,
|
||||
struct net_device *netdev,
|
||||
uint16_t *trans_csum );
|
||||
|
@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
|
||||
@ -21,8 +21,8 @@ struct net_device;
|
||||
*/
|
||||
|
||||
#define UDP_MAX_HLEN 72
|
||||
#define UDP_MAX_TXPKB ETH_MAX_MTU
|
||||
#define UDP_MIN_TXPKB ETH_ZLEN
|
||||
#define UDP_MAX_TXIOB ETH_MAX_MTU
|
||||
#define UDP_MIN_TXIOB ETH_ZLEN
|
||||
|
||||
typedef uint16_t port_t;
|
||||
|
||||
@ -86,7 +86,7 @@ struct udp_connection {
|
||||
/** Local port on which the connection receives packets */
|
||||
port_t local_port;
|
||||
/** Transmit buffer */
|
||||
struct pk_buff *tx_pkb;
|
||||
struct io_buffer *tx_iob;
|
||||
/** List of registered connections */
|
||||
struct list_head list;
|
||||
/** Operations table for this connection */
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <gpxe/list.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/uaccess.h>
|
||||
#include <gpxe/ata.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
@ -70,7 +70,7 @@ static void aoe_done ( struct aoe_session *aoe, int rc ) {
|
||||
*/
|
||||
static int aoe_send_command ( struct aoe_session *aoe ) {
|
||||
struct ata_command *command = aoe->command;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
struct aoehdr *aoehdr;
|
||||
struct aoecmd *aoecmd;
|
||||
unsigned int count;
|
||||
@ -88,14 +88,14 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
|
||||
count = AOE_MAX_COUNT;
|
||||
data_out_len = ( command->data_out ? ( count * ATA_SECTOR_SIZE ) : 0 );
|
||||
|
||||
/* Create outgoing packet buffer */
|
||||
pkb = alloc_pkb ( ETH_HLEN + sizeof ( *aoehdr ) + sizeof ( *aoecmd ) +
|
||||
/* Create outgoing I/O buffer */
|
||||
iobuf = alloc_iob ( ETH_HLEN + sizeof ( *aoehdr ) + sizeof ( *aoecmd ) +
|
||||
data_out_len );
|
||||
if ( ! pkb )
|
||||
if ( ! iobuf )
|
||||
return -ENOMEM;
|
||||
pkb_reserve ( pkb, ETH_HLEN );
|
||||
aoehdr = pkb_put ( pkb, sizeof ( *aoehdr ) );
|
||||
aoecmd = pkb_put ( pkb, sizeof ( *aoecmd ) );
|
||||
iob_reserve ( iobuf, ETH_HLEN );
|
||||
aoehdr = iob_put ( iobuf, sizeof ( *aoehdr ) );
|
||||
aoecmd = iob_put ( iobuf, sizeof ( *aoecmd ) );
|
||||
memset ( aoehdr, 0, ( sizeof ( *aoehdr ) + sizeof ( *aoecmd ) ) );
|
||||
|
||||
/* Fill AoE header */
|
||||
@ -117,12 +117,12 @@ static int aoe_send_command ( struct aoe_session *aoe ) {
|
||||
aoecmd->lba.bytes[3] |= ( command->cb.device & ATA_DEV_MASK );
|
||||
|
||||
/* Fill data payload */
|
||||
copy_from_user ( pkb_put ( pkb, data_out_len ), command->data_out,
|
||||
copy_from_user ( iob_put ( iobuf, data_out_len ), command->data_out,
|
||||
aoe->command_offset, data_out_len );
|
||||
|
||||
/* Send packet */
|
||||
start_timer ( &aoe->timer );
|
||||
return net_tx ( pkb, aoe->netdev, &aoe_protocol, aoe->target );
|
||||
return net_tx ( iobuf, aoe->netdev, &aoe_protocol, aoe->target );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,16 +213,16 @@ static int aoe_rx_response ( struct aoe_session *aoe, struct aoehdr *aoehdr,
|
||||
/**
|
||||
* Process incoming AoE packets
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v ll_source Link-layer source address
|
||||
* @ret rc Return status code
|
||||
*
|
||||
*/
|
||||
static int aoe_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
static int aoe_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused,
|
||||
const void *ll_source ) {
|
||||
struct aoehdr *aoehdr = pkb->data;
|
||||
unsigned int len = pkb_len ( pkb );
|
||||
struct aoehdr *aoehdr = iobuf->data;
|
||||
unsigned int len = iob_len ( iobuf );
|
||||
struct aoe_session *aoe;
|
||||
int rc = 0;
|
||||
|
||||
@ -254,7 +254,7 @@ static int aoe_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
}
|
||||
|
||||
done:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <errno.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/if_arp.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/arp.h>
|
||||
|
||||
@ -119,7 +119,7 @@ int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol,
|
||||
void *dest_ll_addr ) {
|
||||
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
||||
const struct arp_entry *arp;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
struct arphdr *arphdr;
|
||||
int rc;
|
||||
|
||||
@ -136,30 +136,30 @@ int arp_resolve ( struct net_device *netdev, struct net_protocol *net_protocol,
|
||||
net_protocol->ntoa ( dest_net_addr ) );
|
||||
|
||||
/* Allocate ARP packet */
|
||||
pkb = alloc_pkb ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
|
||||
iobuf = alloc_iob ( MAX_LL_HEADER_LEN + sizeof ( *arphdr ) +
|
||||
2 * ( MAX_LL_ADDR_LEN + MAX_NET_ADDR_LEN ) );
|
||||
if ( ! pkb )
|
||||
if ( ! iobuf )
|
||||
return -ENOMEM;
|
||||
pkb_reserve ( pkb, MAX_LL_HEADER_LEN );
|
||||
iob_reserve ( iobuf, MAX_LL_HEADER_LEN );
|
||||
|
||||
/* Build up ARP request */
|
||||
arphdr = pkb_put ( pkb, sizeof ( *arphdr ) );
|
||||
arphdr = iob_put ( iobuf, sizeof ( *arphdr ) );
|
||||
arphdr->ar_hrd = ll_protocol->ll_proto;
|
||||
arphdr->ar_hln = ll_protocol->ll_addr_len;
|
||||
arphdr->ar_pro = net_protocol->net_proto;
|
||||
arphdr->ar_pln = net_protocol->net_addr_len;
|
||||
arphdr->ar_op = htons ( ARPOP_REQUEST );
|
||||
memcpy ( pkb_put ( pkb, ll_protocol->ll_addr_len ),
|
||||
memcpy ( iob_put ( iobuf, ll_protocol->ll_addr_len ),
|
||||
netdev->ll_addr, ll_protocol->ll_addr_len );
|
||||
memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ),
|
||||
memcpy ( iob_put ( iobuf, net_protocol->net_addr_len ),
|
||||
source_net_addr, net_protocol->net_addr_len );
|
||||
memset ( pkb_put ( pkb, ll_protocol->ll_addr_len ),
|
||||
memset ( iob_put ( iobuf, ll_protocol->ll_addr_len ),
|
||||
0, ll_protocol->ll_addr_len );
|
||||
memcpy ( pkb_put ( pkb, net_protocol->net_addr_len ),
|
||||
memcpy ( iob_put ( iobuf, net_protocol->net_addr_len ),
|
||||
dest_net_addr, net_protocol->net_addr_len );
|
||||
|
||||
/* Transmit ARP request */
|
||||
if ( ( rc = net_tx ( pkb, netdev, &arp_protocol,
|
||||
if ( ( rc = net_tx ( iobuf, netdev, &arp_protocol,
|
||||
ll_protocol->ll_broadcast ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
@ -188,7 +188,7 @@ static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) {
|
||||
/**
|
||||
* Process incoming ARP packets
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v ll_source Link-layer source address
|
||||
* @ret rc Return status code
|
||||
@ -199,9 +199,9 @@ static struct arp_net_protocol * arp_find_protocol ( uint16_t net_proto ) {
|
||||
* avoiding the need for extraneous ARP requests; read the RFC for
|
||||
* details.
|
||||
*/
|
||||
static int arp_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
static int arp_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
const void *ll_source __unused ) {
|
||||
struct arphdr *arphdr = pkb->data;
|
||||
struct arphdr *arphdr = iobuf->data;
|
||||
struct arp_net_protocol *arp_net_protocol;
|
||||
struct net_protocol *net_protocol;
|
||||
struct ll_protocol *ll_protocol;
|
||||
@ -265,11 +265,11 @@ static int arp_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
memcpy ( arp_sender_ha ( arphdr ), netdev->ll_addr, arphdr->ar_hln );
|
||||
|
||||
/* Send reply */
|
||||
net_tx ( pkb, netdev, &arp_protocol, arp_target_ha (arphdr ) );
|
||||
pkb = NULL;
|
||||
net_tx ( iobuf, netdev, &arp_protocol, arp_target_ha (arphdr ) );
|
||||
iobuf = NULL;
|
||||
|
||||
done:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <gpxe/if_arp.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/ethernet.h>
|
||||
|
||||
/** @file
|
||||
@ -40,16 +40,16 @@ static uint8_t eth_broadcast[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
/**
|
||||
* Transmit Ethernet packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v net_protocol Network-layer protocol
|
||||
* @v ll_dest Link-layer destination address
|
||||
*
|
||||
* Prepends the Ethernet link-layer header and transmits the packet.
|
||||
*/
|
||||
static int eth_tx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
static int eth_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
struct net_protocol *net_protocol, const void *ll_dest ) {
|
||||
struct ethhdr *ethhdr = pkb_push ( pkb, sizeof ( *ethhdr ) );
|
||||
struct ethhdr *ethhdr = iob_push ( iobuf, sizeof ( *ethhdr ) );
|
||||
|
||||
/* Build Ethernet header */
|
||||
memcpy ( ethhdr->h_dest, ll_dest, ETH_ALEN );
|
||||
@ -57,34 +57,34 @@ static int eth_tx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
ethhdr->h_protocol = net_protocol->net_proto;
|
||||
|
||||
/* Hand off to network device */
|
||||
return netdev_tx ( netdev, pkb );
|
||||
return netdev_tx ( netdev, iobuf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process received Ethernet packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
*
|
||||
* Strips off the Ethernet link-layer header and passes up to the
|
||||
* network-layer protocol.
|
||||
*/
|
||||
static int eth_rx ( struct pk_buff *pkb, struct net_device *netdev ) {
|
||||
struct ethhdr *ethhdr = pkb->data;
|
||||
static int eth_rx ( struct io_buffer *iobuf, struct net_device *netdev ) {
|
||||
struct ethhdr *ethhdr = iobuf->data;
|
||||
|
||||
/* Sanity check */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *ethhdr ) ) {
|
||||
if ( iob_len ( iobuf ) < sizeof ( *ethhdr ) ) {
|
||||
DBG ( "Ethernet packet too short (%d bytes)\n",
|
||||
pkb_len ( pkb ) );
|
||||
free_pkb ( pkb );
|
||||
iob_len ( iobuf ) );
|
||||
free_iob ( iobuf );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Strip off Ethernet header */
|
||||
pkb_pull ( pkb, sizeof ( *ethhdr ) );
|
||||
iob_pull ( iobuf, sizeof ( *ethhdr ) );
|
||||
|
||||
/* Hand off to network-layer protocol */
|
||||
return net_rx ( pkb, netdev, ethhdr->h_protocol, ethhdr->h_source );
|
||||
return net_rx ( iobuf, netdev, ethhdr->h_protocol, ethhdr->h_source );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <gpxe/in.h>
|
||||
#include <gpxe/ip6.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/ndp.h>
|
||||
#include <gpxe/icmp6.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
@ -31,9 +31,9 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse
|
||||
} st_dest;
|
||||
struct ll_protocol *ll_protocol = netdev->ll_protocol;
|
||||
struct neighbour_solicit *nsolicit;
|
||||
struct pk_buff *pkb = alloc_pkb ( sizeof ( *nsolicit ) + MIN_PKB_LEN );
|
||||
pkb_reserve ( pkb, MAX_HDR_LEN );
|
||||
nsolicit = pkb_put ( pkb, sizeof ( *nsolicit ) );
|
||||
struct io_buffer *iobuf = alloc_iob ( sizeof ( *nsolicit ) + MIN_IOB_LEN );
|
||||
iob_reserve ( iobuf, MAX_HDR_LEN );
|
||||
nsolicit = iob_put ( iobuf, sizeof ( *nsolicit ) );
|
||||
|
||||
/* Fill up the headers */
|
||||
memset ( nsolicit, 0, sizeof ( *nsolicit ) );
|
||||
@ -60,25 +60,25 @@ int icmp6_send_solicit ( struct net_device *netdev, struct in6_addr *src __unuse
|
||||
st_dest.sin6.sin6_addr.in6_u.u6_addr8[13] = 0xff;
|
||||
|
||||
/* Send packet over IP6 */
|
||||
return tcpip_tx ( pkb, &icmp6_protocol, &st_dest.st,
|
||||
return tcpip_tx ( iobuf, &icmp6_protocol, &st_dest.st,
|
||||
NULL, &nsolicit->csum );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process ICMP6 headers
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v st_src Source address
|
||||
* @v st_dest Destination address
|
||||
*/
|
||||
static int icmp6_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
static int icmp6_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest ) {
|
||||
struct icmp6_header *icmp6hdr = pkb->data;
|
||||
struct icmp6_header *icmp6hdr = iobuf->data;
|
||||
|
||||
/* Sanity check */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *icmp6hdr ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", pkb_len ( pkb ) );
|
||||
free_pkb ( pkb );
|
||||
if ( iob_len ( iobuf ) < sizeof ( *icmp6hdr ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", iob_len ( iobuf ) );
|
||||
free_iob ( iobuf );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ static int icmp6_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
/* Process the ICMP header */
|
||||
switch ( icmp6hdr->type ) {
|
||||
case ICMP6_NADVERT:
|
||||
return ndp_process_advert ( pkb, st_src, st_dest );
|
||||
return ndp_process_advert ( iobuf, st_src, st_dest );
|
||||
}
|
||||
return -ENOSYS;
|
||||
}
|
||||
@ -97,9 +97,9 @@ void icmp6_test_nadvert (struct net_device *netdev, struct sockaddr_in6 *server_
|
||||
|
||||
struct sockaddr_in6 server;
|
||||
memcpy ( &server, server_p, sizeof ( server ) );
|
||||
struct pk_buff *rxpkb = alloc_pkb ( 500 );
|
||||
pkb_reserve ( rxpkb, MAX_HDR_LEN );
|
||||
struct neighbour_advert *nadvert = pkb_put ( rxpkb, sizeof ( *nadvert ) );
|
||||
struct io_buffer *rxiobuf = alloc_iob ( 500 );
|
||||
iob_reserve ( rxiobuf, MAX_HDR_LEN );
|
||||
struct neighbour_advert *nadvert = iob_put ( rxiobuf, sizeof ( *nadvert ) );
|
||||
nadvert->type = 136;
|
||||
nadvert->code = 0;
|
||||
nadvert->flags = ICMP6_FLAGS_SOLICITED;
|
||||
@ -108,15 +108,15 @@ void icmp6_test_nadvert (struct net_device *netdev, struct sockaddr_in6 *server_
|
||||
nadvert->opt_type = 2;
|
||||
nadvert->opt_len = 1;
|
||||
memcpy ( nadvert->opt_ll_addr, ll_addr, 6 );
|
||||
struct ip6_header *ip6hdr = pkb_push ( rxpkb, sizeof ( *ip6hdr ) );
|
||||
struct ip6_header *ip6hdr = iob_push ( rxiobuf, sizeof ( *ip6hdr ) );
|
||||
ip6hdr->ver_traffic_class_flow_label = htonl ( 0x60000000 );
|
||||
ip6hdr->hop_limit = 255;
|
||||
ip6hdr->nxt_hdr = 58;
|
||||
ip6hdr->payload_len = htons ( sizeof ( *nadvert ) );
|
||||
ip6hdr->src = server.sin6_addr;
|
||||
ip6hdr->dest = server.sin6_addr;
|
||||
hex_dump ( rxpkb->data, pkb_len ( rxpkb ) );
|
||||
net_rx ( rxpkb, netdev, htons ( ETH_P_IPV6 ), ll_addr );
|
||||
hex_dump ( rxiobuf->data, iob_len ( rxiobuf ) );
|
||||
net_rx ( rxiobuf, netdev, htons ( ETH_P_IPV6 ), ll_addr );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
100
src/net/ipv4.c
100
src/net/ipv4.c
@ -8,7 +8,7 @@
|
||||
#include <gpxe/in.h>
|
||||
#include <gpxe/arp.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/ip.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
@ -205,11 +205,11 @@ static void free_fragbuf ( struct frag_buffer *fragbuf ) {
|
||||
/**
|
||||
* Fragment reassembler
|
||||
*
|
||||
* @v pkb Packet buffer, fragment of the datagram
|
||||
* @ret frag_pkb Reassembled packet, or NULL
|
||||
* @v iobuf I/O buffer, fragment of the datagram
|
||||
* @ret frag_iob Reassembled packet, or NULL
|
||||
*/
|
||||
static struct pk_buff * ipv4_reassemble ( struct pk_buff * pkb ) {
|
||||
struct iphdr *iphdr = pkb->data;
|
||||
static struct io_buffer * ipv4_reassemble ( struct io_buffer * iobuf ) {
|
||||
struct iphdr *iphdr = iobuf->data;
|
||||
struct frag_buffer *fragbuf;
|
||||
|
||||
/**
|
||||
@ -223,31 +223,31 @@ static struct pk_buff * ipv4_reassemble ( struct pk_buff * pkb ) {
|
||||
*
|
||||
* The offset of the new packet must be equal to the
|
||||
* length of the data accumulated so far (the length of
|
||||
* the reassembled packet buffer
|
||||
* the reassembled I/O buffer
|
||||
*/
|
||||
if ( pkb_len ( fragbuf->frag_pkb ) ==
|
||||
if ( iob_len ( fragbuf->frag_iob ) ==
|
||||
( iphdr->frags & IP_MASK_OFFSET ) ) {
|
||||
/**
|
||||
* Append the contents of the fragment to the
|
||||
* reassembled packet buffer
|
||||
* reassembled I/O buffer
|
||||
*/
|
||||
pkb_pull ( pkb, sizeof ( *iphdr ) );
|
||||
memcpy ( pkb_put ( fragbuf->frag_pkb,
|
||||
pkb_len ( pkb ) ),
|
||||
pkb->data, pkb_len ( pkb ) );
|
||||
free_pkb ( pkb );
|
||||
iob_pull ( iobuf, sizeof ( *iphdr ) );
|
||||
memcpy ( iob_put ( fragbuf->frag_iob,
|
||||
iob_len ( iobuf ) ),
|
||||
iobuf->data, iob_len ( iobuf ) );
|
||||
free_iob ( iobuf );
|
||||
|
||||
/** Check if the fragment series is over */
|
||||
if ( !iphdr->frags & IP_MASK_MOREFRAGS ) {
|
||||
pkb = fragbuf->frag_pkb;
|
||||
iobuf = fragbuf->frag_iob;
|
||||
free_fragbuf ( fragbuf );
|
||||
return pkb;
|
||||
return iobuf;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Discard the fragment series */
|
||||
free_fragbuf ( fragbuf );
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -262,12 +262,12 @@ static struct pk_buff * ipv4_reassemble ( struct pk_buff * pkb ) {
|
||||
fragbuf->ident = iphdr->ident;
|
||||
fragbuf->src = iphdr->src;
|
||||
|
||||
/* Set up the reassembly packet buffer */
|
||||
fragbuf->frag_pkb = alloc_pkb ( IP_FRAG_PKB_SIZE );
|
||||
pkb_pull ( pkb, sizeof ( *iphdr ) );
|
||||
memcpy ( pkb_put ( fragbuf->frag_pkb, pkb_len ( pkb ) ),
|
||||
pkb->data, pkb_len ( pkb ) );
|
||||
free_pkb ( pkb );
|
||||
/* Set up the reassembly I/O buffer */
|
||||
fragbuf->frag_iob = alloc_iob ( IP_FRAG_IOB_SIZE );
|
||||
iob_pull ( iobuf, sizeof ( *iphdr ) );
|
||||
memcpy ( iob_put ( fragbuf->frag_iob, iob_len ( iobuf ) ),
|
||||
iobuf->data, iob_len ( iobuf ) );
|
||||
free_iob ( iobuf );
|
||||
|
||||
/* Set the reassembly timer */
|
||||
fragbuf->frag_timer.timeout = IP_FRAG_TIMEOUT;
|
||||
@ -284,13 +284,13 @@ static struct pk_buff * ipv4_reassemble ( struct pk_buff * pkb ) {
|
||||
/**
|
||||
* Add IPv4 pseudo-header checksum to existing checksum
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v csum Existing checksum
|
||||
* @ret csum Updated checksum
|
||||
*/
|
||||
static uint16_t ipv4_pshdr_chksum ( struct pk_buff *pkb, uint16_t csum ) {
|
||||
static uint16_t ipv4_pshdr_chksum ( struct io_buffer *iobuf, uint16_t csum ) {
|
||||
struct ipv4_pseudo_header pshdr;
|
||||
struct iphdr *iphdr = pkb->data;
|
||||
struct iphdr *iphdr = iobuf->data;
|
||||
size_t hdrlen = ( ( iphdr->verhdrlen & IP_MASK_HLEN ) * 4 );
|
||||
|
||||
/* Build pseudo-header */
|
||||
@ -298,7 +298,7 @@ static uint16_t ipv4_pshdr_chksum ( struct pk_buff *pkb, uint16_t csum ) {
|
||||
pshdr.dest = iphdr->dest;
|
||||
pshdr.zero_padding = 0x00;
|
||||
pshdr.protocol = iphdr->protocol;
|
||||
pshdr.len = htons ( pkb_len ( pkb ) - hdrlen );
|
||||
pshdr.len = htons ( iob_len ( iobuf ) - hdrlen );
|
||||
|
||||
/* Update the checksum value */
|
||||
return tcpip_continue_chksum ( csum, &pshdr, sizeof ( pshdr ) );
|
||||
@ -345,7 +345,7 @@ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
|
||||
/**
|
||||
* Transmit IP packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v tcpip Transport-layer protocol
|
||||
* @v st_dest Destination network-layer address
|
||||
* @v netdev Network device to use if no route found, or NULL
|
||||
@ -354,12 +354,12 @@ static int ipv4_ll_addr ( struct in_addr dest, struct in_addr src,
|
||||
*
|
||||
* This function expects a transport-layer segment and prepends the IP header
|
||||
*/
|
||||
static int ipv4_tx ( struct pk_buff *pkb,
|
||||
static int ipv4_tx ( struct io_buffer *iobuf,
|
||||
struct tcpip_protocol *tcpip_protocol,
|
||||
struct sockaddr_tcpip *st_dest,
|
||||
struct net_device *netdev,
|
||||
uint16_t *trans_csum ) {
|
||||
struct iphdr *iphdr = pkb_push ( pkb, sizeof ( *iphdr ) );
|
||||
struct iphdr *iphdr = iob_push ( iobuf, sizeof ( *iphdr ) );
|
||||
struct sockaddr_in *sin_dest = ( ( struct sockaddr_in * ) st_dest );
|
||||
struct ipv4_miniroute *miniroute;
|
||||
struct in_addr next_hop;
|
||||
@ -370,7 +370,7 @@ static int ipv4_tx ( struct pk_buff *pkb,
|
||||
memset ( iphdr, 0, sizeof ( *iphdr ) );
|
||||
iphdr->verhdrlen = ( IP_VER | ( sizeof ( *iphdr ) / 4 ) );
|
||||
iphdr->service = IP_TOS;
|
||||
iphdr->len = htons ( pkb_len ( pkb ) );
|
||||
iphdr->len = htons ( iob_len ( iobuf ) );
|
||||
iphdr->ident = htons ( ++next_ident );
|
||||
iphdr->ttl = IP_TTL;
|
||||
iphdr->protocol = tcpip_protocol->tcpip_proto;
|
||||
@ -398,7 +398,7 @@ static int ipv4_tx ( struct pk_buff *pkb,
|
||||
|
||||
/* Fix up checksums */
|
||||
if ( trans_csum )
|
||||
*trans_csum = ipv4_pshdr_chksum ( pkb, *trans_csum );
|
||||
*trans_csum = ipv4_pshdr_chksum ( iobuf, *trans_csum );
|
||||
iphdr->chksum = tcpip_chksum ( iphdr, sizeof ( *iphdr ) );
|
||||
|
||||
/* Print IP4 header for debugging */
|
||||
@ -408,7 +408,7 @@ static int ipv4_tx ( struct pk_buff *pkb,
|
||||
ntohs ( iphdr->ident ), ntohs ( iphdr->chksum ) );
|
||||
|
||||
/* Hand off to link layer */
|
||||
if ( ( rc = net_tx ( pkb, netdev, &ipv4_protocol, ll_dest ) ) != 0 ) {
|
||||
if ( ( rc = net_tx ( iobuf, netdev, &ipv4_protocol, ll_dest ) ) != 0 ) {
|
||||
DBG ( "IPv4 could not transmit packet via %s: %s\n",
|
||||
netdev->name, strerror ( rc ) );
|
||||
return rc;
|
||||
@ -417,23 +417,23 @@ static int ipv4_tx ( struct pk_buff *pkb,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process incoming packets
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v ll_source Link-layer destination source
|
||||
*
|
||||
* This function expects an IP4 network datagram. It processes the headers
|
||||
* and sends it to the transport layer.
|
||||
*/
|
||||
static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
static int ipv4_rx ( struct io_buffer *iobuf, struct net_device *netdev __unused,
|
||||
const void *ll_source __unused ) {
|
||||
struct iphdr *iphdr = pkb->data;
|
||||
struct iphdr *iphdr = iobuf->data;
|
||||
size_t hdrlen;
|
||||
size_t len;
|
||||
union {
|
||||
@ -445,9 +445,9 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
int rc;
|
||||
|
||||
/* Sanity check the IPv4 header */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *iphdr ) ) {
|
||||
if ( iob_len ( iobuf ) < sizeof ( *iphdr ) ) {
|
||||
DBG ( "IPv4 packet too short at %d bytes (min %d bytes)\n",
|
||||
pkb_len ( pkb ), sizeof ( *iphdr ) );
|
||||
iob_len ( iobuf ), sizeof ( *iphdr ) );
|
||||
goto err;
|
||||
}
|
||||
if ( ( iphdr->verhdrlen & IP_MASK_VER ) != IP_VER ) {
|
||||
@ -460,9 +460,9 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
hdrlen, sizeof ( *iphdr ) );
|
||||
goto err;
|
||||
}
|
||||
if ( hdrlen > pkb_len ( pkb ) ) {
|
||||
if ( hdrlen > iob_len ( iobuf ) ) {
|
||||
DBG ( "IPv4 header too long at %d bytes "
|
||||
"(packet is %d bytes)\n", hdrlen, pkb_len ( pkb ) );
|
||||
"(packet is %d bytes)\n", hdrlen, iob_len ( iobuf ) );
|
||||
goto err;
|
||||
}
|
||||
if ( ( csum = tcpip_chksum ( iphdr, hdrlen ) ) != 0 ) {
|
||||
@ -476,9 +476,9 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
"(header is %d bytes)\n", len, hdrlen );
|
||||
goto err;
|
||||
}
|
||||
if ( len > pkb_len ( pkb ) ) {
|
||||
if ( len > iob_len ( iobuf ) ) {
|
||||
DBG ( "IPv4 length too long at %d bytes "
|
||||
"(packet is %d bytes)\n", len, pkb_len ( pkb ) );
|
||||
"(packet is %d bytes)\n", len, iob_len ( iobuf ) );
|
||||
goto err;
|
||||
}
|
||||
|
||||
@ -491,18 +491,18 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
/* Truncate packet to correct length, calculate pseudo-header
|
||||
* checksum and then strip off the IPv4 header.
|
||||
*/
|
||||
pkb_unput ( pkb, ( pkb_len ( pkb ) - len ) );
|
||||
pshdr_csum = ipv4_pshdr_chksum ( pkb, TCPIP_EMPTY_CSUM );
|
||||
pkb_pull ( pkb, hdrlen );
|
||||
iob_unput ( iobuf, ( iob_len ( iobuf ) - len ) );
|
||||
pshdr_csum = ipv4_pshdr_chksum ( iobuf, TCPIP_EMPTY_CSUM );
|
||||
iob_pull ( iobuf, hdrlen );
|
||||
|
||||
/* Fragment reassembly */
|
||||
if ( ( iphdr->frags & htons ( IP_MASK_MOREFRAGS ) ) ||
|
||||
( ( iphdr->frags & htons ( IP_MASK_OFFSET ) ) != 0 ) ) {
|
||||
/* Pass the fragment to ipv4_reassemble() which either
|
||||
* returns a fully reassembled packet buffer or NULL.
|
||||
* returns a fully reassembled I/O buffer or NULL.
|
||||
*/
|
||||
pkb = ipv4_reassemble ( pkb );
|
||||
if ( ! pkb )
|
||||
iobuf = ipv4_reassemble ( iobuf );
|
||||
if ( ! iobuf )
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -513,7 +513,7 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
memset ( &dest, 0, sizeof ( dest ) );
|
||||
dest.sin.sin_family = AF_INET;
|
||||
dest.sin.sin_addr = iphdr->dest;
|
||||
if ( ( rc = tcpip_rx ( pkb, iphdr->protocol, &src.st,
|
||||
if ( ( rc = tcpip_rx ( iobuf, iphdr->protocol, &src.st,
|
||||
&dest.st, pshdr_csum ) ) != 0 ) {
|
||||
DBG ( "IPv4 received packet rejected by stack: %s\n",
|
||||
strerror ( rc ) );
|
||||
@ -523,7 +523,7 @@ static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
|
||||
return 0;
|
||||
|
||||
err:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <gpxe/icmp6.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
#include <gpxe/socket.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
|
||||
@ -157,21 +157,21 @@ void del_ipv6_address ( struct net_device *netdev ) {
|
||||
/**
|
||||
* Calculate TCPIP checksum
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v tcpip TCP/IP protocol
|
||||
*
|
||||
* This function constructs the pseudo header and completes the checksum in the
|
||||
* upper layer header.
|
||||
*/
|
||||
static uint16_t ipv6_tx_csum ( struct pk_buff *pkb, uint16_t csum ) {
|
||||
struct ip6_header *ip6hdr = pkb->data;
|
||||
static uint16_t ipv6_tx_csum ( struct io_buffer *iobuf, uint16_t csum ) {
|
||||
struct ip6_header *ip6hdr = iobuf->data;
|
||||
struct ipv6_pseudo_header pshdr;
|
||||
|
||||
/* Calculate pseudo header */
|
||||
memset ( &pshdr, 0, sizeof ( pshdr ) );
|
||||
pshdr.src = ip6hdr->src;
|
||||
pshdr.dest = ip6hdr->dest;
|
||||
pshdr.len = htons ( pkb_len ( pkb ) - sizeof ( *ip6hdr ) );
|
||||
pshdr.len = htons ( iob_len ( iobuf ) - sizeof ( *ip6hdr ) );
|
||||
pshdr.nxt_hdr = ip6hdr->nxt_hdr;
|
||||
|
||||
/* Update checksum value */
|
||||
@ -192,13 +192,13 @@ void ipv6_dump ( struct ip6_header *ip6hdr ) {
|
||||
/**
|
||||
* Transmit IP6 packet
|
||||
*
|
||||
* pkb Packet buffer
|
||||
* iobuf I/O buffer
|
||||
* tcpip TCP/IP protocol
|
||||
* st_dest Destination socket address
|
||||
*
|
||||
* This function prepends the IPv6 headers to the payload an transmits it.
|
||||
*/
|
||||
static int ipv6_tx ( struct pk_buff *pkb,
|
||||
static int ipv6_tx ( struct io_buffer *iobuf,
|
||||
struct tcpip_protocol *tcpip,
|
||||
struct sockaddr_tcpip *st_dest,
|
||||
struct net_device *netdev,
|
||||
@ -211,10 +211,10 @@ static int ipv6_tx ( struct pk_buff *pkb,
|
||||
int rc;
|
||||
|
||||
/* Construct the IPv6 packet */
|
||||
struct ip6_header *ip6hdr = pkb_push ( pkb, sizeof ( *ip6hdr ) );
|
||||
struct ip6_header *ip6hdr = iob_push ( iobuf, sizeof ( *ip6hdr ) );
|
||||
memset ( ip6hdr, 0, sizeof ( *ip6hdr) );
|
||||
ip6hdr->ver_traffic_class_flow_label = htonl ( 0x60000000 );//IP6_VERSION;
|
||||
ip6hdr->payload_len = htons ( pkb_len ( pkb ) - sizeof ( *ip6hdr ) );
|
||||
ip6hdr->payload_len = htons ( iob_len ( iobuf ) - sizeof ( *ip6hdr ) );
|
||||
ip6hdr->nxt_hdr = tcpip->tcpip_proto;
|
||||
ip6hdr->hop_limit = IP6_HOP_LIMIT; // 255
|
||||
|
||||
@ -244,7 +244,7 @@ static int ipv6_tx ( struct pk_buff *pkb,
|
||||
|
||||
/* Complete the transport layer checksum */
|
||||
if ( trans_csum )
|
||||
*trans_csum = ipv6_tx_csum ( pkb, *trans_csum );
|
||||
*trans_csum = ipv6_tx_csum ( iobuf, *trans_csum );
|
||||
|
||||
/* Print IPv6 header */
|
||||
ipv6_dump ( ip6hdr );
|
||||
@ -267,24 +267,24 @@ static int ipv6_tx ( struct pk_buff *pkb,
|
||||
}
|
||||
|
||||
/* Transmit packet */
|
||||
return net_tx ( pkb, netdev, &ipv6_protocol, ll_dest );
|
||||
return net_tx ( iobuf, netdev, &ipv6_protocol, ll_dest );
|
||||
|
||||
err:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process next IP6 header
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v nxt_hdr Next header number
|
||||
* @v src Source socket address
|
||||
* @v dest Destination socket address
|
||||
*
|
||||
* Refer http://www.iana.org/assignments/ipv6-parameters for the numbers
|
||||
*/
|
||||
static int ipv6_process_nxt_hdr ( struct pk_buff *pkb, uint8_t nxt_hdr,
|
||||
static int ipv6_process_nxt_hdr ( struct io_buffer *iobuf, uint8_t nxt_hdr,
|
||||
struct sockaddr_tcpip *src, struct sockaddr_tcpip *dest ) {
|
||||
switch ( nxt_hdr ) {
|
||||
case IP6_HOPBYHOP:
|
||||
@ -302,31 +302,31 @@ static int ipv6_process_nxt_hdr ( struct pk_buff *pkb, uint8_t nxt_hdr,
|
||||
return 0;
|
||||
}
|
||||
/* Next header is not a IPv6 extension header */
|
||||
return tcpip_rx ( pkb, nxt_hdr, src, dest, 0 /* fixme */ );
|
||||
return tcpip_rx ( iobuf, nxt_hdr, src, dest, 0 /* fixme */ );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process incoming IP6 packets
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v ll_source Link-layer source address
|
||||
*
|
||||
* This function processes a IPv6 packet
|
||||
*/
|
||||
static int ipv6_rx ( struct pk_buff *pkb,
|
||||
static int ipv6_rx ( struct io_buffer *iobuf,
|
||||
struct net_device *netdev,
|
||||
const void *ll_source ) {
|
||||
|
||||
struct ip6_header *ip6hdr = pkb->data;
|
||||
struct ip6_header *ip6hdr = iobuf->data;
|
||||
union {
|
||||
struct sockaddr_in6 sin6;
|
||||
struct sockaddr_tcpip st;
|
||||
} src, dest;
|
||||
|
||||
/* Sanity check */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *ip6hdr ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", pkb_len ( pkb ) );
|
||||
if ( iob_len ( iobuf ) < sizeof ( *ip6hdr ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", iob_len ( iobuf ) );
|
||||
goto drop;
|
||||
}
|
||||
|
||||
@ -342,7 +342,7 @@ static int ipv6_rx ( struct pk_buff *pkb,
|
||||
}
|
||||
|
||||
/* Check the payload length */
|
||||
if ( ntohs ( ip6hdr->payload_len ) > pkb_len ( pkb ) ) {
|
||||
if ( ntohs ( ip6hdr->payload_len ) > iob_len ( iobuf ) ) {
|
||||
DBG ( "Inconsistent packet length (%d bytes)\n",
|
||||
ip6hdr->payload_len );
|
||||
goto drop;
|
||||
@ -359,16 +359,16 @@ static int ipv6_rx ( struct pk_buff *pkb,
|
||||
dest.sin6.sin6_addr = ip6hdr->dest;
|
||||
|
||||
/* Strip header */
|
||||
pkb_unput ( pkb, pkb_len ( pkb ) - ntohs ( ip6hdr->payload_len ) -
|
||||
iob_unput ( iobuf, iob_len ( iobuf ) - ntohs ( ip6hdr->payload_len ) -
|
||||
sizeof ( *ip6hdr ) );
|
||||
pkb_pull ( pkb, sizeof ( *ip6hdr ) );
|
||||
iob_pull ( iobuf, sizeof ( *ip6hdr ) );
|
||||
|
||||
/* Send it to the transport layer */
|
||||
return ipv6_process_nxt_hdr ( pkb, ip6hdr->nxt_hdr, &src.st, &dest.st );
|
||||
return ipv6_process_nxt_hdr ( iobuf, ip6hdr->nxt_hdr, &src.st, &dest.st );
|
||||
|
||||
drop:
|
||||
DBG ( "Packet dropped\n" );
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/ndp.h>
|
||||
#include <gpxe/icmp6.h>
|
||||
#include <gpxe/ip6.h>
|
||||
@ -143,18 +143,18 @@ int ndp_resolve ( struct net_device *netdev, struct in6_addr *dest,
|
||||
/**
|
||||
* Process neighbour advertisement
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v st_src Source address
|
||||
* @v st_dest Destination address
|
||||
*/
|
||||
int ndp_process_advert ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src __unused,
|
||||
int ndp_process_advert ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src __unused,
|
||||
struct sockaddr_tcpip *st_dest __unused ) {
|
||||
struct neighbour_advert *nadvert = pkb->data;
|
||||
struct neighbour_advert *nadvert = iobuf->data;
|
||||
struct ndp_entry *ndp;
|
||||
|
||||
/* Sanity check */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *nadvert ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", pkb_len ( pkb ) );
|
||||
if ( iob_len ( iobuf ) < sizeof ( *nadvert ) ) {
|
||||
DBG ( "Packet too short (%d bytes)\n", iob_len ( iobuf ) );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <gpxe/if_ether.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/tables.h>
|
||||
#include <gpxe/process.h>
|
||||
#include <gpxe/init.h>
|
||||
@ -49,34 +49,34 @@ struct list_head net_devices = LIST_HEAD_INIT ( net_devices );
|
||||
* Transmit raw packet via network device
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* Transmits the packet via the specified network device. This
|
||||
* function takes ownership of the packet buffer.
|
||||
* function takes ownership of the I/O buffer.
|
||||
*/
|
||||
int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
int rc;
|
||||
|
||||
DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
|
||||
netdev, pkb, pkb->data, pkb_len ( pkb ) );
|
||||
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
|
||||
|
||||
list_add_tail ( &pkb->list, &netdev->tx_queue );
|
||||
list_add_tail ( &iobuf->list, &netdev->tx_queue );
|
||||
|
||||
if ( ! ( netdev->state & NETDEV_OPEN ) ) {
|
||||
rc = -ENETUNREACH;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ( ( rc = netdev->transmit ( netdev, pkb ) ) != 0 )
|
||||
if ( ( rc = netdev->transmit ( netdev, iobuf ) ) != 0 )
|
||||
goto err;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
DBGC ( netdev, "NETDEV %p transmission %p failed: %s\n",
|
||||
netdev, pkb, strerror ( rc ) );
|
||||
netdev_tx_complete ( netdev, pkb );
|
||||
netdev, iobuf, strerror ( rc ) );
|
||||
netdev_tx_complete ( netdev, iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -84,19 +84,19 @@ int netdev_tx ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
* Complete network transmission
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
*
|
||||
* The packet must currently be in the network device's TX queue.
|
||||
*/
|
||||
void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, pkb );
|
||||
void netdev_tx_complete ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
DBGC ( netdev, "NETDEV %p transmission %p complete\n", netdev, iobuf );
|
||||
|
||||
/* Catch data corruption as early as possible */
|
||||
assert ( pkb->list.next != NULL );
|
||||
assert ( pkb->list.prev != NULL );
|
||||
assert ( iobuf->list.next != NULL );
|
||||
assert ( iobuf->list.prev != NULL );
|
||||
|
||||
list_del ( &pkb->list );
|
||||
free_pkb ( pkb );
|
||||
list_del ( &iobuf->list );
|
||||
free_iob ( iobuf );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,10 +107,10 @@ void netdev_tx_complete ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
* Completes the oldest outstanding packet in the TX queue.
|
||||
*/
|
||||
void netdev_tx_complete_next ( struct net_device *netdev ) {
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
list_for_each_entry ( pkb, &netdev->tx_queue, list ) {
|
||||
netdev_tx_complete ( netdev, pkb );
|
||||
list_for_each_entry ( iobuf, &netdev->tx_queue, list ) {
|
||||
netdev_tx_complete ( netdev, iobuf );
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -119,15 +119,15 @@ void netdev_tx_complete_next ( struct net_device *netdev ) {
|
||||
* Add packet to receive queue
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
*
|
||||
* The packet is added to the network device's RX queue. This
|
||||
* function takes ownership of the packet buffer.
|
||||
* function takes ownership of the I/O buffer.
|
||||
*/
|
||||
void netdev_rx ( struct net_device *netdev, struct pk_buff *pkb ) {
|
||||
void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
|
||||
DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
|
||||
netdev, pkb, pkb->data, pkb_len ( pkb ) );
|
||||
list_add_tail ( &pkb->list, &netdev->rx_queue );
|
||||
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
|
||||
list_add_tail ( &iobuf->list, &netdev->rx_queue );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,17 +153,17 @@ int netdev_poll ( struct net_device *netdev, unsigned int rx_quota ) {
|
||||
* Remove packet from device's receive queue
|
||||
*
|
||||
* @v netdev Network device
|
||||
* @ret pkb Packet buffer, or NULL
|
||||
* @ret iobuf I/O buffer, or NULL
|
||||
*
|
||||
* Removes the first packet from the device's RX queue and returns it.
|
||||
* Ownership of the packet is transferred to the caller.
|
||||
*/
|
||||
struct pk_buff * netdev_rx_dequeue ( struct net_device *netdev ) {
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer * netdev_rx_dequeue ( struct net_device *netdev ) {
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
list_for_each_entry ( pkb, &netdev->rx_queue, list ) {
|
||||
list_del ( &pkb->list );
|
||||
return pkb;
|
||||
list_for_each_entry ( iobuf, &netdev->rx_queue, list ) {
|
||||
list_del ( &iobuf->list );
|
||||
return iobuf;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -247,7 +247,7 @@ int netdev_open ( struct net_device *netdev ) {
|
||||
* @v netdev Network device
|
||||
*/
|
||||
void netdev_close ( struct net_device *netdev ) {
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
/* Do nothing if device is already closed */
|
||||
if ( ! ( netdev->state & NETDEV_OPEN ) )
|
||||
@ -264,10 +264,10 @@ void netdev_close ( struct net_device *netdev ) {
|
||||
}
|
||||
|
||||
/* Discard any packets in the RX queue */
|
||||
while ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
|
||||
while ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
|
||||
DBGC ( netdev, "NETDEV %p discarding received %p\n",
|
||||
netdev, pkb );
|
||||
free_pkb ( pkb );
|
||||
netdev, iobuf );
|
||||
free_iob ( iobuf );
|
||||
}
|
||||
|
||||
/* Mark as closed */
|
||||
@ -341,31 +341,31 @@ struct net_device * find_pci_netdev ( unsigned int busdevfn ) {
|
||||
/**
|
||||
* Transmit network-layer packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O 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
|
||||
* Prepends link-layer headers to the I/O buffer and transmits the
|
||||
* packet via the specified network device. This function takes
|
||||
* ownership of the packet buffer.
|
||||
* ownership of the I/O buffer.
|
||||
*/
|
||||
int net_tx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
int net_tx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
struct net_protocol *net_protocol, const void *ll_dest ) {
|
||||
return netdev->ll_protocol->tx ( pkb, netdev, net_protocol, ll_dest );
|
||||
return netdev->ll_protocol->tx ( iobuf, netdev, net_protocol, ll_dest );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process received network-layer packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v netdev Network device
|
||||
* @v net_proto Network-layer protocol, in network-byte order
|
||||
* @v ll_source Source link-layer address
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
int net_rx ( struct io_buffer *iobuf, struct net_device *netdev,
|
||||
uint16_t net_proto, const void *ll_source ) {
|
||||
struct net_protocol *net_protocol;
|
||||
|
||||
@ -373,10 +373,10 @@ int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
for ( net_protocol = net_protocols ; net_protocol < net_protocols_end ;
|
||||
net_protocol++ ) {
|
||||
if ( net_protocol->net_proto == net_proto ) {
|
||||
return net_protocol->rx ( pkb, netdev, ll_source );
|
||||
return net_protocol->rx ( iobuf, netdev, ll_source );
|
||||
}
|
||||
}
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -390,7 +390,7 @@ int net_rx ( struct pk_buff *pkb, struct net_device *netdev,
|
||||
*/
|
||||
static void net_step ( struct process *process ) {
|
||||
struct net_device *netdev;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
/* Poll and process each network device */
|
||||
list_for_each_entry ( netdev, &net_devices, list ) {
|
||||
@ -404,10 +404,10 @@ static void net_step ( struct process *process ) {
|
||||
* that assumes that we can receive packets from the
|
||||
* NIC faster than they arrive.
|
||||
*/
|
||||
if ( ( pkb = netdev_rx_dequeue ( netdev ) ) ) {
|
||||
if ( ( iobuf = netdev_rx_dequeue ( netdev ) ) ) {
|
||||
DBGC ( netdev, "NETDEV %p processing %p\n",
|
||||
netdev, pkb );
|
||||
netdev->ll_protocol->rx ( pkb, netdev );
|
||||
netdev, iobuf );
|
||||
netdev->ll_protocol->rx ( iobuf, netdev );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,48 +19,48 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* Packet buffer padding
|
||||
* I/O buffer padding
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
|
||||
/**
|
||||
* Pad packet buffer
|
||||
* Pad I/O buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v min_len Minimum length
|
||||
*
|
||||
* This function pads and aligns packet buffers, for devices that
|
||||
* This function pads and aligns I/O buffers, for devices that
|
||||
* aren't capable of padding in hardware, or that require specific
|
||||
* alignment in TX buffers. The packet data will end up aligned to a
|
||||
* multiple of @c PKB_ALIGN.
|
||||
* multiple of @c IOB_ALIGN.
|
||||
*
|
||||
* @c min_len must not exceed @v PKB_ZLEN.
|
||||
* @c min_len must not exceed @v IOB_ZLEN.
|
||||
*/
|
||||
void pkb_pad ( struct pk_buff *pkb, size_t min_len ) {
|
||||
void iob_pad ( struct io_buffer *iobuf, size_t min_len ) {
|
||||
void *data;
|
||||
size_t len;
|
||||
size_t headroom;
|
||||
signed int pad_len;
|
||||
|
||||
assert ( min_len <= PKB_ZLEN );
|
||||
assert ( min_len <= IOB_ZLEN );
|
||||
|
||||
/* Move packet data to start of packet buffer. This will both
|
||||
* align the data (since packet buffers are aligned to
|
||||
* PKB_ALIGN) and give us sufficient space for the
|
||||
/* Move packet data to start of I/O buffer. This will both
|
||||
* align the data (since I/O buffers are aligned to
|
||||
* IOB_ALIGN) and give us sufficient space for the
|
||||
* zero-padding
|
||||
*/
|
||||
data = pkb->data;
|
||||
len = pkb_len ( pkb );
|
||||
headroom = pkb_headroom ( pkb );
|
||||
pkb_push ( pkb, headroom );
|
||||
memmove ( pkb->data, data, len );
|
||||
pkb_unput ( pkb, headroom );
|
||||
data = iobuf->data;
|
||||
len = iob_len ( iobuf );
|
||||
headroom = iob_headroom ( iobuf );
|
||||
iob_push ( iobuf, headroom );
|
||||
memmove ( iobuf->data, data, len );
|
||||
iob_unput ( iobuf, headroom );
|
||||
|
||||
/* Pad to minimum packet length */
|
||||
pad_len = ( min_len - pkb_len ( pkb ) );
|
||||
pad_len = ( min_len - iob_len ( iobuf ) );
|
||||
if ( pad_len > 0 )
|
||||
memset ( pkb_put ( pkb, pad_len ), 0, pad_len );
|
||||
memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <gpxe/malloc.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Packet buffers
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Allocate packet buffer
|
||||
*
|
||||
* @v len Required length of buffer
|
||||
* @ret pkb Packet buffer, or NULL if none available
|
||||
*
|
||||
* The packet buffer will be physically aligned to a multiple of
|
||||
* @c PKBUFF_SIZE.
|
||||
*/
|
||||
struct pk_buff * alloc_pkb ( size_t len ) {
|
||||
struct pk_buff *pkb = NULL;
|
||||
void *data;
|
||||
|
||||
/* Pad to minimum length */
|
||||
if ( len < PKB_ZLEN )
|
||||
len = PKB_ZLEN;
|
||||
|
||||
/* Align buffer length */
|
||||
len = ( len + __alignof__( *pkb ) - 1 ) & ~( __alignof__( *pkb ) - 1 );
|
||||
|
||||
/* Allocate memory for buffer plus descriptor */
|
||||
data = malloc_dma ( len + sizeof ( *pkb ), PKBUFF_ALIGN );
|
||||
if ( ! data )
|
||||
return NULL;
|
||||
|
||||
pkb = ( struct pk_buff * ) ( data + len );
|
||||
pkb->head = pkb->data = pkb->tail = data;
|
||||
pkb->end = pkb;
|
||||
return pkb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Free packet buffer
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
*/
|
||||
void free_pkb ( struct pk_buff *pkb ) {
|
||||
if ( pkb ) {
|
||||
assert ( pkb->head <= pkb->data );
|
||||
assert ( pkb->data <= pkb->tail );
|
||||
assert ( pkb->tail <= pkb->end );
|
||||
free_dma ( pkb->head,
|
||||
( pkb->end - pkb->head ) + sizeof ( *pkb ) );
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
#include <timer.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/malloc.h>
|
||||
#include <gpxe/retry.h>
|
||||
#include <gpxe/stream.h>
|
||||
@ -68,12 +68,12 @@ struct tcp_connection {
|
||||
*/
|
||||
uint32_t rcv_ack;
|
||||
|
||||
/** Transmit packet buffer
|
||||
/** Transmit I/O buffer
|
||||
*
|
||||
* This buffer is allocated prior to calling the application's
|
||||
* senddata() method, to provide temporary storage space.
|
||||
*/
|
||||
struct pk_buff *tx_pkb;
|
||||
struct io_buffer *tx_iob;
|
||||
/** Retransmission timer */
|
||||
struct retry_timer timer;
|
||||
};
|
||||
@ -222,7 +222,7 @@ static void tcp_abort ( struct tcp_connection *tcp, int send_rst, int rc ) {
|
||||
* eventually attempt to retransmit the failed packet.
|
||||
*/
|
||||
static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
struct tcp_header *tcphdr;
|
||||
struct tcp_mss_option *mssopt;
|
||||
void *payload;
|
||||
@ -233,12 +233,12 @@ static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
int rc;
|
||||
|
||||
/* Allocate space to the TX buffer */
|
||||
pkb = alloc_pkb ( MAX_PKB_LEN );
|
||||
if ( ! pkb ) {
|
||||
iobuf = alloc_iob ( MAX_IOB_LEN );
|
||||
if ( ! iobuf ) {
|
||||
DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
|
||||
/* Start the retry timer so that we attempt to
|
||||
* retransmit this packet later. (Start it
|
||||
* unconditionally, since without a packet buffer we
|
||||
* unconditionally, since without a I/O buffer we
|
||||
* can't call the senddata() callback, and so may not
|
||||
* be able to tell whether or not we have something
|
||||
* that actually needs to be retransmitted).
|
||||
@ -246,20 +246,20 @@ static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
start_timer ( &tcp->timer );
|
||||
return -ENOMEM;
|
||||
}
|
||||
pkb_reserve ( pkb, MAX_HDR_LEN );
|
||||
iob_reserve ( iobuf, MAX_HDR_LEN );
|
||||
|
||||
/* If we are connected, call the senddata() method, which may
|
||||
* call tcp_send() to queue up a data payload.
|
||||
*/
|
||||
if ( TCP_CAN_SEND_DATA ( tcp->tcp_state ) ) {
|
||||
tcp->tx_pkb = pkb;
|
||||
stream_senddata ( &tcp->stream, pkb->data,
|
||||
pkb_tailroom ( pkb ) );
|
||||
tcp->tx_pkb = NULL;
|
||||
tcp->tx_iob = iobuf;
|
||||
stream_senddata ( &tcp->stream, iobuf->data,
|
||||
iob_tailroom ( iobuf ) );
|
||||
tcp->tx_iob = NULL;
|
||||
}
|
||||
|
||||
/* Truncate payload length to fit transmit window */
|
||||
len = pkb_len ( pkb );
|
||||
len = iob_len ( iobuf );
|
||||
if ( len > tcp->snd_win )
|
||||
len = tcp->snd_win;
|
||||
|
||||
@ -276,7 +276,7 @@ static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
|
||||
/* If we have nothing to transmit, drop the packet */
|
||||
if ( ( seq_len == 0 ) && ! force_send ) {
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -294,23 +294,23 @@ static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
window &= ~0x03; /* Keep everything dword-aligned */
|
||||
|
||||
/* Fill up the TCP header */
|
||||
payload = pkb->data;
|
||||
payload = iobuf->data;
|
||||
if ( flags & TCP_SYN ) {
|
||||
mssopt = pkb_push ( pkb, sizeof ( *mssopt ) );
|
||||
mssopt = iob_push ( iobuf, sizeof ( *mssopt ) );
|
||||
mssopt->kind = TCP_OPTION_MSS;
|
||||
mssopt->length = sizeof ( *mssopt );
|
||||
mssopt->mss = htons ( TCP_MSS );
|
||||
}
|
||||
tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
|
||||
tcphdr = iob_push ( iobuf, sizeof ( *tcphdr ) );
|
||||
memset ( tcphdr, 0, sizeof ( *tcphdr ) );
|
||||
tcphdr->src = tcp->local_port;
|
||||
tcphdr->dest = tcp->peer.st_port;
|
||||
tcphdr->seq = htonl ( tcp->snd_seq );
|
||||
tcphdr->ack = htonl ( tcp->rcv_ack );
|
||||
tcphdr->hlen = ( ( payload - pkb->data ) << 2 );
|
||||
tcphdr->hlen = ( ( payload - iobuf->data ) << 2 );
|
||||
tcphdr->flags = flags;
|
||||
tcphdr->win = htons ( window );
|
||||
tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
|
||||
tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) );
|
||||
|
||||
/* Dump header */
|
||||
DBGC ( tcp, "TCP %p TX %d->%d %08lx..%08lx %08lx %4zd",
|
||||
@ -321,7 +321,7 @@ static int tcp_senddata_conn ( struct tcp_connection *tcp, int force_send ) {
|
||||
DBGC ( tcp, "\n" );
|
||||
|
||||
/* Transmit packet */
|
||||
rc = tcpip_tx ( pkb, &tcp_protocol, &tcp->peer, NULL, &tcphdr->csum );
|
||||
rc = tcpip_tx ( iobuf, &tcp_protocol, &tcp->peer, NULL, &tcphdr->csum );
|
||||
|
||||
/* If we got -ENETUNREACH, kill the connection immediately
|
||||
* because there is no point retrying. This isn't strictly
|
||||
@ -372,22 +372,22 @@ static int tcp_send ( struct stream_connection *stream,
|
||||
const void *data, size_t len ) {
|
||||
struct tcp_connection *tcp =
|
||||
container_of ( stream, struct tcp_connection, stream );
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
/* Check that we have a packet buffer to fill */
|
||||
pkb = tcp->tx_pkb;
|
||||
if ( ! pkb ) {
|
||||
/* Check that we have a I/O buffer to fill */
|
||||
iobuf = tcp->tx_iob;
|
||||
if ( ! iobuf ) {
|
||||
DBGC ( tcp, "TCP %p tried to send data outside of the "
|
||||
"senddata() method\n", tcp );
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Truncate length to fit packet buffer */
|
||||
if ( len > pkb_tailroom ( pkb ) )
|
||||
len = pkb_tailroom ( pkb );
|
||||
/* Truncate length to fit I/O buffer */
|
||||
if ( len > iob_tailroom ( iobuf ) )
|
||||
len = iob_tailroom ( iobuf );
|
||||
|
||||
/* Copy payload */
|
||||
memmove ( pkb_put ( pkb, len ), data, len );
|
||||
memmove ( iob_put ( iobuf, len ), data, len );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -434,19 +434,19 @@ static void tcp_expired ( struct retry_timer *timer, int over ) {
|
||||
*/
|
||||
static int tcp_send_reset ( struct tcp_connection *tcp,
|
||||
struct tcp_header *in_tcphdr ) {
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
struct tcp_header *tcphdr;
|
||||
|
||||
/* Allocate space for dataless TX buffer */
|
||||
pkb = alloc_pkb ( MAX_HDR_LEN );
|
||||
if ( ! pkb ) {
|
||||
iobuf = alloc_iob ( MAX_HDR_LEN );
|
||||
if ( ! iobuf ) {
|
||||
DBGC ( tcp, "TCP %p could not allocate data buffer\n", tcp );
|
||||
return -ENOMEM;
|
||||
}
|
||||
pkb_reserve ( pkb, MAX_HDR_LEN );
|
||||
iob_reserve ( iobuf, MAX_HDR_LEN );
|
||||
|
||||
/* Construct RST response */
|
||||
tcphdr = pkb_push ( pkb, sizeof ( *tcphdr ) );
|
||||
tcphdr = iob_push ( iobuf, sizeof ( *tcphdr ) );
|
||||
memset ( tcphdr, 0, sizeof ( *tcphdr ) );
|
||||
tcphdr->src = in_tcphdr->dest;
|
||||
tcphdr->dest = in_tcphdr->src;
|
||||
@ -455,7 +455,7 @@ static int tcp_send_reset ( struct tcp_connection *tcp,
|
||||
tcphdr->hlen = ( ( sizeof ( *tcphdr ) / 4 ) << 4 );
|
||||
tcphdr->flags = ( TCP_RST | TCP_ACK );
|
||||
tcphdr->win = htons ( TCP_MAX_WINDOW_SIZE );
|
||||
tcphdr->csum = tcpip_chksum ( pkb->data, pkb_len ( pkb ) );
|
||||
tcphdr->csum = tcpip_chksum ( iobuf->data, iob_len ( iobuf ) );
|
||||
|
||||
/* Dump header */
|
||||
DBGC ( tcp, "TCP %p TX %d->%d %08lx..%08lx %08lx %4zd",
|
||||
@ -466,7 +466,7 @@ static int tcp_send_reset ( struct tcp_connection *tcp,
|
||||
DBGC ( tcp, "\n" );
|
||||
|
||||
/* Transmit packet */
|
||||
return tcpip_tx ( pkb, &tcp_protocol, &tcp->peer,
|
||||
return tcpip_tx ( iobuf, &tcp_protocol, &tcp->peer,
|
||||
NULL, &tcphdr->csum );
|
||||
}
|
||||
|
||||
@ -662,17 +662,17 @@ static int tcp_rx_rst ( struct tcp_connection *tcp, uint32_t seq ) {
|
||||
/**
|
||||
* Process received packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v st_src Partially-filled source address
|
||||
* @v st_dest Partially-filled destination address
|
||||
* @v pshdr_csum Pseudo-header checksum
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int tcp_rx ( struct pk_buff *pkb,
|
||||
static int tcp_rx ( struct io_buffer *iobuf,
|
||||
struct sockaddr_tcpip *st_src __unused,
|
||||
struct sockaddr_tcpip *st_dest __unused,
|
||||
uint16_t pshdr_csum ) {
|
||||
struct tcp_header *tcphdr = pkb->data;
|
||||
struct tcp_header *tcphdr = iobuf->data;
|
||||
struct tcp_connection *tcp;
|
||||
unsigned int hlen;
|
||||
uint16_t csum;
|
||||
@ -686,9 +686,9 @@ static int tcp_rx ( struct pk_buff *pkb,
|
||||
int rc;
|
||||
|
||||
/* Sanity check packet */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *tcphdr ) ) {
|
||||
if ( iob_len ( iobuf ) < sizeof ( *tcphdr ) ) {
|
||||
DBG ( "TCP packet too short at %d bytes (min %d bytes)\n",
|
||||
pkb_len ( pkb ), sizeof ( *tcphdr ) );
|
||||
iob_len ( iobuf ), sizeof ( *tcphdr ) );
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
@ -699,13 +699,13 @@ static int tcp_rx ( struct pk_buff *pkb,
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if ( hlen > pkb_len ( pkb ) ) {
|
||||
if ( hlen > iob_len ( iobuf ) ) {
|
||||
DBG ( "TCP header too long at %d bytes (max %d bytes)\n",
|
||||
hlen, pkb_len ( pkb ) );
|
||||
hlen, iob_len ( iobuf ) );
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
csum = tcpip_continue_chksum ( pshdr_csum, pkb->data, pkb_len ( pkb ));
|
||||
csum = tcpip_continue_chksum ( pshdr_csum, iobuf->data, iob_len ( iobuf ));
|
||||
if ( csum != 0 ) {
|
||||
DBG ( "TCP checksum incorrect (is %04x including checksum "
|
||||
"field, should be 0000)\n", csum );
|
||||
@ -719,8 +719,8 @@ static int tcp_rx ( struct pk_buff *pkb,
|
||||
ack = ntohl ( tcphdr->ack );
|
||||
win = ntohs ( tcphdr->win );
|
||||
flags = tcphdr->flags;
|
||||
data = pkb_pull ( pkb, hlen );
|
||||
len = pkb_len ( pkb );
|
||||
data = iob_pull ( iobuf, hlen );
|
||||
len = iob_len ( iobuf );
|
||||
|
||||
/* Dump header */
|
||||
DBGC ( tcp, "TCP %p RX %d<-%d %08lx %08lx..%08lx %4zd",
|
||||
@ -787,7 +787,7 @@ static int tcp_rx ( struct pk_buff *pkb,
|
||||
rc = 0;
|
||||
done:
|
||||
/* Free received packet */
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/tables.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
|
||||
@ -28,7 +28,7 @@ static struct tcpip_protocol tcpip_protocols_end[0]
|
||||
|
||||
/** Process a received TCP/IP packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v tcpip_proto Transport-layer protocol number
|
||||
* @v st_src Partially-filled source address
|
||||
* @v st_dest Partially-filled destination address
|
||||
@ -41,7 +41,7 @@ static struct tcpip_protocol tcpip_protocols_end[0]
|
||||
* address family and the network-layer addresses, but leave the ports
|
||||
* and the rest of the structures as zero).
|
||||
*/
|
||||
int tcpip_rx ( struct pk_buff *pkb, uint8_t tcpip_proto,
|
||||
int tcpip_rx ( struct io_buffer *iobuf, uint8_t tcpip_proto,
|
||||
struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest,
|
||||
uint16_t pshdr_csum ) {
|
||||
@ -51,25 +51,25 @@ int tcpip_rx ( struct pk_buff *pkb, uint8_t tcpip_proto,
|
||||
for ( tcpip = tcpip_protocols; tcpip < tcpip_protocols_end; tcpip++ ) {
|
||||
if ( tcpip->tcpip_proto == tcpip_proto ) {
|
||||
DBG ( "TCP/IP received %s packet\n", tcpip->name );
|
||||
return tcpip->rx ( pkb, st_src, st_dest, pshdr_csum );
|
||||
return tcpip->rx ( iobuf, st_src, st_dest, pshdr_csum );
|
||||
}
|
||||
}
|
||||
|
||||
DBG ( "Unrecognised TCP/IP protocol %d\n", tcpip_proto );
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return -EPROTONOSUPPORT;
|
||||
}
|
||||
|
||||
/** Transmit a TCP/IP packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v tcpip_protocol Transport-layer protocol
|
||||
* @v st_dest Destination address
|
||||
* @v netdev Network device to use if no route found, or NULL
|
||||
* @v trans_csum Transport-layer checksum to complete, or NULL
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip_protocol,
|
||||
int tcpip_tx ( struct io_buffer *iobuf, struct tcpip_protocol *tcpip_protocol,
|
||||
struct sockaddr_tcpip *st_dest, struct net_device *netdev,
|
||||
uint16_t *trans_csum ) {
|
||||
struct tcpip_net_protocol *tcpip_net;
|
||||
@ -79,13 +79,13 @@ int tcpip_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip_protocol,
|
||||
tcpip_net < tcpip_net_protocols_end ; tcpip_net++ ) {
|
||||
if ( tcpip_net->sa_family == st_dest->st_family ) {
|
||||
DBG ( "TCP/IP sending %s packet\n", tcpip_net->name );
|
||||
return tcpip_net->tx ( pkb, tcpip_protocol, st_dest,
|
||||
return tcpip_net->tx ( iobuf, tcpip_protocol, st_dest,
|
||||
netdev, trans_csum );
|
||||
}
|
||||
}
|
||||
|
||||
DBG ( "Unrecognised TCP/IP address family %d\n", st_dest->st_family );
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return -EAFNOSUPPORT;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
#include <byteswap.h>
|
||||
#include <errno.h>
|
||||
#include <gpxe/tcpip.h>
|
||||
#include <gpxe/pkbuff.h>
|
||||
#include <gpxe/iobuf.h>
|
||||
#include <gpxe/netdevice.h>
|
||||
#include <gpxe/udp.h>
|
||||
|
||||
@ -89,22 +89,22 @@ void udp_close ( struct udp_connection *conn ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate packet buffer for UDP
|
||||
* Allocate I/O buffer for UDP
|
||||
*
|
||||
* @v conn UDP connection
|
||||
* @ret pkb Packet buffer, or NULL
|
||||
* @ret iobuf I/O buffer, or NULL
|
||||
*/
|
||||
static struct pk_buff * udp_alloc_pkb ( struct udp_connection *conn ) {
|
||||
struct pk_buff *pkb;
|
||||
static struct io_buffer * udp_alloc_iob ( struct udp_connection *conn ) {
|
||||
struct io_buffer *iobuf;
|
||||
|
||||
pkb = alloc_pkb ( UDP_MAX_TXPKB );
|
||||
if ( ! pkb ) {
|
||||
iobuf = alloc_iob ( UDP_MAX_TXIOB );
|
||||
if ( ! iobuf ) {
|
||||
DBGC ( conn, "UDP %p cannot allocate buffer of length %d\n",
|
||||
conn, UDP_MAX_TXPKB );
|
||||
conn, UDP_MAX_TXIOB );
|
||||
return NULL;
|
||||
}
|
||||
pkb_reserve ( pkb, UDP_MAX_HLEN );
|
||||
return pkb;
|
||||
iob_reserve ( iobuf, UDP_MAX_HLEN );
|
||||
return iobuf;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,20 +119,20 @@ static struct pk_buff * udp_alloc_pkb ( struct udp_connection *conn ) {
|
||||
int udp_senddata ( struct udp_connection *conn ) {
|
||||
int rc;
|
||||
|
||||
conn->tx_pkb = udp_alloc_pkb ( conn );
|
||||
if ( ! conn->tx_pkb )
|
||||
conn->tx_iob = udp_alloc_iob ( conn );
|
||||
if ( ! conn->tx_iob )
|
||||
return -ENOMEM;
|
||||
|
||||
rc = conn->udp_op->senddata ( conn, conn->tx_pkb->data,
|
||||
pkb_tailroom ( conn->tx_pkb ) );
|
||||
rc = conn->udp_op->senddata ( conn, conn->tx_iob->data,
|
||||
iob_tailroom ( conn->tx_iob ) );
|
||||
if ( rc != 0 ) {
|
||||
DBGC ( conn, "UDP %p application could not send packet: %s\n",
|
||||
conn, strerror ( rc ) );
|
||||
}
|
||||
|
||||
if ( conn->tx_pkb ) {
|
||||
free_pkb ( conn->tx_pkb );
|
||||
conn->tx_pkb = NULL;
|
||||
if ( conn->tx_iob ) {
|
||||
free_iob ( conn->tx_iob );
|
||||
conn->tx_iob = NULL;
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -152,25 +152,25 @@ int udp_sendto_via ( struct udp_connection *conn, struct sockaddr_tcpip *peer,
|
||||
struct net_device *netdev, const void *data,
|
||||
size_t len ) {
|
||||
struct udp_header *udphdr;
|
||||
struct pk_buff *pkb;
|
||||
struct io_buffer *iobuf;
|
||||
int rc;
|
||||
|
||||
/* Use precreated packet buffer if one is available */
|
||||
if ( conn->tx_pkb ) {
|
||||
pkb = conn->tx_pkb;
|
||||
conn->tx_pkb = NULL;
|
||||
/* Use precreated I/O buffer if one is available */
|
||||
if ( conn->tx_iob ) {
|
||||
iobuf = conn->tx_iob;
|
||||
conn->tx_iob = NULL;
|
||||
} else {
|
||||
pkb = udp_alloc_pkb ( conn );
|
||||
if ( ! pkb )
|
||||
iobuf = udp_alloc_iob ( conn );
|
||||
if ( ! iobuf )
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Avoid overflowing TX buffer */
|
||||
if ( len > pkb_tailroom ( pkb ) )
|
||||
len = pkb_tailroom ( pkb );
|
||||
if ( len > iob_tailroom ( iobuf ) )
|
||||
len = iob_tailroom ( iobuf );
|
||||
|
||||
/* Copy payload */
|
||||
memmove ( pkb_put ( pkb, len ), data, len );
|
||||
memmove ( iob_put ( iobuf, len ), data, len );
|
||||
|
||||
/*
|
||||
* Add the UDP header
|
||||
@ -178,10 +178,10 @@ int udp_sendto_via ( struct udp_connection *conn, struct sockaddr_tcpip *peer,
|
||||
* Covert all 16- and 32- bit integers into network btye order before
|
||||
* sending it over the network
|
||||
*/
|
||||
udphdr = pkb_push ( pkb, sizeof ( *udphdr ) );
|
||||
udphdr = iob_push ( iobuf, sizeof ( *udphdr ) );
|
||||
udphdr->dest_port = peer->st_port;
|
||||
udphdr->source_port = conn->local_port;
|
||||
udphdr->len = htons ( pkb_len ( pkb ) );
|
||||
udphdr->len = htons ( iob_len ( iobuf ) );
|
||||
udphdr->chksum = 0;
|
||||
udphdr->chksum = tcpip_chksum ( udphdr, sizeof ( *udphdr ) + len );
|
||||
|
||||
@ -191,7 +191,7 @@ int udp_sendto_via ( struct udp_connection *conn, struct sockaddr_tcpip *peer,
|
||||
ntohs ( udphdr->len ) );
|
||||
|
||||
/* Send it to the next layer for processing */
|
||||
if ( ( rc = tcpip_tx ( pkb, &udp_protocol, peer, netdev,
|
||||
if ( ( rc = tcpip_tx ( iobuf, &udp_protocol, peer, netdev,
|
||||
&udphdr->chksum ) ) != 0 ) {
|
||||
DBGC ( conn, "UDP %p could not transmit packet: %s\n",
|
||||
conn, strerror ( rc ) );
|
||||
@ -248,24 +248,24 @@ static struct udp_connection * udp_demux ( uint16_t local_port ) {
|
||||
/**
|
||||
* Process a received packet
|
||||
*
|
||||
* @v pkb Packet buffer
|
||||
* @v iobuf I/O buffer
|
||||
* @v st_src Partially-filled source address
|
||||
* @v st_dest Partially-filled destination address
|
||||
* @v pshdr_csum Pseudo-header checksum
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int udp_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
static int udp_rx ( struct io_buffer *iobuf, struct sockaddr_tcpip *st_src,
|
||||
struct sockaddr_tcpip *st_dest, uint16_t pshdr_csum ) {
|
||||
struct udp_header *udphdr = pkb->data;
|
||||
struct udp_header *udphdr = iobuf->data;
|
||||
struct udp_connection *conn;
|
||||
size_t ulen;
|
||||
uint16_t csum;
|
||||
int rc = 0;
|
||||
|
||||
/* Sanity check packet */
|
||||
if ( pkb_len ( pkb ) < sizeof ( *udphdr ) ) {
|
||||
if ( iob_len ( iobuf ) < sizeof ( *udphdr ) ) {
|
||||
DBG ( "UDP packet too short at %d bytes (min %d bytes)\n",
|
||||
pkb_len ( pkb ), sizeof ( *udphdr ) );
|
||||
iob_len ( iobuf ), sizeof ( *udphdr ) );
|
||||
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
@ -277,14 +277,14 @@ static int udp_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if ( ulen > pkb_len ( pkb ) ) {
|
||||
if ( ulen > iob_len ( iobuf ) ) {
|
||||
DBG ( "UDP length too long at %d bytes (packet is %d bytes)\n",
|
||||
ulen, pkb_len ( pkb ) );
|
||||
ulen, iob_len ( iobuf ) );
|
||||
rc = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
if ( udphdr->chksum ) {
|
||||
csum = tcpip_continue_chksum ( pshdr_csum, pkb->data, ulen );
|
||||
csum = tcpip_continue_chksum ( pshdr_csum, iobuf->data, ulen );
|
||||
if ( csum != 0 ) {
|
||||
DBG ( "UDP checksum incorrect (is %04x including "
|
||||
"checksum field, should be 0000)\n", csum );
|
||||
@ -297,8 +297,8 @@ static int udp_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
st_src->st_port = udphdr->source_port;
|
||||
st_dest->st_port = udphdr->dest_port;
|
||||
conn = udp_demux ( udphdr->dest_port );
|
||||
pkb_unput ( pkb, ( pkb_len ( pkb ) - ulen ) );
|
||||
pkb_pull ( pkb, sizeof ( *udphdr ) );
|
||||
iob_unput ( iobuf, ( iob_len ( iobuf ) - ulen ) );
|
||||
iob_pull ( iobuf, sizeof ( *udphdr ) );
|
||||
|
||||
/* Dump debugging information */
|
||||
DBGC ( conn, "UDP %p RX %d<-%d len %zd\n", conn,
|
||||
@ -315,7 +315,7 @@ static int udp_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
|
||||
/* Pass data to application */
|
||||
if ( conn->udp_op->newdata ) {
|
||||
rc = conn->udp_op->newdata ( conn, pkb->data, pkb_len ( pkb ),
|
||||
rc = conn->udp_op->newdata ( conn, iobuf->data, iob_len ( iobuf ),
|
||||
st_src, st_dest );
|
||||
if ( rc != 0 ) {
|
||||
DBGC ( conn, "UDP %p application rejected packet: %s\n",
|
||||
@ -327,7 +327,7 @@ static int udp_rx ( struct pk_buff *pkb, struct sockaddr_tcpip *st_src,
|
||||
}
|
||||
|
||||
done:
|
||||
free_pkb ( pkb );
|
||||
free_iob ( iobuf );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user