mirror of
https://github.com/ipxe/ipxe
synced 2025-12-27 01:52:39 +03:00
[cachedhcp] Include VLAN tag in filter for applying cached DHCPACK
When chainloading iPXE from a VLAN device, the MAC address within the cached DHCPACK will match the MAC address of the trunk device created by iPXE, and the cached DHCPACK will then end up being erroneously applied to the trunk device. This tends to break outbound IPv4 routing, since both the trunk and VLAN devices will have the same assigned IPv4 address. Fix by recording the VLAN tag along with the cached DHCPACK, and treating the VLAN tag as part of the filter used to match the cached DHCPACK against candidate network devices. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
@@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <errno.h>
|
||||
#include <ipxe/cachedhcp.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/efi_path.h>
|
||||
#include <ipxe/efi/efi_cachedhcp.h>
|
||||
#include <ipxe/efi/Protocol/PxeBaseCode.h>
|
||||
|
||||
@@ -40,10 +41,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
* Record cached DHCP packet
|
||||
*
|
||||
* @v device Device handle
|
||||
* @v path Device path
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
int efi_cachedhcp_record ( EFI_HANDLE device,
|
||||
EFI_DEVICE_PATH_PROTOCOL *path ) {
|
||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
unsigned int vlan;
|
||||
union {
|
||||
EFI_PXE_BASE_CODE_PROTOCOL *pxe;
|
||||
void *interface;
|
||||
@@ -52,6 +56,9 @@ int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
||||
/* Get VLAN tag, if any */
|
||||
vlan = efi_path_vlan ( path );
|
||||
|
||||
/* Look for a PXE base code instance on the image's device handle */
|
||||
if ( ( efirc = bs->OpenProtocol ( device,
|
||||
&efi_pxe_base_code_protocol_guid,
|
||||
@@ -75,7 +82,7 @@ int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
|
||||
/* Record DHCPACK, if present */
|
||||
if ( mode->DhcpAckReceived &&
|
||||
( ( rc = cachedhcp_record ( &cached_dhcpack,
|
||||
( ( rc = cachedhcp_record ( &cached_dhcpack, vlan,
|
||||
virt_to_user ( &mode->DhcpAck ),
|
||||
sizeof ( mode->DhcpAck ) ) ) != 0 ) ) {
|
||||
DBGC ( device, "EFI %s could not record DHCPACK: %s\n",
|
||||
@@ -85,7 +92,7 @@ int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
|
||||
/* Record ProxyDHCPOFFER, if present */
|
||||
if ( mode->ProxyOfferReceived &&
|
||||
( ( rc = cachedhcp_record ( &cached_proxydhcp,
|
||||
( ( rc = cachedhcp_record ( &cached_proxydhcp, vlan,
|
||||
virt_to_user ( &mode->ProxyOffer ),
|
||||
sizeof ( mode->ProxyOffer ) ) ) != 0)){
|
||||
DBGC ( device, "EFI %s could not record ProxyDHCPOFFER: %s\n",
|
||||
@@ -95,7 +102,7 @@ int efi_cachedhcp_record ( EFI_HANDLE device ) {
|
||||
|
||||
/* Record PxeBSACK, if present */
|
||||
if ( mode->PxeReplyReceived &&
|
||||
( ( rc = cachedhcp_record ( &cached_pxebs,
|
||||
( ( rc = cachedhcp_record ( &cached_pxebs, vlan,
|
||||
virt_to_user ( &mode->PxeReply ),
|
||||
sizeof ( mode->PxeReply ) ) ) != 0)){
|
||||
DBGC ( device, "EFI %s could not record PXEBSACK: %s\n",
|
||||
|
||||
@@ -78,12 +78,13 @@ EFI_STATUS EFIAPI _efi_start ( EFI_HANDLE image_handle,
|
||||
*/
|
||||
static void efi_init_application ( void ) {
|
||||
EFI_HANDLE device = efi_loaded_image->DeviceHandle;
|
||||
EFI_DEVICE_PATH_PROTOCOL *path = efi_loaded_image_path;
|
||||
|
||||
/* Identify autoboot device, if any */
|
||||
efi_set_autoboot_ll_addr ( device );
|
||||
|
||||
/* Store cached DHCP packet, if any */
|
||||
efi_cachedhcp_record ( device );
|
||||
efi_cachedhcp_record ( device, path );
|
||||
|
||||
/* Load autoexec script, if any */
|
||||
efi_autoexec_load ( device );
|
||||
|
||||
Reference in New Issue
Block a user