7887fd3f23
subinterfaces) after they are created. Interfaces are already started by devd invoking /etc/pccard_ether when they are created, so the explicit calls in childif_create() resulted in interfaces being started twice. Note that interfaces created via cloned_interfaces are not explicitly started but depend on the devd mechanism already. MFC after: 1 week
1769 lines
35 KiB
Plaintext
1769 lines
35 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$
|
|
#
|
|
IFCONFIG_CMD="/sbin/ifconfig"
|
|
|
|
# Maximum number of addresses expanded from a address range specification.
|
|
_IPEXPANDMAX=31
|
|
|
|
#
|
|
# 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
|
|
if ! noafif $ifn; then
|
|
afexists inet && ipv4_up ${ifn} && cfg=0
|
|
afexists inet6 && ipv6_up ${ifn} && cfg=0
|
|
afexists ipx && ipx_up ${ifn} && cfg=0
|
|
fi
|
|
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"
|
|
|
|
if ! noafif $ifn; then
|
|
afexists ipx && ipx_down ${ifn} && cfg=0
|
|
afexists inet6 && ipv6_down ${ifn} && cfg=0
|
|
afexists inet && ipv4_down ${ifn} && cfg=0
|
|
fi
|
|
ifconfig_down ${ifn} && cfg=0
|
|
ifscript_down ${ifn} && cfg=0
|
|
childif_destroy ${ifn} && cfg=0
|
|
|
|
return $cfg
|
|
}
|
|
|
|
# ifn_vnetup ifn
|
|
# Move ifn to the specified vnet jail.
|
|
#
|
|
ifn_vnetup()
|
|
{
|
|
|
|
ifn_vnet0 $1 vnet
|
|
}
|
|
|
|
# ifn_vnetdown ifn
|
|
# Reclaim ifn from the specified vnet jail.
|
|
#
|
|
ifn_vnetdown()
|
|
{
|
|
|
|
ifn_vnet0 $1 -vnet
|
|
}
|
|
|
|
# ifn_vnet0 ifn action
|
|
# Helper function for ifn_vnetup and ifn_vnetdown.
|
|
#
|
|
ifn_vnet0()
|
|
{
|
|
local _ifn _cfg _action _vnet
|
|
_ifn="$1"
|
|
_action="$2"
|
|
_cfg=1
|
|
|
|
if _vnet=$(vnetif $_ifn); then
|
|
${IFCONFIG_CMD} $_ifn $_action $_vnet && _cfg=0
|
|
fi
|
|
|
|
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
|
|
|
|
# Make sure lo0 always comes up.
|
|
if [ "$1" = "lo0" ]; then
|
|
_cfg=0
|
|
fi
|
|
|
|
# ifconfig_IF
|
|
ifconfig_args=`ifconfig_getargs $1`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
|
|
_cfg=0
|
|
fi
|
|
|
|
# inet6 specific
|
|
if ! noafif $1 && afexists inet6; then
|
|
if checkyesno ipv6_activate_all_interfaces; then
|
|
_ipv6_opts="-ifdisabled"
|
|
elif [ "$1" != "lo0" ]; then
|
|
_ipv6_opts="ifdisabled"
|
|
fi
|
|
|
|
# backward compatibility: $ipv6_enable
|
|
case $ipv6_enable in
|
|
[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1)
|
|
case $1 in
|
|
bridge[0-9]*)
|
|
# No accept_rtadv by default on if_bridge(4)
|
|
# to avoid a conflict with the member
|
|
# interfaces.
|
|
;;
|
|
*)
|
|
if ! checkyesno ipv6_gateway_enable; then
|
|
_ipv6_opts="${_ipv6_opts} accept_rtadv"
|
|
fi
|
|
;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
case $ipv6_cpe_wanif in
|
|
$1)
|
|
_ipv6_opts="${_ipv6_opts} -no_radr accept_rtadv"
|
|
;;
|
|
esac
|
|
|
|
if [ -n "${_ipv6_opts}" ]; then
|
|
${IFCONFIG_CMD} $1 inet6 ${_ipv6_opts}
|
|
fi
|
|
|
|
# ifconfig_IF_ipv6
|
|
ifconfig_args=`ifconfig_getargs $1 ipv6`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
# backward compatibility: inet6 keyword
|
|
case "${ifconfig_args}" in
|
|
:*|[0-9a-fA-F]*:*)
|
|
warn "\$ifconfig_$1_ipv6 needs " \
|
|
"\"inet6\" keyword for an IPv6 address."
|
|
ifconfig_args="inet6 ${ifconfig_args}"
|
|
;;
|
|
esac
|
|
${IFCONFIG_CMD} $1 inet6 -ifdisabled
|
|
eval ${IFCONFIG_CMD} $1 ${ifconfig_args}
|
|
_cfg=0
|
|
fi
|
|
|
|
# $ipv6_prefix_IF will be handled in
|
|
# ipv6_prefix_hostid_addr_common().
|
|
ifconfig_args=`get_if_var $1 ipv6_prefix_IF`
|
|
if [ -n "${ifconfig_args}" ]; then
|
|
${IFCONFIG_CMD} $1 inet6 -ifdisabled
|
|
_cfg=0
|
|
fi
|
|
|
|
# backward compatibility: $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_CMD} $1 inet6 -ifdisabled
|
|
eval ${IFCONFIG_CMD} $1 inet6 ${ifconfig_args}
|
|
_cfg=0
|
|
fi
|
|
fi
|
|
|
|
ifalias $1 link alias
|
|
ifalias $1 ether alias
|
|
|
|
if [ ${_cfg} -eq 0 ]; then
|
|
${IFCONFIG_CMD} $1 up
|
|
fi
|
|
|
|
if wpaif $1; then
|
|
/etc/rc.d/wpa_supplicant start $1
|
|
_cfg=0 # XXX: not sure this should count
|
|
elif hostapif $1; then
|
|
/etc/rc.d/hostapd start $1
|
|
_cfg=0
|
|
fi
|
|
|
|
if dhcpif $1; then
|
|
if [ $_cfg -ne 0 ] ; then
|
|
${IFCONFIG_CMD} $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
|
|
elif hostapif $1; then
|
|
/etc/rc.d/hostapd stop $1
|
|
_cfg=0
|
|
fi
|
|
|
|
if dhcpif $1; then
|
|
/etc/rc.d/dhclient stop $1
|
|
_cfg=0
|
|
fi
|
|
|
|
if ifexists $1; then
|
|
${IFCONFIG_CMD} $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]
|
|
# Prints 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 _vnet
|
|
_tmpargs=`_ifconfig_getargs $1 $2`
|
|
if [ $? -eq 1 ]; then
|
|
return 1
|
|
fi
|
|
_args=
|
|
_vnet=0
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg:$_vnet in
|
|
[Dd][Hh][Cc][Pp]:0) ;;
|
|
[Nn][Oo][Aa][Uu][Tt][Oo]:0) ;;
|
|
[Nn][Oo][Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;;
|
|
[Ss][Yy][Nn][Cc][Dd][Hh][Cc][Pp]:0) ;;
|
|
[Ww][Pp][Aa]:0) ;;
|
|
[Hh][Oo][Ss][Tt][Aa][Pp]:0) ;;
|
|
vnet:0) _vnet=1 ;;
|
|
*:1) _vnet=0 ;;
|
|
*:0)
|
|
_args="$_args $_arg"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo $_args
|
|
}
|
|
|
|
# autoif
|
|
# Returns 0 if the interface should be automatically 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`
|
|
|
|
case $1 in
|
|
lo[0-9]*|\
|
|
stf[0-9]*|\
|
|
faith[0-9]*|\
|
|
lp[0-9]*|\
|
|
sl[0-9]*)
|
|
return 1
|
|
;;
|
|
esac
|
|
if noafif $1; then
|
|
return 1
|
|
fi
|
|
|
|
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`
|
|
|
|
if noafif $1; then
|
|
return 1
|
|
fi
|
|
|
|
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
|
|
}
|
|
|
|
# hostapif if
|
|
# Returns 0 if the interface is a HOSTAP interface and 1 otherwise.
|
|
hostapif()
|
|
{
|
|
local _tmpargs _arg
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
for _arg in $_tmpargs; do
|
|
case $_arg in
|
|
[Hh][Oo][Ss][Tt][Aa][Pp])
|
|
return 0
|
|
;;
|
|
esac
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
# vnetif if
|
|
# Returns 0 and echo jail if "vnet" keyword is specified on the
|
|
# interface, and 1 otherwise.
|
|
vnetif()
|
|
{
|
|
local _tmpargs _arg _vnet
|
|
_tmpargs=`_ifconfig_getargs $1`
|
|
|
|
_vnet=0
|
|
for _arg in $_tmpargs; do
|
|
case $_arg:$_vnet in
|
|
vnet:0) _vnet=1 ;;
|
|
*:1) echo $_arg; 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|inet6)
|
|
check_kern_features ${_af}
|
|
;;
|
|
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
|
|
;;
|
|
link|ether)
|
|
return 0
|
|
;;
|
|
*)
|
|
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]*|\
|
|
usbus[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
|
|
|
|
# True if $ipv6_prefix_IF is defined.
|
|
_tmpargs=`get_if_var $_if ipv6_prefix_IF`
|
|
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
|
|
lo[0-9]*|\
|
|
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)
|
|
if checkyesno ipv6_gateway_enable; then
|
|
return 1
|
|
fi
|
|
case $1 in
|
|
bridge[0-9]*)
|
|
# No accept_rtadv by default on if_bridge(4)
|
|
# to avoid a conflict with the member
|
|
# interfaces.
|
|
return 1
|
|
;;
|
|
*)
|
|
return 0
|
|
;;
|
|
esac
|
|
;;
|
|
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_CMD} -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
|
|
|
|
# Add 127.0.0.1/8 to lo0 unless otherwise specified.
|
|
if [ "${_if}" = "lo0" ]; then
|
|
ifconfig_args=`get_if_var ${_if} ifconfig_IF`
|
|
if [ -z "${ifconfig_args}" ]; then
|
|
${IFCONFIG_CMD} ${_if} inet 127.0.0.1/8 alias
|
|
fi
|
|
fi
|
|
ifalias ${_if} inet 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 ${_if} inet6 alias && _ret=0
|
|
ipv6_prefix_hostid_addr_common ${_if} alias && _ret=0
|
|
ipv6_accept_rtadv_up ${_if} && _ret=0
|
|
|
|
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
|
|
|
|
ifalias ${_if} inet -alias && _ret=0
|
|
|
|
inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet ' | tr "\n\t" "$_ifs"`"
|
|
|
|
oldifs="$IFS"
|
|
IFS="$_ifs"
|
|
for _inet in $inetList ; do
|
|
# get rid of extraneous line
|
|
case $_inet in
|
|
inet\ *) ;;
|
|
*) continue ;;
|
|
esac
|
|
|
|
_inet=`expr "$_inet" : '.*\(inet \([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\).*'`
|
|
|
|
IFS="$oldifs"
|
|
${IFCONFIG_CMD} ${_if} ${_inet} delete
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
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
|
|
ipv6_prefix_hostid_addr_common ${_if} -alias && _ret=0
|
|
ifalias ${_if} inet6 -alias && _ret=0
|
|
|
|
inetList="`${IFCONFIG_CMD} ${_if} | grep 'inet6 ' | tr "\n\t" "$_ifs"`"
|
|
|
|
oldifs="$IFS"
|
|
IFS="$_ifs"
|
|
for _inet6 in $inetList ; do
|
|
# get rid of extraneous line
|
|
case $_inet in
|
|
inet6\ *) ;;
|
|
*) continue ;;
|
|
esac
|
|
|
|
_inet6=`expr "$_inet6" : '.*\(inet6 \([0-9a-f:]*\)\).*'`
|
|
|
|
IFS="$oldifs"
|
|
${IFCONFIG_CMD} ${_if} ${_inet6} -alias
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias if af action
|
|
# Configure or remove aliases for network interface $if.
|
|
# It returns 0 if at least one alias was configured or
|
|
# removed, or 1 if there were none.
|
|
#
|
|
ifalias()
|
|
{
|
|
local _ret
|
|
_ret=1
|
|
|
|
afexists $2 || return $_ret
|
|
|
|
case "$2" in
|
|
inet|inet6|link|ether)
|
|
ifalias_af_common $1 $2 $3 && _ret=0
|
|
;;
|
|
esac
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_expand_addr af action addr
|
|
# Expand address range ("N-M") specification in addr.
|
|
# "addr" must not include an address-family keyword.
|
|
# The results will include an address-family keyword.
|
|
#
|
|
ifalias_expand_addr()
|
|
{
|
|
local _af _action
|
|
|
|
_af=$1
|
|
_action=$2
|
|
shift 2
|
|
|
|
afexists $_af || return
|
|
ifalias_expand_addr_$_af $_action $*
|
|
}
|
|
|
|
# ifalias_expand_addr_inet action addr
|
|
# Helper function for ifalias_expand_addr(). Handles IPv4.
|
|
#
|
|
ifalias_expand_addr_inet()
|
|
{
|
|
local _action _arg _cidr _cidr_addr _exargs
|
|
local _ipaddr _plen _range _iphead _iptail _iplow _iphigh _ipcount
|
|
local _retstr _c
|
|
_action=$1
|
|
_arg=$2
|
|
shift 2
|
|
_exargs=$*
|
|
_retstr=
|
|
|
|
case $_action:$_arg:$_exargs in
|
|
*:*--*) return ;; # invalid
|
|
tmp:*[0-9]-[0-9]*:*) # to be expanded
|
|
_action="alias"
|
|
;;
|
|
*:*[0-9]-[0-9]*:*) # to be expanded
|
|
;;
|
|
tmp:*:*netmask*) # already expanded w/ netmask option
|
|
echo ${_arg%/[0-9]*} $_exargs && return
|
|
;;
|
|
tmp:*:*) # already expanded w/o netmask option
|
|
echo $_arg $_exargs && return
|
|
;;
|
|
*:*:*netmask*) # already expanded w/ netmask option
|
|
echo inet ${_arg%/[0-9]*} $_exargs && return
|
|
;;
|
|
*:*:*) # already expanded w/o netmask option
|
|
echo inet $_arg $_exargs && return
|
|
;;
|
|
esac
|
|
|
|
for _cidr in $_arg; do
|
|
_ipaddr=${_cidr%%/*}
|
|
_plen=${_cidr##*/}
|
|
# When subnet prefix length is not specified, use /32.
|
|
case $_plen in
|
|
$_ipaddr) _plen=32 ;; # "/" character not found
|
|
esac
|
|
|
|
OIFS=$IFS
|
|
IFS=. set -- $_ipaddr
|
|
_range=
|
|
_iphead=
|
|
_iptail=
|
|
for _c in $@; do
|
|
case $_range:$_c in
|
|
:[0-9]*-[0-9]*)
|
|
_range=$_c
|
|
;;
|
|
:*)
|
|
_iphead="${_iphead}${_iphead:+.}${_c}"
|
|
;;
|
|
*:*)
|
|
_iptail="${_iptail}${_iptail:+.}${_c}"
|
|
;;
|
|
esac
|
|
done
|
|
IFS=$OIFS
|
|
_iplow=${_range%-*}
|
|
_iphigh=${_range#*-}
|
|
|
|
# clear netmask when removing aliases
|
|
if [ "$_action" = "-alias" ]; then
|
|
_plen=""
|
|
fi
|
|
|
|
_ipcount=$_iplow
|
|
while [ "$_ipcount" -le "$_iphigh" ]; do
|
|
_retstr="${_retstr} ${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail}${_plen:+/}${_plen}"
|
|
if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]; then
|
|
warn "Range specification is too large (${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_iphigh}${_iptail:+.}${_iptail}). ${_iphead}${_iphead:+.}${_iplow}${_iptail:+.}${_iptail}-${_iphead}${_iphead:+.}${_ipcount}${_iptail:+.}${_iptail} was processed."
|
|
break
|
|
else
|
|
_ipcount=$(($_ipcount + 1))
|
|
fi
|
|
# Forcibly set /32 for remaining aliases.
|
|
_plen=32
|
|
done
|
|
done
|
|
|
|
for _c in $_retstr; do
|
|
ifalias_expand_addr_inet $_action $_c $_exargs
|
|
done
|
|
}
|
|
|
|
# ifalias_expand_addr_inet6 action addr
|
|
# Helper function for ifalias_expand_addr(). Handles IPv6.
|
|
#
|
|
ifalias_expand_addr_inet6()
|
|
{
|
|
local _action _arg _cidr _cidr_addr _exargs
|
|
local _ipaddr _plen _ipleft _ipright _iplow _iphigh _ipcount
|
|
local _ipv4part
|
|
local _retstr _c
|
|
_action=$1
|
|
_arg=$2
|
|
shift 2
|
|
_exargs=$*
|
|
_retstr=
|
|
|
|
case $_action:$_arg:$_exargs in
|
|
*:*--*:*) return ;; # invalid
|
|
tmp:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*)# to be expanded
|
|
_action="alias"
|
|
;;
|
|
*:*[0-9a-zA-Z]-[0-9a-zA-Z]*:*) # to be expanded
|
|
;;
|
|
tmp:*:*prefixlen*) # already expanded w/ prefixlen option
|
|
echo ${_arg%/[0-9]*} $_exargs && return
|
|
;;
|
|
tmp:*:*) # already expanded w/o prefixlen option
|
|
echo $_arg $_exargs && return
|
|
;;
|
|
*:*:*prefixlen*) # already expanded w/ prefixlen option
|
|
echo inet6 ${_arg%/[0-9]*} $_exargs && return
|
|
;;
|
|
*:*:*) # already expanded w/o prefixlen option
|
|
echo inet6 $_arg $_exargs && return
|
|
;;
|
|
esac
|
|
|
|
for _cidr in $_arg; do
|
|
_ipaddr="${_cidr%%/*}"
|
|
_plen="${_cidr##*/}"
|
|
|
|
case $_action:$_ipaddr:$_cidr in
|
|
-alias:*:*) unset _plen ;;
|
|
*:$_cidr:$_ipaddr) unset _plen ;;
|
|
esac
|
|
|
|
if [ "${_ipaddr%:*.*.*.*}" = "$_ipaddr" ]; then
|
|
# Handle !v4mapped && !v4compat addresses.
|
|
|
|
# The default prefix length is 64.
|
|
case $_ipaddr:$_cidr in
|
|
$_cidr:$_ipaddr) _plen="64" ;;
|
|
esac
|
|
_ipleft=${_ipaddr%-*}
|
|
_ipright=${_ipaddr#*-}
|
|
_iplow=${_ipleft##*:}
|
|
_iphigh=${_ipright%%:*}
|
|
_ipleft=${_ipleft%:*}
|
|
_ipright=${_ipright#*:}
|
|
|
|
if [ "$_iphigh" = "$_ipright" ]; then
|
|
unset _ipright
|
|
else
|
|
_ipright=:$_ipright
|
|
fi
|
|
|
|
if [ -n "$_iplow" -a -n "$_iphigh" ]; then
|
|
_iplow=$((0x$_iplow))
|
|
_iphigh=$((0x$_iphigh))
|
|
_ipcount=$_iplow
|
|
while [ $_ipcount -le $_iphigh ]; do
|
|
_r=`printf "%s:%04x%s%s" \
|
|
$_ipleft $_ipcount $_ipright \
|
|
${_plen:+/}$_plen`
|
|
_retstr="$_retstr $_r"
|
|
if [ $_ipcount -gt $(($_iplow + $_IPEXPANDMAX)) ]
|
|
then
|
|
warn "Range specification is too large $(printf '(%s:%04x%s-%s:%04x%s)' $_ipleft $_iplow $_ipright $_ipleft $_iphigh $_ipright). $(printf '%s:%04x%s-%s:%04x%s' $_ipleft $_iplow $_ipright $_ipleft $_ipcount $_ipright) was processed."
|
|
break
|
|
else
|
|
_ipcount=$(($_ipcount + 1))
|
|
fi
|
|
done
|
|
else
|
|
_retstr="${_ipaddr}${_plen:+/}${_plen}"
|
|
fi
|
|
|
|
for _c in $_retstr; do
|
|
ifalias_expand_addr_inet6 $_action $_c $_exargs
|
|
done
|
|
else
|
|
# v4mapped/v4compat should handle as an IPv4 alias
|
|
_ipv4part=${_ipaddr##*:}
|
|
|
|
# Adjust prefix length if any. If not, set the
|
|
# default prefix length as 32.
|
|
case $_ipaddr:$_cidr in
|
|
$_cidr:$_ipaddr) _plen=32 ;;
|
|
*) _plen=$(($_plen - 96)) ;;
|
|
esac
|
|
|
|
_retstr=`ifalias_expand_addr_inet \
|
|
tmp ${_ipv4part}${_plen:+/}${_plen}`
|
|
for _c in $_retstr; do
|
|
ifalias_expand_addr_inet $_action $_c $_exargs
|
|
done
|
|
fi
|
|
done
|
|
}
|
|
|
|
# ifalias_af_common_handler if af action args
|
|
# Helper function for ifalias_af_common().
|
|
#
|
|
ifalias_af_common_handler()
|
|
{
|
|
local _ret _if _af _action _args _c _tmpargs
|
|
|
|
_ret=1
|
|
_if=$1
|
|
_af=$2
|
|
_action=$3
|
|
shift 3
|
|
_args=$*
|
|
|
|
case $_args in
|
|
${_af}\ *) ;;
|
|
*) return ;;
|
|
esac
|
|
|
|
# link(ether) does not support address removal.
|
|
case $_af:$_action in
|
|
link:-alias|ether:-alias) return ;;
|
|
esac
|
|
|
|
_tmpargs=
|
|
for _c in $_args; do
|
|
case $_c in
|
|
${_af})
|
|
case $_tmpargs in
|
|
${_af}\ *-*)
|
|
ifalias_af_common_handler $_if $_af $_action \
|
|
`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
|
|
;;
|
|
${_af}\ *)
|
|
${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
|
|
;;
|
|
esac
|
|
_tmpargs=$_af
|
|
;;
|
|
*)
|
|
_tmpargs="$_tmpargs $_c"
|
|
;;
|
|
esac
|
|
done
|
|
# Process the last component if any.
|
|
if [ -n "$_tmpargs}" ]; then
|
|
case $_tmpargs in
|
|
${_af}\ *-*)
|
|
ifalias_af_common_handler $_if $_af $_action \
|
|
`ifalias_expand_addr $_af $_action ${_tmpargs#${_af}\ }`
|
|
;;
|
|
${_af}\ *)
|
|
${IFCONFIG_CMD} $_if $_tmpargs $_action && _ret=0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifalias_af_common if af action
|
|
# Helper function for ifalias().
|
|
#
|
|
ifalias_af_common()
|
|
{
|
|
local _ret _if _af _action alias ifconfig_args _aliasn _c _tmpargs _iaf
|
|
|
|
_ret=1
|
|
_aliasn=
|
|
_if=$1
|
|
_af=$2
|
|
_action=$3
|
|
|
|
# ifconfig_IF_aliasN which starts with $_af
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $_if ifconfig_IF_alias${alias}`
|
|
_iaf=
|
|
case $ifconfig_args in
|
|
inet\ *) _iaf=inet ;;
|
|
inet6\ *) _iaf=inet6 ;;
|
|
ipx\ *) _iaf=ipx ;;
|
|
link\ *) _iaf=link ;;
|
|
ether\ *) _iaf=ether ;;
|
|
esac
|
|
|
|
case ${_af}:${_action}:${_iaf}:"${ifconfig_args}" in
|
|
${_af}:*:${_af}:*)
|
|
_aliasn="$_aliasn $ifconfig_args"
|
|
;;
|
|
${_af}:*:"":"")
|
|
break
|
|
;;
|
|
inet:alias:"":*)
|
|
_aliasn="$_aliasn inet $ifconfig_args"
|
|
warn "\$ifconfig_${_if}_alias${alias} needs " \
|
|
"\"inet\" keyword for an IPv4 address."
|
|
esac
|
|
alias=$(($alias + 1))
|
|
done
|
|
|
|
# backward compatibility: ipv6_ifconfig_IF_aliasN.
|
|
case $_af in
|
|
inet6)
|
|
alias=0
|
|
while : ; do
|
|
ifconfig_args=`get_if_var $_if ipv6_ifconfig_IF_alias${alias}`
|
|
case ${_action}:"${ifconfig_args}" in
|
|
*:"")
|
|
break
|
|
;;
|
|
alias:*)
|
|
_aliasn="${_aliasn} inet6 ${ifconfig_args}"
|
|
warn "\$ipv6_ifconfig_${_if}_alias${alias} " \
|
|
"is obsolete. Use ifconfig_$1_aliasN " \
|
|
"instead."
|
|
;;
|
|
esac
|
|
alias=$(($alias + 1))
|
|
done
|
|
esac
|
|
|
|
# backward compatibility: ipv4_addrs_IF.
|
|
for _tmpargs in `get_if_var $_if ipv4_addrs_IF`; do
|
|
_aliasn="$_aliasn inet $_tmpargs"
|
|
done
|
|
|
|
# Handle ifconfig_IF_aliases, ifconfig_IF_aliasN, and the others.
|
|
_tmpargs=
|
|
for _c in `get_if_var $_if ifconfig_IF_aliases` $_aliasn; do
|
|
case $_c in
|
|
inet|inet6|ipx|link|ether)
|
|
case $_tmpargs in
|
|
${_af}\ *)
|
|
eval ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
|
|
;;
|
|
esac
|
|
_tmpargs=$_c
|
|
;;
|
|
*)
|
|
_tmpargs="$_tmpargs $_c"
|
|
esac
|
|
done
|
|
# Process the last component
|
|
case $_tmpargs in
|
|
${_af}\ *)
|
|
ifalias_af_common_handler $_if $_af $_action $_tmpargs && _ret=0
|
|
;;
|
|
esac
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ipv6_prefix_hostid_addr_common if action
|
|
# Add or remove IPv6 prefix + hostid addr on the interface $if
|
|
#
|
|
ipv6_prefix_hostid_addr_common()
|
|
{
|
|
local _if _action prefix j
|
|
_if=$1
|
|
_action=$2
|
|
prefix=`get_if_var ${_if} ipv6_prefix_IF`
|
|
|
|
if [ -n "${prefix}" ]; then
|
|
for j in ${prefix}; do
|
|
# The default prefixlen is 64.
|
|
plen=${j#*/}
|
|
case $j:$plen in
|
|
$plen:$j) plen=64 ;;
|
|
*) j=${j%/*} ;;
|
|
esac
|
|
|
|
# Normalize the last part by removing ":"
|
|
j=${j%::*}
|
|
j=${j%:}
|
|
${IFCONFIG_CMD} ${_if} inet6 $j:: \
|
|
prefixlen $plen eui64 ${_action}
|
|
|
|
# if I am a router, add subnet router
|
|
# anycast address (RFC 2373).
|
|
if checkyesno ipv6_gateway_enable; then
|
|
${IFCONFIG_CMD} ${_if} inet6 $j:: \
|
|
prefixlen $plen ${_action} 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_CMD} $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_CMD} $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 _list ifn ifopt _iflist _n tmpargs
|
|
_list=
|
|
_iflist=$*
|
|
|
|
# create_args_IF
|
|
for ifn in ${cloned_interfaces}; do
|
|
# Parse ifn:ifopt.
|
|
OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
|
|
case $_iflist in
|
|
""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;;
|
|
*) continue ;;
|
|
esac
|
|
case $ifn in
|
|
epair[0-9]*)
|
|
# epair(4) uses epair[0-9] for creation and
|
|
# epair[0-9][ab] for configuration.
|
|
#
|
|
# Skip if ${ifn}a or ${ifn}b already exist.
|
|
if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then
|
|
continue
|
|
elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
${IFCONFIG_CMD} ${ifn} create \
|
|
`get_if_var ${ifn} create_args_IF`
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list ${ifn}a ${ifn}b"
|
|
fi
|
|
;;
|
|
*)
|
|
# Skip if ${ifn} already exists.
|
|
if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
${IFCONFIG_CMD} ${ifn} create \
|
|
`get_if_var ${ifn} create_args_IF`
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list $ifn"
|
|
fi
|
|
esac
|
|
done
|
|
if [ -n "$gif_interfaces" ]; then
|
|
warn "\$gif_interfaces is obsolete. Use \$cloned_interfaces instead."
|
|
fi
|
|
for ifn in ${gif_interfaces}; do
|
|
# Parse ifn:ifopt.
|
|
OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
|
|
case $_iflist in
|
|
""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;;
|
|
*) continue ;;
|
|
esac
|
|
# Skip if ifn already exists.
|
|
if ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
case $ifn in
|
|
gif[0-9]*)
|
|
${IFCONFIG_CMD} $ifn create
|
|
;;
|
|
*)
|
|
_n=$(${IFCONFIG_CMD} gif create)
|
|
${IFCONFIG_CMD} $_n name $ifn
|
|
;;
|
|
esac
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list $ifn"
|
|
fi
|
|
tmpargs=$(get_if_var $ifn gifconfig_IF)
|
|
eval ifconfig_${ifn}=\"tunnel \$tmpargs\"
|
|
done
|
|
if [ -n "${_list# }" ]; then
|
|
echo "Created clone interfaces: ${_list# }."
|
|
fi
|
|
debug "Cloned: ${_list# }"
|
|
}
|
|
|
|
# clone_down
|
|
# Destroy cloned interfaces. Destroyed interfaces are echoed to
|
|
# standard output.
|
|
#
|
|
clone_down()
|
|
{
|
|
local _list ifn _difn ifopt _iflist _sticky
|
|
_list=
|
|
_iflist=$*
|
|
|
|
: ${cloned_interfaces_sticky:=NO}
|
|
if checkyesno cloned_interfaces_sticky; then
|
|
_sticky=1
|
|
else
|
|
_sticky=0
|
|
fi
|
|
for ifn in ${cloned_interfaces} ${gif_interfaces}; do
|
|
# Parse ifn:ifopt.
|
|
OIFS=$IFS; IFS=:; set -- $ifn; ifn=$1; ifopt=$2; IFS=$OIFS
|
|
case $ifopt:$_sticky in
|
|
sticky:*) continue ;; # :sticky => not destroy
|
|
nosticky:*) ;; # :nosticky => destroy
|
|
*:1) continue ;; # global sticky knob == 1
|
|
esac
|
|
case $_iflist in
|
|
""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;;
|
|
*) continue ;;
|
|
esac
|
|
case $ifn in
|
|
epair[0-9]*)
|
|
# Note: epair(4) uses epair[0-9] for removal and
|
|
# epair[0-9][ab] for configuration.
|
|
#
|
|
# Skip if both of ${ifn}a and ${ifn}b do not exist.
|
|
if ${IFCONFIG_CMD} ${ifn}a > /dev/null 2>&1; then
|
|
_difn=${ifn}a
|
|
elif ${IFCONFIG_CMD} ${ifn}b > /dev/null 2>&1; then
|
|
_difn=${ifn}b
|
|
else
|
|
continue
|
|
fi
|
|
${IFCONFIG_CMD} -n $_difn destroy
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list ${ifn}a ${ifn}b"
|
|
fi
|
|
;;
|
|
*)
|
|
# Skip if ifn does not exist.
|
|
if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
${IFCONFIG_CMD} -n ${ifn} destroy
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list $ifn"
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
if [ -n "${_list# }" ]; then
|
|
echo "Destroyed clone interfaces: ${_list# }."
|
|
fi
|
|
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_CMD} $child create ${create_args} && cfg=0
|
|
if [ -n "${debug_flags}" ]; then
|
|
wlandebug -i $child ${debug_flags}
|
|
fi
|
|
else
|
|
i=`${IFCONFIG_CMD} wlan create ${create_args}`
|
|
if [ -n "${debug_flags}" ]; then
|
|
wlandebug -i $i ${debug_flags}
|
|
fi
|
|
${IFCONFIG_CMD} $i name $child && cfg=0
|
|
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_CMD} $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_CMD} $child create ${create_args} && cfg=0
|
|
else
|
|
i=`${IFCONFIG_CMD} vlan create ${create_args}`
|
|
${IFCONFIG_CMD} $i name $child && cfg=0
|
|
fi
|
|
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_CMD} -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_CMD} -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
|
|
}
|
|
|
|
# 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_CMD} ${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_CMD} ${_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_CMD} ${_if} ${_ipx} delete
|
|
IFS="$_ifs"
|
|
_ret=0
|
|
done
|
|
IFS="$oldifs"
|
|
|
|
return $_ret
|
|
}
|
|
|
|
# ifnet_rename [ifname]
|
|
# Rename interfaces if ifconfig_IF_name is defined.
|
|
#
|
|
ifnet_rename()
|
|
{
|
|
local _if _ifname
|
|
|
|
# ifconfig_IF_name
|
|
for _if in ${*:-$(${IFCONFIG_CMD} -l)}; do
|
|
_ifname=`get_if_var $_if ifconfig_IF_name`
|
|
if [ ! -z "$_ifname" ]; then
|
|
${IFCONFIG_CMD} $_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_CMD} -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# }"
|
|
;;
|
|
*)
|
|
for _if in ${network_interfaces} ${cloned_interfaces}; do
|
|
# epair(4) uses epair[0-9] for creation and
|
|
# epair[0-9][ab] for configuration.
|
|
case $_if in
|
|
epair[0-9]*)
|
|
_tmplist="$_tmplist ${_if}a ${_if}b"
|
|
;;
|
|
*)
|
|
_tmplist="$_tmplist $_if"
|
|
;;
|
|
esac
|
|
done
|
|
#
|
|
# lo0 is effectively mandatory, so help prevent foot-shooting
|
|
#
|
|
case "$_tmplist" in
|
|
lo0|'lo0 '*|*' lo0'|*' lo0 '*)
|
|
# This is fine, do nothing
|
|
_tmplist="${_tmplist# }"
|
|
;;
|
|
*)
|
|
_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_CMD} $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 _if _flag proto addr rest
|
|
_if=$1
|
|
_flag=$2
|
|
|
|
${IFCONFIG_CMD} $_if 2>/dev/null | while read proto addr rest; do
|
|
case "${proto}/${addr}/${_flag}/${rest}" in
|
|
inet6/fe80::*//*)
|
|
echo ${addr}
|
|
;;
|
|
inet6/fe80:://*tentative*) # w/o flag
|
|
sleep `${SYSCTL_N} net.inet6.ip6.dad_count`
|
|
network6_getladdr $_if $_flags
|
|
;;
|
|
inet6/fe80::/*/*tentative*) # w/ flag
|
|
echo ${addr}
|
|
;;
|
|
*)
|
|
continue
|
|
;;
|
|
esac
|
|
|
|
return
|
|
done
|
|
}
|