Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/rtadvd Intsead of forcing out each RA at shutdown a...



details:   https://anonhg.NetBSD.org/src/rev/fe2c5d242a1f
branches:  trunk
changeset: 783301:fe2c5d242a1f
user:      roy <roy%NetBSD.org@localhost>
date:      Fri Dec 14 09:48:31 2012 +0000

description:
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.

diffstat:

 usr.sbin/rtadvd/config.c |   5 +-
 usr.sbin/rtadvd/rtadvd.c |  81 +++++++++++++++++++++++++++++++----------------
 2 files changed, 55 insertions(+), 31 deletions(-)

diffs (168 lines):

diff -r eb6771a4cd6c -r fe2c5d242a1f usr.sbin/rtadvd/config.c
--- a/usr.sbin/rtadvd/config.c  Fri Dec 14 08:57:10 2012 +0000
+++ b/usr.sbin/rtadvd/config.c  Fri Dec 14 09:48:31 2012 +0000
@@ -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 @@
 
        }
 
-       /* 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 @@
                                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;
diff -r eb6771a4cd6c -r fe2c5d242a1f usr.sbin/rtadvd/rtadvd.c
--- a/usr.sbin/rtadvd/rtadvd.c  Fri Dec 14 08:57:10 2012 +0000
+++ b/usr.sbin/rtadvd/rtadvd.c  Fri Dec 14 09:48:31 2012 +0000
@@ -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 @@
 };
 
 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 @@
        } 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 @@
 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__);
+       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 */
        }
 
-       TAILQ_FOREACH(rai, &ralist, next) {
+       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);
-       }
-       for (i = 0; i < retrans; i++) {
-               TAILQ_FOREACH(rai, &ralist, next)
-                       ra_output(rai);
-               sleep(MIN_DELAY_BETWEEN_RAS);
+               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);
        }
-
-#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 @@
 
        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 @@
        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 @@
 
        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)",



Home | Main Index | Thread Index | Old Index