From: vanjeff Date: Tue, 18 Dec 2007 07:01:23 +0000 (+0000) Subject: Sync the latest version from R8. X-Git-Tag: edk2-stable201903~21662 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=c4a62a12c2890297cfcb9828b51b058fb347c01a;hp=372787b85a2a6a6da0a7b0357f58953da26d81a8 Sync the latest version from R8. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4400 6f19259b-4bc3-4df7-8a09-765794883524 --- diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h index c843b6ce79..4a621e111e 100644 --- a/MdeModulePkg/Include/Library/NetLib.h +++ b/MdeModulePkg/Include/Library/NetLib.h @@ -212,7 +212,9 @@ extern IP4_ADDR mIp4AllMasks [IP4_MASK_NUM]; extern EFI_IPv4_ADDRESS mZeroIp4Addr; -#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9')) +#define NET_IS_DIGIT(Ch) (('0' <= (Ch)) && ((Ch) <= '9')) +#define NET_ROUNDUP(size, unit) (((size) + (unit) - 1) & (~((unit) - 1))) + // // Wrap functions to ease the impact of EFI library changes. // diff --git a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c index 279ada7b11..2dd6e60bb5 100644 --- a/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c +++ b/MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c @@ -1092,12 +1092,6 @@ IpIoCancelTxToken ( Ip = SndEntry->Ip; Ip->Cancel (Ip, SndEntry->SndToken); - // - // Abort the user token. - // - SndEntry->SndToken->Status = EFI_ABORTED; - IpIoTransmitHandler (NULL, SndEntry); - break; } } diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c index af2e082576..aa99ff5b51 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c @@ -413,7 +413,7 @@ ArpDriverBindingStop ( // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } // @@ -429,50 +429,43 @@ ArpDriverBindingStop ( ); if (EFI_ERROR (Status)) { ARP_DEBUG_ERROR (("ArpDriverBindingStop: Open ArpSb failed, %r.\n", Status)); - return Status; + return EFI_DEVICE_ERROR; } ArpService = ARP_SERVICE_DATA_FROM_THIS (ServiceBinding); - while (!NetListIsEmpty (&ArpService->ChildrenList)) { + if (NumberOfChildren == 0) { // - // Iterate all the instances. + // Uninstall the ARP ServiceBinding protocol. // - Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List); + gBS->UninstallMultipleProtocolInterfaces ( + NicHandle, + &gEfiArpServiceBindingProtocolGuid, + &ArpService->ServiceBinding, + NULL + ); // - // Destroy this arp child. + // Clean the arp servicebinding context data and free the memory allocated. // - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } + ArpCleanService (ArpService); - ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable)); - ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable)); - ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable)); + NetFreePool (ArpService); + } else { - // - // Uninstall the ARP ServiceBinding protocol. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - NicHandle, - &gEfiArpServiceBindingProtocolGuid, - &ArpService->ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { - ARP_DEBUG_ERROR (("ArpDriverBindingStop: Failed to uninstall ArpSb, %r.\n", Status)); - return Status; - } + while (!NetListIsEmpty (&ArpService->ChildrenList)) { + Instance = NET_LIST_HEAD (&ArpService->ChildrenList, ARP_INSTANCE_DATA, List); - // - // Clean the arp servicebinding context data and free the memory allocated. - // - ArpCleanService (ArpService); - NetFreePool (ArpService); + ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); + } - return Status; -} + ASSERT (NetListIsEmpty (&ArpService->PendingRequestTable)); + ASSERT (NetListIsEmpty (&ArpService->DeniedCacheTable)); + ASSERT (NetListIsEmpty (&ArpService->ResolvedCacheTable)); + } + return EFI_SUCCESS; +} /** Creates a child handle with a set of I/O services. diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c index 9549790883..4d78b87ad1 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c @@ -229,7 +229,7 @@ Dhcp4CreateService ( // Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL | EVT_TIMER, - TPL_CALLBACK, + NET_TPL_TIMER, DhcpOnTimerTick, DhcpSb, &DhcpSb->Timer @@ -372,7 +372,7 @@ Dhcp4DriverBindingStop ( NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } Status = gBS->OpenProtocol ( @@ -394,44 +394,39 @@ Dhcp4DriverBindingStop ( return EFI_SUCCESS; } - OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); - DhcpSb->InDestory = TRUE; - - // - // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild - // may cause other child to be deleted. - // - while (!NetListIsEmpty (&DhcpSb->Children)) { - Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link); - Dhcp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); - } + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); - if (DhcpSb->NumChildren != 0) { - Status = EFI_DEVICE_ERROR; - goto ON_ERROR; - } + if (NumberOfChildren == 0) { - DhcpSb->ServiceState = DHCP_DESTORY; + DhcpSb->InDestory = TRUE; + DhcpSb->ServiceState = DHCP_DESTORY; - Status = gBS->UninstallProtocolInterface ( - NicHandle, - &gEfiDhcp4ServiceBindingProtocolGuid, - ServiceBinding - ); + gBS->UninstallProtocolInterface ( + NicHandle, + &gEfiDhcp4ServiceBindingProtocolGuid, + ServiceBinding + ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; + Dhcp4CloseService (DhcpSb); + + NetFreePool (DhcpSb); + } else { + // + // Don't use NET_LIST_FOR_EACH_SAFE here, Dhcp4ServiceBindingDestoryChild + // may cause other child to be deleted. + // + while (!NetListIsEmpty (&DhcpSb->Children)) { + Instance = NET_LIST_HEAD (&DhcpSb->Children, DHCP_PROTOCOL, Link); + ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); + } + + if (DhcpSb->NumChildren != 0) { + Status = EFI_DEVICE_ERROR; + } } - Dhcp4CloseService (DhcpSb); NET_RESTORE_TPL (OldTpl); - NetFreePool (DhcpSb); - return EFI_SUCCESS; - -ON_ERROR: - DhcpSb->InDestory = FALSE; - NET_RESTORE_TPL (OldTpl); return Status; } @@ -460,6 +455,8 @@ DhcpInitProtocol ( Instance->CompletionEvent = NULL; Instance->RenewRebindEvent = NULL; Instance->Token = NULL; + Instance->UdpIo = NULL; + NetbufQueInit (&Instance->ResponseQueue); } diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c index e8e9b383f8..50f1a2fbbe 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c @@ -57,11 +57,7 @@ EfiDhcp4GetModeData ( } Instance = DHCP_INSTANCE_FROM_THIS (This); - - if (Instance->Signature != DHCP_PROTOCOL_SIGNATURE) { - return EFI_INVALID_PARAMETER; - } - + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); DhcpSb = Instance->Service; @@ -766,6 +762,226 @@ EfiDhcp4Build ( ); } +STATIC +EFI_STATUS +Dhcp4InstanceConfigUdpIo ( + IN UDP_IO_PORT *UdpIo, + IN VOID *Context + ) +{ + DHCP_PROTOCOL *Instance; + DHCP_SERVICE *DhcpSb; + EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token; + EFI_UDP4_CONFIG_DATA UdpConfigData; + IP4_ADDR Ip; + + Instance = (DHCP_PROTOCOL *) Context; + DhcpSb = Instance->Service; + Token = Instance->Token; + + NetZeroMem (&UdpConfigData, sizeof (EFI_UDP4_CONFIG_DATA)); + + UdpConfigData.AcceptBroadcast = TRUE; + UdpConfigData.AllowDuplicatePort = TRUE; + UdpConfigData.TimeToLive = 64; + UdpConfigData.DoNotFragment = TRUE; + + Ip = HTONL (DhcpSb->ClientAddr); + NetCopyMem (&UdpConfigData.StationAddress, &Ip, sizeof (EFI_IPv4_ADDRESS)); + + Ip = HTONL (DhcpSb->Netmask); + NetCopyMem (&UdpConfigData.SubnetMask, &Ip, sizeof (EFI_IPv4_ADDRESS)); + + if ((Token->ListenPointCount == 0) || (Token->ListenPoints[0].ListenPort == 0)) { + UdpConfigData.StationPort = DHCP_CLIENT_PORT; + } else { + UdpConfigData.StationPort = Token->ListenPoints[0].ListenPort; + } + + return UdpIo->Udp->Configure (UdpIo->Udp, &UdpConfigData); +} + +STATIC +EFI_STATUS +Dhcp4InstanceCreateUdpIo ( + IN DHCP_PROTOCOL *Instance + ) +{ + DHCP_SERVICE *DhcpSb; + + ASSERT (Instance->Token != NULL); + + DhcpSb = Instance->Service; + Instance->UdpIo = UdpIoCreatePort (DhcpSb->Controller, DhcpSb->Image, Dhcp4InstanceConfigUdpIo, Instance); + if (Instance->UdpIo == NULL) { + return EFI_OUT_OF_RESOURCES; + } else { + return EFI_SUCCESS; + } +} + +STATIC +VOID +DhcpDummyExtFree ( + IN VOID *Arg + ) +/*++ + +Routine Description: + + Release the packet. + +Arguments: + + Arg - The packet to release + +Returns: + + None + +--*/ +{ +} + +VOID +PxeDhcpInput ( + NET_BUF *UdpPacket, + UDP_POINTS *Points, + EFI_STATUS IoStatus, + VOID *Context + ) +{ + DHCP_PROTOCOL *Instance; + DHCP_SERVICE *DhcpSb; + EFI_DHCP4_HEADER *Head; + NET_BUF *Wrap; + EFI_DHCP4_PACKET *Packet; + EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token; + UINT32 Len; + EFI_STATUS Status; + + Wrap = NULL; + Instance = (DHCP_PROTOCOL *) Context; + Token = Instance->Token; + DhcpSb = Instance->Service; + + // + // Don't restart receive if error occurs or DHCP is destoried. + // + if (EFI_ERROR (IoStatus)) { + return ; + } + + ASSERT (UdpPacket != NULL); + + // + // Validate the packet received + // + if (UdpPacket->TotalSize < sizeof (EFI_DHCP4_HEADER)) { + goto RESTART; + } + + // + // Copy the DHCP message to a continuous memory block, make the buffer size + // of the EFI_DHCP4_PACKET a multiple of 4-byte. + // + Len = NET_ROUNDUP (sizeof (EFI_DHCP4_PACKET) + UdpPacket->TotalSize - sizeof (EFI_DHCP4_HEADER), 4); + Wrap = NetbufAlloc (Len); + + if (Wrap == NULL) { + goto RESTART; + } + + Packet = (EFI_DHCP4_PACKET *) NetbufAllocSpace (Wrap, Len, NET_BUF_TAIL); + Packet->Size = Len; + Head = &Packet->Dhcp4.Header; + Packet->Length = NetbufCopy (UdpPacket, 0, UdpPacket->TotalSize, (UINT8 *) Head); + + if (Packet->Length != UdpPacket->TotalSize) { + goto RESTART; + } + + // + // Is this packet the answer to our packet? + // + if ((Head->OpCode != BOOTP_REPLY) || + (Head->Xid != Token->Packet->Dhcp4.Header.Xid) || + !NET_MAC_EQUAL (&DhcpSb->Mac, Head->ClientHwAddr, DhcpSb->HwLen)) { + goto RESTART; + } + + // + // Validate the options and retrieve the interested options + // + if ((Packet->Length > sizeof (EFI_DHCP4_HEADER) + sizeof (UINT32)) && + (Packet->Dhcp4.Magik == DHCP_OPTION_MAGIC) && + EFI_ERROR (DhcpValidateOptions (Packet, NULL))) { + + goto RESTART; + } + + // + // Keep this packet in the ResponseQueue. + // + NET_GET_REF (Wrap); + NetbufQueAppend (&Instance->ResponseQueue, Wrap); + +RESTART: + + NetbufFree (UdpPacket); + + if (Wrap != NULL) { + NetbufFree (Wrap); + } + + Status = UdpIoRecvDatagram (Instance->UdpIo, PxeDhcpInput, Instance, 0); + if (EFI_ERROR (Status)) { + PxeDhcpDone (Instance); + } +} + +VOID +PxeDhcpDone ( + IN DHCP_PROTOCOL *Instance + ) +{ + EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token; + + Token = Instance->Token; + + Token->ResponseCount = Instance->ResponseQueue.BufNum; + if (Token->ResponseCount != 0) { + Token->ResponseList = (EFI_DHCP4_PACKET *) NetAllocatePool (Instance->ResponseQueue.BufSize); + if (Token->ResponseList == NULL) { + Token->Status = EFI_OUT_OF_RESOURCES; + goto SIGNAL_USER; + } + + // + // Copy the recieved DHCP responses. + // + NetbufQueCopy (&Instance->ResponseQueue, 0, Instance->ResponseQueue.BufSize, (UINT8 *) Token->ResponseList); + Token->Status = EFI_SUCCESS; + } else { + Token->ResponseList = NULL; + Token->Status = EFI_TIMEOUT; + } + +SIGNAL_USER: + // + // Clean the resources dedicated for this transmit receive transaction. + // + NetbufQueFlush (&Instance->ResponseQueue); + UdpIoCleanPort (Instance->UdpIo); + UdpIoFreePort (Instance->UdpIo); + Instance->UdpIo = NULL; + Instance->Token = NULL; + + if (Token->CompletionEvent != NULL) { + gBS->SignalEvent (Token->CompletionEvent); + } +} + /** Transmit and receive a packet through this DHCP service. @@ -785,10 +1001,144 @@ EfiDhcp4TransmitReceive ( IN EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token ) { + DHCP_PROTOCOL *Instance; + EFI_TPL OldTpl; + EFI_STATUS Status; + NET_FRAGMENT Frag; + NET_BUF *Wrap; + UDP_POINTS EndPoint; + IP4_ADDR Ip; + DHCP_SERVICE *DhcpSb; + IP4_ADDR Gateway; + IP4_ADDR SubnetMask; + + if ((This == NULL) || (Token == NULL) || (Token->Packet == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Instance = DHCP_INSTANCE_FROM_THIS (This); + DhcpSb = Instance->Service; + + if (Instance->Token != NULL) { + // + // The previous call to TransmitReceive is not finished. + // + return EFI_NOT_READY; + } + + if ((Token->Packet->Dhcp4.Magik != DHCP_OPTION_MAGIC) || + (NTOHL (Token->Packet->Dhcp4.Header.Xid) == Instance->Service->Xid) || + (Token->TimeoutValue == 0) || + ((Token->ListenPointCount != 0) && (Token->ListenPoints == NULL)) || + EFI_ERROR (DhcpValidateOptions (Token->Packet, NULL)) || + EFI_IP4_EQUAL (&Token->RemoteAddress, &mZeroIp4Addr)) { + // + // The DHCP packet isn't well-formed, the Transaction ID is already used + // , the timeout value is zero, the ListenPoint is invalid, + // or the RemoteAddress is zero. + // + return EFI_INVALID_PARAMETER; + } + + if (DhcpSb->ClientAddr == 0) { + + return EFI_NO_MAPPING; + } + + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); + + // + // Save the token and the timeout value. + // + Instance->Token = Token; + Instance->Timeout = Token->TimeoutValue; + + // + // Create a UDP IO for this transmit receive transaction. + // + Status = Dhcp4InstanceCreateUdpIo (Instance); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + // - // This function is for PXE, leave it for now + // Wrap the DHCP packet into a net buffer. // - return EFI_UNSUPPORTED; + Frag.Bulk = (UINT8 *) &Token->Packet->Dhcp4; + Frag.Len = Token->Packet->Length; + Wrap = NetbufFromExt (&Frag, 1, 0, 0, DhcpDummyExtFree, NULL); + if (Wrap == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_ERROR; + } + + // + // Set the local address and local port. + // + EndPoint.LocalAddr = 0; + EndPoint.LocalPort = 0; + + // + // Set the destination address and destination port. + // + NetCopyMem (&Ip, &Token->RemoteAddress, sizeof (EFI_IPv4_ADDRESS)); + EndPoint.RemoteAddr = NTOHL (Ip); + + if (Token->RemotePort == 0) { + EndPoint.RemotePort = DHCP_SERVER_PORT; + } else { + EndPoint.RemotePort = Token->RemotePort; + } + + // + // Get the gateway. + // + SubnetMask = DhcpSb->Netmask; + Gateway = 0; + if (!IP4_NET_EQUAL (DhcpSb->ClientAddr, EndPoint.RemoteAddr, SubnetMask)) { + NetCopyMem (&Gateway, &Token->GatewayAddress, sizeof (EFI_IPv4_ADDRESS)); + Gateway = NTOHL (Gateway); + } + + // + // Transmit the DHCP packet. + // + Status = UdpIoSendDatagram (Instance->UdpIo, Wrap, &EndPoint, Gateway, DhcpOnPacketSent, NULL); + if (EFI_ERROR (Status)) { + NetbufFree (Wrap); + goto ON_ERROR; + } + + // + // Start to receive the DHCP response. + // + Status = UdpIoRecvDatagram (Instance->UdpIo, PxeDhcpInput, Instance, 0); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + +ON_ERROR: + + if (EFI_ERROR (Status) && (Instance->UdpIo != NULL)) { + UdpIoCleanPort (Instance->UdpIo); + UdpIoFreePort (Instance->UdpIo); + Instance->UdpIo = NULL; + Instance->Token = NULL; + } + + NET_RESTORE_TPL (OldTpl); + + if (!EFI_ERROR (Status) && (Token->CompletionEvent == NULL)) { + // + // Keep polling until timeout if no error happens and the CompletionEvent + // is NULL. + // + while (Instance->Timeout != 0) { + Instance->UdpIo->Udp->Poll (Instance->UdpIo->Udp); + } + } + + return Status; } @@ -910,3 +1260,4 @@ EFI_DHCP4_PROTOCOL mDhcp4ProtocolTemplate = { EfiDhcp4TransmitReceive, EfiDhcp4Parse }; + diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h index 7a04109f4d..15b2270e88 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h @@ -77,6 +77,9 @@ struct _DHCP_PROTOCOL { EFI_EVENT RenewRebindEvent; EFI_DHCP4_TRANSMIT_RECEIVE_TOKEN *Token; + UDP_IO_PORT *UdpIo; // The UDP IO used for TransmitReceive. + UINT32 Timeout; + NET_BUF_QUEUE ResponseQueue; }; // @@ -156,4 +159,9 @@ DhcpYieldControl ( IN DHCP_SERVICE *DhcpSb ); +VOID +PxeDhcpDone ( + IN DHCP_PROTOCOL *Instance + ); + #endif diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c index 8adf40ff43..442deeb509 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c @@ -52,8 +52,6 @@ DhcpInitRequest ( DhcpSb->DhcpState = Dhcp4Init; return Status; } - - DhcpSb->WaitOffer = DHCP_WAIT_OFFER; } else { DhcpSetState (DhcpSb, Dhcp4Rebooting, FALSE); Status = DhcpSendMessage (DhcpSb, NULL, NULL, DHCP_MSG_REQUEST, NULL); @@ -225,7 +223,7 @@ DhcpSetState ( // This will clear the retry count. This is also why the rule // first transit the state, then send packets. // - if (State == Dhcp4Init) { + if (State == Dhcp4Selecting) { DhcpSb->MaxRetries = DhcpSb->ActiveConfig.DiscoverTryCount; } else { DhcpSb->MaxRetries = DhcpSb->ActiveConfig.RequestTryCount; @@ -262,7 +260,7 @@ DhcpSetTransmitTimer ( ASSERT (DhcpSb->MaxRetries > DhcpSb->CurRetry); - if (DhcpSb->DhcpState == Dhcp4Init) { + if (DhcpSb->DhcpState == Dhcp4Selecting) { Times = DhcpSb->ActiveConfig.DiscoverTimeout; } else { Times = DhcpSb->ActiveConfig.RequestTimeout; @@ -273,8 +271,11 @@ DhcpSetTransmitTimer ( } DhcpSb->PacketToLive = Times[DhcpSb->CurRetry]; -} + if (DhcpSb->DhcpState == Dhcp4Selecting) { + DhcpSb->WaitOffer = DhcpSb->PacketToLive; + } +} /** Compute the lease. If the server grants a permanent lease, just @@ -519,6 +520,7 @@ DhcpChooseOffer ( { EFI_DHCP4_PACKET *Selected; EFI_DHCP4_PACKET *NewPacket; + EFI_DHCP4_PACKET *TempPacket; EFI_STATUS Status; ASSERT (DhcpSb->LastOffer != NULL); @@ -542,12 +544,12 @@ DhcpChooseOffer ( Selected = DhcpSb->LastOffer; - if (NewPacket != NULL) { - if (EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) { - NetFreePool (NewPacket); - } else { + if ((NewPacket != NULL) && !EFI_ERROR (DhcpValidateOptions (NewPacket, NULL))) { + TempPacket = (EFI_DHCP4_PACKET *) NetAllocatePool (NewPacket->Size); + if (TempPacket != NULL) { + NetCopyMem (TempPacket, NewPacket, NewPacket->Size); NetFreePool (Selected); - Selected = NewPacket; + Selected = TempPacket; } } @@ -650,10 +652,6 @@ DhcpHandleSelect ( // Head = &Packet->Dhcp4.Header; - if (!Ip4IsUnicast (EFI_NTOHL (Head->YourAddr), (Para == NULL ? 0 : Para->NetMask))) { - goto ON_EXIT; - } - if (!DHCP_IS_BOOTP (Para) && ((Para->DhcpType != DHCP_MSG_OFFER) || (Para->ServerId == 0))) { goto ON_EXIT; @@ -1495,12 +1493,32 @@ DhcpOnTimerTick ( ) { DHCP_SERVICE *DhcpSb; + DHCP_PROTOCOL *Instance; EFI_STATUS Status; + + DhcpSb = (DHCP_SERVICE *) Context; + Instance = DhcpSb->ActiveChild; - DhcpSb = (DHCP_SERVICE *) Context; + // + // Check the time to wait offer + // + if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) { + // + // OK, offer collection finished, select a offer + // + ASSERT (DhcpSb->DhcpState == Dhcp4Selecting); + if (DhcpSb->LastOffer == NULL) { + goto END_SESSION; + } + + if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) { + goto END_SESSION; + } + } + // - // Check the retransmit timer first + // Check the retransmit timer // if ((DhcpSb->PacketToLive > 0) && (--DhcpSb->PacketToLive == 0)) { @@ -1543,22 +1561,7 @@ DhcpOnTimerTick ( } } } - - if ((DhcpSb->WaitOffer > 0) && (--DhcpSb->WaitOffer == 0)) { - // - // OK, offer collection finished, select a offer - // - ASSERT (DhcpSb->DhcpState == Dhcp4Selecting); - - if (DhcpSb->LastOffer == NULL) { - goto END_SESSION; - } - - if (EFI_ERROR (DhcpChooseOffer (DhcpSb))) { - goto END_SESSION; - } - } - + // // If an address has been acquired, check whether need to // refresh or whether it has expired. @@ -1622,6 +1625,16 @@ DhcpOnTimerTick ( } } + // + // + // + if ((Instance != NULL) && (Instance->Token != NULL)) { + Instance->Timeout--; + if (Instance->Timeout == 0) { + PxeDhcpDone (Instance); + } + } + return ; END_SESSION: diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h index 560c791d09..1caba3ad9e 100644 --- a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h +++ b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h @@ -112,4 +112,12 @@ DhcpCleanLease ( IN DHCP_SERVICE *DhcpSb ); +VOID +DhcpOnPacketSent ( + NET_BUF *Packet, + UDP_POINTS *Points, + EFI_STATUS IoStatus, + VOID *Context + ); + #endif diff --git a/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c index cccedf5e46..3f534fcdf1 100644 --- a/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c +++ b/MdeModulePkg/Universal/Network/DpcDxe/Dpc.c @@ -343,7 +343,8 @@ Returns: // Status = gBS->InstallMultipleProtocolInterfaces ( &mDpcHandle, - &gEfiDpcProtocolGuid, &mDpc, + &gEfiDpcProtocolGuid, + &mDpc, NULL ); ASSERT_EFI_ERROR (Status); diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c index bf43677e8a..589eca5208 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c @@ -512,6 +512,7 @@ Ip4DriverBindingStop ( EFI_STATUS Status; EFI_TPL OldTpl; INTN State; + BOOLEAN IsArp; // // IP4 driver opens the MNP child, ARP children or the IP4_CONFIG protocol @@ -549,7 +550,7 @@ Ip4DriverBindingStop ( ); if (EFI_ERROR (Status)) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } IpSb = IP4_SERVICE_FROM_PROTOCOL (ServiceBinding); @@ -594,14 +595,16 @@ Ip4DriverBindingStop ( // service binding is installed on the NIC handle. So, need to open // the protocol info to find the NIC handle. // + IsArp = FALSE; NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiManagedNetworkProtocolGuid); if (NicHandle == NULL) { NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiArpProtocolGuid); + IsArp = TRUE; } if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } // @@ -629,62 +632,88 @@ Ip4DriverBindingStop ( return EFI_SUCCESS; } - IpSb->InDestory = TRUE; + if (IsArp) { + while (!NetListIsEmpty (&IpSb->Children)) { + IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); - State = IpSb->State; - IpSb->State = IP4_SERVICE_DESTORY; + ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); + } - // - // Destory all the children first. If not all children are destoried, - // the IP driver can operate correctly, so restore it state. Don't - // use NET_LIST_FOR_EACH_SAFE here, because it will cache the next - // pointer, which may point to the child that has already been destoried. - // For example, if there are two child in the list, the first is UDP - // listen child, the send is the MTFTP's child. When Udp child is - // destoried, it will destory the MTFTP's child. Then Next point to - // a invalid child. - // - while (!NetListIsEmpty (&IpSb->Children)) { - IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); - Ip4ServiceBindingDestroyChild (ServiceBinding, IpInstance->Handle); - } + if (IpSb->NumChildren != 0) { + Status = EFI_DEVICE_ERROR; + goto ON_ERROR; + } - if (IpSb->NumChildren != 0) { - IpSb->State = State; - Status = EFI_DEVICE_ERROR; - goto ON_ERROR; - } + IpSb->InDestory = TRUE; - // - // Clear the variable data. - // - Ip4ClearVariableData (IpSb); + State = IpSb->State; + IpSb->State = IP4_SERVICE_DESTORY; - // - // OK, clean other resources then uninstall the service binding protocol. - // - Status = Ip4CleanService (IpSb); + // + // Clear the variable data. + // + Ip4ClearVariableData (IpSb); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + // + // OK, clean other resources then uninstall the service binding protocol. + // + Status = Ip4CleanService (IpSb); - Status = gBS->UninstallProtocolInterface ( - NicHandle, - &gEfiIp4ServiceBindingProtocolGuid, - ServiceBinding - ); + if (EFI_ERROR (Status)) { + IpSb->State = State; + goto ON_ERROR; + } - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + gBS->UninstallProtocolInterface ( + NicHandle, + &gEfiIp4ServiceBindingProtocolGuid, + ServiceBinding + ); - NET_RESTORE_TPL (OldTpl); - NetFreePool (IpSb); - return EFI_SUCCESS; + NetFreePool (IpSb); + } else if (NumberOfChildren == 0) { + IpSb->InDestory = TRUE; + + State = IpSb->State; + IpSb->State = IP4_SERVICE_DESTORY; + + // + // Clear the variable data. + // + Ip4ClearVariableData (IpSb); + + // + // OK, clean other resources then uninstall the service binding protocol. + // + Status = Ip4CleanService (IpSb); + + if (EFI_ERROR (Status)) { + IpSb->State = State; + goto ON_ERROR; + } + + gBS->UninstallProtocolInterface ( + NicHandle, + &gEfiIp4ServiceBindingProtocolGuid, + ServiceBinding + ); + + NetFreePool (IpSb); + } else { + + while (!NetListIsEmpty (&IpSb->Children)) { + IpInstance = NET_LIST_HEAD (&IpSb->Children, IP4_PROTOCOL, Link); + + ServiceBinding->DestroyChild (ServiceBinding, IpInstance->Handle); + } + + if (IpSb->NumChildren != 0) { + Status = EFI_DEVICE_ERROR; + } + } ON_ERROR: - IpSb->InDestory = FALSE; + NET_RESTORE_TPL (OldTpl); return Status; } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c index eaed123b84..a7a230d6fb 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c @@ -681,7 +681,6 @@ Ip4CancelReceive ( Interface->RecvRequest = NULL; Interface->Mnp->Cancel (Interface->Mnp, &Token->MnpToken); - Ip4FreeFrameRxToken (Token); NET_RESTORE_TPL (OldTpl); } diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h index aba5055ccb..94b4534de2 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2006, Intel Corporation +Copyright (c) 2005 - 2007, 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 diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c index b2308c6935..06a0110315 100644 --- a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c +++ b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2005 - 2006, Intel Corporation +Copyright (c) 2005 - 2007, 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 diff --git a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c index 814566ec56..946ace1f66 100644 --- a/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c +++ b/MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c @@ -219,64 +219,54 @@ MnpDriverBindingStop ( ("MnpDriverBindingStop: Locate MNP Service Binding Protocol failed, %r.\n", Status) ); - goto EXIT; + return EFI_DEVICE_ERROR; } MnpServiceData = MNP_SERVICE_DATA_FROM_THIS (ServiceBinding); - while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) { + if (NumberOfChildren == 0) { // - // Don't use NetListRemoveHead here, the remove opreration will be done - // in ServiceBindingDestroyChild. + // Uninstall the MNP Service Binding Protocol. // - Instance = NET_LIST_HEAD ( - &MnpServiceData->ChildrenList, - MNP_INSTANCE_DATA, - InstEntry - ); - - ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); - } + gBS->UninstallMultipleProtocolInterfaces ( + ControllerHandle, + &gEfiManagedNetworkServiceBindingProtocolGuid, + ServiceBinding, + NULL + ); - // - // Uninstall the MNP Service Binding Protocol. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - ControllerHandle, - &gEfiManagedNetworkServiceBindingProtocolGuid, - ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { + // + // Close the openned Snp protocol. + // + gBS->CloseProtocol ( + ControllerHandle, + &gEfiSimpleNetworkProtocolGuid, + This->DriverBindingHandle, + ControllerHandle + ); - MNP_DEBUG_ERROR (("MnpDriverBindingStop: Uninstall MNP Service Binding Protocol failed, %r.\n")); - goto EXIT; - } + // + // Flush the Mnp service data. + // + MnpFlushServiceData (MnpServiceData); - // - // Close the openned Snp protocol. - // - Status = gBS->CloseProtocol ( - ControllerHandle, - &gEfiSimpleNetworkProtocolGuid, - This->DriverBindingHandle, - ControllerHandle - ); - if (EFI_ERROR (Status)) { + NetFreePool (MnpServiceData); + } else { + while (!NetListIsEmpty (&MnpServiceData->ChildrenList)) { + // + // Don't use NetListRemoveHead here, the remove opreration will be done + // in ServiceBindingDestroyChild. + // + Instance = NET_LIST_HEAD ( + &MnpServiceData->ChildrenList, + MNP_INSTANCE_DATA, + InstEntry + ); - MNP_DEBUG_ERROR (("MnpDriverBindingStop: Close SNP Protocol failed, %r.\n", Status)); - goto EXIT; + ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle); + } } - // - // Flush the Mnp service data. - // - MnpFlushServiceData (MnpServiceData); - - NetFreePool (MnpServiceData); - -EXIT: - return Status; } diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c index 1186249513..f6f431de68 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c @@ -348,7 +348,7 @@ Mtftp4DriverBindingStop ( NicHandle = NetLibGetNicHandle (Controller, &gEfiUdp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } Status = gBS->OpenProtocol ( @@ -370,37 +370,32 @@ Mtftp4DriverBindingStop ( return EFI_SUCCESS; } - OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); - MtftpSb->InDestory = TRUE; + OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); - while (!NetListIsEmpty (&MtftpSb->Children)) { - Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link); - Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); - } + if (NumberOfChildren == 0) { - if (MtftpSb->ChildrenNum != 0) { - Status = EFI_DEVICE_ERROR; - goto ON_ERROR; - } + MtftpSb->InDestory = TRUE; - Status = gBS->UninstallProtocolInterface ( - NicHandle, - &gEfiMtftp4ServiceBindingProtocolGuid, - ServiceBinding - ); + gBS->UninstallProtocolInterface ( + NicHandle, + &gEfiMtftp4ServiceBindingProtocolGuid, + ServiceBinding + ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } + Mtftp4CleanService (MtftpSb); - Mtftp4CleanService (MtftpSb); - NetFreePool (MtftpSb); + NetFreePool (MtftpSb); + } else { - NET_RESTORE_TPL (OldTpl); - return EFI_SUCCESS; + while (!NetListIsEmpty (&MtftpSb->Children)) { + Instance = NET_LIST_HEAD (&MtftpSb->Children, MTFTP4_PROTOCOL, Link); + Mtftp4ServiceBindingDestroyChild (ServiceBinding, Instance->Handle); + } -ON_ERROR: - MtftpSb->InDestory = FALSE; + if (MtftpSb->ChildrenNum != 0) { + Status = EFI_DEVICE_ERROR; + } + } NET_RESTORE_TPL (OldTpl); return Status; diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c index 3ce8792537..0bd835b7b9 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c @@ -585,6 +585,16 @@ Mtftp4ConfigUnicastPort ( return EFI_SUCCESS; } + if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) { + // + // The station IP address is manually configured and the Gateway IP is not 0. + // Add the default route for this UDP instance. + // + Status = UdpIo->Udp->Routes (UdpIo->Udp, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp); + if (EFI_ERROR (Status)) { + UdpIo->Udp->Configure (UdpIo->Udp, NULL); + } + } return Status; } diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c index 906cce8deb..7c2114e717 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c @@ -412,6 +412,18 @@ Mtftp4RrqConfigMcastPort ( return Status; } + if (!Config->UseDefaultSetting && !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp)) { + // + // The station IP address is manually configured and the Gateway IP is not 0. + // Add the default route for this UDP instance. + // + Status = McastIo->Udp->Routes (McastIo->Udp, FALSE, &mZeroIp4Addr, &mZeroIp4Addr, &Config->GatewayIp); + if (EFI_ERROR (Status)) { + McastIo->Udp->Configure (McastIo->Udp, NULL); + return Status; + } + } + // // join the multicast group // @@ -534,22 +546,22 @@ Mtftp4RrqHandleOack ( return Status; } - + // // Update the parameters used. // if (Reply.BlkSize != 0) { Instance->BlkSize = Reply.BlkSize; } - + if (Reply.Timeout != 0) { Instance->Timeout = Reply.Timeout; - } - } - + } + } + } else { Instance->Master = TRUE; - + if (Reply.BlkSize != 0) { Instance->BlkSize = Reply.BlkSize; } @@ -558,7 +570,7 @@ Mtftp4RrqHandleOack ( Instance->Timeout = Reply.Timeout; } } - + // // Send an ACK to (Expected - 1) which is 0 for unicast download, // or tell the server we want to receive the Expected block. diff --git a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c index ce9db682d9..e56aa156d5 100644 --- a/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c +++ b/MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c @@ -467,7 +467,7 @@ Mtftp4SendPacket ( Instance->UnicastPort, Packet, &UdpPoint, - Instance->Gateway, + 0, Mtftp4OnPacketSent, Instance ); @@ -524,7 +524,7 @@ Mtftp4Retransmit ( Instance->UnicastPort, Instance->LastPacket, &UdpPoint, - Instance->Gateway, + 0, Mtftp4OnPacketSent, Instance ); diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c index 585d91bfa5..a7fa3b627a 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c @@ -584,6 +584,7 @@ SockCreate ( return NULL; } + NetListInit (&Sock->Link); NetListInit (&Sock->ConnectionList); NetListInit (&Sock->ListenTokenList); NetListInit (&Sock->RcvTokenList); diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h index 34b098bcde..b63eaa0106 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h @@ -330,6 +330,7 @@ struct _SOCKET { EFI_HANDLE DriverBinding; // socket't driver binding protocol EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; EFI_DEVICE_PATH_PROTOCOL *DevicePath; + NET_LIST_ENTRY Link; SOCK_CONFIGURE_STATE ConfigureState; SOCK_TYPE Type; SOCK_STATE State; diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c index 1d9138b39b..e2a78b7a9d 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c @@ -297,7 +297,7 @@ Tcp4DriverBindingStart ( " resource to create an Ip Io!\n")); Status = EFI_OUT_OF_RESOURCES; - goto ReleaseServiceData; + goto ON_ERROR; } // @@ -312,7 +312,7 @@ Tcp4DriverBindingStart ( Status = IpIoOpen (TcpServiceData->IpIo, &OpenData); if (EFI_ERROR (Status)) { - goto ReleaseServiceData; + goto ON_ERROR; } // @@ -324,7 +324,7 @@ Tcp4DriverBindingStart ( TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Create TcpTimer" " Event failed with %r\n", Status)); - goto ReleaseIpIo; + goto ON_ERROR; } // @@ -344,7 +344,8 @@ Tcp4DriverBindingStart ( TCP4_DEBUG_ERROR (("Tcp4DriverBindingStart: Install Tcp4 Service Binding" " Protocol failed for %r\n", Status)); - goto ReleaseTimer; + Tcp4DestroyTimer (); + goto ON_ERROR; } // @@ -354,19 +355,17 @@ Tcp4DriverBindingStart ( TcpServiceData->Signature = TCP4_DRIVER_SIGNATURE; TcpServiceData->DriverBindingHandle = This->DriverBindingHandle; + NetListInit (&TcpServiceData->SocketList); + TcpSetVariableData (TcpServiceData); return EFI_SUCCESS; -ReleaseTimer: - - Tcp4DestroyTimer (); - -ReleaseIpIo: +ON_ERROR: - IpIoDestroy (TcpServiceData->IpIo); - -ReleaseServiceData: + if (TcpServiceData->IpIo != NULL) { + IpIoDestroy (TcpServiceData->IpIo); + } NetFreePool (TcpServiceData); @@ -398,19 +397,15 @@ Tcp4DriverBindingStop ( { EFI_STATUS Status; EFI_HANDLE NicHandle; - EFI_SERVICE_BINDING_PROTOCOL *Tcp4ServiceBinding; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; TCP4_SERVICE_DATA *TcpServiceData; - TCP_CB *TcpPcb; SOCKET *Sock; - TCP4_PROTO_DATA *TcpProto; - NET_LIST_ENTRY *Entry; - NET_LIST_ENTRY *NextEntry; // Find the NicHandle where Tcp4 ServiceBinding Protocol is installed. // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } // @@ -419,7 +414,7 @@ Tcp4DriverBindingStop ( Status = gBS->OpenProtocol ( NicHandle, &gEfiTcp4ServiceBindingProtocolGuid, - (VOID **) &Tcp4ServiceBinding, + (VOID **) &ServiceBinding, This->DriverBindingHandle, ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL @@ -429,95 +424,53 @@ Tcp4DriverBindingStop ( TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Locate Tcp4 Service " " Binding Protocol failed with %r\n", Status)); - return Status; + return EFI_DEVICE_ERROR; } - TcpServiceData = TCP4_FROM_THIS (Tcp4ServiceBinding); - - // - // Kill TCP driver - // - NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpRunQue) { - TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List); + TcpServiceData = TCP4_FROM_THIS (ServiceBinding); + if (NumberOfChildren == 0) { // - // Try to destroy this child + // Uninstall TCP servicebinding protocol // - Sock = TcpPcb->Sk; - TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved; - - if (TcpProto->TcpService == TcpServiceData) { - Status = SockDestroyChild (Sock); + gBS->UninstallMultipleProtocolInterfaces ( + NicHandle, + &gEfiTcp4ServiceBindingProtocolGuid, + ServiceBinding, + NULL + ); - if (EFI_ERROR (Status)) { + // + // Destroy the IpIO consumed by TCP driver + // + IpIoDestroy (TcpServiceData->IpIo); - TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp " - "instance failed with %r\n", Status)); - return Status; - } - } - } + // + // Destroy the heartbeat timer. + // + Tcp4DestroyTimer (); - NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mTcpListenQue) { - TcpPcb = NET_LIST_USER_STRUCT (Entry, TCP_CB, List); + // + // Clear the variable. + // + TcpClearVariableData (TcpServiceData); // - // Try to destroy this child + // Release the TCP service data // - Sock = TcpPcb->Sk; - TcpProto = (TCP4_PROTO_DATA *) Sock->ProtoReserved; + NetFreePool (TcpServiceData); + } else { - if (TcpProto->TcpService == TcpServiceData) { - Status = SockDestroyChild (TcpPcb->Sk); - if (EFI_ERROR (Status)) { + while (!NetListIsEmpty (&TcpServiceData->SocketList)) { + Sock = NET_LIST_HEAD (&TcpServiceData->SocketList, SOCKET, Link); - TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Destroy Tcp " - "instance failed with %r\n", Status)); - return Status; - } + ServiceBinding->DestroyChild (ServiceBinding, Sock->SockHandle); } } - // - // Uninstall TCP servicebinding protocol - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - NicHandle, - &gEfiTcp4ServiceBindingProtocolGuid, - Tcp4ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { - - TCP4_DEBUG_ERROR (("Tcp4DriverBindingStop: Uninstall TCP service " - "binding protocol failed with %r\n", Status)); - return Status; - } - - // - // Destroy the IpIO consumed by TCP driver - // - Status = IpIoDestroy (TcpServiceData->IpIo); - - // - // Destroy the heartbeat timer. - // - Tcp4DestroyTimer (); - - // - // Clear the variable. - // - TcpClearVariableData (TcpServiceData); - - // - // Release the TCP service data - // - NetFreePool (TcpServiceData); - return Status; } - /** Creates a child handle with a set of TCP4 services. @@ -608,9 +561,12 @@ Tcp4ServiceBindingCreateChild ( Sock->SockHandle ); SockDestroyChild (Sock); + } else { + NetListInsertTail (&TcpServiceData->SocketList, &Sock->Link); } ON_EXIT: + NET_RESTORE_TPL (OldTpl); return Status; } @@ -672,7 +628,9 @@ Tcp4ServiceBindingDestroyChild ( TcpProtoData = (TCP4_PROTO_DATA *) Sock->ProtoReserved; TcpServiceData = TcpProtoData->TcpService; - Status = SockDestroyChild (Sock); + NetListRemoveEntry (&Sock->Link); + + SockDestroyChild (Sock); // // Close the device path protocol diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h index 28fe53dc5a..9478a7b550 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h @@ -41,6 +41,7 @@ typedef struct _TCP4_SERVICE_DATA { EFI_SERVICE_BINDING_PROTOCOL Tcp4ServiceBinding; EFI_HANDLE DriverBindingHandle; CHAR16 *MacString; + NET_LIST_ENTRY SocketList; } TCP4_SERVICE_DATA; // diff --git a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c index 41516a9ad8..3930539d77 100644 --- a/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c +++ b/MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c @@ -426,6 +426,7 @@ TcpCloneTcb ( { TCP_CB *Clone; TCP4_SERVICE_DATA *TcpService; + EFI_IP4_PROTOCOL *Ip4; Clone = NetAllocatePool (sizeof (TCP_CB)); @@ -454,10 +455,13 @@ TcpCloneTcb ( ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpPcb = Clone; + TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService; + + NetListInsertTail (&TcpService->SocketList, &Clone->Sk->Link); + // // Open the device path on the handle where service binding resides on. // - TcpService = ((TCP4_PROTO_DATA *) (Clone->Sk->ProtoReserved))->TcpService; gBS->OpenProtocol ( TcpService->ControllerHandle, &gEfiDevicePathProtocolGuid, @@ -467,6 +471,18 @@ TcpCloneTcb ( EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); + // + // Open the ip protocol by child controller. + // + gBS->OpenProtocol ( + TcpService->IpIo->ChildHandle, + &gEfiIp4ProtocolGuid, + (VOID **) &Ip4, + TcpService->DriverBindingHandle, + Clone->Sk->SockHandle, + EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER + ); + return Clone; } diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c index 7e2bc451ae..7a7c184498 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c @@ -123,7 +123,8 @@ Udp4DriverBindingStart ( Status = Udp4CreateService (Udp4Service, This->DriverBindingHandle, ControllerHandle); if (EFI_ERROR (Status)) { - goto FREE_SERVICE; + NetFreePool (Udp4Service); + return Status; } // @@ -136,21 +137,12 @@ Udp4DriverBindingStart ( NULL ); if (EFI_ERROR (Status)) { - goto CLEAN_SERVICE; + Udp4CleanService (Udp4Service); + NetFreePool (Udp4Service); + } else { + Udp4SetVariableData (Udp4Service); } - Udp4SetVariableData (Udp4Service); - - return Status; - -CLEAN_SERVICE: - - Udp4CleanService (Udp4Service); - -FREE_SERVICE: - - NetFreePool (Udp4Service); - return Status; } @@ -188,7 +180,7 @@ Udp4DriverBindingStop ( // NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiIp4ProtocolGuid); if (NicHandle == NULL) { - return EFI_SUCCESS; + return EFI_DEVICE_ERROR; } // @@ -208,35 +200,30 @@ Udp4DriverBindingStop ( Udp4Service = UDP4_SERVICE_DATA_FROM_THIS (ServiceBinding); - // - // Uninstall the UDP4 ServiceBinding Protocol. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - NicHandle, - &gEfiUdp4ServiceBindingProtocolGuid, - &Udp4Service->ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { - return EFI_DEVICE_ERROR; - } + if (NumberOfChildren == 0) { - while (!NetListIsEmpty (&Udp4Service->ChildrenList)) { - // - // Destroy all instances. - // - Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link); + gBS->UninstallMultipleProtocolInterfaces ( + NicHandle, + &gEfiUdp4ServiceBindingProtocolGuid, + &Udp4Service->ServiceBinding, + NULL + ); - ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); - } + Udp4ClearVariableData (Udp4Service); - Udp4ClearVariableData (Udp4Service); + Udp4CleanService (Udp4Service); - Udp4CleanService (Udp4Service); + NetFreePool (Udp4Service); + } else { - NetFreePool (Udp4Service); + while (!NetListIsEmpty (&Udp4Service->ChildrenList)) { + Instance = NET_LIST_HEAD (&Udp4Service->ChildrenList, UDP4_INSTANCE_DATA, Link); - return EFI_SUCCESS; + ServiceBinding->DestroyChild (ServiceBinding, Instance->ChildHandle); + } + } + + return Status; } @@ -277,7 +264,7 @@ Udp4ServiceBindingCreateChild ( // // Allocate the instance private data structure. // - Instance = NetAllocatePool (sizeof (UDP4_INSTANCE_DATA)); + Instance = NetAllocateZeroPool (sizeof (UDP4_INSTANCE_DATA)); if (Instance == NULL) { return EFI_OUT_OF_RESOURCES; } @@ -290,7 +277,7 @@ Udp4ServiceBindingCreateChild ( Instance->IpInfo = IpIoAddIp (Udp4Service->IpIo); if (Instance->IpInfo == NULL) { Status = EFI_OUT_OF_RESOURCES; - goto FREE_INSTANCE; + goto ON_ERROR; } // @@ -303,7 +290,7 @@ Udp4ServiceBindingCreateChild ( NULL ); if (EFI_ERROR (Status)) { - goto REMOVE_IPINFO; + goto ON_ERROR; } Instance->ChildHandle = *ChildHandle; @@ -320,7 +307,7 @@ Udp4ServiceBindingCreateChild ( EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ); if (EFI_ERROR (Status)) { - goto UNINSTALL_PROTOCOL; + goto ON_ERROR; } OldTpl = NET_RAISE_TPL (NET_TPL_LOCK); @@ -333,22 +320,22 @@ Udp4ServiceBindingCreateChild ( NET_RESTORE_TPL (OldTpl); - return Status; - -UNINSTALL_PROTOCOL: - - gBS->UninstallMultipleProtocolInterfaces ( - Instance->ChildHandle, - &gEfiUdp4ProtocolGuid, - &Instance->Udp4Proto, - NULL - ); + return EFI_SUCCESS; -REMOVE_IPINFO: +ON_ERROR: - IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); + if (Instance->ChildHandle != NULL) { + gBS->UninstallMultipleProtocolInterfaces ( + Instance->ChildHandle, + &gEfiUdp4ProtocolGuid, + &Instance->Udp4Proto, + NULL + ); + } -FREE_INSTANCE: + if (Instance->IpInfo != NULL) { + IpIoRemoveIp (Udp4Service->IpIo, Instance->IpInfo); + } Udp4CleanInstance (Instance); diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c index 9cbd29511f..39924cfa7a 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c @@ -153,6 +153,8 @@ Udp4CreateService ( EFI_STATUS Status; IP_IO_OPEN_DATA OpenData; + NetZeroMem (Udp4Service, sizeof (UDP4_SERVICE_DATA)); + Udp4Service->Signature = UDP4_SERVICE_DATA_SIGNATURE; Udp4Service->ServiceBinding = mUdp4ServiceBinding; Udp4Service->ImageHandle = ImageHandle; @@ -184,7 +186,7 @@ Udp4CreateService ( // Status = IpIoOpen (Udp4Service->IpIo, &OpenData); if (EFI_ERROR (Status)) { - goto RELEASE_IPIO; + goto ON_ERROR; } // @@ -198,7 +200,7 @@ Udp4CreateService ( &Udp4Service->TimeoutEvent ); if (EFI_ERROR (Status)) { - goto RELEASE_IPIO; + goto ON_ERROR; } // @@ -210,18 +212,16 @@ Udp4CreateService ( UDP4_TIMEOUT_INTERVAL ); if (EFI_ERROR (Status)) { - goto RELEASE_ALL; + goto ON_ERROR; } - Udp4Service->MacString = NULL; - return EFI_SUCCESS; -RELEASE_ALL: - - gBS->CloseEvent (Udp4Service->TimeoutEvent); +ON_ERROR: -RELEASE_IPIO: + if (Udp4Service->TimeoutEvent != NULL) { + gBS->CloseEvent (Udp4Service->TimeoutEvent); + } IpIoDestroy (Udp4Service->IpIo); diff --git a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c index 93a5cee35b..9d3b20a8a6 100644 --- a/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c +++ b/MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c @@ -291,7 +291,7 @@ Udp4Configure ( // Udp4FlushRcvdDgram (Instance); -////bugbug ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue)); + ASSERT (NetListIsEmpty (&Instance->DeliveredDgramQue)); } Udp4SetVariableData (Instance->Udp4Service);