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.

440 lines
11 KiB

  1. //============================================================================
  2. // Copyright (c) 1995, Microsoft Corporation
  3. //
  4. // File: forward.c
  5. //
  6. // History:
  7. // V Raman June-25-1997 Created.
  8. //
  9. // Wrapper functions for callbacks into IP Router Manager.
  10. //============================================================================
  11. #include "pchmgm.h"
  12. #pragma hdrstop
  13. VOID
  14. GetMfeFromForwarder(
  15. PGROUP_ENTRY pge,
  16. PSOURCE_ENTRY pse
  17. )
  18. {
  19. BOOL bFound;
  20. DWORD dwErr = NO_ERROR, dwInd;
  21. PLIST_ENTRY ple, pleHead;
  22. POUT_IF_ENTRY poie = NULL;
  23. PIPMCAST_MFE_STATS pimms = NULL;
  24. TRACEFORWARD4(
  25. FORWARD, "ENTERED GetMfeFromForwarder : Group : %x, %x : Source : "
  26. "%x, %x : ", pge-> dwGroupAddr, pge-> dwGroupMask, pse-> dwSourceAddr,
  27. pse-> dwSourceMask
  28. );
  29. do
  30. {
  31. //
  32. // if MFE is not in forwarder, do not get it
  33. //
  34. if ( !pse-> bInForwarder )
  35. {
  36. break;
  37. }
  38. //
  39. // Allocate large enough buffer and set up query
  40. //
  41. pimms = MGM_ALLOC( SIZEOF_MFE_STATS( pse-> dwMfeIfCount ) );
  42. if ( pimms == NULL )
  43. {
  44. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  45. TRACE1(
  46. ANY, "GetMfeFromForwarder : Failed to create MFE of size : %x",
  47. SIZEOF_MFE_STATS( pse-> dwMfeIfCount )
  48. );
  49. LOGERR0( HEAP_ALLOC_FAILED, dwErr );
  50. break;
  51. }
  52. ZeroMemory( pimms, SIZEOF_MFE_STATS( pse-> dwMfeIfCount ) );
  53. pimms-> dwGroup = pge-> dwGroupAddr;
  54. pimms-> dwSource = pse-> dwSourceAddr;
  55. pimms-> dwSrcMask = pse-> dwSourceMask;
  56. pimms-> ulNumOutIf = pse-> dwMfeIfCount;
  57. //
  58. // Get MFE
  59. //
  60. dwErr = GET_MFE_CALLBACK()( pimms );
  61. if ( dwErr != NO_ERROR )
  62. {
  63. TRACE1(
  64. ANY, "GetMfeFromForwarder : Failed to get MFE from forwarder"
  65. ": %x", dwErr
  66. );
  67. break;
  68. }
  69. //
  70. // Update base MFE statistics
  71. //
  72. RtlCopyMemory( &pse-> imsStatistics, pimms, SIZEOF_BASIC_MFE_STATS );
  73. TRACEFORWARD4(
  74. FORWARD, "Group : %x, Source : %x, In Interface : %x, #out if : %x",
  75. pimms-> dwGroup, pimms-> dwSource, pimms-> dwInIfIndex, pimms-> ulNumOutIf
  76. );
  77. TRACEFORWARD4(
  78. FORWARD, "In Packets : %d, In Bytes : %d, Diff i/f : %d, Q overflow : %d",
  79. pimms-> ulInPkts, pimms-> ulInOctets, pimms-> ulPktsDifferentIf,
  80. pimms-> ulQueueOverflow
  81. );
  82. //
  83. // Update statistics for each outgoing interface
  84. //
  85. pleHead = &pse-> leMfeIfList;
  86. //
  87. // for each outgoing interface in the MFE present in the KMF
  88. //
  89. for ( dwInd = 0; dwInd < pimms-> ulNumOutIf; dwInd++ )
  90. {
  91. //
  92. // find the outgoing interface in the MFE maintained
  93. // by MGM and update the statistics based on what is
  94. // retrieved by the kernel mode forwarder
  95. //
  96. bFound = FALSE;
  97. ple = pleHead-> Flink;
  98. while ( ple != pleHead )
  99. {
  100. poie = CONTAINING_RECORD( ple, OUT_IF_ENTRY, leIfList );
  101. //
  102. // Check if interface has a valid next hop address (non zero)
  103. // - if it does then assume RAS client interface and do
  104. // the interface matching based on (Interface index +
  105. // Next Hop )
  106. //
  107. // - otherwise just do it based on the Interface Index
  108. //
  109. bFound = ( poie-> dwIfIndex ==
  110. pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex );
  111. if ( poie-> dwIfNextHopAddr )
  112. {
  113. bFound = bFound &&
  114. ( poie-> dwIfNextHopAddr ==
  115. pimms-> rgiosOutStats[ dwInd ].dwNextHopAddr );
  116. }
  117. if ( bFound )
  118. {
  119. //
  120. // Outgoing Interface found in MFE in MGM
  121. //
  122. break;
  123. }
  124. ple = ple-> Flink;
  125. }
  126. if ( bFound )
  127. {
  128. //
  129. // Update outgoing interface statistics in MGM
  130. //
  131. poie-> imosIfStats.dwOutIfIndex =
  132. pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex;
  133. poie-> imosIfStats.dwNextHopAddr =
  134. pimms-> rgiosOutStats[ dwInd ].dwNextHopAddr;
  135. poie-> imosIfStats.ulTtlTooLow =
  136. pimms-> rgiosOutStats[ dwInd ].ulTtlTooLow;
  137. poie-> imosIfStats.ulFragNeeded =
  138. pimms-> rgiosOutStats[ dwInd ].ulFragNeeded;
  139. poie-> imosIfStats.ulOutPackets =
  140. pimms-> rgiosOutStats[ dwInd ].ulOutPackets;
  141. poie-> imosIfStats.ulOutDiscards =
  142. pimms-> rgiosOutStats[ dwInd ].ulOutDiscards;
  143. TRACEFORWARD4(
  144. FORWARD, "Out If : %d, Frag : %d, Out packets : %d, Out discards : %d",
  145. pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex,
  146. pimms-> rgiosOutStats[ dwInd ].ulFragNeeded,
  147. pimms-> rgiosOutStats[ dwInd ].ulOutPackets,
  148. pimms-> rgiosOutStats[ dwInd ].ulOutDiscards
  149. );
  150. }
  151. }
  152. } while ( FALSE );
  153. if ( pimms != NULL )
  154. {
  155. MGM_FREE( pimms );
  156. }
  157. TRACEFORWARD0( FORWARD, "LEAVING GetMfeFromForwarder" );
  158. }
  159. //----------------------------------------------------------------------------
  160. // AddMfeToForwarder
  161. //
  162. //
  163. //----------------------------------------------------------------------------
  164. VOID
  165. AddMfeToForwarder(
  166. PGROUP_ENTRY pge,
  167. PSOURCE_ENTRY pse,
  168. DWORD dwTimeout
  169. )
  170. {
  171. DWORD dwErr = NO_ERROR, dwInd = 0;
  172. PIPMCAST_MFE pimm = NULL;
  173. POUT_IF_ENTRY poie = NULL;
  174. PLIST_ENTRY ple = NULL, pleHead = NULL;
  175. TRACEFORWARD6(
  176. FORWARD, "ENTERED AddMfeToForwarder : source : %x, %x : Group : "
  177. "%x, %x : #(out if) : %d : Timeout : %x", pge-> dwGroupAddr,
  178. pge-> dwGroupMask, pse-> dwSourceAddr, pse-> dwSourceMask,
  179. pse-> dwMfeIfCount, dwTimeout
  180. );
  181. do
  182. {
  183. //
  184. // Allocate appropriate sized MFE.
  185. //
  186. pimm = MGM_ALLOC( SIZEOF_MFE( pse-> dwMfeIfCount ) );
  187. if ( pimm == NULL )
  188. {
  189. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  190. TRACE1(
  191. ANY, "AddMfeToForwarder : Failed to create MFE of size : %x",
  192. SIZEOF_MFE( pse-> dwMfeIfCount )
  193. );
  194. LOGERR0( HEAP_ALLOC_FAILED, dwErr );
  195. break;
  196. }
  197. ZeroMemory( pimm, SIZEOF_MFE( pse-> dwMfeIfCount ) );
  198. //
  199. // fill it up
  200. //
  201. pimm-> dwGroup = pge-> dwGroupAddr;
  202. pimm-> dwSource = pse-> dwSourceAddr;
  203. pimm-> dwSrcMask = pse-> dwSourceMask;
  204. pimm-> dwInIfIndex = (pse-> dwMfeIfCount) ? pse-> dwInIfIndex : 0;
  205. pimm-> ulNumOutIf = pse-> dwMfeIfCount;
  206. pimm-> ulTimeOut = ( pse-> dwMfeIfCount ) ? 0 : dwTimeout;
  207. //
  208. // populate the outgoing interface list
  209. //
  210. pleHead = &pse-> leMfeIfList;
  211. for ( ple = pleHead-> Flink ; ple != pleHead; ple = ple-> Flink )
  212. {
  213. poie = CONTAINING_RECORD( ple, OUT_IF_ENTRY, leIfList );
  214. pimm-> rgioOutInfo[ dwInd ].dwOutIfIndex = poie-> dwIfIndex;
  215. if ( poie-> dwIfNextHopAddr )
  216. {
  217. pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr =
  218. poie-> dwIfNextHopAddr;
  219. }
  220. else
  221. {
  222. pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr = pimm-> dwGroup;
  223. }
  224. TRACEFORWARD2(
  225. FORWARD, "AddMfeToForwarder : Out interface %x, next hop %x",
  226. pimm-> rgioOutInfo[ dwInd ].dwOutIfIndex,
  227. pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr
  228. );
  229. pimm-> rgioOutInfo[ dwInd++ ].dwDialContext = 0;
  230. }
  231. //
  232. // invoke callback into the IP router manager
  233. //
  234. if ( IS_ADD_MFE_CALLBACK() )
  235. {
  236. ADD_MFE_CALLBACK() ( pimm );
  237. }
  238. MGM_FREE( pimm );
  239. } while ( FALSE );
  240. TRACEFORWARD1( FORWARD, "LEAVING AddMfeToForwarder %x", dwErr );
  241. return;
  242. }
  243. //----------------------------------------------------------------------------
  244. // DeleteMfeFromForwarder
  245. //
  246. //
  247. //----------------------------------------------------------------------------
  248. VOID
  249. DeleteMfeFromForwarder(
  250. PGROUP_ENTRY pge,
  251. PSOURCE_ENTRY pse
  252. )
  253. {
  254. DWORD dwErr = NO_ERROR;
  255. PIPMCAST_DELETE_MFE pimdm = NULL;
  256. TRACEFORWARD4(
  257. FORWARD, "ENTERED DeleteMfeToForwarder : source : %x, %x : Group : "
  258. "%x, %x : Timeout : %x", pge-> dwGroupAddr, pge-> dwGroupMask,
  259. pse-> dwSourceAddr, pse-> dwSourceMask
  260. );
  261. do
  262. {
  263. //
  264. // Allocate appropriate sized MFE.
  265. //
  266. pimdm = MGM_ALLOC( sizeof( IPMCAST_DELETE_MFE ) );
  267. if ( pimdm == NULL )
  268. {
  269. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  270. TRACE1(
  271. ANY, "DeleteMfeFromForwarder : Failed to create MFE of size :"
  272. " %x", sizeof( IPMCAST_DELETE_MFE )
  273. );
  274. LOGERR0( HEAP_ALLOC_FAILED, dwErr );
  275. break;
  276. }
  277. ZeroMemory( pimdm, sizeof( IPMCAST_DELETE_MFE ) );
  278. //
  279. // fill it up
  280. //
  281. pimdm-> dwGroup = pge-> dwGroupAddr;
  282. pimdm-> dwSource = pse-> dwSourceAddr;
  283. pimdm-> dwSrcMask = pse-> dwSourceMask;
  284. //
  285. // invoke callback into the IP router manager
  286. //
  287. if ( IS_DELETE_MFE_CALLBACK() )
  288. {
  289. DELETE_MFE_CALLBACK() ( pimdm );
  290. }
  291. MGM_FREE( pimdm );
  292. } while ( FALSE );
  293. TRACEFORWARD1( FORWARD, "LEAVING DeleteMfeToForwarder %x", dwErr );
  294. return;
  295. }