/** * Clear all routes from routing table, and alerts Leaves upstream. */ void clearAllRoutes() { struct RouteTable *croute, *remainroute; // Loop through all routes... for(croute = routing_table; croute; croute = remainroute) { remainroute = croute->nextroute; // Log the cleanup in debugmode... my_log(LOG_DEBUG, 0, "Removing route entry for %s", inetFmt(croute->group, s1)); // Uninstall current route if(!internUpdateKernelRoute(croute, 0)) { my_log(LOG_WARNING, 0, "The removal from Kernel failed."); } // Send Leave message upstream. sendJoinLeaveUpstream(croute, 0); // Clear memory, and set pointer to next route... free(croute); } routing_table = NULL; // Send a notice that the routing table is empty... my_log(LOG_NOTICE, 0, "All routes removed. Routing table is empty."); }
/** * Remove a specified route. Returns 1 on success, * and 0 if route was not found. */ int removeRoute(struct RouteTable* croute) { struct Config *conf = getCommonConfig(); int result = 1; // If croute is null, no routes was found. if(croute==NULL) { return 0; } // Log the cleanup in debugmode... my_log(LOG_DEBUG, 0, "Removed route entry for %s from table.", inetFmt(croute->group, s1)); //BIT_ZERO(croute->vifBits); // Uninstall current route from kernel if(!internUpdateKernelRoute(croute, 0)) { my_log(LOG_WARNING, 0, "The removal from Kernel failed."); result = 0; } // Send Leave request upstream if group is joined if(croute->upstrState == ROUTESTATE_JOINED || (croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave)) { sendJoinLeaveUpstream(croute, 0); } // Update pointers... if(croute->prevroute == NULL) { // Topmost node... if(croute->nextroute != NULL) { croute->nextroute->prevroute = NULL; } routing_table = croute->nextroute; } else { croute->prevroute->nextroute = croute->nextroute; if(croute->nextroute != NULL) { croute->nextroute->prevroute = croute->prevroute; } } // Free the memory, and set the route to NULL... free(croute); croute = NULL; logRouteTable("Remove route"); return result; }
/** * Should be called when a leave message is recieved, to * mark a route for the last member probe state. */ void setRouteLastMemberMode(uint32_t group) { struct Config *conf = getCommonConfig(); struct RouteTable *croute; croute = findRoute(group); if(croute!=NULL) { // Check for fast leave mode... if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) { // Send a leave message right away.. sendJoinLeaveUpstream(croute, 0); } // Set the routingstate to Last member check... croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER; // Set the count value for expiring... (-1 since first aging) croute->ageValue = conf->lastMemberQueryCount; } }
/** * Should be called when a leave message is received, to * mark a route for the last member probe state. */ void setRouteLastMemberMode(uint32_t group) { struct Config *conf = getCommonConfig(); struct RouteTable *croute; croute = findRoute(group); if(croute!=NULL) { // Check for fast leave mode... if(croute->upstrState == ROUTESTATE_JOINED && conf->fastUpstreamLeave) { // Send a leave message right away only when the route has been active on only one interface if (numberOfInterfaces(croute) <= 1) { my_log(LOG_DEBUG, 0, "Leaving group %d now", group); sendJoinLeaveUpstream(croute, 0); } } // Set the routingstate to Last member check... croute->upstrState = ROUTESTATE_CHECK_LAST_MEMBER; // Set the count value for expiring... (-1 since first aging) croute->ageValue = conf->lastMemberQueryCount; } }
/** * 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; }
/** * Remove a specified route. Returns 1 on success, * and 0 if route was not found. */ int removeRoute(struct RouteTable* croute) { int result = 1; struct RouteTable* tmpRoute; struct Config *conf = getCommonConfig(); // If croute is null, no routes was found. if(croute==NULL) return 0; //printf("removeRoute called\n"); //BIT_ZERO(croute->vifBits); // Uninstall current route from kernel if(!internUpdateKernelRoute(croute, 0)) { //printf("The removal from Kernel failed.\n"); atlog(LOG_WARNING, 0, "The removal from Kernel failed."); result = 0; } // Send Leave request upstream if group is joined if(croute->upstrState == ROUTESTATE_JOINED || (croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER && !conf->fastUpstreamLeave)) { tmpRoute = findNextRoute( &(croute->group), NULL); if (tmpRoute && tmpRoute->nextroute) tmpRoute = findNextRoute( &(croute->group), tmpRoute->nextroute); // the group is not used by others if (tmpRoute == NULL) sendJoinLeaveUpstream(croute, 0); } // Update pointers... if(croute->prevroute == NULL) { // Topmost node... if(croute->nextroute != NULL) { croute->nextroute->prevroute = NULL; } routing_table = croute->nextroute; } else { croute->prevroute->nextroute = croute->nextroute; if(croute->nextroute != NULL) { croute->nextroute->prevroute = croute->prevroute; } } // Free the memory, and set the route to NULL... free(croute); croute = NULL; IF_DEBUG atlogRouteTable("Remove route"); 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; }