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;
}