diff options
-rw-r--r-- | RELNOTES | 11 | ||||
-rw-r--r-- | client/dhclient.8 | 13 | ||||
-rw-r--r-- | client/dhclient.c | 19 | ||||
-rwxr-xr-x | client/scripts/freebsd | 36 | ||||
-rwxr-xr-x | client/scripts/linux | 35 | ||||
-rwxr-xr-x | client/scripts/macos | 35 | ||||
-rwxr-xr-x | client/scripts/netbsd | 35 | ||||
-rw-r--r-- | client/scripts/openbsd | 35 |
8 files changed, 216 insertions, 3 deletions
@@ -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. diff --git a/client/dhclient.8 b/client/dhclient.8 index cf073b4a..dd1e530e 100644 --- a/client/dhclient.8 +++ b/client/dhclient.8 @@ -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 diff --git a/client/dhclient.c b/client/dhclient.c index ad3c899b..0193de41 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -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); } } diff --git a/client/scripts/freebsd b/client/scripts/freebsd index 6485cc75..8f3e2a23 100755 --- a/client/scripts/freebsd +++ b/client/scripts/freebsd @@ -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 diff --git a/client/scripts/linux b/client/scripts/linux index e6792c67..7d77fd39 100755 --- a/client/scripts/linux +++ b/client/scripts/linux @@ -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 diff --git a/client/scripts/macos b/client/scripts/macos index cb661921..a896b1e9 100755 --- a/client/scripts/macos +++ b/client/scripts/macos @@ -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 diff --git a/client/scripts/netbsd b/client/scripts/netbsd index 8a5007e7..6a41edf4 100755 --- a/client/scripts/netbsd +++ b/client/scripts/netbsd @@ -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 diff --git a/client/scripts/openbsd b/client/scripts/openbsd index f20d0ff6..151b50aa 100644 --- a/client/scripts/openbsd +++ b/client/scripts/openbsd @@ -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 |