Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
15 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. trie.h
  5. Abstract:
  6. This module contains declarations common to all
  7. trie schemes for fast, scalable IP route lookup
  8. Author:
  9. Chaitanya Kodeboyina (chaitk) 26-Nov-1997
  10. Revision History:
  11. --*/
  12. #ifndef TRIE_H_INCLUDED
  13. #define TRIE_H_INCLUDED
  14. // Dest and Route declarations
  15. #include "iprtdef.h"
  16. #include "misc.h"
  17. //
  18. // Constants
  19. //
  20. // Size of an IP addr
  21. #define ADDRSIZE 32
  22. // Max number of levels
  23. #define MAXLEVEL 32
  24. // Success and Error Codes
  25. #define TRIE_SUCCESS STATUS_SUCCESS
  26. #define ERROR_TRIE_NOT_INITED STATUS_INVALID_PARAMETER_1
  27. #define ERROR_TRIE_RESOURCES STATUS_INSUFFICIENT_RESOURCES
  28. #define ERROR_TRIE_BAD_PARAM STATUS_INVALID_PARAMETER
  29. #define ERROR_TRIE_NO_ROUTES STATUS_NOT_FOUND
  30. #define ERROR_TRIE_NOT_EMPTY STATUS_INVALID_PARAMETER_2
  31. // Trie being accessed
  32. #define SLOW 0x0100
  33. #define FAST 0x0200
  34. // Trie's Control Flags
  35. #define TFLAG_FAST_TRIE_ENABLED 0x01
  36. // Level of debug print
  37. #define NONE 0x0000
  38. #define POOL 0x0001
  39. #define STAT 0x0002
  40. #define SUMM 0x000F
  41. #define TRIE 0x0080
  42. #define FULL 0x00FF
  43. // Control Matching Routes
  44. #define MATCH_NONE 0x00
  45. #define MATCH_NHOP 0x01
  46. #define MATCH_INTF 0x02
  47. #define MATCH_EXCLUDE_LOCAL 0x04
  48. #define MATCH_FULL (MATCH_NHOP|MATCH_INTF)
  49. // General Macros
  50. #define CALLCONV __fastcall
  51. #define TRY_BLOCK { \
  52. UINT lastError = TRIE_SUCCESS; \
  53. #define ERR_BLOCK CleanUp: \
  54. #define END_BLOCK return lastError; \
  55. } \
  56. #define SET_ERROR(E) lastError = (E); \
  57. #define RECOVER(E) SET_ERROR(E); \
  58. goto CleanUp; \
  59. #define GET_ERROR() (E) \
  60. #define Error(S, E) { \
  61. return( (UINT) E); \
  62. } \
  63. #define Recover(S, E) { \
  64. RECOVER(E); \
  65. } \
  66. #define Assert(s) ASSERT(s)
  67. #define Fatal(S, E) { \
  68. Print("%s\n", S); \
  69. Assert(FALSE); \
  70. } \
  71. // Memory Macros
  72. #define AllocMemory0(nBytes) CTEAllocMemNBoot(nBytes, 'ZICT'); \
  73. #define AllocMemory1(pMem, nBytes, nAvail) \
  74. { \
  75. if (nBytes <= nAvail) \
  76. pMem = CTEAllocMemNBoot(nBytes, \
  77. 'ZICT');\
  78. else \
  79. pMem = NULL; \
  80. \
  81. if (pMem == NULL) \
  82. { \
  83. Recover( \
  84. "Unable to Allocate Memory", \
  85. (UINT)ERROR_TRIE_RESOURCES); \
  86. } \
  87. \
  88. nAvail -= nBytes; \
  89. }
  90. #define AllocMemory2(pMem, nBytes, nAvail) \
  91. { \
  92. if (nBytes <= nAvail) \
  93. pMem = CTEAllocMem(nBytes); \
  94. else \
  95. pMem = NULL; \
  96. \
  97. if (pMem == NULL) \
  98. { \
  99. Recover( \
  100. "Unable to Allocate Memory", \
  101. (UINT)ERROR_TRIE_RESOURCES); \
  102. } \
  103. \
  104. nAvail -= nBytes; \
  105. }
  106. #define FreeMemory0(pMem) \
  107. { \
  108. Assert(pMem != NULL); \
  109. CTEFreeMem(pMem); \
  110. pMem = NULL; \
  111. } \
  112. #define FreeMemory1(pMem, nBytes, nAvail) \
  113. { \
  114. Assert(pMem != NULL); \
  115. CTEFreeMem(pMem); \
  116. pMem = NULL; \
  117. nAvail += nBytes; \
  118. } \
  119. // Bit Macros
  120. #define MaskBits(nb) MaskBitsArr[nb]
  121. #define LS(ul, nb) ((ul << nb) & ((nb & ~0x1f) ? 0 : -1))
  122. #define ShowMostSigNBits(ul, nb) (ul & ( LS(~0,(ADDRSIZE - nb)) ))
  123. #define PickMostSigNBits(ul, nb) ((ul) >> (ADDRSIZE - nb))
  124. #define RS(ul, nb) ((ul >> nb) & ((nb & ~0x1f) ? 0 : -1))
  125. _inline
  126. ULONG PickDistPosition(ULONG ul1, ULONG ul2, ULONG nbits, PULONG ul)
  127. {
  128. *ul = ((ul1 ^ ul2) & ~(RS(((ULONG)~0), nbits)));
  129. return (*ul) ? ADDRSIZE - RtlGetMostSigBitSet(*ul) - 1: nbits;
  130. }
  131. //
  132. // #define STRUCT_OF(type, address, field) ((type *) \
  133. // ((PCHAR)(address) - (PCHAR)(&((type *)0)->field)))
  134. //
  135. // Structures
  136. //
  137. typedef struct _STrie STrie;
  138. typedef struct _FTrie FTrie;
  139. // An Trie Data Structure
  140. typedef struct _Trie Trie;
  141. struct _Trie
  142. {
  143. ULONG flags; // Trie's Control Flags
  144. STrie *sTrie; // Slow Trie Component
  145. FTrie *fTrie; // Fast Trie Component
  146. };
  147. //
  148. // Macros
  149. //
  150. /*
  151. UINT
  152. SearchRouteInTrie (IN Trie *pTrie,
  153. IN ULONG routeDest,
  154. IN ULONG routeMask,
  155. IN ULONG routeNHop,
  156. IN PVOID routeOutIF,
  157. IN ULONG matchFlags,
  158. OUT Route **ppBestRoute)
  159. /++
  160. Routine Description:
  161. Search for a specific route in a trie
  162. Arguments:
  163. pTrie - Pointer to the trie to search
  164. routeDest - Dest of route being looked up
  165. routeMask - Mask of route being looked up
  166. routeNHop - NHop of route being looked up
  167. routeOutIF - Outgoing IF for this route
  168. matchFlags - Flags to control route matching
  169. ppBestRoute - To return the best route match
  170. Return Value:
  171. TRIE_SUCCESS or ERROR_TRIE_*
  172. --/
  173. {
  174. return SearchRouteInSTrie(&pTrie->sTrie, routeDest, routeMask, routeNHop,
  175. routeOutIF, matchFlags, ppBestRoute);
  176. }
  177. */
  178. #define SearchRouteInTrie(_pTrie_, _Dest_, _Mask_, _NHop_, \
  179. _OutIF_, _matchFlags_, _ppBestRoute_) \
  180. SearchRouteInSTrie( (_pTrie_)->sTrie, \
  181. _Dest_, \
  182. _Mask_, \
  183. _NHop_, \
  184. _OutIF_, \
  185. _matchFlags_, \
  186. _ppBestRoute_) \
  187. /*++
  188. Dest *
  189. SearchAddrInTrie (IN Trie *pTrie,
  190. IN ULONG Addr)
  191. Routine Description:
  192. Search for an address in a trie
  193. Arguments:
  194. pTrie - Pointer to the trie to search
  195. Addr - Pointer to addr being queried
  196. Return Value:
  197. Return best dest match for this address
  198. --*/
  199. #if !DBG
  200. #define SearchAddrInTrie(_pTrie_, _Addr_) \
  201. (((_pTrie_)->flags & TFLAG_FAST_TRIE_ENABLED) \
  202. ? SearchAddrInFTrie((_pTrie_)->fTrie, _Addr_) \
  203. : SearchAddrInSTrie((_pTrie_)->sTrie, _Addr_)) \
  204. #endif // !DBG
  205. /*
  206. VOID
  207. IterateOverTrie (IN Trie *pTrie,
  208. IN TrieCtxt *pContext,
  209. OUT Route **ppNextRoute,
  210. OUT Dest **ppNextDest OPTIONAL,
  211. OUT UINT *status)
  212. /++
  213. Routine Description:
  214. Gets a pointer to the next route in the Trie.
  215. The first time this function is called, the
  216. context structure should be zeroed, and not
  217. touched thereafter until all routes are read
  218. at which point status is set to TRIE_SUCCESS
  219. Arguments:
  220. pTrie - Pointer to trie to iterate over
  221. pContext - Pointer to iterator context
  222. ppNextRoute - To return the next trie route
  223. ppNextDest - If specified, the routine iterates over destinations
  224. instead of over routes.
  225. status - Iterate Operation's return status
  226. Return Value:
  227. TRIE_SUCCESS or ERROR_TRIE_*
  228. --/
  229. {
  230. *status =
  231. IterateOverSTrie(&pTrie->sTrie, pContext, ppNextRoute, ppNextDest);
  232. }
  233. */
  234. #define IterateOverTrie(_pTrie_, _pContext_, _ppNextRoute_, _ppNextDest_) \
  235. IterateOverSTrie( \
  236. (_pTrie_)->sTrie, _pContext_, _ppNextRoute_, _ppNextDest_)
  237. /*
  238. INLINE
  239. UINT
  240. CALLCONV
  241. IsTrieIteratorValid (IN Trie *pTrie,
  242. IN TrieCtxt *pContext)
  243. /++
  244. Routine Description:
  245. Validates an iterator context & returns status
  246. Arguments:
  247. pTrie - Pointer to trie to iterate over
  248. pContext - Pointer to iterator context
  249. Return Value:
  250. TRIE_SUCCESS or ERROR_TRIE_*
  251. --/
  252. {
  253. return IsSTrieIteratorValid(&pTrie->sTrie, pContext);
  254. }
  255. */
  256. #define IsTrieIteratorValid(_pTrie_, _pContext_) \
  257. IsSTrieIteratorValid( (_pTrie_)->sTrie, _pContext_)
  258. /*
  259. VOID
  260. FreeRouteInTrie (IN Trie *pTrie,
  261. IN Route *pRoute)
  262. /++
  263. Routine Description:
  264. Frees memory for a route
  265. Arguments:
  266. IN -
  267. pTrie - Pointer to trie that owns the route
  268. Route - The Route to be freed
  269. Return Value:
  270. None
  271. --/
  272. {
  273. FreeRouteInSTrie(&pTrie->sTrie, pRoute);
  274. }
  275. */
  276. #define FreeRouteInTrie(_pTrie_, _pRoute_) FreeRouteInSTrie( (_pTrie_)->sTrie, _pRoute_)
  277. // Wrapper Functions
  278. UINT
  279. CreateTrie (IN ULONG levels,
  280. IN ULONG flags,
  281. IN ULONG maxSTMemory,
  282. IN ULONG maxFTMemory,
  283. OUT Trie **pTrie);
  284. VOID
  285. DestroyTrie (IN Trie *pTrie,
  286. OUT UINT *status);
  287. UINT
  288. CALLCONV
  289. InsertIntoTrie (IN Trie *pTrie,
  290. IN Route *pIncRoute,
  291. IN ULONG matchFlags,
  292. OUT Route **ppInsRoute,
  293. OUT Route **ppOldBestRoute,
  294. OUT Route **ppNewBestRoute);
  295. UINT
  296. CALLCONV
  297. DeleteFromTrie (IN Trie *pTrie,
  298. IN Route *pIncRoute,
  299. IN ULONG matchFlags,
  300. OUT Route **ppDelRoute,
  301. OUT Route **ppOldBestRoute,
  302. OUT Route **ppNewBestRoute);
  303. #if DBG
  304. Dest *
  305. SearchAddrInTrie (IN Trie *pTrie,
  306. IN ULONG Addr);
  307. VOID
  308. PrintTrie (IN Trie *pTrie,
  309. IN UINT flags);
  310. VOID
  311. PrintRoute (IN Route *route);
  312. VOID
  313. PrintDest (IN Dest *dest);
  314. VOID
  315. PrintIPAddr (IN ULONG *addr);
  316. #endif
  317. //
  318. // Extern Variables
  319. //
  320. extern const ULONG MaskBitsArr[];
  321. #endif // TRIE_H_INCLUDED