]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4Dxe / Ip4Route.c
diff --git a/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c b/MdeModulePkg/Universal/Network/Ip4Dxe/Ip4Route.c
deleted file mode 100644 (file)
index 124c073..0000000
+++ /dev/null
@@ -1,673 +0,0 @@
-/** @file\r
-\r
-Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Ip4Impl.h"\r
-\r
-\r
-/**\r
-  Allocate a route entry then initialize it with the Dest/Netmaks\r
-  and Gateway.\r
-\r
-  @param[in]  Dest                  The destination network\r
-  @param[in]  Netmask               The destination network mask\r
-  @param[in]  GateWay               The nexthop address\r
-\r
-  @return NULL if failed to allocate memeory, otherwise the newly created\r
-          route entry.\r
-\r
-**/\r
-IP4_ROUTE_ENTRY *\r
-Ip4CreateRouteEntry (\r
-  IN IP4_ADDR               Dest,\r
-  IN IP4_ADDR               Netmask,\r
-  IN IP4_ADDR               GateWay\r
-  )\r
-{\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-\r
-  RtEntry = AllocatePool (sizeof (IP4_ROUTE_ENTRY));\r
-\r
-  if (RtEntry == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  InitializeListHead (&RtEntry->Link);\r
-\r
-  RtEntry->RefCnt  = 1;\r
-  RtEntry->Dest    = Dest;\r
-  RtEntry->Netmask = Netmask;\r
-  RtEntry->NextHop = GateWay;\r
-  RtEntry->Flag    = 0;\r
-\r
-  return RtEntry;\r
-}\r
-\r
-\r
-/**\r
-  Free the route table entry. It is reference counted.\r
-\r
-  @param  RtEntry               The route entry to free.\r
-\r
-**/\r
-VOID\r
-Ip4FreeRouteEntry (\r
-  IN IP4_ROUTE_ENTRY    *RtEntry\r
-  )\r
-{\r
-  ASSERT (RtEntry->RefCnt > 0);\r
-\r
-  if (--RtEntry->RefCnt == 0) {\r
-    FreePool (RtEntry);\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Allocate and initialize an IP4 route cache entry.\r
-\r
-  @param[in]  Dst                   The destination address\r
-  @param[in]  Src                   The source address\r
-  @param[in]  GateWay               The next hop address\r
-  @param[in]  Tag                   The tag from the caller. This marks all the cache\r
-                                    entries spawned from one route table entry.\r
-\r
-  @return NULL if failed to allocate memory for the cache, other point\r
-          to the created route cache entry.\r
-\r
-**/\r
-IP4_ROUTE_CACHE_ENTRY *\r
-Ip4CreateRouteCacheEntry (\r
-  IN IP4_ADDR               Dst,\r
-  IN IP4_ADDR               Src,\r
-  IN IP4_ADDR               GateWay,\r
-  IN UINTN                  Tag\r
-  )\r
-{\r
-  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;\r
-\r
-  RtCacheEntry = AllocatePool (sizeof (IP4_ROUTE_CACHE_ENTRY));\r
-\r
-  if (RtCacheEntry == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  InitializeListHead (&RtCacheEntry->Link);\r
-\r
-  RtCacheEntry->RefCnt  = 1;\r
-  RtCacheEntry->Dest    = Dst;\r
-  RtCacheEntry->Src     = Src;\r
-  RtCacheEntry->NextHop = GateWay;\r
-  RtCacheEntry->Tag     = Tag;\r
-\r
-  return RtCacheEntry;\r
-}\r
-\r
-\r
-/**\r
-  Free the route cache entry. It is reference counted.\r
-\r
-  @param  RtCacheEntry          The route cache entry to free.\r
-\r
-**/\r
-VOID\r
-Ip4FreeRouteCacheEntry (\r
-  IN IP4_ROUTE_CACHE_ENTRY  *RtCacheEntry\r
-  )\r
-{\r
-  ASSERT (RtCacheEntry->RefCnt > 0);\r
-\r
-  if (--RtCacheEntry->RefCnt == 0) {\r
-    FreePool (RtCacheEntry);\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Initialize an empty route cache table.\r
-\r
-  @param[in, out]  RtCache               The rotue cache table to initialize.\r
-\r
-**/\r
-VOID\r
-Ip4InitRouteCache (\r
-  IN OUT IP4_ROUTE_CACHE        *RtCache\r
-  )\r
-{\r
-  UINT32                    Index;\r
-\r
-  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {\r
-    InitializeListHead (&(RtCache->CacheBucket[Index]));\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Clean up a route cache, that is free all the route cache\r
-  entries enqueued in the cache.\r
-\r
-  @param[in]  RtCache               The route cache table to clean up\r
-\r
-**/\r
-VOID\r
-Ip4CleanRouteCache (\r
-  IN IP4_ROUTE_CACHE        *RtCache\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;\r
-  UINT32                    Index;\r
-\r
-  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {\r
-    NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtCache->CacheBucket[Index])) {\r
-      RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);\r
-\r
-      RemoveEntryList (Entry);\r
-      Ip4FreeRouteCacheEntry (RtCacheEntry);\r
-    }\r
-  }\r
-}\r
-\r
-\r
-\r
-/**\r
-  Create an empty route table, includes its internal route cache\r
-\r
-  @return NULL if failed to allocate memory for the route table, otherwise\r
-          the point to newly created route table.\r
-\r
-**/\r
-IP4_ROUTE_TABLE *\r
-Ip4CreateRouteTable (\r
-  VOID\r
-  )\r
-{\r
-  IP4_ROUTE_TABLE           *RtTable;\r
-  UINT32                    Index;\r
-\r
-  RtTable = AllocatePool (sizeof (IP4_ROUTE_TABLE));\r
-\r
-  if (RtTable == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  RtTable->RefCnt   = 1;\r
-  RtTable->TotalNum = 0;\r
-\r
-  for (Index = 0; Index <= IP4_MASK_MAX; Index++) {\r
-    InitializeListHead (&(RtTable->RouteArea[Index]));\r
-  }\r
-\r
-  RtTable->Next = NULL;\r
-\r
-  Ip4InitRouteCache (&RtTable->Cache);\r
-  return RtTable;\r
-}\r
-\r
-\r
-/**\r
-  Free the route table and its associated route cache. Route\r
-  table is reference counted.\r
-\r
-  @param[in]  RtTable               The route table to free.\r
-\r
-**/\r
-VOID\r
-Ip4FreeRouteTable (\r
-  IN IP4_ROUTE_TABLE        *RtTable\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-  UINT32                    Index;\r
-\r
-  ASSERT (RtTable->RefCnt > 0);\r
-\r
-  if (--RtTable->RefCnt > 0) {\r
-    return ;\r
-  }\r
-\r
-  //\r
-  // Free all the route table entry and its route cache.\r
-  //\r
-  for (Index = 0; Index <= IP4_MASK_MAX; Index++) {\r
-    NET_LIST_FOR_EACH_SAFE (Entry, Next, &(RtTable->RouteArea[Index])) {\r
-      RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
-\r
-      RemoveEntryList (Entry);\r
-      Ip4FreeRouteEntry (RtEntry);\r
-    }\r
-  }\r
-\r
-  Ip4CleanRouteCache (&RtTable->Cache);\r
-\r
-  FreePool (RtTable);\r
-}\r
-\r
-\r
-\r
-/**\r
-  Remove all the cache entries bearing the Tag. When a route cache\r
-  entry is created, it is tagged with the address of route entry\r
-  from which it is spawned. When a route entry is deleted, the cache\r
-  entries spawned from it are also deleted.\r
-\r
-  @param  RtCache               Route cache to remove the entries from\r
-  @param  Tag                   The Tag of the entries to remove\r
-\r
-**/\r
-VOID\r
-Ip4PurgeRouteCache (\r
-  IN OUT IP4_ROUTE_CACHE        *RtCache,\r
-  IN     UINTN                  Tag\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;\r
-  UINT32                    Index;\r
-\r
-  for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {\r
-    NET_LIST_FOR_EACH_SAFE (Entry, Next, &RtCache->CacheBucket[Index]) {\r
-\r
-      RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);\r
-\r
-      if (RtCacheEntry->Tag == Tag) {\r
-        RemoveEntryList (Entry);\r
-        Ip4FreeRouteCacheEntry (RtCacheEntry);\r
-      }\r
-    }\r
-  }\r
-}\r
-\r
-\r
-/**\r
-  Add a route entry to the route table. All the IP4_ADDRs are in\r
-  host byte order.\r
-\r
-  @param[in, out]  RtTable      Route table to add route to\r
-  @param[in]       Dest         The destination of the network\r
-  @param[in]       Netmask      The netmask of the destination\r
-  @param[in]       Gateway      The next hop address\r
-\r
-  @retval EFI_ACCESS_DENIED     The same route already exists\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the entry\r
-  @retval EFI_SUCCESS           The route is added successfully.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip4AddRoute (\r
-  IN OUT IP4_ROUTE_TABLE        *RtTable,\r
-  IN     IP4_ADDR               Dest,\r
-  IN     IP4_ADDR               Netmask,\r
-  IN     IP4_ADDR               Gateway\r
-  )\r
-{\r
-  LIST_ENTRY                *Head;\r
-  LIST_ENTRY                *Entry;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-\r
-  //\r
-  // All the route entries with the same netmask length are\r
-  // linke to the same route area\r
-  //\r
-  Head = &(RtTable->RouteArea[NetGetMaskLength (Netmask)]);\r
-\r
-  //\r
-  // First check whether the route exists\r
-  //\r
-  NET_LIST_FOR_EACH (Entry, Head) {\r
-    RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
-\r
-    if (IP4_NET_EQUAL (RtEntry->Dest, Dest, Netmask) && (RtEntry->NextHop == Gateway)) {\r
-      return EFI_ACCESS_DENIED;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Create a route entry and insert it to the route area.\r
-  //\r
-  RtEntry = Ip4CreateRouteEntry (Dest, Netmask, Gateway);\r
-\r
-  if (RtEntry == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  if (Gateway == IP4_ALLZERO_ADDRESS) {\r
-    RtEntry->Flag = IP4_DIRECT_ROUTE;\r
-  }\r
-\r
-  InsertHeadList (Head, &RtEntry->Link);\r
-  RtTable->TotalNum++;\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Remove a route entry and all the route caches spawn from it.\r
-\r
-  @param  RtTable           The route table to remove the route from\r
-  @param  Dest              The destination network\r
-  @param  Netmask           The netmask of the Dest\r
-  @param  Gateway           The next hop address\r
-\r
-  @retval EFI_SUCCESS           The route entry is successfully removed\r
-  @retval EFI_NOT_FOUND         There is no route entry in the table with that\r
-                                properity.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip4DelRoute (\r
-  IN OUT IP4_ROUTE_TABLE      *RtTable,\r
-  IN     IP4_ADDR             Dest,\r
-  IN     IP4_ADDR             Netmask,\r
-  IN     IP4_ADDR             Gateway\r
-  )\r
-{\r
-  LIST_ENTRY                *Head;\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-\r
-  Head = &(RtTable->RouteArea[NetGetMaskLength (Netmask)]);\r
-\r
-  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {\r
-    RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
-\r
-    if (IP4_NET_EQUAL (RtEntry->Dest, Dest, Netmask) && (RtEntry->NextHop == Gateway)) {\r
-      Ip4PurgeRouteCache (&RtTable->Cache, (UINTN) RtEntry);\r
-      RemoveEntryList (Entry);\r
-      Ip4FreeRouteEntry  (RtEntry);\r
-\r
-      RtTable->TotalNum--;\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
-\r
-\r
-/**\r
-  Find a route cache with the dst and src. This is used by ICMP\r
-  redirect messasge process. All kinds of redirect is treated as\r
-  host redirect according to RFC1122. So, only route cache entries\r
-  are modified according to the ICMP redirect message.\r
-\r
-  @param[in]  RtTable               The route table to search the cache for\r
-  @param[in]  Dest                  The destination address\r
-  @param[in]  Src                   The source address\r
-\r
-  @return NULL if no route entry to the (Dest, Src). Otherwise the point\r
-          to the correct route cache entry.\r
-\r
-**/\r
-IP4_ROUTE_CACHE_ENTRY *\r
-Ip4FindRouteCache (\r
-  IN IP4_ROUTE_TABLE        *RtTable,\r
-  IN IP4_ADDR               Dest,\r
-  IN IP4_ADDR               Src\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;\r
-  UINT32                    Index;\r
-\r
-  Index = IP4_ROUTE_CACHE_HASH (Dest, Src);\r
-\r
-  NET_LIST_FOR_EACH (Entry, &RtTable->Cache.CacheBucket[Index]) {\r
-    RtCacheEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);\r
-\r
-    if ((RtCacheEntry->Dest == Dest) && (RtCacheEntry->Src == Src)) {\r
-      NET_GET_REF (RtCacheEntry);\r
-      return RtCacheEntry;\r
-    }\r
-  }\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Search the route table for a most specific match to the Dst. It searches\r
-  from the longest route area (mask length == 32) to the shortest route area\r
-  (default routes). In each route area, it will first search the instance's\r
-  route table, then the default route table. This is required by the following\r
-  requirements:\r
-  1. IP search the route table for a most specific match\r
-  2. The local route entries have precedence over the default route entry.\r
-\r
-  @param[in]  RtTable               The route table to search from\r
-  @param[in]  Dst                   The destionation address to search\r
-\r
-  @return NULL if no route matches the Dst, otherwise the point to the\r
-          most specific route to the Dst.\r
-\r
-**/\r
-IP4_ROUTE_ENTRY *\r
-Ip4FindRouteEntry (\r
-  IN IP4_ROUTE_TABLE        *RtTable,\r
-  IN IP4_ADDR               Dst\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-  IP4_ROUTE_TABLE           *Table;\r
-  INTN                      Index;\r
-\r
-  RtEntry = NULL;\r
-\r
-  for (Index = IP4_MASK_MAX; Index >= 0; Index--) {\r
-    for (Table = RtTable; Table != NULL; Table = Table->Next) {\r
-      NET_LIST_FOR_EACH (Entry, &Table->RouteArea[Index]) {\r
-        RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
-\r
-        if (IP4_NET_EQUAL (RtEntry->Dest, Dst, RtEntry->Netmask)) {\r
-          NET_GET_REF (RtEntry);\r
-          return RtEntry;\r
-        }\r
-      }\r
-    }\r
-  }\r
-\r
-\r
-  return NULL;\r
-}\r
-\r
-\r
-/**\r
-  Search the route table to route the packet. Return/create a route\r
-  cache if there is a route to the destination.\r
-\r
-  @param[in]  RtTable               The route table to search from\r
-  @param[in]  Dest                  The destination address to search for\r
-  @param[in]  Src                   The source address to search for\r
-  @param[in]  SubnetMask            The subnet mask of the Src address, this field is\r
-                                    used to check if the station is using /32 subnet.\r
-  @param[in]  AlwaysTryDestAddr     Always try to use the dest address as next hop even\r
-                                    though we can't find a matching route entry. This\r
-                                    field is only valid when using /32 subnet.\r
-\r
-  @return NULL if failed to route packet, otherwise a route cache\r
-          entry that can be used to route packet.\r
-\r
-**/\r
-IP4_ROUTE_CACHE_ENTRY *\r
-Ip4Route (\r
-  IN IP4_ROUTE_TABLE        *RtTable,\r
-  IN IP4_ADDR               Dest,\r
-  IN IP4_ADDR               Src,\r
-  IN IP4_ADDR               SubnetMask,\r
-  IN BOOLEAN                AlwaysTryDestAddr\r
-  )\r
-{\r
-  LIST_ENTRY                *Head;\r
-  LIST_ENTRY                *Entry;\r
-  LIST_ENTRY                *Next;\r
-  IP4_ROUTE_CACHE_ENTRY     *RtCacheEntry;\r
-  IP4_ROUTE_CACHE_ENTRY     *Cache;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-  IP4_ADDR                  NextHop;\r
-  UINT32                    Count;\r
-\r
-  ASSERT (RtTable != NULL);\r
-\r
-  Head          = &RtTable->Cache.CacheBucket[IP4_ROUTE_CACHE_HASH (Dest, Src)];\r
-  RtCacheEntry  = Ip4FindRouteCache (RtTable, Dest, Src);\r
-\r
-  //\r
-  // If found, promote the cache entry to the head of the hash bucket. LRU\r
-  //\r
-  if (RtCacheEntry != NULL) {\r
-    RemoveEntryList (&RtCacheEntry->Link);\r
-    InsertHeadList (Head, &RtCacheEntry->Link);\r
-    return RtCacheEntry;\r
-  }\r
-\r
-  //\r
-  // Search the route table for the most specific route\r
-  //\r
-  RtEntry = Ip4FindRouteEntry (RtTable, Dest);\r
-\r
-  if (RtEntry == NULL) {\r
-    if (SubnetMask != IP4_ALLONE_ADDRESS) {\r
-      return NULL;\r
-    } else if (!AlwaysTryDestAddr) {\r
-      return NULL;\r
-    }\r
-  }\r
-\r
-  //\r
-  // Found a route to the Dest, if it is a direct route, the packet\r
-  // will be sent directly to the destination, such as for connected\r
-  // network. Otherwise, it is an indirect route, the packet will be\r
-  // sent to the next hop router.\r
-  //\r
-  // When using /32 subnet mask, the packet will always be sent to the direct\r
-  // destination first, if we can't find a matching route cache.\r
-  //\r
-  if (SubnetMask == IP4_ALLONE_ADDRESS || ((RtEntry->Flag & IP4_DIRECT_ROUTE) != 0)) {\r
-    NextHop = Dest;\r
-  } else {\r
-    NextHop = RtEntry->NextHop;\r
-  }\r
-\r
-  if (RtEntry != NULL) {\r
-    Ip4FreeRouteEntry (RtEntry);\r
-  }\r
-\r
-  //\r
-  // Create a route cache entry, and tag it as spawned from this route entry\r
-  // For /32 subnet mask, the default route in RtEntry will be used if failed\r
-  // to send the packet to driect destination address.\r
-  //\r
-  RtCacheEntry = Ip4CreateRouteCacheEntry (Dest, Src, NextHop, (UINTN) RtEntry);\r
-\r
-  if (RtCacheEntry == NULL) {\r
-    return NULL;\r
-  }\r
-\r
-  InsertHeadList (Head, &RtCacheEntry->Link);\r
-  NET_GET_REF (RtCacheEntry);\r
-\r
-  //\r
-  // Each bucket of route cache can contain at most 64 entries.\r
-  // Remove the entries at the tail of the bucket. These entries\r
-  // are likely to be used least.\r
-  //\r
-  Count = 0;\r
-  NET_LIST_FOR_EACH_SAFE (Entry, Next, Head) {\r
-    if (++Count < IP4_ROUTE_CACHE_MAX) {\r
-      continue;\r
-    }\r
-\r
-    Cache = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_CACHE_ENTRY, Link);\r
-\r
-    RemoveEntryList (Entry);\r
-    Ip4FreeRouteCacheEntry (Cache);\r
-  }\r
-\r
-  return RtCacheEntry;\r
-}\r
-\r
-\r
-/**\r
-  Build a EFI_IP4_ROUTE_TABLE to be returned to the caller of\r
-  GetModeData. The EFI_IP4_ROUTE_TABLE is clumsy to use in the\r
-  internal operation of the IP4 driver.\r
-\r
-  @param[in]  IpInstance        The IP4 child that requests the route table.\r
-\r
-  @retval EFI_SUCCESS           The route table is successfully build\r
-  @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the rotue table.\r
-\r
-**/\r
-EFI_STATUS\r
-Ip4BuildEfiRouteTable (\r
-  IN IP4_PROTOCOL           *IpInstance\r
-  )\r
-{\r
-  LIST_ENTRY                *Entry;\r
-  IP4_ROUTE_TABLE           *RtTable;\r
-  IP4_ROUTE_ENTRY           *RtEntry;\r
-  EFI_IP4_ROUTE_TABLE       *Table;\r
-  UINT32                    Count;\r
-  INT32                     Index;\r
-\r
-  RtTable = IpInstance->RouteTable;\r
-\r
-  if (IpInstance->EfiRouteTable != NULL) {\r
-    FreePool (IpInstance->EfiRouteTable);\r
-\r
-    IpInstance->EfiRouteTable = NULL;\r
-    IpInstance->EfiRouteCount = 0;\r
-  }\r
-\r
-  Count = RtTable->TotalNum;\r
-\r
-  if (RtTable->Next != NULL) {\r
-    Count += RtTable->Next->TotalNum;\r
-  }\r
-\r
-  if (Count == 0) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  Table = AllocatePool (sizeof (EFI_IP4_ROUTE_TABLE) * Count);\r
-\r
-  if (Table == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  //\r
-  // Copy the route entry to EFI route table. Keep the order of\r
-  // route entry copied from most specific to default route. That\r
-  // is, interlevel the route entry from the instance's route area\r
-  // and those from the default route table's route area.\r
-  //\r
-  Count = 0;\r
-\r
-  for (Index = IP4_MASK_MAX; Index >= 0; Index--) {\r
-    for (RtTable = IpInstance->RouteTable; RtTable != NULL; RtTable = RtTable->Next) {\r
-      NET_LIST_FOR_EACH (Entry, &(RtTable->RouteArea[Index])) {\r
-        RtEntry = NET_LIST_USER_STRUCT (Entry, IP4_ROUTE_ENTRY, Link);\r
-\r
-        EFI_IP4 (Table[Count].SubnetAddress)  = HTONL (RtEntry->Dest & RtEntry->Netmask);\r
-        EFI_IP4 (Table[Count].SubnetMask)     = HTONL (RtEntry->Netmask);\r
-        EFI_IP4 (Table[Count].GatewayAddress) = HTONL (RtEntry->NextHop);\r
-\r
-        Count++;\r
-      }\r
-    }\r
-  }\r
-\r
-  IpInstance->EfiRouteTable = Table;\r
-  IpInstance->EfiRouteCount = Count;\r
-  return EFI_SUCCESS;\r
-}\r