]> git.ipfire.org Git - thirdparty/dhcp.git/blobdiff - client/scripts/macos
[master] Added DAD error checking on BOUND6 to client scripts
[thirdparty/dhcp.git] / client / scripts / macos
index a896b1e9a288e4145379c3b60449e45fc6c2def9..0164b1f0b3747e618c2679043c09d22fa1b16295 100755 (executable)
@@ -108,6 +108,51 @@ commit_resolv_conf() {
   to_commit="done"
 }
 
+# This function was largely borrowed from dhclient-script that
+# ships with Centos, authored by Jiri Popelka and David Cantrell
+# of Redhat. Thanks guys.
+add_ipv6_addr_with_DAD() {
+    ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} alias
+
+    if [ ${dad_wait_time} -le 0 ]
+    then
+        # if we're not waiting for DAD, assume we're good
+        return 0
+    fi
+
+    # Repeatedly test whether newly added address passed
+    # duplicate address detection (DAD)
+    for i in $(seq 1 ${dad_wait_time}); do
+        sleep 1 # give the DAD some time
+
+        addr=$(ifconfig ${interface} \
+            | grep "${new_ip6_address} prefixlen ${new_ip6_prefixlen}")
+
+        # tentative flag == DAD is still not complete
+        tentative=$(echo "${addr}" | grep tentative)
+        # dadfailed flag == address is already in use somewhere else
+        dadfailed=$(echo "${addr}" | grep duplicated)
+
+        if [ -n "${dadfailed}" ] ; then
+            # dad failed, remove the address
+            ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} -alias
+            exit_with_hooks 3
+        fi
+
+        if [ -z "${tentative}" ] ; then
+            if [ -n "${addr}" ]; then
+                # DAD is over
+                return 0
+            else
+                # address was auto-removed (or not added at all)
+                exit_with_hooks 3
+            fi
+        fi
+    done
+
+    return 0
+}
+
 # Must be used on exit.   Invokes the local dhcp client exit hooks, if any.
 exit_with_hooks() {
   exit_status=$1
@@ -195,7 +240,8 @@ if [ x$reason = xBOUND6 ]; then
     exit_with_hooks 2;
   fi
 
-  ifconfig ${interface} inet6 ${new_ip6_address}/${new_ip6_prefixlen} alias
+  # Add address to interface, check for DAD if dad_wait_time > 0
+  add_ipv6_addr_with_DAD
 
   # Check for nameserver options.
   make_resolv_conf