]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4If.c
MdeModulePkg: Remove trailing white space
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4If.c
index e45727679638106bf2a021d833fa822fbb43aa8e..4e3988132d6bf379a2c87b097343690ef4ccb552 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Implement IP4 pesudo interface.\r
-  \r
-Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
+\r
+Copyright (c) 2005 - 2018, Intel Corporation. All rights reserved.<BR>\r
 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
@@ -68,7 +68,7 @@ Ip4OnArpResolvedDpc (
   @param  Event             The Arp request event.\r
   @param  Context           The context of the callback, a point to the ARP\r
                             queue.\r
-                                \r
+\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -138,8 +138,9 @@ Ip4CancelFrameArp (
   @param[in]  CallBack          Call back function to execute if transmission\r
                                 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   Token               The wrapped token if succeed \r
+  @retval   Token               The wrapped token if succeed\r
   @retval   NULL                The wrapped token if NULL\r
 \r
 **/\r
@@ -149,7 +150,8 @@ Ip4WrapLinkTxToken (
   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
@@ -170,6 +172,7 @@ Ip4WrapLinkTxToken (
 \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
@@ -560,9 +563,6 @@ Ip4SetAddress (
 {\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
@@ -577,13 +577,7 @@ Ip4SetAddress (
   Interface->Ip             = IpAddr;\r
   Interface->SubnetMask     = SubnetMask;\r
   Interface->SubnetBrdcast  = (IpAddr | ~SubnetMask);\r
-\r
-  Type                      = NetGetIpClass (IpAddr);\r
-  ASSERT (Type <= IP4_ADDR_CLASSC);\r
-  Len                       = NetGetMaskLength (SubnetMask);\r
-  ASSERT (Len <= IP4_MASK_MAX);\r
-  Netmask                   = gIp4AllMasks[MIN (Len, Type << 3)];\r
-  Interface->NetBrdcast     = (IpAddr | ~Netmask);\r
+  Interface->NetBrdcast     = (IpAddr | ~SubnetMask);\r
 \r
   //\r
   // Do clean up for Arp child\r
@@ -596,10 +590,10 @@ Ip4SetAddress (
              Interface->Image,\r
              Interface->Controller\r
              );\r
-      \r
+\r
       Interface->Arp = NULL;\r
     }\r
-    \r
+\r
     NetLibDestroyServiceChild (\r
       Interface->Controller,\r
       Interface->Image,\r
@@ -801,9 +795,89 @@ Ip4FreeInterface (
   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
@@ -823,6 +897,7 @@ Ip4OnArpResolvedDpc (
   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
@@ -830,14 +905,23 @@ Ip4OnArpResolvedDpc (
   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
@@ -845,6 +929,7 @@ Ip4OnArpResolvedDpc (
   // 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
@@ -864,7 +949,7 @@ Ip4OnArpResolvedDpc (
 \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
@@ -872,7 +957,8 @@ Ip4OnArpResolvedDpc (
     }\r
   }\r
 \r
-  Ip4FreeArpQue (ArpQue, EFI_SUCCESS);\r
+ON_EXIT:\r
+  Ip4FreeArpQue (ArpQue, IoStatus);\r
 }\r
 \r
 /**\r
@@ -881,7 +967,7 @@ Ip4OnArpResolvedDpc (
   @param  Event             The Arp request event.\r
   @param  Context           The context of the callback, a point to the ARP\r
                             queue.\r
-                                \r
+\r
 **/\r
 VOID\r
 EFIAPI\r
@@ -966,6 +1052,7 @@ Ip4OnFrameSent (
                                 to.\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
@@ -980,7 +1067,8 @@ Ip4SendFrame (
   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
@@ -991,7 +1079,7 @@ Ip4SendFrame (
 \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
@@ -1090,7 +1178,7 @@ SEND_NOW:
   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