/** @file\r
\r
-Copyright (c) 2005 - 2006, 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
- Ip4Route.c\r
-\r
-Abstract:\r
-\r
+Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
Allocate a route entry then initialize it with the Dest/Netmaks\r
and Gateway.\r
\r
- @param Dest The destination network\r
- @param Netmask The destination network mask\r
- @param GateWay The nexthop address\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
- @return route entry.\r
+ route entry.\r
\r
**/\r
IP4_ROUTE_ENTRY *\r
\r
@param RtEntry The route entry to free.\r
\r
- @return NONE\r
-\r
**/\r
VOID\r
Ip4FreeRouteEntry (\r
ASSERT (RtEntry->RefCnt > 0);\r
\r
if (--RtEntry->RefCnt == 0) {\r
- gBS->FreePool (RtEntry);\r
+ FreePool (RtEntry);\r
}\r
}\r
\r
\r
/**\r
- Allocate and initialize a IP4 route cache entry.\r
+ Allocate and initialize an IP4 route cache entry.\r
\r
- @param Dst The destination address\r
- @param Src The source address\r
- @param GateWay The next hop address\r
- @param Tag The tag from the caller. This marks all the cache\r
- entries spawned from one route table entry.\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
- @return to the created route cache entry.\r
+ to the created route cache entry.\r
\r
**/\r
IP4_ROUTE_CACHE_ENTRY *\r
\r
@param RtCacheEntry The route cache entry to free.\r
\r
- @return None\r
-\r
**/\r
VOID\r
Ip4FreeRouteCacheEntry (\r
ASSERT (RtCacheEntry->RefCnt > 0);\r
\r
if (--RtCacheEntry->RefCnt == 0) {\r
- gBS->FreePool (RtCacheEntry);\r
+ FreePool (RtCacheEntry);\r
}\r
}\r
\r
/**\r
Initialize an empty route cache table.\r
\r
- @param RtCache The rotue cache table to initialize.\r
-\r
- @return NONE\r
+ @param[in, out] RtCache The rotue cache table to initialize.\r
\r
**/\r
VOID\r
Ip4InitRouteCache (\r
- IN IP4_ROUTE_CACHE *RtCache\r
+ IN OUT IP4_ROUTE_CACHE *RtCache\r
)\r
{\r
UINT32 Index;\r
\r
- for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {\r
+ for (Index = 0; Index < IP4_ROUTE_CACHE_HASH_VALUE; Index++) {\r
InitializeListHead (&(RtCache->CacheBucket[Index]));\r
}\r
}\r
Clean up a route cache, that is free all the route cache\r
entries enqueued in the cache.\r
\r
- @param RtCache The route cache table to clean up\r
-\r
- @return None\r
+ @param[in] RtCache The route cache table to clean up\r
\r
**/\r
VOID\r
IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;\r
UINT32 Index;\r
\r
- for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {\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
/**\r
Create an empty route table, includes its internal route cache\r
\r
- None\r
-\r
@return NULL if failed to allocate memory for the route table, otherwise\r
- @return the point to newly created route table.\r
+ the point to newly created route table.\r
\r
**/\r
IP4_ROUTE_TABLE *\r
RtTable->RefCnt = 1;\r
RtTable->TotalNum = 0;\r
\r
- for (Index = 0; Index < IP4_MASK_NUM; Index++) {\r
+ for (Index = 0; Index <= IP4_MASK_MAX; Index++) {\r
InitializeListHead (&(RtTable->RouteArea[Index]));\r
}\r
\r
Free the route table and its associated route cache. Route\r
table is reference counted.\r
\r
- @param RtTable The route table to free.\r
-\r
- @return None\r
+ @param[in] RtTable The route table to free.\r
\r
**/\r
VOID\r
//\r
// Free all the route table entry and its route cache.\r
//\r
- for (Index = 0; Index < IP4_MASK_NUM; Index++) {\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
\r
Ip4CleanRouteCache (&RtTable->Cache);\r
\r
- gBS->FreePool (RtTable);\r
+ FreePool (RtTable);\r
}\r
\r
\r
@param RtCache Route cache to remove the entries from\r
@param Tag The Tag of the entries to remove\r
\r
- @return None\r
-\r
**/\r
VOID\r
Ip4PurgeRouteCache (\r
- IN IP4_ROUTE_CACHE *RtCache,\r
- IN UINTN Tag\r
+ IN OUT IP4_ROUTE_CACHE *RtCache,\r
+ IN UINTN Tag\r
)\r
{\r
LIST_ENTRY *Entry;\r
IP4_ROUTE_CACHE_ENTRY *RtCacheEntry;\r
UINT32 Index;\r
\r
- for (Index = 0; Index < IP4_ROUTE_CACHE_HASH; Index++) {\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
Add a route entry to the route table. All the IP4_ADDRs are in\r
host byte order.\r
\r
- @param RtTable Route table to add route to\r
- @param Dest The destination of the network\r
- @param Netmask The netmask of the destination\r
- @param Gateway The next hop address\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
**/\r
EFI_STATUS\r
Ip4AddRoute (\r
- IN IP4_ROUTE_TABLE *RtTable,\r
- IN IP4_ADDR Dest,\r
- IN IP4_ADDR Netmask,\r
- IN IP4_ADDR Gateway\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
/**\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
+ @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
**/\r
EFI_STATUS\r
Ip4DelRoute (\r
- IN IP4_ROUTE_TABLE *RtTable,\r
- IN IP4_ADDR Dest,\r
- IN IP4_ADDR Netmask,\r
- IN IP4_ADDR Gateway\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
host redirect according to RFC1122. So, only route cache entries\r
are modified according to the ICMP redirect message.\r
\r
- @param RtTable The route table to search the cache for\r
- @param Dest The destination address\r
- @param Src The source address\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
- @return to the correct route cache entry.\r
+ to the correct route cache entry.\r
\r
**/\r
IP4_ROUTE_CACHE_ENTRY *\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
+ 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 RtTable The route table to search from\r
- @param Dst The destionation address to search\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
- @return most specific route to the Dst.\r
+ most specific route to the Dst.\r
\r
**/\r
IP4_ROUTE_ENTRY *\r
\r
RtEntry = NULL;\r
\r
- for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {\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
\r
/**\r
- Search the route table to route the packet. Return/creat a route\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 RtTable The route table to search from\r
- @param Dest The destination address to search for\r
- @param Src The source address to search for\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
- @return entry that can be used to route packet.\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 Src,\r
+ IN IP4_ADDR SubnetMask,\r
+ IN BOOLEAN AlwaysTryDestAddr\r
)\r
{\r
LIST_ENTRY *Head;\r
RtEntry = Ip4FindRouteEntry (RtTable, Dest);\r
\r
if (RtEntry == NULL) {\r
- return 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 send directly to the destination, such as for connected\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
- // send the next hop router.\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 (RtEntry->Flag & IP4_DIRECT_ROUTE) {\r
+ if (SubnetMask == IP4_ALLONE_ADDRESS || ((RtEntry->Flag & IP4_DIRECT_ROUTE) != 0)) {\r
NextHop = Dest;\r
} else {\r
NextHop = RtEntry->NextHop;\r
}\r
\r
- Ip4FreeRouteEntry (RtEntry);\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
GetModeData. The EFI_IP4_ROUTE_TABLE is clumsy to use in the\r
internal operation of the IP4 driver.\r
\r
- @param IpInstance The IP4 child that requests the route table.\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
RtTable = IpInstance->RouteTable;\r
\r
if (IpInstance->EfiRouteTable != NULL) {\r
- gBS->FreePool (IpInstance->EfiRouteTable);\r
+ FreePool (IpInstance->EfiRouteTable);\r
\r
IpInstance->EfiRouteTable = NULL;\r
IpInstance->EfiRouteCount = 0;\r
//\r
Count = 0;\r
\r
- for (Index = IP4_MASK_NUM - 1; Index >= 0; Index--) {\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