From 05c0e3cb8ad921c94ef51fc972e117baa32ce82f Mon Sep 17 00:00:00 2001 From: vanjeff Date: Fri, 19 Sep 2008 07:12:23 +0000 Subject: [PATCH] 1. Sync Bug:PXE Boot issue- UefiPxeBc driver currently does not follow PXE Spec [Root Cause Analysis] The PXE offer selection in the PXE driver is splitted into two passes and the two passes are required to follow the same flow. However, in current code, there is some difference between the two. [Solution] make the second offer selection pass exactly match the first one. 2. Fixed one bug when allocating pool for UDP transmit packet. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@5932 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Network/UefiPxeBcDxe/PxeBcDhcp.c | 118 +++++++++--------- .../Network/UefiPxeBcDxe/PxeBcImpl.c | 7 +- .../Network/UefiPxeBcDxe/PxeBcImpl.h | 7 +- 3 files changed, 69 insertions(+), 63 deletions(-) diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c index c70390ab2e..eb91307944 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcDhcp.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2007, Intel Corporation +Copyright (c) 2007 - 2008, Intel Corporation All rights reserved. This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -401,72 +401,84 @@ PxeBcCheckSelectedOffer ( if (!PxeBcTryBinl (Private, Private->SelectedOffer - 1)) { Status = EFI_NO_RESPONSE; } - } else if ((SelectedOffer->OfferType == DHCP4_PACKET_TYPE_DHCP_ONLY) && - (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL)) { + } else if (SelectedOffer->OfferType == DHCP4_PACKET_TYPE_DHCP_ONLY) { // - // The selected offer to finish the D.O.R.A. is a DHCP only offer and - // bootfile name is not provided in this offer, we need try proxy offers - // to get the bootfile name or the discovery info + // The selected offer to finish the D.O.R.A. is a DHCP only offer, we need + // try proxy offers if there are some, othewise the bootfile name must be + // set in this DHCP only offer. // - ProxyOfferIndex = Private->NumOffers; - - if (Private->SortOffers) { + if (Private->GotProxyOffer) { // - // Choose proxy offer from the type we stored during DHCP offer selection + // Get rid of the compiler warning. // - ASSERT (Private->ProxyIndex[Private->ProxyOfferType] > 0); - - if (Private->ProxyOfferType == DHCP4_PACKET_TYPE_BINL) { + ProxyOfferIndex = 0; + if (Private->SortOffers) { // - // We buffer all received BINL proxy offers, try them all one by one + // The offers are sorted before selecting, the proxy offer type must be + // already determined. // - if (!PxeBcTryBinlProxy (Private, &ProxyOfferIndex)) { - Status = EFI_NO_RESPONSE; + ASSERT (Private->ProxyIndex[Private->ProxyOfferType] > 0); + + if (Private->ProxyOfferType == DHCP4_PACKET_TYPE_BINL) { + // + // We buffer all received BINL proxy offers, try them all one by one + // + if (!PxeBcTryBinlProxy (Private, &ProxyOfferIndex)) { + Status = EFI_NO_RESPONSE; + } + } else { + // + // For other types, only one proxy offer is buffered. + // + ProxyOfferIndex = Private->ProxyIndex[Private->ProxyOfferType] - 1; } } else { // - // For other types, only one proxy offer is buffered. + // The proxy offer type is not determined, choose proxy offer in the + // received order. // - ProxyOfferIndex = Private->ProxyIndex[Private->ProxyOfferType] - 1; - } - } else { - // - // Choose proxy offer in the received order. - // - Status = EFI_NO_RESPONSE; + Status = EFI_NO_RESPONSE; - for (Index = 0; Index < Private->NumOffers; Index++) { + for (Index = 0; Index < Private->NumOffers; Index++) { - Offer = &Private->Dhcp4Offers[Index].Packet.Offer; - if (!IS_PROXY_DHCP_OFFER (Offer)) { - // - // Skip non proxy dhcp offers. - // - continue; - } - - if (Private->Dhcp4Offers[Index].OfferType == DHCP4_PACKET_TYPE_BINL) { - // - // Try BINL - // - if (!PxeBcTryBinl (Private, Index)) { + Offer = &Private->Dhcp4Offers[Index].Packet.Offer; + if (!IS_PROXY_DHCP_OFFER (Offer)) { // - // Failed, skip to the next offer + // Skip non proxy dhcp offers. // continue; } - } - Status = EFI_SUCCESS; - break; + if (Private->Dhcp4Offers[Index].OfferType == DHCP4_PACKET_TYPE_BINL) { + // + // Try BINL + // + if (!PxeBcTryBinl (Private, Index)) { + // + // Failed, skip to the next offer + // + continue; + } + } + + Private->ProxyOfferType = Private->Dhcp4Offers[Index].OfferType; + ProxyOfferIndex = Index; + Status = EFI_SUCCESS; + break; + } } - } - if (!EFI_ERROR (Status) && (Private->ProxyOfferType != DHCP4_PACKET_TYPE_BINL)) { + if (!EFI_ERROR (Status) && (Private->ProxyOfferType != DHCP4_PACKET_TYPE_BINL)) { + // + // Copy the proxy offer to Mode and set the flag + // + PxeBcCopyProxyOffer (Private, ProxyOfferIndex); + } + } else { // - // Copy the proxy offer to Mode and set the flag + // No proxy offer is received, the bootfile name MUST be set. // - PxeBcCopyProxyOffer (Private, ProxyOfferIndex); + ASSERT (Options[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL); } } @@ -560,6 +572,8 @@ PxeBcCacheDhcpOffer ( // // It's a proxy dhcp offer with no your address, including pxe10, wfm11a or binl offer. // + Private->GotProxyOffer = TRUE; + if (OfferType == DHCP4_PACKET_TYPE_BINL) { // // Cache all binl offers. @@ -609,7 +623,6 @@ PxeBcSelectOffer ( UINT32 Index; UINT32 OfferIndex; EFI_DHCP4_PACKET *Offer; - BOOLEAN GotProxyOffer; Private->SelectedOffer = 0; @@ -688,15 +701,6 @@ PxeBcSelectOffer ( // // Try the offers in the received order. // - GotProxyOffer = FALSE; - for (Index = 0; Index < DHCP4_PACKET_TYPE_MAX; Index++) { - - GotProxyOffer = (BOOLEAN) (Private->ProxyIndex[Index] > 0); - if (GotProxyOffer) { - break; - } - } - for (Index = 0; Index < Private->NumOffers; Index++) { Offer = &Private->Dhcp4Offers[Index].Packet.Offer; @@ -709,7 +713,7 @@ PxeBcSelectOffer ( } if ((Private->Dhcp4Offers[Index].OfferType == DHCP4_PACKET_TYPE_DHCP_ONLY) && - ((!GotProxyOffer) && (Private->Dhcp4Offers[Index].Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL))) { + ((!Private->GotProxyOffer) && (Private->Dhcp4Offers[Index].Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] == NULL))) { // // DHCP only offer but no proxy offer received and no bootfile option in this offer // diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c index f8bdf5c945..87bedcb006 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c @@ -513,8 +513,9 @@ EfiPxeBcDhcp ( // // Zero those arrays to record the varies numbers of DHCP OFFERS. // - Private->NumOffers = 0; - Private->BootpIndex = 0; + Private->GotProxyOffer = FALSE; + Private->NumOffers = 0; + Private->BootpIndex = 0; ZeroMem (Private->ServerCount, sizeof (Private->ServerCount)); ZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex)); @@ -1158,7 +1159,7 @@ EfiPxeBcUdpWrite ( } FragCount = (HeaderSize != NULL) ? 2 : 1; - Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) AllocatePool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA)); + Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) AllocateZeroPool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA)); if (Udp4TxData == NULL) { return EFI_OUT_OF_RESOURCES; } diff --git a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h index df77c5da49..028adcd753 100644 --- a/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h +++ b/MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.h @@ -103,6 +103,7 @@ struct _PXEBC_PRIVATE_DATA { UINT8 MacLen; BOOLEAN SortOffers; + BOOLEAN GotProxyOffer; UINT32 NumOffers; UINT32 SelectedOffer; UINT32 ProxyOfferType; @@ -127,9 +128,9 @@ struct _PXEBC_PRIVATE_DATA { UINT32 BinlIndex[PXEBC_MAX_OFFER_NUM]; EFI_EVENT GetArpCacheEvent; - // - // token and event used to get ICMP error data from IP - // + // + // token and event used to get ICMP error data from IP + // EFI_IP4_COMPLETION_TOKEN IcmpErrorRcvToken; }; -- 2.39.2