Condividi tramite


Aggiungere e aggiornare route con RtmAddRouteToDest

La funzione rtmAddRouteToDest viene usata per aggiungere nuove route e aggiornare le route esistenti per una destinazione. Le procedure seguenti illustrano entrambi i casi. Il codice di esempio seguente illustra come implementare la prima procedura.

Per aggiungere una route, il client deve seguire questa procedura

  1. Se il client ha già memorizzato nella cache l'handle hop successivo, andare al passaggio 4.

  2. Creare una struttura RTM_NEXTHOP_INFO e riempirla con le informazioni appropriate.

  3. Aggiungere l'hop successivo alla tabella di routing chiamando RtmAddNextHop. Il gestore delle tabelle di routing restituisce un handle all'hop successivo. Se l'hop successivo esiste già, la tabella di routing non aggiunge l'hop successivo; restituisce invece l'handle all'hop successivo.

  4. Creare una struttura RTM_ROUTE_INFO e riempirla con le informazioni appropriate, incluso l'handle hop successivo restituito dal gestore delle tabelle di routing.

  5. Aggiungere la rotta alla tabella di routing chiamando RtmAddRouteToDest. Il gestore della tabella di routing confronta la nuova rotta con le rotte già presenti nella tabella di routing. Due route sono uguali se tutte le condizioni seguenti sono vere:

    • La rotta viene aggiunta alla stessa destinazione.
    • La route viene aggiunta dallo stesso client specificato dal proprietario membro della struttura RTM_ROUTE_INFO.
    • La rotta è pubblicizzata dallo stesso vicino specificato dal membro Neighbor della struttura RTM_ROUTE_INFO.

    Se il percorso esiste, il gestore della tabella di routing restituisce l'handle al percorso esistente. In caso contrario, il gestore delle tabelle di routing aggiunge la route e restituisce l'handle alla nuova route.

    Il client può impostare il parametro Change_Flags su RTM_ROUTE_CHANGE_NEW per indicare alla gestione tabelle di routing di aggiungere una nuova route nella destinazione, anche se esiste un'altra route con gli stessi campi proprietario e adiacente.

    Il client può impostare il parametro Change_Flags su RTM_ROUTE_CHANGE_FIRST per indicare al gestore delle tabelle di routing di aggiornare il primo percorso nella destinazione di proprietà del client. Questo aggiornamento può essere eseguito se esiste una route di questo tipo, anche se il campo adiacente non corrisponde. Questo flag viene usato dai client che mantengono una singola route per destinazione.

Per aggiornare una route, il client deve seguire questa procedura

  1. Chiamare RtmGetRouteInfo con l'handle della route. L'handle è precedentemente memorizzato nella cache dal client o restituito dalla gestione tabelle di routing da una chiamata che restituisce un handle di route, ad esempio RtmGetRouteInfo.
  2. Apportare le modifiche alla struttura RTM_ROUTE_INFO restituita dal gestore della tabella di routing.
  3. Chiamare RtmAddRouteToDest con l'handle alla route e la struttura RTM_ROUTE_INFO modificata.

Il codice di esempio seguente illustra come aggiungere una route a una destinazione usando gestione tabelle di routing come 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);
}