X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FArpDxe%2FArpMain.c;h=ac76fcd6324917747c2778b8ad80a39e4f754e59;hb=9cff2f8d3687aeed765e1ee787c18ce70ae500bc;hp=eb1b082a21c0b2b9f39eb5976f0e1c83a348bd40;hpb=772db4bb33ae66fa20e39f786b5f80d107d450a5;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c b/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c index eb1b082a21..ac76fcd632 100644 --- a/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c +++ b/MdeModulePkg/Universal/Network/ArpDxe/ArpMain.c @@ -1,21 +1,15 @@ /** @file - -Copyright (c) 2006, Intel Corporation + Implementation of EFI Address Resolution Protocol (ARP) Protocol interface functions. + +Copyright (c) 2006, 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 +which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. -Module Name: - - ArpMain.c - -Abstract: - - **/ #include "ArpImpl.h" @@ -23,8 +17,15 @@ Abstract: /** This function is used to assign a station address to the ARP cache for this instance - of the ARP driver. A call to this function with the ConfigData field set to NULL - will reset this ARP instance. + of the ARP driver. + + Each ARP instance has one station address. The EFI_ARP_PROTOCOL driver will + respond to ARP requests that match this registered station address. A call to + this function with the ConfigData field set to NULL will reset this ARP instance. + + Once a protocol type and station address have been assigned to this ARP instance, + all the following ARP functions will use this information. Attempting to change + the protocol type or station address to a configured ARP instance will result in errors. @param This Pointer to the EFI_ARP_PROTOCOL instance. @param ConfigData Pointer to the EFI_ARP_CONFIG_DATA structure. @@ -51,6 +52,7 @@ ArpConfigure ( { EFI_STATUS Status; ARP_INSTANCE_DATA *Instance; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -65,16 +67,14 @@ ArpConfigure ( Instance = ARP_INSTANCE_DATA_FROM_THIS (This); - if (EFI_ERROR (NET_TRYLOCK (&Instance->ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Configure this instance, the ConfigData has already passed the basic checks. // Status = ArpConfigureInstance (Instance, ConfigData); - NET_UNLOCK (&Instance->ArpService->Lock); + gBS->RestoreTPL (OldTpl); return Status; } @@ -83,6 +83,17 @@ ArpConfigure ( /** This function is used to insert entries into the ARP cache. + ARP cache entries are typically inserted and updated by network protocol drivers + as network traffic is processed. Most ARP cache entries will time out and be + deleted if the network traffic stops. ARP cache entries that were inserted + by the Add() function may be static (will not time out) or dynamic (will time out). + Default ARP cache timeout values are not covered in most network protocol + specifications (although RFC 1122 comes pretty close) and will only be + discussed in general in this specification. The timeout values that are + used in the EFI Sample Implementation should be used only as a guideline. + Final product implementations of the EFI network stack should be tuned for + their expected network environments. + @param This Pointer to the EFI_ARP_PROTOCOL instance. @param DenyFlag Set to TRUE if this entry is a deny entry. Set to FALSE if this entry is a normal entry. @@ -131,6 +142,7 @@ ArpAdd ( ARP_CACHE_ENTRY *CacheEntry; EFI_SIMPLE_NETWORK_MODE *SnpMode; NET_ARP_ADDRESS MatchAddress[2]; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -166,9 +178,7 @@ ArpAdd ( MatchAddress[Protocol].Length = Instance->ConfigData.SwAddressLength; MatchAddress[Protocol].AddressPtr = TargetSwAddress; - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // See whether the entry to add exists. Check the DeinedCacheTable first. @@ -217,7 +227,7 @@ ArpAdd ( // // Remove it from the Table. // - NetListRemoveEntry (&CacheEntry->List); + RemoveEntryList (&CacheEntry->List); } else { // // It's a new entry, allocate memory for the entry. @@ -225,7 +235,7 @@ ArpAdd ( CacheEntry = ArpAllocCacheEntry (Instance); if (CacheEntry == NULL) { - ARP_DEBUG_ERROR (("ArpAdd: Failed to allocate pool for CacheEntry.\n")); + DEBUG ((EFI_D_ERROR, "ArpAdd: Failed to allocate pool for CacheEntry.\n")); Status = EFI_OUT_OF_RESOURCES; goto UNLOCK_EXIT; } @@ -255,14 +265,14 @@ ArpAdd ( // Add this CacheEntry to the corresponding CacheTable. // if (DenyFlag) { - NetListInsertHead (&ArpService->DeniedCacheTable, &CacheEntry->List); + InsertHeadList (&ArpService->DeniedCacheTable, &CacheEntry->List); } else { - NetListInsertHead (&ArpService->ResolvedCacheTable, &CacheEntry->List); + InsertHeadList (&ArpService->ResolvedCacheTable, &CacheEntry->List); } UNLOCK_EXIT: - NET_UNLOCK (&ArpService->Lock); + gBS->RestoreTPL (OldTpl); return Status; } @@ -271,7 +281,14 @@ UNLOCK_EXIT: /** This function searches the ARP cache for matching entries and allocates a buffer into which those entries are copied. - + + The first part of the allocated buffer is EFI_ARP_FIND_DATA, following which + are protocol address pairs and hardware address pairs. + When finding a specific protocol address (BySwAddress is TRUE and AddressBuffer + is not NULL), the ARP cache timeout for the found entry is reset if Refresh is + set to TRUE. If the found ARP cache entry is a permanent entry, it is not + affected by Refresh. + @param This Pointer to the EFI_ARP_PROTOCOL instance. @param BySwAddress Set to TRUE to look for matching software protocol addresses. Set to FALSE to look for matching @@ -309,7 +326,7 @@ ArpFind ( { EFI_STATUS Status; ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; + EFI_TPL OldTpl; if ((This == NULL) || (!Refresh && (EntryCount == NULL) && (EntryLength == NULL)) || @@ -318,15 +335,12 @@ ArpFind ( } Instance = ARP_INSTANCE_DATA_FROM_THIS (This); - ArpService = Instance->ArpService; if (!Instance->Configured) { return EFI_NOT_STARTED; } - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // All the check passed, find the cache entries now. @@ -341,7 +355,7 @@ ArpFind ( Refresh ); - NET_UNLOCK (&ArpService->Lock); + gBS->RestoreTPL (OldTpl); return Status; } @@ -373,8 +387,8 @@ ArpDelete ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -386,18 +400,14 @@ ArpDelete ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Delete the specified cache entries. // Count = ArpDeleteCacheEntry (Instance, BySwAddress, AddressBuffer, TRUE); - NET_UNLOCK (&ArpService->Lock); + gBS->RestoreTPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; } @@ -422,8 +432,8 @@ ArpFlush ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if (This == NULL) { return EFI_INVALID_PARAMETER; @@ -435,18 +445,14 @@ ArpFlush ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Delete the dynamic entries from the cache table. // Count = ArpDeleteCacheEntry (Instance, FALSE, NULL, FALSE); - NET_UNLOCK (&ArpService->Lock); + gBS->RestoreTPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; } @@ -491,6 +497,7 @@ ArpRequest ( NET_ARP_ADDRESS HardwareAddress; NET_ARP_ADDRESS ProtocolAddress; USER_REQUEST_CONTEXT *RequestContext; + EFI_TPL OldTpl; if ((This == NULL) || (TargetHwAddress == NULL)) { return EFI_INVALID_PARAMETER; @@ -507,17 +514,17 @@ ArpRequest ( SnpMode = &ArpService->SnpMode; if ((TargetSwAddress == NULL) || - ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) && + ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) && IP4_IS_LOCAL_BROADCAST (*((UINT32 *)TargetSwAddress)))) { // // Return the hardware broadcast address. // - NetCopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize); + CopyMem (TargetHwAddress, &SnpMode->BroadcastAddress, SnpMode->HwAddressSize); goto SIGNAL_USER; } - if ((Instance->ConfigData.SwAddressType == IPv4_ETHER_PROTO_TYPE) && + if ((Instance->ConfigData.SwAddressType == IPV4_ETHER_PROTO_TYPE) && IP4_IS_MULTICAST (NTOHL (*((UINT32 *)TargetSwAddress)))) { // // If the software address is an IPv4 multicast address, invoke Mnp to @@ -543,11 +550,9 @@ ArpRequest ( // // Initialize the TargetHwAddrss to a zero address. // - NetZeroMem (TargetHwAddress, SnpMode->HwAddressSize); + ZeroMem (TargetHwAddress, SnpMode->HwAddressSize); - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Check whether the software address is in the denied table. @@ -572,7 +577,7 @@ ArpRequest ( // // Resolved, copy the address into the user buffer. // - NetCopyMem ( + CopyMem ( TargetHwAddress, CacheEntry->Addresses[Hardware].AddressPtr, CacheEntry->Addresses[Hardware].Length @@ -589,9 +594,9 @@ ArpRequest ( // // Create a request context for this arp request. // - RequestContext = NetAllocatePool (sizeof(USER_REQUEST_CONTEXT)); + RequestContext = AllocatePool (sizeof(USER_REQUEST_CONTEXT)); if (RequestContext == NULL) { - ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for RequestContext failed.\n")); + DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for RequestContext failed.\n")); Status = EFI_OUT_OF_RESOURCES; goto UNLOCK_EXIT; @@ -600,7 +605,7 @@ ArpRequest ( RequestContext->Instance = Instance; RequestContext->UserRequestEvent = ResolvedEvent; RequestContext->UserHwAddrBuffer = TargetHwAddress; - NetListInit (&RequestContext->List); + InitializeListHead (&RequestContext->List); // // Check whether there is a same request. @@ -622,8 +627,8 @@ ArpRequest ( // CacheEntry = ArpAllocCacheEntry (Instance); if (CacheEntry == NULL) { - ARP_DEBUG_ERROR (("ArpRequest: Allocate memory for CacheEntry failed.\n")); - NetFreePool (RequestContext); + DEBUG ((EFI_D_ERROR, "ArpRequest: Allocate memory for CacheEntry failed.\n")); + gBS->FreePool (RequestContext); Status = EFI_OUT_OF_RESOURCES; goto UNLOCK_EXIT; @@ -637,13 +642,13 @@ ArpRequest ( // // Add this entry into the PendingRequestTable. // - NetListInsertTail (&ArpService->PendingRequestTable, &CacheEntry->List); + InsertTailList (&ArpService->PendingRequestTable, &CacheEntry->List); } // // Link this request context into the cache entry. // - NetListInsertHead (&CacheEntry->UserRequestList, &RequestContext->List); + InsertHeadList (&CacheEntry->UserRequestList, &RequestContext->List); // // Send out the ARP Request frame. @@ -653,12 +658,17 @@ ArpRequest ( UNLOCK_EXIT: - NET_UNLOCK (&ArpService->Lock); + gBS->RestoreTPL (OldTpl); SIGNAL_USER: if ((ResolvedEvent != NULL) && (Status == EFI_SUCCESS)) { gBS->SignalEvent (ResolvedEvent); + + // + // Dispatch the DPC queued by the NotifyFunction of ResolvedEvent. + // + NetLibDispatchDpc (); } return Status; @@ -668,7 +678,13 @@ SIGNAL_USER: /** This function aborts the previous ARP request (identified by This, TargetSwAddress and ResolvedEvent) that is issued by EFI_ARP_PROTOCOL.Request(). - + + If the request is in the internal ARP request queue, the request is aborted + immediately and its ResolvedEvent is signaled. Only an asynchronous address + request needs to be canceled. If TargeSwAddress and ResolveEvent are both + NULL, all the pending asynchronous requests that have been issued by This + instance will be cancelled and their corresponding events will be signaled. + @param This Pointer to the EFI_ARP_PROTOCOL instance. @param TargetSwAddress Pointer to the protocol address in previous request session. @@ -695,8 +711,8 @@ ArpCancel ( ) { ARP_INSTANCE_DATA *Instance; - ARP_SERVICE_DATA *ArpService; UINTN Count; + EFI_TPL OldTpl; if ((This == NULL) || ((TargetSwAddress != NULL) && (ResolvedEvent == NULL)) || @@ -710,18 +726,20 @@ ArpCancel ( return EFI_NOT_STARTED; } - ArpService = Instance->ArpService; - - if (EFI_ERROR (NET_TRYLOCK (&ArpService->Lock))) { - return EFI_ACCESS_DENIED; - } + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); // // Cancel the specified request. // Count = ArpCancelRequest (Instance, TargetSwAddress, ResolvedEvent); - NET_UNLOCK (&ArpService->Lock); + // + // Dispatch the DPCs queued by the NotifyFunction of the events signaled + // by ArpCancleRequest. + // + NetLibDispatchDpc (); + + gBS->RestoreTPL (OldTpl); return (Count == 0) ? EFI_NOT_FOUND : EFI_SUCCESS; }