windows-nt/Source/XPSP1/NT/net/rras/mgm/forward.c

441 lines
11 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
//============================================================================
// 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;
}