david/ipxe
Archived
1
0

[DHCP] Save precious packet-aligned memory by copying DHCP responses

Copy DHCP responses to a standard malloc()ed buffer, rather than
retaining the I/O buffer that they arrived in.
This commit is contained in:
Michael Brown 2008-03-26 12:25:59 +00:00
parent 96edbd128f
commit 83617e5b1c

View File

@ -342,27 +342,12 @@ int create_dhcp_request ( struct dhcp_packet *dhcppkt,
struct dhcp_settings { struct dhcp_settings {
/** Reference counter */ /** Reference counter */
struct refcnt refcnt; struct refcnt refcnt;
/** Containing I/O buffer */
struct io_buffer *iobuf;
/** DHCP packet */ /** DHCP packet */
struct dhcp_packet dhcppkt; struct dhcp_packet dhcppkt;
/** Setting interface */ /** Setting interface */
struct settings settings; struct settings settings;
}; };
/**
* Free DHCP settings block
*
* @v refcnt Reference counter
*/
static void dhcpset_free ( struct refcnt *refcnt ) {
struct dhcp_settings *dhcpset =
container_of ( refcnt, struct dhcp_settings, refcnt );
free_iob ( dhcpset->iobuf );
free ( dhcpset );
}
/** /**
* Decrement reference count on DHCP settings block * Decrement reference count on DHCP settings block
* *
@ -413,23 +398,22 @@ static struct settings_operations dhcpset_settings_operations = {
}; };
/** /**
* Create DHCP setting block from I/O buffer * Create DHCP setting block
* *
* @v iobuf I/O buffer * @v dhcphdr DHCP packet
* @v len Length of DHCP packet
* @ret dhcpset DHCP settings block * @ret dhcpset DHCP settings block
*
* This function takes ownership of the I/O buffer. Future accesses
* must be via the @c dhcpset data structure.
*/ */
static struct dhcp_settings * dhcpset_create_iob ( struct io_buffer *iobuf ) { static struct dhcp_settings * dhcpset_create ( const struct dhcphdr *dhcphdr,
size_t len ) {
struct dhcp_settings *dhcpset; struct dhcp_settings *dhcpset;
void *data;
dhcpset = zalloc ( sizeof ( *dhcpset ) ); dhcpset = zalloc ( sizeof ( *dhcpset ) + len );
if ( dhcpset ) { if ( dhcpset ) {
dhcpset->refcnt.free = dhcpset_free; data = ( ( ( void * ) dhcpset ) + sizeof ( *dhcpset ) );
dhcpset->iobuf = iobuf; memcpy ( data, dhcphdr, len );
dhcppkt_init ( &dhcpset->dhcppkt, dhcppkt_init ( &dhcpset->dhcppkt, data, len );
iobuf->data, iob_len ( iobuf ) );
settings_init ( &dhcpset->settings, settings_init ( &dhcpset->settings,
&dhcpset_settings_operations, &dhcpset->refcnt, &dhcpset_settings_operations, &dhcpset->refcnt,
DHCP_SETTINGS_NAME ); DHCP_SETTINGS_NAME );
@ -632,9 +616,8 @@ static void dhcp_timer_expired ( struct retry_timer *timer, int fail ) {
* @v len Length of received data * @v len Length of received data
* @ret rc Return status code * @ret rc Return status code
*/ */
static int dhcp_deliver_iob ( struct xfer_interface *xfer, static int dhcp_deliver_raw ( struct xfer_interface *xfer,
struct io_buffer *iobuf, const void *data, size_t len ) {
struct xfer_metadata *meta __unused ) {
struct dhcp_session *dhcp = struct dhcp_session *dhcp =
container_of ( xfer, struct dhcp_session, xfer ); container_of ( xfer, struct dhcp_session, xfer );
struct dhcp_settings *response; struct dhcp_settings *response;
@ -648,8 +631,8 @@ static int dhcp_deliver_iob ( struct xfer_interface *xfer,
uint8_t ignore_proxy = 0; uint8_t ignore_proxy = 0;
int rc; int rc;
/* Convert packet into a DHCP-packet-in-iobuf */ /* Convert packet into a DHCP settings block */
response = dhcpset_create_iob ( iobuf ); response = dhcpset_create ( data, len );
if ( ! response ) { if ( ! response ) {
DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp ); DBGC ( dhcp, "DHCP %p could not store DHCP packet\n", dhcp );
return -ENOMEM; return -ENOMEM;
@ -748,8 +731,8 @@ static struct xfer_interface_operations dhcp_xfer_operations = {
.vredirect = xfer_vopen, .vredirect = xfer_vopen,
.window = unlimited_xfer_window, .window = unlimited_xfer_window,
.alloc_iob = default_xfer_alloc_iob, .alloc_iob = default_xfer_alloc_iob,
.deliver_iob = dhcp_deliver_iob, .deliver_iob = xfer_deliver_as_raw,
.deliver_raw = xfer_deliver_as_iob, .deliver_raw = dhcp_deliver_raw,
}; };
/**************************************************************************** /****************************************************************************