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