david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

Autopadding was sometimes overwriting the struct list_head at the end

of the packet buffer.  Although pkbuffs are guaranteed to be at least
PKB_ZLEN bytes long, there's no guarantee that the data starts at the
start of the packet buffer.

Since we have to align data for rtl8139 anyway, and since the start of
the packet buffer is guaranteed to be aligned to PKB_ALIGN, we may as
well just shuffle the packet down so that it starts at the start of
the packet buffer.  This simultaneously aligns the packet and ensures
that there is enough room for the zero-padding.
This commit is contained in:
Michael Brown 2007-01-09 21:01:55 +00:00
parent 18e5353bed
commit e822bc2a90
1 changed files with 16 additions and 7 deletions

View File

@ -367,8 +367,10 @@ static void rtl_close ( struct net_device *netdev ) {
*/
static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
struct rtl8139_nic *rtl = netdev->priv;
int align;
int pad_len;
void *data;
size_t len;
size_t headroom;
signed int pad_len;
/* Check for space in TX ring */
if ( rtl->tx.pkb[rtl->tx.next] != NULL ) {
@ -376,11 +378,18 @@ static int rtl_transmit ( struct net_device *netdev, struct pk_buff *pkb ) {
return -ENOBUFS;
}
/* Align packet data */
align = ( virt_to_bus ( pkb->data ) & 0x3 );
pkb_push ( pkb, align );
memmove ( pkb->data, pkb->data + align, pkb_len ( pkb ) - align );
pkb_unput ( pkb, align );
/* 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
* 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 );
assert ( ( virt_to_bus ( pkb->data ) & 0x3 ) == 0 );
/* Pad to minimum packet length */
pad_len = ( ETH_ZLEN - pkb_len ( pkb ) );