//============================================================================ // Copyright (c) 1995, Microsoft Corporation // // File: forward.c // // History: // V Raman June-25-1997 Created. // // Wrapper functions for callbacks into IP Router Manager. //============================================================================ #include "pchmgm.h" #pragma hdrstop VOID GetMfeFromForwarder( PGROUP_ENTRY pge, PSOURCE_ENTRY pse ) { BOOL bFound; DWORD dwErr = NO_ERROR, dwInd; PLIST_ENTRY ple, pleHead; POUT_IF_ENTRY poie = NULL; PIPMCAST_MFE_STATS pimms = NULL; TRACEFORWARD4( FORWARD, "ENTERED GetMfeFromForwarder : Group : %x, %x : Source : " "%x, %x : ", pge-> dwGroupAddr, pge-> dwGroupMask, pse-> dwSourceAddr, pse-> dwSourceMask ); do { // // if MFE is not in forwarder, do not get it // if ( !pse-> bInForwarder ) { break; } // // Allocate large enough buffer and set up query // pimms = MGM_ALLOC( SIZEOF_MFE_STATS( pse-> dwMfeIfCount ) ); if ( pimms == NULL ) { dwErr = ERROR_NOT_ENOUGH_MEMORY; TRACE1( ANY, "GetMfeFromForwarder : Failed to create MFE of size : %x", SIZEOF_MFE_STATS( pse-> dwMfeIfCount ) ); LOGERR0( HEAP_ALLOC_FAILED, dwErr ); break; } ZeroMemory( pimms, SIZEOF_MFE_STATS( pse-> dwMfeIfCount ) ); pimms-> dwGroup = pge-> dwGroupAddr; pimms-> dwSource = pse-> dwSourceAddr; pimms-> dwSrcMask = pse-> dwSourceMask; pimms-> ulNumOutIf = pse-> dwMfeIfCount; // // Get MFE // dwErr = GET_MFE_CALLBACK()( pimms ); if ( dwErr != NO_ERROR ) { TRACE1( ANY, "GetMfeFromForwarder : Failed to get MFE from forwarder" ": %x", dwErr ); break; } // // Update base MFE statistics // RtlCopyMemory( &pse-> imsStatistics, pimms, SIZEOF_BASIC_MFE_STATS ); TRACEFORWARD4( FORWARD, "Group : %x, Source : %x, In Interface : %x, #out if : %x", pimms-> dwGroup, pimms-> dwSource, pimms-> dwInIfIndex, pimms-> ulNumOutIf ); TRACEFORWARD4( FORWARD, "In Packets : %d, In Bytes : %d, Diff i/f : %d, Q overflow : %d", pimms-> ulInPkts, pimms-> ulInOctets, pimms-> ulPktsDifferentIf, pimms-> ulQueueOverflow ); // // Update statistics for each outgoing interface // pleHead = &pse-> leMfeIfList; // // for each outgoing interface in the MFE present in the KMF // for ( dwInd = 0; dwInd < pimms-> ulNumOutIf; dwInd++ ) { // // find the outgoing interface in the MFE maintained // by MGM and update the statistics based on what is // retrieved by the kernel mode forwarder // bFound = FALSE; ple = pleHead-> Flink; while ( ple != pleHead ) { poie = CONTAINING_RECORD( ple, OUT_IF_ENTRY, leIfList ); // // Check if interface has a valid next hop address (non zero) // - if it does then assume RAS client interface and do // the interface matching based on (Interface index + // Next Hop ) // // - otherwise just do it based on the Interface Index // bFound = ( poie-> dwIfIndex == pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex ); if ( poie-> dwIfNextHopAddr ) { bFound = bFound && ( poie-> dwIfNextHopAddr == pimms-> rgiosOutStats[ dwInd ].dwNextHopAddr ); } if ( bFound ) { // // Outgoing Interface found in MFE in MGM // break; } ple = ple-> Flink; } if ( bFound ) { // // Update outgoing interface statistics in MGM // poie-> imosIfStats.dwOutIfIndex = pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex; poie-> imosIfStats.dwNextHopAddr = pimms-> rgiosOutStats[ dwInd ].dwNextHopAddr; poie-> imosIfStats.ulTtlTooLow = pimms-> rgiosOutStats[ dwInd ].ulTtlTooLow; poie-> imosIfStats.ulFragNeeded = pimms-> rgiosOutStats[ dwInd ].ulFragNeeded; poie-> imosIfStats.ulOutPackets = pimms-> rgiosOutStats[ dwInd ].ulOutPackets; poie-> imosIfStats.ulOutDiscards = pimms-> rgiosOutStats[ dwInd ].ulOutDiscards; TRACEFORWARD4( FORWARD, "Out If : %d, Frag : %d, Out packets : %d, Out discards : %d", pimms-> rgiosOutStats[ dwInd ].dwOutIfIndex, pimms-> rgiosOutStats[ dwInd ].ulFragNeeded, pimms-> rgiosOutStats[ dwInd ].ulOutPackets, pimms-> rgiosOutStats[ dwInd ].ulOutDiscards ); } } } while ( FALSE ); if ( pimms != NULL ) { MGM_FREE( pimms ); } TRACEFORWARD0( FORWARD, "LEAVING GetMfeFromForwarder" ); } //---------------------------------------------------------------------------- // AddMfeToForwarder // // //---------------------------------------------------------------------------- VOID AddMfeToForwarder( PGROUP_ENTRY pge, PSOURCE_ENTRY pse, DWORD dwTimeout ) { DWORD dwErr = NO_ERROR, dwInd = 0; PIPMCAST_MFE pimm = NULL; POUT_IF_ENTRY poie = NULL; PLIST_ENTRY ple = NULL, pleHead = NULL; TRACEFORWARD6( FORWARD, "ENTERED AddMfeToForwarder : source : %x, %x : Group : " "%x, %x : #(out if) : %d : Timeout : %x", pge-> dwGroupAddr, pge-> dwGroupMask, pse-> dwSourceAddr, pse-> dwSourceMask, pse-> dwMfeIfCount, dwTimeout ); do { // // Allocate appropriate sized MFE. // pimm = MGM_ALLOC( SIZEOF_MFE( pse-> dwMfeIfCount ) ); if ( pimm == NULL ) { dwErr = ERROR_NOT_ENOUGH_MEMORY; TRACE1( ANY, "AddMfeToForwarder : Failed to create MFE of size : %x", SIZEOF_MFE( pse-> dwMfeIfCount ) ); LOGERR0( HEAP_ALLOC_FAILED, dwErr ); break; } ZeroMemory( pimm, SIZEOF_MFE( pse-> dwMfeIfCount ) ); // // fill it up // pimm-> dwGroup = pge-> dwGroupAddr; pimm-> dwSource = pse-> dwSourceAddr; pimm-> dwSrcMask = pse-> dwSourceMask; pimm-> dwInIfIndex = (pse-> dwMfeIfCount) ? pse-> dwInIfIndex : 0; pimm-> ulNumOutIf = pse-> dwMfeIfCount; pimm-> ulTimeOut = ( pse-> dwMfeIfCount ) ? 0 : dwTimeout; // // populate the outgoing interface list // pleHead = &pse-> leMfeIfList; for ( ple = pleHead-> Flink ; ple != pleHead; ple = ple-> Flink ) { poie = CONTAINING_RECORD( ple, OUT_IF_ENTRY, leIfList ); pimm-> rgioOutInfo[ dwInd ].dwOutIfIndex = poie-> dwIfIndex; if ( poie-> dwIfNextHopAddr ) { pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr = poie-> dwIfNextHopAddr; } else { pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr = pimm-> dwGroup; } TRACEFORWARD2( FORWARD, "AddMfeToForwarder : Out interface %x, next hop %x", pimm-> rgioOutInfo[ dwInd ].dwOutIfIndex, pimm-> rgioOutInfo[ dwInd ].dwNextHopAddr ); pimm-> rgioOutInfo[ dwInd++ ].dwDialContext = 0; } // // invoke callback into the IP router manager // if ( IS_ADD_MFE_CALLBACK() ) { ADD_MFE_CALLBACK() ( pimm ); } MGM_FREE( pimm ); } while ( FALSE ); TRACEFORWARD1( FORWARD, "LEAVING AddMfeToForwarder %x", dwErr ); return; } //---------------------------------------------------------------------------- // DeleteMfeFromForwarder // // //---------------------------------------------------------------------------- VOID DeleteMfeFromForwarder( PGROUP_ENTRY pge, PSOURCE_ENTRY pse ) { DWORD dwErr = NO_ERROR; PIPMCAST_DELETE_MFE pimdm = NULL; TRACEFORWARD4( FORWARD, "ENTERED DeleteMfeToForwarder : source : %x, %x : Group : " "%x, %x : Timeout : %x", pge-> dwGroupAddr, pge-> dwGroupMask, pse-> dwSourceAddr, pse-> dwSourceMask ); do { // // Allocate appropriate sized MFE. // pimdm = MGM_ALLOC( sizeof( IPMCAST_DELETE_MFE ) ); if ( pimdm == NULL ) { dwErr = ERROR_NOT_ENOUGH_MEMORY; TRACE1( ANY, "DeleteMfeFromForwarder : Failed to create MFE of size :" " %x", sizeof( IPMCAST_DELETE_MFE ) ); LOGERR0( HEAP_ALLOC_FAILED, dwErr ); break; } ZeroMemory( pimdm, sizeof( IPMCAST_DELETE_MFE ) ); // // fill it up // pimdm-> dwGroup = pge-> dwGroupAddr; pimdm-> dwSource = pse-> dwSourceAddr; pimdm-> dwSrcMask = pse-> dwSourceMask; // // invoke callback into the IP router manager // if ( IS_DELETE_MFE_CALLBACK() ) { DELETE_MFE_CALLBACK() ( pimdm ); } MGM_FREE( pimdm ); } while ( FALSE ); TRACEFORWARD1( FORWARD, "LEAVING DeleteMfeToForwarder %x", dwErr ); return; }