In case of the DHCP and PXE services on different servers,PXEv6 boot will
failure when DhcpBinl offer received. The issue is caused by the following
reasons:
* PXE Client doesn't append VENDOR_CLASS request parameter, so the
offer replied from DHCP service will not contain VENDOR_CLASS option
(16).
* Once the DhcpBinl offer is selected, the boot discover message should
be sent out to request the bootfile by this offer. Current implementation
always use servers multi-cast address instead of BootFileUrl address in
dhcp6 offer. we should check it first, then decide whether use multi-cast
address or not.
* If DhcpBinl offer is selected, the boot discover message shouldn't
find server ID Option from DhcpBinl offer. That's incorrect because DHCP
service and PXE service on different servers. In such a case, we can ignore
the Server ID Option.

With the above fix in the patch, PXEv6 can boot successfully when DhcpBinl
offer received.

Cc: Ye Ting <ting...@intel.com>
Cc: Fu Siyuan <siyuan...@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin...@intel.com>
---
 NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c | 43 +++++++++++++++++++-----------------
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c 
b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
index 4cd1770..f2239fd 100644
--- a/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
+++ b/NetworkPkg/UefiPxeBcDxe/PxeBcDhcp6.c
@@ -91,15 +91,16 @@ PxeBcBuildDhcp6Options (
 
   //
   // Append client option request option
   //
   OptList[Index]->OpCode     = HTONS (DHCP6_OPT_ORO);
-  OptList[Index]->OpLen      = HTONS (6);
+  OptList[Index]->OpLen      = HTONS (8);
   OptEnt.Oro                 = (PXEBC_DHCP6_OPTION_ORO *) OptList[Index]->Data;
   OptEnt.Oro->OpCode[0]      = HTONS(DHCP6_OPT_BOOT_FILE_URL);
   OptEnt.Oro->OpCode[1]      = HTONS(DHCP6_OPT_BOOT_FILE_PARAM);
   OptEnt.Oro->OpCode[2]      = HTONS(DHCP6_OPT_DNS_SERVERS);
+  OptEnt.Oro->OpCode[3]      = HTONS(DHCP6_OPT_VENDOR_CLASS);
   Index++;
   OptList[Index]             = GET_NEXT_DHCP6_OPTION (OptList[Index - 1]);
 
   //
   // Append client network device interface option
@@ -905,16 +906,16 @@ PxeBcRequestBootService (
   UINTN                               ReadSize;
   UINT16                              OpFlags;
   UINT16                              OpCode;
   UINT16                              OpLen;
   EFI_STATUS                          Status;
-  EFI_DHCP6_PACKET                    *ProxyOffer;
+  EFI_DHCP6_PACKET                    *IndexOffer;
   UINT8                               *Option;
 
   PxeBc       = &Private->PxeBc;
   Request     = Private->Dhcp6Request;
-  ProxyOffer = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer;
+  IndexOffer  = &Private->OfferBuffer[Index].Dhcp6.Packet.Offer;
   SrcPort     = PXEBC_BS_DISCOVER_PORT;
   DestPort    = PXEBC_BS_DISCOVER_PORT;
   OpFlags     = 0;
 
   if (Request == NULL) {
@@ -927,36 +928,38 @@ PxeBcRequestBootService (
   }
 
   //
   // Build the request packet by the cached request packet before.
   //
-  Discover->TransactionId = ProxyOffer->Dhcp6.Header.TransactionId;
+  Discover->TransactionId = IndexOffer->Dhcp6.Header.TransactionId;
   Discover->MessageType   = Request->Dhcp6.Header.MessageType;
   RequestOpt              = Request->Dhcp6.Option;
   DiscoverOpt             = Discover->DhcpOptions;
   DiscoverLen             = sizeof (EFI_DHCP6_HEADER);
   RequestLen              = DiscoverLen;
 
   //
   // Find Server ID Option from ProxyOffer.
   //
-  Option = PxeBcDhcp6SeekOption (
-             ProxyOffer->Dhcp6.Option,
-             ProxyOffer->Length - 4,
-             DHCP6_OPT_SERVER_ID
-             );
-  if (Option == NULL) {
-    return EFI_NOT_FOUND;
-  }
+  if (Private->OfferBuffer[Index].Dhcp6.OfferType == PxeOfferTypeProxyBinl) {  
+    Option = PxeBcDhcp6SeekOption (
+               IndexOffer->Dhcp6.Option,
+               IndexOffer->Length - 4,
+               DHCP6_OPT_SERVER_ID
+               );
+    if (Option == NULL) {
+      return EFI_NOT_FOUND;
+    }
   
-  //
-  // Add Server ID Option.
-  //
-  OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) Option)->OpLen);
-  CopyMem (DiscoverOpt, Option, OpLen + 4);
-  DiscoverOpt += (OpLen + 4);
-  DiscoverLen += (OpLen + 4);
+    //
+    // Add Server ID Option.
+    //
+    OpLen = NTOHS (((EFI_DHCP6_PACKET_OPTION *) Option)->OpLen);
+    CopyMem (DiscoverOpt, Option, OpLen + 4);
+    DiscoverOpt += (OpLen + 4);
+    DiscoverLen += (OpLen + 4);
+  }
 
   while (RequestLen < Request->Length) {
     OpCode = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpCode);
     OpLen  = NTOHS (((EFI_DHCP6_PACKET_OPTION *) RequestOpt)->OpLen);
     if (OpCode != EFI_DHCP6_IA_TYPE_NA &&
@@ -1076,11 +1079,11 @@ PxeBcRetryDhcp6Binl (
           Private->OfferBuffer[Index].Dhcp6.OfferType == 
PxeOfferTypeProxyBinl);
 
   Mode                  = Private->PxeBc.Mode;
   Private->IsDoDiscover = FALSE;
   Offer                 = &Private->OfferBuffer[Index].Dhcp6;
-  if (Offer->OfferType == PxeOfferTypeDhcpBinl) {
+  if (Offer->OptList[PXEBC_DHCP6_IDX_BOOT_FILE_URL] == NULL) {
     //
     // There is no BootFileUrl option in dhcp6 offer, so use servers 
multi-cast address instead.
     //
     CopyMem (
       &Private->ServerIp.v6,
-- 
1.9.5.msysgit.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to