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.

556 lines
13 KiB

  1. /*++
  2. Copyright (c) 1997 - 98, Microsoft Corporation
  3. Module Name:
  4. rtmquer.c
  5. Abstract:
  6. Contains routines for querying the
  7. best route information in RTM.
  8. Author:
  9. Chaitanya Kodeboyina (chaitk) 24-Aug-1998
  10. Revision History:
  11. --*/
  12. #include "pchrtm.h"
  13. #pragma hdrstop
  14. DWORD
  15. WINAPI
  16. RtmGetExactMatchDestination (
  17. IN RTM_ENTITY_HANDLE RtmRegHandle,
  18. IN PRTM_NET_ADDRESS DestAddress,
  19. IN ULONG ProtocolId,
  20. IN RTM_VIEW_SET TargetViews,
  21. OUT PRTM_DEST_INFO DestInfo
  22. )
  23. /*++
  24. Routine Description:
  25. Queries the route table for a destination with a particular
  26. network address.
  27. Arguments:
  28. RtmRegHandle - RTM registration handle for calling entity,
  29. DestAddress - Network Address of the destination we want,
  30. Protocol Id - Protocol Id that determines the best route
  31. information returned in 'DestInfo' param,
  32. TargetViews - Views in which the query is executed (a '0'
  33. val will eliminate view membership checks),
  34. DestInfo - Information related to this dest is returned
  35. in this structure for all the views requested.
  36. Return Value:
  37. Status of the operation
  38. --*/
  39. {
  40. PADDRFAM_INFO AddrFamInfo;
  41. PENTITY_INFO Entity;
  42. PDEST_INFO Dest;
  43. PLOOKUP_LINKAGE DestData;
  44. DWORD Status;
  45. //
  46. // Validate the input parameters before the search
  47. //
  48. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  49. AddrFamInfo = Entity->OwningAddrFamily;
  50. ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  51. //
  52. // Search route table using the dest address
  53. //
  54. Status = SearchInTable(AddrFamInfo->RouteTable,
  55. DestAddress->NumBits,
  56. DestAddress->AddrBits,
  57. NULL,
  58. &DestData);
  59. if (SUCCESS(Status))
  60. {
  61. Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
  62. //
  63. // Check if the destination is in any of the input views
  64. //
  65. if ((TargetViews == RTM_VIEW_MASK_ANY) ||
  66. (Dest->BelongsToViews & TargetViews))
  67. {
  68. //
  69. // Get the destination info from the dest
  70. //
  71. GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
  72. Status = NO_ERROR;
  73. }
  74. else
  75. {
  76. Status = ERROR_NOT_FOUND;
  77. }
  78. }
  79. RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  80. return Status;
  81. }
  82. DWORD
  83. WINAPI
  84. RtmGetMostSpecificDestination (
  85. IN RTM_ENTITY_HANDLE RtmRegHandle,
  86. IN PRTM_NET_ADDRESS DestAddress,
  87. IN ULONG ProtocolId,
  88. IN RTM_VIEW_SET TargetViews,
  89. OUT PRTM_DEST_INFO DestInfo
  90. )
  91. /*++
  92. Routine Description:
  93. Queries the route table for a destination with the best
  94. (longest) match of a particular network address.
  95. Arguments:
  96. RtmRegHandle - RTM registration handle for calling entity,
  97. DestAddress - Network Address that we are searching for,
  98. Protocol Id - Protocol Id that determines the best route
  99. information returned in 'DestInfo' param,
  100. TargetViews - Views in which the query is executed (a '0'
  101. val will eliminate view membership checks),
  102. DestInfo - Information related to this dest is returned
  103. in this structure for all the views requested.
  104. Return Value:
  105. Status of the operation
  106. --*/
  107. {
  108. PADDRFAM_INFO AddrFamInfo;
  109. PENTITY_INFO Entity;
  110. PDEST_INFO Dest;
  111. PLOOKUP_LINKAGE DestData;
  112. DWORD Status;
  113. //
  114. // Validate the input parameters before the search
  115. //
  116. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  117. AddrFamInfo = Entity->OwningAddrFamily;
  118. Status = ERROR_NOT_FOUND;
  119. ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  120. //
  121. // Search the table for the best match in tree
  122. //
  123. SearchInTable(AddrFamInfo->RouteTable,
  124. DestAddress->NumBits,
  125. DestAddress->AddrBits,
  126. NULL,
  127. &DestData);
  128. while (DestData)
  129. {
  130. Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
  131. //
  132. // Check if the destination is in any of the input views
  133. //
  134. if ((TargetViews == RTM_VIEW_MASK_ANY) ||
  135. (Dest->BelongsToViews & TargetViews))
  136. {
  137. //
  138. // Get the destination info from the dest
  139. //
  140. GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
  141. Status = NO_ERROR;
  142. break;
  143. }
  144. //
  145. // Get the next best prefix, and see if it is in view
  146. //
  147. NextMatchInTable(AddrFamInfo->RouteTable,
  148. DestData,
  149. &DestData);
  150. }
  151. RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  152. return Status;
  153. }
  154. DWORD
  155. WINAPI
  156. RtmGetLessSpecificDestination (
  157. IN RTM_ENTITY_HANDLE RtmRegHandle,
  158. IN RTM_DEST_HANDLE DestHandle,
  159. IN ULONG ProtocolId,
  160. IN RTM_VIEW_SET TargetViews,
  161. OUT PRTM_DEST_INFO DestInfo
  162. )
  163. /*++
  164. Routine Description:
  165. Queries the route table for a destination with the next best
  166. match (longest) prefix. (for a destination given by handle).
  167. Arguments:
  168. RtmRegHandle - RTM registration handle for calling entity,
  169. DestHandle - Destination whose next best match we want,
  170. Protocol Id - Protocol Id that determines the best route
  171. information returned in 'DestInfo' param,
  172. TargetViews - Views in which the query is executed (a '0'
  173. val will eliminate view membership checks),
  174. DestInfo - Information related to this dest is returned
  175. in this structure for all the views requested.
  176. Return Value:
  177. Status of the operation
  178. --*/
  179. {
  180. PADDRFAM_INFO AddrFamInfo;
  181. PENTITY_INFO Entity;
  182. PDEST_INFO Dest;
  183. PLOOKUP_LINKAGE DestData;
  184. DWORD Status;
  185. //
  186. // Validate the input parameters before the search
  187. //
  188. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  189. AddrFamInfo = Entity->OwningAddrFamily;
  190. VALIDATE_DEST_HANDLE(DestHandle, &Dest);
  191. DestData = &Dest->LookupLinkage;
  192. Status = ERROR_NOT_FOUND;
  193. ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  194. //
  195. // Go up the prefix tree till you have a dest in views
  196. //
  197. do
  198. {
  199. //
  200. // Get the next best prefix, and see if it is in views
  201. //
  202. NextMatchInTable(AddrFamInfo->RouteTable,
  203. DestData,
  204. &DestData);
  205. if (DestData == NULL)
  206. {
  207. break;
  208. }
  209. Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
  210. //
  211. // Check if the destination is in any of the input views
  212. //
  213. if ((TargetViews == RTM_VIEW_MASK_ANY) ||
  214. (Dest->BelongsToViews & TargetViews))
  215. {
  216. //
  217. // Get the destination info from the dest
  218. //
  219. GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
  220. Status = NO_ERROR;
  221. break;
  222. }
  223. }
  224. while (TRUE);
  225. RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  226. return Status;
  227. }
  228. DWORD
  229. WINAPI
  230. RtmGetExactMatchRoute (
  231. IN RTM_ENTITY_HANDLE RtmRegHandle,
  232. IN PRTM_NET_ADDRESS DestAddress,
  233. IN RTM_MATCH_FLAGS MatchingFlags,
  234. IN OUT PRTM_ROUTE_INFO RouteInfo,
  235. IN ULONG InterfaceIndex,
  236. IN RTM_VIEW_SET TargetViews,
  237. OUT PRTM_ROUTE_HANDLE RouteHandle
  238. )
  239. /*++
  240. Routine Description:
  241. Queries the route table for a route that matches certain
  242. criteria - a network address, preference and/or nexthop.
  243. Arguments:
  244. RtmRegHandle - RTM registration handle for calling entity,
  245. DestAddress - Network Address of the route we want,
  246. MatchingFlags - Flags that tell how to match a route,
  247. RouteInfo - Criteria that we need to match against,
  248. IntefaceIndex - Interface on which route should be present
  249. in case RTM_MATCH_INTERFACE is specified,
  250. TargetViews - Views in which the query is executed (a '0'
  251. val will eliminate view membership checks),
  252. RouteHandle - Route handle (if an exact match exists),
  253. RouteInfo - Information related to this route is retd.
  254. Return Value:
  255. Status of the operation
  256. --*/
  257. {
  258. PADDRFAM_INFO AddrFamInfo;
  259. PENTITY_INFO Entity;
  260. PDEST_INFO Dest;
  261. PROUTE_INFO Route;
  262. PLOOKUP_LINKAGE DestData;
  263. PLIST_ENTRY p;
  264. DWORD Status;
  265. //
  266. // Validate the input parameters before the search
  267. //
  268. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  269. AddrFamInfo = Entity->OwningAddrFamily;
  270. ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  271. //
  272. // Search route table using the dest address
  273. //
  274. Status = SearchInTable(AddrFamInfo->RouteTable,
  275. DestAddress->NumBits,
  276. DestAddress->AddrBits,
  277. NULL,
  278. &DestData);
  279. if (SUCCESS(Status))
  280. {
  281. Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
  282. Status = ERROR_NOT_FOUND;
  283. //
  284. // Check if the destination matches any input views
  285. //
  286. if ((TargetViews == RTM_VIEW_MASK_ANY) ||
  287. (Dest->BelongsToViews & TargetViews))
  288. {
  289. #if DBG
  290. REFERENCE_DEST(Dest, TEMP_USE_REF);
  291. #endif
  292. //
  293. // At this point, we have the dest. So take the
  294. // dest lock, and release the route table lock.
  295. //
  296. ACQUIRE_DEST_READ_LOCK(Dest);
  297. RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  298. //
  299. // Search routes on dest for a matching route
  300. //
  301. for (p = Dest->RouteList.Flink; p != &Dest->RouteList; p= p->Flink)
  302. {
  303. Route = CONTAINING_RECORD(p, ROUTE_INFO, DestLE);
  304. // Check if this route matches any input views
  305. if ((TargetViews != RTM_VIEW_MASK_ANY) &&
  306. (Route->RouteInfo.BelongsToViews & TargetViews) == 0)
  307. {
  308. continue;
  309. }
  310. // Check if this route matches input criteria
  311. if (MatchingFlags &&
  312. !MatchRouteWithCriteria(Route,
  313. MatchingFlags,
  314. RouteInfo,
  315. InterfaceIndex))
  316. {
  317. continue;
  318. }
  319. //
  320. // Found a matching route - copy the route info
  321. //
  322. REFERENCE_ROUTE(Route, HANDLE_REF);
  323. *RouteHandle = MAKE_HANDLE_FROM_POINTER(Route);
  324. if (ARGUMENT_PRESENT(RouteInfo))
  325. {
  326. GetRouteInfo(Dest, Route, RouteInfo);
  327. }
  328. Status = NO_ERROR;
  329. break;
  330. }
  331. RELEASE_DEST_READ_LOCK(Dest);
  332. #if DBG
  333. DEREFERENCE_DEST(Dest, TEMP_USE_REF);
  334. #endif
  335. return Status;
  336. }
  337. }
  338. RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
  339. return Status;
  340. }
  341. DWORD
  342. WINAPI
  343. RtmIsBestRoute (
  344. IN RTM_ENTITY_HANDLE RtmRegHandle,
  345. IN RTM_ROUTE_HANDLE RouteHandle,
  346. OUT PRTM_VIEW_SET BestInViews
  347. )
  348. /*++
  349. Routine Description:
  350. Gives the set of views in which the route is the best route
  351. to its destination.
  352. Arguments:
  353. RtmRegHandle - RTM registration handle for calling entity,
  354. RouteHandle - Handle to the route whose info we want,
  355. BestInViews - Views that route is the best one in is retd.
  356. Return Value:
  357. Status of the operation
  358. --*/
  359. {
  360. PENTITY_INFO Entity;
  361. PDEST_INFO Dest;
  362. PROUTE_INFO Route;
  363. UINT i;
  364. *BestInViews = 0;
  365. VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
  366. VALIDATE_ROUTE_HANDLE(RouteHandle, &Route);
  367. Dest = DEST_FROM_HANDLE(Route->RouteInfo.DestHandle);
  368. //
  369. // Set the bit in mask if the route is the best in the corr view
  370. //
  371. ACQUIRE_DEST_READ_LOCK(Dest);
  372. for (i = 0; i < Entity->OwningAddrFamily->NumberOfViews; i++)
  373. {
  374. if (Dest->ViewInfo[i].BestRoute == Route)
  375. {
  376. *BestInViews |=
  377. VIEW_MASK(Entity->OwningAddrFamily->ViewIdFromIndex[i]);
  378. }
  379. }
  380. RELEASE_DEST_READ_LOCK(Dest);
  381. return NO_ERROR;
  382. }