使用 RtmUpdateAndUnlockRoute 就地更新路由

以下过程概述了用于就地更新路由的步骤。 下面的示例代码演示如何实现过程。

若要就地更新路由,客户端应执行以下步骤

  1. 通过调用 RtmLockRoute 锁定路由。 目前,此函数实际上锁定路由的目标。 路由表管理器返回指向路由的指针。

  2. 使用指向在步骤 1 中获取的路由表管理器 RTM_ROUTE_INFO 结构的指针对路由进行必要的更改。 就地更新时,只能修改 RTM_ROUTE_INFO 结构的某些成员。 这些成员包括: 邻居PrefInfoEntitySpecificInfoBelongsToViewsNextHopsList

    注意

    如果客户端向 邻居NextHopsList 成员添加信息,则客户端必须调用 RtmReferenceHandles 以显式递增路由表管理器保留在下一跃点对象上的引用计数。 同样,如果客户端从 NextHopsList 成员中删除信息,则客户端必须调用 RtmReleaseNextHops 来减少引用计数。

     

  3. 调用 RtmUpdateAndUnlockRoute 以通知路由表管理器已发生更改。 路由表管理器提交更改,更新目标以反映新信息,然后解锁路由。

以下示例代码演示如何使用指向路由表中实际路由信息的指针直接更新路由。

Status = RtmLockRoute(RtmRegHandle,
                      RouteHandle,
                      TRUE,
                      TRUE,
                      &RoutePointer);

if (Status == NO_ERROR)
{
        // Update route parameters in place (i.e., directly on 
// the routing table manager's copy)
    
    // Update the metric and views of the route
    RoutePointer->PrefInfo.Metric = 16;

    // Change the views so that the route belongs to only the multicast view
    RoutePointer->BelongsToViews = RTM_VIEW_MASK_MCAST;

    // Set the entity-specific information to X
    RoutePointer->EntitySpecificInfo = X;

    // Note that the following manipulation of
    // next-hop references is not needed when
    // using RtmAddRouteToDest, as it is done
    // by the routing table manager automatically
    
    // Change next hop from NextHop1 to NextHop2
    NextHop1 = RoutePointer->NextHopsList.NextHop[0];

    // Explicitly dereference the old next hop
    RtmReleaseNextHops(RtmRegHandle, 1, &NextHop1);

    RoutePointer->NextHopsList.NextHop[0] = NextHop2;

    // Explicitly reference next hop being added
    RtmReferenceHandles(RtmRegHandle, 1, &NextHop2);

    // Call the routing table manager to indicate that route information
    // has changed, and that its position might
    // have to be rearranged and the corresponding destination
    // needs to be updated to reflect this change.
    
    Status = RtmUpdateAndUnlockRoute(RtmRegHandle,
                                     RouteHandle,
                                     INFINITE, // Keep forever
                                     NULL,
                                     0,
                                     NULL,
                                     &ChangeFlags);
    ASSERT(Status == NO_ERROR);
}