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