Exemple #1
0
/**
*   Adds a specified route to the routingtable.
*   If the route already exists, the existing route 
*   is updated...
*/
int insertRoute(uint32_t group, int ifx) {
    
    struct Config *conf = getCommonConfig();
    struct RouteTable*  croute;

    // Sanitycheck the group adress...
    if( ! IN_MULTICAST( ntohl(group) )) {
        my_log(LOG_WARNING, 0, "The group address %s is not a valid Multicast group. Table insert failed.",
            inetFmt(group, s1));
        return 0;
    }

    // Santiycheck the VIF index...
    //if(ifx < 0 || ifx >= MAX_MC_VIFS) {
    if(ifx >= MAX_MC_VIFS) {
        my_log(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",ifx,MAX_MC_VIFS);
        return 0;
    }

    // Try to find an existing route for this group...
    croute = findRoute(group);
    if(croute==NULL) {
        struct RouteTable*  newroute;

        my_log(LOG_DEBUG, 0, "No existing route for %s. Create new.",
                     inetFmt(group, s1));


        // Create and initialize the new route table entry..
        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
        // Insert the route desc and clear all pointers...
        newroute->group      = group;
        memset(newroute->originAddrs, 0, MAX_ORIGINS * sizeof(newroute->originAddrs[0]));
        newroute->nextroute  = NULL;
        newroute->prevroute  = NULL;

        // The group is not joined initially.
        newroute->upstrState = ROUTESTATE_NOTJOINED;

        // The route is not active yet, so the age is unimportant.
        newroute->ageValue    = conf->robustnessValue;
        newroute->ageActivity = 0;
        
        BIT_ZERO(newroute->ageVifBits);     // Initially we assume no listeners.

        // Set the listener flag...
        BIT_ZERO(newroute->vifBits);    // Initially no listeners...
        if(ifx >= 0) {
            BIT_SET(newroute->vifBits, ifx);
        }

        // Check if there is a table already....
        if(routing_table == NULL) {
            // No location set, so insert in on the table top.
            routing_table = newroute;
            my_log(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");
        } else {

            my_log(LOG_DEBUG, 0, "Found existing routes. Find insert location.");

            // Check if the route could be inserted at the beginning...
            if(routing_table->group > group) {
                my_log(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));

                // Insert at beginning...
                newroute->nextroute = routing_table;
                newroute->prevroute = NULL;
                routing_table = newroute;

                // If the route has a next node, the previous pointer must be updated.
                if(newroute->nextroute != NULL) {
                    newroute->nextroute->prevroute = newroute;
                }

            } else {

                // Find the location which is closest to the route.
                for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) {
                    // Find insert position.
                    if(croute->nextroute->group > group) {
                        break;
                    }
                }

                my_log(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));
                
                // Insert after current...
                newroute->nextroute = croute->nextroute;
                newroute->prevroute = croute;
                if(croute->nextroute != NULL) {
                    croute->nextroute->prevroute = newroute; 
                }
                croute->nextroute = newroute;
            }
        }

        // Set the new route as the current...
        croute = newroute;

        // Log the cleanup in debugmode...
        my_log(LOG_INFO, 0, "Inserted route table entry for %s on VIF #%d",
            inetFmt(croute->group, s1),ifx);

    } else if(ifx >= 0) {

        // The route exists already, so just update it.
        BIT_SET(croute->vifBits, ifx);
        
        // Register the VIF activity for the aging routine
        BIT_SET(croute->ageVifBits, ifx);

        // Log the cleanup in debugmode...
        my_log(LOG_INFO, 0, "Updated route entry for %s on VIF #%d",
            inetFmt(croute->group, s1), ifx);
        
        // Update route in kernel...
        if(!internUpdateKernelRoute(croute, 1)) {
            my_log(LOG_WARNING, 0, "The insertion into Kernel failed.");
            return 0;
        }
    }

    // Send join message upstream, if the route has no joined flag...
    if(croute->upstrState != ROUTESTATE_JOINED) {
        // Send Join request upstream
        sendJoinLeaveUpstream(croute, 1);
    }

    logRouteTable("Insert Route");

    return 1;
}
Exemple #2
0
/**
*   Ages a specific route
*/
int internAgeRoute(struct RouteTable*  croute) {
    struct Config *conf = getCommonConfig();
    int result = 0;

    // Drop age by 1.
    croute->ageValue--;

    // Check if there has been any activity...
    if( croute->ageVifBits > 0 && croute->ageActivity == 0 ) {
        // There was some activity, check if all registered vifs responded.
        if(croute->vifBits == croute->ageVifBits) {
            // Everything is in perfect order, so we just update the route age.
            croute->ageValue = conf->robustnessValue;
            //croute->ageActivity = 0;
        } else {
            // One or more VIF has not gotten any response.
            croute->ageActivity++;

            // Update the actual bits for the route...
            croute->vifBits = croute->ageVifBits;
        }
    } 
    // Check if there have been activity in aging process...
    else if( croute->ageActivity > 0 ) {

        // If the bits are different in this round, we must
        if(croute->vifBits != croute->ageVifBits) {
            // Or the bits together to insure we don't lose any listeners.
            croute->vifBits |= croute->ageVifBits;

            // Register changes in this round as well..
            croute->ageActivity++;
        }
    }

    // If the aging counter has reached zero, its time for updating...
    if(croute->ageValue == 0) {
        // Check for activity in the aging process,
        if(croute->ageActivity>0) {
            
            my_log(LOG_DEBUG, 0, "Updating route after aging : %s",
                         inetFmt(croute->group,s1));
            
            // Just update the routing settings in kernel...
            internUpdateKernelRoute(croute, 1);
    
            // We append the activity counter to the age, and continue...
            croute->ageValue = croute->ageActivity;
            croute->ageActivity = 0;
        } else {

            my_log(LOG_DEBUG, 0, "Removing group %s. Died of old age.",
                         inetFmt(croute->group,s1));

            // No activity was registered within the timelimit, so remove the route.
            removeRoute(croute);
        }
        // Tell that the route was updated...
        result = 1;
    }

    // The aging vif bits must be reset for each round...
    BIT_ZERO(croute->ageVifBits);

    return result;
}
Exemple #3
0
/**
*   Adds a specified route to the routingtable.
*   If the route already exists, the existing route 
*   is updated...
*/
int insertRoute(struct in6_addr *group, struct in6_addr *src, struct sockaddr_in6 *from) 
{
    struct Config *conf = getCommonConfig();
    struct RouteTable *croute, *tmpRoute;
    //int result = 1;
/*
    int i;
    printf("insertRoute called\n");

    for (i = 0; i < 16; i ++)
        printf("%02x ", ((char*)group)[i] & 255 );
    printf("\n");

    for (i = 0; i < 16; i ++)
        printf("%02x ", ((char*)src)[i] & 255 );
    printf("\n");
*/
    

    // Sanitycheck the group adress...
    if ( !IN6_IS_ADDR_MULTICAST(group) ) 
    {
        atlog( LOG_DEBUG, 0, "Not multicast group");    
        return 0;
    }

    // Santiycheck the VIF index...
    if(from->sin6_scope_id >= MAX_MC_VIFS) 
    {
        atlog(LOG_WARNING, 0, "The VIF Ix %d is out of range (0-%d). Table insert failed.",
              from->sin6_scope_id,MAX_MC_VIFS);
        return 0;
    }

    // Try to find an existing route for this group...
    croute = findRoute(group, src);
    
    if(croute==NULL)
    {
        struct RouteTable*  newroute;

        /*
        IF_DEBUG atlog(LOG_DEBUG, 0, "No existing route for %s. Create new.",
                     inetFmt(group, s1));
        */

        // Create and initialize the new route table entry..
        newroute = (struct RouteTable*)malloc(sizeof(struct RouteTable));
        // Insert the route desc and clear all pointers...
        newroute->group = *group;
        newroute->originAddr = *src;
        
        newroute->nextroute  = NULL;
        newroute->prevroute  = NULL;

        // The group is not joined initially.
        newroute->upstrState = ROUTESTATE_NOTJOINED;

        // The route is not active yet, so the age is unimportant.
        newroute->ageValue    = conf->robustnessValue;
        newroute->ageActivity = 0;
        
        BIT_ZERO(newroute->ageVifBits);     // Initially we assume no listeners.

        // Set the listener flag...
        BIT_ZERO(newroute->vifBits);    // Initially no listeners...
        if(from->sin6_scope_id >= 0) 
        {
            BIT_SET(newroute->vifBits, from->sin6_scope_id);
        }

        // Check if there is a table already....
        if(routing_table == NULL) 
        {
            // No location set, so insert in on the table top.
            routing_table = newroute;
            IF_DEBUG atlog(LOG_DEBUG, 0, "No routes in table. Insert at beginning.");
        }
        else 
        {
            IF_DEBUG atlog(LOG_DEBUG, 0, "Found existing routes. Find insert location.");

            // Check if the route could be inserted at the beginning...
            if( memcmp(&routing_table->group, group, sizeof(struct in6_addr)) > 0 ) 
            {
                //IF_DEBUG atlog(LOG_DEBUG, 0, "Inserting at beginning, before route %s",inetFmt(routing_table->group,s1));

                // Insert at beginning...
                newroute->nextroute = routing_table;
                newroute->prevroute = NULL;
                routing_table = newroute;

                // If the route has a next node, the previous pointer must be updated.
                if(newroute->nextroute != NULL) 
                {
                    newroute->nextroute->prevroute = newroute;
                }

            } 
            else 
            {
                // Find the location which is closest to the route.
                for( croute = routing_table; croute->nextroute != NULL; croute = croute->nextroute ) 
                {
                    // Find insert position.
                    if( memcmp( &(croute->nextroute->group), group, sizeof(struct in6_addr) ) > 0 ) 
                        break;
                }

                //IF_DEBUG atlog(LOG_DEBUG, 0, "Inserting after route %s",inetFmt(croute->group,s1));
                
                // Insert after current...
                newroute->nextroute = croute->nextroute;
                newroute->prevroute = croute;
                if(croute->nextroute != NULL) 
                {
                    croute->nextroute->prevroute = newroute; 
                }
                croute->nextroute = newroute;
            }
        }

        // Set the new route as the current...
        croute = newroute;

     
        if( !IN6_ARE_ADDR_EQUAL( &croute->originAddr, &allzero_addr) ) 
        {
            // Update route in kernel...
            if( !internUpdateKernelRoute(croute, 1) ) 
            {
                atlog(LOG_WARNING, 0, "The insertion into Kernel failed.");
                return 0;
            }
        }    
    } 
    else if(from->sin6_scope_id >= 0) 
    {
        if( !IN6_ARE_ADDR_EQUAL( &croute->originAddr, &allzero_addr) ) 
        {
            // The route exists already, so just update it.
            BIT_SET(croute->vifBits, from->sin6_scope_id);
            
            // Register the VIF activity for the aging routine
            BIT_SET(croute->ageVifBits, from->sin6_scope_id);
        }
        else
        {
            tmpRoute = findNextRoute(group, NULL);
            while (tmpRoute != NULL)
            {
                // The route exists already, so just update it.
                BIT_SET(tmpRoute->vifBits, from->sin6_scope_id);
                
                // Register the VIF activity for the aging routine
                BIT_SET(tmpRoute->ageVifBits, from->sin6_scope_id);
                if (tmpRoute->nextroute)
                    tmpRoute = findNextRoute(group, tmpRoute->nextroute);  
                else
                    break;
            }
        }
    }

    // Send join message upstream, if the route has no joined flag...
    if(croute->upstrState != ROUTESTATE_JOINED)
    {
        // Send Join request upstream
        sendJoinLeaveUpstream(croute, 1);
    }

    IF_DEBUG atlogRouteTable("Insert Route");
    return 1;
}