summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcin Siodelski <marcin@isc.org>2017-06-05 15:11:22 +0200
committerMarcin Siodelski <marcin@isc.org>2017-06-05 15:11:22 +0200
commita68ec967692171e5a7178fc9172556d9c2df4265 (patch)
tree66b0c2962c1188fdc76bd3dabedcfa5c678e027e
parentc8f0b32ac5ab4acf566a592ab7255eab45a6d202 (diff)
downloadisc-dhcp-a68ec967692171e5a7178fc9172556d9c2df4265.tar.gz
[master] Implemented --dad-wait-time option for dhclient.
Merged #36169
-rw-r--r--RELNOTES11
-rw-r--r--client/dhclient.813
-rw-r--r--client/dhclient.c19
-rwxr-xr-xclient/scripts/freebsd36
-rwxr-xr-xclient/scripts/linux35
-rwxr-xr-xclient/scripts/macos35
-rwxr-xr-xclient/scripts/netbsd35
-rw-r--r--client/scripts/openbsd35
8 files changed, 216 insertions, 3 deletions
diff --git a/RELNOTES b/RELNOTES
index 115a44a9..ee0caca7 100644
--- 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.
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