]> git.ipfire.org Git - people/stevee/network.git/blobdiff - src/dhclient-script
dhclient: Add support for DHCPv6 and PD
[people/stevee/network.git] / src / dhclient-script
index 16e765d9d75e1d3c5fca4dc6c3afdd29f461cea9..5a6e8a3954c9bcc77ec77376ec4b1d176e4f05e2 100644 (file)
@@ -15,6 +15,14 @@ assert device_exists ${interface}
 basename="$(basename $0)"
 log DEBUG "${basename} called for interface=${interface} reason=${reason}"
 
+# Log all information from dhclient
+if enabled DEBUG; then
+       while read line; do
+               [[ ${line} =~ ^(cur|old|new)_ ]] || continue
+               log DEBUG "  ${line}"
+       done <<< "$(printenv | sort)"
+fi
+
 # Main pitchfork.
 case "${reason}" in
        MEDIUM)
@@ -22,6 +30,106 @@ case "${reason}" in
                exit 0
                ;;
 
+       # IPv6
+
+       PREINIT6)
+               if ! device_is_up "${interface}"; then
+                       log WARNING "Device '${interface}' was not brought up before starting the DHCP client"
+                       device_set_up "${interface}"
+               fi
+
+               # Flush all other aborted IP addresses
+               ipv6_address_flush "${interface}"
+
+               # Wait until DAD for the link-local address has finished
+               for address in $(ipv6_device_get_addresses "${interface}" --scope="link"); do
+                       ipv6_wait_for_dad "${address}" "${interface}" && exit ${EXIT_OK}
+               done
+
+               log ERROR "There is no active link-local address on ${interface}"
+
+               exit ${EXIT_ERROR}
+               ;;
+
+       BOUND6)
+               # We will be called twice. Once for the assigned address and once for an assigned prefix.
+
+               # Handle temporarily-assigned address
+               if isset new_ip6_address && isset new_ip6_prefixlen; then
+                       ipv6_address_add "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \
+                               --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}"
+
+                       # Save configuration
+                       routing_db_set "${interface}" "ipv6" "local-ip-address" "${new_ip6_address}/${new_ip6_prefixlen}"
+                       routing_db_set "${interface}" "ipv6" "active" 1
+                       #routing_db_set "${interface}" "ipv6" "domain-name" "${new_
+
+                       exit 0
+
+               # Handle Prefix Delegation
+               elif isset new_ip6_prefix; then
+                       routing_db_set "${interface}" "ipv6" "delegated-prefix" "${new_ip6_prefix}"
+
+                       exit 0
+               fi
+               ;;
+
+       RENEW6|REBIND6)
+               # Will be called twice like BOUND6.
+
+               if isset new_ip6_address && isset new_ip6_prefixlen; then
+                       # Update nameservers if those have changed
+                       if [[ "${old_dhcp6_name_servers}" != "${new_dhcp6_name_servers}" ]]; then
+                               routing_db_set "${interface}" "ipv6" "domain-name-servers" "${new_dhcp6_name_servers}"
+                               dns_generate_resolvconf
+                       fi
+
+                       # Update the lifetime if the address has not changed
+                       if [[ "${old_ip6_address}" = "${new_ip6_address}" ]]; then
+                               ipv6_address_change_lifetime "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \
+                                       --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}"
+
+                               exit ${EXIT_OK}
+                       fi
+
+                       # Remove any old IP addresses
+                       if [ -n "${old_ip6_address}" ]; then
+                               ipv6_address_del "${old_ip6_address}/${old_ip6_prefixlen}" "${interface}"
+                       fi
+
+                       # Add the new one
+                       ipv6_address_add "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \
+                               --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}"
+
+                       exit ${EXIT_OK}
+
+               # Handle Prefix Delegation
+               elif isset new_ip6_prefix || isset old_ip6_prefix; then
+                       if [[ "${old_ip6_prefix}" = "${new_ip6_prefix}" ]]; then
+                               # TODO What do we need to do if the prefix hasn't changed?
+                               exit ${EXIT_OK}
+                       fi
+
+                       log DEBUG "The delegated prefix has changed from ${old_ip6_prefix} to ${new_ip6_prefix}"
+                       routing_db_set "${interface}" "ipv6" "delegated-prefix" "${new_ip6_prefix}"
+
+                       exit ${EXIT_OK}
+               fi
+               ;;
+
+       DEPREF6)
+               # Check if all necessary information is there
+               if ! isset cur_ip6_address || ! isset cur_ip6_prefixlen; then
+                       exit ${EXIT_ERROR}
+               fi
+
+               # Set lifetime to zero
+               ipv6_address_change_lifetime "${cur_ip6_address}/${cur_ip6_prefixlen}" "${interface}" \
+                       --preferred-lifetime=0 || exit ${EXIT_ERROR}
+               ;;
+
+       # IPv4
+
        PREINIT)
                # Bring up the device if it hasn't been done before.
                if ! device_is_up ${interface}; then
@@ -63,7 +171,6 @@ case "${reason}" in
                exit 0
                ;;
 
-
        BOUND|RENEW|REBIND|REBOOT)
                # Check if the IP address has changed. If so, delete all routes and stuff.
                if [ -n "${old_ip_address}" -a "${old_ip_address}" != "${new_ip_address}" ]; then
@@ -127,6 +234,10 @@ case "${reason}" in
 
                exit 0
                ;;
+
+       *)
+               log ERROR "Unhandled reason: ${reason}"
+               ;;
 esac
 
 exit 1