Module Name: src Committed By: roy Date: Fri Dec 14 09:48:31 UTC 2012
Modified Files: src/usr.sbin/rtadvd: config.c rtadvd.c Log Message: Intsead of forcing out each RA at shutdown and sleeping we now use the existing timer model and wait for each RA to expire itself after sending the required number of transmissions. This allows for a faster and saner shutdown. To generate a diff of this commit: cvs rdiff -u -r1.30 -r1.31 src/usr.sbin/rtadvd/config.c cvs rdiff -u -r1.40 -r1.41 src/usr.sbin/rtadvd/rtadvd.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.sbin/rtadvd/config.c diff -u src/usr.sbin/rtadvd/config.c:1.30 src/usr.sbin/rtadvd/config.c:1.31 --- src/usr.sbin/rtadvd/config.c:1.30 Thu Dec 13 15:36:36 2012 +++ src/usr.sbin/rtadvd/config.c Fri Dec 14 09:48:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: config.c,v 1.30 2012/12/13 15:36:36 roy Exp $ */ +/* $NetBSD: config.c,v 1.31 2012/12/14 09:48:31 roy Exp $ */ /* $KAME: config.c,v 1.93 2005/10/17 14:40:02 suz Exp $ */ /* @@ -738,8 +738,6 @@ getconfig(const char *intface, int exith } - /* If we are advertising an existing RA configuration, - * expire it */ TAILQ_FOREACH(rai, &ralist, next) { if (rai->ifindex == tmp->ifindex) { TAILQ_REMOVE(&ralist, rai, next); @@ -759,6 +757,7 @@ getconfig(const char *intface, int exith dnssl->lifetime = 0; rai->leaving_for = tmp; tmp->leaving = rai; + rai->initcounter = MAX_INITIAL_RTR_ADVERTISEMENTS; rai->mininterval = MIN_DELAY_BETWEEN_RAS; rai->maxinterval = MIN_DELAY_BETWEEN_RAS; rai->leaving_adv = MAX_FINAL_RTR_ADVERTISEMENTS; Index: src/usr.sbin/rtadvd/rtadvd.c diff -u src/usr.sbin/rtadvd/rtadvd.c:1.40 src/usr.sbin/rtadvd/rtadvd.c:1.41 --- src/usr.sbin/rtadvd/rtadvd.c:1.40 Thu Dec 13 15:40:05 2012 +++ src/usr.sbin/rtadvd/rtadvd.c Fri Dec 14 09:48:31 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: rtadvd.c,v 1.40 2012/12/13 15:40:05 roy Exp $ */ +/* $NetBSD: rtadvd.c,v 1.41 2012/12/14 09:48:31 roy Exp $ */ /* $KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $ */ /* @@ -153,7 +153,7 @@ struct sockaddr_in6 sin6_sitelocal_allro }; static void set_die(int); -static void die(void); // XXX __dead; +static void die(void); static void set_reconf(int); static void sock_open(void); static void rtsock_open(void); @@ -260,6 +260,7 @@ main(int argc, char *argv[]) } else set[1].fd = -1; + signal(SIGINT, set_die); signal(SIGTERM, set_die); signal(SIGHUP, set_reconf); signal(SIGUSR1, rtadvd_set_dump_file); @@ -342,44 +343,53 @@ set_die(__unused int sig) static void die(void) { - struct rainfo *rai; + static int waiting; + struct rainfo *rai, *ran; struct rdnss *rdnss; struct dnssl *dnssl; - int i; - const int retrans = MAX_FINAL_RTR_ADVERTISEMENTS; - if (dflag > 1) { - syslog(LOG_DEBUG, "<%s> cease to be an advertising router\n", - __func__); - } - - TAILQ_FOREACH(rai, &ralist, next) { + if (waiting) { + if (TAILQ_FIRST(&ralist)) { + syslog(LOG_INFO, + "<%s> waiting for expiration of all RA timers", + __func__); + return; + } + syslog(LOG_NOTICE, "<%s> gracefully terminated", __func__); + free(rcvcmsgbuf); + free(sndcmsgbuf); + exit(0); + /* NOT REACHED */ + } + + waiting = 1; + syslog(LOG_NOTICE, "<%s> final RA transmission started", __func__); + + TAILQ_FOREACH_SAFE(rai, &ralist, next, ran) { + if (rai->leaving) { + TAILQ_REMOVE(&ralist, rai, next); + TAILQ_INSERT_HEAD(&ralist, rai->leaving, next); + rai->leaving->leaving = rai->leaving; + rai->leaving->leaving_for = rai->leaving; + free_rainfo(rai); + continue; + } rai->lifetime = 0; TAILQ_FOREACH(rdnss, &rai->rdnss, next) rdnss->lifetime = 0; TAILQ_FOREACH(dnssl, &rai->dnssl, next) dnssl->lifetime = 0; make_packet(rai); + rai->leaving = rai; + rai->leaving_for = rai; + rai->initcounter = MAX_INITIAL_RTR_ADVERTISEMENTS; + rai->mininterval = MIN_DELAY_BETWEEN_RAS; + rai->maxinterval = MIN_DELAY_BETWEEN_RAS; + rai->leaving_adv = MAX_FINAL_RTR_ADVERTISEMENTS; + ra_output(rai); + ra_timer_update((void *)rai, &rai->timer->tm); + rtadvd_set_timer(&rai->timer->tm, rai->timer); } - for (i = 0; i < retrans; i++) { - TAILQ_FOREACH(rai, &ralist, next) - ra_output(rai); - sleep(MIN_DELAY_BETWEEN_RAS); - } - -#ifdef __VALGRIND__ - while ((rai = TAILQ_FIRST(&ralist))) { - TAILQ_REMOVE(&ralist, rai, next); - if (rai->leaving) - free_rainfo(rai->leaving); - free_rainfo(rai); - } - free(rcvcmsgbuf); - free(sndcmsgbuf); -#endif - - exit(0); - /*NOTREACHED*/ } static void @@ -401,6 +411,11 @@ rtmsg_input(void) memset(&buffer, 0, sizeof(buffer)); n = read(rtsock, &buffer, sizeof(buffer)); + + /* We read the buffer first to clear the FD */ + if (do_die) + return; + msg = buffer.data; if (dflag > 1) { syslog(LOG_DEBUG, "<%s> received a routing message " @@ -668,6 +683,10 @@ rtadvd_input(void) if ((i = recvmsg(sock, &rcvmhdr, 0)) < 0) return; + /* We read the buffer first to clear the FD */ + if (do_die) + return; + /* extract optional information via Advanced API */ for (cm = (struct cmsghdr *)CMSG_FIRSTHDR(&rcvmhdr); cm; @@ -1678,6 +1697,12 @@ ra_output(struct rainfo *rai) if (rai->leaving_adv > 0) { if (--(rai->leaving_adv) == 0) { + /* leaving for ourself means we're shutting down */ + if (rai->leaving_for == rai) { + TAILQ_REMOVE(&ralist, rai, next); + free_rainfo(rai); + return NULL; + } syslog(LOG_DEBUG, "<%s> expired RA," " new config active for interface (%s)",