]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/ArpDxe/ArpImpl.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / ArpDxe / ArpImpl.c
index 52b6e21652c630fa654153a80674649a92ffa654..0e9ef103eff9c31d1f34fb5a1feae5bd97021bed 100644 (file)
@@ -1,27 +1,16 @@
 /** @file\r
+  The implementation of the ARP protocol.\r
 \r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-Module Name:\r
-\r
-  ArpImpl.c\r
-\r
-Abstract:\r
-\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
-\r
 #include "ArpImpl.h"\r
-#include "ArpDebug.h"\r
 \r
+//\r
+// Global variable of EFI ARP Protocol Interface.\r
+//\r
 EFI_ARP_PROTOCOL  mEfiArpProtocolTemplate = {\r
   ArpConfigure,\r
   ArpAdd,\r
@@ -36,17 +25,17 @@ EFI_ARP_PROTOCOL  mEfiArpProtocolTemplate = {
 /**\r
   Initialize the instance context data.\r
 \r
-  @param  ArpService             Pointer to the arp service context data this\r
+  @param[in]   ArpService        Pointer to the arp service context data this\r
                                  instance belongs to.\r
-  @param  Instance               Pointer to the instance context data.\r
+  @param[out]  Instance          Pointer to the instance context data.\r
 \r
   @return None.\r
 \r
 **/\r
 VOID\r
 ArpInitInstance (\r
-  IN ARP_SERVICE_DATA   *ArpService,\r
-  IN ARP_INSTANCE_DATA  *Instance\r
+  IN  ARP_SERVICE_DATA   *ArpService,\r
+  OUT ARP_INSTANCE_DATA  *Instance\r
   )\r
 {\r
   NET_CHECK_SIGNATURE (ArpService, ARP_SERVICE_DATA_SIGNATURE);\r
@@ -57,17 +46,16 @@ ArpInitInstance (
   CopyMem (&Instance->ArpProto, &mEfiArpProtocolTemplate, sizeof (Instance->ArpProto));\r
 \r
   Instance->Configured = FALSE;\r
-  Instance->Destroyed  = FALSE;\r
+  Instance->InDestroy  = FALSE;\r
 \r
-  NetListInit (&Instance->List);\r
+  InitializeListHead (&Instance->List);\r
 }\r
 \r
 \r
 /**\r
   Process the Arp packets received from Mnp, the procedure conforms to RFC826.\r
 \r
-  @param  Event                  The Event this notify function registered to.\r
-  @param  Context                Pointer to the context data registerd to the\r
+  @param[in]  Context            Pointer to the context data registerd to the\r
                                  Event.\r
 \r
   @return None.\r
@@ -75,8 +63,7 @@ ArpInitInstance (
 **/\r
 VOID\r
 EFIAPI\r
-ArpOnFrameRcvd (\r
-  IN EFI_EVENT  Event,\r
+ArpOnFrameRcvdDpc (\r
   IN VOID       *Context\r
   )\r
 {\r
@@ -87,7 +74,7 @@ ArpOnFrameRcvd (
   ARP_HEAD                              *Head;\r
   ARP_ADDRESS                           ArpAddress;\r
   ARP_CACHE_ENTRY                       *CacheEntry;\r
-  NET_LIST_ENTRY                        *Entry;\r
+  LIST_ENTRY                            *Entry;\r
   ARP_INSTANCE_DATA                     *Instance;\r
   EFI_ARP_CONFIG_DATA                   *ConfigData;\r
   NET_ARP_ADDRESS                       SenderAddress[2];\r
@@ -119,15 +106,28 @@ ArpOnFrameRcvd (
   // Status is EFI_SUCCESS, process the received frame.\r
   //\r
   RxData = RxToken->Packet.RxData;\r
-  Head   = (ARP_HEAD *) RxData->PacketData;\r
+  //\r
+  // Sanity check.\r
+  //\r
+  if (RxData->DataLength < sizeof (ARP_HEAD)) {\r
+    //\r
+    // Restart the receiving if packet size is not correct.\r
+    //\r
+    goto RESTART_RECEIVE;\r
+  }\r
 \r
   //\r
   // Convert the byte order of the multi-byte fields.\r
   //\r
+  Head   = (ARP_HEAD *) RxData->PacketData;\r
   Head->HwType    = NTOHS (Head->HwType);\r
   Head->ProtoType = NTOHS (Head->ProtoType);\r
   Head->OpCode    = NTOHS (Head->OpCode);\r
 \r
+  if (RxData->DataLength < (sizeof (ARP_HEAD) + 2 * Head->HwAddrLen + 2 * Head->ProtoAddrLen)) {\r
+    goto RESTART_RECEIVE;\r
+  }\r
+\r
   if ((Head->HwType != ArpService->SnpMode.IfType) ||\r
     (Head->HwAddrLen != ArpService->SnpMode.HwAddressSize) ||\r
     (RxData->ProtocolType != ARP_ETHER_PROTO_TYPE)) {\r
@@ -146,11 +146,6 @@ ArpOnFrameRcvd (
   ArpAddress.TargetHwAddr    = ArpAddress.SenderProtoAddr + Head->ProtoAddrLen;\r
   ArpAddress.TargetProtoAddr = ArpAddress.TargetHwAddr + Head->HwAddrLen;\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    ARP_DEBUG_ERROR (("ArpOnFrameRcvd: Faild to acquire the CacheTableLock.\n"));\r
-    goto RECYCLE_RXDATA;\r
-  }\r
-\r
   SenderAddress[Hardware].Type       = Head->HwType;\r
   SenderAddress[Hardware].Length     = Head->HwAddrLen;\r
   SenderAddress[Hardware].AddressPtr = ArpAddress.SenderHwAddr;\r
@@ -172,7 +167,7 @@ ArpOnFrameRcvd (
     // This address (either hardware or protocol address, or both) is configured to\r
     // be a deny entry, silently skip the normal process.\r
     //\r
-    goto UNLOCK_EXIT;\r
+    goto RECYCLE_RXDATA;\r
   }\r
 \r
   ProtoMatched = FALSE;\r
@@ -193,7 +188,7 @@ ArpOnFrameRcvd (
       // The protocol type is matched for the received arp packet.\r
       //\r
       ProtoMatched = TRUE;\r
-      if (0 == NetCompareMem (\r
+      if (0 == CompareMem (\r
                  (VOID *)ArpAddress.TargetProtoAddr,\r
                  ConfigData->StationAddress,\r
                  ConfigData->SwAddressLength\r
@@ -211,7 +206,7 @@ ArpOnFrameRcvd (
     //\r
     // Protocol type unmatchable, skip.\r
     //\r
-    goto UNLOCK_EXIT;\r
+    goto RECYCLE_RXDATA;\r
   }\r
 \r
   //\r
@@ -238,7 +233,7 @@ ArpOnFrameRcvd (
     //\r
     // This arp packet isn't targeted to us, skip now.\r
     //\r
-    goto UNLOCK_EXIT;\r
+    goto RECYCLE_RXDATA;\r
   }\r
 \r
   if (!MergeFlag) {\r
@@ -259,12 +254,12 @@ ArpOnFrameRcvd (
       //\r
       CacheEntry = ArpAllocCacheEntry (NULL);\r
       if (CacheEntry == NULL) {\r
-        goto UNLOCK_EXIT;\r
+        goto RECYCLE_RXDATA;\r
       }\r
     }\r
 \r
     if (!IsListEmpty (&CacheEntry->List)) {\r
-      NetListRemoveEntry (&CacheEntry->List);\r
+      RemoveEntryList (&CacheEntry->List);\r
     }\r
 \r
     //\r
@@ -284,7 +279,7 @@ ArpOnFrameRcvd (
     //\r
     // Add this entry into the ResolvedCacheTable\r
     //\r
-    NetListInsertHead (&ArpService->ResolvedCacheTable, &CacheEntry->List);\r
+    InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List);\r
   }\r
 \r
   if (Head->OpCode == ARP_OPCODE_REQUEST) {\r
@@ -295,10 +290,6 @@ ArpOnFrameRcvd (
     ArpSendFrame (Instance, CacheEntry, ARP_OPCODE_REPLY);\r
   }\r
 \r
-UNLOCK_EXIT:\r
-\r
-  NET_UNLOCK (&ArpService->Lock);\r
-\r
 RECYCLE_RXDATA:\r
 \r
   //\r
@@ -315,27 +306,47 @@ RESTART_RECEIVE:
 \r
   DEBUG_CODE (\r
     if (EFI_ERROR (Status)) {\r
-      ARP_DEBUG_ERROR (("ArpOnFrameRcvd: ArpService->Mnp->Receive "\r
+      DEBUG ((EFI_D_ERROR, "ArpOnFrameRcvd: ArpService->Mnp->Receive "\r
         "failed, %r\n.", Status));\r
     }\r
   );\r
 }\r
 \r
+/**\r
+  Queue ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK.\r
+\r
+  @param[in]  Event                  The Event this notify function registered to.\r
+  @param[in]  Context                Pointer to the context data registerd to the\r
+                                     Event.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ArpOnFrameRcvd (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  //\r
+  // Request ArpOnFrameRcvdDpc as a DPC at TPL_CALLBACK\r
+  //\r
+  QueueDpc (TPL_CALLBACK, ArpOnFrameRcvdDpc, Context);\r
+}\r
 \r
 /**\r
   Process the already sent arp packets.\r
 \r
-  @param  Event                  The Event this notify function registered to.\r
-  @param  Context                Pointer to the context data registerd to the\r
-                                 Event.\r
+  @param[in]  Context                Pointer to the context data registerd to the\r
+                                     Event.\r
 \r
   @return None.\r
 \r
 **/\r
 VOID\r
 EFIAPI\r
-ArpOnFrameSent (\r
-  IN EFI_EVENT  Event,\r
+ArpOnFrameSentDpc (\r
   IN VOID       *Context\r
   )\r
 {\r
@@ -349,26 +360,49 @@ ArpOnFrameSent (
 \r
   DEBUG_CODE (\r
     if (EFI_ERROR (TxToken->Status)) {\r
-      ARP_DEBUG_ERROR (("ArpOnFrameSent: TxToken->Status, %r.\n", TxToken->Status));\r
+      DEBUG ((EFI_D_ERROR, "ArpOnFrameSent: TxToken->Status, %r.\n", TxToken->Status));\r
     }\r
   );\r
 \r
   //\r
   // Free the allocated memory and close the event.\r
   //\r
-  NetFreePool (TxData->FragmentTable[0].FragmentBuffer);\r
-  NetFreePool (TxData);\r
+  FreePool (TxData->FragmentTable[0].FragmentBuffer);\r
+  FreePool (TxData);\r
   gBS->CloseEvent (TxToken->Event);\r
-  NetFreePool (TxToken);\r
+  FreePool (TxToken);\r
+}\r
+\r
+/**\r
+  Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK.\r
+\r
+  @param[in]  Event                  The Event this notify function registered to.\r
+  @param[in]  Context                Pointer to the context data registerd to the\r
+                                     Event.\r
+\r
+  @return None.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ArpOnFrameSent (\r
+  IN EFI_EVENT  Event,\r
+  IN VOID       *Context\r
+  )\r
+{\r
+  //\r
+  // Request ArpOnFrameSentDpc as a DPC at TPL_CALLBACK\r
+  //\r
+  QueueDpc (TPL_CALLBACK, ArpOnFrameSentDpc, Context);\r
 }\r
 \r
 \r
 /**\r
   Process the arp cache olding and drive the retrying arp requests.\r
 \r
-  @param  Event                  The Event this notify function registered to.\r
-  @param  Context                Pointer to the context data registerd to the\r
-                                 Event.\r
+  @param[in]  Event                  The Event this notify function registered to.\r
+  @param[in]  Context                Pointer to the context data registerd to the\r
+                                     Event.\r
 \r
   @return None.\r
 \r
@@ -381,19 +415,15 @@ ArpTimerHandler (
   )\r
 {\r
   ARP_SERVICE_DATA      *ArpService;\r
-  NET_LIST_ENTRY        *Entry;\r
-  NET_LIST_ENTRY        *NextEntry;\r
-  NET_LIST_ENTRY        *ContextEntry;\r
+  LIST_ENTRY            *Entry;\r
+  LIST_ENTRY            *NextEntry;\r
+  LIST_ENTRY            *ContextEntry;\r
   ARP_CACHE_ENTRY       *CacheEntry;\r
   USER_REQUEST_CONTEXT  *RequestContext;\r
 \r
   ASSERT (Context != NULL);\r
   ArpService = (ARP_SERVICE_DATA *)Context;\r
 \r
-  if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) {\r
-    return;\r
-  }\r
-\r
   //\r
   // Iterate all the pending requests to see whether a retry is needed to send out\r
   // or the request finally fails because the retry time reaches the limitation.\r
@@ -411,15 +441,15 @@ ArpTimerHandler (
         // Abort this request.\r
         //\r
         ArpAddressResolved (CacheEntry, NULL, NULL);\r
-        ASSERT (NetListIsEmpty (&CacheEntry->UserRequestList));\r
+        ASSERT (IsListEmpty (&CacheEntry->UserRequestList));\r
 \r
-        NetListRemoveEntry (&CacheEntry->List);\r
-        NetFreePool (CacheEntry);\r
+        RemoveEntryList (&CacheEntry->List);\r
+        FreePool (CacheEntry);\r
       } else {\r
         //\r
         // resend the ARP request.\r
         //\r
-        ASSERT (!NetListIsEmpty(&CacheEntry->UserRequestList));\r
+        ASSERT (!IsListEmpty(&CacheEntry->UserRequestList));\r
 \r
         ContextEntry   = CacheEntry->UserRequestList.ForwardLink;\r
         RequestContext = NET_LIST_USER_STRUCT (ContextEntry, USER_REQUEST_CONTEXT, List);\r
@@ -442,7 +472,7 @@ ArpTimerHandler (
   //\r
   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &ArpService->DeniedCacheTable) {\r
     CacheEntry = NET_LIST_USER_STRUCT (Entry, ARP_CACHE_ENTRY, List);\r
-    ASSERT (NetListIsEmpty (&CacheEntry->UserRequestList));\r
+    ASSERT (IsListEmpty (&CacheEntry->UserRequestList));\r
 \r
     if (CacheEntry->DefaultDecayTime == 0) {\r
       //\r
@@ -455,8 +485,8 @@ ArpTimerHandler (
       //\r
       // Time out, remove it.\r
       //\r
-      NetListRemoveEntry (&CacheEntry->List);\r
-      NetFreePool (CacheEntry);\r
+      RemoveEntryList (&CacheEntry->List);\r
+      FreePool (CacheEntry);\r
     } else {\r
       //\r
       // Update the DecayTime.\r
@@ -470,7 +500,7 @@ ArpTimerHandler (
   //\r
   NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &ArpService->ResolvedCacheTable) {\r
     CacheEntry = NET_LIST_USER_STRUCT (Entry, ARP_CACHE_ENTRY, List);\r
-    ASSERT (NetListIsEmpty (&CacheEntry->UserRequestList));\r
+    ASSERT (IsListEmpty (&CacheEntry->UserRequestList));\r
 \r
     if (CacheEntry->DefaultDecayTime == 0) {\r
       //\r
@@ -483,8 +513,8 @@ ArpTimerHandler (
       //\r
       // Time out, remove it.\r
       //\r
-      NetListRemoveEntry (&CacheEntry->List);\r
-      NetFreePool (CacheEntry);\r
+      RemoveEntryList (&CacheEntry->List);\r
+      FreePool (CacheEntry);\r
     } else {\r
       //\r
       // Update the DecayTime.\r
@@ -492,27 +522,26 @@ ArpTimerHandler (
       CacheEntry->DecayTime -= ARP_PERIODIC_TIMER_INTERVAL;\r
     }\r
   }\r
-\r
-  NET_UNLOCK (&ArpService->Lock);\r
 }\r
 \r
 \r
 /**\r
   Match the two NET_ARP_ADDRESSes.\r
 \r
-  @param  AddressOne             Pointer to the first address to match.\r
-  @param  AddressTwo             Pointer to the second address to match.\r
+  @param[in]  AddressOne             Pointer to the first address to match.\r
+  @param[in]  AddressTwo             Pointer to the second address to match.\r
 \r
   @return The two addresses match or not.\r
 \r
 **/\r
-STATIC\r
 BOOLEAN\r
 ArpMatchAddress (\r
   IN NET_ARP_ADDRESS  *AddressOne,\r
   IN NET_ARP_ADDRESS  *AddressTwo\r
   )\r
 {\r
+  ASSERT (AddressOne != NULL && AddressTwo != NULL);\r
+\r
   if ((AddressOne->Type != AddressTwo->Type) ||\r
     (AddressOne->Length != AddressTwo->Length)) {\r
     //\r
@@ -522,7 +551,7 @@ ArpMatchAddress (
   }\r
 \r
   if ((AddressOne->AddressPtr != NULL) &&\r
-    (NetCompareMem (\r
+    (CompareMem (\r
       AddressOne->AddressPtr,\r
       AddressTwo->AddressPtr,\r
       AddressOne->Length\r
@@ -540,26 +569,26 @@ ArpMatchAddress (
 /**\r
   Find the CacheEntry which matches the requirements in the specified CacheTable.\r
 \r
-  @param  CacheTable             Pointer to the arp cache table.\r
-  @param  StartEntry             Pointer to the start entry this search begins with\r
-                                 in the cache table.\r
-  @param  FindOpType             The search type.\r
-  @param  ProtocolAddress        Pointer to the protocol address to match.\r
-  @param  HardwareAddress        Pointer to the hardware address to match.\r
+  @param[in]  CacheTable             Pointer to the arp cache table.\r
+  @param[in]  StartEntry             Pointer to the start entry this search begins with\r
+                                     in the cache table.\r
+  @param[in]  FindOpType             The search type.\r
+  @param[in]  ProtocolAddress        Pointer to the protocol address to match.\r
+  @param[in]  HardwareAddress        Pointer to the hardware address to match.\r
 \r
   @return Pointer to the matched arp cache entry, if NULL, no match is found.\r
 \r
 **/\r
 ARP_CACHE_ENTRY *\r
 ArpFindNextCacheEntryInTable (\r
-  IN NET_LIST_ENTRY    *CacheTable,\r
-  IN NET_LIST_ENTRY    *StartEntry,\r
+  IN LIST_ENTRY        *CacheTable,\r
+  IN LIST_ENTRY        *StartEntry,\r
   IN FIND_OPTYPE       FindOpType,\r
   IN NET_ARP_ADDRESS   *ProtocolAddress OPTIONAL,\r
   IN NET_ARP_ADDRESS   *HardwareAddress OPTIONAL\r
   )\r
 {\r
-  NET_LIST_ENTRY   *Entry;\r
+  LIST_ENTRY       *Entry;\r
   ARP_CACHE_ENTRY  *CacheEntry;\r
 \r
   if (StartEntry == NULL) {\r
@@ -572,7 +601,7 @@ ArpFindNextCacheEntryInTable (
   for (Entry = StartEntry->ForwardLink; Entry != CacheTable; Entry = Entry->ForwardLink) {\r
     CacheEntry = NET_LIST_USER_STRUCT (Entry, ARP_CACHE_ENTRY, List);\r
 \r
-    if (FindOpType & MATCH_SW_ADDRESS) {\r
+    if ((FindOpType & MATCH_SW_ADDRESS) != 0) {\r
       //\r
       // Find by the software address.\r
       //\r
@@ -584,7 +613,7 @@ ArpFindNextCacheEntryInTable (
       }\r
     }\r
 \r
-    if (FindOpType & MATCH_HW_ADDRESS) {\r
+    if ((FindOpType & MATCH_HW_ADDRESS) != 0) {\r
       //\r
       // Find by the hardware address.\r
       //\r
@@ -613,9 +642,9 @@ ArpFindNextCacheEntryInTable (
   Find the CacheEntry, using ProtocolAddress or HardwareAddress or both, as the keyword,\r
   in the DeniedCacheTable.\r
 \r
-  @param  ArpService             Pointer to the arp service context data.\r
-  @param  ProtocolAddress        Pointer to the protocol address.\r
-  @param  HardwareAddress        Pointer to the hardware address.\r
+  @param[in]  ArpService             Pointer to the arp service context data.\r
+  @param[in]  ProtocolAddress        Pointer to the protocol address.\r
+  @param[in]  HardwareAddress        Pointer to the hardware address.\r
 \r
   @return Pointer to the matched cache entry, if NULL no match is found.\r
 \r
@@ -673,7 +702,7 @@ ArpFindDeniedCacheEntry (
 /**\r
   Allocate a cache entry and initialize it.\r
 \r
-  @param  Instance               Pointer to the instance context data.\r
+  @param[in]  Instance               Pointer to the instance context data.\r
 \r
   @return Pointer to the new created cache entry.\r
 \r
@@ -690,7 +719,7 @@ ArpAllocCacheEntry (
   //\r
   // Allocate memory for the cache entry.\r
   //\r
-  CacheEntry = NetAllocatePool (sizeof (ARP_CACHE_ENTRY));\r
+  CacheEntry = AllocatePool (sizeof (ARP_CACHE_ENTRY));\r
   if (CacheEntry == NULL) {\r
     return NULL;\r
   }\r
@@ -698,8 +727,8 @@ ArpAllocCacheEntry (
   //\r
   // Init the lists.\r
   //\r
-  NetListInit (&CacheEntry->List);\r
-  NetListInit (&CacheEntry->UserRequestList);\r
+  InitializeListHead (&CacheEntry->List);\r
+  InitializeListHead (&CacheEntry->UserRequestList);\r
 \r
   for (Index = 0; Index < 2; Index++) {\r
     //\r
@@ -712,7 +741,7 @@ ArpAllocCacheEntry (
   //\r
   // Zero the hardware address first.\r
   //\r
-  NetZeroMem (CacheEntry->Addresses[Hardware].AddressPtr, ARP_MAX_HARDWARE_ADDRESS_LEN);\r
+  ZeroMem (CacheEntry->Addresses[Hardware].AddressPtr, ARP_MAX_HARDWARE_ADDRESS_LEN);\r
 \r
   if (Instance != NULL) {\r
     //\r
@@ -740,9 +769,9 @@ ArpAllocCacheEntry (
 /**\r
   Turn the CacheEntry into the resolved status.\r
 \r
-  @param  CacheEntry             Pointer to the resolved cache entry.\r
-  @param  Instance               Pointer to the instance context data.\r
-  @param  UserEvent              Pointer to the UserEvent to notify.\r
+  @param[in]  CacheEntry             Pointer to the resolved cache entry.\r
+  @param[in]  Instance               Pointer to the instance context data.\r
+  @param[in]  UserEvent              Pointer to the UserEvent to notify.\r
 \r
   @return The count of notifications sent to the instance.\r
 \r
@@ -754,8 +783,8 @@ ArpAddressResolved (
   IN EFI_EVENT          UserEvent OPTIONAL\r
   )\r
 {\r
-  NET_LIST_ENTRY        *Entry;\r
-  NET_LIST_ENTRY        *NextEntry;\r
+  LIST_ENTRY            *Entry;\r
+  LIST_ENTRY            *NextEntry;\r
   USER_REQUEST_CONTEXT  *Context;\r
   UINTN                 Count;\r
 \r
@@ -772,7 +801,7 @@ ArpAddressResolved (
       //\r
       // Copy the address to the user-provided buffer and notify the user.\r
       //\r
-      NetCopyMem (\r
+      CopyMem (\r
         Context->UserHwAddrBuffer,\r
         CacheEntry->Addresses[Hardware].AddressPtr,\r
         CacheEntry->Addresses[Hardware].Length\r
@@ -782,13 +811,18 @@ ArpAddressResolved (
       //\r
       // Remove this user request and free the context data.\r
       //\r
-      NetListRemoveEntry (&Context->List);\r
-      NetFreePool (Context);\r
+      RemoveEntryList (&Context->List);\r
+      FreePool (Context);\r
 \r
       Count++;\r
     }\r
   }\r
 \r
+  //\r
+  // Dispatch the DPCs queued by the NotifyFunction of the Context->UserRequestEvent.\r
+  //\r
+  DispatchDpc ();\r
+\r
   return Count;\r
 }\r
 \r
@@ -797,9 +831,9 @@ ArpAddressResolved (
   Fill the addresses in the CacheEntry using the information passed in by\r
   HwAddr and SwAddr.\r
 \r
-  @param  CacheEntry             Pointer to the cache entry.\r
-  @param  HwAddr                 Pointer to the software address.\r
-  @param  SwAddr                 Pointer to the hardware address.\r
+  @param[in]  CacheEntry             Pointer to the cache entry.\r
+  @param[in]  HwAddr                 Pointer to the software address.\r
+  @param[in]  SwAddr                 Pointer to the hardware address.\r
 \r
   @return None.\r
 \r
@@ -832,7 +866,7 @@ ArpFillAddressInCacheEntry (
         //\r
         // Copy it if the AddressPtr points to some buffer.\r
         //\r
-        NetCopyMem (\r
+        CopyMem (\r
           CacheAddress->AddressPtr,\r
           Address[Index]->AddressPtr,\r
           CacheAddress->Length\r
@@ -841,7 +875,7 @@ ArpFillAddressInCacheEntry (
         //\r
         // Zero the corresponding address buffer in the CacheEntry.\r
         //\r
-        NetZeroMem (CacheAddress->AddressPtr, CacheAddress->Length);\r
+        ZeroMem (CacheAddress->AddressPtr, CacheAddress->Length);\r
       }\r
     }\r
   }\r
@@ -851,9 +885,9 @@ ArpFillAddressInCacheEntry (
 /**\r
   Configure the instance using the ConfigData. ConfigData is already validated.\r
 \r
-  @param  Instance               Pointer to the instance context data to be\r
+  @param[in]  Instance           Pointer to the instance context data to be\r
                                  configured.\r
-  @param  ConfigData             Pointer to the configuration data used to\r
+  @param[in]  ConfigData         Pointer to the configuration data used to\r
                                  configure the instance.\r
 \r
   @retval EFI_SUCCESS            The instance is configured with the ConfigData.\r
@@ -885,7 +919,7 @@ ArpConfigureInstance (
       //\r
       if ((OldConfigData->SwAddressType != ConfigData->SwAddressType) ||\r
         (OldConfigData->SwAddressLength != ConfigData->SwAddressLength) ||\r
-        (NetCompareMem (\r
+        (CompareMem (\r
            OldConfigData->StationAddress,\r
            ConfigData->StationAddress,\r
            OldConfigData->SwAddressLength\r
@@ -900,12 +934,12 @@ ArpConfigureInstance (
       // The instance is not configured.\r
       //\r
 \r
-      if (ConfigData->SwAddressType == IPv4_ETHER_PROTO_TYPE) {\r
-        NetCopyMem (&Ip, ConfigData->StationAddress, sizeof (IP4_ADDR));\r
+      if (ConfigData->SwAddressType == IPV4_ETHER_PROTO_TYPE) {\r
+        CopyMem (&Ip, ConfigData->StationAddress, sizeof (IP4_ADDR));\r
 \r
-        if (!Ip4IsUnicast (NTOHL (Ip), 0)) {\r
+        if (IP4_IS_UNSPECIFIED (Ip) || IP4_IS_LOCAL_BROADCAST (Ip)) {\r
           //\r
-          // The station address is not a valid IPv4 unicast address.\r
+          // The station address should not be zero or broadcast address.\r
           //\r
           return EFI_INVALID_PARAMETER;\r
         }\r
@@ -916,9 +950,9 @@ ArpConfigureInstance (
       //\r
       CopyMem (OldConfigData, ConfigData, sizeof (*OldConfigData));\r
 \r
-      OldConfigData->StationAddress = NetAllocatePool (OldConfigData->SwAddressLength);\r
+      OldConfigData->StationAddress = AllocatePool (OldConfigData->SwAddressLength);\r
       if (OldConfigData->StationAddress == NULL) {\r
-        ARP_DEBUG_ERROR (("ArpConfigInstance: NetAllocatePool for the StationAddress "\r
+        DEBUG ((EFI_D_ERROR, "ArpConfigInstance: AllocatePool for the StationAddress "\r
           "failed.\n"));\r
         return EFI_OUT_OF_RESOURCES;\r
       }\r
@@ -926,7 +960,7 @@ ArpConfigureInstance (
       //\r
       // Save the StationAddress.\r
       //\r
-      NetCopyMem (\r
+      CopyMem (\r
         OldConfigData->StationAddress,\r
         ConfigData->StationAddress,\r
         OldConfigData->SwAddressLength\r
@@ -958,12 +992,12 @@ ArpConfigureInstance (
       //\r
       // Cancel the arp requests issued by this instance.\r
       //\r
-      ArpCancelRequest (Instance, NULL, NULL);\r
+      Instance->ArpProto.Cancel (&Instance->ArpProto, NULL, NULL);\r
 \r
       //\r
       // Free the buffer previously allocated to hold the station address.\r
       //\r
-      NetFreePool (OldConfigData->StationAddress);\r
+      FreePool (OldConfigData->StationAddress);\r
     }\r
 \r
     Instance->Configured = FALSE;\r
@@ -976,11 +1010,11 @@ ArpConfigureInstance (
 /**\r
   Send out an arp frame using the CachEntry and the ArpOpCode.\r
 \r
-  @param  Instance               Pointer to the instance context data.\r
-  @param  CacheEntry             Pointer to the configuration data used to\r
-                                 configure the instance.\r
-  @param  ArpOpCode              The opcode used to send out this Arp frame, either\r
-                                 request or reply.\r
+  @param[in]  Instance               Pointer to the instance context data.\r
+  @param[in]  CacheEntry             Pointer to the configuration data used to\r
+                                     configure the instance.\r
+  @param[in]  ArpOpCode              The opcode used to send out this Arp frame, either\r
+                                     request or reply.\r
 \r
   @return None.\r
 \r
@@ -1008,9 +1042,9 @@ ArpSendFrame (
   //\r
   // Allocate memory for the TxToken.\r
   //\r
-  TxToken = NetAllocatePool (sizeof(EFI_MANAGED_NETWORK_COMPLETION_TOKEN));\r
+  TxToken = AllocatePool (sizeof(EFI_MANAGED_NETWORK_COMPLETION_TOKEN));\r
   if (TxToken == NULL) {\r
-    ARP_DEBUG_ERROR (("ArpSendFrame: Allocate memory for TxToken failed.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpSendFrame: Allocate memory for TxToken failed.\n"));\r
     return;\r
   }\r
 \r
@@ -1023,22 +1057,22 @@ ArpSendFrame (
   //\r
   Status = gBS->CreateEvent (\r
                   EVT_NOTIFY_SIGNAL,\r
-                  NET_TPL_EVENT,\r
+                  TPL_NOTIFY,\r
                   ArpOnFrameSent,\r
                   (VOID *)TxToken,\r
                   &TxToken->Event\r
                   );\r
   if (EFI_ERROR (Status)) {\r
-    ARP_DEBUG_ERROR (("ArpSendFrame: CreateEvent failed for TxToken->Event.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpSendFrame: CreateEvent failed for TxToken->Event.\n"));\r
     goto CLEAN_EXIT;\r
   }\r
 \r
   //\r
   // Allocate memory for the TxData used in the TxToken.\r
   //\r
-  TxData = NetAllocatePool (sizeof(EFI_MANAGED_NETWORK_TRANSMIT_DATA));\r
+  TxData = AllocatePool (sizeof(EFI_MANAGED_NETWORK_TRANSMIT_DATA));\r
   if (TxData == NULL) {\r
-    ARP_DEBUG_ERROR (("ArpSendFrame: Allocate memory for TxData failed.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpSendFrame: Allocate memory for TxData failed.\n"));\r
     goto CLEAN_EXIT;\r
   }\r
 \r
@@ -1055,9 +1089,10 @@ ArpSendFrame (
   //\r
   // Allocate buffer for the arp frame.\r
   //\r
-  Packet = NetAllocatePool (TotalLength);\r
+  Packet = AllocatePool (TotalLength);\r
   if (Packet == NULL) {\r
-    ARP_DEBUG_ERROR (("ArpSendFrame: Allocate memory for Packet failed.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpSendFrame: Allocate memory for Packet failed.\n"));\r
+    ASSERT (Packet != NULL);\r
   }\r
 \r
   TmpPtr = Packet;\r
@@ -1066,9 +1101,9 @@ ArpSendFrame (
   // The destination MAC address.\r
   //\r
   if (ArpOpCode == ARP_OPCODE_REQUEST) {\r
-    NetCopyMem (TmpPtr, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);\r
+    CopyMem (TmpPtr, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize);\r
   } else {\r
-    NetCopyMem (\r
+    CopyMem (\r
       TmpPtr,\r
       CacheEntry->Addresses[Hardware].AddressPtr,\r
       SnpMode->HwAddressSize\r
@@ -1079,7 +1114,7 @@ ArpSendFrame (
   //\r
   // The source MAC address.\r
   //\r
-  NetCopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);\r
+  CopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);\r
   TmpPtr += SnpMode->HwAddressSize;\r
 \r
   //\r
@@ -1102,19 +1137,19 @@ ArpSendFrame (
   //\r
   // The sender hardware address.\r
   //\r
-  NetCopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);\r
+  CopyMem (TmpPtr, &SnpMode->CurrentAddress, SnpMode->HwAddressSize);\r
   TmpPtr += SnpMode->HwAddressSize;\r
 \r
   //\r
   // The sender protocol address.\r
   //\r
-  NetCopyMem (TmpPtr, ConfigData->StationAddress, ConfigData->SwAddressLength);\r
+  CopyMem (TmpPtr, ConfigData->StationAddress, ConfigData->SwAddressLength);\r
   TmpPtr += ConfigData->SwAddressLength;\r
 \r
   //\r
   // The target hardware address.\r
   //\r
-  NetCopyMem (\r
+  CopyMem (\r
     TmpPtr,\r
     CacheEntry->Addresses[Hardware].AddressPtr,\r
     SnpMode->HwAddressSize\r
@@ -1124,7 +1159,7 @@ ArpSendFrame (
   //\r
   // The target protocol address.\r
   //\r
-  NetCopyMem (\r
+  CopyMem (\r
     TmpPtr,\r
     CacheEntry->Addresses[Protocol].AddressPtr,\r
     ConfigData->SwAddressLength\r
@@ -1154,7 +1189,7 @@ ArpSendFrame (
   //\r
   Status = ArpService->Mnp->Transmit (ArpService->Mnp, TxToken);\r
   if (EFI_ERROR (Status)) {\r
-    ARP_DEBUG_ERROR (("Mnp->Transmit failed, %r.\n", Status));\r
+    DEBUG ((EFI_D_ERROR, "Mnp->Transmit failed, %r.\n", Status));\r
     goto CLEAN_EXIT;\r
   }\r
 \r
@@ -1163,18 +1198,18 @@ ArpSendFrame (
 CLEAN_EXIT:\r
 \r
   if (Packet != NULL) {\r
-    NetFreePool (Packet);\r
+    FreePool (Packet);\r
   }\r
 \r
   if (TxData != NULL) {\r
-    NetFreePool (TxData);\r
+    FreePool (TxData);\r
   }\r
 \r
   if (TxToken->Event != NULL) {\r
     gBS->CloseEvent (TxToken->Event);\r
   }\r
 \r
-  NetFreePool (TxToken);\r
+  FreePool (TxToken);\r
 }\r
 \r
 \r
@@ -1183,29 +1218,28 @@ CLEAN_EXIT:
   SwAddressType, AddressBuffer combination as the matching key, if Force is TRUE,\r
   the cache is deleted event it's a static entry.\r
 \r
-  @param  CacheTable             Pointer to the cache table to do the deletion.\r
-  @param  BySwAddress            Delete the cache entry by software address or by\r
-                                 hardware address.\r
-  @param  SwAddressType          The software address used to do the deletion.\r
-  @param  AddressBuffer          Pointer to the buffer containing the address to\r
-                                 match for the deletion.\r
-  @param  Force                  This deletion is forced or not.\r
+  @param[in]  CacheTable             Pointer to the cache table to do the deletion.\r
+  @param[in]  BySwAddress            Delete the cache entry by software address or by\r
+                                     hardware address.\r
+  @param[in]  SwAddressType          The software address used to do the deletion.\r
+  @param[in]  AddressBuffer          Pointer to the buffer containing the address to\r
+                                     match for the deletion.\r
+  @param[in]  Force                  This deletion is forced or not.\r
 \r
   @return The count of the deleted cache entries.\r
 \r
 **/\r
-STATIC\r
 UINTN\r
 ArpDeleteCacheEntryInTable (\r
-  IN NET_LIST_ENTRY  *CacheTable,\r
+  IN LIST_ENTRY      *CacheTable,\r
   IN BOOLEAN         BySwAddress,\r
   IN UINT16          SwAddressType,\r
   IN UINT8           *AddressBuffer OPTIONAL,\r
   IN BOOLEAN         Force\r
   )\r
 {\r
-  NET_LIST_ENTRY   *Entry;\r
-  NET_LIST_ENTRY   *NextEntry;\r
+  LIST_ENTRY       *Entry;\r
+  LIST_ENTRY       *NextEntry;\r
   ARP_CACHE_ENTRY  *CacheEntry;\r
   UINTN            Count;\r
 \r
@@ -1227,7 +1261,7 @@ ArpDeleteCacheEntryInTable (
         // Protocol address type matched. Check the address.\r
         //\r
         if ((AddressBuffer == NULL) ||\r
-          (NetCompareMem (\r
+          (CompareMem (\r
              AddressBuffer,\r
              CacheEntry->Addresses[Protocol].AddressPtr,\r
              CacheEntry->Addresses[Protocol].Length\r
@@ -1240,7 +1274,7 @@ ArpDeleteCacheEntryInTable (
       }\r
     } else {\r
       if ((AddressBuffer == NULL) ||\r
-        (NetCompareMem (\r
+        (CompareMem (\r
            AddressBuffer,\r
            CacheEntry->Addresses[Hardware].AddressPtr,\r
            CacheEntry->Addresses[Hardware].Length\r
@@ -1259,9 +1293,9 @@ MATCHED:
     //\r
     // Delete this entry.\r
     //\r
-    NetListRemoveEntry (&CacheEntry->List);\r
-    ASSERT (NetListIsEmpty (&CacheEntry->UserRequestList));\r
-    NetFreePool (CacheEntry);\r
+    RemoveEntryList (&CacheEntry->List);\r
+    ASSERT (IsListEmpty (&CacheEntry->UserRequestList));\r
+    FreePool (CacheEntry);\r
 \r
     Count++;\r
   }\r
@@ -1273,12 +1307,12 @@ MATCHED:
 /**\r
   Delete cache entries in all the cache tables.\r
 \r
-  @param  Instance               Pointer to the instance context data.\r
-  @param  BySwAddress            Delete the cache entry by software address or by\r
-                                 hardware address.\r
-  @param  AddressBuffer          Pointer to the buffer containing the address to\r
-                                 match for the deletion.\r
-  @param  Force                  This deletion is forced or not.\r
+  @param[in]  Instance               Pointer to the instance context data.\r
+  @param[in]  BySwAddress            Delete the cache entry by software address or by\r
+                                     hardware address.\r
+  @param[in]  AddressBuffer          Pointer to the buffer containing the address to\r
+                                     match for the deletion.\r
+  @param[in]  Force                  This deletion is forced or not.\r
 \r
   @return The count of the deleted cache entries.\r
 \r
@@ -1327,11 +1361,11 @@ ArpDeleteCacheEntry (
 /**\r
   Cancel the arp request.\r
 \r
-  @param  Instance               Pointer to the instance context data.\r
-  @param  TargetSwAddress        Pointer to the buffer containing the target\r
-                                 software address to match the arp request.\r
-  @param  UserEvent              The user event used to notify this request\r
-                                 cancellation.\r
+  @param[in]  Instance               Pointer to the instance context data.\r
+  @param[in]  TargetSwAddress        Pointer to the buffer containing the target\r
+                                     software address to match the arp request.\r
+  @param[in]  UserEvent              The user event used to notify this request\r
+                                     cancellation.\r
 \r
   @return The count of the cancelled requests.\r
 \r
@@ -1344,8 +1378,8 @@ ArpCancelRequest (
   )\r
 {\r
   ARP_SERVICE_DATA  *ArpService;\r
-  NET_LIST_ENTRY    *Entry;\r
-  NET_LIST_ENTRY    *NextEntry;\r
+  LIST_ENTRY        *Entry;\r
+  LIST_ENTRY        *NextEntry;\r
   ARP_CACHE_ENTRY   *CacheEntry;\r
   UINTN             Count;\r
 \r
@@ -1358,7 +1392,7 @@ ArpCancelRequest (
     CacheEntry = NET_LIST_USER_STRUCT (Entry, ARP_CACHE_ENTRY, List);\r
 \r
     if ((TargetSwAddress == NULL) ||\r
-      (NetCompareMem (\r
+      (CompareMem (\r
          TargetSwAddress,\r
          CacheEntry->Addresses[Protocol].AddressPtr,\r
          CacheEntry->Addresses[Protocol].Length\r
@@ -1369,12 +1403,12 @@ ArpCancelRequest (
       //\r
       Count += ArpAddressResolved (CacheEntry, Instance, UserEvent);\r
 \r
-      if (NetListIsEmpty (&CacheEntry->UserRequestList)) {\r
+      if (IsListEmpty (&CacheEntry->UserRequestList)) {\r
         //\r
         // No user requests any more, remove this request cache entry.\r
         //\r
-        NetListRemoveEntry (&CacheEntry->List);\r
-        NetFreePool (CacheEntry);\r
+        RemoveEntryList (&CacheEntry->List);\r
+        FreePool (CacheEntry);\r
       }\r
     }\r
   }\r
@@ -1386,18 +1420,18 @@ ArpCancelRequest (
 /**\r
   Find the cache entry in the cache table.\r
 \r
-  @param  Instance               Pointer to the instance context data.\r
-  @param  BySwAddress            Set to TRUE to look for matching software protocol\r
+  @param[in]  Instance           Pointer to the instance context data.\r
+  @param[in]  BySwAddress        Set to TRUE to look for matching software protocol\r
                                  addresses. Set to FALSE to look for matching\r
                                  hardware protocol addresses.\r
-  @param  AddressBuffer          Pointer to address buffer. Set to NULL to match\r
+  @param[in]  AddressBuffer      Pointer to address buffer. Set to NULL to match\r
                                  all addresses.\r
-  @param  EntryLength            The size of an entry in the entries buffer.\r
-  @param  EntryCount             The number of ARP cache entries that are found by\r
+  @param[out] EntryLength        The size of an entry in the entries buffer.\r
+  @param[out] EntryCount         The number of ARP cache entries that are found by\r
                                  the specified criteria.\r
-  @param  Entries                Pointer to the buffer that will receive the ARP\r
+  @param[out] Entries            Pointer to the buffer that will receive the ARP\r
                                  cache entries.\r
-  @param  Refresh                Set to TRUE to refresh the timeout value of the\r
+  @param[in]  Refresh            Set to TRUE to refresh the timeout value of the\r
                                  matching ARP cache entry.\r
 \r
   @retval EFI_SUCCESS            The requested ARP cache entries are copied into\r
@@ -1421,12 +1455,13 @@ ArpFindCacheEntry (
   ARP_SERVICE_DATA   *ArpService;\r
   NET_ARP_ADDRESS    MatchAddress;\r
   FIND_OPTYPE        FindOpType;\r
-  NET_LIST_ENTRY     *StartEntry;\r
+  LIST_ENTRY         *StartEntry;\r
   ARP_CACHE_ENTRY    *CacheEntry;\r
   NET_MAP            FoundEntries;\r
   UINT32             FoundCount;\r
   EFI_ARP_FIND_DATA  *FindData;\r
-  NET_LIST_ENTRY     *CacheTable;\r
+  LIST_ENTRY         *CacheTable;\r
+  UINT32             FoundEntryLength;\r
 \r
   ArpService = Instance->ArpService;\r
 \r
@@ -1543,12 +1578,14 @@ ArpFindCacheEntry (
     goto CLEAN_EXIT;\r
   }\r
 \r
+  //\r
+  // Found the entry length, make sure its 8 bytes alignment.\r
+  //\r
+  FoundEntryLength = (((sizeof (EFI_ARP_FIND_DATA) + Instance->ConfigData.SwAddressLength +\r
+                       ArpService->SnpMode.HwAddressSize) + 3) & ~(0x3));\r
+\r
   if (EntryLength != NULL) {\r
-    //\r
-    // Return the entry length, make sure its 8 bytes alignment.\r
-    //\r
-    *EntryLength = (((sizeof (EFI_ARP_FIND_DATA) + Instance->ConfigData.SwAddressLength +\r
-                   ArpService->SnpMode.HwAddressSize) + 3) & ~(0x3));\r
+    *EntryLength = FoundEntryLength;\r
   }\r
 \r
   if (EntryCount != NULL) {\r
@@ -1565,9 +1602,9 @@ ArpFindCacheEntry (
   //\r
   // Allocate buffer to copy the found entries.\r
   //\r
-  FindData = NetAllocatePool (FoundCount * (*EntryLength));\r
+  FindData = AllocatePool (FoundCount * FoundEntryLength);\r
   if (FindData == NULL) {\r
-    ARP_DEBUG_ERROR (("ArpFindCacheEntry: Failed to allocate memory.\n"));\r
+    DEBUG ((EFI_D_ERROR, "ArpFindCacheEntry: Failed to allocate memory.\n"));\r
     Status = EFI_OUT_OF_RESOURCES;\r
     goto CLEAN_EXIT;\r
   }\r
@@ -1589,7 +1626,7 @@ ArpFindCacheEntry (
     //\r
     // Set the fields in FindData.\r
     //\r
-    FindData->Size            = *EntryLength;\r
+    FindData->Size            = FoundEntryLength;\r
     FindData->DenyFlag        = (BOOLEAN)(CacheTable == &ArpService->DeniedCacheTable);\r
     FindData->StaticFlag      = (BOOLEAN)(CacheEntry->DefaultDecayTime == 0);\r
     FindData->HwAddressType   = ArpService->SnpMode.IfType;\r
@@ -1600,7 +1637,7 @@ ArpFindCacheEntry (
     //\r
     // Copy the software address.\r
     //\r
-    NetCopyMem (\r
+    CopyMem (\r
       FindData + 1,\r
       CacheEntry->Addresses[Protocol].AddressPtr,\r
       FindData->SwAddressLength\r
@@ -1609,7 +1646,7 @@ ArpFindCacheEntry (
     //\r
     // Copy the hardware address.\r
     //\r
-    NetCopyMem (\r
+    CopyMem (\r
       (UINT8 *)(FindData + 1) + FindData->SwAddressLength,\r
       CacheEntry->Addresses[Hardware].AddressPtr,\r
       FindData->HwAddressLength\r
@@ -1618,7 +1655,7 @@ ArpFindCacheEntry (
     //\r
     // Slip to the next FindData.\r
     //\r
-    FindData = (EFI_ARP_FIND_DATA *)((UINT8 *)FindData + *EntryLength);\r
+    FindData = (EFI_ARP_FIND_DATA *)((UINT8 *)FindData + FoundEntryLength);\r
   }\r
 \r
 CLEAN_EXIT:\r