Index: sys/netinet/libalias/alias_db.c =================================================================== --- sys/netinet/libalias/alias_db.c +++ sys/netinet/libalias/alias_db.c @@ -182,11 +182,6 @@ near relevant functions or structs) */ -/* Parameters used for cleanup of expired links */ -/* NOTE: ALIAS_CLEANUP_INTERVAL_SECS must be less then LINK_TABLE_OUT_SIZE */ -#define ALIAS_CLEANUP_INTERVAL_SECS 64 -#define ALIAS_CLEANUP_MAX_SPOKES (LINK_TABLE_OUT_SIZE/5) - /* Timeouts (in seconds) for different link types */ #define ICMP_EXPIRE_TIME 60 #define UDP_EXPIRE_TIME 60 @@ -330,6 +325,7 @@ /* Linked list of pointers for input and output lookup tables */ LIST_ENTRY (alias_link) list_out; LIST_ENTRY (alias_link) list_in; + TAILQ_ENTRY (alias_link) list_expire; /* Auxiliary data */ union { char *frag_ptr; @@ -511,7 +507,7 @@ Link creation and deletion: CleanupAliasData() - remove all link chains from lookup table - IncrementalCleanup() - look for stale links in a single chain + IncrementalCleanup() - look for a stale link DeleteLink() - remove link AddLink() - add link ReLink() - change link @@ -531,7 +527,7 @@ #endif static void CleanupAliasData(struct libalias *); static void IncrementalCleanup(struct libalias *); -static void DeleteLink(struct alias_link *); +static void DeleteLink(struct alias_link **); static struct alias_link * ReLink(struct alias_link *, @@ -808,41 +804,41 @@ static void CleanupAliasData(struct libalias *la) { - struct alias_link *lnk; - int i; + struct alias_link *lnk, *lnk_tmp; LIBALIAS_LOCK_ASSERT(la); - for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) { - lnk = LIST_FIRST(&la->linkTableOut[i]); - while (lnk != NULL) { - struct alias_link *link_next = LIST_NEXT(lnk, list_out); - DeleteLink(lnk); - lnk = link_next; - } - } - la->cleanupIndex = 0; + /* permanent entries may stay */ + TAILQ_FOREACH_SAFE(lnk, &la->checkExpire, list_expire, lnk_tmp) + DeleteLink(&lnk); } static void IncrementalCleanup(struct libalias *la) { - struct alias_link *lnk, *lnk_tmp; + struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); - LIST_FOREACH_SAFE(lnk, &la->linkTableOut[la->cleanupIndex++], - list_out, lnk_tmp) { - if (la->timeStamp - lnk->timestamp > lnk->expire_time) - DeleteLink(lnk); + + lnk = TAILQ_FIRST(&la->checkExpire); + if (lnk == NULL) + return; + + if (la->timeStamp - lnk->timestamp > lnk->expire_time) { + DeleteLink(&lnk); + if (lnk == NULL) + return; } - if (la->cleanupIndex == LINK_TABLE_OUT_SIZE) - la->cleanupIndex = 0; + /* move to end, swap may fail on a single entry list */ + TAILQ_REMOVE(&la->checkExpire, lnk, list_expire); + TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire); } static void -DeleteLink(struct alias_link *lnk) +DeleteLink(struct alias_link **plnk) { + struct alias_link *lnk = *plnk; struct libalias *la = lnk->la; LIBALIAS_LOCK_ASSERT(la); @@ -870,6 +866,10 @@ /* Adjust input table pointers */ LIST_REMOVE(lnk, list_in); + + /* remove from housekeeping */ + TAILQ_REMOVE(&la->checkExpire, lnk, list_expire); + #ifndef NO_USE_SOCKETS /* Close socket, if one has been allocated */ if (lnk->sockfd != -1) { @@ -909,6 +909,7 @@ /* Free memory */ free(lnk); + *plnk = NULL; /* Write statistics, if logging enabled */ if (la->packetAliasMode & PKT_ALIAS_LOG) { @@ -1040,6 +1041,9 @@ /* Set up pointers for input lookup table */ start_point = StartPointIn(alias_addr, lnk->alias_port, link_type); LIST_INSERT_HEAD(&la->linkTableIn[start_point], lnk, list_in); + + /* Include the element into the housekeeping list */ + TAILQ_INSERT_TAIL(&la->checkExpire, lnk, list_expire); } else { #ifdef LIBALIAS_DEBUG fprintf(stderr, "PacketAlias/AddLink(): "); @@ -1080,7 +1084,7 @@ PunchFWHole(new_lnk); } #endif - DeleteLink(old_lnk); + DeleteLink(&old_lnk); return (new_lnk); } @@ -2040,7 +2044,7 @@ { if (expire == 0) { lnk->flags &= ~LINK_PERMANENT; - DeleteLink(lnk); + DeleteLink(&lnk); } else if (expire == -1) { lnk->flags |= LINK_PERMANENT; } else if (expire > 0) { @@ -2103,7 +2107,6 @@ void HouseKeeping(struct libalias *la) { - int i, n; #ifndef _KERNEL struct timeval tv; #endif @@ -2120,25 +2123,7 @@ gettimeofday(&tv, NULL); la->timeStamp = tv.tv_sec; #endif - - /* Compute number of spokes (output table link chains) to cover */ - n = LINK_TABLE_OUT_SIZE * (la->timeStamp - la->lastCleanupTime); - n /= ALIAS_CLEANUP_INTERVAL_SECS; - - /* Handle different cases */ - if (n > 0) { - if (n > ALIAS_CLEANUP_MAX_SPOKES) - n = ALIAS_CLEANUP_MAX_SPOKES; - la->lastCleanupTime = la->timeStamp; - for (i = 0; i < n; i++) - IncrementalCleanup(la); - } else if (n < 0) { -#ifdef LIBALIAS_DEBUG - fprintf(stderr, "PacketAlias/HouseKeeping(): "); - fprintf(stderr, "something unexpected in time values\n"); -#endif - la->lastCleanupTime = la->timeStamp; - } + IncrementalCleanup(la); } /* Init the log file and enable logging */ @@ -2365,7 +2350,7 @@ { LIBALIAS_LOCK(la); la->deleteAllLinks = 1; - DeleteLink(lnk); + DeleteLink(&lnk); la->deleteAllLinks = 0; LIBALIAS_UNLOCK(la); } @@ -2435,17 +2420,16 @@ #ifdef _KERNEL la->timeStamp = time_uptime; - la->lastCleanupTime = time_uptime; #else gettimeofday(&tv, NULL); la->timeStamp = tv.tv_sec; - la->lastCleanupTime = tv.tv_sec; #endif for (i = 0; i < LINK_TABLE_OUT_SIZE; i++) LIST_INIT(&la->linkTableOut[i]); for (i = 0; i < LINK_TABLE_IN_SIZE; i++) LIST_INIT(&la->linkTableIn[i]); + TAILQ_INIT(&la->checkExpire); #ifdef _KERNEL AliasSctpInit(la); #endif Index: sys/netinet/libalias/alias_local.h =================================================================== --- sys/netinet/libalias/alias_local.h +++ sys/netinet/libalias/alias_local.h @@ -94,6 +94,8 @@ * output lookup tables. */ LIST_HEAD (, alias_link) linkTableOut[LINK_TABLE_OUT_SIZE]; LIST_HEAD (, alias_link) linkTableIn[LINK_TABLE_IN_SIZE]; + /* HouseKeeping */ + TAILQ_HEAD (, alias_link) checkExpire; /* Link statistics */ int icmpLinkCount; int udpLinkCount; @@ -107,8 +109,6 @@ int cleanupIndex; /* System time in seconds for current packet */ int timeStamp; - /* Last time IncrementalCleanup() was called */ - int lastCleanupTime; /* If equal to zero, DeleteLink() * will not remove permanent links */ int deleteAllLinks;