]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Implemented --dad-wait-time option for dhclient.
authorMarcin Siodelski <marcin@isc.org>
Mon, 5 Jun 2017 15:51:31 +0000 (17:51 +0200)
committerMarcin Siodelski <marcin@isc.org>
Mon, 5 Jun 2017 15:51:31 +0000 (17:51 +0200)
    Merged #36169

RELNOTES
client/dhclient.8
client/dhclient.c
client/scripts/freebsd
client/scripts/linux
client/scripts/macos
client/scripts/netbsd
client/scripts/openbsd

index 00fa829270a417004c358be9f97f05fbdfca1f27..058eab151a4305d034586a8f4894d6ace21b9e0e 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -129,6 +129,17 @@ by Eric Young (eay@cryptsoft.com).
   default location of the server configuration file.
   [ISC-Bugs #44765]
 
+- Added --dad-wait-time parameter to dhclient. It specifies the maximum time,
+  in seconds, that the client process should wait for the duplicate address
+  detection to complete before initiating DHCP requests. This value is
+  propagated to the dhclient script and the script is responsible for waiting
+  the specified amount of time or until DAD has completed. If the script does
+  not support it, specifying this parameter has no effect. The default value
+  is 0 which specifies that the script should not wait for DAD. With this
+  change the following scripts have been modified to support the new parameter:
+  freebsd, linux, macos, netbsd, openbsd.
+  [ISC-Bugs #36169]
+
                        Changes since 4.1-ESV-R14b1
 - None
 
index 4a254f253759b1f01226a996dc109d78ef3efebd..9d797a5f2ba06f14d4183a8ef010c20610e180f3 100644 (file)
@@ -1,6 +1,6 @@
 .\"    $Id: dhclient.8,v 1.30.8.4.6.1 2011/04/15 22:26:20 sar Exp $
 .\"
-.\" Copyright (c) 2004-2016 by Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (c) 2004-2017 by Internet Systems Consortium, Inc. ("ISC")
 .\" Copyright (c) 1996-2003 by Internet Software Consortium
 .\"
 .\" Permission to use, copy, modify, and distribute this software for any
@@ -116,6 +116,10 @@ dhclient - Dynamic Host Configuration Protocol Client
 .B -w
 ]
 [
+.B --dad-wait-time
+.I seconds
+]
+[
 .B -v
 ]
 [
@@ -361,6 +365,15 @@ all of the items.
 Restore normal address query for IPv6. This implies \fB-6\fR.
 It is used to restore normal operation after using \fB-T\fR or \fB-P\fR.
 Multiple addresses can be requested with multiple \fB\-N\fR flags.
+.TP
+.BI \--dad-wait-time \ seconds
+Specify maximum time (in seconds) that the client should wait for the
+duplicate address detection (DAD) to complete on an interface. This
+value is propagated to the dhclient script in a dad_wait_time environment
+variable. If any of the IPv6 addresses on the interface are tentative
+(DAD is in progress), the script will wait for the specified number of
+seconds for DAD to complete. If the script ignores this variable the
+parameter has no effect.
 .PP
 .I Modifying default file locations:
 The following options can be used to modify the locations a client uses
index ca519a4b0e837c9c42bebefe6fae64bdb4c8cc9b..3c140bae7e860e8625583b89e6d2527582f76881 100644 (file)
@@ -66,7 +66,7 @@ struct data_string default_duid;
 #define ASSERT_STATE(state_is, state_shouldbe) {}
 
 static const char copyright[] = 
-"Copyright 2004-2016 Internet Systems Consortium.";
+"Copyright 2004-2017 Internet Systems Consortium.";
 static const char arr [] = "All rights reserved.";
 static const char message [] = "Internet Systems Consortium DHCP Client";
 static const char url [] = 
@@ -87,6 +87,7 @@ int wanted_ia_pd = 0;
 int require_all_ias = 0;       /* If the user requires all of the IAs to
                                   be available before accepting a lease
                                   0 = no, 1 = requries */
+int dad_wait_time = 0;
 char *mockup_relay = NULL;
 
 char *progname = NULL;
@@ -139,6 +140,7 @@ usage(const char *sfmt, const char *sarg)
        log_fatal("Usage: %s "
 #ifdef DHCPv6
                  "[-4|-6] [-SNTPR1dvrx] [-nw] [-p <port>]\n"
+                 "                [--dad-wait-time seconds]\n"
 #else /* DHCPv6 */
                  "[-1dvrx] [-nw] [-p <port>]\n"
 #endif /* DHCPv6 */
@@ -353,6 +355,15 @@ main(int argc, char **argv) {
                        local_family_set = 1;
                        local_family = AF_INET6;
                        require_all_ias = 1;
+               } else if (!strcmp(argv[i], "--dad-wait-time")) {
+                       if (++i == argc) {
+                               usage(use_noarg, argv[i-1]);
+                       }
+                       dad_wait_time = (int)strtol(argv[i], &s, 10);
+                       if (errno || (*s != '\0') || (dad_wait_time < 0)) {
+                               usage("Invalid value for --dad-wait-time: %s", argv[i]);
+                       }
+
 #endif /* DHCPv6 */
                } else if (!strcmp(argv[i], "-v")) {
                        quiet = 0;
@@ -3172,6 +3183,8 @@ void script_init (client, reason, medium)
 
                client_envadd (client, "", "reason", "%s", reason);
                client_envadd (client, "", "pid", "%ld", (long int)getpid ());
+               client_envadd (client, "", "dad_wait_time", "%ld",
+                                          (long int)dad_wait_time);
        }
 }
 
index b6d2a57ac9be2c53f9d19c806a5c4a26d0d6ac3f..14ab91b48e408b98f9a553a737ac87b33632b042 100755 (executable)
@@ -335,6 +335,42 @@ if [ ${reason} = PREINIT6 ] ; then
 
   # XXX: Remove any stale addresses from aborted clients.
 
+  # We need to give the kernel some time to active interface
+  interface_up_wait_time=5
+  for i in $(seq 0 ${interface_up_wait_time})
+  do
+      ifconfig ${interface} | grep inactive >/dev/null 2>&1
+      if [ $? -ne 0 ]; then
+          break;
+      fi
+      sleep 1
+  done
+
+  # Wait for duplicate address detection for this interface if the
+  # --dad-wait-time parameter has been specified and is greater than
+  # zero.
+  if [ ${dad_wait_time} -gt 0 ]; then
+      # Check if any IPv6 address on this interface is marked as
+      # tentative.
+      ifconfig ${interface} | grep inet6 | grep tentative \
+          >/dev/null 2>&1
+      if [ $? -eq 0 ]; then
+          # Wait for duplicate address detection to complete or for
+          # the timeout specified as --dad-wait-time.
+          for i in $(seq 0 $dad_wait_time)
+          do
+              # We're going to poll for the tentative flag every second.
+              sleep 1
+              ifconfig ${interface} | grep inet6 | grep tentative \
+                  >/dev/null 2>&1
+              if [ $? -ne 0 ]; then
+                  break;
+              fi
+          done
+      fi
+  fi
+
+
   exit_with_hooks 0
 fi
 
index e6792c67d54692fe2113e0d10a548a21d7c8f24c..7d77fd39e33d52122e898cf78af0012ceee0e9b6 100755 (executable)
@@ -248,9 +248,44 @@ if [ x$reason = xPREINIT6 ] ; then
   # Ensure interface is up.
   ${ip} link set ${interface} up
 
+  # We need to give the kernel some time to active interface
+  interface_up_wait_time=5
+  for i in $(seq 0 ${interface_up_wait_time})
+  do
+      ifconfig ${interface} | grep RUNNING >/dev/null 2>&1
+      if [ $? -eq 0 ]; then
+          break;
+      fi
+      sleep 1
+  done
+
   # Remove any stale addresses from aborted clients.
   ${ip} -f inet6 addr flush dev ${interface} scope global permanent
 
+  # Wait for duplicate address detection for this interface if the
+  # --dad-wait-time parameter has been specified and is greater than
+  # zero.
+  if [ ${dad_wait_time} -gt 0 ]; then
+      # Check if any IPv6 address on this interface is marked as
+      # tentative.
+      ${ip} addr show ${interface} | grep inet6 | grep tentative \
+          &> /dev/null
+      if [ $? -eq 0 ]; then
+          # Wait for duplicate address detection to complete or for
+          # the timeout specified as --dad-wait-time.
+          for i in $(seq 0 $dad_wait_time)
+          do
+              # We're going to poll for the tentative flag every second.
+              sleep 1
+              ${ip} addr show ${interface} | grep inet6 | grep tentative \
+                  &> /dev/null
+              if [ $? -ne 0 ]; then
+                  break;
+              fi
+          done
+      fi
+  fi
+
   exit_with_hooks 0
 fi
 
index 0593e25a5232b1568ed338892b8244acdf76028b..a0bdb5b8ee7d16a8b7313ef9c4522f49891280c7 100755 (executable)
@@ -144,8 +144,43 @@ if [ x$reason = xPREINIT6 ]; then
   # Ensure interface is up.
   ifconfig ${interface} up
 
+  # We need to give the kernel some time to active interface
+  interface_up_wait_time=5
+  for i in $(seq 0 ${interface_up_wait_time})
+  do
+      ifconfig ${interface} | grep inactive &> /dev/null
+      if [ $? -ne 0 ]; then
+          break;
+      fi
+      sleep 1
+  done
+
   # XXX: Remove any stale addresses from aborted clients.
 
+  # Wait for duplicate address detection for this interface if the
+  # --dad-wait-time parameter has been specified and is greater than
+  # zero.
+  if [ ${dad_wait_time} -gt 0 ]; then
+      # Check if any IPv6 address on this interface is marked as
+      # tentative.
+      ifconfig ${interface} | grep inet6 | grep tentative \
+          &> /dev/null
+      if [ $? -eq 0 ]; then
+          # Wait for duplicate address detection to complete or for
+          # the timeout specified as --dad-wait-time.
+          for i in $(seq 0 $dad_wait_time)
+          do
+              # We're going to poll for the tentative flag every second.
+              sleep 1
+              ifconfig ${interface} | grep inet6 | grep tentative \
+                  &> /dev/null
+              if [ $? -ne 0 ]; then
+                  break;
+              fi
+          done
+      fi
+  fi
+
   exit_with_hooks 0
 fi
 
index 8a5007e74063e9863fec0b039a6923d4b0206d4e..6a41edf421bcd4bbf03a8ff8094a090f061fe02f 100755 (executable)
@@ -265,6 +265,41 @@ if [ ${reason} = PREINIT6 ] ; then
 
   # XXX: Remove any stale addresses from aborted clients.
 
+  # We need to give the kernel some time to active interface
+  interface_up_wait_time=5
+  for i in $(seq 0 ${interface_up_wait_time})
+  do
+      ifconfig ${interface} | grep inactive >/dev/null 2>&1
+      if [ $? -ne 0 ]; then
+          break;
+      fi
+      sleep 1
+  done
+
+  # Wait for duplicate address detection for this interface if the
+  # --dad-wait-time parameter has been specified and is greater than
+  # zero.
+  if [ ${dad_wait_time} -gt 0 ]; then
+      # Check if any IPv6 address on this interface is marked as
+      # tentative.
+      ifconfig ${interface} | grep inet6 | grep tentative \
+          >/dev/null 2>&1
+      if [ $? -eq 0 ]; then
+          # Wait for duplicate address detection to complete or for
+          # the timeout specified as --dad-wait-time.
+          for i in $(seq 0 $dad_wait_time)
+          do
+              # We're going to poll for the tentative flag every second.
+              sleep 1
+              ifconfig ${interface} | grep inet6 | grep tentative \
+                  >/dev/null 2>&1
+              if [ $? -ne 0 ]; then
+                  break;
+              fi
+          done
+      fi
+  fi
+
   exit_with_hooks 0
 fi
 
index f20d0ff6174f7f3c30ff6d14e8585f8a3c6cb513..151b50aa7f82d4e4aab08480cd9eff28cc40e069 100644 (file)
@@ -259,6 +259,41 @@ if [ ${reason} = PREINIT6 ] ; then
 
   # XXX: Remove any stale addresses from aborted clients.
 
+  # We need to give the kernel some time to active interface
+  interface_up_wait_time=5
+  for i in $(seq 0 ${interface_up_wait_time})
+  do
+      ifconfig ${interface} | grep inactive >/dev/null 2>&1
+      if [ $? -ne 0 ]; then
+          break;
+      fi
+      sleep 1
+  done
+
+  # Wait for duplicate address detection for this interface if the
+  # --dad-wait-time parameter has been specified and is greater than
+  # zero.
+  if [ ${dad_wait_time} -gt 0 ]; then
+      # Check if any IPv6 address on this interface is marked as
+      # tentative.
+      ifconfig ${interface} | grep inet6 | grep tentative \
+          >/dev/null 2>&1
+      if [ $? -eq 0 ]; then
+          # Wait for duplicate address detection to complete or for
+          # the timeout specified as --dad-wait-time.
+          for i in $(seq 0 $dad_wait_time)
+          do
+              # We're going to poll for the tentative flag every second.
+              sleep 1
+              ifconfig ${interface} | grep inet6 | grep tentative \
+                  >/dev/null 2>&1
+              if [ $? -ne 0 ]; then
+                  break;
+              fi
+          done
+      fi
+  fi
+
   exit_with_hooks 0
 fi