-
Notifications
You must be signed in to change notification settings - Fork 671
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[pxe] Always retrieve cached DHCPACK and apply to relevant network de…
…vice When chainloading, always retrieve the cached DHCPACK packet from the underlying PXE stack, and apply it as the original contents of the "net<X>.dhcp" settings block. This allows cached DHCP settings to be used for any chainloaded iPXE binary (not just undionly.kkpxe). This change eliminates the undocumented "use-cached" setting. Issuing the "dhcp" command will now always result in a fresh DHCP request. Signed-off-by: Michael Brown <mcb30@ipxe.org>
- Loading branch information
Showing
7 changed files
with
239 additions
and
198 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
/* | ||
* Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License as | ||
* published by the Free Software Foundation; either version 2 of the | ||
* License, or any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
* 02110-1301, USA. | ||
*/ | ||
|
||
FILE_LICENCE ( GPL2_OR_LATER ); | ||
|
||
#include <stdint.h> | ||
#include <stdlib.h> | ||
#include <ipxe/dhcppkt.h> | ||
#include <ipxe/init.h> | ||
#include <ipxe/netdevice.h> | ||
#include <realmode.h> | ||
#include <pxe_api.h> | ||
|
||
/** @file | ||
* | ||
* Cached DHCP packet | ||
* | ||
*/ | ||
|
||
/** Cached DHCPACK physical address | ||
* | ||
* This can be set by the prefix. | ||
*/ | ||
uint32_t __bss16 ( cached_dhcpack_phys ); | ||
#define cached_dhcpack_phys __use_data16 ( cached_dhcpack_phys ) | ||
|
||
/** Colour for debug messages */ | ||
#define colour &cached_dhcpack_phys | ||
|
||
/** Cached DHCPACK */ | ||
static struct dhcp_packet *cached_dhcpack; | ||
|
||
/** | ||
* Cached DHCPACK startup function | ||
* | ||
*/ | ||
static void cachedhcp_startup ( void ) { | ||
struct dhcp_packet *dhcppkt; | ||
struct dhcp_packet *tmp; | ||
struct dhcphdr *dhcphdr; | ||
size_t len; | ||
|
||
/* Do nothing if no cached DHCPACK is present */ | ||
if ( ! cached_dhcpack_phys ) { | ||
DBGC ( colour, "CACHEDHCP found no cached DHCPACK\n" ); | ||
return; | ||
} | ||
|
||
/* No reliable way to determine length before parsing packet; | ||
* start by assuming maximum length permitted by PXE. | ||
*/ | ||
len = sizeof ( BOOTPLAYER_t ); | ||
|
||
/* Allocate and populate DHCP packet */ | ||
dhcppkt = zalloc ( sizeof ( *dhcppkt ) + len ); | ||
if ( ! dhcppkt ) { | ||
DBGC ( colour, "CACHEDHCP could not allocate copy\n" ); | ||
return; | ||
} | ||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) ); | ||
copy_from_user ( dhcphdr, phys_to_user ( cached_dhcpack_phys ), 0, | ||
len ); | ||
dhcppkt_init ( dhcppkt, dhcphdr, len ); | ||
|
||
/* Resize packet to required length. If reallocation fails, | ||
* just continue to use the original packet. | ||
*/ | ||
len = dhcppkt_len ( dhcppkt ); | ||
tmp = realloc ( dhcppkt, ( sizeof ( *dhcppkt ) + len ) ); | ||
if ( tmp ) | ||
dhcppkt = tmp; | ||
|
||
/* Reinitialise packet at new address */ | ||
dhcphdr = ( ( ( void * ) dhcppkt ) + sizeof ( *dhcppkt ) ); | ||
dhcppkt_init ( dhcppkt, dhcphdr, len ); | ||
|
||
/* Store as cached DHCPACK, and mark original copy as consumed */ | ||
DBGC ( colour, "CACHEDHCP found cached DHCPACK at %08x+%zx\n", | ||
cached_dhcpack_phys, len ); | ||
cached_dhcpack = dhcppkt; | ||
cached_dhcpack_phys = 0; | ||
} | ||
|
||
/** | ||
* Cached DHCPACK shutdown function | ||
* | ||
* @v booting Shutting down in order to boot | ||
*/ | ||
static void cachedhcp_shutdown ( int booting __unused ) { | ||
|
||
/* If cached DHCP packet has not yet been claimed, free it */ | ||
if ( cached_dhcpack ) { | ||
DBGC ( colour, "CACHEDHCP freeing unclaimed cached DHCPACK\n" ); | ||
dhcppkt_put ( cached_dhcpack ); | ||
cached_dhcpack = NULL; | ||
} | ||
} | ||
|
||
/** Cached DHCPACK initialisation function */ | ||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_NORMAL ) = { | ||
.startup = cachedhcp_startup, | ||
.shutdown = cachedhcp_shutdown, | ||
}; | ||
|
||
/** | ||
* Apply cached DHCPACK to network device, if applicable | ||
* | ||
* @v netdev Network device | ||
* @ret rc Return status code | ||
*/ | ||
static int cachedhcp_probe ( struct net_device *netdev ) { | ||
struct ll_protocol *ll_protocol = netdev->ll_protocol; | ||
int rc; | ||
|
||
/* Do nothing unless we have a cached DHCPACK */ | ||
if ( ! cached_dhcpack ) | ||
return 0; | ||
|
||
/* Do nothing unless cached DHCPACK's MAC address matches this | ||
* network device. | ||
*/ | ||
if ( memcmp ( netdev->ll_addr, cached_dhcpack->dhcphdr->chaddr, | ||
ll_protocol->ll_addr_len ) != 0 ) { | ||
DBGC ( colour, "CACHEDHCP cached DHCPACK does not match %s\n", | ||
netdev->name ); | ||
return 0; | ||
} | ||
DBGC ( colour, "CACHEDHCP cached DHCPACK is for %s\n", netdev->name ); | ||
|
||
/* Register as DHCP settings for this network device */ | ||
if ( ( rc = register_settings ( &cached_dhcpack->settings, | ||
netdev_settings ( netdev ), | ||
DHCP_SETTINGS_NAME ) ) != 0 ) { | ||
DBGC ( colour, "CACHEDHCP could not register settings: %s\n", | ||
strerror ( rc ) ); | ||
return rc; | ||
} | ||
|
||
/* Claim cached DHCPACK */ | ||
dhcppkt_put ( cached_dhcpack ); | ||
cached_dhcpack = NULL; | ||
|
||
return 0; | ||
} | ||
|
||
/** | ||
* Handle network device link state change | ||
* | ||
* @v netdev Network device | ||
*/ | ||
static void cachedhcp_notify ( struct net_device *netdev __unused ) { | ||
|
||
/* Nothing to do */ | ||
} | ||
|
||
/** | ||
* Handle network device removal | ||
* | ||
* @v netdev Network device | ||
*/ | ||
static void cachedhcp_remove ( struct net_device *netdev __unused ) { | ||
|
||
/* Nothing to do */ | ||
} | ||
|
||
/** Cached DHCP packet network device driver */ | ||
struct net_driver cachedhcp_driver __net_driver = { | ||
.name = "cachedhcp", | ||
.probe = cachedhcp_probe, | ||
.notify = cachedhcp_notify, | ||
.remove = cachedhcp_remove, | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.