b1865d5303
Now that printf(1) is a shell builtin, there is no need to emulate it anymore. The external printf(1) is /usr/bin/printf and therefore may not be available in early boot. It may be faster to use printf directly but the function is useful for compatibility.
1384 lines
26 KiB
Plaintext
1384 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
|
|
if checkyesno ipv6_gateway_enable; then
|
|
_ipv6_opts="-accept_rtadv"
|
|
fi
|
|
else
|
|
if checkyesno ipv6_activate_all_interfaces; then
|
|
_ipv6_opts="-ifdisabled"
|
|
else
|
|
_ipv6_opts="ifdisabled"
|
|
fi
|
|
|
|
# backward compatibility: $ipv6_enable
|
|
case $ipv6_enable in
|
|
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
|
|
_ipv6_opts="${_ipv6_opts} accept_rtadv"
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [ -n "${_ipv6_opts}" ]; then
|
|
ifconfig $1 inet6 ${_ipv6_opts}
|
|
fi
|
|
|
|
# ifconfig_IF_ipv6
|
|
ifconfig_args=`ifconfig_getargs $1 ipv6`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
ifconfig $1 inet6 -ifdisabled
|
|
ifconfig $1 ${ifconfig_args}
|
|
_cfg=0
|
|
fi
|
|
|
|
# backward compatiblity: $ipv6_ifconfig_IF
|
|
ifconfig_args=`get_if_var $1 ipv6_ifconfig_IF`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
warn "\$ipv6_ifconfig_$1 is obsolete." \
|
|
" Use ifconfig_$1_ipv6 instead."
|
|
ifconfig $1 inet6 -ifdisabled
|
|
ifconfig $1 inet6 ${ifconfig_args}
|
|
_cfg=0
|
|
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
|
|
_ifn=$1
|
|
_af=${2+_$2}
|
|
|
|
if [ -z "$_ifn" ]; then
|
|
return 1
|
|
fi
|
|
|
|
get_if_var $_ifn ifconfig_IF$_af "$ifconfig_DEFAULT"
|
|
}
|
|
|
|
# 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]) ;;
|
|
*)
|
|
_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
|
|
}
|
|
|
|
# noafif if
|
|
# Returns 0 if the interface has no af configuration and 1 otherwise.
|
|
noafif()
|
|
{
|
|
local _if
|
|
_if=$1
|
|
|
|
case $_if in
|
|
pflog[0-9]*|\
|
|
pfsync[0-9]*|\
|
|
an[0-9]*|\
|
|
ath[0-9]*|\
|
|
ipw[0-9]*|\
|
|
ipfw[0-9]*|\
|
|
iwi[0-9]*|\
|
|
iwn[0-9]*|\
|
|
ral[0-9]*|\
|
|
wi[0-9]*|\
|
|
wl[0-9]*|\
|
|
wpi[0-9]*)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
# ipv6if if
|
|
# Returns 0 if the interface should be configured for IPv6 and
|
|
# 1 otherwise.
|
|
ipv6if()
|
|
{
|
|
local _if _tmpargs i
|
|
_if=$1
|
|
|
|
if ! afexists inet6; then
|
|
return 1
|
|
fi
|
|
|
|
# lo0 is always IPv6-enabled
|
|
case $_if in
|
|
lo0)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
case "${ipv6_network_interfaces}" in
|
|
$_if|"$_if "*|*" $_if"|*" $_if "*|[Aa][Uu][Tt][Oo])
|
|
# True if $ifconfig_IF_ipv6 is defined.
|
|
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
|
if [ -n "${_tmpargs}" ]; then
|
|
return 0
|
|
fi
|
|
|
|
# backward compatibility: True if $ipv6_ifconfig_IF is defined.
|
|
_tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
|
|
if [ -n "${_tmpargs}" ]; then
|
|
return 0
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
return 1
|
|
}
|
|
|
|
# ipv6_autoconfif if
|
|
# Returns 0 if the interface should be configured for IPv6 with
|
|
# Stateless Address Configuration, 1 otherwise.
|
|
ipv6_autoconfif()
|
|
{
|
|
local _if _tmpargs _arg
|
|
_if=$1
|
|
|
|
case $_if in
|
|
lo0|\
|
|
stf[0-9]*|\
|
|
faith[0-9]*|\
|
|
lp[0-9]*|\
|
|
sl[0-9]*)
|
|
return 1
|
|
;;
|
|
esac
|
|
if noafif $_if; then
|
|
return 1
|
|
fi
|
|
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
|
|
# backward compatibility: $ipv6_enable
|
|
case $ipv6_enable in
|
|
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
|
|
return 0
|
|
;;
|
|
esac
|
|
|
|
_tmpargs=`_ifconfig_getargs $_if ipv6`
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
accept_rtadv)
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# backward compatibility: $ipv6_ifconfig_IF
|
|
_tmpargs=`get_if_var $_if ipv6_ifconfig_IF`
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
accept_rtadv)
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
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 -n ${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
|
|
ifconfig -n $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
|
|
ifconfig -n $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()
|
|
{
|
|
printf '%x\n' "$1"
|
|
}
|
|
|
|
# hexprint arg
|
|
# Echo decimal number $arg (multiple digits) in hexadecimal format.
|
|
hexprint()
|
|
{
|
|
printf '%x\n' "$1"
|
|
}
|
|
|
|
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
|
|
}
|