|
|
/*++
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; }
|