summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MdeModulePkg/Include/Library/NetLib.h4
-rw-r--r--MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.c6
-rw-r--r--MdeModulePkg/Universal/Network/ArpDxe/ArpDriver.c55
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c61
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.c365
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Impl.h8
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.c77
-rw-r--r--MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Io.h8
-rw-r--r--MdeModulePkg/Universal/Network/DpcDxe/Dpc.c3
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Driver.c123
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c1
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Impl.h2
-rw-r--r--MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Input.c2
-rw-r--r--MdeModulePkg/Universal/Network/MnpDxe/MnpDriver.c82
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Driver.c45
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Impl.c10
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Rrq.c26
-rw-r--r--MdeModulePkg/Universal/Network/Mtftp4Dxe/Mtftp4Support.c4
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/SockImpl.c1
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Socket.h1
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.c138
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Driver.h1
-rw-r--r--MdeModulePkg/Universal/Network/Tcp4Dxe/Tcp4Misc.c18
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Driver.c97
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Impl.c18
-rw-r--r--MdeModulePkg/Universal/Network/Udp4Dxe/Udp4Main.c2
26 files changed, 762 insertions, 396 deletions
diff --git a/MdeModulePkg/Include/Library/NetLib.h b/MdeModulePkg/Include/Library/NetLib.h
index c843b6c..4a621e1 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 279ada7..2dd6e60 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 af2e082..aa99ff5 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 9549790..4d78b87 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 e8e9b38..50f1a2f 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 7a04109..15b2270 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 8adf40f..442deeb 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 560c791..1caba3a 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 cccedf5..3f534fc 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 bf43677..589eca5 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 eaed123..a7a230d 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 aba5055..94b4534 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 b2308c6..06a0110 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 814566e..946ace1 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 1186249..f6f431d 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 3ce8792..0bd835b 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 906cce8..7c2114e 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 ce9db68..e56aa15 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 585d91b..a7fa3b6 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 34b098b..b63eaa0 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 1d9138b..e2a78b7 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 28fe53d..9478a7b 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 41516a9..3930539 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 7e2bc45..7a7c184 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 9cbd295..39924cf 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 93a5cee..9d3b20a 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);