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.

489 lines
15 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\rtm\rtmp.h
  5. Abstract:
  6. Provate Interface for Routing Table Manager DLL
  7. Author:
  8. Vadim Eydelman
  9. Revision History:
  10. --*/
  11. #if 0
  12. #ifndef NT_INCLUDED
  13. #include <nt.h>
  14. #endif
  15. #ifndef _NTRTL_
  16. #include <ntrtl.h>
  17. #endif
  18. #ifndef _NTURTL_
  19. #include <nturtl.h>
  20. #endif
  21. #ifndef _WINDEF_
  22. #include <windef.h>
  23. #endif
  24. #ifndef _WINBASE_
  25. #include <winbase.h>
  26. #endif
  27. #ifndef _WINREG_
  28. #include <winreg.h>
  29. #endif
  30. #ifndef _ROUTING_RTM_
  31. #include "rtm.h"
  32. #endif
  33. #ifndef _ROUTING_RMRTM_
  34. #include "rmrtm.h"
  35. #endif
  36. #endif
  37. /*++
  38. *******************************************************************
  39. S u p l e m e n t s t o R T M . H S t r u c t u r e s
  40. *******************************************************************
  41. --*/
  42. // Basic route info, present in routes of all types
  43. typedef struct {
  44. ROUTE_HEADER;
  45. } RTM_XX_ROUTE, *PRTM_XX_ROUTE;
  46. #define XX_INTERFACE RR_InterfaceID
  47. #define XX_PROTOCOL RR_RoutingProtocol
  48. #define XX_METRIC RR_Metric
  49. #define XX_TIMESTAMP RR_TimeStamp
  50. #define XX_PSD RR_ProtocolSpecificData
  51. /*++
  52. *******************************************************************
  53. S u p l e m e n t s t o N T R T L . H S t r u c t u r e s
  54. *******************************************************************
  55. --*/
  56. #define InitializeListEntry(entry) InitializeListHead(entry)
  57. #define IsListEntry(entry) (!IsListEmpty(entry))
  58. #if DBG
  59. #define ASSERTERR(exp) \
  60. if (!(exp)) { \
  61. DbgPrint("Get last error= %d\n", GetLastError ()); \
  62. RtlAssert( #exp, __FILE__, __LINE__, NULL ); \
  63. }
  64. #else
  65. #define ASSERTERR(exp)
  66. #endif
  67. #if DBG
  68. #define ASSERTERRMSG(msg,exp) \
  69. if (!(exp)) { \
  70. DbgPrint("Get last error= %d\n", GetLastError ()); \
  71. RtlAssert( #exp, __FILE__, __LINE__, msg ); \
  72. }
  73. #else
  74. #define ASSERTERRMSG(msg,exp)
  75. #endif
  76. /*++
  77. *******************************************************************
  78. C o n f i g u r a t i o n C o n s t a n t s
  79. *******************************************************************
  80. --*/
  81. // Size of interface index hash table
  82. #define RTM_INTF_HASH_SIZE 31
  83. // Maximum number of nodes in temp net number list that will
  84. // triger an update (temp list is scaned when inserting the route)
  85. #define RTM_TEMP_LIST_MAX_COUNT 16
  86. // Maximum number of nodes in deleted list that will
  87. // triger an update
  88. #define RTM_DELETED_LIST_MAX_COUNT 16
  89. // Maximum time between updates (if not triggered by the conditions above or
  90. // client's query)
  91. #define RTM_NET_NUMBER_UPDATE_PERIOD {(ULONG)(-60*1000*10000), -1L}
  92. // Maximum number of pednign notification change messages
  93. // the queue. If this number is exceeded because some client(s) are
  94. // not dequeueing them, oldest message will be purged
  95. #define RTM_MAX_ROUTE_CHANGE_MESSAGES 10000
  96. /*++
  97. *******************************************************************
  98. D a t a T y p e s
  99. *******************************************************************
  100. --*/
  101. // Types of nodes that can exist in the table
  102. #define RTM_ENUMERATOR_FLAG 0x00000001
  103. #define RTM_BEST_NODE_FLAG 0x00000002
  104. #define RTM_ENABLED_NODE_FLAG 0x00000004
  105. #define RTM_ANY_ENABLE_STATE ((DWORD)(~RTM_ENABLED_NODE_FLAG))
  106. #define RTM_SORTED_NODE_FLAG 0x00000008
  107. #define IsEnumerator(node) (node->RN_Flags&RTM_ENUMERATOR_FLAG)
  108. #define IsBest(node) (node->RN_Flags&RTM_BEST_NODE_FLAG)
  109. #define SetBest(node) node->RN_Flags|=RTM_BEST_NODE_FLAG
  110. #define ResetBest(node) node->RN_Flags&=(~RTM_BEST_NODE_FLAG)
  111. #define IsEnabled(node) (node->RN_Flags&RTM_ENABLED_NODE_FLAG)
  112. #define IsSameEnableState(node,EnableFlag) \
  113. ((node->RN_Flags&RTM_ENABLED_NODE_FLAG)==EnableFlag)
  114. #define SetEnable(node,enable) \
  115. node->RN_Flags = enable \
  116. ? (node->RN_Flags|RTM_ENABLED_NODE_FLAG) \
  117. : (node->RN_Flags&(~RTM_ENABLED_NODE_FLAG))
  118. #define IsSorted(node) (node->RN_Flags&RTM_SORTED_NODE_FLAG)
  119. #define SetSorted(node) node->RN_Flags|=RTM_SORTED_NODE_FLAG
  120. #define RTM_NODE_FLAGS_INIT RTM_ENABLED_NODE_FLAG
  121. #define RTM_ENUMERATOR_FLAGS_INIT RTM_ENUMERATOR_FLAG
  122. // Each node will have the following links:
  123. // Hash table link (routes in each basket are ordered by
  124. // net number.interface.protocol.next_hop_address)
  125. #define RTM_NET_NUMBER_HASH_LINK 0
  126. // Deleted list link: used if entry cannot be deleted
  127. // immediately because net number list is locked by the
  128. // update thread. It is same as hash table link
  129. // because one must first delete entry form the hash table
  130. // before adding it to deleted list (there is no ordering
  131. // in this list)
  132. #define RTM_DELETED_LIST_LINK RTM_NET_NUMBER_HASH_LINK
  133. #if RTM_USE_PROTOCOL_LISTS
  134. // Link in the list of routes associated with a particular routing protocol
  135. // (routes are grouped (not oredered) by the net number and
  136. // ordered by protocol.next_hop_address inside of net number group
  137. #define RTM_PROTOCOL_LIST_LINK (RTM_NET_NUMBER_HASH_LINK+1)
  138. // Link in the list of routes associated with a particular interface
  139. // (routes are grouped (not oredered) by the net number and
  140. // ordered by interface.next_hop_address inside of net number group
  141. #define RTM_INTERFACE_LIST_LINK (RTM_PROTOCOL_LIST_LINK+1)
  142. #else
  143. #define RTM_INTERFACE_LIST_LINK (RTM_NET_NUMBER_HASH_LINK+1)
  144. #endif
  145. // Link in the list ordered by net number.interface.protocol.next_hop_address
  146. // There are two of these list. New routes are normaly inserted
  147. // in temporary list that is periodically merged with master list
  148. #define RTM_NET_NUMBER_LIST_LINK (RTM_INTERFACE_LIST_LINK+1)
  149. // Link in list ordered by expiration time
  150. #define RTM_EXPIRATION_QUEUE_LINK (RTM_NET_NUMBER_LIST_LINK+1)
  151. // Total number of links for each node
  152. #define RTM_NUM_OF_LINKS (RTM_EXPIRATION_QUEUE_LINK+1)
  153. // Client count treshold that prevents client from entering RTM
  154. // API's until table is initialized
  155. #define RTM_CLIENT_STOP_TRESHHOLD (-10000)
  156. // Event with link to store it in the stack
  157. typedef struct _RTM_SYNC_OBJECT {
  158. HANDLE RSO_Event;
  159. SINGLE_LIST_ENTRY RSO_Link;
  160. } RTM_SYNC_OBJECT, *PRTM_SYNC_OBJECT;
  161. // Doubly linked list protected by the event that is
  162. // assigned to the list on demand (when somebody is trying
  163. // to access the list that is already in use)
  164. typedef struct _RTM_SYNC_LIST {
  165. PRTM_SYNC_OBJECT RSL_Sync; // Assigned event
  166. LONG RSL_UseCount; // Number of user accessing or waiting
  167. LIST_ENTRY RSL_Head; // List itself (head)
  168. } RTM_SYNC_LIST, *PRTM_SYNC_LIST;
  169. #if RTM_PROTOCOL_LIST_LINK
  170. /* ****** Protocol lists no longer used ****** */
  171. // Node of list of protocol lists
  172. typedef struct _RTM_PROTOCOL_NODE {
  173. LIST_ENTRY PN_Link; // Link in list of protocol lists
  174. LIST_ENTRY PN_Head; // List of routes associated with
  175. // a protocol
  176. DWORD PN_RoutingProtocol; // Routing Protocol number
  177. } RTM_PROTOCOL_NODE, *PRTM_PROTOCOL_NODE;
  178. #endif
  179. // Node of list of interface lists
  180. typedef struct _RTM_INTERFACE_NODE {
  181. LIST_ENTRY IN_Link; // Link in list of interface lists
  182. LIST_ENTRY IN_Head; // List of routes associated with
  183. // an interface
  184. DWORD IN_InterfaceID; // Interface handle
  185. } RTM_INTERFACE_NODE, *PRTM_INTERFACE_NODE;
  186. // Node of Routing Table
  187. typedef struct _RTM_ROUTE_NODE {
  188. LIST_ENTRY RN_Links[RTM_NUM_OF_LINKS]; // Links in all lists
  189. DWORD RN_Flags;
  190. PRTM_SYNC_LIST RN_Hash; // Hash bucket this entry belongs to
  191. DWORD RN_ExpirationTime; // System (Windows) Time in msec
  192. RTM_XX_ROUTE RN_Route; // Route entry
  193. } RTM_ROUTE_NODE, *PRTM_ROUTE_NODE;
  194. // Node used to enumerate through any of the lists
  195. typedef struct _RTM_ENUMERATOR {
  196. LIST_ENTRY RE_Links[RTM_NUM_OF_LINKS]; // header is same as in
  197. DWORD RE_Flags; // RTM_ROUTE_NODE
  198. INT RE_Link; // Which link is used for enumeration
  199. PLIST_ENTRY RE_Head; // Head of list through which we are
  200. // enumerting
  201. PRTM_SYNC_LIST RE_Lock; // Syncronization object protecting
  202. // the this list
  203. PRTM_SYNC_LIST RE_Hash; // Hash bucket this entry belongs to
  204. DWORD RE_ProtocolFamily; // Table in which we are enumerating
  205. DWORD RE_EnumerationFlags; // Which types of entries to limit
  206. // enumeration to
  207. RTM_XX_ROUTE RE_Route; // Criteria
  208. } RTM_ENUMERATOR, *PRTM_ENUMERATOR;
  209. // Node in route change message list
  210. typedef struct _RTM_ROUTE_CHANGE_NODE {
  211. LIST_ENTRY RCN_Link; // Link in the list
  212. HANDLE RCN_ResponsibleClient; // Client that caused this change
  213. // or null if route was aged out
  214. ULONG RCN_ReferenceCount; // Initialized with total number
  215. // of registered clients and decremented as messages are reported to
  216. // each client until all clients are informed at which point the node
  217. // can be deleted
  218. DWORD RCN_Flags;
  219. PRTM_ROUTE_NODE RCN_Route2;
  220. RTM_XX_ROUTE RCN_Route1;
  221. } RTM_ROUTE_CHANGE_NODE, *PRTM_ROUTE_CHANGE_NODE;
  222. #define RTM_NODE_BASE_SIZE \
  223. (FIELD_OFFSET(RTM_ROUTE_NODE,RN_Route) \
  224. >FIELD_OFFSET(RTM_ROUTE_CHANGE_NODE,RCN_Route1)) \
  225. ? FIELD_OFFSET(RTM_ROUTE_NODE,RN_Route) \
  226. : FIELD_OFFSET(RTM_ROUTE_CHANGE_NODE,RCN_Route1)
  227. // Routing Manager Table
  228. typedef struct _RTM_TABLE {
  229. HANDLE RT_Heap; // Heap to allocate nodes from
  230. LONG RT_APIclientCount; // Count of clients that are
  231. // inside of RTM API calls
  232. HANDLE RT_ExpirationTimer; // Nt timer handle
  233. HANDLE RT_UpdateTimer; // Nt timer handle
  234. DWORD RT_NumOfMessages; // Number of notification
  235. // messages in the queue
  236. ULONG RT_NetworkCount; // Total number of networks
  237. // to which we have routes
  238. DWORD RT_NetNumberTempCount; // How many entries are in
  239. // net number temp list
  240. DWORD RT_DeletedNodesCount; // How many entries are in
  241. // deleted list
  242. LONG RT_UpdateWorkerPending; // Sorted list update is
  243. // being performed or scheduled
  244. // if >=0
  245. LONG RT_ExpirationWorkerPending; // Expiration queue check is
  246. // being performed or scheduled
  247. // if >=0
  248. SINGLE_LIST_ENTRY RT_SyncObjectList; // Stack of events that can be
  249. // used for synchronization
  250. #if RTM_PROTOCOL_LIST_LINK
  251. /* ****** Protocol lists no longer used ****** */
  252. RTM_SYNC_LIST RT_ProtocolList; // List of protocol lists
  253. #endif
  254. RTM_SYNC_LIST RT_NetNumberMasterList; // Master net number list
  255. RTM_SYNC_LIST RT_NetNumberTempList; // Temp net number list
  256. RTM_SYNC_LIST RT_DeletedList; // List of deleted routes
  257. RTM_SYNC_LIST RT_ExpirationQueue; // Expiration queue
  258. RTM_SYNC_LIST RT_RouteChangeQueue;// List of route change messages
  259. RTM_SYNC_LIST RT_ClientList; // List of registered clients
  260. PRTM_SYNC_LIST RT_NetNumberHash; // Hash table
  261. PRTM_SYNC_LIST RT_InterfaceHash; // Hash table of interface lists
  262. RTM_PROTOCOL_FAMILY_CONFIG RT_Config; // Configuration params
  263. CRITICAL_SECTION RT_Lock; // Table-wide lock
  264. } RTM_TABLE, *PRTM_TABLE;
  265. // Structure associated with each client
  266. typedef struct _RTM_CLIENT {
  267. LIST_ENTRY RC_Link; // Link in client list
  268. DWORD RC_ProtocolFamily;
  269. DWORD RC_RoutingProtocol;
  270. DWORD RC_Flags;
  271. HANDLE RC_NotificationEvent; // Event through which client
  272. // is notified about route change
  273. PLIST_ENTRY RC_PendingMessage; // Pointer to first message in
  274. // the route change queue that was not reported
  275. // to the client
  276. } RTM_CLIENT, *PRTM_CLIENT;
  277. #define RT_RouteSize RT_Config.RPFC_RouteSize
  278. #define RT_HashTableSize RT_Config.RPFC_HashSize
  279. #define NNM(Route) (((char *)Route)+sizeof (RTM_XX_ROUTE))
  280. #define NetNumCmp(Table,Route1,Route2) \
  281. (*Table->RT_Config.RPFC_NNcmp)(NNM(Route1),NNM(Route2))
  282. #define NextHopCmp(Table,Route1,Route2) \
  283. (*Table->RT_Config.RPFC_NHAcmp)(Route1,Route2)
  284. #define FSDCmp(Table,Route1,Route2) \
  285. (*Table->RT_Config.RPFC_FSDcmp)(Route1,Route2)
  286. #define ValidateRoute(Table,Route) \
  287. (*Table->RT_Config.RPFC_Validate)(Route)
  288. #define MetricCmp(Table,Route1,Route2) \
  289. (*Table->RT_Config.RPFC_RMcmp)(Route1,Route2)
  290. #define EnterTableAPI(Table) \
  291. ((InterlockedIncrement(&(Table)->RT_APIclientCount)>0) \
  292. ? TRUE \
  293. : (InterlockedDecrement (&(Table)->RT_APIclientCount), FALSE))
  294. #define ExitTableAPI(Table) \
  295. InterlockedDecrement(&(Table)->RT_APIclientCount)
  296. /*++
  297. *******************************************************************
  298. I n t e r n a l F u n c t i o n P r o t o t y p e s
  299. *******************************************************************
  300. --*/
  301. // Initializes sync list object
  302. VOID
  303. InitializeSyncList (
  304. PRTM_SYNC_LIST list
  305. );
  306. #if DBG
  307. #define EnterSyncList(table,list,wait) DoEnterSyncList(table,list,wait,__FILE__,__LINE__)
  308. #else
  309. #define EnterSyncList(table,list,wait) DoEnterSyncList(table,list,wait)
  310. #endif
  311. // Get mutually exclusive access to the sync list obect
  312. // Returns TRUE if access if obtained, FALSE otherwise
  313. BOOLEAN
  314. DoEnterSyncList (
  315. PRTM_TABLE table,
  316. PRTM_SYNC_LIST list,
  317. BOOLEAN wait
  318. #if DBG
  319. , LPSTR file,
  320. ULONG line
  321. #endif
  322. );
  323. // Release previously owned sync list object
  324. VOID
  325. LeaveSyncList (
  326. PRTM_TABLE table,
  327. PRTM_SYNC_LIST list
  328. );
  329. #define HashFunction(Table,Net) \
  330. (*Table->RT_Config.RPFC_Hash)(Net)
  331. #define IntfHashFunction(Table,InterfaceID) \
  332. (InterfaceID%RTM_INTF_HASH_SIZE)
  333. // Finds list of routes that are associated with given interface and returns
  334. // pointer to its head
  335. // Creates new list of none exists yet
  336. PLIST_ENTRY
  337. FindInterfaceList (
  338. PRTM_SYNC_LIST intfHash,
  339. DWORD Interface,
  340. BOOL CreateNew
  341. );
  342. // Finds list of routes that are associated with given iprotocol and returns
  343. // pointer to its head
  344. // Creates new list of none exists yet
  345. PLIST_ENTRY
  346. FindProtocolList (
  347. PRTM_TABLE Table,
  348. DWORD RoutingProtocol,
  349. BOOL CreateNew
  350. );
  351. // Adds node to temporary net number list (to be later merged with master list)
  352. // Both lists are ordered by net number.interface.protocol.next hop address
  353. VOID
  354. AddNetNumberListNode (
  355. PRTM_TABLE Table,
  356. PRTM_ROUTE_NODE newNode
  357. );
  358. // Adds node to expiration time queue. (Queue is ordered by expiration time)
  359. // Return TRUE if new node is the first in the queue
  360. BOOL
  361. AddExpirationQueueNode (
  362. PRTM_TABLE Table,
  363. PRTM_ROUTE_NODE newNode
  364. );
  365. #define MAXTICKS MAXULONG
  366. #define IsLater(Time1,Time2) \
  367. (Time1-Time2<MAXTICKS/2)
  368. #define TimeDiff(Time1,Time2) \
  369. (Time1-Time2)
  370. #define IsPositiveTimeDiff(TimeDiff) \
  371. (TimeDiff<MAXTICKS/2)
  372. #if DBG
  373. // Include debugging function prototypes
  374. #ifndef _RTMDLG_
  375. #include "rtmdlg.h"
  376. #endif
  377. #include <rtutils.h>
  378. #include "rtmdbg.h"
  379. #endif
  380. typedef struct _MASK_ENTRY
  381. {
  382. DWORD dwMask;
  383. DWORD dwCount;
  384. } MASK_ENTRY, *PMASK_ENTRY;
  385. //
  386. // for IPv4 addresses
  387. //
  388. #define MAX_MASKS 32