diff --git a/diskimage_builder/elements/dhcp-all-interfaces/install.d/50-dhcp-all-interfaces b/diskimage_builder/elements/dhcp-all-interfaces/install.d/50-dhcp-all-interfaces index 439a7900..0c180c01 100755 --- a/diskimage_builder/elements/dhcp-all-interfaces/install.d/50-dhcp-all-interfaces +++ b/diskimage_builder/elements/dhcp-all-interfaces/install.d/50-dhcp-all-interfaces @@ -21,6 +21,9 @@ if [ -f /etc/dhcp/dhclient.conf ] ; then else echo -e "# \"timeout\" Value set by dhcp-all-interfaces\ntimeout ${DIB_DHCP_TIMEOUT:-30};" >> /etc/dhcp/dhclient.conf fi + if grep -o "^retry " /etc/dhcp/dhclient.conf ; then + sed -i -e '/^retry/s/^/# \"retry\" Value commented by dhcp-all-interfaces\n# /g' /etc/dhcp/dhclient.conf + fi fi if [ "$DIB_INIT_SYSTEM" == "upstart" ]; then @@ -34,7 +37,7 @@ if [ "$DIB_INIT_SYSTEM" == "upstart" ]; then elif [ "$DIB_INIT_SYSTEM" == "systemd" ]; then install -D -g root -o root -m 0644 ${SCRIPTDIR}/dhcp-interface@.service /usr/lib/systemd/system/dhcp-interface@.service install -D -g root -o root -m 0644 ${SCRIPTDIR}/dhcp-all-interfaces-udev.rules /etc/udev/rules.d/99-dhcp-all-interfaces.rules - sed -i "s/TimeoutStartSec=DIB_DHCP_TIMEOUT/TimeoutStartSec=${DIB_DHCP_TIMEOUT:-30}s/" /usr/lib/systemd/system/dhcp-interface@.service + sed -i "s/TimeoutStartSec=DIB_DHCP_TIMEOUT/TimeoutStartSec=$(( ${DIB_DHCP_TIMEOUT:-30} * 2 ))s/" /usr/lib/systemd/system/dhcp-interface@.service elif [ "$DIB_INIT_SYSTEM" == "sysv" ]; then install -D -g root -o root -m 0755 ${SCRIPTDIR}/dhcp-all-interfaces.init /etc/init.d/dhcp-all-interfaces update-rc.d dhcp-all-interfaces defaults diff --git a/diskimage_builder/elements/dhcp-all-interfaces/install.d/dhcp-all-interfaces.sh b/diskimage_builder/elements/dhcp-all-interfaces/install.d/dhcp-all-interfaces.sh index 25113b71..1e534884 100755 --- a/diskimage_builder/elements/dhcp-all-interfaces/install.d/dhcp-all-interfaces.sh +++ b/diskimage_builder/elements/dhcp-all-interfaces/install.d/dhcp-all-interfaces.sh @@ -47,15 +47,54 @@ function get_if_type() { function enable_interface() { local interface=$1 + local ipv6_init=$2 + local ipv6_AdvManagedFlag=$3 + local ipv6_AdvOtherConfigFlag=$4 serialize_me if [ "$CONF_TYPE" == "eni" ]; then printf "auto $interface\niface $interface inet dhcp\n\n" >>$ENI_FILE + if [ "$ipv6_init" == "True" ]; then + # Make DUID-UUID Type 4 (RFC 6355) + echo "default-duid \"\\x00\\x04$(sed 's/.\{2\}/\\x&/g' < /etc/machine-id)\";" >"/var/lib/dhclient/dhclient6--$interface.lease" + if [ $ipv6_AdvManagedFlag == "Yes" ]; then + # IPv6 DHCPv6 Stateful address configuration + printf "iface $interface inet6 dhcp\n\n" >>$ENI_FILE + echo "DHCPv6 Stateful Configured." + elif [ $ipv6_AdvOtherConfigFlag == "Yes" ]; then + # IPv6 DHCPv6 Stateless address configursation + printf "iface $interface inet6 auto\n\tdhcp 1\n\n" >>$ENI_FILE + echo "DHCPv6 Stateless Configured." + else + # IPv6 Autoconfiguration (SLAAC) + printf "iface $interface inet6 auto\tdhcp 0\n\n" >>$ENI_FILE + echo "IPv6 SLAAC Configured" + fi + fi + printf "\n" >>$ENI_FILE elif [ "$CONF_TYPE" == "rhel-netscripts" ]; then if [ "$(get_if_type $interface)" == "32" ]; then printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nTYPE=\"InfiniBand\"\nCONNECTED_MODE=\"no\"\nDEFROUTE=\"yes\"\nPEERDNS=\"yes\"\nPEERROUTES=\"yes\"\nIPV4_FAILURE_FATAL=\"yes\"\nIPV6INIT=\"no\"" >"${SCRIPTS_PATH}ifcfg-$interface" else - printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nTYPE=\"Ethernet\"" >"${SCRIPTS_PATH}ifcfg-$interface" + printf "DEVICE=\"$interface\"\nBOOTPROTO=\"dhcp\"\nONBOOT=\"yes\"\nTYPE=\"Ethernet\"\n" >"${SCRIPTS_PATH}ifcfg-$interface" + if [ "$ipv6_init" == "True" ]; then + # Make DUID-UUID Type 4 (RFC 6355) + echo "default-duid \"\\x00\\x04$(sed 's/.\{2\}/\\x&/g' < /etc/machine-id)\";" >"/var/lib/dhclient/dhclient6--$interface.lease" + printf "IPV6INIT=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface" + if [ $ipv6_AdvManagedFlag == "Yes" ]; then + # IPv6 DHCPv6 Stateful address configuration + printf "IPV6_FORCE_ACCEPT_RA=\"yes\"\nDHCPV6C=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface" + echo "DHCPv6 Stateful Configured" + elif [ $ipv6_AdvOtherConfigFlag == "Yes" ]; then + # IPv6 DHCPv6 Stateless address configursation + printf "IPV6_AUTOCONF=\"yes\"\nDHCPV6C=\"yes\"\nDHCPV6C_OPTIONS=\"-S\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface" + echo "DHCPv6 Stateless Configured" + else + # IPv6 Autoconfiguration (SLAAC) + printf "IPV6_AUTOCONF=\"yes\"\n" >>"${SCRIPTS_PATH}ifcfg-$interface" + echo "IPv6 SLAAC Configured" + fi + fi fi elif [ "$CONF_TYPE" == "suse-netscripts" ]; then printf "BOOTPROTO=\"dhcp\"\nSTARTMODE=\"auto\"" >"${SCRIPTS_PATH}ifcfg-$interface" @@ -106,7 +145,37 @@ function inspect_interface() { sleep 1 done if [ "$has_link" == "1" ]; then - enable_interface "$interface" + local ipv6_init=False + local ipv6_AdvManagedFlag=No + local ipv6_AdvOtherConfigFlag=No + if type rdisc6 &>/dev/null; then + # We have rdisc6, let's try to configure IPv6 autoconfig/dhcpv6 + tries=DIB_DHCP_TIMEOUT + for ((; tries > 0; tries--)); do + # Need to retry this, link-local-address required for + # Neighbor Discovery, DHCPv6 etc. + set +e # Do not exit on error, capture rdisc6 error codes. + RA=$(rdisc6 --retry 3 --single "$interface" 2>/dev/null) + local return_code=$? + set -e # Re-enable exit on error. + if [ $return_code -eq 0 ]; then + ipv6_init=True + ipv6_AdvManagedFlag=$(echo "$RA" | grep "Stateful address conf." | awk -F: '{ print $2 }') + ipv6_AdvOtherConfigFlag=$(echo "$RA" | grep "Stateful other conf." | awk -F: '{ print $2 }') + elif [ $return_code -eq 1 ]; then + sleep 1 + elif [ $return_code -eq 2 ]; then + # If rdisc6 does not receive any response after the + # specified number of attempts waiting for wait_ms + # (1000ms by default) milliseconds each time, it will + # exit with code 2. + break + fi + done + else + echo "rdisc6 not available, skipping IPv6 configuration." + fi + enable_interface "$interface" "$ipv6_init" "$ipv6_AdvManagedFlag" "$ipv6_AdvOtherConfigFlag" else echo "No link detected, skipping" fi diff --git a/diskimage_builder/elements/dhcp-all-interfaces/package-installs.yaml b/diskimage_builder/elements/dhcp-all-interfaces/package-installs.yaml index f7310872..eee9f212 100644 --- a/diskimage_builder/elements/dhcp-all-interfaces/package-installs.yaml +++ b/diskimage_builder/elements/dhcp-all-interfaces/package-installs.yaml @@ -1,2 +1,3 @@ dhcp-client: ifupdown: +ndisc6: diff --git a/diskimage_builder/elements/dhcp-all-interfaces/pkg-map b/diskimage_builder/elements/dhcp-all-interfaces/pkg-map index 080f6cd4..95416c86 100644 --- a/diskimage_builder/elements/dhcp-all-interfaces/pkg-map +++ b/diskimage_builder/elements/dhcp-all-interfaces/pkg-map @@ -1,20 +1,24 @@ { "family": { "redhat": { - "dhcp-client": "dhclient" + "dhcp-client": "dhclient", + "ndisc6": "ndisc6" }, "gentoo": { - "dhcp-client": "net-misc/dhcpcd" + "dhcp-client": "net-misc/dhcpcd", + "ndisc6": "net-misc/ndisc6" }, "suse": { "dhcp-client": "dhcp-client" }, "debian": { - "ifupdown": "ifupdown" + "ifupdown": "ifupdown", + "ndisc6": "ndisc6" } }, "default": { "dhcp-client": "isc-dhcp-client", - "ifupdown": "" + "ifupdown": "", + "ndisc6": "" } }