network.subr revision 223506
11195Srgrimes# 22906Swollman# Copyright (c) 2003 The FreeBSD Project. All rights reserved. 337Srgrimes# 437Srgrimes# Redistribution and use in source and binary forms, with or without 537Srgrimes# modification, are permitted provided that the following conditions 6147Srgrimes# are met: 7147Srgrimes# 1. Redistributions of source code must retain the above copyright 83017Srgrimes# notice, this list of conditions and the following disclaimer. 93017Srgrimes# 2. Redistributions in binary form must reproduce the above copyright 103017Srgrimes# notice, this list of conditions and the following disclaimer in the 113017Srgrimes# documentation and/or other materials provided with the distribution. 123017Srgrimes# 133017Srgrimes# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 141734Sjkh# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 151734Sjkh# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1637Srgrimes# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 1737Srgrimes# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1837Srgrimes# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1937Srgrimes# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 201773Sjkh# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21147Srgrimes# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22147Srgrimes# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 232779Srgrimes# SUCH DAMAGE. 242779Srgrimes# 252779Srgrimes# $FreeBSD: head/etc/network.subr 223506 2011-06-24 14:56:38Z pluknet $ 261767Sjkh# 272570Srgrimes 282570Srgrimes# 292570Srgrimes# Subroutines commonly used from network startup scripts. 302570Srgrimes# Requires that rc.conf be loaded first. 312570Srgrimes# 322570Srgrimes 332570Srgrimes# ifn_start ifn 342570Srgrimes# Bring up and configure an interface. If some configuration is 351782Sjkh# applied print the interface configuration. 361782Sjkh# 37491Srgrimesifn_start() 3837Srgrimes{ 3937Srgrimes local ifn cfg 4037Srgrimes ifn="$1" 4137Srgrimes cfg=1 4237Srgrimes 43263Srgrimes [ -z "$ifn" ] && err 1 "ifn_start called without an interface" 442779Srgrimes 452779Srgrimes ifscript_up ${ifn} && cfg=0 46993Srgrimes ifconfig_up ${ifn} && cfg=0 47277Srgrimes afexists inet && ipv4_up ${ifn} && cfg=0 482779Srgrimes afexists inet6 && ipv6_up ${ifn} && cfg=0 49284Srgrimes afexists ipx && ipx_up ${ifn} && cfg=0 50463Srgrimes childif_create ${ifn} && cfg=0 511205Srgrimes 522779Srgrimes return $cfg 532779Srgrimes} 54284Srgrimes 55284Srgrimes# ifn_stop ifn 56284Srgrimes# Shutdown and de-configure an interface. If action is taken 57284Srgrimes# print the interface name. 58284Srgrimes# 591285Srgrimesifn_stop() 60284Srgrimes{ 611767Sjkh local ifn cfg 621285Srgrimes ifn="$1" 632499Sgpalmer cfg=1 641285Srgrimes 65284Srgrimes [ -z "$ifn" ] && err 1 "ifn_stop called without an interface" 661371Srgrimes 671371Srgrimes afexists ipx && ipx_down ${ifn} && cfg=0 681194Srgrimes afexists inet6 && ipv6_down ${ifn} && cfg=0 69358Srgrimes afexists inet && ipv4_down ${ifn} && cfg=0 70358Srgrimes ifconfig_down ${ifn} && cfg=0 71412Salm ifscript_down ${ifn} && cfg=0 72358Srgrimes childif_destroy ${ifn} && cfg=0 73452Srgrimes 74358Srgrimes return $cfg 751194Srgrimes} 761767Sjkh 771194Srgrimes# ifconfig_up if 782779Srgrimes# Evaluate ifconfig(8) arguments for interface $if and 791194Srgrimes# run ifconfig(8) with those arguments. It returns 0 if 801194Srgrimes# arguments were found and executed or 1 if the interface 811194Srgrimes# had no arguments. Pseudo arguments DHCP and WPA are handled 821194Srgrimes# here. 831194Srgrimes# 841194Srgrimesifconfig_up() 851194Srgrimes{ 861194Srgrimes local _cfg _ipv6_opts ifconfig_args 871194Srgrimes _cfg=1 881194Srgrimes 891194Srgrimes # Make sure lo0 always comes up. 901194Srgrimes if [ "$1" = "lo0" ]; then 911194Srgrimes _cfg=0 922779Srgrimes fi 931194Srgrimes 941194Srgrimes # ifconfig_IF 951243Srgrimes ifconfig_args=`ifconfig_getargs $1` 96263Srgrimes if [ -n "${ifconfig_args}" ]; then 97358Srgrimes eval ifconfig $1 ${ifconfig_args} 981194Srgrimes _cfg=0 991194Srgrimes fi 1001194Srgrimes 1011773Sjkh # inet6 specific 1022499Sgpalmer if afexists inet6; then 1031194Srgrimes if checkyesno ipv6_activate_all_interfaces; then 104452Srgrimes _ipv6_opts="-ifdisabled" 1051194Srgrimes elif [ "$1" != "lo0" ]; then 1061194Srgrimes _ipv6_opts="ifdisabled" 107358Srgrimes fi 1081194Srgrimes 1092779Srgrimes # backward compatibility: $ipv6_enable 1102779Srgrimes case $ipv6_enable in 1112779Srgrimes [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 1122779Srgrimes _ipv6_opts="${_ipv6_opts} accept_rtadv" 1132779Srgrimes ;; 1142779Srgrimes esac 1151243Srgrimes 1161194Srgrimes if [ -n "${_ipv6_opts}" ]; then 1171194Srgrimes ifconfig $1 inet6 ${_ipv6_opts} 1181243Srgrimes fi 1191243Srgrimes 120284Srgrimes # ifconfig_IF_ipv6 1212570Srgrimes ifconfig_args=`ifconfig_getargs $1 ipv6` 1222570Srgrimes if [ -n "${ifconfig_args}" ]; then 123372Srgrimes ifconfig $1 inet6 -ifdisabled 1242570Srgrimes ifconfig $1 ${ifconfig_args} 1252779Srgrimes _cfg=0 1262779Srgrimes fi 127347Srgrimes 1281767Sjkh # backward compatiblity: $ipv6_ifconfig_IF 12937Srgrimes ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF` 1302538Spst if [ -n "${ifconfig_args}" ]; then 131347Srgrimes warn "\$ipv6_ifconfig_$1 is obsolete." \ 1322538Spst " Use ifconfig_$1_ipv6 instead." 133355Srgrimes ifconfig $1 inet6 -ifdisabled 134372Srgrimes ifconfig $1 inet6 ${ifconfig_args} 135347Srgrimes _cfg=0 136355Srgrimes fi 137347Srgrimes fi 1382538Spst 1392538Spst if [ ${_cfg} -eq 0 ]; then 1402538Spst ifconfig $1 up 1412538Spst fi 1422538Spst 143372Srgrimes if wpaif $1; then 144347Srgrimes /etc/rc.d/wpa_supplicant start $1 145355Srgrimes _cfg=0 # XXX: not sure this should count 146347Srgrimes fi 147347Srgrimes 1482538Spst if dhcpif $1; then 149147Srgrimes if [ $_cfg -ne 0 ] ; then 1501759Sjkh ifconfig $1 up 1511759Sjkh fi 1521759Sjkh if syncdhcpif $1; then 1531759Sjkh /etc/rc.d/dhclient start $1 1541759Sjkh fi 1551731Sjkh _cfg=0 1561759Sjkh fi 1571731Sjkh 1581759Sjkh return $_cfg 1591759Sjkh} 16037Srgrimes 1611759Sjkh# ifconfig_down if 162347Srgrimes# returns 1 if wpa_supplicant or dhclient was stopped or 1631759Sjkh# the interface exists. 164347Srgrimes# 1651731Sjkhifconfig_down() 1661731Sjkh{ 16737Srgrimes local _cfg 1681731Sjkh _cfg=1 16937Srgrimes 1701731Sjkh if wpaif $1; then 17137Srgrimes /etc/rc.d/wpa_supplicant stop $1 1721731Sjkh _cfg=0 17337Srgrimes fi 17437Srgrimes 17537Srgrimes if dhcpif $1; then 17637Srgrimes /etc/rc.d/dhclient stop $1 1771731Sjkh _cfg=0 1781731Sjkh fi 1791731Sjkh 1801731Sjkh if ifexists $1; then 18137Srgrimes ifconfig $1 down 18237Srgrimes _cfg=0 183147Srgrimes fi 184147Srgrimes 18537Srgrimes return $_cfg 186147Srgrimes} 18737Srgrimes 18837Srgrimes# get_if_var if var [default] 18937Srgrimes# Return the value of the pseudo-hash corresponding to $if where 190288Srgrimes# $var is a string containg the sub-string "IF" which will be 191288Srgrimes# replaced with $if after the characters defined in _punct are 192147Srgrimes# replaced with '_'. If the variable is unset, replace it with 19337Srgrimes# $default if given. 194147Srgrimesget_if_var() 195147Srgrimes{ 19637Srgrimes local _if _punct _punct_c _var _default prefix suffix 1971759Sjkh 1981759Sjkh if [ $# -ne 2 -a $# -ne 3 ]; then 1991759Sjkh err 3 'USAGE: get_if_var name var [default]' 2001759Sjkh fi 201347Srgrimes 2022538Spst _if=$1 2032538Spst _punct=". - / +" 204347Srgrimes for _punct_c in $_punct; do 2052538Spst _if=`ltr ${_if} ${_punct_c} '_'` 2061775Sjkh done 207347Srgrimes _var=$2 2081759Sjkh _default=$3 209355Srgrimes 210277Srgrimes prefix=${_var%%IF*} 2111126Srgrimes suffix=${_var##*IF} 2121126Srgrimes eval echo \${${prefix}${_if}${suffix}-${_default}} 2131731Sjkh} 214238Sroot 2151759Sjkh# _ifconfig_getargs if [af] 2161731Sjkh# Echos the arguments for the supplied interface to stdout. 2171759Sjkh# returns 1 if empty. In general, ifconfig_getargs should be used 218333Srgrimes# outside this file. 2191759Sjkh_ifconfig_getargs() 2201759Sjkh{ 221168Srgrimes local _ifn _af 222333Srgrimes _ifn=$1 2231759Sjkh _af=${2+_$2} 2241759Sjkh 225333Srgrimes if [ -z "$_ifn" ]; then 22637Srgrimes return 1 2271731Sjkh fi 2282619Srgrimes 2291782Sjkh get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT" 2302619Srgrimes} 2311782Sjkh 2321731Sjkh# ifconfig_getargs if [af] 2331731Sjkh# Takes the result from _ifconfig_getargs and removes pseudo 2341731Sjkh# args such as DHCP and WPA. 2352570Srgrimesifconfig_getargs() 2362570Srgrimes{ 2371731Sjkh local _tmpargs _arg _args 2382570Srgrimes _tmpargs=`_ifconfig_getargs $1 $2` 2392570Srgrimes if [ $? -eq 1 ]; then 2401731Sjkh return 1 2412570Srgrimes fi 2422570Srgrimes _args= 2431731Sjkh 24437Srgrimes for _arg in $_tmpargs; do 2451759Sjkh case $_arg in 2461759Sjkh [Dd][Hh][Cc][Pp]) ;; 24737Srgrimes [Nn][Oo][Aa][Uu][Tt][Oo]) ;; 2481759Sjkh [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 2491759Sjkh [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;; 2501759Sjkh [Ww][Pp][Aa]) ;; 2511759Sjkh *) 2522779Srgrimes _args="$_args $_arg" 2532779Srgrimes ;; 2541759Sjkh esac 2552779Srgrimes done 2562779Srgrimes 257320Srgrimes echo $_args 258358Srgrimes} 2592779Srgrimes 2602779Srgrimes# autoif 2611762Sjkh# Returns 0 if the interface should be automaticly configured at 2621027Sache# boot time and 1 otherwise. 2631027Sacheautoif() 2641731Sjkh{ 265333Srgrimes local _tmpargs _arg 266284Srgrimes _tmpargs=`_ifconfig_getargs $1` 267320Srgrimes 2682570Srgrimes for _arg in $_tmpargs; do 269284Srgrimes case $_arg in 270320Srgrimes [Nn][Oo][Aa][Uu][Tt][Oo]) 2711731Sjkh return 1 2721731Sjkh ;; 2731731Sjkh esac 2741762Sjkh done 2751194Srgrimes 2761194Srgrimes return 0 2771194Srgrimes} 2781194Srgrimes 279320Srgrimes# dhcpif if 2801205Srgrimes# Returns 0 if the interface is a DHCP interface and 1 otherwise. 2812570Srgrimesdhcpif() 2821759Sjkh{ 2832779Srgrimes local _tmpargs _arg 284277Srgrimes _tmpargs=`_ifconfig_getargs $1` 2852779Srgrimes 2862779Srgrimes for _arg in $_tmpargs; do 2871027Sache case $_arg in 2881205Srgrimes [Dd][Hh][Cc][Pp]) 2892779Srgrimes return 0 2901205Srgrimes ;; 2911782Sjkh [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 292277Srgrimes return 0 2931205Srgrimes ;; 2942570Srgrimes [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 2951759Sjkh return 0 2962779Srgrimes ;; 297320Srgrimes esac 2982779Srgrimes done 2992779Srgrimes 3001027Sache return 1 3011205Srgrimes} 3022779Srgrimes 3031205Srgrimes# syncdhcpif 3041782Sjkh# Returns 0 if the interface should be configured synchronously and 305320Srgrimes# 1 otherwise. 3061285Srgrimessyncdhcpif() 3072570Srgrimes{ 3081371Srgrimes local _tmpargs _arg 3091371Srgrimes _tmpargs=`_ifconfig_getargs $1` 3101371Srgrimes 3111371Srgrimes for _arg in $_tmpargs; do 3121371Srgrimes case $_arg in 3131285Srgrimes [Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 3141731Sjkh return 1 3151285Srgrimes ;; 3161731Sjkh [Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) 3171731Sjkh return 0 3181731Sjkh ;; 3191731Sjkh esac 3201285Srgrimes done 3211285Srgrimes 3222570Srgrimes checkyesno synchronous_dhclient 3231759Sjkh} 3242779Srgrimes 3251285Srgrimes# wpaif if 3262779Srgrimes# Returns 0 if the interface is a WPA interface and 1 otherwise. 3272779Srgrimeswpaif() 3281285Srgrimes{ 3291285Srgrimes local _tmpargs _arg 3302779Srgrimes _tmpargs=`_ifconfig_getargs $1` 3311285Srgrimes 3321782Sjkh for _arg in $_tmpargs; do 3331285Srgrimes case $_arg in 3341285Srgrimes [Ww][Pp][Aa]) 3352570Srgrimes return 0 3361759Sjkh ;; 3372779Srgrimes esac 3381285Srgrimes done 3392779Srgrimes 3402779Srgrimes return 1 3411285Srgrimes} 3421285Srgrimes 3432779Srgrimes# afexists af 3441285Srgrimes# Returns 0 if the address family is enabled in the kernel 3451782Sjkh# 1 otherwise. 3461285Srgrimesafexists() 3471205Srgrimes{ 3482779Srgrimes local _af 3492779Srgrimes _af=$1 350568Srgrimes 3511027Sache case ${_af} in 3521027Sache inet|inet6) 3531731Sjkh check_kern_features ${_af} 354333Srgrimes ;; 355284Srgrimes ipx) 356358Srgrimes ${SYSCTL_N} net.ipx > /dev/null 2>&1 3572570Srgrimes ;; 358284Srgrimes atm) 3591194Srgrimes if [ -x /sbin/atmconfig ]; then 3601243Srgrimes /sbin/atmconfig diag list > /dev/null 2>&1 3611194Srgrimes else 3621194Srgrimes return 1 3631731Sjkh fi 3641731Sjkh ;; 3651731Sjkh *) 3661731Sjkh err 1 "afexists(): Unsupported address family: $_af" 3671731Sjkh ;; 3681762Sjkh esac 369284Srgrimes} 3701194Srgrimes 3711194Srgrimes# noafif if 3721194Srgrimes# Returns 0 if the interface has no af configuration and 1 otherwise. 3731194Srgrimesnoafif() 374358Srgrimes{ 3751194Srgrimes local _if 376358Srgrimes _if=$1 377358Srgrimes 3781243Srgrimes case $_if in 379333Srgrimes pflog[0-9]*|\ 380284Srgrimes pfsync[0-9]*|\ 3812779Srgrimes an[0-9]*|\ 3822779Srgrimes ath[0-9]*|\ 3831027Sache ipw[0-9]*|\ 3841205Srgrimes ipfw[0-9]*|\ 3852779Srgrimes iwi[0-9]*|\ 3861205Srgrimes iwn[0-9]*|\ 3871782Sjkh ral[0-9]*|\ 388284Srgrimes wi[0-9]*|\ 3891205Srgrimes wl[0-9]*|\ 3902779Srgrimes wpi[0-9]*) 3912779Srgrimes return 0 392568Srgrimes ;; 3931027Sache esac 3941027Sache 3951731Sjkh return 1 396333Srgrimes} 397284Srgrimes 398358Srgrimes# ipv6if if 3992779Srgrimes# Returns 0 if the interface should be configured for IPv6 and 4002779Srgrimes# 1 otherwise. 4011769Sjkhipv6if() 4021769Sjkh{ 4032779Srgrimes local _if _tmpargs i 4042779Srgrimes _if=$1 4051769Sjkh 4061769Sjkh if ! afexists inet6; then 4071769Sjkh return 1 408284Srgrimes fi 409444Srgrimes 4101194Srgrimes # lo0 is always IPv6-enabled 4111194Srgrimes case $_if in 4122779Srgrimes lo0) 4131769Sjkh return 0 4141731Sjkh ;; 4151731Sjkh esac 4161731Sjkh 4171731Sjkh case "${ipv6_network_interfaces}" in 4181731Sjkh $_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo]) 4191731Sjkh # True if $ifconfig_IF_ipv6 is defined. 420284Srgrimes _tmpargs=`_ifconfig_getargs $_if ipv6` 4212779Srgrimes if [ -n "${_tmpargs}" ]; then 4222779Srgrimes return 0 4231027Sache fi 4241205Srgrimes 4252779Srgrimes # backward compatibility: True if $ipv6_ifconfig_IF is defined. 4261205Srgrimes _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 4271782Sjkh if [ -n "${_tmpargs}" ]; then 428284Srgrimes return 0 429372Srgrimes fi 430372Srgrimes ;; 431538Srgrimes esac 4321782Sjkh 433372Srgrimes return 1 4341782Sjkh} 4352570Srgrimes 4361782Sjkh# ipv6_autoconfif if 4372570Srgrimes# Returns 0 if the interface should be configured for IPv6 with 4381782Sjkh# Stateless Address Configuration, 1 otherwise. 4391782Sjkhipv6_autoconfif() 4401782Sjkh{ 441538Srgrimes local _if _tmpargs _arg 442376Srgrimes _if=$1 4431782Sjkh 4441782Sjkh case $_if in 445376Srgrimes lo0|\ 446538Srgrimes stf[0-9]*|\ 447376Srgrimes faith[0-9]*|\ 4481782Sjkh lp[0-9]*|\ 4492570Srgrimes sl[0-9]*) 450376Srgrimes return 1 451538Srgrimes ;; 452538Srgrimes esac 4531782Sjkh if noafif $_if; then 4541782Sjkh return 1 455538Srgrimes fi 456538Srgrimes if ! ipv6if $_if; then 457538Srgrimes return 1 4581782Sjkh fi 4591782Sjkh if checkyesno ipv6_gateway_enable; then 460538Srgrimes return 1 461538Srgrimes fi 462538Srgrimes _tmpargs=`get_if_var $_if ipv6_prefix_IF` 4631782Sjkh if [ -n "${_tmpargs}" ]; then 4641782Sjkh return 1 465538Srgrimes fi 466538Srgrimes # backward compatibility: $ipv6_enable 467538Srgrimes case $ipv6_enable in 4681782Sjkh [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) 4691782Sjkh return 0 470538Srgrimes ;; 471538Srgrimes esac 472538Srgrimes 4731782Sjkh _tmpargs=`_ifconfig_getargs $_if ipv6` 4741782Sjkh for _arg in $_tmpargs; do 4751782Sjkh case $_arg in 476538Srgrimes accept_rtadv) 477538Srgrimes return 0 478538Srgrimes ;; 4791782Sjkh esac 4801782Sjkh done 481538Srgrimes 482538Srgrimes # backward compatibility: $ipv6_ifconfig_IF 483538Srgrimes _tmpargs=`get_if_var $_if ipv6_ifconfig_IF` 4841782Sjkh for _arg in $_tmpargs; do 4851782Sjkh case $_arg in 486538Srgrimes accept_rtadv) 487538Srgrimes return 0 488538Srgrimes ;; 4891782Sjkh esac 4901782Sjkh done 491538Srgrimes 492538Srgrimes return 1 493538Srgrimes} 4941782Sjkh 4951782Sjkh# ifexists if 496538Srgrimes# Returns 0 if the interface exists and 1 otherwise. 497538Srgrimesifexists() 498538Srgrimes{ 4991782Sjkh [ -z "$1" ] && return 1 5001782Sjkh ifconfig -n $1 > /dev/null 2>&1 501538Srgrimes} 502538Srgrimes 503538Srgrimes# ipv4_up if 5041782Sjkh# add IPv4 addresses to the interface $if 5051782Sjkhipv4_up() 506538Srgrimes{ 507538Srgrimes local _if _ret 508538Srgrimes _if=$1 5091782Sjkh _ret=1 5101782Sjkh 511538Srgrimes # Add 127.0.0.1/8 to lo0 unless otherwise specified. 5122619Srgrimes if [ "${_if}" = "lo0" ]; then 5131782Sjkh ifconfig_args=`ifconfig_getargs ${_if}` 5141782Sjkh if [ -z "${ifconfig_args}" ]; then 5151782Sjkh ifconfig ${_if} inet 127.0.0.1/8 alias 516538Srgrimes fi 517372Srgrimes fi 518372Srgrimes ifalias_up ${_if} inet && _ret=0 519372Srgrimes ipv4_addrs_common ${_if} alias && _ret=0 520372Srgrimes 521372Srgrimes return $_ret 522372Srgrimes} 523372Srgrimes 524372Srgrimes# ipv6_up if 525372Srgrimes# add IPv6 addresses to the interface $if 526372Srgrimesipv6_up() 527372Srgrimes{ 528372Srgrimes local _if _ret 529372Srgrimes _if=$1 530372Srgrimes _ret=1 531372Srgrimes 532372Srgrimes if ! ipv6if $_if; then 533372Srgrimes return 0 534372Srgrimes fi 535372Srgrimes 536372Srgrimes ifalias_up ${_if} inet6 && _ret=0 537372Srgrimes ipv6_prefix_hostid_addr_up ${_if} && _ret=0 538372Srgrimes ipv6_accept_rtadv_up ${_if} && _ret=0 539372Srgrimes 540372Srgrimes # wait for DAD 541372Srgrimes sleep `${SYSCTL_N} net.inet6.ip6.dad_count` 542372Srgrimes sleep 1 543372Srgrimes 544538Srgrimes return $_ret 5451782Sjkh} 546372Srgrimes 547372Srgrimes# ipv4_down if 548147Srgrimes# remove IPv4 addresses from the interface $if 5492779Srgrimesipv4_down() 5502779Srgrimes{ 5512779Srgrimes local _if _ifs _ret inetList oldifs _inet 5522779Srgrimes _if=$1 5532779Srgrimes _ifs="^" 5542779Srgrimes _ret=1 5552779Srgrimes 556372Srgrimes inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`" 5572779Srgrimes 558372Srgrimes oldifs="$IFS" 559410Srgrimes IFS="$_ifs" 560147Srgrimes for _inet in $inetList ; do 5611285Srgrimes # get rid of extraneous line 5621285Srgrimes [ -z "$_inet" ] && break 563372Srgrimes 5641731Sjkh _inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'` 5651769Sjkh 5661731Sjkh IFS="$oldifs" 567372Srgrimes ifconfig ${_if} ${_inet} delete 5682779Srgrimes IFS="$_ifs" 5692611Srgrimes _ret=0 5702779Srgrimes done 571372Srgrimes IFS="$oldifs" 57237Srgrimes 573 ifalias_down ${_if} inet && _ret=0 574 ipv4_addrs_common ${_if} -alias && _ret=0 575 576 return $_ret 577} 578 579# ipv6_down if 580# remove IPv6 addresses from the interface $if 581ipv6_down() 582{ 583 local _if _ifs _ret inetList oldifs _inet6 584 _if=$1 585 _ifs="^" 586 _ret=1 587 588 if ! ipv6if $_if; then 589 return 0 590 fi 591 592 ipv6_accept_rtadv_down ${_if} && _ret=0 593 ifalias_down ${_if} inet6 && _ret=0 594 595 inetList="`ifconfig ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`" 596 597 oldifs="$IFS" 598 IFS="$_ifs" 599 for _inet6 in $inetList ; do 600 # get rid of extraneous line 601 [ -z "$_inet6" ] && break 602 603 _inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'` 604 605 IFS="$oldifs" 606 ifconfig ${_if} ${_inet6} -alias 607 IFS="$_ifs" 608 _ret=0 609 done 610 IFS="$oldifs" 611 612 return $_ret 613} 614 615# ipv4_addrs_common if action 616# Evaluate the ifconfig_if_ipv4 arguments for interface $if and 617# use $action to add or remove IPv4 addresses from $if. 618ipv4_addrs_common() 619{ 620 local _ret _if _action _cidr _cidr_addr 621 local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount 622 _ret=1 623 _if=$1 624 _action=$2 625 626 # get ipv4-addresses 627 cidr_addr=`get_if_var $_if ipv4_addrs_IF` 628 629 for _cidr in ${cidr_addr}; do 630 _ipaddr=${_cidr%%/*} 631 _netmask="/"${_cidr##*/} 632 _range=${_ipaddr##*.} 633 _ipnet=${_ipaddr%.*} 634 _iplow=${_range%-*} 635 _iphigh=${_range#*-} 636 637 # clear netmask when removing aliases 638 if [ "${_action}" = "-alias" ]; then 639 _netmask="" 640 fi 641 642 _ipcount=${_iplow} 643 while [ "${_ipcount}" -le "${_iphigh}" ]; do 644 eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}" 645 _ipcount=$((${_ipcount}+1)) 646 _ret=0 647 648 # only the first ipaddr in a subnet need the real netmask 649 if [ "${_action}" != "-alias" ]; then 650 _netmask="/32" 651 fi 652 done 653 done 654 655 return $_ret 656} 657 658# ifalias_up if af 659# Configure aliases for network interface $if. 660# It returns 0 if at least one alias was configured or 661# 1 if there were none. 662# 663ifalias_up() 664{ 665 local _ret 666 _ret=1 667 668 case "$2" in 669 inet) 670 _ret=`ifalias_ipv4_up "$1"` 671 ;; 672 inet6) 673 _ret=`ifalias_ipv6_up "$1"` 674 ;; 675 esac 676 677 return $_ret 678} 679 680# ifalias_ipv4_up if 681# Helper function for ifalias_up(). Handles IPv4. 682# 683ifalias_ipv4_up() 684{ 685 local _ret alias ifconfig_args 686 _ret=1 687 688 # ifconfig_IF_aliasN which starts with "inet" 689 alias=0 690 while : ; do 691 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 692 case "${ifconfig_args}" in 693 inet\ *) 694 ifconfig $1 ${ifconfig_args} alias && _ret=0 695 ;; 696 "") 697 break 698 ;; 699 esac 700 alias=$((${alias} + 1)) 701 done 702 703 return $_ret 704} 705 706# ifalias_ipv6_up if 707# Helper function for ifalias_up(). Handles IPv6. 708# 709ifalias_ipv6_up() 710{ 711 local _ret alias ifconfig_args 712 _ret=1 713 714 # ifconfig_IF_aliasN which starts with "inet6" 715 alias=0 716 while : ; do 717 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 718 case "${ifconfig_args}" in 719 inet6\ *) 720 ifconfig $1 ${ifconfig_args} alias && _ret=0 721 ;; 722 "") 723 break 724 ;; 725 esac 726 alias=$((${alias} + 1)) 727 done 728 729 # backward compatibility: ipv6_ifconfig_IF_aliasN. 730 alias=0 731 while : ; do 732 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 733 case "${ifconfig_args}" in 734 "") 735 break 736 ;; 737 *) 738 ifconfig $1 inet6 ${ifconfig_args} alias && _ret=0 739 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 740 " Use ifconfig_$1_aliasN instead." 741 ;; 742 esac 743 alias=$((${alias} + 1)) 744 done 745 746 return $_ret 747} 748 749# ifalias_down if af 750# Remove aliases for network interface $if. 751# It returns 0 if at least one alias was removed or 752# 1 if there were none. 753# 754ifalias_down() 755{ 756 local _ret 757 _ret=1 758 759 case "$2" in 760 inet) 761 _ret=`ifalias_ipv4_down "$1"` 762 ;; 763 inet6) 764 _ret=`ifalias_ipv6_down "$1"` 765 ;; 766 esac 767 768 return $_ret 769} 770 771# ifalias_ipv4_down if 772# Helper function for ifalias_down(). Handles IPv4. 773# 774ifalias_ipv4_down() 775{ 776 local _ret alias ifconfig_args 777 _ret=1 778 779 # ifconfig_IF_aliasN which starts with "inet" 780 alias=0 781 while : ; do 782 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 783 case "${ifconfig_args}" in 784 inet\ *) 785 ifconfig $1 ${ifconfig_args} -alias && _ret=0 786 ;; 787 "") 788 break 789 ;; 790 esac 791 alias=$((${alias} + 1)) 792 done 793 794 return $_ret 795} 796 797# ifalias_ipv6_down if 798# Helper function for ifalias_down(). Handles IPv6. 799# 800ifalias_ipv6_down() 801{ 802 local _ret alias ifconfig_args 803 _ret=1 804 805 # ifconfig_IF_aliasN which starts with "inet6" 806 alias=0 807 while : ; do 808 ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}` 809 case "${ifconfig_args}" in 810 inet6\ *) 811 ifconfig $1 ${ifconfig_args} -alias && _ret=0 812 ;; 813 "") 814 break 815 ;; 816 esac 817 alias=$((${alias} + 1)) 818 done 819 820 # backward compatibility: ipv6_ifconfig_IF_aliasN. 821 alias=0 822 while : ; do 823 ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}` 824 case "${ifconfig_args}" in 825 "") 826 break 827 ;; 828 *) 829 ifconfig $1 inet6 ${ifconfig_args} -alias && _ret=0 830 warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \ 831 " Use ifconfig_$1_aliasN instead." 832 ;; 833 esac 834 alias=$((${alias} + 1)) 835 done 836 837 return $_ret 838} 839 840# ipv6_prefix_hostid_addr_up if 841# add IPv6 prefix + hostid addr to the interface $if 842ipv6_prefix_hostid_addr_up() 843{ 844 local _if prefix laddr hostid j address 845 _if=$1 846 prefix=`get_if_var ${_if} ipv6_prefix_IF` 847 848 if [ -n "${prefix}" ]; then 849 laddr=`network6_getladdr ${_if}` 850 hostid=${laddr#fe80::} 851 hostid=${hostid%\%*} 852 853 for j in ${prefix}; do 854 address=$j\:${hostid} 855 ifconfig ${_if} inet6 ${address} prefixlen 64 alias 856 857 # if I am a router, add subnet router 858 # anycast address (RFC 2373). 859 if checkyesno ipv6_gateway_enable; then 860 ifconfig ${_if} inet6 $j:: prefixlen 64 \ 861 alias anycast 862 fi 863 done 864 fi 865} 866 867# ipv6_accept_rtadv_up if 868# Enable accepting Router Advertisement and send Router 869# Solicitation message 870ipv6_accept_rtadv_up() 871{ 872 if ipv6_autoconfif $1; then 873 ifconfig $1 inet6 accept_rtadv up 874 if ! checkyesno rtsold_enable; then 875 rtsol ${rtsol_flags} $1 876 fi 877 fi 878} 879 880# ipv6_accept_rtadv_down if 881# Disable accepting Router Advertisement 882ipv6_accept_rtadv_down() 883{ 884 if ipv6_autoconfif $1; then 885 ifconfig $1 inet6 -accept_rtadv 886 fi 887} 888 889# ifscript_up if 890# Evaluate a startup script for the $if interface. 891# It returns 0 if a script was found and processed or 892# 1 if no script was found. 893# 894ifscript_up() 895{ 896 if [ -r /etc/start_if.$1 ]; then 897 . /etc/start_if.$1 898 return 0 899 else 900 return 1 901 fi 902} 903 904# ifscript_down if 905# Evaluate a shutdown script for the $if interface. 906# It returns 0 if a script was found and processed or 907# 1 if no script was found. 908# 909ifscript_down() 910{ 911 if [ -r /etc/stop_if.$1 ]; then 912 . /etc/stop_if.$1 913 return 0 914 else 915 return 1 916 fi 917} 918 919# clone_up 920# Create cloneable interfaces. 921# 922clone_up() 923{ 924 local _prefix _list ifn 925 _prefix= 926 _list= 927 928 # create_args_IF 929 for ifn in ${cloned_interfaces}; do 930 ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF` 931 if [ $? -eq 0 ]; then 932 _list="${_list}${_prefix}${ifn}" 933 [ -z "$_prefix" ] && _prefix=' ' 934 fi 935 done 936 debug "Cloned: ${_list}" 937} 938 939# clone_down 940# Destroy cloned interfaces. Destroyed interfaces are echoed to 941# standard output. 942# 943clone_down() 944{ 945 local _prefix _list ifn 946 _prefix= 947 _list= 948 949 for ifn in ${cloned_interfaces}; do 950 ifconfig -n ${ifn} destroy 951 if [ $? -eq 0 ]; then 952 _list="${_list}${_prefix}${ifn}" 953 [ -z "$_prefix" ] && _prefix=' ' 954 fi 955 done 956 debug "Destroyed clones: ${_list}" 957} 958 959# childif_create 960# Create and configure child interfaces. Return 0 if child 961# interfaces are created. 962# 963childif_create() 964{ 965 local cfg child child_vlans child_wlans create_args debug_flags ifn i 966 cfg=1 967 ifn=$1 968 969 # Create wireless interfaces 970 child_wlans=`get_if_var $ifn wlans_IF` 971 972 for child in ${child_wlans}; do 973 create_args="wlandev $ifn `get_if_var $child create_args_IF`" 974 debug_flags="`get_if_var $child wlandebug_IF`" 975 976 if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then 977 ifconfig $child create ${create_args} && cfg=0 978 if [ -n "${debug_flags}" ]; then 979 wlandebug -i $child ${debug_flags} 980 fi 981 else 982 i=`ifconfig wlan create ${create_args}` 983 if [ -n "${debug_flags}" ]; then 984 wlandebug -i $i ${debug_flags} 985 fi 986 ifconfig $i name $child && cfg=0 987 fi 988 if autoif $child; then 989 ifn_start $child 990 fi 991 done 992 993 # Create vlan interfaces 994 child_vlans=`get_if_var $ifn vlans_IF` 995 996 if [ -n "${child_vlans}" ]; then 997 load_kld if_vlan 998 fi 999 1000 for child in ${child_vlans}; do 1001 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1002 child="${ifn}.${child}" 1003 create_args=`get_if_var $child create_args_IF` 1004 ifconfig $child create ${create_args} && cfg=0 1005 else 1006 create_args="vlandev $ifn `get_if_var $child create_args_IF`" 1007 if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then 1008 ifconfig $child create ${create_args} && cfg=0 1009 else 1010 i=`ifconfig vlan create ${create_args}` 1011 ifconfig $i name $child && cfg=0 1012 fi 1013 fi 1014 if autoif $child; then 1015 ifn_start $child 1016 fi 1017 done 1018 1019 return ${cfg} 1020} 1021 1022# childif_destroy 1023# Destroy child interfaces. 1024# 1025childif_destroy() 1026{ 1027 local cfg child child_vlans child_wlans ifn 1028 cfg=1 1029 1030 child_wlans=`get_if_var $ifn wlans_IF` 1031 for child in ${child_wlans}; do 1032 if ! ifexists $child; then 1033 continue 1034 fi 1035 ifconfig -n $child destroy && cfg=0 1036 done 1037 1038 child_vlans=`get_if_var $ifn vlans_IF` 1039 for child in ${child_vlans}; do 1040 if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then 1041 child="${ifn}.${child}" 1042 fi 1043 if ! ifexists $child; then 1044 continue 1045 fi 1046 ifconfig -n $child destroy && cfg=0 1047 done 1048 1049 return ${cfg} 1050} 1051 1052# ng_mkpeer 1053# Create netgraph nodes. 1054# 1055ng_mkpeer() 1056{ 1057 ngctl -f - 2> /dev/null <<EOF 1058mkpeer $* 1059msg dummy nodeinfo 1060EOF 1061} 1062 1063# ng_create_one 1064# Create netgraph nodes. 1065# 1066ng_create_one() 1067{ 1068 local t 1069 1070 ng_mkpeer $* | while read line; do 1071 t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'` 1072 if [ -n "${t}" ]; then 1073 echo ${t} 1074 return 1075 fi 1076 done 1077} 1078 1079# gif_up 1080# Create gif(4) tunnel interfaces. 1081gif_up() 1082{ 1083 local i peers 1084 1085 for i in ${gif_interfaces}; do 1086 peers=`get_if_var $i gifconfig_IF` 1087 case ${peers} in 1088 '') 1089 continue 1090 ;; 1091 *) 1092 if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then 1093 ifconfig $i create >/dev/null 2>&1 1094 else 1095 gif=`ifconfig gif create` 1096 ifconfig $gif name $i 1097 fi 1098 ifconfig $i tunnel ${peers} 1099 ifconfig $i up 1100 ;; 1101 esac 1102 done 1103} 1104 1105# ng_fec_create ifn 1106# Configure Fast EtherChannel for interface $ifn. Returns 0 if 1107# FEC arguments were found and configured; returns !0 otherwise. 1108ng_fec_create() 1109{ 1110 local req_iface iface bogus 1111 req_iface="$1" 1112 1113 ngctl shutdown ${req_iface}: > /dev/null 2>&1 1114 1115 bogus="" 1116 while true; do 1117 iface=`ng_create_one fec dummy fec` 1118 if [ -z "${iface}" ]; then 1119 exit 2 1120 fi 1121 if [ "${iface}" = "${req_iface}" ]; then 1122 break 1123 fi 1124 bogus="${bogus} ${iface}" 1125 done 1126 1127 for iface in ${bogus}; do 1128 ngctl shutdown ${iface}: 1129 done 1130} 1131 1132# fec_up 1133# Create Fast EtherChannel interfaces. 1134fec_up() 1135{ 1136 local i j 1137 1138 for i in ${fec_interfaces}; do 1139 ng_fec_create $i 1140 for j in `get_if_var $i fecconfig_IF`; do 1141 case ${j} in 1142 '') 1143 continue 1144 ;; 1145 *) 1146 ngctl msg ${i}: add_iface "\"${j}\"" 1147 ;; 1148 esac 1149 done 1150 done 1151} 1152 1153# ipx_up ifn 1154# Configure any IPX addresses for interface $ifn. Returns 0 if 1155# IPX arguments were found and configured; returns 1 otherwise. 1156# 1157ipx_up() 1158{ 1159 local ifn 1160 ifn="$1" 1161 1162 # ifconfig_IF_ipx 1163 ifconfig_args=`_ifconfig_getargs $ifn ipx` 1164 if [ -n "${ifconfig_args}" ]; then 1165 ifconfig ${ifn} ${ifconfig_args} 1166 return 0 1167 fi 1168 1169 return 1 1170} 1171 1172# ipx_down ifn 1173# Remove IPX addresses for interface $ifn. Returns 0 if IPX 1174# addresses were found and unconfigured. It returns 1, otherwise. 1175# 1176ipx_down() 1177{ 1178 local _if _ifs _ret ipxList oldifs _ipx 1179 _if=$1 1180 _ifs="^" 1181 _ret=1 1182 ipxList="`ifconfig ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`" 1183 oldifs="$IFS" 1184 1185 IFS="$_ifs" 1186 for _ipx in $ipxList ; do 1187 # get rid of extraneous line 1188 [ -z "$_ipx" ] && break 1189 1190 _ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'` 1191 1192 IFS="$oldifs" 1193 ifconfig ${_if} ${_ipx} delete 1194 IFS="$_ifs" 1195 _ret=0 1196 done 1197 IFS="$oldifs" 1198 1199 return $_ret 1200} 1201 1202# ifnet_rename 1203# Rename all requested interfaces. 1204# 1205ifnet_rename() 1206{ 1207 local _if _ifname 1208 1209 # ifconfig_IF_name 1210 for _if in `ifconfig -l`; do 1211 _ifname=`get_if_var $_if ifconfig_IF_name` 1212 if [ ! -z "$_ifname" ]; then 1213 ifconfig $_if name $_ifname 1214 fi 1215 done 1216 1217 return 0 1218} 1219 1220# list_net_interfaces type 1221# List all network interfaces. The type of interface returned 1222# can be controlled by the type argument. The type 1223# argument can be any of the following: 1224# nodhcp - all interfaces, excluding DHCP configured interfaces 1225# dhcp - list only DHCP configured interfaces 1226# noautoconf - all interfaces, excluding IPv6 Stateless 1227# Address Autoconf configured interfaces 1228# autoconf - list only IPv6 Stateless Address Autoconf 1229# configured interfaces 1230# If no argument is specified all network interfaces are output. 1231# Note that the list will include cloned interfaces if applicable. 1232# Cloned interfaces must already exist to have a chance to appear 1233# in the list if ${network_interfaces} is set to `auto'. 1234# 1235list_net_interfaces() 1236{ 1237 local type _tmplist _list _autolist _lo _if 1238 type=$1 1239 1240 # Get a list of ALL the interfaces and make lo0 first if it's there. 1241 # 1242 _tmplist= 1243 case ${network_interfaces} in 1244 [Aa][Uu][Tt][Oo]) 1245 _autolist="`ifconfig -l`" 1246 _lo= 1247 for _if in ${_autolist} ; do 1248 if autoif $_if; then 1249 if [ "$_if" = "lo0" ]; then 1250 _lo="lo0 " 1251 else 1252 _tmplist="${_tmplist} ${_if}" 1253 fi 1254 fi 1255 done 1256 _tmplist="${_lo}${_tmplist# }" 1257 ;; 1258 *) 1259 _tmplist="${network_interfaces} ${cloned_interfaces}" 1260 1261 # lo0 is effectively mandatory, so help prevent foot-shooting 1262 # 1263 case "$_tmplist" in 1264 lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing 1265 *) _tmplist="lo0 ${_tmplist}" ;; 1266 esac 1267 ;; 1268 esac 1269 1270 _list= 1271 case "$type" in 1272 nodhcp) 1273 for _if in ${_tmplist} ; do 1274 if ! dhcpif $_if && \ 1275 [ -n "`_ifconfig_getargs $_if`" ]; then 1276 _list="${_list# } ${_if}" 1277 fi 1278 done 1279 ;; 1280 dhcp) 1281 for _if in ${_tmplist} ; do 1282 if dhcpif $_if; then 1283 _list="${_list# } ${_if}" 1284 fi 1285 done 1286 ;; 1287 noautoconf) 1288 for _if in ${_tmplist} ; do 1289 if ! ipv6_autoconfif $_if && \ 1290 [ -n "`_ifconfig_getargs $_if ipv6`" ]; then 1291 _list="${_list# } ${_if}" 1292 fi 1293 done 1294 ;; 1295 autoconf) 1296 for _if in ${_tmplist} ; do 1297 if ipv6_autoconfif $_if; then 1298 _list="${_list# } ${_if}" 1299 fi 1300 done 1301 ;; 1302 *) 1303 _list=${_tmplist} 1304 ;; 1305 esac 1306 1307 echo $_list 1308 1309 return 0 1310} 1311 1312# get_default_if -address_family 1313# Get the interface of the default route for the given address family. 1314# The -address_family argument must be suitable passing to route(8). 1315# 1316get_default_if() 1317{ 1318 local routeget oldifs defif line 1319 defif= 1320 oldifs="$IFS" 1321 IFS=" 1322" 1323 for line in `route -n get $1 default 2>/dev/null`; do 1324 case $line in 1325 *interface:*) 1326 defif=${line##*: } 1327 ;; 1328 esac 1329 done 1330 IFS=${oldifs} 1331 1332 echo $defif 1333} 1334 1335# hexdigit arg 1336# Echo decimal number $arg (single digit) in hexadecimal format. 1337hexdigit() 1338{ 1339 printf '%x\n' "$1" 1340} 1341 1342# hexprint arg 1343# Echo decimal number $arg (multiple digits) in hexadecimal format. 1344hexprint() 1345{ 1346 printf '%x\n' "$1" 1347} 1348 1349is_wired_interface() 1350{ 1351 local media 1352 1353 case `ifconfig $1 2>/dev/null` in 1354 *media:?Ethernet*) media=Ethernet ;; 1355 esac 1356 1357 test "$media" = "Ethernet" 1358} 1359 1360# network6_getladdr if [flag] 1361# Echo link-local address from $if if any. 1362# If flag is defined, tentative ones will be excluded. 1363network6_getladdr() 1364{ 1365 local proto addr rest 1366 ifconfig $1 2>/dev/null | while read proto addr rest; do 1367 case ${proto} in 1368 inet6) 1369 case ${addr} in 1370 fe80::*) 1371 if [ -z "$2" ]; then 1372 echo ${addr} 1373 return 1374 fi 1375 case ${rest} in 1376 *tentative*) 1377 continue 1378 ;; 1379 *) 1380 echo ${addr} 1381 return 1382 esac 1383 esac 1384 esac 1385 done 1386} 1387