+/**\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