/** @file EFI IP6 route table and route cache table definitions. Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef __EFI_IP6_ROUTE_H__ #define __EFI_IP6_ROUTE_H__ #define IP6_DIRECT_ROUTE 0x00000001 #define IP6_PACKET_TOO_BIG 0x00000010 #define IP6_ROUTE_CACHE_HASH_SIZE 31 /// /// Max NO. of cache entry per hash bucket /// #define IP6_ROUTE_CACHE_MAX 32 #define IP6_ROUTE_CACHE_HASH(Ip1, Ip2) Ip6RouteCacheHash ((Ip1), (Ip2)) typedef struct { LIST_ENTRY Link; INTN RefCnt; UINT32 Flag; UINT8 PrefixLength; EFI_IPv6_ADDRESS Destination; EFI_IPv6_ADDRESS NextHop; } IP6_ROUTE_ENTRY; typedef struct { LIST_ENTRY Link; INTN RefCnt; UINTN Tag; EFI_IPv6_ADDRESS Destination; EFI_IPv6_ADDRESS Source; EFI_IPv6_ADDRESS NextHop; } IP6_ROUTE_CACHE_ENTRY; typedef struct { LIST_ENTRY CacheBucket[IP6_ROUTE_CACHE_HASH_SIZE]; UINT8 CacheNum[IP6_ROUTE_CACHE_HASH_SIZE]; } IP6_ROUTE_CACHE; // // Each IP6 instance has its own route table. Each ServiceBinding // instance has a default route table and default address. // // All the route table entries with the same prefix length are linked // together in one route area. For example, RouteArea[0] contains // the default routes. A route table also contains a route cache. // typedef struct _IP6_ROUTE_TABLE { INTN RefCnt; UINT32 TotalNum; LIST_ENTRY RouteArea[IP6_PREFIX_NUM]; IP6_ROUTE_CACHE Cache; } IP6_ROUTE_TABLE; /** This is the worker function for IP6_ROUTE_CACHE_HASH(). It calculates the value as the index of the route cache bucket according to the prefix of two IPv6 addresses. @param[in] Ip1 The IPv6 address. @param[in] Ip2 The IPv6 address. @return The hash value of the prefix of two IPv6 addresses. **/ UINT32 Ip6RouteCacheHash ( IN EFI_IPv6_ADDRESS *Ip1, IN EFI_IPv6_ADDRESS *Ip2 ); /** Allocate and initialize an IP6 route cache entry. @param[in] Dst The destination address. @param[in] Src The source address. @param[in] GateWay The next hop address. @param[in] Tag The tag from the caller. This marks all the cache entries spawned from one route table entry. @return NULL if it failed to allocate memory for the cache. Otherwise, point to the created route cache entry. **/ IP6_ROUTE_CACHE_ENTRY * Ip6CreateRouteCacheEntry ( IN EFI_IPv6_ADDRESS *Dst, IN EFI_IPv6_ADDRESS *Src, IN EFI_IPv6_ADDRESS *GateWay, IN UINTN Tag ); /** Free the route cache entry. It is reference counted. @param[in, out] RtCacheEntry The route cache entry to free. **/ VOID Ip6FreeRouteCacheEntry ( IN OUT IP6_ROUTE_CACHE_ENTRY *RtCacheEntry ); /** Find a route cache with the destination and source address. This is used by the ICMPv6 redirect message process. @param[in] RtTable The route table to search the cache for. @param[in] Dest The destination address. @param[in] Src The source address. @return NULL if no route entry to the (Dest, Src). Otherwise, point to the correct route cache entry. **/ IP6_ROUTE_CACHE_ENTRY * Ip6FindRouteCache ( IN IP6_ROUTE_TABLE *RtTable, IN EFI_IPv6_ADDRESS *Dest, IN EFI_IPv6_ADDRESS *Src ); /** Build a array of EFI_IP6_ROUTE_TABLE to be returned to the caller. The number of EFI_IP6_ROUTE_TABLE is also returned. @param[in] RouteTable The pointer of IP6_ROUTE_TABLE internal used. @param[out] EfiRouteCount The number of returned route entries. @param[out] EfiRouteTable The pointer to the array of EFI_IP6_ROUTE_TABLE. If NULL, only the route entry count is returned. @retval EFI_SUCCESS The EFI_IP6_ROUTE_TABLE successfully built. @retval EFI_OUT_OF_RESOURCES Failed to allocate the memory for the route table. **/ EFI_STATUS Ip6BuildEfiRouteTable ( IN IP6_ROUTE_TABLE *RouteTable, OUT UINT32 *EfiRouteCount, OUT EFI_IP6_ROUTE_TABLE **EfiRouteTable OPTIONAL ); /** Create an empty route table, includes its internal route cache. @return NULL if failed to allocate memory for the route table. Otherwise, the point to newly created route table. **/ IP6_ROUTE_TABLE * Ip6CreateRouteTable ( VOID ); /** Free the route table and its associated route cache. Route table is reference counted. @param[in, out] RtTable The route table to free. **/ VOID Ip6CleanRouteTable ( IN OUT IP6_ROUTE_TABLE *RtTable ); /** Allocate a route entry then initialize it with the Destination/PrefixLength and Gateway. @param[in] Destination The IPv6 destination address. This is an optional parameter that may be NULL. @param[in] PrefixLength The destination network's prefix length. @param[in] GatewayAddress The next hop address. This is optional parameter that may be NULL. @return NULL if it failed to allocate memory. Otherwise, the newly created route entry. **/ IP6_ROUTE_ENTRY * Ip6CreateRouteEntry ( IN EFI_IPv6_ADDRESS *Destination OPTIONAL, IN UINT8 PrefixLength, IN EFI_IPv6_ADDRESS *GatewayAddress OPTIONAL ); /** Search the route table for a most specific match to the Dst. It searches from the longest route area (prefix length == 128) to the shortest route area (default routes). In each route area, it will first search the instance's route table, then the default route table. This is required per the following requirements: 1. IP search the route table for a most specific match. 2. The local route entries have precedence over the default route entry. @param[in] RtTable The route table to search from. @param[in] Destination The destination address to search. If NULL, search the route table by NextHop. @param[in] NextHop The next hop address. If NULL, search the route table by Destination. @return NULL if no route matches the Dst. Otherwise the point to the most specific route to the Dst. **/ IP6_ROUTE_ENTRY * Ip6FindRouteEntry ( IN IP6_ROUTE_TABLE *RtTable, IN EFI_IPv6_ADDRESS *Destination OPTIONAL, IN EFI_IPv6_ADDRESS *NextHop OPTIONAL ); /** Free the route table entry. It is reference counted. @param[in, out] RtEntry The route entry to free. **/ VOID Ip6FreeRouteEntry ( IN OUT IP6_ROUTE_ENTRY *RtEntry ); /** Add a route entry to the route table. It is the help function for EfiIp6Routes. @param[in, out] RtTable Route table to add route to. @param[in] Destination The destination of the network. @param[in] PrefixLength The PrefixLength of the destination. @param[in] GatewayAddress The next hop address. @retval EFI_ACCESS_DENIED The same route already exists. @retval EFI_OUT_OF_RESOURCES Failed to allocate memory for the entry. @retval EFI_SUCCESS The route was added successfully. **/ EFI_STATUS Ip6AddRoute ( IN OUT IP6_ROUTE_TABLE *RtTable, IN EFI_IPv6_ADDRESS *Destination, IN UINT8 PrefixLength, IN EFI_IPv6_ADDRESS *GatewayAddress ); /** Remove a route entry and all the route caches spawn from it. It is the help function for EfiIp6Routes. @param[in, out] RtTable The route table to remove the route from. @param[in] Destination The destination network. @param[in] PrefixLength The PrefixLength of the Destination. @param[in] GatewayAddress The next hop address. @retval EFI_SUCCESS Successfully removed the route entry. @retval EFI_NOT_FOUND There is no route entry in the table with that property. **/ EFI_STATUS Ip6DelRoute ( IN OUT IP6_ROUTE_TABLE *RtTable, IN EFI_IPv6_ADDRESS *Destination, IN UINT8 PrefixLength, IN EFI_IPv6_ADDRESS *GatewayAddress ); /** Search the route table to route the packet. Return/create a route cache if there is a route to the destination. @param[in] IpSb The IP6 service data. @param[in] Dest The destination address to search for. @param[in] Src The source address to search for. @return NULL if failed to route packet. Otherwise, a route cache entry that can be used to route packet. **/ IP6_ROUTE_CACHE_ENTRY * Ip6Route ( IN IP6_SERVICE *IpSb, IN EFI_IPv6_ADDRESS *Dest, IN EFI_IPv6_ADDRESS *Src ); #endif