Partager via


Ajouter et mettre à jour des itinéraires à l’aide de RtmAddRouteToDest

La fonction RtmAddRouteToDest permet d’ajouter de nouveaux itinéraires et de mettre à jour les itinéraires existants pour une destination. Les procédures suivantes expliquent les deux cas. L’exemple de code qui suit montre comment implémenter la première procédure.

Pour ajouter un itinéraire, le client doit effectuer les étapes suivantes

  1. Si le client a déjà mis en cache le handle de tronçon suivant, passez à l’étape 4.

  2. Créez une structure RTM_NEXTHOP_INFO et remplissez-la avec les informations appropriées.

  3. Ajoutez le tronçon suivant à la table de routage en appelant RtmAddNextHop. Le gestionnaire de table de routage retourne un handle au tronçon suivant. Si le tronçon suivant existe déjà, la table de routage n’ajoute pas le tronçon suivant ; au lieu de cela, il retourne le handle au tronçon suivant.

  4. Créez une structure RTM_ROUTE_INFO et remplissez-la avec les informations appropriées, y compris le handle de tronçon suivant retourné par le gestionnaire de table de routage.

  5. Ajoutez l’itinéraire à la table de routage en appelant RtmAddRouteToDest. Le gestionnaire de table de routage compare la nouvelle route aux itinéraires qui se trouvent déjà dans la table de routage. Deux itinéraires sont égaux si toutes les conditions suivantes sont remplies :

    • L’itinéraire est ajouté à la même destination.
    • L’itinéraire est ajouté par le même client que celui spécifié par le membre Propriétaire de la structure RTM_ROUTE_INFO .
    • L’itinéraire est publié par le même voisin que celui spécifié par le membre Neighbor de la structure RTM_ROUTE_INFO .

    Si l’itinéraire existe, le gestionnaire de table de routage retourne le handle à l’itinéraire existant. Sinon, le gestionnaire de table de routage ajoute l’itinéraire et retourne le handle à la nouvelle route.

    Le client peut définir le paramètre Change_Flags sur RTM_ROUTE_CHANGE_NEW pour indiquer au gestionnaire de table de routage d’ajouter un nouvel itinéraire sur la destination, même s’il existe une autre route avec les mêmes champs propriétaire et voisin.

    Le client peut définir le paramètre Change_Flags sur RTM_ROUTE_CHANGE_FIRST pour indiquer au gestionnaire de table de routage de mettre à jour la première route sur la destination détenue par le client. Cette mise à jour peut être effectuée si un tel itinéraire existe, même si le champ voisin ne correspond pas. Cet indicateur est utilisé par les clients qui gèrent un itinéraire unique par destination.

Pour mettre à jour un itinéraire, le client doit effectuer les étapes suivantes

  1. Appelez RtmGetRouteInfo avec le handle de l’itinéraire. Le handle est précédemment mis en cache par le client, ou retourné par le gestionnaire de table de routage à partir d’un appel qui retourne un handle d’itinéraire tel que RtmGetRouteInfo.
  2. Apportez les modifications à la structure RTM_ROUTE_INFO retournée par le gestionnaire de table de routage.
  3. Appelez RtmAddRouteToDest avec le handle de l’itinéraire et la structure RTM_ROUTE_INFO modifiée.

L’exemple de code suivant montre comment ajouter un itinéraire à une destination à l’aide du gestionnaire de table de routage comme intermédiaire.

// 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);
}