557 lines
13 KiB
C
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;
|
|
}
|