2ae521fa83
and ipv6_ifconfig_<interface> options have already been deprecated, these changes do not alter that. With these changes any value set for ipv6_enable will emit a warning. In order to avoid a POLA violation for the deprecation of the option ipv6_enable=NO will still disable configuration for all interfaces other than lo0. ipv6_enable=YES will not have any effect, but will emit an additional warning. Support and warnings for this option will be removed in FreeBSD 10.x. Consistent with the current code, in order for IPv6 to be configured on an interface (other than lo0) an ifconfig_<interface>_ipv6 option will have to be added to /etc/rc.conf[.local]. 1. Clean up and minor optimizations for the following functions: ifconfig_up (the ipv6 elements) ipv6if ipv6_autoconfif get_if_var _ifconfig_getargs The cleanups generally were to move the "easy" tests earlier in the functions, and consolidate duplicate code. 2. Stop overloading ipv6_prefer with the ability to disable IPv6 configuration. 3. Remove noafif() which was only ever called from ipv6_autoconfif. Instead, simplify and integrate the tests into that function, and convert the test to use is_wired_interface() instead of listing wireless interfaces explicitly. 4. Integrate backwards compatibility for ipv6_ifconfig_<interface> into _ifconfig_getargs. This dramatically simplifies the code in all of the callers, and avoids a lot of other code duplication. 5. In rc.d/netoptions, add code for an ipv6_privacy option to use RFC 4193 style pseudo-random addresses (this is what windows does by default, FYI). 6. Add support for the [NO]RTADV options in ifconfig_getargs() and ipv6_autoconfif(). In the latter, include support for the explicit addition of [-]accept_rtadv in ifconfig_<interface>_ipv6 as is done in the current code. 7. In rc.d/netif add a warning if $ipv6_enable is set, and remove the set_rcvar_obsolete for it. Also remove the latter from rc.d/ip6addrctl. 8. In /etc/defaults/rc.conf: Add an example for RTADV configuration. Set ipv6_network_interfaces to AUTO. Switch ipv6_prefer to YES. If ipv6_enable is not set this will have no effect. Add a default for ipv6_privacy (NO). 9. Document all of this in rc.conf.5.
1385 lines
26 KiB
Plaintext
1385 lines
26 KiB
Plaintext
#
|
|
# Copyright (c) 2003 The FreeBSD Project. All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
# SUCH DAMAGE.
|
|
#
|
|
# $FreeBSD$
|
|
#
|
|
|
|
#
|
|
# Subroutines commonly used from network startup scripts.
|
|
# Requires that rc.conf be loaded first.
|
|
#
|
|
|
|
# ifn_start ifn
|
|
# Bring up and configure an interface. If some configuration is
|
|
# applied print the interface configuration.
|
|
#
|
|
ifn_start()
|
|
{
|
|
local ifn cfg
|
|
ifn="$1"
|
|
cfg=1
|
|
|
|
[ -z "$ifn" ] && err 1 "ifn_start called without an interface"
|
|
|
|
ifscript_up ${ifn} && cfg=0
|
|
ifconfig_up ${ifn} && cfg=0
|
|
ipv4_up ${ifn} && cfg=0
|
|
ipv6_up ${ifn} && cfg=0
|
|
ipx_up ${ifn} && cfg=0
|
|
childif_create ${ifn} && cfg=0
|
|
|
|
return $cfg
|
|
}
|
|
|
|
# ifn_stop ifn
|
|
# Shutdown and de-configure an interface. If action is taken
|
|
# print the interface name.
|
|
#
|
|
ifn_stop()
|
|
{
|
|
local ifn cfg
|
|
ifn="$1"
|
|
cfg=1
|
|
|
|
[ -z "$ifn" ] && err 1 "ifn_stop called without an interface"
|
|
|
|
ipx_down ${ifn} && cfg=0
|
|
ipv6_down ${ifn} && cfg=0
|
|
ipv4_down ${ifn} && cfg=0
|
|
ifconfig_down ${ifn} && cfg=0
|
|
ifscript_down ${ifn} && cfg=0
|
|
childif_destroy ${ifn} && cfg=0
|
|
|
|
return $cfg
|
|
}
|
|
|
|
# ifconfig_up if
|
|
# Evaluate ifconfig(8) arguments for interface $if and
|
|
# run ifconfig(8) with those arguments. It returns 0 if
|
|
# arguments were found and executed or 1 if the interface
|
|
# had no arguments. Pseudo arguments DHCP and WPA are handled
|
|
# here.
|
|
#
|
|
ifconfig_up()
|
|
{
|
|
local _cfg _ipv6_opts ifconfig_args
|
|
_cfg=1
|
|
|
|
# ifconfig_IF
|
|
ifconfig_args=`ifconfig_getargs $1`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
ifconfig $1 ${ifconfig_args}
|
|
_cfg=0
|
|
fi
|
|
|
|
# inet6 specific
|
|
if afexists inet6; then
|
|
if ipv6if $1; then
|
|
# Implicitly handles ipv6_gateway_enable
|
|
_ipv6_opts='-ifdisabled -accept_rtadv'
|
|
|
|
if ipv6_autoconfif $1; then
|
|
_ipv6_opts='-ifdisabled accept_rtadv'
|
|
fi
|
|
|
|
ifconfig $1 inet6 $_ipv6_opts
|
|
|
|
# ifconfig_IF_ipv6
|
|
ifconfig_args=`ifconfig_getargs $1 ipv6`
|
|
|
|
if [ -n "$ifconfig_args" ]; then
|
|
ifconfig $1 $ifconfig_args
|
|
_cfg=0
|
|
fi
|
|
else
|
|
# Remove in FreeBSD 10.x
|
|
# Explicit test is necessary here to avoid nonexistence error
|
|
case "$ipv6_enable" in
|
|
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
|
|
warn "Interface $1 will NOT be configured for IPv6"
|
|
;;
|
|
esac
|
|
|
|
ifconfig $1 inet6 ifdisabled
|
|
fi
|
|
fi
|
|
|
|
if [ ${_cfg} -eq 0 ]; then
|
|
ifconfig $1 up
|
|
fi
|
|
|
|
if wpaif $1; then
|
|
/etc/rc.d/wpa_supplicant start $1
|
|
_cfg=0 # XXX: not sure this should count
|
|
fi
|
|
|
|
if dhcpif $1; then
|
|
if [ $_cfg -ne 0 ] ; then
|
|
ifconfig $1 up
|
|
fi
|
|
if syncdhcpif $1; then
|
|
/etc/rc.d/dhclient start $1
|
|
fi
|
|
_cfg=0
|
|
fi
|
|
|
|
return $_cfg
|
|
}
|
|
|
|
# ifconfig_down if
|
|
# returns 1 if wpa_supplicant or dhclient was stopped or
|
|
# the interface exists.
|
|
#
|
|
ifconfig_down()
|
|
{
|
|
local _cfg
|
|
_cfg=1
|
|
|
|
if wpaif $1; then
|
|
/etc/rc.d/wpa_supplicant stop $1
|
|
_cfg=0
|
|
fi
|
|
|
|
if dhcpif $1; then
|
|
/etc/rc.d/dhclient stop $1
|
|
_cfg=0
|
|
fi
|
|
|
|
if ifexists $1; then
|
|
ifconfig $1 down
|
|
_cfg=0
|
|
fi
|
|
|
|
return $_cfg
|
|
}
|
|
|
|
# get_if_var if var [default]
|
|
# Return the value of the pseudo-hash corresponding to $if where
|
|
# $var is a string containg the sub-string "IF" which will be
|
|
# replaced with $if after the characters defined in _punct are
|
|
# replaced with '_'. If the variable is unset, replace it with
|
|
# $default if given.
|
|
get_if_var()
|
|
{
|
|
local _if _punct _punct_c _var _default prefix suffix
|
|
|
|
if [ $# -ne 2 -a $# -ne 3 ]; then
|
|
err 3 'USAGE: get_if_var name var [default]'
|
|
fi
|
|
|
|
_if=$1
|
|
_punct=". - / +"
|
|
for _punct_c in $_punct; do
|
|
_if=`ltr ${_if} ${_punct_c} '_'`
|
|
done
|
|
_var=$2
|
|
_default=$3
|
|
|
|
prefix=${_var%%IF*}
|
|
suffix=${_var##*IF}
|
|
eval echo \${${prefix}${_if}${suffix}-${_default}}
|
|
}
|
|
|
|
# _ifconfig_getargs if [af]
|
|
# Echos the arguments for the supplied interface to stdout.
|
|
# returns 1 if empty. In general, ifconfig_getargs should be used
|
|
# outside this file.
|
|
_ifconfig_getargs()
|
|
{
|
|
local _ifn _af value
|
|
_ifn=$1
|
|
_af=${2+_$2}
|
|
|
|
if [ -z "$_ifn" ]; then
|
|
return 1
|
|
fi
|
|
|
|
value=`get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT"`
|
|
|
|
# Remove in FreeBSD 10.x
|
|
if [ "$_af" = _ipv6 -a -z "$value" ]; then
|
|
value=`get_if_var $_ifn ipv6_ifconfig_IF "$ifconfig_DEFAULT"`
|
|
if [ -n "$value" ]; then
|
|
warn "\$ipv6_ifconfig_$1 is obsolete." \
|
|
" Use ifconfig_$1_ipv6 instead."
|
|
fi
|
|
fi
|
|
|
|
echo $value
|
|
}
|
|
|
|
# ifconfig_getargs if [af]
|
|
# Takes the result from _ifconfig_getargs and removes pseudo
|
|
# args such as DHCP and WPA.
|
|
ifconfig_getargs()
|
|
{
|
|
local _tmpargs _arg _args
|
|
_tmpargs=`_ifconfig_getargs $1 $2`
|
|
if [ $? -eq 1 ]; then
|
|
return 1
|
|
fi
|
|
_args=
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Dd][Hh][Cc][Pp]) ;;
|
|
[Nn][Oo][Aa][Uu][Tt][Oo]) ;;
|
|
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
|
|
[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]) ;;
|
|
[Ww][Pp][Aa]) ;;
|
|
[Rr][Tt][Aa][Dd][Vv]) ;;
|
|
[Nn][Oo][Rr][Tt][Aa][Dd][Vv]) ;;
|
|
*)
|
|
_args="$_args $_arg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo $_args
|
|
}
|
|
|
|
# autoif
|
|
# Returns 0 if the interface should be automaticly configured at
|
|
# boot time and 1 otherwise.
|
|
autoif()
|
|
{
|
|
local _tmpargs _arg
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Nn][Oo][Aa][Uu][Tt][Oo])
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
# dhcpif if
|
|
# Returns 0 if the interface is a DHCP interface and 1 otherwise.
|
|
dhcpif()
|
|
{
|
|
local _tmpargs _arg
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Dd][Hh][Cc][Pp])
|
|
return 0
|
|
;;
|
|
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
|
|
return 0
|
|
;;
|
|
[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# syncdhcpif
|
|
# Returns 0 if the interface should be configured synchronously and
|
|
# 1 otherwise.
|
|
syncdhcpif()
|
|
{
|
|
local _tmpargs _arg
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
|
|
return 1
|
|
;;
|
|
[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp])
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
checkyesno synchronous_dhclient
|
|
}
|
|
|
|
# wpaif if
|
|
# Returns 0 if the interface is a WPA interface and 1 otherwise.
|
|
wpaif()
|
|
{
|
|
local _tmpargs _arg
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Ww][Pp][Aa])
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# afexists af
|
|
# Returns 0 if the address family is enabled in the kernel
|
|
# 1 otherwise.
|
|
afexists()
|
|
{
|
|
local _af
|
|
_af=$1
|
|
|
|
case ${_af} in
|
|
inet)
|
|
${SYSCTL_N} net.inet > /dev/null 2>&1
|
|
;;
|
|
inet6)
|
|
${SYSCTL_N} net.inet6 > /dev/null 2>&1
|
|
;;
|
|
ipx)
|
|
${SYSCTL_N} net.ipx > /dev/null 2>&1
|
|
;;
|
|
atm)
|
|
if [ -x /sbin/atmconfig ]; then
|
|
/sbin/atmconfig diag list > /dev/null 2>&1
|
|
else
|
|
return 1
|
|
fi
|
|
;;
|
|
*)
|
|
err 1 "afexists(): Unsupported address family: $_af"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# ipv6if if
|
|
# Returns 0 if the interface should be configured for IPv6 and
|
|
# 1 otherwise.
|
|
ipv6if()
|
|
{
|
|
if ! afexists inet6; then
|
|
return 1
|
|
fi
|
|
|
|
# lo0 is always IPv6-enabled
|
|
case $1 in
|
|
lo0)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
local _if _tmpargs i
|
|
_if=$1
|
|
|
|
case "$ipv6_network_interfaces" in
|
|
''|[Nn][Oo][Nn][Ee])
|
|
return 1
|
|
;;
|
|
$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
|
|
# True if $ifconfig_IF_ipv6 is defined.
|
|
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
|
;;
|
|
esac
|
|
|
|
if [ -n "$_tmpargs" ]; then
|
|
# Remove in FreeBSD 10.x
|
|
# Explicit test is necessary here to avoid nonexistence error
|
|
case "$ipv6_enable" in
|
|
[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0)
|
|
;;
|
|
*) return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# ipv6_autoconfif if
|
|
# Returns 0 if the interface should be configured for IPv6 with
|
|
# Stateless Address Configuration, 1 otherwise.
|
|
ipv6_autoconfif()
|
|
{
|
|
case $1 in
|
|
lo0|\
|
|
stf[0-9]*|\
|
|
faith[0-9]*|\
|
|
lp[0-9]*|\
|
|
sl[0-9]*|\
|
|
pflog[0-9]*|\
|
|
pfsync[0-9]*)
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
local _if _tmpargs _arg
|
|
_if=$1
|
|
|
|
if ! ipv6if $_if; then
|
|
return 1
|
|
fi
|
|
if checkyesno ipv6_gateway_enable; then
|
|
return 1
|
|
fi
|
|
_tmpargs=`get_if_var $_if ipv6_prefix_IF`
|
|
if [ -n "${_tmpargs}" ]; then
|
|
return 1
|
|
fi
|
|
if ! is_wired_interface $_if; then
|
|
case $_if in
|
|
wlan[0-9]*) ;; # Allow test to continue
|
|
*) return 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
|
case "$_tmpargs" in
|
|
*inet6\ *|*[Nn][Oo][Rr][Tt][Aa][Dd][Vv]*|*-accept_rtadv*)
|
|
return 1
|
|
;;
|
|
*[Rr][Tt][Aa][Dd][Vv]*|*accept_rtadv*)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
# ifexists if
|
|
# Returns 0 if the interface exists and 1 otherwise.
|
|
ifexists()
|
|
{
|
|
[ -z "$1" ] && return 1
|
|
ifconfig -n $1 > /dev/null 2>&1
|
|
}
|
|
|
|
# ipv4_up if
|
|
# add IPv4 addresses to the interface $if
|
|
ipv4_up()
|
|
{
|
|
local _if _ret
|
|
_if=$1
|
|
_ret=1
|
|
|
|
ifalias_up ${_if} inet && _ret=0
|
|
ipv4_addrs_common ${_if} alias && _ret=0
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv6_up if
|
|
# add IPv6 addresses to the interface $if
|
|
ipv6_up()
|
|
{
|
|
local _if _ret
|
|
_if=$1
|
|
_ret=1
|
|
|
|
if ! ipv6if $_if; then
|
|
return 0
|
|
fi
|
|
|
|
ifalias_up ${_if} inet6 && _ret=0
|
|
ipv6_prefix_hostid_addr_up ${_if} && _ret=0
|
|
ipv6_accept_rtadv_up ${_if} && _ret=0
|
|
|
|
# wait for DAD
|
|
sleep `${SYSCTL_N} net.inet6.ip6.dad_count`
|
|
sleep 1
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv4_down if
|
|
# remove IPv4 addresses from the interface $if
|
|
ipv4_down()
|
|
{
|
|
local _if _ifs _ret inetList oldifs _inet
|
|
_if=$1
|
|
_ifs="^"
|
|
_ret=1
|
|
|
|
inetList="`ifconfig ${_if} | grep 'inet ' | tr "\n" "$_ifs"`"
|
|
|
|
oldifs="$IFS"
|
|
IFS="$_ifs"
|
|
for _inet in $inetList ; do
|
|
# get rid of extraneous line
|
|
[ -z "$_inet" ] && break
|
|
|
|
_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
|
|
|
|
IFS="$oldifs"
|
|
ifconfig ${_if} ${_inet} delete
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
ifalias_down ${_if} inet && _ret=0
|
|
ipv4_addrs_common ${_if} -alias && _ret=0
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv6_down if
|
|
# remove IPv6 addresses from the interface $if
|
|
ipv6_down()
|
|
{
|
|
local _if _ifs _ret inetList oldifs _inet6
|
|
_if=$1
|
|
_ifs="^"
|
|
_ret=1
|
|
|
|
if ! ipv6if $_if; then
|
|
return 0
|
|
fi
|
|
|
|
ipv6_accept_rtadv_down ${_if} && _ret=0
|
|
ifalias_down ${_if} inet6 && _ret=0
|
|
|
|
inetList="`ifconfig ${_if} | grep 'inet6 ' | tr "\n" "$_ifs"`"
|
|
|
|
oldifs="$IFS"
|
|
IFS="$_ifs"
|
|
for _inet6 in $inetList ; do
|
|
# get rid of extraneous line
|
|
[ -z "$_inet6" ] && break
|
|
|
|
_inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'`
|
|
|
|
IFS="$oldifs"
|
|
ifconfig ${_if} ${_inet6} -alias
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv4_addrs_common if action
|
|
# Evaluate the ifconfig_if_ipv4 arguments for interface $if and
|
|
# use $action to add or remove IPv4 addresses from $if.
|
|
ipv4_addrs_common()
|
|
{
|
|
local _ret _if _action _cidr _cidr_addr
|
|
local _ipaddr _netmask _range _ipnet _iplow _iphigh _ipcount
|
|
_ret=1
|
|
_if=$1
|
|
_action=$2
|
|
|
|
# get ipv4-addresses
|
|
cidr_addr=`get_if_var $_if ipv4_addrs_IF`
|
|
|
|
for _cidr in ${cidr_addr}; do
|
|
_ipaddr=${_cidr%%/*}
|
|
_netmask="/"${_cidr##*/}
|
|
_range=${_ipaddr##*.}
|
|
_ipnet=${_ipaddr%.*}
|
|
_iplow=${_range%-*}
|
|
_iphigh=${_range#*-}
|
|
|
|
# clear netmask when removing aliases
|
|
if [ "${_action}" = "-alias" ]; then
|
|
_netmask=""
|
|
fi
|
|
|
|
_ipcount=${_iplow}
|
|
while [ "${_ipcount}" -le "${_iphigh}" ]; do
|
|
eval "ifconfig ${_if} ${_action} ${_ipnet}.${_ipcount}${_netmask}"
|
|
_ipcount=$((${_ipcount}+1))
|
|
_ret=0
|
|
|
|
# only the first ipaddr in a subnet need the real netmask
|
|
if [ "${_action}" != "-alias" ]; then
|
|
_netmask="/32"
|
|
fi
|
|
done
|
|
done
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_up if af
|
|
# Configure aliases for network interface $if.
|
|
# It returns 0 if at least one alias was configured or
|
|
# 1 if there were none.
|
|
#
|
|
ifalias_up()
|
|
{
|
|
local _ret
|
|
_ret=1
|
|
|
|
case "$2" in
|
|
inet)
|
|
_ret=`ifalias_ipv4_up "$1"`
|
|
;;
|
|
inet6)
|
|
_ret=`ifalias_ipv6_up "$1"`
|
|
;;
|
|
esac
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_ipv4_up if
|
|
# Helper function for ifalias_up(). Handles IPv4.
|
|
#
|
|
ifalias_ipv4_up()
|
|
{
|
|
local _ret alias ifconfig_args
|
|
_ret=1
|
|
|
|
# ifconfig_IF_aliasN which starts with "inet"
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
inet\ *)
|
|
ifconfig $1 ${ifconfig_args} alias && _ret=0
|
|
;;
|
|
"")
|
|
break
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_ipv6_up if
|
|
# Helper function for ifalias_up(). Handles IPv6.
|
|
#
|
|
ifalias_ipv6_up()
|
|
{
|
|
local _ret alias ifconfig_args
|
|
_ret=1
|
|
|
|
# ifconfig_IF_aliasN which starts with "inet6"
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
inet6\ *)
|
|
ifconfig $1 ${ifconfig_args} alias && _ret=0
|
|
;;
|
|
"")
|
|
break
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
# backward compatibility: ipv6_ifconfig_IF_aliasN.
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
"")
|
|
break
|
|
;;
|
|
*)
|
|
ifconfig $1 inet6 ${ifconfig_args} alias && _ret=0
|
|
warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \
|
|
" Use ifconfig_$1_aliasN instead."
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_down if af
|
|
# Remove aliases for network interface $if.
|
|
# It returns 0 if at least one alias was removed or
|
|
# 1 if there were none.
|
|
#
|
|
ifalias_down()
|
|
{
|
|
local _ret
|
|
_ret=1
|
|
|
|
case "$2" in
|
|
inet)
|
|
_ret=`ifalias_ipv4_down "$1"`
|
|
;;
|
|
inet6)
|
|
_ret=`ifalias_ipv6_down "$1"`
|
|
;;
|
|
esac
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_ipv4_down if
|
|
# Helper function for ifalias_down(). Handles IPv4.
|
|
#
|
|
ifalias_ipv4_down()
|
|
{
|
|
local _ret alias ifconfig_args
|
|
_ret=1
|
|
|
|
# ifconfig_IF_aliasN which starts with "inet"
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
inet\ *)
|
|
ifconfig $1 ${ifconfig_args} -alias && _ret=0
|
|
;;
|
|
"")
|
|
break
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_ipv6_down if
|
|
# Helper function for ifalias_down(). Handles IPv6.
|
|
#
|
|
ifalias_ipv6_down()
|
|
{
|
|
local _ret alias ifconfig_args
|
|
_ret=1
|
|
|
|
# ifconfig_IF_aliasN which starts with "inet6"
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
inet6\ *)
|
|
ifconfig $1 ${ifconfig_args} -alias && _ret=0
|
|
;;
|
|
"")
|
|
break
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
# backward compatibility: ipv6_ifconfig_IF_aliasN.
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF_alias${alias}`
|
|
case "${ifconfig_args}" in
|
|
"")
|
|
break
|
|
;;
|
|
*)
|
|
ifconfig $1 inet6 ${ifconfig_args} -alias && _ret=0
|
|
warn "\$ipv6_ifconfig_$1_alias${alias} is obsolete." \
|
|
" Use ifconfig_$1_aliasN instead."
|
|
;;
|
|
esac
|
|
alias=$((${alias} + 1))
|
|
done
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv6_prefix_hostid_addr_up if
|
|
# add IPv6 prefix + hostid addr to the interface $if
|
|
ipv6_prefix_hostid_addr_up()
|
|
{
|
|
local _if prefix laddr hostid j address
|
|
_if=$1
|
|
prefix=`get_if_var ${_if} ipv6_prefix_IF`
|
|
|
|
if [ -n "${prefix}" ]; then
|
|
laddr=`network6_getladdr ${_if}`
|
|
hostid=${laddr#fe80::}
|
|
hostid=${hostid%\%*}
|
|
|
|
for j in ${prefix}; do
|
|
address=$j\:${hostid}
|
|
ifconfig ${_if} inet6 ${address} prefixlen 64 alias
|
|
|
|
# if I am a router, add subnet router
|
|
# anycast address (RFC 2373).
|
|
if checkyesno ipv6_gateway_enable; then
|
|
ifconfig ${_if} inet6 $j:: prefixlen 64 \
|
|
alias anycast
|
|
fi
|
|
done
|
|
fi
|
|
}
|
|
|
|
# ipv6_accept_rtadv_up if
|
|
# Enable accepting Router Advertisement and send Router
|
|
# Solicitation message
|
|
ipv6_accept_rtadv_up()
|
|
{
|
|
if ipv6_autoconfif $1; then
|
|
ifconfig $1 inet6 accept_rtadv up
|
|
if ! checkyesno rtsold_enable; then
|
|
rtsol ${rtsol_flags} $1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# ipv6_accept_rtadv_down if
|
|
# Disable accepting Router Advertisement
|
|
ipv6_accept_rtadv_down()
|
|
{
|
|
if ipv6_autoconfif $1; then
|
|
ifconfig $1 inet6 -accept_rtadv
|
|
fi
|
|
}
|
|
|
|
# ifscript_up if
|
|
# Evaluate a startup script for the $if interface.
|
|
# It returns 0 if a script was found and processed or
|
|
# 1 if no script was found.
|
|
#
|
|
ifscript_up()
|
|
{
|
|
if [ -r /etc/start_if.$1 ]; then
|
|
. /etc/start_if.$1
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# ifscript_down if
|
|
# Evaluate a shutdown script for the $if interface.
|
|
# It returns 0 if a script was found and processed or
|
|
# 1 if no script was found.
|
|
#
|
|
ifscript_down()
|
|
{
|
|
if [ -r /etc/stop_if.$1 ]; then
|
|
. /etc/stop_if.$1
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# clone_up
|
|
# Create cloneable interfaces.
|
|
#
|
|
clone_up()
|
|
{
|
|
local _prefix _list ifn
|
|
_prefix=
|
|
_list=
|
|
|
|
# create_args_IF
|
|
for ifn in ${cloned_interfaces}; do
|
|
ifconfig ${ifn} create `get_if_var ${ifn} create_args_IF`
|
|
if [ $? -eq 0 ]; then
|
|
_list="${_list}${_prefix}${ifn}"
|
|
[ -z "$_prefix" ] && _prefix=' '
|
|
fi
|
|
done
|
|
debug "Cloned: ${_list}"
|
|
}
|
|
|
|
# clone_down
|
|
# Destroy cloned interfaces. Destroyed interfaces are echoed to
|
|
# standard output.
|
|
#
|
|
clone_down()
|
|
{
|
|
local _prefix _list ifn
|
|
_prefix=
|
|
_list=
|
|
|
|
for ifn in ${cloned_interfaces}; do
|
|
ifconfig ${ifn} destroy
|
|
if [ $? -eq 0 ]; then
|
|
_list="${_list}${_prefix}${ifn}"
|
|
[ -z "$_prefix" ] && _prefix=' '
|
|
fi
|
|
done
|
|
debug "Destroyed clones: ${_list}"
|
|
}
|
|
|
|
# childif_create
|
|
# Create and configure child interfaces. Return 0 if child
|
|
# interfaces are created.
|
|
#
|
|
childif_create()
|
|
{
|
|
local cfg child child_vlans child_wlans create_args debug_flags ifn i
|
|
cfg=1
|
|
ifn=$1
|
|
|
|
# Create wireless interfaces
|
|
child_wlans=`get_if_var $ifn wlans_IF`
|
|
|
|
for child in ${child_wlans}; do
|
|
create_args="wlandev $ifn `get_if_var $child create_args_IF`"
|
|
debug_flags="`get_if_var $child wlandebug_IF`"
|
|
|
|
if expr $child : 'wlan[0-9][0-9]*$' >/dev/null 2>&1; then
|
|
ifconfig $child create ${create_args} && cfg=0
|
|
if [ -n "${debug_flags}" ]; then
|
|
wlandebug -i $child ${debug_flags}
|
|
fi
|
|
else
|
|
i=`ifconfig wlan create ${create_args}`
|
|
if [ -n "${debug_flags}" ]; then
|
|
wlandebug -i $i ${debug_flags}
|
|
fi
|
|
ifconfig $i name $child && cfg=0
|
|
fi
|
|
if autoif $child; then
|
|
ifn_start $child
|
|
fi
|
|
done
|
|
|
|
# Create vlan interfaces
|
|
child_vlans=`get_if_var $ifn vlans_IF`
|
|
|
|
if [ -n "${child_vlans}" ]; then
|
|
load_kld if_vlan
|
|
fi
|
|
|
|
for child in ${child_vlans}; do
|
|
if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
|
|
child="${ifn}.${child}"
|
|
create_args=`get_if_var $child create_args_IF`
|
|
ifconfig $child create ${create_args} && cfg=0
|
|
else
|
|
create_args="vlandev $ifn `get_if_var $child create_args_IF`"
|
|
if expr $child : 'vlan[0-9][0-9]*$' >/dev/null 2>&1; then
|
|
ifconfig $child create ${create_args} && cfg=0
|
|
else
|
|
i=`ifconfig vlan create ${create_args}`
|
|
ifconfig $i name $child && cfg=0
|
|
fi
|
|
fi
|
|
if autoif $child; then
|
|
ifn_start $child
|
|
fi
|
|
done
|
|
|
|
return ${cfg}
|
|
}
|
|
|
|
# childif_destroy
|
|
# Destroy child interfaces.
|
|
#
|
|
childif_destroy()
|
|
{
|
|
local cfg child child_vlans child_wlans ifn
|
|
cfg=1
|
|
|
|
child_wlans=`get_if_var $ifn wlans_IF`
|
|
for child in ${child_wlans}; do
|
|
if ! ifexists $child; then
|
|
continue
|
|
fi
|
|
if autoif $child; then
|
|
ifn_stop $child
|
|
fi
|
|
ifconfig $child destroy && cfg=0
|
|
done
|
|
|
|
child_vlans=`get_if_var $ifn vlans_IF`
|
|
for child in ${child_vlans}; do
|
|
if expr $child : '[1-9][0-9]*$' >/dev/null 2>&1; then
|
|
child="${ifn}.${child}"
|
|
fi
|
|
if ! ifexists $child; then
|
|
continue
|
|
fi
|
|
if autoif $child; then
|
|
ifn_stop $child
|
|
fi
|
|
ifconfig $child destroy && cfg=0
|
|
done
|
|
|
|
return ${cfg}
|
|
}
|
|
|
|
# ng_mkpeer
|
|
# Create netgraph nodes.
|
|
#
|
|
ng_mkpeer()
|
|
{
|
|
ngctl -f - 2> /dev/null <<EOF
|
|
mkpeer $*
|
|
msg dummy nodeinfo
|
|
EOF
|
|
}
|
|
|
|
# ng_create_one
|
|
# Create netgraph nodes.
|
|
#
|
|
ng_create_one()
|
|
{
|
|
local t
|
|
|
|
ng_mkpeer $* | while read line; do
|
|
t=`expr "${line}" : '.* name="\([a-z]*[0-9]*\)" .*'`
|
|
if [ -n "${t}" ]; then
|
|
echo ${t}
|
|
return
|
|
fi
|
|
done
|
|
}
|
|
|
|
# gif_up
|
|
# Create gif(4) tunnel interfaces.
|
|
gif_up()
|
|
{
|
|
local i peers
|
|
|
|
for i in ${gif_interfaces}; do
|
|
peers=`get_if_var $i gifconfig_IF`
|
|
case ${peers} in
|
|
'')
|
|
continue
|
|
;;
|
|
*)
|
|
if expr $i : 'gif[0-9][0-9]*$' >/dev/null 2>&1; then
|
|
ifconfig $i create >/dev/null 2>&1
|
|
else
|
|
gif=`ifconfig gif create`
|
|
ifconfig $gif name $i
|
|
fi
|
|
ifconfig $i tunnel ${peers}
|
|
ifconfig $i up
|
|
;;
|
|
esac
|
|
done
|
|
}
|
|
|
|
# ng_fec_create ifn
|
|
# Configure Fast EtherChannel for interface $ifn. Returns 0 if
|
|
# FEC arguments were found and configured; returns !0 otherwise.
|
|
ng_fec_create()
|
|
{
|
|
local req_iface iface bogus
|
|
req_iface="$1"
|
|
|
|
ngctl shutdown ${req_iface}: > /dev/null 2>&1
|
|
|
|
bogus=""
|
|
while true; do
|
|
iface=`ng_create_one fec dummy fec`
|
|
if [ -z "${iface}" ]; then
|
|
exit 2
|
|
fi
|
|
if [ "${iface}" = "${req_iface}" ]; then
|
|
break
|
|
fi
|
|
bogus="${bogus} ${iface}"
|
|
done
|
|
|
|
for iface in ${bogus}; do
|
|
ngctl shutdown ${iface}:
|
|
done
|
|
}
|
|
|
|
# fec_up
|
|
# Create Fast EtherChannel interfaces.
|
|
fec_up()
|
|
{
|
|
local i j
|
|
|
|
for i in ${fec_interfaces}; do
|
|
ng_fec_create $i
|
|
for j in `get_if_var $i fecconfig_IF`; do
|
|
case ${j} in
|
|
'')
|
|
continue
|
|
;;
|
|
*)
|
|
ngctl msg ${i}: add_iface "\"${j}\""
|
|
;;
|
|
esac
|
|
done
|
|
done
|
|
}
|
|
|
|
# ipx_up ifn
|
|
# Configure any IPX addresses for interface $ifn. Returns 0 if
|
|
# IPX arguments were found and configured; returns 1 otherwise.
|
|
#
|
|
ipx_up()
|
|
{
|
|
local ifn
|
|
ifn="$1"
|
|
|
|
# ifconfig_IF_ipx
|
|
ifconfig_args=`_ifconfig_getargs $ifn ipx`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
ifconfig ${ifn} ${ifconfig_args}
|
|
return 0
|
|
fi
|
|
|
|
return 1
|
|
}
|
|
|
|
# ipx_down ifn
|
|
# Remove IPX addresses for interface $ifn. Returns 0 if IPX
|
|
# addresses were found and unconfigured. It returns 1, otherwise.
|
|
#
|
|
ipx_down()
|
|
{
|
|
local _if _ifs _ret ipxList oldifs _ipx
|
|
_if=$1
|
|
_ifs="^"
|
|
_ret=1
|
|
ipxList="`ifconfig ${_if} | grep 'ipx ' | tr "\n" "$_ifs"`"
|
|
oldifs="$IFS"
|
|
|
|
IFS="$_ifs"
|
|
for _ipx in $ipxList ; do
|
|
# get rid of extraneous line
|
|
[ -z "$_ipx" ] && break
|
|
|
|
_ipx=`expr "$_ipx" : '.*\(ipx [0-9a-h]\{1,8\}H*\.[0-9a-h]\{1,12\}\).*'`
|
|
|
|
IFS="$oldifs"
|
|
ifconfig ${_if} ${_ipx} delete
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifnet_rename
|
|
# Rename all requested interfaces.
|
|
#
|
|
ifnet_rename()
|
|
{
|
|
local _if _ifname
|
|
|
|
# ifconfig_IF_name
|
|
for _if in `ifconfig -l`; do
|
|
_ifname=`get_if_var $_if ifconfig_IF_name`
|
|
if [ ! -z "$_ifname" ]; then
|
|
ifconfig $_if name $_ifname
|
|
fi
|
|
done
|
|
|
|
return 0
|
|
}
|
|
|
|
# list_net_interfaces type
|
|
# List all network interfaces. The type of interface returned
|
|
# can be controlled by the type argument. The type
|
|
# argument can be any of the following:
|
|
# nodhcp - all interfaces, excluding DHCP configured interfaces
|
|
# dhcp - list only DHCP configured interfaces
|
|
# noautoconf - all interfaces, excluding IPv6 Stateless
|
|
# Address Autoconf configured interfaces
|
|
# autoconf - list only IPv6 Stateless Address Autoconf
|
|
# configured interfaces
|
|
# If no argument is specified all network interfaces are output.
|
|
# Note that the list will include cloned interfaces if applicable.
|
|
# Cloned interfaces must already exist to have a chance to appear
|
|
# in the list if ${network_interfaces} is set to `auto'.
|
|
#
|
|
list_net_interfaces()
|
|
{
|
|
local type _tmplist _list _autolist _lo _if
|
|
type=$1
|
|
|
|
# Get a list of ALL the interfaces and make lo0 first if it's there.
|
|
#
|
|
_tmplist=
|
|
case ${network_interfaces} in
|
|
[Aa][Uu][Tt][Oo])
|
|
_autolist="`ifconfig -l`"
|
|
_lo=
|
|
for _if in ${_autolist} ; do
|
|
if autoif $_if; then
|
|
if [ "$_if" = "lo0" ]; then
|
|
_lo="lo0 "
|
|
else
|
|
_tmplist="${_tmplist} ${_if}"
|
|
fi
|
|
fi
|
|
done
|
|
_tmplist="${_lo}${_tmplist# }"
|
|
;;
|
|
*)
|
|
_tmplist="${network_interfaces} ${cloned_interfaces}"
|
|
|
|
# lo0 is effectively mandatory, so help prevent foot-shooting
|
|
#
|
|
case "$_tmplist" in
|
|
lo0|'lo0 '*|*' lo0'|*' lo0 '*) ;; # This is fine, do nothing
|
|
*) _tmplist="lo0 ${_tmplist}" ;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
_list=
|
|
case "$type" in
|
|
nodhcp)
|
|
for _if in ${_tmplist} ; do
|
|
if ! dhcpif $_if && \
|
|
[ -n "`_ifconfig_getargs $_if`" ]; then
|
|
_list="${_list# } ${_if}"
|
|
fi
|
|
done
|
|
;;
|
|
dhcp)
|
|
for _if in ${_tmplist} ; do
|
|
if dhcpif $_if; then
|
|
_list="${_list# } ${_if}"
|
|
fi
|
|
done
|
|
;;
|
|
noautoconf)
|
|
for _if in ${_tmplist} ; do
|
|
if ! ipv6_autoconfif $_if && \
|
|
[ -n "`_ifconfig_getargs $_if ipv6`" ]; then
|
|
_list="${_list# } ${_if}"
|
|
fi
|
|
done
|
|
;;
|
|
autoconf)
|
|
for _if in ${_tmplist} ; do
|
|
if ipv6_autoconfif $_if; then
|
|
_list="${_list# } ${_if}"
|
|
fi
|
|
done
|
|
;;
|
|
*)
|
|
_list=${_tmplist}
|
|
;;
|
|
esac
|
|
|
|
echo $_list
|
|
|
|
return 0
|
|
}
|
|
|
|
# get_default_if -address_family
|
|
# Get the interface of the default route for the given address family.
|
|
# The -address_family argument must be suitable passing to route(8).
|
|
#
|
|
get_default_if()
|
|
{
|
|
local routeget oldifs defif line
|
|
defif=
|
|
oldifs="$IFS"
|
|
IFS="
|
|
"
|
|
for line in `route -n get $1 default 2>/dev/null`; do
|
|
case $line in
|
|
*interface:*)
|
|
defif=${line##*: }
|
|
;;
|
|
esac
|
|
done
|
|
IFS=${oldifs}
|
|
|
|
echo $defif
|
|
}
|
|
|
|
# hexdigit arg
|
|
# Echo decimal number $arg (single digit) in hexadecimal format.
|
|
hexdigit()
|
|
{
|
|
if [ $1 -lt 10 ]; then
|
|
echo $1
|
|
else
|
|
case $1 in
|
|
10) echo a ;;
|
|
11) echo b ;;
|
|
12) echo c ;;
|
|
13) echo d ;;
|
|
14) echo e ;;
|
|
15) echo f ;;
|
|
esac
|
|
fi
|
|
}
|
|
|
|
# hexprint arg
|
|
# Echo decimal number $arg (multiple digits) in hexadecimal format.
|
|
hexprint()
|
|
{
|
|
local val str dig
|
|
val=$1
|
|
str=''
|
|
dig=`hexdigit $((${val} & 15))`
|
|
str=${dig}${str}
|
|
val=$((${val} >> 4))
|
|
|
|
while [ ${val} -gt 0 ]; do
|
|
dig=`hexdigit $((${val} & 15))`
|
|
str=${dig}${str}
|
|
val=$((${val} >> 4))
|
|
done
|
|
|
|
echo ${str}
|
|
}
|
|
|
|
is_wired_interface()
|
|
{
|
|
local media
|
|
|
|
case `ifconfig $1 2>/dev/null` in
|
|
*media:?Ethernet*) media=Ethernet ;;
|
|
esac
|
|
|
|
test "$media" = "Ethernet"
|
|
}
|
|
|
|
# network6_getladdr if [flag]
|
|
# Echo link-local address from $if if any.
|
|
# If flag is defined, tentative ones will be excluded.
|
|
network6_getladdr()
|
|
{
|
|
local proto addr rest
|
|
ifconfig $1 2>/dev/null | while read proto addr rest; do
|
|
case ${proto} in
|
|
inet6)
|
|
case ${addr} in
|
|
fe80::*)
|
|
if [ -z "$2" ]; then
|
|
echo ${addr}
|
|
return
|
|
fi
|
|
case ${rest} in
|
|
*tentative*)
|
|
continue
|
|
;;
|
|
*)
|
|
echo ${addr}
|
|
return
|
|
esac
|
|
esac
|
|
esac
|
|
done
|
|
}
|