1 1.1 christos #!/bin/bash 2 1.1 christos # dhclient-script for Linux. Dan Halbert, March, 1997. 3 1.1 christos # Updated for Linux 2.[12] by Brian J. Murrell, January 1999. 4 1.1 christos # No guarantees about this. I'm a novice at the details of Linux 5 1.1 christos # networking. 6 1.1 christos 7 1.1 christos # Notes: 8 1.1 christos 9 1.1 christos # 0. This script is based on the netbsd script supplied with dhcp-970306. 10 1.1 christos 11 1.1 christos # 1. ifconfig down apparently deletes all relevant routes and flushes 12 1.1 christos # the arp cache, so this doesn't need to be done explicitly. 13 1.1 christos 14 1.1 christos # 2. The alias address handling here has not been tested AT ALL. 15 1.1 christos # I'm just going by the doc of modern Linux ip aliasing, which uses 16 1.1 christos # notations like eth0:0, eth0:1, for each alias. 17 1.1 christos 18 1.1 christos # 3. I have to calculate the network address, and calculate the broadcast 19 1.1 christos # address if it is not supplied. This might be much more easily done 20 1.1 christos # by the dhclient C code, and passed on. 21 1.1 christos 22 1.1 christos # 4. TIMEOUT not tested. ping has a flag I don't know, and I'm suspicious 23 1.1 christos # of the $1 in its args. 24 1.1 christos 25 1.1 christos # 5. Script refresh in 2017. The aliasing code was too convoluted and needs 26 1.1 christos # to go away. Migrated DHCPv4 script to ip command from iproute2 suite. 27 1.1 christos # This is based on Debian script with some tweaks. ifconfig is no longer 28 1.1 christos # used. Everything is done using ip tool from ip-route2. 29 1.1 christos 30 1.1 christos # 'ip' just looks too weird. Also, we now have unit-tests! Those unit-tests 31 1.1 christos # overwirte this line to use a fake ip-echo tool. It's also convenient 32 1.1 christos # if your system holds ip tool in a non-standard location. 33 1.1 christos ip=/sbin/ip 34 1.1 christos 35 1.1 christos # update /etc/resolv.conf based on received values 36 1.1 christos # This updated version mostly follows Debian script by Andrew Pollock et al. 37 1.1 christos make_resolv_conf() { 38 1.1 christos local new_resolv_conf 39 1.1 christos 40 1.1 christos # DHCPv4 41 1.1 christos if [ -n "$new_domain_search" ] || [ -n "$new_domain_name" ] || 42 1.1 christos [ -n "$new_domain_name_servers" ]; then 43 1.1 christos new_resolv_conf=/etc/resolv.conf.dhclient-new 44 1.1 christos rm -f $new_resolv_conf 45 1.1 christos 46 1.1 christos if [ -n "$new_domain_name" ]; then 47 1.1 christos echo domain ${new_domain_name%% *} >>$new_resolv_conf 48 1.1 christos fi 49 1.1 christos 50 1.1 christos if [ -n "$new_domain_search" ]; then 51 1.1 christos if [ -n "$new_domain_name" ]; then 52 1.1 christos domain_in_search_list="" 53 1.1 christos for domain in $new_domain_search; do 54 1.1 christos if [ "$domain" = "${new_domain_name}" ] || 55 1.1 christos [ "$domain" = "${new_domain_name}." ]; then 56 1.1 christos domain_in_search_list="Yes" 57 1.1 christos fi 58 1.1 christos done 59 1.1 christos if [ -z "$domain_in_search_list" ]; then 60 1.1 christos new_domain_search="$new_domain_name $new_domain_search" 61 1.1 christos fi 62 1.1 christos fi 63 1.1 christos echo "search ${new_domain_search}" >> $new_resolv_conf 64 1.1 christos elif [ -n "$new_domain_name" ]; then 65 1.1 christos echo "search ${new_domain_name}" >> $new_resolv_conf 66 1.1 christos fi 67 1.1 christos 68 1.1 christos if [ -n "$new_domain_name_servers" ]; then 69 1.1 christos for nameserver in $new_domain_name_servers; do 70 1.1 christos echo nameserver $nameserver >>$new_resolv_conf 71 1.1 christos done 72 1.1 christos else # keep 'old' nameservers 73 1.1 christos sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf 74 1.1 christos fi 75 1.1 christos 76 1.1 christos if [ -f /etc/resolv.conf ]; then 77 1.1 christos chown --reference=/etc/resolv.conf $new_resolv_conf 78 1.1 christos chmod --reference=/etc/resolv.conf $new_resolv_conf 79 1.1 christos fi 80 1.1 christos mv -f $new_resolv_conf /etc/resolv.conf 81 1.1 christos # DHCPv6 82 1.1 christos elif [ -n "$new_dhcp6_domain_search" ] || [ -n "$new_dhcp6_name_servers" ]; then 83 1.1 christos new_resolv_conf=/etc/resolv.conf.dhclient-new 84 1.1 christos rm -f $new_resolv_conf 85 1.1 christos 86 1.1 christos if [ -n "$new_dhcp6_domain_search" ]; then 87 1.1 christos echo "search ${new_dhcp6_domain_search}" >> $new_resolv_conf 88 1.1 christos fi 89 1.1 christos 90 1.1 christos if [ -n "$new_dhcp6_name_servers" ]; then 91 1.1 christos for nameserver in $new_dhcp6_name_servers; do 92 1.1 christos # append %interface to link-local-address nameservers 93 1.1 christos if [ "${nameserver##fe80::}" != "$nameserver" ] || 94 1.1 christos [ "${nameserver##FE80::}" != "$nameserver" ]; then 95 1.1 christos nameserver="${nameserver}%${interface}" 96 1.1 christos fi 97 1.1 christos echo nameserver $nameserver >>$new_resolv_conf 98 1.1 christos done 99 1.1 christos else # keep 'old' nameservers 100 1.1 christos sed -n /^\w*[Nn][Aa][Mm][Ee][Ss][Ee][Rr][Vv][Ee][Rr]/p /etc/resolv.conf >>$new_resolv_conf 101 1.1 christos fi 102 1.1 christos 103 1.1 christos if [ -f /etc/resolv.conf ]; then 104 1.1 christos chown --reference=/etc/resolv.conf $new_resolv_conf 105 1.1 christos chmod --reference=/etc/resolv.conf $new_resolv_conf 106 1.1 christos fi 107 1.1 christos mv -f $new_resolv_conf /etc/resolv.conf 108 1.1 christos fi 109 1.1 christos } 110 1.1 christos 111 1.1 christos # set host name 112 1.1 christos set_hostname() { 113 1.1 christos local current_hostname 114 1.1 christos 115 1.1 christos if [ -n "$new_host_name" ]; then 116 1.1 christos current_hostname=$(hostname) 117 1.1 christos 118 1.1 christos # current host name is empty, '(none)' or 'localhost' or differs from new one from DHCP 119 1.1 christos if [ -z "$current_hostname" ] || 120 1.1 christos [ "$current_hostname" = '(none)' ] || 121 1.1 christos [ "$current_hostname" = 'localhost' ] || 122 1.1 christos [ "$current_hostname" = "$old_host_name" ]; then 123 1.1 christos if [ "$new_host_name" != "$old_host_name" ]; then 124 1.1 christos hostname "$new_host_name" 125 1.1 christos fi 126 1.1 christos fi 127 1.1 christos fi 128 1.1 christos } 129 1.1 christos 130 1.1 christos # run given script 131 1.1 christos run_hook() { 132 1.1 christos local script 133 1.1 christos local exit_status 134 1.1 christos script="$1" 135 1.1 christos 136 1.1 christos if [ -f $script ]; then 137 1.1 christos . $script 138 1.1 christos fi 139 1.1 christos 140 1.1 christos if [ -n "$exit_status" ] && [ "$exit_status" -ne 0 ]; then 141 1.1 christos logger -p daemon.err "$script returned non-zero exit status $exit_status" 142 1.1 christos fi 143 1.1 christos 144 1.1 christos return $exit_status 145 1.1 christos } 146 1.1 christos 147 1.1 christos # run scripts in given directory 148 1.1 christos run_hookdir() { 149 1.1 christos local dir 150 1.1 christos local exit_status 151 1.1 christos dir="$1" 152 1.1 christos 153 1.1 christos if [ -d "$dir" ]; then 154 1.1 christos for script in $(run-parts --list $dir); do 155 1.1 christos run_hook $script || true 156 1.1 christos exit_status=$? 157 1.1 christos done 158 1.1 christos fi 159 1.1 christos 160 1.1 christos return $exit_status 161 1.1 christos } 162 1.1 christos 163 1.1 christos # Must be used on exit. Invokes the local dhcp client exit hooks, if any. 164 1.1 christos exit_with_hooks() { 165 1.1 christos exit_status=$1 166 1.1 christos 167 1.1 christos # Source the documented exit-hook script, if it exists 168 1.1 christos if ! run_hook /etc/dhclient-exit-hooks; then 169 1.1 christos exit_status=$? 170 1.1 christos fi 171 1.1 christos 172 1.1 christos # Now run scripts in the Debian-specific directory. 173 1.1 christos if ! run_hookdir /etc/dhclient-exit-hooks.d; then 174 1.1 christos exit_status=$? 175 1.1 christos fi 176 1.1 christos 177 1.1 christos exit $exit_status 178 1.1 christos } 179 1.1 christos 180 1.1 christos # This function was largely borrowed from dhclient-script that 181 1.1 christos # ships with Centos, authored by Jiri Popelka and David Cantrell 182 1.1 christos # of Redhat. Thanks guys. 183 1.1 christos add_ipv6_addr_with_DAD() { 184 1.1 christos ${ip} -6 addr replace ${new_ip6_address}/${new_ip6_prefixlen} \ 185 1.1 christos dev ${interface} scope global valid_lft ${new_max_life} \ 186 1.1 christos preferred_lft ${new_preferred_life} 187 1.1 christos 188 1.1 christos if [ ${dad_wait_time} -le 0 ] 189 1.1 christos then 190 1.1 christos # if we're not waiting for DAD, assume we're good 191 1.1 christos return 0 192 1.1 christos fi 193 1.1 christos 194 1.1 christos # Repeatedly test whether newly added address passed 195 1.1 christos # duplicate address detection (DAD) 196 1.1 christos for i in $(seq 1 ${dad_wait_time}); do 197 1.1 christos sleep 1 # give the DAD some time 198 1.1 christos 199 1.1 christos addr=$(${ip} -6 addr show dev ${interface} \ 200 1.1 christos | grep ${new_ip6_address}/${new_ip6_prefixlen}) 201 1.1 christos 202 1.1 christos # tentative flag == DAD is still not complete 203 1.1 christos tentative=$(echo "${addr}" | grep tentative) 204 1.1 christos # dadfailed flag == address is already in use somewhere else 205 1.1 christos dadfailed=$(echo "${addr}" | grep dadfailed) 206 1.1 christos 207 1.1 christos if [ -n "${dadfailed}" ] ; then 208 1.1 christos # address was added with valid_lft/preferred_lft 'forever', 209 1.1 christos # remove it 210 1.1 christos ${ip} -6 addr del ${new_ip6_address}/${new_ip6_prefixlen} \ 211 1.1 christos dev ${interface} 212 1.1 christos 213 1.1 christos exit_with_hooks 3 214 1.1 christos fi 215 1.1 christos 216 1.1 christos if [ -z "${tentative}" ] ; then 217 1.1 christos if [ -n "${addr}" ]; then 218 1.1 christos # DAD is over 219 1.1 christos return 0 220 1.1 christos else 221 1.1 christos # address was auto-removed (or not added at all) 222 1.1 christos exit_with_hooks 3 223 1.1 christos fi 224 1.1 christos fi 225 1.1 christos done 226 1.1 christos 227 1.1 christos return 0 228 1.1 christos } 229 1.1 christos 230 1.1 christos # Invoke the local dhcp client enter hooks, if they exist. 231 1.1 christos run_hook /etc/dhclient-enter-hooks 232 1.1 christos run_hookdir /etc/dhclient-enter-hooks.d 233 1.1 christos 234 1.1 christos # Execute the operation 235 1.1 christos case "$reason" in 236 1.1 christos 237 1.1 christos ### DHCPv4 Handlers 238 1.1 christos 239 1.1 christos MEDIUM|ARPCHECK|ARPSEND) 240 1.1 christos # Do nothing 241 1.1 christos ;; 242 1.1 christos PREINIT) 243 1.1 christos # The DHCP client is requesting that an interface be 244 1.1 christos # configured as required in order to send packets prior to 245 1.1 christos # receiving an actual address. - dhclient-script(8) 246 1.1 christos 247 1.1 christos # ensure interface is up 248 1.1 christos ${ip} link set dev ${interface} up 249 1.1 christos 250 1.1 christos if [ -n "$alias_ip_address" ]; then 251 1.1 christos # flush alias IP from interface 252 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface}:0 253 1.1 christos fi 254 1.1 christos 255 1.1 christos ;; 256 1.1 christos 257 1.1 christos BOUND|RENEW|REBIND|REBOOT) 258 1.1 christos set_hostname 259 1.1 christos 260 1.1 christos if [ -n "$old_ip_address" ] && [ -n "$alias_ip_address" ] && 261 1.1 christos [ "$alias_ip_address" != "$old_ip_address" ]; then 262 1.1 christos # alias IP may have changed => flush it 263 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface}:0 264 1.1 christos fi 265 1.1 christos 266 1.1 christos if [ -n "$old_ip_address" ] && 267 1.1 christos [ "$old_ip_address" != "$new_ip_address" ]; then 268 1.1 christos # leased IP has changed => flush it 269 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface} 270 1.1 christos fi 271 1.1 christos 272 1.1 christos if [ -z "$old_ip_address" ] || 273 1.1 christos [ "$old_ip_address" != "$new_ip_address" ] || 274 1.1 christos [ "$reason" = "BOUND" ] || [ "$reason" = "REBOOT" ]; then 275 1.1 christos # new IP has been leased or leased IP changed => set it 276 1.1 christos ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \ 277 1.1 christos ${new_broadcast_address:+broadcast $new_broadcast_address} \ 278 1.1 christos dev ${interface} label ${interface} 279 1.1 christos 280 1.1 christos if [ -n "$new_interface_mtu" ]; then 281 1.1 christos # set MTU 282 1.1 christos ${ip} link set dev ${interface} mtu ${new_interface_mtu} 283 1.1 christos fi 284 1.1 christos 285 1.1 christos # if we have $new_rfc3442_classless_static_routes then we have to 286 1.1 christos # ignore $new_routers entirely 287 1.1 christos if [ ! "$new_rfc3442_classless_static_routes" ]; then 288 1.1 christos # set if_metric if IF_METRIC is set or there's more than one router 289 1.1 christos if_metric="$IF_METRIC" 290 1.1 christos if [ "${new_routers%% *}" != "${new_routers}" ]; then 291 1.1 christos if_metric=${if_metric:-1} 292 1.1 christos fi 293 1.1 christos 294 1.1 christos for router in $new_routers; do 295 1.1 christos if [ "$new_subnet_mask" = "255.255.255.255" ]; then 296 1.1 christos # point-to-point connection => set explicit route 297 1.1 christos ${ip} -4 route add ${router} dev $interface >/dev/null 2>&1 298 1.1 christos fi 299 1.1 christos 300 1.1 christos # set default route 301 1.1 christos ${ip} -4 route add default via ${router} dev ${interface} \ 302 1.1 christos ${if_metric:+metric $if_metric} >/dev/null 2>&1 303 1.1 christos 304 1.1 christos if [ -n "$if_metric" ]; then 305 1.1 christos if_metric=$((if_metric+1)) 306 1.1 christos fi 307 1.1 christos done 308 1.1 christos fi 309 1.1 christos fi 310 1.1 christos 311 1.1 christos if [ -n "$alias_ip_address" ] && 312 1.1 christos [ "$new_ip_address" != "$alias_ip_address" ]; then 313 1.1 christos # separate alias IP given, which may have changed 314 1.1 christos # => flush it, set it & add host route to it 315 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface}:0 316 1.1 christos ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 317 1.1 christos dev ${interface} label ${interface}:0 318 1.1 christos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 319 1.1 christos fi 320 1.1 christos 321 1.1 christos # update /etc/resolv.conf 322 1.1 christos make_resolv_conf 323 1.1 christos 324 1.1 christos ;; 325 1.1 christos 326 1.1 christos EXPIRE|FAIL|RELEASE|STOP) 327 1.1 christos if [ -n "$alias_ip_address" ]; then 328 1.1 christos # flush alias IP 329 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface}:0 330 1.1 christos fi 331 1.1 christos 332 1.1 christos if [ -n "$old_ip_address" ]; then 333 1.1 christos # flush leased IP 334 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface} 335 1.1 christos fi 336 1.1 christos 337 1.1 christos if [ -n "$alias_ip_address" ]; then 338 1.1 christos # alias IP given => set it & add host route to it 339 1.1 christos ${ip} -4 addr add ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 340 1.1 christos dev ${interface} label ${interface}:0 341 1.1 christos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 342 1.1 christos fi 343 1.1 christos 344 1.1 christos ;; 345 1.1 christos 346 1.1 christos TIMEOUT) 347 1.1 christos if [ -n "$alias_ip_address" ]; then 348 1.1 christos # flush alias IP 349 1.1 christos ${ip} -4 addr flush dev ${interface} label ${interface}:0 350 1.1 christos fi 351 1.1 christos 352 1.1 christos # set IP from recorded lease 353 1.1 christos ${ip} -4 addr add ${new_ip_address}${new_subnet_mask:+/$new_subnet_mask} \ 354 1.1 christos ${new_broadcast_address:+broadcast $new_broadcast_address} \ 355 1.1 christos dev ${interface} label ${interface} 356 1.1 christos 357 1.1 christos if [ -n "$new_interface_mtu" ]; then 358 1.1 christos # set MTU 359 1.1 christos ${ip} link set dev ${interface} mtu ${new_interface_mtu} 360 1.1 christos fi 361 1.1 christos 362 1.1 christos # if there is no router recorded in the lease or the 1st router answers pings 363 1.1 christos if [ -z "$new_routers" ] || ping -q -c 1 "${new_routers%% *}"; then 364 1.1 christos # if we have $new_rfc3442_classless_static_routes then we have to 365 1.1 christos # ignore $new_routers entirely 366 1.1 christos if [ ! "$new_rfc3442_classless_static_routes" ]; then 367 1.1 christos if [ -n "$alias_ip_address" ] && 368 1.1 christos [ "$new_ip_address" != "$alias_ip_address" ]; then 369 1.1 christos # separate alias IP given => set up the alias IP & add host route to it 370 1.1 christos ${ip} -4 addr add \ 371 1.1 christos ${alias_ip_address}${alias_subnet_mask:+/$alias_subnet_mask} \ 372 1.1 christos dev ${interface} label ${interface}:0 373 1.1 christos ${ip} -4 route add ${alias_ip_address} dev ${interface} >/dev/null 2>&1 374 1.1 christos fi 375 1.1 christos 376 1.1 christos # set if_metric if IF_METRIC is set or there's more than one router 377 1.1 christos if_metric="$IF_METRIC" 378 1.1 christos if [ "${new_routers%% *}" != "${new_routers}" ]; then 379 1.1 christos if_metric=${if_metric:-1} 380 1.1 christos fi 381 1.1 christos 382 1.1 christos # set default route 383 1.1 christos for router in $new_routers; do 384 1.1 christos ${ip} -4 route add default via ${router} dev ${interface} \ 385 1.1 christos ${if_metric:+metric $if_metric} >/dev/null 2>&1 386 1.1 christos 387 1.1 christos if [ -n "$if_metric" ]; then 388 1.1 christos if_metric=$((if_metric+1)) 389 1.1 christos fi 390 1.1 christos done 391 1.1 christos fi 392 1.1 christos 393 1.1 christos # update /etc/resolv.conf 394 1.1 christos make_resolv_conf 395 1.1 christos else 396 1.1 christos # flush all IPs from interface 397 1.1 christos ip -4 addr flush dev ${interface} 398 1.1 christos exit_with_hooks 2 399 1.1 christos fi 400 1.1 christos 401 1.1 christos ;; 402 1.1 christos 403 1.1.1.2 christos V6ONLY) 404 1.1.1.2 christos if [ -n "$old_ip_address" ]; then 405 1.1.1.2 christos # flush leased IP 406 1.1.1.2 christos ${ip} -4 addr flush dev ${interface} label ${interface} 407 1.1.1.2 christos fi 408 1.1.1.2 christos 409 1.1.1.2 christos ;; 410 1.1.1.2 christos 411 1.1 christos ### DHCPv6 Handlers 412 1.1 christos # TODO handle prefix change: ?based on ${old_ip6_prefix} and ${new_ip6_prefix}? 413 1.1 christos 414 1.1 christos PREINIT6) 415 1.1 christos # ensure interface is up 416 1.1 christos ${ip} link set ${interface} up 417 1.1 christos 418 1.1 christos # We need to give the kernel some time to active interface 419 1.1 christos interface_up_wait_time=5 420 1.1 christos for i in $(seq 0 ${interface_up_wait_time}) 421 1.1 christos do 422 1.1.1.2 christos ${ip} link show dev ${interface} | grep -q LOWER_UP 2>&1 423 1.1 christos if [ $? -eq 0 ]; then 424 1.1 christos break; 425 1.1 christos fi 426 1.1 christos sleep 1 427 1.1 christos done 428 1.1 christos 429 1.1 christos # flush any stale global permanent IPs from interface 430 1.1 christos ${ip} -6 addr flush dev ${interface} scope global permanent 431 1.1 christos 432 1.1 christos # Wait for duplicate address detection for this interface if the 433 1.1 christos # --dad-wait-time parameter has been specified and is greater than 434 1.1 christos # zero. 435 1.1 christos if [ ${dad_wait_time} -gt 0 ]; then 436 1.1 christos # Check if any IPv6 address on this interface is marked as 437 1.1 christos # tentative. 438 1.1 christos ${ip} addr show ${interface} | grep inet6 | grep tentative \ 439 1.1 christos &> /dev/null 440 1.1 christos if [ $? -eq 0 ]; then 441 1.1 christos # Wait for duplicate address detection to complete or for 442 1.1 christos # the timeout specified as --dad-wait-time. 443 1.1 christos for i in $(seq 0 $dad_wait_time) 444 1.1 christos do 445 1.1 christos # We're going to poll for the tentative flag every second. 446 1.1 christos sleep 1 447 1.1 christos ${ip} addr show ${interface} | grep inet6 | grep tentative \ 448 1.1 christos &> /dev/null 449 1.1 christos if [ $? -ne 0 ]; then 450 1.1 christos break; 451 1.1 christos fi 452 1.1 christos done 453 1.1 christos fi 454 1.1 christos fi 455 1.1 christos 456 1.1 christos ;; 457 1.1 christos 458 1.1 christos BOUND6|RENEW6|REBIND6) 459 1.1 christos if [ "${new_ip6_address}" ] && [ "${new_ip6_prefixlen}" ]; then 460 1.1 christos # set leased IP 461 1.1 christos add_ipv6_addr_with_DAD 462 1.1 christos fi 463 1.1 christos 464 1.1 christos # update /etc/resolv.conf 465 1.1 christos if [ "${reason}" = BOUND6 ] || 466 1.1 christos [ "${new_dhcp6_name_servers}" != "${old_dhcp6_name_servers}" ] || 467 1.1 christos [ "${new_dhcp6_domain_search}" != "${old_dhcp6_domain_search}" ]; then 468 1.1 christos make_resolv_conf 469 1.1 christos fi 470 1.1 christos 471 1.1 christos ;; 472 1.1 christos 473 1.1 christos DEPREF6) 474 1.1 christos if [ -z "${cur_ip6_prefixlen}" ]; then 475 1.1 christos exit_with_hooks 2 476 1.1 christos fi 477 1.1 christos 478 1.1 christos # set preferred lifetime of leased IP to 0 479 1.1 christos ${ip} -6 addr change ${cur_ip6_address}/${cur_ip6_prefixlen} \ 480 1.1 christos dev ${interface} scope global preferred_lft 0 481 1.1 christos 482 1.1 christos ;; 483 1.1 christos 484 1.1 christos EXPIRE6|RELEASE6|STOP6) 485 1.1 christos if [ -z "${old_ip6_address}" ] || [ -z "${old_ip6_prefixlen}" ]; then 486 1.1 christos exit_with_hooks 2 487 1.1 christos fi 488 1.1 christos 489 1.1 christos # delete leased IP 490 1.1 christos ${ip} -6 addr del ${old_ip6_address}/${old_ip6_prefixlen} \ 491 1.1 christos dev ${interface} 492 1.1 christos 493 1.1 christos ;; 494 1.1 christos esac 495 1.1 christos 496 1.1 christos exit_with_hooks 0 497