@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
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
// network. Otherwise, it is an indirect route, the packet will be\r
// sent to the next hop router.\r
//\r
- if ((RtEntry->Flag & IP4_DIRECT_ROUTE) != 0) {\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
- 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