mirror of https://github.com/ipxe/ipxe.git
[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.pull/1/head
parent
96edbd128f
commit
83617e5b1c
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|
Loading…
Reference in New Issue