tech-net archive

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

Re: removal of rtsol{d}



On 2014-09-08 11:24, Roy Marples wrote:
I also propose we change ip6mode `autohost` to start dhcpcd if not started in rc.conf. Also, the static DAD sleep timings should be removed as dhcpcd will ensure DAD has completed before forking if a carrier is present (if no carrier
then the static sleep is pointless anyway and dhcpcd will fork).

For the ip6mode == host | router users I suggest we add a new command to ifconfig, like say ifconfig -w, so that ifconfig will spin until all addresses have finished DAD which would result in a potentially faster and certainly
more accurate boot than just sleeping.

I'm not sure I can do the first part.
rc.d/network expects $rtsol_flags to be defined and doesn't actually do anything for rtsold As such, I think the best we can do is show a warning if rtsol is set and dhcpcd isn't.

Here's a patch which does this and adds the -w command to ifconfig(8).
The bootup of my laptop is noticeably faster now when processing the network script.

Comments welcome.

Roy
Index: sbin/ifconfig/ifconfig.8
===================================================================
RCS file: /cvsroot/src/sbin/ifconfig/ifconfig.8,v
retrieving revision 1.106
diff -u -p -r1.106 ifconfig.8
--- sbin/ifconfig/ifconfig.8    7 Jan 2014 20:25:24 -0000       1.106
+++ sbin/ifconfig/ifconfig.8    8 Sep 2014 13:27:00 -0000
@@ -60,6 +60,8 @@
 .Ar interface
 .Nm
 .Fl C
+.Nm
+.Fl w
 .Sh DESCRIPTION
 .Nm
 is used to assign an address
@@ -860,6 +862,12 @@ flag except that it zeros the interface 
 after printing them.
 .Pp
 The
+.Fl w
+flag may be used to wait for the
+.Cm tentative
+flag to be removed from all addresses.
+.Pp
+The
 .Fl N
 flag is just the opposite of the
 .Fl n
Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvsroot/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.231
diff -u -p -r1.231 ifconfig.c
--- sbin/ifconfig/ifconfig.c    19 Oct 2013 00:35:30 -0000      1.231
+++ sbin/ifconfig/ifconfig.c    8 Sep 2014 13:27:00 -0000
@@ -102,10 +102,12 @@ __RCSID("$NetBSD: ifconfig.c,v 1.231 201
 #include "env.h"
 #include "prog_ops.h"
 
-static bool bflag, dflag, hflag, sflag, uflag;
+#define WAIT_DAD       10000000 /* nanoseconds between each poll, 10ms */
+
+static bool bflag, dflag, hflag, sflag, uflag, wflag;
 bool lflag, Nflag, vflag, zflag;
 
-static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvz";
+static char gflags[10 + 26 * 2 + 1] = "AabCdhlNsuvwz";
 bool gflagset[10 + 26 * 2];
 
 static int carrier(prop_dictionary_t);
@@ -115,6 +117,7 @@ static int flag_index(int);
 static void init_afs(void);
 static int list_cloners(prop_dictionary_t, prop_dictionary_t);
 static int media_status_exec(prop_dictionary_t, prop_dictionary_t);
+static int wait_dad_exec(prop_dictionary_t, prop_dictionary_t);
 static int no_cmds_exec(prop_dictionary_t, prop_dictionary_t);
 static int notrailers(prop_dictionary_t, prop_dictionary_t);
 static void printall(const char *, prop_dictionary_t);
@@ -223,6 +226,9 @@ static struct kwinst familykw[24];
 struct pterm cloneterm = PTERM_INITIALIZER(&cloneterm, "list cloners",
     list_cloners, "none");
 
+struct pterm wait_dad = PTERM_INITIALIZER(&wait_dad, "wait DAD", wait_dad_exec,
+    "none");
+
 struct pterm no_cmds = PTERM_INITIALIZER(&no_cmds, "no commands", no_cmds_exec,
     "none");
 
@@ -506,6 +512,55 @@ no_cmds_exec(prop_dictionary_t env, prop
 }
 
 static int
+wait_dad_exec(prop_dictionary_t env, prop_dictionary_t oenv)
+{
+#ifdef INET6
+       bool waiting;
+       struct ifaddrs *ifaddrs, *ifa;
+       struct in6_ifreq ifr6;
+       int s;
+       const struct timespec ts = { .tv_sec = 0, .tv_nsec = WAIT_DAD };
+
+       if (getifaddrs(&ifaddrs) == -1)
+               err(EXIT_FAILURE, "getifaddrs");
+
+       do {
+               waiting = false;
+               for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
+                       if (ifa->ifa_addr == NULL)
+                               continue;
+                       switch (ifa->ifa_addr->sa_family) {
+                       case AF_INET6:
+                               memset(&ifr6, 0, sizeof(ifr6));
+                               strncpy(ifr6.ifr_name,
+                                   ifa->ifa_name, sizeof(ifr6.ifr_name));
+                               ifr6.ifr_addr =
+                                   *(struct sockaddr_in6 *)ifa->ifa_addr;
+                               if ((s = getsock(AF_INET6)) == -1)
+                                       err(EXIT_FAILURE,
+                                           "%s: getsock", __func__);
+                               if (ioctl(s, SIOCGIFAFLAG_IN6, &ifr6) == -1)
+                                       err(EXIT_FAILURE, "SIOCGIFAFLAG_IN6");
+                               if (ifr6.ifr_ifru.ifru_flags6 &
+                                   IN6_IFF_TENTATIVE)
+                               {
+                                       waiting = true;
+                                       break;
+                               }
+                       }
+                       if (waiting)
+                               break;
+               }
+               if (waiting)
+                       nanosleep(&ts, NULL);
+       } while (waiting);
+
+       freeifaddrs(ifaddrs);
+#endif
+       exit(EXIT_SUCCESS);
+}
+
+static int
 media_status_exec(prop_dictionary_t env, prop_dictionary_t oenv)
 {
        const char *ifname;
@@ -605,6 +660,10 @@ main(int argc, char **argv)
                        vflag = true;
                        break;
 
+               case 'w':
+                       wflag = true;
+                       break;
+
                case 'z':
                        zflag = true;
                        break;
@@ -636,6 +695,9 @@ main(int argc, char **argv)
                            start != &opt_family_only.pb_parser)
                                start = &iface_only.pif_parser;
                        break;
+               case 'w':
+                       start = &wait_dad.pt_parser;
+                       break;
                default:
                        break;
                }
@@ -644,19 +706,23 @@ main(int argc, char **argv)
        argv += optind;
 
        /*
-        * -l means "list all interfaces", and is mutally exclusive with
+        * -l means "list all interfaces", and is mutually exclusive with
         * all other flags/commands.
         *
         * -C means "list all names of cloners", and it mutually exclusive
         * with all other flags/commands.
         *
         * -a means "print status of all interfaces".
+        *
+        * -w means "spin until DAD completes for all addreseses", and is
+        * mutually exclusivewith all other flags/commands.
         */
-       if ((lflag || Cflag) && (aflag || get_flag('m') || vflag || zflag))
+       if ((lflag || Cflag || wflag) &&
+           (aflag || get_flag('m') || vflag || zflag))
                usage();
-       if ((lflag || Cflag) && get_flag('L'))
+       if ((lflag || Cflag || wflag) && get_flag('L'))
                usage();
-       if (lflag && Cflag)
+       if ((lflag && Cflag) || (lflag & wflag) || (Cflag && wflag))
                usage();
 
        nmatch = __arraycount(match);
Index: etc/rc.d/network
===================================================================
RCS file: /cvsroot/src/etc/rc.d/network,v
retrieving revision 1.66
diff -u -p -r1.66 network
--- etc/rc.d/network    29 Apr 2014 09:58:18 -0000      1.66
+++ etc/rc.d/network    8 Sep 2014 13:27:00 -0000
@@ -432,33 +432,19 @@ network_start_defaultroute6()
 network_start_ipv6_autoconf()
 {
        # IPv6 interface autoconfiguration.
-       #
-       # wait till DAD is completed. always invoke it in case
-       # if are configured manually by ifconfig
-       #
-       echo 'Waiting for DAD completion for' \
+
+       # wait till DAD is completed
+       echo 'Waiting for DAD to complete for' \
            'statically configured addresses...'
-       dadcount=$(/sbin/sysctl -n net.inet6.ip6.dad_count 2>/dev/null)
-       sleep $dadcount
-       sleep 1
+       /sbin/ifconfig -w
 
-       if checkyesno rtsol; then
+       # dhcpcd will ensure DAD completes before forking
+       if checkyesno rtsol && !checkyesno dhcpcd; then
                if [ "$ip6mode" = "autohost" ]; then
-                       echo 'Sending router solicitation...'
-                       /sbin/rtsol $rtsol_flags
-               else
                        echo
-                       warn \
-                   "ip6mode must be set to 'autohost' to use rtsol."
+                       warn "rtsol has been removed, " \
+                           "please configure dhcpcd in its place."
                fi
-
-               # wait till DAD is completed, for global addresses
-               # configured by router advert message.
-               #
-               echo 'Waiting for DAD completion for' \
-                   'addresses configured by router advert message...'
-               sleep $dadcount
-               sleep 1
        fi
 }
 


Home | Main Index | Thread Index | Old Index