1 /** @file
2   EFI IP6 route table and route cache table defintions.
3 
4   Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
5 
6   SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #ifndef __EFI_IP6_ROUTE_H__
11 #define __EFI_IP6_ROUTE_H__
12 
13 #define IP6_DIRECT_ROUTE          0x00000001
14 #define IP6_PACKET_TOO_BIG        0x00000010
15 
16 #define IP6_ROUTE_CACHE_HASH_SIZE 31
17 ///
18 /// Max NO. of cache entry per hash bucket
19 ///
20 #define IP6_ROUTE_CACHE_MAX       32
21 
22 #define IP6_ROUTE_CACHE_HASH(Ip1, Ip2) Ip6RouteCacheHash ((Ip1), (Ip2))
23 
24 typedef struct {
25   LIST_ENTRY                Link;
26   INTN                      RefCnt;
27   UINT32                    Flag;
28   UINT8                     PrefixLength;
29   EFI_IPv6_ADDRESS          Destination;
30   EFI_IPv6_ADDRESS          NextHop;
31 } IP6_ROUTE_ENTRY;
32 
33 typedef struct {
34   LIST_ENTRY                Link;
35   INTN                      RefCnt;
36   UINTN                     Tag;
37   EFI_IPv6_ADDRESS          Destination;
38   EFI_IPv6_ADDRESS          Source;
39   EFI_IPv6_ADDRESS          NextHop;
40 } IP6_ROUTE_CACHE_ENTRY;
41 
42 typedef struct {
43   LIST_ENTRY                CacheBucket[IP6_ROUTE_CACHE_HASH_SIZE];
44   UINT8                     CacheNum[IP6_ROUTE_CACHE_HASH_SIZE];
45 } IP6_ROUTE_CACHE;
46 
47 //
48 // Each IP6 instance has its own route table. Each ServiceBinding
49 // instance has a default route table and default address.
50 //
51 // All the route table entries with the same prefix length are linked
52 // together in one route area. For example, RouteArea[0] contains
53 // the default routes. A route table also contains a route cache.
54 //
55 
56 typedef struct _IP6_ROUTE_TABLE {
57   INTN                      RefCnt;
58   UINT32                    TotalNum;
59   LIST_ENTRY                RouteArea[IP6_PREFIX_NUM];
60   IP6_ROUTE_CACHE           Cache;
61 } IP6_ROUTE_TABLE;
62 
63 /**
64   This is the worker function for IP6_ROUTE_CACHE_HASH(). It calculates the value
65   as the index of the route cache bucket according to the prefix of two IPv6 addresses.
66 
67   @param[in]  Ip1     The IPv6 address.
68   @param[in]  Ip2     The IPv6 address.
69 
70   @return The hash value of the prefix of two IPv6 addresses.
71 
72 **/
73 UINT32
74 Ip6RouteCacheHash (
75   IN EFI_IPv6_ADDRESS       *Ip1,
76   IN EFI_IPv6_ADDRESS       *Ip2
77   );
78 
79 /**
80   Allocate and initialize an IP6 route cache entry.
81 
82   @param[in]  Dst           The destination address.
83   @param[in]  Src           The source address.
84   @param[in]  GateWay       The next hop address.
85   @param[in]  Tag           The tag from the caller. This marks all the cache entries
86                             spawned from one route table entry.
87 
88   @return NULL if it failed to allocate memory for the cache. Otherwise, point
89           to the created route cache entry.
90 
91 **/
92 IP6_ROUTE_CACHE_ENTRY *
93 Ip6CreateRouteCacheEntry (
94   IN EFI_IPv6_ADDRESS       *Dst,
95   IN EFI_IPv6_ADDRESS       *Src,
96   IN EFI_IPv6_ADDRESS       *GateWay,
97   IN UINTN                  Tag
98   );
99 
100 /**
101   Free the route cache entry. It is reference counted.
102 
103   @param[in, out]  RtCacheEntry  The route cache entry to free.
104 
105 **/
106 VOID
107 Ip6FreeRouteCacheEntry (
108   IN OUT IP6_ROUTE_CACHE_ENTRY  *RtCacheEntry
109   );
110 
111 /**
112   Find a route cache with the destination and source address. This is
113   used by the ICMPv6 redirect messasge process.
114 
115   @param[in]  RtTable       The route table to search the cache for.
116   @param[in]  Dest          The destination address.
117   @param[in]  Src           The source address.
118 
119   @return NULL if no route entry to the (Dest, Src). Otherwise, point
120           to the correct route cache entry.
121 
122 **/
123 IP6_ROUTE_CACHE_ENTRY *
124 Ip6FindRouteCache (
125   IN IP6_ROUTE_TABLE        *RtTable,
126   IN EFI_IPv6_ADDRESS       *Dest,
127   IN EFI_IPv6_ADDRESS       *Src
128   );
129 
130 /**
131   Build a array of EFI_IP6_ROUTE_TABLE to be returned to the caller. The number
132   of EFI_IP6_ROUTE_TABLE is also returned.
133 
134   @param[in]  RouteTable        The pointer of IP6_ROUTE_TABLE internal used.
135   @param[out] EfiRouteCount     The number of returned route entries.
136   @param[out] EfiRouteTable     The pointer to the array of EFI_IP6_ROUTE_TABLE.
137                                 If NULL, only the route entry count is returned.
138 
139   @retval EFI_SUCCESS           The EFI_IP6_ROUTE_TABLE successfully built.
140   @retval EFI_OUT_OF_RESOURCES  Failed to allocate the memory for the route table.
141 
142 **/
143 EFI_STATUS
144 Ip6BuildEfiRouteTable (
145   IN IP6_ROUTE_TABLE        *RouteTable,
146   OUT UINT32                *EfiRouteCount,
147   OUT EFI_IP6_ROUTE_TABLE   **EfiRouteTable OPTIONAL
148   );
149 
150 /**
151   Create an empty route table, includes its internal route cache.
152 
153   @return NULL if failed to allocate memory for the route table. Otherwise,
154           the point to newly created route table.
155 
156 **/
157 IP6_ROUTE_TABLE *
158 Ip6CreateRouteTable (
159   VOID
160   );
161 
162 /**
163   Free the route table and its associated route cache. Route
164   table is reference counted.
165 
166   @param[in, out]  RtTable      The route table to free.
167 
168 **/
169 VOID
170 Ip6CleanRouteTable (
171   IN OUT IP6_ROUTE_TABLE        *RtTable
172   );
173 
174 /**
175   Allocate a route entry then initialize it with the Destination/PrefixLength
176   and Gateway.
177 
178   @param[in]  Destination     The IPv6 destination address. This is an optional
179                               parameter that may be NULL.
180   @param[in]  PrefixLength    The destination network's prefix length.
181   @param[in]  GatewayAddress  The next hop address. This is optional parameter
182                               that may be NULL.
183 
184   @return NULL if it failed to allocate memeory. Otherwise, the newly created route entry.
185 
186 **/
187 IP6_ROUTE_ENTRY *
188 Ip6CreateRouteEntry (
189   IN EFI_IPv6_ADDRESS       *Destination    OPTIONAL,
190   IN UINT8                  PrefixLength,
191   IN EFI_IPv6_ADDRESS       *GatewayAddress OPTIONAL
192   );
193 
194 /**
195   Search the route table for a most specific match to the Dst. It searches
196   from the longest route area (prefix length == 128) to the shortest route area
197   (default routes). In each route area, it will first search the instance's
198   route table, then the default route table. This is required per the following
199   requirements:
200   1. IP search the route table for a most specific match.
201   2. The local route entries have precedence over the default route entry.
202 
203   @param[in]  RtTable       The route table to search from.
204   @param[in]  Destination   The destionation address to search. If NULL, search
205                             the route table by NextHop.
206   @param[in]  NextHop       The next hop address. If NULL, search the route table
207                             by Destination.
208 
209   @return NULL if no route matches the Dst. Otherwise the point to the
210           most specific route to the Dst.
211 
212 **/
213 IP6_ROUTE_ENTRY *
214 Ip6FindRouteEntry (
215   IN IP6_ROUTE_TABLE        *RtTable,
216   IN EFI_IPv6_ADDRESS       *Destination OPTIONAL,
217   IN EFI_IPv6_ADDRESS       *NextHop     OPTIONAL
218   );
219 
220 /**
221   Free the route table entry. It is reference counted.
222 
223   @param[in, out]  RtEntry  The route entry to free.
224 
225 **/
226 VOID
227 Ip6FreeRouteEntry (
228   IN OUT IP6_ROUTE_ENTRY    *RtEntry
229   );
230 
231 /**
232   Add a route entry to the route table. It is the help function for EfiIp6Routes.
233 
234   @param[in, out]  RtTable        Route table to add route to.
235   @param[in]       Destination    The destination of the network.
236   @param[in]       PrefixLength   The PrefixLength of the destination.
237   @param[in]       GatewayAddress The next hop address.
238 
239   @retval EFI_ACCESS_DENIED     The same route already exists.
240   @retval EFI_OUT_OF_RESOURCES  Failed to allocate memory for the entry.
241   @retval EFI_SUCCESS           The route was added successfully.
242 
243 **/
244 EFI_STATUS
245 Ip6AddRoute (
246   IN OUT IP6_ROUTE_TABLE    *RtTable,
247   IN EFI_IPv6_ADDRESS       *Destination,
248   IN UINT8                  PrefixLength,
249   IN EFI_IPv6_ADDRESS       *GatewayAddress
250   );
251 
252 /**
253   Remove a route entry and all the route caches spawn from it.
254   It is the help function for EfiIp6Routes.
255 
256   @param[in, out] RtTable           The route table to remove the route from.
257   @param[in]      Destination       The destination network.
258   @param[in]      PrefixLength      The PrefixLength of the Destination.
259   @param[in]      GatewayAddress    The next hop address.
260 
261   @retval EFI_SUCCESS           Successfully removed the route entry.
262   @retval EFI_NOT_FOUND         There is no route entry in the table with that
263                                 properity.
264 
265 **/
266 EFI_STATUS
267 Ip6DelRoute (
268   IN OUT IP6_ROUTE_TABLE    *RtTable,
269   IN EFI_IPv6_ADDRESS       *Destination,
270   IN UINT8                  PrefixLength,
271   IN EFI_IPv6_ADDRESS       *GatewayAddress
272   );
273 
274 /**
275   Search the route table to route the packet. Return/create a route
276   cache if there is a route to the destination.
277 
278   @param[in]  IpSb          The IP6 service data.
279   @param[in]  Dest          The destination address to search for.
280   @param[in]  Src           The source address to search for.
281 
282   @return NULL if failed to route packet. Otherwise, a route cache
283           entry that can be used to route packet.
284 
285 **/
286 IP6_ROUTE_CACHE_ENTRY *
287 Ip6Route (
288   IN IP6_SERVICE            *IpSb,
289   IN EFI_IPv6_ADDRESS       *Dest,
290   IN EFI_IPv6_ADDRESS       *Src
291   );
292 
293 #endif
294