]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Implemented --dad-wait-time option for dhclient.
authorMarcin Siodelski <marcin@isc.org>
Mon, 5 Jun 2017 13:11:22 +0000 (15:11 +0200)
committerMarcin Siodelski <marcin@isc.org>
Mon, 5 Jun 2017 13:11:22 +0000 (15:11 +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 115a44a9ac751dd6beacf6b8fde6fc4fccc7ac93..ee0caca77cbc2f002d83b2d714d8d28ed6ef39cf 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -133,6 +133,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.3.0 (bug fixes)
 
 - Tidy up several small tickets.
index cf073b4a873a9f88745ce9195d89524e45fc8362..dd1e530eb7940e94a5190eb26550432f809cb9a7 100644 (file)
@@ -134,6 +134,10 @@ dhclient - Dynamic Host Configuration Protocol Client
 .B -w
 ]
 [
+.B --dad-wait-time
+.I seconds
+]
+[
 .B -v
 ]
 [
@@ -409,6 +413,15 @@ overrides these default, with a value of either \fILL\fR or \fILLT\fR.
 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 ad3c899bea60b757366cc1ebeefb51f625cead15..0193de417e28d4c17de2524c24d7688d2e190fe4 100644 (file)
@@ -97,6 +97,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;
@@ -153,11 +154,12 @@ static const char use_v6command[] = "Command not used for DHCPv4: %s";
 #ifdef DHCPv6
 #ifdef DHCP4o6
 #define DHCLIENT_USAGE0 \
-"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>]\n" \
-"                [-p <port>] [-D LL|LLT] \n"
+"[-4|-6] [-SNTPRI1dvrxi] [-nw] -4o6 <port>] [-p <port>]\n" \
+"                [-D LL|LLT] [--dad-wait-time seconds]\n"
 #else /* DHCP4o6 */
 #define DHCLIENT_USAGE0 \
-"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT] \n"
+"[-4|-6] [-SNTPRI1dvrxi] [-nw] [-p <port>] [-D LL|LLT]\n" \
+"                [--dad-wait-time seconds]\n"
 #endif
 #else /* DHCPv6 */
 #define DHCLIENT_USAGE0 \
@@ -478,6 +480,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], "-D")) {
                        duid_v4 = 1;
@@ -3930,6 +3941,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 6485cc7513ff92928f99f527ece253cc5efcbd6f..8f3e2a23ad761dc66512c837e6ebb29388a1577e 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 cb6619215a388c4af770e76c85643a26d4f03dd7..a896b1e9a288e4145379c3b60449e45fc6c2def9 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