16fb29d29Schristos#!/bin/bash 26fb29d29Schristos# dhclient-script for Linux. Dan Halbert, March, 1997. 36fb29d29Schristos# Updated for Linux 2.[12] by Brian J. Murrell, January 1999. 46fb29d29Schristos# No guarantees about this. I'm a novice at the details of Linux 56fb29d29Schristos# networking. 66fb29d29Schristos 76fb29d29Schristos# Notes: 86fb29d29Schristos 96fb29d29Schristos# 0. This script is based on the netbsd script supplied with dhcp-970306. 106fb29d29Schristos 116fb29d29Schristos# 1. ifconfig down apparently deletes all relevant routes and flushes 126fb29d29Schristos# the arp cache, so this doesn't need to be done explicitly. 136fb29d29Schristos 146fb29d29Schristos# 2. The alias address handling here has not been tested AT ALL. 156fb29d29Schristos# I'm just going by the doc of modern Linux ip aliasing, which uses 166fb29d29Schristos# notations like eth0:0, eth0:1, for each alias. 176fb29d29Schristos 186fb29d29Schristos# 3. I have to calculate the network address, and calculate the broadcast 196fb29d29Schristos# address if it is not supplied. This might be much more easily done 206fb29d29Schristos# by the dhclient C code, and passed on. 216fb29d29Schristos 226fb29d29Schristos# 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious 236fb29d29Schristos# of the $1 in its args. 246fb29d29Schristos 256fb29d29Schristos# 5. Script refresh in 2017. The aliasing code was too convoluted and needs 266fb29d29Schristos# to go away. Migrated DHCPv4 script to ip command from iproute2 suite. 276fb29d29Schristos# This is based on Debian script with some tweaks. ifconfig is no longer 286fb29d29Schristos# used. Everything is done using ip tool from ip-route2. 296fb29d29Schristos 306fb29d29Schristos# 'ip' just looks too weird. Also, we now have unit-tests! Those unit-tests 316fb29d29Schristos# overwirte this line to use a fake ip-echo tool. It's also convenient 326fb29d29Schristos# if your system holds ip tool in a non-standard location. 336fb29d29Schristosip=/sbin/ip 346fb29d29Schristos 356fb29d29Schristos# update /etc/resolv.conf based on received values 366fb29d29Schristos# This updated version mostly follows Debian script by Andrew Pollock et al. 376fb29d29Schristosmake_resolv_conf() { 386fb29d29Schristos local new_resolv_conf 396fb29d29Schristos 406fb29d29Schristos # DHCPv4 416fb29d29Schristos if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] || 426fb29d29Schristos [ -n "$new_domain_name_servers" ]; then 436fb29d29Schristos new_resolv_conf=/etc/resolv.conf.dhclient-new 446fb29d29Schristos rm -f $new_resolv_conf 456fb29d29Schristos 466fb29d29Schristos if [ -n "$new_domain_name" ]; then 476fb29d29Schristos echo domain ${new_domain_name%% *} >>$new_resolv_conf 486fb29d29Schristos fi 496fb29d29Schristos 506fb29d29Schristos if [ -n "$new_domain_search" ]; then 516fb29d29Schristos if [ -n "$new_domain_name" ]; then 526fb29d29Schristos domain_in_search_list="" 536fb29d29Schristos for domain in $new_domain_search; do 546fb29d29Schristos if [ "$domain" = "${new_domain_name}" ] || 556fb29d29Schristos [ "$domain" = "${new_domain_name}." ]; then 566fb29d29Schristos domain_in_search_list="Yes" 576fb29d29Schristos fi 586fb29d29Schristos done 596fb29d29Schristos if [ -z "$domain_in_search_list" ]; then 606fb29d29Schristos new_domain_search="$new_domain_name $new_domain_search" 616fb29d29Schristos fi 626fb29d29Schristos fi 636fb29d29Schristos echo "search ${new_domain_search}" >> $new_resolv_conf 646fb29d29Schristos elif [ -n "$new_domain_name" ]; then 656fb29d29Schristos echo "search ${new_domain_name}" >> $new_resolv_conf 666fb29d29Schristos fi 676fb29d29Schristos 686fb29d29Schristos if [ -n "$new_domain_name_servers" ]; then 696fb29d29Schristos for nameserver in $new_domain_name_servers; do 706fb29d29Schristos echo nameserver $nameserver >>$new_resolv_conf 716fb29d29Schristos done 726fb29d29Schristos else # keep 'old' nameservers 736fb29d29Schristos sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf 746fb29d29Schristos fi 756fb29d29Schristos 766fb29d29Schristos if [ -f /etc/resolv.conf ]; then 776fb29d29Schristos chown --reference=/etc/resolv.conf $new_resolv_conf 786fb29d29Schristos chmod --reference=/etc/resolv.conf $new_resolv_conf 796fb29d29Schristos fi 806fb29d29Schristos mv -f $new_resolv_conf /etc/resolv.conf 816fb29d29Schristos # DHCPv6 826fb29d29Schristos elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then 836fb29d29Schristos new_resolv_conf=/etc/resolv.conf.dhclient-new 846fb29d29Schristos rm -f $new_resolv_conf 856fb29d29Schristos 866fb29d29Schristos if [ -n "$new_dhcp6_domain_search" ]; then 876fb29d29Schristos echo "search ${new_dhcp6_domain_search}" >> $new_resolv_conf 886fb29d29Schristos fi 896fb29d29Schristos 906fb29d29Schristos if [ -n "$new_dhcp6_name_servers" ]; then 916fb29d29Schristos for nameserver in $new_dhcp6_name_servers; do 926fb29d29Schristos # append %interface to link-local-address nameservers 936fb29d29Schristos if [ "${nameserver##fe80::}" != "$nameserver" ] || 946fb29d29Schristos [ "${nameserver##FE80::}" != "$nameserver" ]; then 956fb29d29Schristos nameserver="${nameserver}%${interface}" 966fb29d29Schristos fi 976fb29d29Schristos echo nameserver $nameserver >>$new_resolv_conf 986fb29d29Schristos done 996fb29d29Schristos else # keep 'old' nameservers 1006fb29d29Schristos sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf 1016fb29d29Schristos fi 1026fb29d29Schristos 1036fb29d29Schristos if [ -f /etc/resolv.conf ]; then 1046fb29d29Schristos chown --reference=/etc/resolv.conf $new_resolv_conf 1056fb29d29Schristos chmod --reference=/etc/resolv.conf $new_resolv_conf 1066fb29d29Schristos fi 1076fb29d29Schristos mv -f $new_resolv_conf /etc/resolv.conf 1086fb29d29Schristos fi 1096fb29d29Schristos} 1106fb29d29Schristos 1116fb29d29Schristos# set host name 1126fb29d29Schristosset_hostname() { 1136fb29d29Schristos local current_hostname 1146fb29d29Schristos 1156fb29d29Schristos if [ -n "$new_host_name" ]; then 1166fb29d29Schristos current_hostname=$(hostname) 1176fb29d29Schristos 1186fb29d29Schristos # current host name is empty, '(none)' or 'localhost' or differs from new one from DHCP 1196fb29d29Schristos if [ -z "$current_hostname" ] || 1206fb29d29Schristos [ "$current_hostname" = '(none)' ] || 1216fb29d29Schristos [ "$current_hostname" = 'localhost' ] || 1226fb29d29Schristos [ "$current_hostname" = "$old_host_name" ]; then 1236fb29d29Schristos if [ "$new_host_name" != "$old_host_name" ]; then 1246fb29d29Schristos hostname "$new_host_name" 1256fb29d29Schristos fi 1266fb29d29Schristos fi 1276fb29d29Schristos fi 1286fb29d29Schristos} 1296fb29d29Schristos 1306fb29d29Schristos# run given script 1316fb29d29Schristosrun_hook() { 1326fb29d29Schristos local script 1336fb29d29Schristos local exit_status 1346fb29d29Schristos script="$1" 1356fb29d29Schristos 1366fb29d29Schristos if [ -f $script ]; then 1376fb29d29Schristos . $script 1386fb29d29Schristos fi 1396fb29d29Schristos 1406fb29d29Schristos if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then 1416fb29d29Schristos logger -p daemon.err "$script returned non-zero exit status $exit_status" 1426fb29d29Schristos fi 1436fb29d29Schristos 1446fb29d29Schristos return $exit_status 1456fb29d29Schristos} 1466fb29d29Schristos 1476fb29d29Schristos# run scripts in given directory 1486fb29d29Schristosrun_hookdir() { 1496fb29d29Schristos local dir 1506fb29d29Schristos local exit_status 1516fb29d29Schristos dir="$1" 1526fb29d29Schristos 1536fb29d29Schristos if [ -d "$dir" ]; then 1546fb29d29Schristos for script in $(run-parts --list $dir); do 1556fb29d29Schristos run_hook $script || true 1566fb29d29Schristos exit_status=$? 1576fb29d29Schristos done 1586fb29d29Schristos fi 1596fb29d29Schristos 1606fb29d29Schristos return $exit_status 1616fb29d29Schristos} 1626fb29d29Schristos 1636fb29d29Schristos# Must be used on exit. Invokes the local dhcp client exit hooks, if any. 1646fb29d29Schristosexit_with_hooks() { 1656fb29d29Schristos exit_status=$1 1666fb29d29Schristos 1676fb29d29Schristos # Source the documented exit-hook script, if it exists 1686fb29d29Schristos if ! run_hook /etc/dhclient-exit-hooks; then 1696fb29d29Schristos exit_status=$? 1706fb29d29Schristos fi 1716fb29d29Schristos 1726fb29d29Schristos # Now run scripts in the Debian-specific directory. 1736fb29d29Schristos if ! run_hookdir /etc/dhclient-exit-hooks.d; then 1746fb29d29Schristos exit_status=$? 1756fb29d29Schristos fi 1766fb29d29Schristos 1776fb29d29Schristos exit $exit_status 1786fb29d29Schristos} 1796fb29d29Schristos 1806fb29d29Schristos# This function was largely borrowed from dhclient-script that 1816fb29d29Schristos# ships with Centos, authored by Jiri Popelka and David Cantrell 1826fb29d29Schristos# of Redhat. Thanks guys. 1836fb29d29Schristosadd_ipv6_addr_with_DAD() { 1846fb29d29Schristos ${ip} -6 addr replace ${new_ip6_address}/${new_ip6_prefixlen} \ 1856fb29d29Schristos dev ${interface} scope global valid_lft ${new_max_life} \ 1866fb29d29Schristos preferred_lft ${new_preferred_life} 1876fb29d29Schristos 1886fb29d29Schristos if [ ${dad_wait_time} -le 0 ] 1896fb29d29Schristos then 1906fb29d29Schristos # if we're not waiting for DAD, assume we're good 1916fb29d29Schristos return 0 1926fb29d29Schristos fi 1936fb29d29Schristos 1946fb29d29Schristos # Repeatedly test whether newly added address passed 1956fb29d29Schristos # duplicate address detection (DAD) 1966fb29d29Schristos for i in $(seq 1 ${dad_wait_time}); do 1976fb29d29Schristos sleep 1 # give the DAD some time 1986fb29d29Schristos 1996fb29d29Schristos addr=$(${ip} -6 addr show dev ${interface} \ 2006fb29d29Schristos | grep ${new_ip6_address}/${new_ip6_prefixlen}) 2016fb29d29Schristos 2026fb29d29Schristos # tentative flag == DAD is still not complete 2036fb29d29Schristos tentative=$(echo "${addr}" | grep tentative) 2046fb29d29Schristos # dadfailed flag == address is already in use somewhere else 2056fb29d29Schristos dadfailed=$(echo "${addr}" | grep dadfailed) 2066fb29d29Schristos 2076fb29d29Schristos if [ -n "${dadfailed}" ] ; then 2086fb29d29Schristos # address was added with valid_lft/preferred_lft 'forever', 2096fb29d29Schristos # remove it 2106fb29d29Schristos ${ip} -6 addr del ${new_ip6_address}/${new_ip6_prefixlen} \ 2116fb29d29Schristos dev ${interface} 2126fb29d29Schristos 2136fb29d29Schristos exit_with_hooks 3 2146fb29d29Schristos fi 2156fb29d29Schristos 2166fb29d29Schristos if [ -z "${tentative}" ] ; then 2176fb29d29Schristos if [ -n "${addr}" ]; then 2186fb29d29Schristos # DAD is over 2196fb29d29Schristos return 0 2206fb29d29Schristos else 2216fb29d29Schristos # address was auto-removed (or not added at all) 2226fb29d29Schristos exit_with_hooks 3 2236fb29d29Schristos fi 2246fb29d29Schristos fi 2256fb29d29Schristos done 2266fb29d29Schristos 2276fb29d29Schristos return 0 2286fb29d29Schristos} 2296fb29d29Schristos 2306fb29d29Schristos# Invoke the local dhcp client enter hooks, if they exist. 2316fb29d29Schristosrun_hook /etc/dhclient-enter-hooks 2326fb29d29Schristosrun_hookdir /etc/dhclient-enter-hooks.d 2336fb29d29Schristos 2346fb29d29Schristos# Execute the operation 2356fb29d29Schristoscase "$reason" in 2366fb29d29Schristos 2376fb29d29Schristos ### DHCPv4 Handlers 2386fb29d29Schristos 2396fb29d29Schristos MEDIUM|ARPCHECK|ARPSEND) 2406fb29d29Schristos # Do nothing 2416fb29d29Schristos ;; 2426fb29d29Schristos PREINIT) 2436fb29d29Schristos # The DHCP client is requesting that an interface be 2446fb29d29Schristos # configured as required in order to send packets prior to 2456fb29d29Schristos # receiving an actual address. - dhclient-script(8) 2466fb29d29Schristos 2476fb29d29Schristos # ensure interface is up 2486fb29d29Schristos ${ip} link set dev ${interface} up 2496fb29d29Schristos 2506fb29d29Schristos if [ -n "$alias_ip_address" ]; then 2516fb29d29Schristos # flush alias IP from interface 2526fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface}:0 2536fb29d29Schristos fi 2546fb29d29Schristos 2556fb29d29Schristos ;; 2566fb29d29Schristos 2576fb29d29Schristos BOUND|RENEW|REBIND|REBOOT) 2586fb29d29Schristos set_hostname 2596fb29d29Schristos 2606fb29d29Schristos if [ -n "$old_ip_address" ] && [ -n "$alias_ip_address" ] && 2616fb29d29Schristos [ "$alias_ip_address" != "$old_ip_address" ]; then 2626fb29d29Schristos # alias IP may have changed => flush it 2636fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface}:0 2646fb29d29Schristos fi 2656fb29d29Schristos 2666fb29d29Schristos if [ -n "$old_ip_address" ] && 2676fb29d29Schristos [ "$old_ip_address" != "$new_ip_address" ]; then 2686fb29d29Schristos # leased IP has changed => flush it 2696fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface} 2706fb29d29Schristos fi 2716fb29d29Schristos 2726fb29d29Schristos if [ -z "$old_ip_address" ] || 2736fb29d29Schristos [ "$old_ip_address" != "$new_ip_address" ] || 2746fb29d29Schristos [ "$reason" = "BOUND" ] || [ "$reason" = "REBOOT" ]; then 2756fb29d29Schristos # new IP has been leased or leased IP changed => set it 2766fb29d29Schristos ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \ 2776fb29d29Schristos ${new_broadcast_address:+broadcast $new_broadcast_address} \ 2786fb29d29Schristos dev ${interface} label ${interface} 2796fb29d29Schristos 2806fb29d29Schristos if [ -n "$new_interface_mtu" ]; then 2816fb29d29Schristos # set MTU 2826fb29d29Schristos ${ip} link set dev ${interface} mtu ${new_interface_mtu} 2836fb29d29Schristos fi 2846fb29d29Schristos 2856fb29d29Schristos # if we have $new_rfc3442_classless_static_routes then we have to 2866fb29d29Schristos # ignore $new_routers entirely 2876fb29d29Schristos if [ ! "$new_rfc3442_classless_static_routes" ]; then 2886fb29d29Schristos # set if_metric if IF_METRIC is set or there's more than one router 2896fb29d29Schristos if_metric="$IF_METRIC" 2906fb29d29Schristos if [ "${new_routers%% *}" != "${new_routers}" ]; then 2916fb29d29Schristos if_metric=${if_metric:-1} 2926fb29d29Schristos fi 2936fb29d29Schristos 2946fb29d29Schristos for router in $new_routers; do 2956fb29d29Schristos if [ "$new_subnet_mask" = "255.255.255.255" ]; then 2966fb29d29Schristos # point-to-point connection => set explicit route 2976fb29d29Schristos ${ip} -4 route add ${router} dev $interface >/dev/null 2>&1 2986fb29d29Schristos fi 2996fb29d29Schristos 3006fb29d29Schristos # set default route 3016fb29d29Schristos ${ip} -4 route add default via ${router} dev ${interface} \ 3026fb29d29Schristos ${if_metric:+metric $if_metric} >/dev/null 2>&1 3036fb29d29Schristos 3046fb29d29Schristos if [ -n "$if_metric" ]; then 3056fb29d29Schristos if_metric=$((if_metric+1)) 3066fb29d29Schristos fi 3076fb29d29Schristos done 3086fb29d29Schristos fi 3096fb29d29Schristos fi 3106fb29d29Schristos 3116fb29d29Schristos if [ -n "$alias_ip_address" ] && 3126fb29d29Schristos [ "$new_ip_address" != "$alias_ip_address" ]; then 3136fb29d29Schristos # separate alias IP given, which may have changed 3146fb29d29Schristos # => flush it, set it & add host route to it 3156fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface}:0 3166fb29d29Schristos ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 3176fb29d29Schristos dev ${interface} label ${interface}:0 3186fb29d29Schristos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 3196fb29d29Schristos fi 3206fb29d29Schristos 3216fb29d29Schristos # update /etc/resolv.conf 3226fb29d29Schristos make_resolv_conf 3236fb29d29Schristos 3246fb29d29Schristos ;; 3256fb29d29Schristos 3266fb29d29Schristos EXPIRE|FAIL|RELEASE|STOP) 3276fb29d29Schristos if [ -n "$alias_ip_address" ]; then 3286fb29d29Schristos # flush alias IP 3296fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface}:0 3306fb29d29Schristos fi 3316fb29d29Schristos 3326fb29d29Schristos if [ -n "$old_ip_address" ]; then 3336fb29d29Schristos # flush leased IP 3346fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface} 3356fb29d29Schristos fi 3366fb29d29Schristos 3376fb29d29Schristos if [ -n "$alias_ip_address" ]; then 3386fb29d29Schristos # alias IP given => set it & add host route to it 3396fb29d29Schristos ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 3406fb29d29Schristos dev ${interface} label ${interface}:0 3416fb29d29Schristos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 3426fb29d29Schristos fi 3436fb29d29Schristos 3446fb29d29Schristos ;; 3456fb29d29Schristos 3466fb29d29Schristos TIMEOUT) 3476fb29d29Schristos if [ -n "$alias_ip_address" ]; then 3486fb29d29Schristos # flush alias IP 3496fb29d29Schristos ${ip} -4 addr flush dev ${interface} label ${interface}:0 3506fb29d29Schristos fi 3516fb29d29Schristos 3526fb29d29Schristos # set IP from recorded lease 3536fb29d29Schristos ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \ 3546fb29d29Schristos ${new_broadcast_address:+broadcast $new_broadcast_address} \ 3556fb29d29Schristos dev ${interface} label ${interface} 3566fb29d29Schristos 3576fb29d29Schristos if [ -n "$new_interface_mtu" ]; then 3586fb29d29Schristos # set MTU 3596fb29d29Schristos ${ip} link set dev ${interface} mtu ${new_interface_mtu} 3606fb29d29Schristos fi 3616fb29d29Schristos 3626fb29d29Schristos # if there is no router recorded in the lease or the 1st router answers pings 3636fb29d29Schristos if [ -z "$new_routers" ] || ping -q -c 1 "${new_routers%% *}"; then 3646fb29d29Schristos # if we have $new_rfc3442_classless_static_routes then we have to 3656fb29d29Schristos # ignore $new_routers entirely 3666fb29d29Schristos if [ ! "$new_rfc3442_classless_static_routes" ]; then 3676fb29d29Schristos if [ -n "$alias_ip_address" ] && 3686fb29d29Schristos [ "$new_ip_address" != "$alias_ip_address" ]; then 3696fb29d29Schristos # separate alias IP given => set up the alias IP & add host route to it 3706fb29d29Schristos ${ip} -4 addr add \ 3716fb29d29Schristos ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 3726fb29d29Schristos dev ${interface} label ${interface}:0 3736fb29d29Schristos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 3746fb29d29Schristos fi 3756fb29d29Schristos 3766fb29d29Schristos # set if_metric if IF_METRIC is set or there's more than one router 3776fb29d29Schristos if_metric="$IF_METRIC" 3786fb29d29Schristos if [ "${new_routers%% *}" != "${new_routers}" ]; then 3796fb29d29Schristos if_metric=${if_metric:-1} 3806fb29d29Schristos fi 3816fb29d29Schristos 3826fb29d29Schristos # set default route 3836fb29d29Schristos for router in $new_routers; do 3846fb29d29Schristos ${ip} -4 route add default via ${router} dev ${interface} \ 3856fb29d29Schristos ${if_metric:+metric $if_metric} >/dev/null 2>&1 3866fb29d29Schristos 3876fb29d29Schristos if [ -n "$if_metric" ]; then 3886fb29d29Schristos if_metric=$((if_metric+1)) 3896fb29d29Schristos fi 3906fb29d29Schristos done 3916fb29d29Schristos fi 3926fb29d29Schristos 3936fb29d29Schristos # update /etc/resolv.conf 3946fb29d29Schristos make_resolv_conf 3956fb29d29Schristos else 3966fb29d29Schristos # flush all IPs from interface 3976fb29d29Schristos ip -4 addr flush dev ${interface} 3986fb29d29Schristos exit_with_hooks 2 3996fb29d29Schristos fi 4006fb29d29Schristos 4016fb29d29Schristos ;; 4026fb29d29Schristos 403*41e8421fSchristos V6ONLY) 404*41e8421fSchristos if [ -n "$old_ip_address" ]; then 405*41e8421fSchristos # flush leased IP 406*41e8421fSchristos ${ip} -4 addr flush dev ${interface} label ${interface} 407*41e8421fSchristos fi 408*41e8421fSchristos 409*41e8421fSchristos ;; 410*41e8421fSchristos 4116fb29d29Schristos ### DHCPv6 Handlers 4126fb29d29Schristos # TODO handle prefix change: ?based on ${old_ip6_prefix} and ${new_ip6_prefix}? 4136fb29d29Schristos 4146fb29d29Schristos PREINIT6) 4156fb29d29Schristos # ensure interface is up 4166fb29d29Schristos ${ip} link set ${interface} up 4176fb29d29Schristos 4186fb29d29Schristos # We need to give the kernel some time to active interface 4196fb29d29Schristos interface_up_wait_time=5 4206fb29d29Schristos for i in $(seq 0 ${interface_up_wait_time}) 4216fb29d29Schristos do 422*41e8421fSchristos ${ip} link show dev ${interface} | grep -q LOWER_UP 2>&1 4236fb29d29Schristos if [ $? -eq 0 ]; then 4246fb29d29Schristos break; 4256fb29d29Schristos fi 4266fb29d29Schristos sleep 1 4276fb29d29Schristos done 4286fb29d29Schristos 4296fb29d29Schristos # flush any stale global permanent IPs from interface 4306fb29d29Schristos ${ip} -6 addr flush dev ${interface} scope global permanent 4316fb29d29Schristos 4326fb29d29Schristos # Wait for duplicate address detection for this interface if the 4336fb29d29Schristos # --dad-wait-time parameter has been specified and is greater than 4346fb29d29Schristos # zero. 4356fb29d29Schristos if [ ${dad_wait_time} -gt 0 ]; then 4366fb29d29Schristos # Check if any IPv6 address on this interface is marked as 4376fb29d29Schristos # tentative. 4386fb29d29Schristos ${ip} addr show ${interface} | grep inet6 | grep tentative \ 4396fb29d29Schristos &> /dev/null 4406fb29d29Schristos if [ $? -eq 0 ]; then 4416fb29d29Schristos # Wait for duplicate address detection to complete or for 4426fb29d29Schristos # the timeout specified as --dad-wait-time. 4436fb29d29Schristos for i in $(seq 0 $dad_wait_time) 4446fb29d29Schristos do 4456fb29d29Schristos # We're going to poll for the tentative flag every second. 4466fb29d29Schristos sleep 1 4476fb29d29Schristos ${ip} addr show ${interface} | grep inet6 | grep tentative \ 4486fb29d29Schristos &> /dev/null 4496fb29d29Schristos if [ $? -ne 0 ]; then 4506fb29d29Schristos break; 4516fb29d29Schristos fi 4526fb29d29Schristos done 4536fb29d29Schristos fi 4546fb29d29Schristos fi 4556fb29d29Schristos 4566fb29d29Schristos ;; 4576fb29d29Schristos 4586fb29d29Schristos BOUND6|RENEW6|REBIND6) 4596fb29d29Schristos if [ "${new_ip6_address}" ] && [ "${new_ip6_prefixlen}" ]; then 4606fb29d29Schristos # set leased IP 4616fb29d29Schristos add_ipv6_addr_with_DAD 4626fb29d29Schristos fi 4636fb29d29Schristos 4646fb29d29Schristos # update /etc/resolv.conf 4656fb29d29Schristos if [ "${reason}" = BOUND6 ] || 4666fb29d29Schristos [ "${new_dhcp6_name_servers}" != "${old_dhcp6_name_servers}" ] || 4676fb29d29Schristos [ "${new_dhcp6_domain_search}" != "${old_dhcp6_domain_search}" ]; then 4686fb29d29Schristos make_resolv_conf 4696fb29d29Schristos fi 4706fb29d29Schristos 4716fb29d29Schristos ;; 4726fb29d29Schristos 4736fb29d29Schristos DEPREF6) 4746fb29d29Schristos if [ -z "${cur_ip6_prefixlen}" ]; then 4756fb29d29Schristos exit_with_hooks 2 4766fb29d29Schristos fi 4776fb29d29Schristos 4786fb29d29Schristos # set preferred lifetime of leased IP to 0 4796fb29d29Schristos ${ip} -6 addr change ${cur_ip6_address}/${cur_ip6_prefixlen} \ 4806fb29d29Schristos dev ${interface} scope global preferred_lft 0 4816fb29d29Schristos 4826fb29d29Schristos ;; 4836fb29d29Schristos 4846fb29d29Schristos EXPIRE6|RELEASE6|STOP6) 4856fb29d29Schristos if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then 4866fb29d29Schristos exit_with_hooks 2 4876fb29d29Schristos fi 4886fb29d29Schristos 4896fb29d29Schristos # delete leased IP 4906fb29d29Schristos ${ip} -6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \ 4916fb29d29Schristos dev ${interface} 4926fb29d29Schristos 4936fb29d29Schristos ;; 4946fb29d29Schristosesac 4956fb29d29Schristos 4966fb29d29Schristosexit_with_hooks 0 497