📄 rttable.c
字号:
} // 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 logRouteTable("Insert Route"); return 1;}/*** Activates a passive group. If the group is already* activated, it's reinstalled in the kernel. If* the route is activated, no originAddr is needed.*/int activateRoute(uint32 group, uint32 originAddr) { struct RouteTable* croute; int result = 0; // Find the requested route. croute = findRoute(group); if(croute == NULL) { IF_DEBUG log(LOG_DEBUG, 0, "No table entry for %s [From: %s]. Inserting route.", inetFmt(group, s1),inetFmt(originAddr, s2)); // Insert route, but no interfaces have yet requested it downstream. insertRoute(group, -1); // Retrieve the route from table... croute = findRoute(group); } if(croute != NULL) { // If the origin address is set, update the route data. if(originAddr > 0) { if(croute->originAddr > 0 && croute->originAddr!=originAddr) { log(LOG_WARNING, 0, "The origin for route %s changed from %s to %s", inetFmt(croute->group, s1), inetFmt(croute->originAddr, s2), inetFmt(originAddr, s3)); } croute->originAddr = originAddr; } // Only update kernel table if there are listeners ! if(croute->vifBits > 0) { result = internUpdateKernelRoute(croute, 1); } } IF_DEBUG logRouteTable("Activate Route"); return result;}/*** This function loops through all routes, and updates the age * of any active routes.*/void ageActiveRoutes() { struct RouteTable *croute, *nroute; IF_DEBUG log(LOG_DEBUG, 0, "Aging routes in table."); // Scan all routes... for( croute = routing_table; croute != NULL; croute = nroute ) { // Keep the next route (since current route may be removed)... nroute = croute->nextroute; // Run the aging round algorithm. if(croute->upstrState != ROUTESTATE_CHECK_LAST_MEMBER) { // Only age routes if Last member probe is not active... internAgeRoute(croute); } } IF_DEBUG logRouteTable("Age active routes");}/*** Should be called when a leave message is recieved, to* mark a route for the last member probe state.*/void setRouteLastMemberMode(uint32 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; }}/*** Ages groups in the last member check state. If the* route is not found, or not in this state, 0 is returned.*/int lastMemberGroupAge(uint32 group) { struct Config *conf = getCommonConfig(); struct RouteTable *croute; croute = findRoute(group); if(croute!=NULL) { if(croute->upstrState == ROUTESTATE_CHECK_LAST_MEMBER) { return !internAgeRoute(croute); } else { return 0; } } return 0;}/*** 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... IF_DEBUG 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)) { 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; IF_DEBUG logRouteTable("Remove route"); return result;}/*** 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) { IF_DEBUG 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 { IF_DEBUG 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;}/*** Updates the Kernel routing table. If activate is 1, the route* is (re-)activated. If activate is false, the route is removed.*/int internUpdateKernelRoute(struct RouteTable *route, int activate) { struct MRouteDesc mrDesc; struct IfDesc *Dp; unsigned Ix; if(route->originAddr>0) { // Build route descriptor from table entry... // Set the source address and group address... mrDesc.McAdr.s_addr = route->group; mrDesc.OriginAdr.s_addr = route->originAddr; // clear output interfaces memset( mrDesc.TtlVc, 0, sizeof( mrDesc.TtlVc ) ); IF_DEBUG log(LOG_DEBUG, 0, "Vif bits : 0x%08x", route->vifBits); // Set the TTL's for the route descriptor... for ( Ix = 0; Dp = getIfByIx( Ix ); Ix++ ) { if(Dp->state == IF_STATE_UPSTREAM) { //IF_DEBUG log(LOG_DEBUG, 0, "Identified VIF #%d as upstream.", Dp->index); mrDesc.InVif = Dp->index; } else if(BIT_TST(route->vifBits, Dp->index)) { IF_DEBUG log(LOG_DEBUG, 0, "Setting TTL for Vif %d to %d", Dp->index, Dp->threshold); mrDesc.TtlVc[ Dp->index ] = Dp->threshold; } } // Do the actual Kernel route update... if(activate) { // Add route in kernel... addMRoute( &mrDesc ); } else { // Delete the route from Kernel... delMRoute( &mrDesc ); } } else { log(LOG_NOTICE, 0, "Route is not active. No kernel updates done."); } return 1;}/*** Debug function that writes the routing table entries* to the log.*/void logRouteTable(char *header) { IF_DEBUG { struct RouteTable* croute = routing_table; unsigned rcount = 0; log(LOG_DEBUG, 0, "\nCurrent routing table (%s);\n-----------------------------------------------------\n", header); if(croute==NULL) { log(LOG_DEBUG, 0, "No routes in table..."); } else { do { /* log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, Prev: 0x%08x, T: 0x%08x, Next: 0x%08x", rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2), croute->ageValue,(croute->originAddr>0?"A":"I"), croute->prevroute, croute, croute->nextroute); */ log(LOG_DEBUG, 0, "#%d: Src: %s, Dst: %s, Age:%d, St: %s, OutVifs: 0x%08x", rcount, inetFmt(croute->originAddr, s1), inetFmt(croute->group, s2), croute->ageValue,(croute->originAddr>0?"A":"I"), croute->vifBits); croute = croute->nextroute; rcount++; } while ( croute != NULL ); } log(LOG_DEBUG, 0, "\n-----------------------------------------------------\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -