/** @file\r
-\r
-Copyright (c) 2005 - 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
-\r
-Module Name:\r
-\r
- Ip4If.c\r
-\r
-Abstract:\r
-\r
Implement IP4 pesudo interface.\r
\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
// Mac address with all zero, used to determine whethter the ARP\r
// resolve succeeded. Failed ARP requests zero the MAC address buffer.\r
//\r
-STATIC EFI_MAC_ADDRESS mZeroMacAddress;\r
+EFI_MAC_ADDRESS mZeroMacAddress;\r
+\r
+/**\r
+ Callback funtion when frame transmission is finished. It will\r
+ call the frame owner's callback function to tell it the result.\r
\r
-STATIC\r
+ @param[in] Context Context which is point to the token.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameSentDpc (\r
- IN VOID *Context\r
+ IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param[in] Event The transmit token's event.\r
+ @param[in] Context Context which is point to the token.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameSent (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Callback function when ARP request are finished. It will cancelled\r
+ all the queued frame if the ARP requests failed. Or transmit them\r
+ if the request succeed.\r
+\r
+ @param[in] Context The context of the callback, a point to the ARP\r
+ queue\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnArpResolvedDpc (\r
IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The Arp request event.\r
+ @param Context The context of the callback, a point to the ARP\r
+ queue.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnArpResolved (\r
IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Received a frame from MNP, wrap it in net buffer then deliver\r
+ it to IP's input function. The ownship of the packet also\r
+ transferred to IP. When Ip is finished with this packet, it\r
+ will call NetbufFree to release the packet, NetbufFree will\r
+ again call the Ip4RecycleFrame to signal MNP's event and free\r
+ the token used.\r
+\r
+ @param Context Context for the callback.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameReceivedDpc (\r
- IN VOID *Context\r
+ IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The receive event delivered to MNP for receive.\r
+ @param Context Context for the callback.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameReceived (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
);\r
\r
-STATIC\r
+/**\r
+ Remove all the frames on the ARP queue that pass the FrameToCancel,\r
+ that is, either FrameToCancel is NULL or it returns true for the frame.\r
+\r
+ @param[in] ArpQue ARP frame to remove the frames from.\r
+ @param[in] IoStatus The status returned to the cancelled frames'\r
+ callback function.\r
+ @param[in] FrameToCancel Function to select which frame to cancel.\r
+ @param[in] Context Opaque parameter to the FrameToCancel.\r
+\r
+**/\r
VOID\r
Ip4CancelFrameArp (\r
IN IP4_ARP_QUE *ArpQue,\r
IN EFI_STATUS IoStatus,\r
- IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL\r
+ IN IP4_FRAME_TO_CANCEL FrameToCancel OPTIONAL,\r
IN VOID *Context\r
);\r
\r
/**\r
Wrap a transmit request into a newly allocated IP4_LINK_TX_TOKEN.\r
\r
- @param Interface The interface to send out from\r
- @param IpInstance The IpInstance that transmit the packet. NULL if\r
+ @param[in] Interface The interface to send out to.\r
+ @param[in] IpInstance The IpInstance that transmit the packet. NULL if\r
the packet is sent by the IP4 driver itself.\r
- @param Packet The packet to transmit\r
- @param CallBack Call back function to execute if transmission\r
+ @param[in] Packet The packet to transmit\r
+ @param[in] CallBack Call back function to execute if transmission\r
finished.\r
- @param Context Opaque parameter to the call back.\r
+ @param[in] Context Opaque parameter to the call back.\r
+ @param[in] IpSb The pointer to the IP4 service binding instance.\r
\r
- @return The wrapped token if succeed or NULL\r
+ @retval Token The wrapped token if succeed\r
+ @retval NULL The wrapped token if NULL\r
\r
**/\r
-STATIC\r
IP4_LINK_TX_TOKEN *\r
Ip4WrapLinkTxToken (\r
IN IP4_INTERFACE *Interface,\r
- IN IP4_PROTOCOL *IpInstance, OPTIONAL\r
+ IN IP4_PROTOCOL *IpInstance OPTIONAL,\r
IN NET_BUF *Packet,\r
IN IP4_FRAME_CALLBACK CallBack,\r
- IN VOID *Context\r
+ IN VOID *Context,\r
+ IN IP4_SERVICE *IpSb\r
)\r
{\r
EFI_MANAGED_NETWORK_COMPLETION_TOKEN *MnpToken;\r
\r
Token->Interface = Interface;\r
Token->IpInstance = IpInstance;\r
+ Token->IpSb = IpSb;\r
Token->CallBack = CallBack;\r
Token->Packet = Packet;\r
Token->Context = Context;\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Token);\r
+ FreePool (Token);\r
return NULL;\r
}\r
\r
Free the link layer transmit token. It will close the event\r
then free the memory used.\r
\r
- @param Token Token to free\r
-\r
- @return NONE\r
+ @param[in] Token Token to free\r
\r
**/\r
-STATIC\r
VOID\r
Ip4FreeLinkTxToken (\r
IN IP4_LINK_TX_TOKEN *Token\r
NET_CHECK_SIGNATURE (Token, IP4_FRAME_TX_SIGNATURE);\r
\r
gBS->CloseEvent (Token->MnpToken.Event);\r
- gBS->FreePool (Token);\r
+ FreePool (Token);\r
}\r
\r
\r
/**\r
Create an IP_ARP_QUE structure to request ARP service.\r
\r
- @param Interface The interface to send ARP from.\r
- @param DestIp The destination IP (host byte order) to request MAC\r
+ @param[in] Interface The interface to send ARP from.\r
+ @param[in] DestIp The destination IP (host byte order) to request MAC\r
for\r
\r
@return Point to newly created IP4_ARP_QUE if succeed, otherwise NULL.\r
\r
**/\r
-STATIC\r
IP4_ARP_QUE *\r
Ip4CreateArpQue (\r
IN IP4_INTERFACE *Interface,\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (ArpQue);\r
+ FreePool (ArpQue);\r
return NULL;\r
}\r
\r
/**\r
Remove all the transmit requests queued on the ARP queue, then free it.\r
\r
- @param ArpQue Arp queue to free\r
- @param IoStatus The transmit status returned to transmit requests'\r
+ @param[in] ArpQue Arp queue to free\r
+ @param[in] IoStatus The transmit status returned to transmit requests'\r
callback.\r
\r
- @return NONE\r
-\r
**/\r
-STATIC\r
VOID\r
Ip4FreeArpQue (\r
IN IP4_ARP_QUE *ArpQue,\r
Ip4CancelFrameArp (ArpQue, IoStatus, NULL, NULL);\r
\r
gBS->CloseEvent (ArpQue->OnResolved);\r
- gBS->FreePool (ArpQue);\r
+ FreePool (ArpQue);\r
}\r
\r
\r
/**\r
Create a link layer receive token to wrap the receive request\r
\r
- @param Interface The interface to receive from\r
- @param IpInstance The instance that request the receive (NULL for IP4\r
+ @param[in] Interface The interface to receive from\r
+ @param[in] IpInstance The instance that request the receive (NULL for IP4\r
driver itself)\r
- @param CallBack Call back function to execute when finished.\r
- @param Context Opaque parameters to the callback\r
+ @param[in] CallBack Call back function to execute when finished.\r
+ @param[in] Context Opaque parameters to the callback\r
\r
@return Point to created IP4_LINK_RX_TOKEN if succeed, otherwise NULL.\r
\r
**/\r
-STATIC\r
IP4_LINK_RX_TOKEN *\r
Ip4CreateLinkRxToken (\r
IN IP4_INTERFACE *Interface,\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- gBS->FreePool (Token);\r
+ FreePool (Token);\r
return NULL;\r
}\r
\r
Free the link layer request token. It will close the event\r
then free the memory used.\r
\r
- @param Token Request token to free\r
-\r
- @return NONE\r
+ @param[in] Token Request token to free.\r
\r
**/\r
-STATIC\r
VOID\r
Ip4FreeFrameRxToken (\r
IN IP4_LINK_RX_TOKEN *Token\r
NET_CHECK_SIGNATURE (Token, IP4_FRAME_RX_SIGNATURE);\r
\r
gBS->CloseEvent (Token->MnpToken.Event);\r
- gBS->FreePool (Token);\r
+ FreePool (Token);\r
}\r
\r
\r
Remove all the frames on the ARP queue that pass the FrameToCancel,\r
that is, either FrameToCancel is NULL or it returns true for the frame.\r
\r
- @param ArpQue ARP frame to remove the frames from.\r
- @param IoStatus The status returned to the cancelled frames'\r
+ @param[in] ArpQue ARP frame to remove the frames from.\r
+ @param[in] IoStatus The status returned to the cancelled frames'\r
callback function.\r
- @param FrameToCancel Function to select which frame to cancel.\r
- @param Context Opaque parameter to the FrameToCancel.\r
-\r
- @return NONE\r
+ @param[in] FrameToCancel Function to select which frame to cancel.\r
+ @param[in] Context Opaque parameter to the FrameToCancel.\r
\r
**/\r
-STATIC\r
VOID\r
Ip4CancelFrameArp (\r
IN IP4_ARP_QUE *ArpQue,\r
IN EFI_STATUS IoStatus,\r
- IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL\r
+ IN IP4_FRAME_TO_CANCEL FrameToCancel OPTIONAL,\r
IN VOID *Context\r
)\r
{\r
either queued on ARP queues or that have already been delivered to\r
MNP and not yet recycled.\r
\r
- @param Interface Interface to remove the frames from\r
- @param IoStatus The transmit status returned to the frames'\r
- callback\r
- @param FrameToCancel Function to select the frame to cancel, NULL to\r
- select all\r
- @param Context Opaque parameters passed to FrameToCancel\r
-\r
- @return NONE\r
+ @param[in] Interface Interface to remove the frames from.\r
+ @param[in] IoStatus The transmit status returned to the frames'\r
+ callback.\r
+ @param[in] FrameToCancel Function to select the frame to cancel, NULL to\r
+ select all.\r
+ @param[in] Context Opaque parameters passed to FrameToCancel.\r
\r
**/\r
VOID\r
Ip4CancelFrames (\r
IN IP4_INTERFACE *Interface,\r
IN EFI_STATUS IoStatus,\r
- IN IP4_FRAME_TO_CANCEL FrameToCancel, OPTIONAL\r
+ IN IP4_FRAME_TO_CANCEL FrameToCancel OPTIONAL,\r
IN VOID *Context\r
)\r
{\r
Create an IP4_INTERFACE. Delay the creation of ARP instance until\r
the interface is configured.\r
\r
- @param Mnp The shared MNP child of this IP4 service binding\r
- instance\r
- @param Controller The controller this IP4 service binding instance\r
+ @param[in] Mnp The shared MNP child of this IP4 service binding\r
+ instance.\r
+ @param[in] Controller The controller this IP4 service binding instance\r
is installed. Most like the UNDI handle.\r
- @param ImageHandle This driver's image handle\r
+ @param[in] ImageHandle This driver's image handle.\r
\r
@return Point to the created IP4_INTERFACE, otherwise NULL.\r
\r
// Get the interface's Mac address and broadcast mac address from SNP\r
//\r
if (EFI_ERROR (Mnp->GetModeData (Mnp, NULL, &SnpMode))) {\r
- gBS->FreePool (Interface);\r
+ FreePool (Interface);\r
return NULL;\r
}\r
\r
Set the interface's address, create and configure\r
the ARP child if necessary.\r
\r
- @param Interface The interface to set the address\r
- @param IpAddr The interface's IP address\r
- @param SubnetMask The interface's netmask\r
+ @param Interface The interface to set the address.\r
+ @param IpAddr The interface's IP address.\r
+ @param SubnetMask The interface's netmask.\r
\r
@retval EFI_SUCCESS The interface is configured with Ip/netmask pair,\r
and a ARP is created for it.\r
**/\r
EFI_STATUS\r
Ip4SetAddress (\r
- IN IP4_INTERFACE *Interface,\r
- IN IP4_ADDR IpAddr,\r
- IN IP4_ADDR SubnetMask\r
+ IN OUT IP4_INTERFACE *Interface,\r
+ IN IP4_ADDR IpAddr,\r
+ IN IP4_ADDR SubnetMask\r
)\r
{\r
EFI_ARP_CONFIG_DATA ArpConfig;\r
EFI_STATUS Status;\r
- INTN Type;\r
- INTN Len;\r
- IP4_ADDR Netmask;\r
\r
NET_CHECK_SIGNATURE (Interface, IP4_INTERFACE_SIGNATURE);\r
\r
- ASSERT (!Interface->Configured);\r
-\r
//\r
// Set the ip/netmask, then compute the subnet broadcast\r
// and network broadcast for easy access. When computing\r
Interface->Ip = IpAddr;\r
Interface->SubnetMask = SubnetMask;\r
Interface->SubnetBrdcast = (IpAddr | ~SubnetMask);\r
+ Interface->NetBrdcast = (IpAddr | ~SubnetMask);\r
+\r
+ //\r
+ // Do clean up for Arp child\r
+ //\r
+ if (Interface->ArpHandle != NULL) {\r
+ if (Interface->Arp != NULL) {\r
+ gBS->CloseProtocol (\r
+ Interface->ArpHandle,\r
+ &gEfiArpProtocolGuid,\r
+ Interface->Image,\r
+ Interface->Controller\r
+ );\r
+\r
+ Interface->Arp = NULL;\r
+ }\r
\r
- Type = NetGetIpClass (IpAddr);\r
- Len = NetGetMaskLength (SubnetMask);\r
- Netmask = gIp4AllMasks[MIN (Len, Type << 3)];\r
- Interface->NetBrdcast = (IpAddr | ~Netmask);\r
+ NetLibDestroyServiceChild (\r
+ Interface->Controller,\r
+ Interface->Image,\r
+ &gEfiArpServiceBindingProtocolGuid,\r
+ &Interface->ArpHandle\r
+ );\r
+\r
+ Interface->ArpHandle = NULL;\r
+ }\r
\r
//\r
// If the address is NOT all zero, create then configure an ARP child.\r
// Pay attention: DHCP configures its station address as 0.0.0.0/0\r
//\r
- Interface->Arp = NULL;\r
- Interface->ArpHandle = NULL;\r
-\r
if (IpAddr != IP4_ALLZERO_ADDRESS) {\r
Status = NetLibCreateServiceChild (\r
Interface->Controller,\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- return Status;;\r
+ return Status;\r
}\r
\r
Status = gBS->OpenProtocol (\r
\r
if (EFI_ERROR (Status)) {\r
gBS->CloseProtocol (\r
- Interface->ArpHandle,\r
- &gEfiArpProtocolGuid,\r
- Interface->Image,\r
- Interface->Controller\r
- );\r
+ Interface->ArpHandle,\r
+ &gEfiArpProtocolGuid,\r
+ Interface->Image,\r
+ Interface->Controller\r
+ );\r
\r
goto ON_ERROR;\r
}\r
\r
\r
/**\r
- Fileter function to cancel all the frame related to an IP instance.\r
+ Filter function to cancel all the frame related to an IP instance.\r
\r
- @param Frame The transmit request to test whether to cancel\r
- @param Context The context which is the Ip instance that issued\r
+ @param[in] Frame The transmit request to test whether to cancel\r
+ @param[in] Context The context which is the Ip instance that issued\r
the transmit.\r
\r
@retval TRUE The frame belongs to this instance and is to be\r
@retval FALSE The frame doesn't belong to this instance.\r
\r
**/\r
-STATIC\r
BOOLEAN\r
Ip4CancelInstanceFrame (\r
IN IP4_LINK_TX_TOKEN *Frame,\r
packet and update the upper layer's transmit request status, say\r
that from the UDP.\r
\r
- @param Interface The interface used by the IpInstance\r
-\r
- @return None\r
+ @param[in] Interface The interface used by the IpInstance\r
\r
**/\r
VOID\r
Because the IpInstance is optional, the caller must remove\r
IpInstance from the interface's instance list itself.\r
\r
- @param Interface The interface used by the IpInstance\r
- @param IpInstance The Ip instance that free the interface. NULL if\r
- the Ip driver is releasing the default interface.\r
+ @param[in] Interface The interface used by the IpInstance.\r
+ @param[in] IpInstance The Ip instance that free the interface. NULL if\r
+ the Ip driver is releasing the default interface.\r
\r
@retval EFI_SUCCESS The interface use IpInstance is freed.\r
\r
}\r
\r
//\r
- // Destory the interface if this is the last IP instance that\r
+ // Destroy the interface if this is the last IP instance that\r
// has the address. Remove all the system transmitted packets\r
// from this interface, cancel the receive request if there is\r
- // one, and destory the ARP requests.\r
+ // one, and destroy the ARP requests.\r
//\r
Ip4CancelFrames (Interface, EFI_ABORTED, Ip4CancelInstanceFrame, NULL);\r
Ip4CancelReceive (Interface);\r
}\r
\r
RemoveEntryList (&Interface->Link);\r
- gBS->FreePool (Interface);\r
+ FreePool (Interface);\r
\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ This function tries to send all the queued frames in ArpQue to the default gateway if\r
+ the ARP resolve for direct destination address is failed when using /32 subnet mask.\r
+\r
+ @param[in] ArpQue The ARP queue of a failed request.\r
+\r
+ @retval EFI_SUCCESS All the queued frames have been send to the default route.\r
+ @retval Others Failed to send the queued frames.\r
+\r
+**/\r
+EFI_STATUS\r
+Ip4SendFrameToDefaultRoute (\r
+ IN IP4_ARP_QUE *ArpQue\r
+ )\r
+{\r
+ LIST_ENTRY *Entry;\r
+ LIST_ENTRY *Next;\r
+ IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;\r
+ IP4_LINK_TX_TOKEN *Token;\r
+ IP4_ADDR Gateway;\r
+ EFI_STATUS Status;\r
+ IP4_ROUTE_ENTRY *DefaultRoute;\r
+\r
+ //\r
+ // ARP resolve failed when using /32 subnet mask.\r
+ //\r
+ NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {\r
+ RemoveEntryList (Entry);\r
+ Token = NET_LIST_USER_STRUCT (Entry, IP4_LINK_TX_TOKEN, Link);\r
+ ASSERT (Token->Interface->SubnetMask == IP4_ALLONE_ADDRESS);\r
+ //\r
+ // Find the default gateway IP address. The default route was saved to the RtCacheEntry->Tag in Ip4Route().\r
+ //\r
+ RtCacheEntry = NULL;\r
+ if (Token->IpInstance != NULL) {\r
+ RtCacheEntry = Ip4FindRouteCache (Token->IpInstance->RouteTable, NTOHL (ArpQue->Ip), Token->Interface->Ip);\r
+ }\r
+ if (RtCacheEntry == NULL) {\r
+ RtCacheEntry = Ip4FindRouteCache (Token->IpSb->DefaultRouteTable, NTOHL (ArpQue->Ip), Token->Interface->Ip);\r
+ }\r
+ if (RtCacheEntry == NULL) {\r
+ Status= EFI_NO_MAPPING;\r
+ goto ON_ERROR;\r
+ }\r
+ DefaultRoute = (IP4_ROUTE_ENTRY*)RtCacheEntry->Tag;\r
+ if (DefaultRoute == NULL) {\r
+ Status= EFI_NO_MAPPING;\r
+ goto ON_ERROR;\r
+ }\r
+ //\r
+ // Try to send the frame to the default route.\r
+ //\r
+ Gateway = DefaultRoute->NextHop;\r
+ if (ArpQue->Ip == Gateway) {\r
+ //\r
+ // ARP resolve for the default route is failed, return error to caller.\r
+ //\r
+ Status= EFI_NO_MAPPING;\r
+ goto ON_ERROR;\r
+ }\r
+ RtCacheEntry->NextHop = Gateway;\r
+ Status = Ip4SendFrame (Token->Interface,Token->IpInstance,Token->Packet,Gateway,Token->CallBack,Token->Context,Token->IpSb);\r
+ if (EFI_ERROR (Status)) {\r
+ Status= EFI_NO_MAPPING;\r
+ goto ON_ERROR;\r
+ }\r
+ Ip4FreeRouteCacheEntry (RtCacheEntry);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+\r
+ON_ERROR:\r
+ if (RtCacheEntry != NULL) {\r
+ Ip4FreeRouteCacheEntry (RtCacheEntry);\r
+ }\r
+ Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context);\r
+ Ip4FreeLinkTxToken (Token);\r
+ return Status;\r
+}\r
+\r
\r
/**\r
- Callback function when ARP request are finished. It will cancelled\r
+ Callback function when ARP request are finished. It will cancel\r
all the queued frame if the ARP requests failed. Or transmit them\r
if the request succeed.\r
\r
- @param Context The context of the callback, a point to the ARP\r
+ @param[in] Context The context of the callback, a point to the ARP\r
queue\r
\r
- @return None\r
-\r
**/\r
-STATIC\r
VOID\r
EFIAPI\r
Ip4OnArpResolvedDpc (\r
IP4_INTERFACE *Interface;\r
IP4_LINK_TX_TOKEN *Token;\r
EFI_STATUS Status;\r
+ EFI_STATUS IoStatus;\r
\r
ArpQue = (IP4_ARP_QUE *) Context;\r
NET_CHECK_SIGNATURE (ArpQue, IP4_FRAME_ARP_SIGNATURE);\r
RemoveEntryList (&ArpQue->Link);\r
\r
//\r
- // ARP resolve failed for some reason. Release all the frame\r
- // and ARP queue itself. Ip4FreeArpQue will call the frame's\r
- // owner back.\r
+ // ARP resolve failed for some reason.\r
//\r
if (NET_MAC_EQUAL (&ArpQue->Mac, &mZeroMacAddress, ArpQue->Interface->HwaddrLen)) {\r
- Ip4FreeArpQue (ArpQue, EFI_NO_MAPPING);\r
-\r
- return ;\r
+ if (ArpQue->Interface->SubnetMask != IP4_ALLONE_ADDRESS) {\r
+ //\r
+ // Release all the frame and ARP queue itself. Ip4FreeArpQue will call the frame's\r
+ // owner back.\r
+ //\r
+ IoStatus = EFI_NO_MAPPING;\r
+ } else {\r
+ //\r
+ // ARP resolve failed when using 32bit subnet mask, try to send the packets to the\r
+ // default route.\r
+ //\r
+ IoStatus = Ip4SendFrameToDefaultRoute (ArpQue);\r
+ }\r
+ goto ON_EXIT;\r
}\r
\r
//\r
// queue. It isn't necessary for us to cache the ARP binding because\r
// we always check the ARP cache first before transmit.\r
//\r
+ IoStatus = EFI_SUCCESS;\r
Interface = ArpQue->Interface;\r
\r
NET_LIST_FOR_EACH_SAFE (Entry, Next, &ArpQue->Frames) {\r
\r
Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);\r
if (EFI_ERROR (Status)) {\r
- RemoveEntryList (Entry);\r
+ RemoveEntryList (&Token->Link);\r
Token->CallBack (Token->IpInstance, Token->Packet, Status, 0, Token->Context);\r
\r
Ip4FreeLinkTxToken (Token);\r
}\r
}\r
\r
- Ip4FreeArpQue (ArpQue, EFI_SUCCESS);\r
+ON_EXIT:\r
+ Ip4FreeArpQue (ArpQue, IoStatus);\r
}\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The Arp request event.\r
+ @param Context The context of the callback, a point to the ARP\r
+ queue.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnArpResolved (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK\r
-\r
-Arguments:\r
-\r
- Event - The Arp request event\r
- Context - The context of the callback, a point to the ARP queue\r
-\r
-Returns:\r
-\r
- None\r
-\r
---*/\r
{\r
//\r
// Request Ip4OnArpResolvedDpc as a DPC at TPL_CALLBACK\r
//\r
- NetLibQueueDpc (TPL_CALLBACK, Ip4OnArpResolvedDpc, Context);\r
+ QueueDpc (TPL_CALLBACK, Ip4OnArpResolvedDpc, Context);\r
}\r
\r
\r
Callback funtion when frame transmission is finished. It will\r
call the frame owner's callback function to tell it the result.\r
\r
- @param Context Context which is point to the token.\r
-\r
- @return None.\r
+ @param[in] Context Context which is point to the token.\r
\r
**/\r
-STATIC\r
VOID\r
EFIAPI\r
Ip4OnFrameSentDpc (\r
Ip4FreeLinkTxToken (Token);\r
}\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param[in] Event The transmit token's event.\r
+ @param[in] Context Context which is point to the token.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameSent (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK\r
-\r
-Arguments:\r
-\r
- Event - The transmit token's event\r
- Context - Context which is point to the token.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
{\r
//\r
// Request Ip4OnFrameSentDpc as a DPC at TPL_CALLBACK\r
//\r
- NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameSentDpc, Context);\r
+ QueueDpc (TPL_CALLBACK, Ip4OnFrameSentDpc, Context);\r
}\r
\r
\r
If some error happened, the CallBack won't be called. So, the caller\r
must test the return value, and take action when there is an error.\r
\r
- @param Interface The interface to send the frame from\r
- @param IpInstance The IP child that request the transmission. NULL\r
+ @param[in] Interface The interface to send the frame from\r
+ @param[in] IpInstance The IP child that request the transmission. NULL\r
if it is the IP4 driver itself.\r
- @param Packet The packet to transmit.\r
- @param NextHop The immediate destination to transmit the packet\r
+ @param[in] Packet The packet to transmit.\r
+ @param[in] NextHop The immediate destination to transmit the packet\r
to.\r
- @param CallBack Function to call back when transmit finished.\r
- @param Context Opaque parameter to the call back.\r
+ @param[in] CallBack Function to call back when transmit finished.\r
+ @param[in] Context Opaque parameter to the call back.\r
+ @param[in] IpSb The pointer to the IP4 service binding instance.\r
\r
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource to send the frame\r
@retval EFI_NO_MAPPING Can't resolve the MAC for the nexthop\r
@retval EFI_SUCCESS The packet is successfully transmitted.\r
+ @retval other Other error occurs.\r
\r
**/\r
EFI_STATUS\r
Ip4SendFrame (\r
IN IP4_INTERFACE *Interface,\r
- IN IP4_PROTOCOL *IpInstance, OPTIONAL\r
+ IN IP4_PROTOCOL *IpInstance OPTIONAL,\r
IN NET_BUF *Packet,\r
IN IP4_ADDR NextHop,\r
IN IP4_FRAME_CALLBACK CallBack,\r
- IN VOID *Context\r
+ IN VOID *Context,\r
+ IN IP4_SERVICE *IpSb\r
)\r
{\r
IP4_LINK_TX_TOKEN *Token;\r
\r
ASSERT (Interface->Configured);\r
\r
- Token = Ip4WrapLinkTxToken (Interface, IpInstance, Packet, CallBack, Context);\r
+ Token = Ip4WrapLinkTxToken (Interface, IpInstance, Packet, CallBack, Context, IpSb);\r
\r
if (Token == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
InsertTailList (&Interface->SentFrames, &Token->Link);\r
Status = Interface->Mnp->Transmit (Interface->Mnp, &Token->MnpToken);\r
if (EFI_ERROR (Status)) {\r
- RemoveEntryList (&Interface->SentFrames);\r
+ RemoveEntryList (&Token->Link);\r
goto ON_ERROR;\r
}\r
\r
Call back function when the received packet is freed.\r
Check Ip4OnFrameReceived for information.\r
\r
- @param Context Context, which is the IP4_LINK_RX_TOKEN.\r
-\r
- @return None.\r
+ @param Context Context, which is the IP4_LINK_RX_TOKEN.\r
\r
**/\r
-STATIC\r
VOID\r
+EFIAPI\r
Ip4RecycleFrame (\r
IN VOID *Context\r
)\r
\r
@param Context Context for the callback.\r
\r
- @return None.\r
-\r
**/\r
-STATIC\r
VOID\r
EFIAPI\r
Ip4OnFrameReceivedDpc (\r
Token->CallBack (Token->IpInstance, Packet, EFI_SUCCESS, Flag, Token->Context);\r
}\r
\r
-STATIC\r
+/**\r
+ Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK.\r
+\r
+ @param Event The receive event delivered to MNP for receive.\r
+ @param Context Context for the callback.\r
+\r
+**/\r
VOID\r
EFIAPI\r
Ip4OnFrameReceived (\r
IN EFI_EVENT Event,\r
IN VOID *Context\r
)\r
-/*++\r
-\r
-Routine Description:\r
-\r
- Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK\r
-\r
-Arguments:\r
-\r
- Event - The receive event delivered to MNP for receive.\r
- Context - Context for the callback.\r
-\r
-Returns:\r
-\r
- None.\r
-\r
---*/\r
{\r
//\r
// Request Ip4OnFrameReceivedDpc as a DPC at TPL_CALLBACK\r
//\r
- NetLibQueueDpc (TPL_CALLBACK, Ip4OnFrameReceivedDpc, Context);\r
+ QueueDpc (TPL_CALLBACK, Ip4OnFrameReceivedDpc, Context);\r
}\r
\r
\r
/**\r
Request to receive the packet from the interface.\r
\r
- @param Interface The interface to receive the frames from\r
- @param IpInstance The instance that requests the receive. NULL for\r
+ @param[in] Interface The interface to receive the frames from.\r
+ @param[in] IpInstance The instance that requests the receive. NULL for\r
the driver itself.\r
- @param CallBack Function to call when receive finished.\r
- @param Context Opaque parameter to the callback\r
+ @param[in] CallBack Function to call when receive finished.\r
+ @param[in] Context Opaque parameter to the callback.\r
\r
@retval EFI_ALREADY_STARTED There is already a pending receive request.\r
- @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to receive\r
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to receive.\r
@retval EFI_SUCCESS The recieve request has been started.\r
+ @retval other Other error occurs.\r
\r
**/\r
EFI_STATUS\r
Ip4ReceiveFrame (\r
IN IP4_INTERFACE *Interface,\r
- IN IP4_PROTOCOL *IpInstance, OPTIONAL\r
+ IN IP4_PROTOCOL *IpInstance OPTIONAL,\r
IN IP4_FRAME_CALLBACK CallBack,\r
IN VOID *Context\r
)\r