Agregar y actualizar rutas mediante RtmAddRouteToDest
La función RtmAddRouteToDest se usa para agregar nuevas rutas y actualizar las rutas existentes para un destino. Los procedimientos siguientes explican ambos casos. El código de ejemplo siguiente muestra cómo implementar el primer procedimiento.
Para agregar una ruta, el cliente debe realizar los pasos siguientes:
Si el cliente ya ha almacenado en caché el identificador del próximo salto, vaya al paso 4.
Cree una estructura de RTM_NEXTHOP_INFO y llene con la información adecuada.
Agregue el próximo salto a la tabla de enrutamiento llamando a RtmAddNextHop. El administrador de tablas de enrutamiento devuelve un identificador al próximo salto. Si el próximo salto ya existe, la tabla de enrutamiento no agrega el próximo salto; en su lugar, devuelve el identificador al próximo salto.
Cree una estructura de RTM_ROUTE_INFO y llene con la información adecuada, incluido el identificador de próximo salto devuelto por el administrador de tablas de enrutamiento.
Agregue la ruta a la tabla de enrutamiento llamando a RtmAddRouteToDest. El administrador de tablas de enrutamiento compara la nueva ruta con las rutas que ya están en la tabla de enrutamiento. Dos rutas son iguales si se cumplen todas las condiciones siguientes:
- La ruta se agrega al mismo destino.
- El mismo cliente que especifica el miembro Propietario de la estructura RTM_ROUTE_INFO agrega la ruta.
- El mismo vecino que especifica el miembro Vecino de la estructura RTM_ROUTE_INFO anuncia la ruta.
Si la ruta existe, el administrador de tablas de enrutamiento devuelve el identificador a la ruta existente. De lo contrario, el administrador de tablas de enrutamiento agrega la ruta y devuelve el identificador a la nueva ruta.
El cliente puede establecer el parámetro Change_Flags en RTM_ROUTE_CHANGE_NEW para indicar al administrador de tablas de enrutamiento que agregue una nueva ruta en el destino, incluso si existe otra ruta con los mismos campos propietario y vecino.
El cliente puede establecer el parámetro Change_Flags en RTM_ROUTE_CHANGE_FIRST para indicar al administrador de tablas de enrutamiento que actualice la primera ruta en el destino propiedad del cliente. Esta actualización se puede realizar si existe una ruta de este tipo, incluso si el campo vecino no coincide. Los clientes que mantienen una única ruta por destino usan esta marca.
Para actualizar una ruta, el cliente debe realizar los pasos siguientes:
- Llame a RtmGetRouteInfo con el identificador de la ruta. El identificador es uno almacenado previamente en caché por el cliente o devuelto por el administrador de tablas de enrutamiento desde una llamada que devuelve un identificador de ruta como RtmGetRouteInfo.
- Realice los cambios en la estructura de RTM_ROUTE_INFO que devuelve el administrador de tablas de enrutamiento.
- Llame a RtmAddRouteToDest con el identificador de la ruta y la estructura de RTM_ROUTE_INFO modificada.
En el código de ejemplo siguiente se muestra cómo agregar una ruta a un destino mediante el administrador de tablas de enrutamiento como intermediario.
// Add a route to a destination given by (addr, masklen)
// using a next hop reachable with an interface
RTM_NEXTHOP_INFO NextHopInfo;
// First, create and add a next hop to the caller's
// next-hop tree (if it does not already exist)
ZeroMemory(&NextHopInfo, sizeof(RTM_NEXTHOP_INFO);
RTM_IPV4_MAKE_NET_ADDRESS(&NextHopInfo.NextHopAddress,
nexthop, // Address of the next hop
32);
NextHopInfo.InterfaceIndex = interface;
NextHopHandle = NULL;
Status = RtmAddNextHop(RtmRegHandle,
&NextHopInfo,
&NextHopHandle,
&ChangeFlags);
if (Status == NO_ERROR)
{
// Created a new next hop or found an old one
// Fill in the route information for the route
ZeroMemory(&RouteInfo, sizeof(RTM_ROUTE_INFO);
// Fill in the destination network's address and mask values
RTM_IPV4_MAKE_NET_ADDRESS(&NetAddress, addr, masklen);
// Assume 'neighbour learnt from' is the first next hop
RouteInfo.Neighbour = NextHopHandle;
// Set metric for route; Preference set internally
RouteInfo.PrefInfo.Metric = metric;
// Adding a route to both the unicast and multicast views
RouteInfo.BelongsToViews = RTM_VIEW_MASK_UCAST|RTM_VIEW_MASK_MCAST;
RouteInfo.NextHopsList.NumNextHops = 1;
RouteInfo.NextHopsList.NextHops[0] = NextHopHandle;
// If you want to add a new route, regardless of
// whether a similar route already exists, use the following
// ChangeFlags = RTM_ROUTE_CHANGE_NEW;
ChangeFlags = 0;
Status = RtmAddRouteToDest(RtmRegHandle,
&RouteHandle, // Can be NULL if you do not need handle
&NetAddress,
&RouteInfo,
1000, // Time out route after 1000 ms
RouteListHandle1, // Also add the route to this list
0,
NULL,
&ChangeFlags);
if (Status == NO_ERROR)
{
if (ChangeFlags & RTM_ROUTE_CHANGE_NEW)
{
; // A new route has been created
}
else
{
; // An existing route is updated
}
if (ChangeFlags & RTM_ROUTE_CHANGE_BEST)
{
; // Best route information has changed
}
// Release the route handle if you do not need it
RtmReleaseRoutes(RtmRegHandle, 1, &RouteHandle);
}
// Also release the next hop since it is no longer needed
RtmReleaseNextHops(RtmRegHandle, 1, &NextHopHandle);
}