mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
79d2c5e857
with the net80211 stack. Historical background: originally wireless devices created an interface, just like Ethernet devices do. Name of an interface matched the name of the driver that created. Later, wlan(4) layer was introduced, and the wlanX interfaces become the actual interface, leaving original ones as "a parent interface" of wlanX. Kernelwise, the KPI between net80211 layer and a driver became a mix of methods that pass a pointer to struct ifnet as identifier and methods that pass pointer to struct ieee80211com. From user point of view, the parent interface just hangs on in the ifconfig list, and user can't do anything useful with it. Now, the struct ifnet goes away. The struct ieee80211com is the only KPI between a device driver and net80211. Details: - The struct ieee80211com is embedded into drivers softc. - Packets are sent via new ic_transmit method, which is very much like the previous if_transmit. - Bringing parent up/down is done via new ic_parent method, which notifies driver about any changes: number of wlan(4) interfaces, number of them in promisc or allmulti state. - Device specific ioctls (if any) are received on new ic_ioctl method. - Packets/errors accounting are done by the stack. In certain cases, when driver experiences errors and can not attribute them to any specific interface, driver updates ic_oerrors or ic_ierrors counters. Details on interface configuration with new world order: - A sequence of commands needed to bring up wireless DOESN"T change. - /etc/rc.conf parameters DON'T change. - List of devices that can be used to create wlan(4) interfaces is now provided by net.wlan.devices sysctl. Most drivers in this change were converted by me, except of wpi(4), that was done by Andriy Voskoboinyk. Big thanks to Kevin Lo for testing changes to at least 8 drivers. Thanks to Olivier Cochard, gjb@, mmoll@, op@ and lev@, who also participated in testing. Details here: https://wiki.freebsd.org/projects/ifnet/net80211 Still, drivers: ndis, wtap, mwl, ipw, bwn, wi, upgt, uath were not tested. Changes to mwl, ipw, bwn, wi, upgt are trivial and chances of problems are low. The wtap wasn't compilable even before this change. But the ndis driver is complex, and it is likely to be broken with this commit. Help with testing and debugging it is appreciated. Differential Revision: D2655, D2740 Sponsored by: Nginx, Inc. Sponsored by: Netflix
1787 lines
36 KiB
Plaintext
1787 lines
36 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"
|
|
: ${netif_ipexpand_max:=2048}
|
|
|
|
#
|
|
# 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
|
|
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 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
|
|
|
|
# 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
|
|
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
|
|
# 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 leading" \
|
|
"\"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=".-/+"
|
|
ltr ${_if} "${_punct}" '_' _if
|
|
_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]*|\
|
|
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}
|
|
;;
|
|
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]*|\
|
|
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 $_inet6 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 + $netif_ipexpand_max)) ]; 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. Increase \$netif_ipexpand_max in rc.conf."
|
|
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 + $netif_ipexpand_max)) ]
|
|
then
|
|
warn "Range specification is too large $(printf '(%s:%x%s-%s:%x%s)' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_iphigh" "$_ipright"). $(printf '%s:%x%s-%s:%x%s' "$_ipleft" "$_iplow" "$_ipright" "$_ipleft" "$_ipcount" "$_ipright") was processed. Increase \$netif_ipexpand_max in rc.conf."
|
|
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}\ *[0-9a-fA-F]-*)
|
|
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}\ *[0-9a-fA-F]-*)
|
|
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
|
|
local _vif _punct=".-/+"
|
|
|
|
_ret=1
|
|
_aliasn=
|
|
_if=$1
|
|
_af=$2
|
|
_action=$3
|
|
|
|
# Normalize $_if before using it in a pattern to list_vars()
|
|
ltr "$_if" "$_punct" "_" _vif
|
|
|
|
# ifconfig_IF_aliasN which starts with $_af
|
|
for alias in `list_vars ifconfig_${_vif}_alias[0-9]\* |
|
|
sort_lite -nk1.$((9+${#_vif}+7))`
|
|
do
|
|
eval ifconfig_args=\"\$$alias\"
|
|
_iaf=
|
|
case $ifconfig_args in
|
|
inet\ *) _iaf=inet ;;
|
|
inet6\ *) _iaf=inet6 ;;
|
|
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 "\$${alias} needs leading" \
|
|
"\"inet\" keyword for an IPv4 address."
|
|
esac
|
|
done
|
|
|
|
# backward compatibility: ipv6_ifconfig_IF_aliasN.
|
|
case $_af in
|
|
inet6)
|
|
for alias in `list_vars ipv6_ifconfig_${_vif}_alias[0-9]\* |
|
|
sort_lite -nk1.$((14+${#_vif}+7))`
|
|
do
|
|
eval ifconfig_args=\"\$$alias\"
|
|
case ${_action}:"${ifconfig_args}" in
|
|
*:"")
|
|
break
|
|
;;
|
|
alias:*)
|
|
_aliasn="${_aliasn} inet6 ${ifconfig_args}"
|
|
warn "\$${alias} is obsolete. " \
|
|
"Use ifconfig_${_vif}_aliasN instead."
|
|
;;
|
|
esac
|
|
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|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
|
|
}
|
|
|
|
# wlan_up
|
|
# Create IEEE802.3 interfaces.
|
|
#
|
|
wlan_up()
|
|
{
|
|
local _list _iflist wlan parent ifn
|
|
_list=
|
|
_iflist=$*
|
|
|
|
for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do
|
|
# Parse wlans_$parent=$ifn
|
|
wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'`
|
|
OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$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
|
|
${IFCONFIG_CMD} ${ifn} create wlandev ${parent}
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list $ifn"
|
|
fi
|
|
done
|
|
if [ -n "${_list# }" ]; then
|
|
echo "Created wlan(4) interfaces: ${_list# }."
|
|
fi
|
|
debug "Created wlan(4)s: ${_list# }"
|
|
}
|
|
|
|
# wlan_down
|
|
# Destroy IEEE802.3 interfaces.
|
|
#
|
|
wlan_down()
|
|
{
|
|
local _list _iflist wlan parent ifn
|
|
_list=
|
|
_iflist=$*
|
|
|
|
for wlan in `set | egrep ^wlans_[a-z]+[0-9]+=[a-z]+[0-9]+`; do
|
|
# Parse wlans_$parent=$ifn
|
|
wlan=`echo $wlan | sed -E 's/wlans_([a-z]+[0-9]+)=([a-z]+[0-9]+)/\1:\2/'`
|
|
OIFS=$IFS; IFS=:; set -- $wlan; parent=$1; ifn=$2; IFS=$OIFS
|
|
case $_iflist in
|
|
""|$ifn|$ifn\ *|*\ $ifn\ *|*\ $ifn) ;;
|
|
*) continue ;;
|
|
esac
|
|
# Skip if ${ifn} doesn't exists.
|
|
if ! ${IFCONFIG_CMD} $ifn > /dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
${IFCONFIG_CMD} -n ${ifn} destroy
|
|
if [ $? -eq 0 ]; then
|
|
_list="$_list $ifn"
|
|
fi
|
|
done
|
|
if [ -n "${_list# }" ]; then
|
|
echo "Destroyed wlan(4) interfaces: ${_list# }."
|
|
fi
|
|
debug "Destroyed wlan(4)s: ${_list# }"
|
|
}
|
|
|
|
# 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.
|
|
#
|
|
# XXXGL: the wlan code in this functions is superseded by wlan_up(),
|
|
# and will go away soon.
|
|
#
|
|
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
|
|
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_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
|
|
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_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
|
|
}
|
|
|
|
# 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
|
|
}
|