Source code of Windows XP (NT5)
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.

434 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. Print("%s\n", S); \
  62. return(E); \
  63. } \
  64. #define Recover(S, E) { \
  65. Print("%s\n", S); \
  66. RECOVER(E); \
  67. } \
  68. #define Assert(s) ASSERT(s)
  69. #define Fatal(S, E) { \
  70. Print("%s\n", S); \
  71. Assert(FALSE); \
  72. } \
  73. // Memory Macros
  74. #define AllocMemory0(nBytes) CTEAllocMemNBoot(nBytes, 'ZICT'); \
  75. #define AllocMemory1(pMem, nBytes, nAvail) \
  76. { \
  77. if (nBytes <= nAvail) \
  78. pMem = CTEAllocMemNBoot(nBytes, \
  79. 'ZICT');\
  80. else \
  81. pMem = NULL; \
  82. \
  83. if (pMem == NULL) \
  84. { \
  85. Recover( \
  86. "Unable to Allocate Memory", \
  87. ERROR_TRIE_RESOURCES); \
  88. } \
  89. \
  90. nAvail -= nBytes; \
  91. }
  92. #define AllocMemory2(pMem, nBytes, nAvail) \
  93. { \
  94. if (nBytes <= nAvail) \
  95. pMem = CTEAllocMem(nBytes); \
  96. else \
  97. pMem = NULL; \
  98. \
  99. if (pMem == NULL) \
  100. { \
  101. Recover( \
  102. "Unable to Allocate Memory", \
  103. ERROR_TRIE_RESOURCES); \
  104. } \
  105. \
  106. nAvail -= nBytes; \
  107. }
  108. #define FreeMemory0(pMem) \
  109. { \
  110. Assert(pMem != NULL); \
  111. CTEFreeMem(pMem); \
  112. pMem = NULL; \
  113. } \
  114. #define FreeMemory1(pMem, nBytes, nAvail) \
  115. { \
  116. Assert(pMem != NULL); \
  117. CTEFreeMem(pMem); \
  118. pMem = NULL; \
  119. nAvail += nBytes; \
  120. } \
  121. // Bit Macros
  122. #define MaskBits(nb) MaskBitsArr[nb]
  123. #define LS(ul, nb) ((ul << nb) & ((nb & ~0x1f) ? 0 : -1))
  124. #define ShowMostSigNBits(ul, nb) (ul & ( LS(~0,(ADDRSIZE - nb)) ))
  125. #define PickMostSigNBits(ul, nb) ((ul) >> (ADDRSIZE - nb))
  126. #define RS(ul, nb) ((ul >> nb) & ((nb & ~0x1f) ? 0 : -1))
  127. #define PickDistPosition(ul1, ul2, nbits, ul) \
  128. (ul = ((ul1 ^ ul2) & ~(RS(((ULONG)~0), nbits)))) \
  129. ? ADDRSIZE - RtlGetMostSigBitSet(ul) - 1: nbits \
  130. //
  131. // #define STRUCT_OF(type, address, field) ((type *) \
  132. // ((PCHAR)(address) - (PCHAR)(&((type *)0)->field)))
  133. //
  134. // Structures
  135. //
  136. typedef struct _STrie STrie;
  137. typedef struct _FTrie FTrie;
  138. // An Trie Data Structure
  139. typedef struct _Trie Trie;
  140. struct _Trie
  141. {
  142. ULONG flags; // Trie's Control Flags
  143. STrie *sTrie; // Slow Trie Component
  144. FTrie *fTrie; // Fast Trie Component
  145. };
  146. //
  147. // Macros
  148. //
  149. /*
  150. UINT
  151. SearchRouteInTrie (IN Trie *pTrie,
  152. IN ULONG routeDest,
  153. IN ULONG routeMask,
  154. IN ULONG routeNHop,
  155. IN PVOID routeOutIF,
  156. IN ULONG matchFlags,
  157. OUT Route **ppBestRoute)
  158. /++
  159. Routine Description:
  160. Search for a specific route in a trie
  161. Arguments:
  162. pTrie - Pointer to the trie to search
  163. routeDest - Dest of route being looked up
  164. routeMask - Mask of route being looked up
  165. routeNHop - NHop of route being looked up
  166. routeOutIF - Outgoing IF for this route
  167. matchFlags - Flags to control route matching
  168. ppBestRoute - To return the best route match
  169. Return Value:
  170. TRIE_SUCCESS or ERROR_TRIE_*
  171. --/
  172. {
  173. return SearchRouteInSTrie(&pTrie->sTrie, routeDest, routeMask, routeNHop,
  174. routeOutIF, matchFlags, ppBestRoute);
  175. }
  176. */
  177. #define SearchRouteInTrie(_pTrie_, _Dest_, _Mask_, _NHop_, \
  178. _OutIF_, _matchFlags_, _ppBestRoute_) \
  179. SearchRouteInSTrie( (_pTrie_)->sTrie, \
  180. _Dest_, \
  181. _Mask_, \
  182. _NHop_, \
  183. _OutIF_, \
  184. _matchFlags_, \
  185. _ppBestRoute_) \
  186. /*++
  187. Dest *
  188. SearchAddrInTrie (IN Trie *pTrie,
  189. IN ULONG Addr)
  190. Routine Description:
  191. Search for an address in a trie
  192. Arguments:
  193. pTrie - Pointer to the trie to search
  194. Addr - Pointer to addr being queried
  195. Return Value:
  196. Return best dest match for this address
  197. --*/
  198. #if !DBG
  199. #define SearchAddrInTrie(_pTrie_, _Addr_) \
  200. (((_pTrie_)->flags & TFLAG_FAST_TRIE_ENABLED) \
  201. ? SearchAddrInFTrie((_pTrie_)->fTrie, _Addr_) \
  202. : SearchAddrInSTrie((_pTrie_)->sTrie, _Addr_)) \
  203. #endif // !DBG
  204. /*
  205. VOID
  206. IterateOverTrie (IN Trie *pTrie,
  207. IN TrieCtxt *pContext,
  208. OUT Route **ppNextRoute,
  209. OUT Dest **ppNextDest OPTIONAL,
  210. OUT UINT *status)
  211. /++
  212. Routine Description:
  213. Gets a pointer to the next route in the Trie.
  214. The first time this function is called, the
  215. context structure should be zeroed, and not
  216. touched thereafter until all routes are read
  217. at which point status is set to TRIE_SUCCESS
  218. Arguments:
  219. pTrie - Pointer to trie to iterate over
  220. pContext - Pointer to iterator context
  221. ppNextRoute - To return the next trie route
  222. ppNextDest - If specified, the routine iterates over destinations
  223. instead of over routes.
  224. status - Iterate Operation's return status
  225. Return Value:
  226. TRIE_SUCCESS or ERROR_TRIE_*
  227. --/
  228. {
  229. *status =
  230. IterateOverSTrie(&pTrie->sTrie, pContext, ppNextRoute, ppNextDest);
  231. }
  232. */
  233. #define IterateOverTrie(_pTrie_, _pContext_, _ppNextRoute_, _ppNextDest_) \
  234. IterateOverSTrie( \
  235. (_pTrie_)->sTrie, _pContext_, _ppNextRoute_, _ppNextDest_)
  236. /*
  237. INLINE
  238. UINT
  239. CALLCONV
  240. IsTrieIteratorValid (IN Trie *pTrie,
  241. IN TrieCtxt *pContext)
  242. /++
  243. Routine Description:
  244. Validates an iterator context & returns status
  245. Arguments:
  246. pTrie - Pointer to trie to iterate over
  247. pContext - Pointer to iterator context
  248. Return Value:
  249. TRIE_SUCCESS or ERROR_TRIE_*
  250. --/
  251. {
  252. return IsSTrieIteratorValid(&pTrie->sTrie, pContext);
  253. }
  254. */
  255. #define IsTrieIteratorValid(_pTrie_, _pContext_) \
  256. IsSTrieIteratorValid( (_pTrie_)->sTrie, _pContext_)
  257. /*
  258. VOID
  259. FreeRouteInTrie (IN Trie *pTrie,
  260. IN Route *pRoute)
  261. /++
  262. Routine Description:
  263. Frees memory for a route
  264. Arguments:
  265. IN -
  266. pTrie - Pointer to trie that owns the route
  267. Route - The Route to be freed
  268. Return Value:
  269. None
  270. --/
  271. {
  272. FreeRouteInSTrie(&pTrie->sTrie, pRoute);
  273. }
  274. */
  275. #define FreeRouteInTrie(_pTrie_, _pRoute_) FreeRouteInSTrie( (_pTrie_)->sTrie, _pRoute_)
  276. // Wrapper Functions
  277. UINT
  278. CreateTrie (IN ULONG levels,
  279. IN ULONG flags,
  280. IN ULONG maxSTMemory,
  281. IN ULONG maxFTMemory,
  282. OUT Trie **pTrie);
  283. VOID
  284. DestroyTrie (IN Trie *pTrie,
  285. OUT UINT *status);
  286. UINT
  287. CALLCONV
  288. InsertIntoTrie (IN Trie *pTrie,
  289. IN Route *pIncRoute,
  290. IN ULONG matchFlags,
  291. OUT Route **ppInsRoute,
  292. OUT Route **ppOldBestRoute,
  293. OUT Route **ppNewBestRoute);
  294. UINT
  295. CALLCONV
  296. DeleteFromTrie (IN Trie *pTrie,
  297. IN Route *pIncRoute,
  298. IN ULONG matchFlags,
  299. OUT Route **ppDelRoute,
  300. OUT Route **ppOldBestRoute,
  301. OUT Route **ppNewBestRoute);
  302. #if DBG
  303. Dest *
  304. SearchAddrInTrie (IN Trie *pTrie,
  305. IN ULONG Addr);
  306. VOID
  307. PrintTrie (IN Trie *pTrie,
  308. IN UINT flags);
  309. VOID
  310. PrintRoute (IN Route *route);
  311. VOID
  312. PrintDest (IN Dest *dest);
  313. VOID
  314. PrintIPAddr (IN ULONG *addr);
  315. #endif
  316. //
  317. // Extern Variables
  318. //
  319. extern const ULONG MaskBitsArr[];
  320. #endif // TRIE_H_INCLUDED