windows-nt/Source/XPSP1/NT/net/rras/rtmv2/rtmquer.c
2020-09-26 16:20:57 +08:00

557 lines
13 KiB
C

/*++
Copyright (c) 1997 - 98, Microsoft Corporation
Module Name:
rtmquer.c
Abstract:
Contains routines for querying the
best route information in RTM.
Author:
Chaitanya Kodeboyina (chaitk) 24-Aug-1998
Revision History:
--*/
#include "pchrtm.h"
#pragma hdrstop
DWORD
WINAPI
RtmGetExactMatchDestination (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_NET_ADDRESS DestAddress,
IN ULONG ProtocolId,
IN RTM_VIEW_SET TargetViews,
OUT PRTM_DEST_INFO DestInfo
)
/*++
Routine Description:
Queries the route table for a destination with a particular
network address.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestAddress - Network Address of the destination we want,
Protocol Id - Protocol Id that determines the best route
information returned in 'DestInfo' param,
TargetViews - Views in which the query is executed (a '0'
val will eliminate view membership checks),
DestInfo - Information related to this dest is returned
in this structure for all the views requested.
Return Value:
Status of the operation
--*/
{
PADDRFAM_INFO AddrFamInfo;
PENTITY_INFO Entity;
PDEST_INFO Dest;
PLOOKUP_LINKAGE DestData;
DWORD Status;
//
// Validate the input parameters before the search
//
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
AddrFamInfo = Entity->OwningAddrFamily;
ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
//
// Search route table using the dest address
//
Status = SearchInTable(AddrFamInfo->RouteTable,
DestAddress->NumBits,
DestAddress->AddrBits,
NULL,
&DestData);
if (SUCCESS(Status))
{
Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
//
// Check if the destination is in any of the input views
//
if ((TargetViews == RTM_VIEW_MASK_ANY) ||
(Dest->BelongsToViews & TargetViews))
{
//
// Get the destination info from the dest
//
GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
Status = NO_ERROR;
}
else
{
Status = ERROR_NOT_FOUND;
}
}
RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
return Status;
}
DWORD
WINAPI
RtmGetMostSpecificDestination (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_NET_ADDRESS DestAddress,
IN ULONG ProtocolId,
IN RTM_VIEW_SET TargetViews,
OUT PRTM_DEST_INFO DestInfo
)
/*++
Routine Description:
Queries the route table for a destination with the best
(longest) match of a particular network address.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestAddress - Network Address that we are searching for,
Protocol Id - Protocol Id that determines the best route
information returned in 'DestInfo' param,
TargetViews - Views in which the query is executed (a '0'
val will eliminate view membership checks),
DestInfo - Information related to this dest is returned
in this structure for all the views requested.
Return Value:
Status of the operation
--*/
{
PADDRFAM_INFO AddrFamInfo;
PENTITY_INFO Entity;
PDEST_INFO Dest;
PLOOKUP_LINKAGE DestData;
DWORD Status;
//
// Validate the input parameters before the search
//
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
AddrFamInfo = Entity->OwningAddrFamily;
Status = ERROR_NOT_FOUND;
ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
//
// Search the table for the best match in tree
//
SearchInTable(AddrFamInfo->RouteTable,
DestAddress->NumBits,
DestAddress->AddrBits,
NULL,
&DestData);
while (DestData)
{
Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
//
// Check if the destination is in any of the input views
//
if ((TargetViews == RTM_VIEW_MASK_ANY) ||
(Dest->BelongsToViews & TargetViews))
{
//
// Get the destination info from the dest
//
GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
Status = NO_ERROR;
break;
}
//
// Get the next best prefix, and see if it is in view
//
NextMatchInTable(AddrFamInfo->RouteTable,
DestData,
&DestData);
}
RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
return Status;
}
DWORD
WINAPI
RtmGetLessSpecificDestination (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_DEST_HANDLE DestHandle,
IN ULONG ProtocolId,
IN RTM_VIEW_SET TargetViews,
OUT PRTM_DEST_INFO DestInfo
)
/*++
Routine Description:
Queries the route table for a destination with the next best
match (longest) prefix. (for a destination given by handle).
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestHandle - Destination whose next best match we want,
Protocol Id - Protocol Id that determines the best route
information returned in 'DestInfo' param,
TargetViews - Views in which the query is executed (a '0'
val will eliminate view membership checks),
DestInfo - Information related to this dest is returned
in this structure for all the views requested.
Return Value:
Status of the operation
--*/
{
PADDRFAM_INFO AddrFamInfo;
PENTITY_INFO Entity;
PDEST_INFO Dest;
PLOOKUP_LINKAGE DestData;
DWORD Status;
//
// Validate the input parameters before the search
//
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
AddrFamInfo = Entity->OwningAddrFamily;
VALIDATE_DEST_HANDLE(DestHandle, &Dest);
DestData = &Dest->LookupLinkage;
Status = ERROR_NOT_FOUND;
ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
//
// Go up the prefix tree till you have a dest in views
//
do
{
//
// Get the next best prefix, and see if it is in views
//
NextMatchInTable(AddrFamInfo->RouteTable,
DestData,
&DestData);
if (DestData == NULL)
{
break;
}
Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
//
// Check if the destination is in any of the input views
//
if ((TargetViews == RTM_VIEW_MASK_ANY) ||
(Dest->BelongsToViews & TargetViews))
{
//
// Get the destination info from the dest
//
GetDestInfo(Entity, Dest, ProtocolId, TargetViews, DestInfo);
Status = NO_ERROR;
break;
}
}
while (TRUE);
RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
return Status;
}
DWORD
WINAPI
RtmGetExactMatchRoute (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_NET_ADDRESS DestAddress,
IN RTM_MATCH_FLAGS MatchingFlags,
IN OUT PRTM_ROUTE_INFO RouteInfo,
IN ULONG InterfaceIndex,
IN RTM_VIEW_SET TargetViews,
OUT PRTM_ROUTE_HANDLE RouteHandle
)
/*++
Routine Description:
Queries the route table for a route that matches certain
criteria - a network address, preference and/or nexthop.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestAddress - Network Address of the route we want,
MatchingFlags - Flags that tell how to match a route,
RouteInfo - Criteria that we need to match against,
IntefaceIndex - Interface on which route should be present
in case RTM_MATCH_INTERFACE is specified,
TargetViews - Views in which the query is executed (a '0'
val will eliminate view membership checks),
RouteHandle - Route handle (if an exact match exists),
RouteInfo - Information related to this route is retd.
Return Value:
Status of the operation
--*/
{
PADDRFAM_INFO AddrFamInfo;
PENTITY_INFO Entity;
PDEST_INFO Dest;
PROUTE_INFO Route;
PLOOKUP_LINKAGE DestData;
PLIST_ENTRY p;
DWORD Status;
//
// Validate the input parameters before the search
//
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
AddrFamInfo = Entity->OwningAddrFamily;
ACQUIRE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
//
// Search route table using the dest address
//
Status = SearchInTable(AddrFamInfo->RouteTable,
DestAddress->NumBits,
DestAddress->AddrBits,
NULL,
&DestData);
if (SUCCESS(Status))
{
Dest = CONTAINING_RECORD(DestData, DEST_INFO, LookupLinkage);
Status = ERROR_NOT_FOUND;
//
// Check if the destination matches any input views
//
if ((TargetViews == RTM_VIEW_MASK_ANY) ||
(Dest->BelongsToViews & TargetViews))
{
#if DBG
REFERENCE_DEST(Dest, TEMP_USE_REF);
#endif
//
// At this point, we have the dest. So take the
// dest lock, and release the route table lock.
//
ACQUIRE_DEST_READ_LOCK(Dest);
RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
//
// Search routes on dest for a matching route
//
for (p = Dest->RouteList.Flink; p != &Dest->RouteList; p= p->Flink)
{
Route = CONTAINING_RECORD(p, ROUTE_INFO, DestLE);
// Check if this route matches any input views
if ((TargetViews != RTM_VIEW_MASK_ANY) &&
(Route->RouteInfo.BelongsToViews & TargetViews) == 0)
{
continue;
}
// Check if this route matches input criteria
if (MatchingFlags &&
!MatchRouteWithCriteria(Route,
MatchingFlags,
RouteInfo,
InterfaceIndex))
{
continue;
}
//
// Found a matching route - copy the route info
//
REFERENCE_ROUTE(Route, HANDLE_REF);
*RouteHandle = MAKE_HANDLE_FROM_POINTER(Route);
if (ARGUMENT_PRESENT(RouteInfo))
{
GetRouteInfo(Dest, Route, RouteInfo);
}
Status = NO_ERROR;
break;
}
RELEASE_DEST_READ_LOCK(Dest);
#if DBG
DEREFERENCE_DEST(Dest, TEMP_USE_REF);
#endif
return Status;
}
}
RELEASE_ROUTE_TABLE_READ_LOCK(AddrFamInfo);
return Status;
}
DWORD
WINAPI
RtmIsBestRoute (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ROUTE_HANDLE RouteHandle,
OUT PRTM_VIEW_SET BestInViews
)
/*++
Routine Description:
Gives the set of views in which the route is the best route
to its destination.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
RouteHandle - Handle to the route whose info we want,
BestInViews - Views that route is the best one in is retd.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PDEST_INFO Dest;
PROUTE_INFO Route;
UINT i;
*BestInViews = 0;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_ROUTE_HANDLE(RouteHandle, &Route);
Dest = DEST_FROM_HANDLE(Route->RouteInfo.DestHandle);
//
// Set the bit in mask if the route is the best in the corr view
//
ACQUIRE_DEST_READ_LOCK(Dest);
for (i = 0; i < Entity->OwningAddrFamily->NumberOfViews; i++)
{
if (Dest->ViewInfo[i].BestRoute == Route)
{
*BestInViews |=
VIEW_MASK(Entity->OwningAddrFamily->ViewIdFromIndex[i]);
}
}
RELEASE_DEST_READ_LOCK(Dest);
return NO_ERROR;
}