mirror of
https://github.com/ipxe/ipxe
synced 2025-12-21 12:30:20 +03:00
[cachedhcp] Allow cached DHCPACK to apply to temporary network devices
Retain a reference to the cached DHCPACK until the late startup phase, and allow it to be recycled for reuse. This allows the cached DHCPACK to be used for a temporary MNP network device and then subsequently reused for the corresponding real network device. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -46,11 +46,20 @@ struct cached_dhcp_packet {
|
|||||||
struct dhcp_packet *dhcppkt;
|
struct dhcp_packet *dhcppkt;
|
||||||
/** VLAN tag (if applicable) */
|
/** VLAN tag (if applicable) */
|
||||||
unsigned int vlan;
|
unsigned int vlan;
|
||||||
|
/** Flags */
|
||||||
|
unsigned int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** Cached DHCP packet should be retained */
|
||||||
|
#define CACHEDHCP_RETAIN 0x0001
|
||||||
|
|
||||||
|
/** Cached DHCP packet has been used */
|
||||||
|
#define CACHEDHCP_USED 0x0002
|
||||||
|
|
||||||
/** Cached DHCPACK */
|
/** Cached DHCPACK */
|
||||||
struct cached_dhcp_packet cached_dhcpack = {
|
struct cached_dhcp_packet cached_dhcpack = {
|
||||||
.name = DHCP_SETTINGS_NAME,
|
.name = DHCP_SETTINGS_NAME,
|
||||||
|
.flags = CACHEDHCP_RETAIN,
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Cached ProxyDHCPOFFER */
|
/** Cached ProxyDHCPOFFER */
|
||||||
@@ -101,8 +110,8 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
|
|||||||
size_t ll_addr_len;
|
size_t ll_addr_len;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* Do nothing if cache is empty */
|
/* Do nothing if cache is empty or already in use */
|
||||||
if ( ! cache->dhcppkt )
|
if ( ( ! cache->dhcppkt ) || ( cache->flags & CACHEDHCP_USED ) )
|
||||||
return 0;
|
return 0;
|
||||||
chaddr = cache->dhcppkt->dhcphdr->chaddr;
|
chaddr = cache->dhcppkt->dhcphdr->chaddr;
|
||||||
|
|
||||||
@@ -169,7 +178,11 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free cached DHCP packet */
|
/* Mark as used */
|
||||||
|
cache->flags |= CACHEDHCP_USED;
|
||||||
|
|
||||||
|
/* Free cached DHCP packet, if applicable */
|
||||||
|
if ( ! ( cache->flags & CACHEDHCP_RETAIN ) )
|
||||||
cachedhcp_free ( cache );
|
cachedhcp_free ( cache );
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -246,10 +259,10 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cached DHCP packet startup function
|
* Cached DHCP packet early startup function
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static void cachedhcp_startup ( void ) {
|
static void cachedhcp_startup_early ( void ) {
|
||||||
|
|
||||||
/* Apply cached ProxyDHCPOFFER, if any */
|
/* Apply cached ProxyDHCPOFFER, if any */
|
||||||
cachedhcp_apply ( &cached_proxydhcp, NULL );
|
cachedhcp_apply ( &cached_proxydhcp, NULL );
|
||||||
@@ -258,6 +271,20 @@ static void cachedhcp_startup ( void ) {
|
|||||||
/* Apply cached PXEBSACK, if any */
|
/* Apply cached PXEBSACK, if any */
|
||||||
cachedhcp_apply ( &cached_pxebs, NULL );
|
cachedhcp_apply ( &cached_pxebs, NULL );
|
||||||
cachedhcp_free ( &cached_pxebs );
|
cachedhcp_free ( &cached_pxebs );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cache DHCP packet late startup function
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void cachedhcp_startup_late ( void ) {
|
||||||
|
|
||||||
|
/* Clear retention flag */
|
||||||
|
cached_dhcpack.flags &= ~CACHEDHCP_RETAIN;
|
||||||
|
|
||||||
|
/* Free cached DHCPACK, if used by a network device */
|
||||||
|
if ( cached_dhcpack.flags & CACHEDHCP_USED )
|
||||||
|
cachedhcp_free ( &cached_dhcpack );
|
||||||
|
|
||||||
/* Report unclaimed DHCPACK, if any. Do not free yet, since
|
/* Report unclaimed DHCPACK, if any. Do not free yet, since
|
||||||
* it may still be claimed by a dynamically created device
|
* it may still be claimed by a dynamically created device
|
||||||
@@ -284,10 +311,16 @@ static void cachedhcp_shutdown ( int booting __unused ) {
|
|||||||
cachedhcp_free ( &cached_dhcpack );
|
cachedhcp_free ( &cached_dhcpack );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Cached DHCPACK startup function */
|
/** Cached DHCP packet early startup function */
|
||||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
|
struct startup_fn cachedhcp_early_fn __startup_fn ( STARTUP_EARLY ) = {
|
||||||
.name = "cachedhcp",
|
.name = "cachedhcp1",
|
||||||
.startup = cachedhcp_startup,
|
.startup = cachedhcp_startup_early,
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Cached DHCP packet late startup function */
|
||||||
|
struct startup_fn cachedhcp_late_fn __startup_fn ( STARTUP_LATE ) = {
|
||||||
|
.name = "cachedhcp2",
|
||||||
|
.startup = cachedhcp_startup_late,
|
||||||
.shutdown = cachedhcp_shutdown,
|
.shutdown = cachedhcp_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -309,3 +342,25 @@ struct net_driver cachedhcp_driver __net_driver = {
|
|||||||
.name = "cachedhcp",
|
.name = "cachedhcp",
|
||||||
.probe = cachedhcp_probe,
|
.probe = cachedhcp_probe,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recycle cached DHCPACK
|
||||||
|
*
|
||||||
|
* @v netdev Network device
|
||||||
|
* @v priv Private data
|
||||||
|
*/
|
||||||
|
void cachedhcp_recycle ( struct net_device *netdev ) {
|
||||||
|
struct cached_dhcp_packet *cache = &cached_dhcpack;
|
||||||
|
struct settings *settings;
|
||||||
|
|
||||||
|
/* Return DHCPACK to cache, if applicable */
|
||||||
|
settings = find_child_settings ( netdev_settings ( netdev ),
|
||||||
|
cache->name );
|
||||||
|
if ( cache->dhcppkt && ( settings == &cache->dhcppkt->settings ) ) {
|
||||||
|
DBGC ( colour, "CACHEDHCP %s recycled from %s\n",
|
||||||
|
cache->name, netdev->name );
|
||||||
|
assert ( cache->flags & CACHEDHCP_USED );
|
||||||
|
unregister_settings ( settings );
|
||||||
|
cache->flags &= ~CACHEDHCP_USED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <ipxe/iobuf.h>
|
#include <ipxe/iobuf.h>
|
||||||
#include <ipxe/netdevice.h>
|
#include <ipxe/netdevice.h>
|
||||||
#include <ipxe/ethernet.h>
|
#include <ipxe/ethernet.h>
|
||||||
|
#include <ipxe/cachedhcp.h>
|
||||||
#include <ipxe/efi/efi.h>
|
#include <ipxe/efi/efi.h>
|
||||||
#include <ipxe/efi/efi_driver.h>
|
#include <ipxe/efi/efi_driver.h>
|
||||||
#include <ipxe/efi/efi_service.h>
|
#include <ipxe/efi/efi_service.h>
|
||||||
@@ -551,6 +552,9 @@ void mnptemp_destroy ( struct net_device *netdev ) {
|
|||||||
struct mnp_nic *mnp = netdev->priv;
|
struct mnp_nic *mnp = netdev->priv;
|
||||||
struct efi_device *efidev = mnp->efidev;
|
struct efi_device *efidev = mnp->efidev;
|
||||||
|
|
||||||
|
/* Recycle any cached DHCP packet */
|
||||||
|
cachedhcp_recycle ( netdev );
|
||||||
|
|
||||||
/* Stop temporary network device */
|
/* Stop temporary network device */
|
||||||
mnpnet_stop ( efidev );
|
mnpnet_stop ( efidev );
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <ipxe/uaccess.h>
|
#include <ipxe/uaccess.h>
|
||||||
|
|
||||||
|
struct net_device;
|
||||||
struct cached_dhcp_packet;
|
struct cached_dhcp_packet;
|
||||||
|
|
||||||
extern struct cached_dhcp_packet cached_dhcpack;
|
extern struct cached_dhcp_packet cached_dhcpack;
|
||||||
@@ -21,5 +22,6 @@ extern struct cached_dhcp_packet cached_pxebs;
|
|||||||
extern int cachedhcp_record ( struct cached_dhcp_packet *cache,
|
extern int cachedhcp_record ( struct cached_dhcp_packet *cache,
|
||||||
unsigned int vlan, userptr_t data,
|
unsigned int vlan, userptr_t data,
|
||||||
size_t max_len );
|
size_t max_len );
|
||||||
|
extern void cachedhcp_recycle ( struct net_device *netdev );
|
||||||
|
|
||||||
#endif /* _IPXE_CACHEDHCP_H */
|
#endif /* _IPXE_CACHEDHCP_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user