From 2024ccca17e83c9615ac0157103fe3eb17365ceb Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Sat, 2 May 2015 21:26:00 +0000 Subject: [PATCH] dhclient: Properly handle IPv6 Router advertisements are now properly processed if there is dhclient running on an interface and all information from the DHCP client is removed when dhclient is stopped. --- src/dhclient-script | 26 ++++++++++++++++++++++++++ src/functions/functions.ipv6 | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/dhclient-script b/src/dhclient-script index 5c22539f..fd5c6f13 100644 --- a/src/dhclient-script +++ b/src/dhclient-script @@ -41,6 +41,13 @@ case "${reason}" in # Flush all other aborted IP addresses ipv6_address_flush "${interface}" + # Disable autoconf because DHCP is handling this + ipv6_device_autoconf_disable "${interface}" + + # Enable forwarding because we are acting as a host + # to uplink network zones. + ipv6_device_forwarding_enable "${interface}" --accept-ra + # 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} @@ -64,6 +71,9 @@ case "${reason}" in db_set "${interface}/ipv6/active" 1 #db_set "${interface}/ipv6/domain-name" "${new_ + # Update the routing tables + routing_update "${interface}" ipv6 + exit 0 # Handle Prefix Delegation @@ -105,6 +115,9 @@ case "${reason}" in ipv6_address_add "${new_ip6_address}/${new_ip6_prefixlen}" "${interface}" \ --valid-lifetime="${new_max_life}" --preferred-lifetime="${new_preferred_life}" + # Update the routing tables + routing_update "${interface}" ipv6 + exit ${EXIT_OK} # Handle Prefix Delegation @@ -132,6 +145,19 @@ case "${reason}" in --preferred-lifetime=0 || exit ${EXIT_ERROR} ;; + EXPIRE6|FAIL6|RELEASE6|STOP6) + # Remove the currently configured addresses from the device. + ipv6_address_flush "${interface}" + + # Reset autoconf mode and disable forwarding + ipv6_device_forwarding_disable "${interface}" + ipv6_device_autoconf_disable "${interface}" + + db_delete "${interface}/ipv6" + + exit 0 + ;; + # IPv4 PREINIT) diff --git a/src/functions/functions.ipv6 b/src/functions/functions.ipv6 index 74e01c00..5e618dc5 100644 --- a/src/functions/functions.ipv6 +++ b/src/functions/functions.ipv6 @@ -53,10 +53,32 @@ ipv6_device_autoconf_disable() { ipv6_device_forwarding_enable() { local device="${1}" + shift + + local accept_ra=0 + + local arg + while read arg; do + case "${arg}" in + --accept-ra) + accept_ra=2 + ;; + esac + done <<< "$(args $@)" sysctl_set "net.ipv6.conf.${device}.forwarding" 1 log INFO "Enabled IPv6 forwarding on '${device}'" + + # If forwarding is enabled, the kernel won't process + # any router advertisements any more, which is not good + # when we still want a default route when running in + # DHCP client mode on an uplink zone. + if [ ${accept_ra} -gt 0 ]; then + log INFO " and accepting router advertisements" + + sysctl_set "net.ipv6.conf.${device}.accept_ra" 2 + fi } ipv6_device_forwarding_disable() { @@ -206,6 +228,7 @@ ipv6_address_flush() { # Remove any stale addresses from aborted clients cmd_quiet ip -6 addr flush dev "${device}" scope global permanent + cmd_quiet ip -6 addr flush dev "${device}" scope global dynamic } ipv6_address_change_lifetime() { -- 2.39.2