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

756 lines
16 KiB
C

/*++
Copyright (c) 1997 - 98, Microsoft Corporation
Module Name:
rtminfo.c
Abstract:
Contains routines for getting information
on various objects pointed to by handles.
Author:
Chaitanya Kodeboyina (chaitk) 22-Aug-1998
Revision History:
--*/
#include "pchrtm.h"
#pragma hdrstop
DWORD
WINAPI
RtmGetEntityInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ENTITY_HANDLE EntityHandle,
OUT PRTM_ENTITY_INFO EntityInfo
)
/*++
Routine Description:
Retrieves information pertaining to a registered entity.
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
EntityHandle - RTM handle for entity whose info we want,
EntityInfo - Block in which the entity info is returned.
Return Value:
Status of the operation
--*/
{
PADDRFAM_INFO AddrFamilyInfo;
PENTITY_INFO Entity;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_ENTITY_HANDLE(EntityHandle, &Entity);
//
// Copy the entity information to output buffer
//
AddrFamilyInfo = Entity->OwningAddrFamily;
EntityInfo->RtmInstanceId = AddrFamilyInfo->Instance->RtmInstanceId;
EntityInfo->AddressFamily = AddrFamilyInfo->AddressFamily;
EntityInfo->EntityId = Entity->EntityId;
return NO_ERROR;
}
DWORD
WINAPI
RtmGetDestInfo (
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:
Retrieves information for a destination in the route table
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestHandle - RTM handle for dest whose info we want,
ProtocolId - Protocol whose best route info is retd,
TargetViews - Views in which best route info is retd,
DestInfo - Block in which the dest info is returned.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PDEST_INFO Dest;
VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
// VALIDATE_DEST_HANDLE(DestHandle, &Dest);
Dest = DEST_FROM_HANDLE(DestHandle);
if (!Dest)
{
return ERROR_INVALID_HANDLE;
}
ACQUIRE_DEST_READ_LOCK(Dest);
GetDestInfo(Entity,
Dest,
ProtocolId,
TargetViews,
DestInfo);
RELEASE_DEST_READ_LOCK(Dest);
return NO_ERROR;
}
VOID
GetDestInfo (
IN PENTITY_INFO Entity,
IN PDEST_INFO Dest,
IN ULONG ProtocolId,
IN RTM_VIEW_SET TargetViews,
OUT PRTM_DEST_INFO DestInfo
)
/*++
Routine Description:
Retrieves information for a destination in the route table
Arguments:
Entity - RTM registration info for calling entity,
Dest - Pointer to the dest whose info we want,
ProtocolId - Protocol whose best route info is retd,
TargetViews - Views in which best route info is retd,
DestInfo - Block in which the dest info is returned.
Return Value:
None
--*/
{
PENTITY_INFO Owner;
PROUTE_INFO Route;
RTM_VIEW_SET ViewsSeen;
RTM_VIEW_SET ViewSet;
RTM_VIEW_SET BelongsToViews;
PLIST_ENTRY p;
UINT i, j, k;
// Limit caller's interest to set of views supported
TargetViews &= Entity->OwningAddrFamily->ViewsSupported;
//
// Copy dest info to output and ref handles given out
//
DestInfo->DestHandle = MAKE_HANDLE_FROM_POINTER(Dest);
REFERENCE_DEST(Dest, HANDLE_REF);
CopyMemory(&DestInfo->DestAddress,
&Dest->DestAddress,
sizeof(RTM_NET_ADDRESS));
DestInfo->LastChanged = Dest->LastChanged;
DestInfo->BelongsToViews = Dest->BelongsToViews;
//
// Copy the holddown route out in all requested views
//
ViewSet = TargetViews;
for (i = j = 0; ViewSet && (i < RTM_VIEW_MASK_SIZE); i++)
{
if (ViewSet & 0x01)
{
k = Entity->OwningAddrFamily->ViewIndexFromId[i];
Route = Dest->ViewInfo[k].HoldRoute;
//
// Init view info and fill the holddown route
//
ZeroMemory(&DestInfo->ViewInfo[j], sizeof(DestInfo->ViewInfo[0]));
DestInfo->ViewInfo[j].ViewId = i;
if (Route)
{
DestInfo->ViewInfo[j].HoldRoute =
MAKE_HANDLE_FROM_POINTER(Route);
REFERENCE_ROUTE(Route, HANDLE_REF);
}
j++;
}
ViewSet >>= 1;
}
// Keep track of total number of view info slots filled in
DestInfo->NumberOfViews = j;
//
// Fill up information in all the views he is interested in
//
if (TargetViews & Dest->BelongsToViews)
{
// Resolve the protocol id if it is RTM_THIS_PROTOCOL
if (ProtocolId == RTM_THIS_PROTOCOL)
{
ProtocolId = Entity->EntityId.EntityProtocolId;
}
ViewsSeen = 0;
//
// Copy best route in each view & ref handles given out
//
for (p = Dest->RouteList.Flink; p != &Dest->RouteList; p = p->Flink)
{
Route = CONTAINING_RECORD(p, ROUTE_INFO, DestLE);
//
// Make sure that this agrees with our protocol id
//
Owner = ENTITY_FROM_HANDLE(Route->RouteInfo.RouteOwner);
if (ProtocolId != RTM_BEST_PROTOCOL)
{
if (Owner->EntityId.EntityProtocolId != ProtocolId)
{
continue;
}
}
//
// Does this route belong to any interested views
//
if ((TargetViews & Route->RouteInfo.BelongsToViews) == 0)
{
continue;
}
//
// Update dest info in each view that route belongs to
//
BelongsToViews = Route->RouteInfo.BelongsToViews;
ViewSet = TargetViews;
for (i = j = 0; ViewSet && (i < RTM_VIEW_MASK_SIZE); i++)
{
if (ViewSet & 0x01)
{
if (BelongsToViews & 0x01)
{
//
// Increment number of routes in this view
//
DestInfo->ViewInfo[j].NumRoutes++;
//
// If you not already seen this view (in
// other words got the best route in it)
// update the DestInfo for this view now
//
if (!(ViewsSeen & VIEW_MASK(i)))
{
DestInfo->ViewInfo[j].Route =
MAKE_HANDLE_FROM_POINTER(Route);
REFERENCE_ROUTE(Route, HANDLE_REF);
DestInfo->ViewInfo[j].Owner =
MAKE_HANDLE_FROM_POINTER(Owner);
REFERENCE_ENTITY(Owner, HANDLE_REF);
DestInfo->ViewInfo[j].DestFlags =
Route->RouteInfo.Flags;
}
}
j++;
}
ViewSet >>= 1;
BelongsToViews >>= 1;
}
ViewsSeen |= Route->RouteInfo.BelongsToViews;
}
}
return;
}
DWORD
WINAPI
RtmGetRouteInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_ROUTE_HANDLE RouteHandle,
OUT PRTM_ROUTE_INFO RouteInfo OPTIONAL,
OUT PRTM_NET_ADDRESS DestAddress OPTIONAL
)
/*++
Routine Description:
Retrieves information for a route in the route table
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
RouteHandle - RTM handle for route whose info we want,
RouteInfo - Block in which the route info is returned.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PROUTE_INFO Route;
PDEST_INFO Dest;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
#if 1
Route = ROUTE_FROM_HANDLE(RouteHandle);
if (!Route)
{
return ERROR_INVALID_HANDLE;
}
#else
VALIDATE_ROUTE_HANDLE(RouteHandle, &Route);
#endif
Dest = DEST_FROM_HANDLE(Route->RouteInfo.DestHandle);
// Get a consitent picture of the route
ACQUIRE_DEST_READ_LOCK(Dest);
if (ARGUMENT_PRESENT(RouteInfo))
{
GetRouteInfo(Dest, Route, RouteInfo);
}
RELEASE_DEST_READ_LOCK(Dest);
// No lock reqd - dest addr is constant
if (ARGUMENT_PRESENT(DestAddress))
{
CopyMemory(DestAddress, &Dest->DestAddress, sizeof(RTM_NET_ADDRESS));
}
return NO_ERROR;
}
VOID
WINAPI
GetRouteInfo (
IN PDEST_INFO Dest,
IN PROUTE_INFO Route,
OUT PRTM_ROUTE_INFO RouteInfo
)
/*++
Routine Description:
Retrieves information for a route in the route table
Arguments:
Dest - Pointer to the destination of the route,
Route - Pointer to the route whose info we want,
RouteInfo - Block in which the route info is returned.
Return Value:
None
--*/
{
PENTITY_INFO Entity;
PNEXTHOP_INFO Neighbour;
PNEXTHOP_INFO NextHop;
UINT NumBytes;
UINT i;
//
// Copy the route information to output buffer
//
NumBytes = sizeof(RTM_ROUTE_INFO) +
sizeof(RTM_NEXTHOP_HANDLE) *
(Route->RouteInfo.NextHopsList.NumNextHops - 1);
CopyMemory(RouteInfo, &Route->RouteInfo, NumBytes);
//
// Reference handles that are given out in info
//
Entity = ENTITY_FROM_HANDLE(RouteInfo->RouteOwner);
REFERENCE_ENTITY(Entity, HANDLE_REF);
if (RouteInfo->Neighbour)
{
Neighbour = NEXTHOP_FROM_HANDLE(RouteInfo->Neighbour);
REFERENCE_NEXTHOP(Neighbour, HANDLE_REF);
}
for (i = 0; i < RouteInfo->NextHopsList.NumNextHops; i++)
{
NextHop = NEXTHOP_FROM_HANDLE(RouteInfo->NextHopsList.NextHops[i]);
REFERENCE_NEXTHOP(NextHop, HANDLE_REF);
}
REFERENCE_DEST(Dest, HANDLE_REF);
return;
}
DWORD
WINAPI
RtmGetNextHopInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN RTM_NEXTHOP_HANDLE NextHopHandle,
OUT PRTM_NEXTHOP_INFO NextHopInfo
)
/*++
Routine Description:
Retrieves information for a next-hop in the route table
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
NextHopHandle - RTM handle for next-hop whose info we want,
NextHopInfo - Block in which the next-hop info is returned.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PNEXTHOP_INFO NextHop;
PDEST_INFO Dest;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
VALIDATE_NEXTHOP_HANDLE(NextHopHandle, &NextHop);
Entity = ENTITY_FROM_HANDLE(NextHop->NextHopInfo.NextHopOwner);
ACQUIRE_NHOP_TABLE_READ_LOCK(Entity);
//
// Copy the next-hop information to output buffer
//
CopyMemory(NextHopInfo, &NextHop->NextHopInfo, sizeof(RTM_NEXTHOP_INFO));
//
// Reference handles that are given out in info
//
if (NextHop->NextHopInfo.RemoteNextHop)
{
Dest = DEST_FROM_HANDLE(NextHop->NextHopInfo.RemoteNextHop);
REFERENCE_DEST(Dest, HANDLE_REF);
}
REFERENCE_ENTITY(Entity, HANDLE_REF);
RELEASE_NHOP_TABLE_READ_LOCK(Entity);
return NO_ERROR;
}
DWORD
WINAPI
RtmReleaseEntityInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_ENTITY_INFO EntityInfo
)
/*++
Routine Description:
Releases all handles present in the input info structure
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
EntityInfo - All handles in this info are de-referenced.
Return Value:
Status of the operation
--*/
{
UNREFERENCED_PARAMETER(RtmRegHandle);
UNREFERENCED_PARAMETER(EntityInfo);
return NO_ERROR;
}
DWORD
WINAPI
RtmReleaseDestInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_DEST_INFO DestInfo
)
/*++
Routine Description:
Releases all handles present in the input info structure
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
DestInfo - All handles in this info are de-referenced.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PENTITY_INFO Owner;
PDEST_INFO Dest;
PROUTE_INFO Route;
UINT i;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
for (i = 0; i < DestInfo->NumberOfViews; i++)
{
//
// If a best route, dereference it and its owner
//
if (DestInfo->ViewInfo[i].Route)
{
Route = ROUTE_FROM_HANDLE(DestInfo->ViewInfo[i].Route);
DEREFERENCE_ROUTE(Route, HANDLE_REF);
Owner = ENTITY_FROM_HANDLE(DestInfo->ViewInfo[i].Owner);
DEREFERENCE_ENTITY(Owner, HANDLE_REF);
}
//
// If we have a holddown route, dereference it
//
if (DestInfo->ViewInfo[i].HoldRoute)
{
Route = ROUTE_FROM_HANDLE(DestInfo->ViewInfo[i].HoldRoute);
DEREFERENCE_ROUTE(Route, HANDLE_REF);
}
}
Dest = DEST_FROM_HANDLE(DestInfo->DestHandle);
DEREFERENCE_DEST(Dest, HANDLE_REF);
return NO_ERROR;
}
DWORD
WINAPI
RtmReleaseRouteInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_ROUTE_INFO RouteInfo
)
/*++
Routine Description:
Releases all handles present in the input info structure
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
RouteInfo - All handles in this info are de-referenced.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PDEST_INFO Dest;
PNEXTHOP_INFO Neighbour;
PNEXTHOP_INFO NextHop;
UINT i;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
for (i = 0; i < RouteInfo->NextHopsList.NumNextHops; i++)
{
NextHop = NEXTHOP_FROM_HANDLE(RouteInfo->NextHopsList.NextHops[i]);
DEREFERENCE_NEXTHOP(NextHop, HANDLE_REF);
}
if (RouteInfo->Neighbour)
{
Neighbour = NEXTHOP_FROM_HANDLE(RouteInfo->Neighbour);
DEREFERENCE_NEXTHOP(Neighbour, HANDLE_REF);
}
Entity = ENTITY_FROM_HANDLE(RouteInfo->RouteOwner);
DEREFERENCE_ENTITY(Entity, HANDLE_REF);
Dest = DEST_FROM_HANDLE(RouteInfo->DestHandle);
DEREFERENCE_DEST(Dest, HANDLE_REF);
return NO_ERROR;
}
DWORD
WINAPI
RtmReleaseNextHopInfo (
IN RTM_ENTITY_HANDLE RtmRegHandle,
IN PRTM_NEXTHOP_INFO NextHopInfo
)
/*++
Routine Description:
Releases all handles present in the input info structure
Arguments:
RtmRegHandle - RTM registration handle for calling entity,
NextHopInfo - All handles in this info are de-referenced.
Return Value:
Status of the operation
--*/
{
PENTITY_INFO Entity;
PDEST_INFO Dest;
DBG_VALIDATE_ENTITY_HANDLE(RtmRegHandle, &Entity);
if (NextHopInfo->RemoteNextHop)
{
Dest = DEST_FROM_HANDLE(NextHopInfo->RemoteNextHop);
if (Dest)
{
DEREFERENCE_DEST(Dest, HANDLE_REF);
}
}
Entity = ENTITY_FROM_HANDLE(NextHopInfo->NextHopOwner);
DEREFERENCE_ENTITY(Entity, HANDLE_REF);
return NO_ERROR;
}