X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=NetworkPkg%2FUefiPxeBcDxe%2FPxeBcImpl.c;h=7175e107bb1458f23c8090e04dbc2c457f53de8b;hb=53db912ea1ef7be5cb40e7dbff55d3bc059d9f90;hp=0e17731151129777929485f824c9ffd05fdca6f9;hpb=eb2710af5bee8637741d92ed8d32df562941e6d9;p=mirror_edk2.git diff --git a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c index 0e17731151..7175e107bb 100644 --- a/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c +++ b/NetworkPkg/UefiPxeBcDxe/PxeBcImpl.c @@ -1,7 +1,7 @@ /** @file This implementation of EFI_PXE_BASE_CODE_PROTOCOL and EFI_LOAD_FILE_PROTOCOL. - Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+ Copyright (c) 2007 - 2014, 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 @@ -81,6 +81,17 @@ EfiPxeBcStart ( if (Mode->UsingIpv6) { AsciiPrint ("\n>>Start PXE over IPv6"); + // + // Configure udp6 instance to receive data. + // + Status = Private->Udp6Read->Configure ( + Private->Udp6Read, + &Private->Udp6CfgData + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // // Configure block size for TFTP as a default value to handle all link layers. // @@ -115,6 +126,17 @@ EfiPxeBcStart ( } } else { AsciiPrint ("\n>>Start PXE over IPv4"); + // + // Configure udp4 instance to receive data. + // + Status = Private->Udp4Read->Configure ( + Private->Udp4Read, + &Private->Udp4CfgData + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // // Configure block size for TFTP as a default value to handle all link layers. // @@ -323,6 +345,10 @@ EfiPxeBcStop ( Private->BootFileSize = 0; Private->SolicitTimes = 0; Private->ElapsedTime = 0; + ZeroMem (&Private->StationIp, sizeof (EFI_IP_ADDRESS)); + ZeroMem (&Private->SubnetMask, sizeof (EFI_IP_ADDRESS)); + ZeroMem (&Private->GatewayIp, sizeof (EFI_IP_ADDRESS)); + ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS)); // // Reset the mode data. @@ -406,15 +432,6 @@ EfiPxeBcDhcp ( // Start S.A.R.R. process to get a IPv6 address and other boot information. // Status = PxeBcDhcp6Sarr (Private, Private->Dhcp6); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Configure Udp6Read instance - // - Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); } else { // @@ -426,17 +443,16 @@ EfiPxeBcDhcp ( // Start D.O.R.A. process to get a IPv4 address and other boot information. // Status = PxeBcDhcp4Dora (Private, Private->Dhcp4); - - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Configure Udp4Read instance - // - Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); } + // + // Reconfigure the UDP instance with the default configuration. + // + if (Mode->UsingIpv6) { + Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); + } else { + Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); + } // // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. @@ -511,6 +527,7 @@ EfiPxeBcDiscover ( UINT16 Index; EFI_STATUS Status; EFI_PXE_BASE_CODE_IP_FILTER IpFilter; + EFI_PXE_BASE_CODE_DISCOVER_INFO *NewCreatedInfo; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -523,6 +540,7 @@ EfiPxeBcDiscover ( SrvList = NULL; Status = EFI_DEVICE_ERROR; Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER; + NewCreatedInfo = NULL; if (!Mode->Started) { return EFI_NOT_STARTED; @@ -552,6 +570,7 @@ EfiPxeBcDiscover ( // // There are 3 methods to get the information for discover. // + ZeroMem (&DefaultInfo, sizeof (EFI_PXE_BASE_CODE_DISCOVER_INFO)); if (*Layer != EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL) { // // 1. Take the previous setting as the discover info. @@ -576,12 +595,12 @@ EfiPxeBcDiscover ( // // 2. Extract the discover information from the cached packets if unspecified. // - Info = &DefaultInfo; - Status = PxeBcExtractDiscoverInfo (Private, Type, Info, &BootSvrEntry, &SrvList); + NewCreatedInfo = &DefaultInfo; + Status = PxeBcExtractDiscoverInfo (Private, Type, &NewCreatedInfo, &BootSvrEntry, &SrvList); if (EFI_ERROR (Status)) { goto ON_EXIT; } - + Info = NewCreatedInfo; } else { // // 3. Take the pass-in information as the discover info, and validate the server list. @@ -597,7 +616,7 @@ EfiPxeBcDiscover ( if (Index != Info->IpCnt) { // // It's invalid if the first server doesn't accecpt any response - // and meanwhile any of the rest servers accept any reponse. + // but any of the other servers does accept any response. // Status = EFI_INVALID_PARAMETER; goto ON_EXIT; @@ -616,30 +635,7 @@ EfiPxeBcDiscover ( Private->IsDoDiscover = TRUE; - if (Info->UseUCast) { - // - // Do discover by unicast. - // - for (Index = 0; Index < Info->IpCnt; Index++) { - if (BootSvrEntry == NULL) { - CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS)); - } else { - ASSERT (!Mode->UsingIpv6); - ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS)); - CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); - } - - Status = PxeBcDiscoverBootServer ( - Private, - Type, - Layer, - UseBis, - &SrvList[Index].IpAddr, - 0, - NULL - ); - } - } else if (Info->UseMCast) { + if (Info->UseMCast) { // // Do discover by multicast. // @@ -649,8 +645,8 @@ EfiPxeBcDiscover ( Layer, UseBis, &Info->ServerMCastIp, - 0, - NULL + Info->IpCnt, + SrvList ); } else if (Info->UseBCast) { @@ -667,11 +663,33 @@ EfiPxeBcDiscover ( Info->IpCnt, SrvList ); + + } else if (Info->UseUCast) { + // + // Do discover by unicast. + // + for (Index = 0; Index < Info->IpCnt; Index++) { + if (BootSvrEntry == NULL) { + CopyMem (&Private->ServerIp, &SrvList[Index].IpAddr, sizeof (EFI_IP_ADDRESS)); + } else { + ASSERT (!Mode->UsingIpv6); + ZeroMem (&Private->ServerIp, sizeof (EFI_IP_ADDRESS)); + CopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS)); + } + + Status = PxeBcDiscoverBootServer ( + Private, + Type, + Layer, + UseBis, + &Private->ServerIp, + Info->IpCnt, + SrvList + ); + } } - if (EFI_ERROR (Status)) { - return Status; - } else { + if (!EFI_ERROR (Status)) { // // Parse the cached PXE reply packet, and store it into mode data if valid. // @@ -680,8 +698,8 @@ EfiPxeBcDiscover ( if (!EFI_ERROR (Status)) { CopyMem ( &Mode->PxeReply.Dhcpv6, - &Private->PxeReply.Dhcp6.Packet.Offer, - Private->PxeReply.Dhcp6.Packet.Offer.Length + &Private->PxeReply.Dhcp6.Packet.Ack.Dhcp6, + Private->PxeReply.Dhcp6.Packet.Ack.Length ); Mode->PxeReplyReceived = TRUE; Mode->PxeDiscoverValid = TRUE; @@ -691,8 +709,8 @@ EfiPxeBcDiscover ( if (!EFI_ERROR (Status)) { CopyMem ( &Mode->PxeReply.Dhcpv4, - &Private->PxeReply.Dhcp4.Packet.Offer, - Private->PxeReply.Dhcp4.Packet.Offer.Length + &Private->PxeReply.Dhcp4.Packet.Ack.Dhcp4, + Private->PxeReply.Dhcp4.Packet.Ack.Length ); Mode->PxeReplyReceived = TRUE; Mode->PxeDiscoverValid = TRUE; @@ -702,10 +720,14 @@ EfiPxeBcDiscover ( ON_EXIT: + if (NewCreatedInfo != NULL && NewCreatedInfo != &DefaultInfo) { + FreePool (NewCreatedInfo); + } + if (Mode->UsingIpv6) { - Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); + Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); } else { - Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); + Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); } // @@ -939,16 +961,14 @@ EfiPxeBcMtftp ( Mode->IcmpErrorReceived = TRUE; } - if (EFI_ERROR (Status)) { - return Status; - } - + // + // Reconfigure the UDP instance with the default configuration. + // if (Mode->UsingIpv6) { - Status = Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); + Private->Udp6Read->Configure (Private->Udp6Read, &Private->Udp6CfgData); } else { - Status = Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); + Private->Udp4Read->Configure (Private->Udp4Read, &Private->Udp4CfgData); } - // // Dhcp(), Discover(), and Mtftp() set the IP filter, and return with the IP // receive filter list emptied and the filter set to EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP. @@ -1360,7 +1380,9 @@ EfiPxeBcUdpRead ( if (Udp6Rx->DataLength - HeaderLen > *BufferSize) { Status = EFI_BUFFER_TOO_SMALL; } else { - *HeaderSize = HeaderLen; + if (HeaderSize != NULL) { + *HeaderSize = HeaderLen; + } *BufferSize = Udp6Rx->DataLength - HeaderLen; HeaderCopiedLen = 0; @@ -1412,7 +1434,9 @@ EfiPxeBcUdpRead ( if (Udp4Rx->DataLength - HeaderLen > *BufferSize) { Status = EFI_BUFFER_TOO_SMALL; } else { - *HeaderSize = HeaderLen; + if (HeaderSize != NULL) { + *HeaderSize = HeaderLen; + } *BufferSize = Udp4Rx->DataLength - HeaderLen; HeaderCopiedLen = 0; @@ -2000,7 +2024,7 @@ EfiPxeBcSetStationIP ( CopyMem (&Private->SubnetMask ,NewSubnetMask, sizeof (EFI_IP_ADDRESS)); } - Status = PxeBcFlushStaionIp (Private, NewStationIp, NewSubnetMask); + Status = PxeBcFlushStationIp (Private, NewStationIp, NewSubnetMask); ON_EXIT: return Status; } @@ -2319,6 +2343,15 @@ EfiPxeLoadFile ( // Start Pxe Base Code to initialize PXE boot. // Status = PxeBc->Start (PxeBc, UsingIpv6); + if (Status == EFI_ALREADY_STARTED && UsingIpv6 != PxeBc->Mode->UsingIpv6) { + // + // PxeBc protocol has already been started but not on the required IP version, restart it. + // + Status = PxeBc->Stop (PxeBc); + if (!EFI_ERROR (Status)) { + Status = PxeBc->Start (PxeBc, UsingIpv6); + } + } if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) { Status = PxeBcLoadBootFile (Private, BufferSize, Buffer); }