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.
450 lines
9.0 KiB
450 lines
9.0 KiB
/*++
|
|
|
|
|
|
Copyright (c) 1995 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
routing\ip\priority\priority.c
|
|
|
|
Abstract:
|
|
|
|
Route Priority DLL
|
|
|
|
Revision History:
|
|
|
|
Gurdeep Singh Pall 7/19/95 Created
|
|
|
|
--*/
|
|
|
|
#include "priority.h"
|
|
|
|
PRTR_TOC_ENTRY
|
|
GetPointerToTocEntry(
|
|
DWORD dwType,
|
|
PRTR_INFO_BLOCK_HEADER pInfoHdr
|
|
)
|
|
{
|
|
DWORD i;
|
|
|
|
if(pInfoHdr == NULL)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
for(i = 0; i < pInfoHdr->TocEntriesCount; i++)
|
|
{
|
|
if(pInfoHdr->TocEntry[i].InfoType == dwType)
|
|
{
|
|
return &(pInfoHdr->TocEntry[i]);
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
VOID
|
|
InitHashTable(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Initializes the hash tables where the priority information is kept
|
|
|
|
Locks
|
|
|
|
None
|
|
|
|
Arguments
|
|
|
|
None
|
|
|
|
Return Value
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
|
|
for(i=0; i < HASH_TABLE_SIZE; i++)
|
|
{
|
|
InitializeListHead(&HashTable[i]);
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
InitPriorityDLL (
|
|
HANDLE hInst,
|
|
DWORD ulCallReason,
|
|
PVOID pReserved
|
|
)
|
|
{
|
|
static BOOL bPriorityLockInitialized = FALSE;
|
|
|
|
switch(ulCallReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
{
|
|
//
|
|
// Not interested in any XXX_THREAD_XXX reasons
|
|
//
|
|
|
|
DisableThreadLibraryCalls(hInst);
|
|
|
|
//
|
|
// Initialize Critical Section for routing protocol list
|
|
//
|
|
|
|
try
|
|
{
|
|
InitializeCriticalSection(&PriorityLock);
|
|
}
|
|
except (EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
bPriorityLockInitialized = TRUE;
|
|
|
|
//
|
|
// Initialize Hash Table
|
|
//
|
|
|
|
InitHashTable();
|
|
|
|
break;
|
|
}
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
{
|
|
if ( bPriorityLockInitialized )
|
|
{
|
|
DeleteCriticalSection(&PriorityLock);
|
|
bPriorityLockInitialized = FALSE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
case DLL_THREAD_DETACH:
|
|
{
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD
|
|
ComputeRouteMetric(
|
|
IN DWORD dwProtoId
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
This is the main function that computes the priority of a route.
|
|
The priority is filled into the
|
|
|
|
Locks
|
|
|
|
Takes the lock guarding the hash table
|
|
|
|
Arguments
|
|
|
|
pRoute Pointer to route
|
|
|
|
Return Value
|
|
|
|
DWORD priority for the protocol
|
|
|
|
--*/
|
|
|
|
{
|
|
PLIST_ENTRY pleNode;
|
|
RoutingProtocolBlock *pProtoBlk;
|
|
DWORD dwMetric;
|
|
|
|
//
|
|
// Initialize in case the specified protocol is not in the list
|
|
//
|
|
|
|
dwMetric = IP_PRIORITY_DEFAULT_METRIC;
|
|
|
|
EnterCriticalSection(&PriorityLock);
|
|
|
|
//
|
|
// Walk the hash bucket for the protocol
|
|
//
|
|
|
|
for(pleNode = HashTable[dwProtoId % HASH_TABLE_SIZE].Flink;
|
|
pleNode != &(HashTable[dwProtoId % HASH_TABLE_SIZE]);
|
|
pleNode = pleNode->Flink)
|
|
{
|
|
//
|
|
// Cast to appropriate structure
|
|
//
|
|
|
|
pProtoBlk = CONTAINING_RECORD(pleNode,
|
|
RoutingProtocolBlock,
|
|
RPB_List);
|
|
|
|
//
|
|
// If the info is for the protocol, copy out the priority metric
|
|
//
|
|
|
|
if(pProtoBlk->RPB_ProtocolMetric.dwProtocolId == dwProtoId)
|
|
{
|
|
dwMetric = pProtoBlk->RPB_ProtocolMetric.dwMetric;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// *** Exclusion End ***
|
|
//
|
|
|
|
LeaveCriticalSection(&PriorityLock);
|
|
|
|
return dwMetric;
|
|
}
|
|
|
|
|
|
DWORD
|
|
SetPriorityInfo(
|
|
PRTR_INFO_BLOCK_HEADER pInfoHdr
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
This function is called by the IP Router Manager to set the priority
|
|
information in the DLL. The structure and contents of this information
|
|
are opaque to all but the setup and this DLL
|
|
|
|
Locks
|
|
|
|
Takes the hash table lock since the information is changing
|
|
|
|
Arguments
|
|
|
|
pInfoHdr Pointer to the InfoBlock header
|
|
|
|
Return Value
|
|
|
|
NO_ERROR Everything worked OK
|
|
ERROR_NOT_ENOUGH_MEMORY Couldnt allocate memory
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i;
|
|
PLIST_ENTRY pleListHead;
|
|
PPRIORITY_INFO pInfo;
|
|
RoutingProtocolBlock *currentblock;
|
|
PRTR_TOC_ENTRY pToc;
|
|
|
|
pToc = GetPointerToTocEntry(IP_PROT_PRIORITY_INFO,
|
|
pInfoHdr);
|
|
|
|
//
|
|
// No info means leave things as they are
|
|
//
|
|
|
|
if(!pToc)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
pInfo = (PPRIORITY_INFO)GetInfoFromTocEntry(pInfoHdr,
|
|
pToc);
|
|
|
|
if(!pInfo)
|
|
{
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// *** Exclusion Begin ***
|
|
//
|
|
|
|
EnterCriticalSection(&PriorityLock);
|
|
|
|
//
|
|
// If we already have the hash table populated - free the whole table.
|
|
//
|
|
|
|
if(RoutingProtocolBlockPtr)
|
|
{
|
|
HeapFree(GetProcessHeap(),
|
|
0,
|
|
RoutingProtocolBlockPtr);
|
|
|
|
InitHashTable();
|
|
}
|
|
|
|
if(pToc->InfoSize == 0)
|
|
{
|
|
//
|
|
// Means delete all the info - which is done above
|
|
//
|
|
|
|
LeaveCriticalSection(&PriorityLock);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
//
|
|
// Allocate enough RoutingProtocolBlocks to hold the newly specified info
|
|
//
|
|
|
|
RoutingProtocolBlockPtr =
|
|
HeapAlloc(GetProcessHeap(),
|
|
HEAP_ZERO_MEMORY,
|
|
pInfo->dwNumProtocols * sizeof (RoutingProtocolBlock));
|
|
|
|
if(RoutingProtocolBlockPtr == NULL)
|
|
{
|
|
//
|
|
// *** Exclusion End ***
|
|
//
|
|
|
|
LeaveCriticalSection (&PriorityLock);
|
|
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
//
|
|
// Keep a count of the number of protocols
|
|
//
|
|
|
|
NumProtocols = pInfo->dwNumProtocols;
|
|
|
|
//
|
|
// Go thru pInfo and add each protocol and metric to the hash table
|
|
//
|
|
|
|
currentblock = RoutingProtocolBlockPtr;
|
|
|
|
for(i=0; i < NumProtocols; i++)
|
|
{
|
|
currentblock->RPB_ProtocolMetric.dwProtocolId =
|
|
pInfo->ppmProtocolMetric[i].dwProtocolId;
|
|
|
|
currentblock->RPB_ProtocolMetric.dwMetric =
|
|
pInfo->ppmProtocolMetric[i].dwMetric;
|
|
|
|
pleListHead = &HashTable[pInfo->ppmProtocolMetric[i].dwProtocolId % HASH_TABLE_SIZE];
|
|
|
|
InsertTailList(pleListHead,
|
|
¤tblock->RPB_List);
|
|
|
|
currentblock++;
|
|
}
|
|
|
|
//
|
|
// *** Exclusion End ***
|
|
//
|
|
|
|
LeaveCriticalSection (&PriorityLock);
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
DWORD
|
|
GetPriorityInfo(
|
|
IN PVOID pvBuffer,
|
|
OUT PDWORD pdwBufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description
|
|
|
|
Called by router manager to get a copy of our priority information
|
|
|
|
Locks
|
|
|
|
Takes the table lock to ensure consistency
|
|
|
|
Arguments
|
|
|
|
pvBuffer Pointer to buffer into which info is to be written
|
|
pdwBufferSize [IN] Size of the buffer pointed to by pvBuffer
|
|
[OUT] Size of data copied out, or size of buffer needed
|
|
Return Value
|
|
|
|
NO_ERROR Buffer of size *pdwBufferSize was copied out
|
|
ERROR_INSUFFICIENT_BUFFER The buffer was too small to copy out the info
|
|
The size of buffer needed is in *pdwBufferSize
|
|
|
|
--*/
|
|
|
|
{
|
|
DWORD i, dwSizeReqd;
|
|
PPRIORITY_INFO ppiPriorityInfo;
|
|
RoutingProtocolBlock *currentblock;
|
|
|
|
ppiPriorityInfo = pvBuffer;
|
|
|
|
//
|
|
// *** Exclusion Begin ***
|
|
//
|
|
|
|
EnterCriticalSection (&PriorityLock);
|
|
|
|
dwSizeReqd = SIZEOF_PRIORITY_INFO(NumProtocols);
|
|
|
|
if(dwSizeReqd > *pdwBufferSize)
|
|
{
|
|
*pdwBufferSize = dwSizeReqd;
|
|
|
|
//
|
|
// *** Exclusion End ***
|
|
//
|
|
|
|
LeaveCriticalSection (&PriorityLock);
|
|
|
|
return ERROR_INSUFFICIENT_BUFFER;
|
|
}
|
|
|
|
*pdwBufferSize = dwSizeReqd;
|
|
|
|
//
|
|
// Go thru pinfo and get each protocol and metric
|
|
//
|
|
|
|
currentblock = RoutingProtocolBlockPtr;
|
|
|
|
for(i=0; i < NumProtocols; i++)
|
|
{
|
|
ppiPriorityInfo->ppmProtocolMetric[i].dwProtocolId =
|
|
currentblock->RPB_ProtocolMetric.dwProtocolId;
|
|
|
|
ppiPriorityInfo->ppmProtocolMetric[i].dwMetric =
|
|
currentblock->RPB_ProtocolMetric.dwMetric;
|
|
|
|
currentblock++;
|
|
}
|
|
|
|
ppiPriorityInfo->dwNumProtocols = NumProtocols;
|
|
|
|
//
|
|
// *** Exclusion End ***
|
|
//
|
|
|
|
LeaveCriticalSection(&PriorityLock);
|
|
|
|
return NO_ERROR;
|
|
}
|