david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[efi] Provide guaranteed space in transmitted packets

eIPoIB requires space to expand a transmitted ARP packet.  This
guarantee is met by ensuring that a transmitted packet consists of at
least MAX_LL_HEADER_LEN bytes from the start of the I/O buffer up to
the end of the link-layer header, and at least IOB_ZLEN bytes
thereafter.

Adjust the I/O buffer allocation for SNP transmitted packets to ensure
that this guarantee is met.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2012-09-14 17:49:53 +01:00
parent 73eb3f17db
commit 09cc63fc8b
1 changed files with 7 additions and 6 deletions

View File

@ -536,7 +536,7 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
container_of ( snp, struct efi_snp_device, snp ); container_of ( snp, struct efi_snp_device, snp );
struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol; struct ll_protocol *ll_protocol = snpdev->netdev->ll_protocol;
struct io_buffer *iobuf; struct io_buffer *iobuf;
size_t ll_headroom; size_t payload_len;
int rc; int rc;
EFI_STATUS efirc; EFI_STATUS efirc;
@ -589,21 +589,22 @@ efi_snp_transmit ( EFI_SIMPLE_NETWORK_PROTOCOL *snp,
} }
/* Allocate buffer */ /* Allocate buffer */
ll_headroom = ( MAX_LL_HEADER_LEN - ll_header_len ); payload_len = ( len - ll_protocol->ll_header_len );
iobuf = alloc_iob ( ll_headroom + iobuf = alloc_iob ( MAX_LL_HEADER_LEN + ( ( payload_len > IOB_ZLEN ) ?
( ( len > IOB_ZLEN ) ? len : IOB_ZLEN ) ); payload_len : IOB_ZLEN ) );
if ( ! iobuf ) { if ( ! iobuf ) {
DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte " DBGC ( snpdev, "SNPDEV %p TX could not allocate %ld-byte "
"buffer\n", snpdev, ( ( unsigned long ) len ) ); "buffer\n", snpdev, ( ( unsigned long ) len ) );
efirc = EFI_DEVICE_ERROR; efirc = EFI_DEVICE_ERROR;
goto err_alloc_iob; goto err_alloc_iob;
} }
iob_reserve ( iobuf, ll_headroom ); iob_reserve ( iobuf, ( MAX_LL_HEADER_LEN -
ll_protocol->ll_header_len ) );
memcpy ( iob_put ( iobuf, len ), data, len ); memcpy ( iob_put ( iobuf, len ), data, len );
/* Create link-layer header, if specified */ /* Create link-layer header, if specified */
if ( ll_header_len ) { if ( ll_header_len ) {
iob_pull ( iobuf, ll_header_len ); iob_pull ( iobuf, ll_protocol->ll_header_len );
if ( ( rc = ll_protocol->push ( snpdev->netdev, if ( ( rc = ll_protocol->push ( snpdev->netdev,
iobuf, ll_dest, ll_src, iobuf, ll_dest, ll_src,
htons ( *net_proto ) )) != 0 ){ htons ( *net_proto ) )) != 0 ){