5bfebbecea
We were telling users that setting shutdown_network=YES would shut down the network interfaces during shutdown, but this was exactly the opposite of what we were doing. The default was YES, which was keeping the interfaces active. This keeps the default behavior, but renames the setting to keep_network which more accurately describes its function, and instructs users to set it to NO if they want the network interfaces to go down.
787 lines
17 KiB
Plaintext
787 lines
17 KiB
Plaintext
#!@PREFIX@/sbin/runscript
|
|
# Copyright (c) 2007-2009 Roy Marples <roy@marples.name>
|
|
# Released under the 2-clause BSD license.
|
|
|
|
MODULESDIR="${RC_LIBEXECDIR}/net"
|
|
MODULESLIST="${RC_SVCDIR}/nettree"
|
|
_config_vars="config routes"
|
|
|
|
[ -z "${IN_BACKGROUND}" ] && IN_BACKGROUND="NO"
|
|
|
|
description="Configures network interfaces."
|
|
|
|
# Handy var so we don't have to embed new lines everywhere for array splitting
|
|
__IFS="
|
|
"
|
|
depend()
|
|
{
|
|
local IFACE=${RC_SVCNAME#*.}
|
|
local IFVAR=$(shell_var "${IFACE}")
|
|
|
|
need localmount
|
|
if [ "$RC_UNAME" = Linux -a "$IFACE" != lo ]; then
|
|
need sysfs
|
|
fi
|
|
after bootmisc
|
|
keyword -jail -prefix -vserver
|
|
|
|
case "${IFACE}" in
|
|
lo|lo0) ;;
|
|
*)
|
|
after net.lo net.lo0 dbus
|
|
provide net
|
|
;;
|
|
esac
|
|
|
|
if [ "$(command -v "depend_${IFVAR}")" = "depend_${IFVAR}" ]; then
|
|
depend_${IFVAR}
|
|
fi
|
|
|
|
local dep= prov=
|
|
for dep in need use before after provide keyword; do
|
|
eval prov=\$rc_${dep}_${IFVAR}
|
|
if [ -n "${prov}" ]; then
|
|
${dep} ${prov}
|
|
ewarn "rc_${dep}_${IFVAR} is deprecated."
|
|
ewarn "Please use rc_net_${IFVAR}_${dep} instead."
|
|
fi
|
|
done
|
|
}
|
|
|
|
# Support bash arrays - sigh
|
|
_array_helper()
|
|
{
|
|
local _a=
|
|
|
|
eval _a=\$$1
|
|
_a=$(echo "${_a}" | sed -e 's:^[[:space:]]*::' -e 's:[[:space:]]*$::' -e '/^$/d' -e 's:[[:space:]]\{1,\}: :g')
|
|
|
|
[ -n "${_a}" ] && printf "%s\n" "${_a}"
|
|
}
|
|
|
|
_get_array()
|
|
{
|
|
local _a=
|
|
if [ -n "${BASH}" ]; then
|
|
case "$(declare -p "$1" 2>/dev/null)" in
|
|
"declare -a "*)
|
|
ewarn "You are using a bash array for $1."
|
|
ewarn "This feature will be removed in the future."
|
|
ewarn "Please see net.example for the correct format for $1."
|
|
eval "set -- \"\${$1[@]}\""
|
|
for _a; do
|
|
printf "%s\n" "${_a}"
|
|
done
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_array_helper $1
|
|
}
|
|
|
|
# Flatten bash arrays to simple strings
|
|
_flatten_array()
|
|
{
|
|
if [ -n "${BASH}" ]; then
|
|
case "$(declare -p "$1" 2>/dev/null)" in
|
|
"declare -a "*)
|
|
ewarn "You are using a bash array for $1."
|
|
ewarn "This feature will be removed in the future."
|
|
ewarn "Please see net.example for the correct format for $1."
|
|
eval "set -- \"\${$1[@]}\""
|
|
for x; do
|
|
printf "'%s' " "$(printf "$x" | sed "s:':'\\\'':g")"
|
|
done
|
|
return 0
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
_array_helper $1
|
|
}
|
|
|
|
_wait_for_carrier()
|
|
{
|
|
local timeout= efunc=einfon
|
|
|
|
_has_carrier && return 0
|
|
|
|
eval timeout=\$carrier_timeout_${IFVAR}
|
|
timeout=${timeout:-${carrier_timeout:-0}}
|
|
|
|
# Incase users don't want this nice feature ...
|
|
[ ${timeout} -le 0 ] && return 0
|
|
|
|
yesno ${RC_PARALLEL} && efunc=einfo
|
|
${efunc} "Waiting for carrier (${timeout} seconds) "
|
|
while [ ${timeout} -gt 0 ]; do
|
|
if _has_carrier; then
|
|
[ "${efunc}" = "einfon" ] && echo
|
|
eend 0
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
: $(( timeout -= 1 ))
|
|
[ "${efunc}" = "einfon" ] && printf "."
|
|
done
|
|
|
|
[ "${efunc}" = "einfon" ] && echo
|
|
eend 1
|
|
return 1
|
|
}
|
|
|
|
_netmask2cidr()
|
|
{
|
|
# Some shells cannot handle hex arithmetic, so we massage it slightly
|
|
# Buggy shells include FreeBSD sh, dash and busybox.
|
|
# bash and NetBSD sh don't need this.
|
|
case $1 in
|
|
0x*)
|
|
local hex=${1#0x*} quad=
|
|
while [ -n "${hex}" ]; do
|
|
local lastbut2=${hex#??*}
|
|
quad=${quad}${quad:+.}0x${hex%${lastbut2}*}
|
|
hex=${lastbut2}
|
|
done
|
|
set -- ${quad}
|
|
;;
|
|
esac
|
|
|
|
local i= len=
|
|
local IFS=.
|
|
for i in $1; do
|
|
while [ ${i} -ne 0 ]; do
|
|
: $(( len += i % 2 ))
|
|
: $(( i >>= 1 ))
|
|
done
|
|
done
|
|
|
|
echo "${len}"
|
|
}
|
|
|
|
_configure_variables()
|
|
{
|
|
local var= v= t=
|
|
|
|
for var in ${_config_vars}; do
|
|
local v=
|
|
for t; do
|
|
eval v=\$${var}_${t}
|
|
if [ -n "${v}" ]; then
|
|
eval ${var}_${IFVAR}=\$${var}_${t}
|
|
continue 2
|
|
fi
|
|
done
|
|
done
|
|
}
|
|
|
|
_which()
|
|
{
|
|
local i OIFS
|
|
# Empty
|
|
[ -z "$1" ] && return
|
|
# check paths
|
|
OIFS="$IFS"
|
|
IFS=:
|
|
for i in $PATH ; do
|
|
[ -x $i/$1 ] && echo $i/$1 && break
|
|
done
|
|
IFS=$OIFS
|
|
}
|
|
|
|
# Like _which, but also consider shell builtins, and multiple alternatives
|
|
_program_available()
|
|
{
|
|
[ -z "$1" ] && return 0
|
|
local x=
|
|
for x; do
|
|
case "${x}" in
|
|
/*) [ -x "${x}" ] && break;;
|
|
*) type "${x}" >/dev/null 2>&1 && break;;
|
|
esac
|
|
unset x
|
|
done
|
|
[ -n "${x}" ] && echo $x && return 0
|
|
return 1
|
|
}
|
|
|
|
_show_address()
|
|
{
|
|
einfo "received address $(_get_inet_address "${IFACE}")"
|
|
}
|
|
|
|
# Basically sorts our modules into order and saves the list
|
|
_gen_module_list()
|
|
{
|
|
local x= f= force=$1
|
|
if ! ${force} && [ -s "${MODULESLIST}" -a "${MODULESLIST}" -nt "${MODULESDIR}" ]; then
|
|
local update=false
|
|
for x in "${MODULESDIR}"/*.sh; do
|
|
[ -e "${x}" ] || continue
|
|
if [ "${x}" -nt "${MODULESLIST}" ]; then
|
|
update=true
|
|
break
|
|
fi
|
|
done
|
|
${update} || return 0
|
|
fi
|
|
|
|
einfo "Caching network module dependencies"
|
|
# Run in a subshell to protect the main script
|
|
(
|
|
after() {
|
|
eval ${MODULE}_after="\"\${${MODULE}_after}\${${MODULE}_after:+ }$*\""
|
|
}
|
|
|
|
before() {
|
|
local mod=${MODULE}
|
|
local MODULE=
|
|
for MODULE; do
|
|
after "${mod}"
|
|
done
|
|
}
|
|
|
|
program() {
|
|
if [ "$1" = "start" -o "$1" = "stop" ]; then
|
|
local s="$1"
|
|
shift
|
|
eval ${MODULE}_program_${s}="\"\${${MODULE}_program_${s}}\${${MODULE}_program_${s}:+ }$*\""
|
|
else
|
|
eval ${MODULE}_program="\"\${${MODULE}_program}\${${MODULE}_program:+ }$*\""
|
|
fi
|
|
}
|
|
|
|
provide() {
|
|
eval ${MODULE}_provide="\"\${${MODULE}_provide}\${${MODULE}_provide:+ }$*\""
|
|
local x
|
|
for x in $*; do
|
|
eval ${x}_providedby="\"\${${MODULE}_providedby}\${${MODULE}_providedby:+ }${MODULE}\""
|
|
done
|
|
}
|
|
|
|
for MODULE in "${MODULESDIR}"/*.sh; do
|
|
sh -n "${MODULE}" || continue
|
|
. "${MODULE}" || continue
|
|
MODULE=${MODULE#${MODULESDIR}/}
|
|
MODULE=${MODULE%.sh}
|
|
eval ${MODULE}_depend
|
|
MODULES="${MODULES} ${MODULE}"
|
|
done
|
|
|
|
VISITED=
|
|
SORTED=
|
|
visit() {
|
|
case " ${VISITED} " in
|
|
*" $1 "*) return;;
|
|
esac
|
|
VISITED="${VISITED} $1"
|
|
|
|
eval AFTER=\$${1}_after
|
|
for MODULE in ${AFTER}; do
|
|
eval PROVIDEDBY=\$${MODULE}_providedby
|
|
if [ -n "${PROVIDEDBY}" ]; then
|
|
for MODULE in ${PROVIDEDBY}; do
|
|
visit "${MODULE}"
|
|
done
|
|
else
|
|
visit "${MODULE}"
|
|
fi
|
|
done
|
|
|
|
eval PROVIDE=\$${1}_provide
|
|
for MODULE in ${PROVIDE}; do
|
|
visit "${MODULE}"
|
|
done
|
|
|
|
eval PROVIDEDBY=\$${1}_providedby
|
|
[ -z "${PROVIDEDBY}" ] && SORTED="${SORTED} $1"
|
|
}
|
|
|
|
for MODULE in ${MODULES}; do
|
|
visit "${MODULE}"
|
|
done
|
|
|
|
printf "" > "${MODULESLIST}"
|
|
i=0
|
|
for MODULE in ${SORTED}; do
|
|
eval PROGRAM=\$${MODULE}_program
|
|
eval PROGRAM_START=\$${MODULE}_program_start
|
|
eval PROGRAM_STOP=\$${MODULE}_program_stop
|
|
eval PROVIDE=\$${MODULE}_provide
|
|
echo "module_${i}='${MODULE}'" >> "${MODULESLIST}"
|
|
echo "module_${i}_program='${PROGRAM}'" >> "${MODULESLIST}"
|
|
echo "module_${i}_program_start='${PROGRAM_START}'" >> "${MODULESLIST}"
|
|
echo "module_${i}_program_stop='${PROGRAM_STOP}'" >> "${MODULESLIST}"
|
|
echo "module_${i}_provide='${PROVIDE}'" >> "${MODULESLIST}"
|
|
: $(( i += 1 ))
|
|
done
|
|
echo "module_${i}=" >> "${MODULESLIST}"
|
|
)
|
|
|
|
return 0
|
|
}
|
|
|
|
_load_modules()
|
|
{
|
|
local starting=$1 mymods=
|
|
|
|
# Ensure our list is up to date
|
|
_gen_module_list false
|
|
if ! . "${MODULESLIST}"; then
|
|
_gen_module_list true
|
|
. "${MODULESLIST}"
|
|
fi
|
|
|
|
MODULES=
|
|
if [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
|
|
eval mymods=\$modules_${IFVAR}
|
|
[ -z "${mymods}" ] && mymods=${modules}
|
|
fi
|
|
|
|
local i=-1 x= mod= f= provides=
|
|
while true; do
|
|
: $(( i += 1 ))
|
|
eval mod=\$module_${i}
|
|
[ -z "${mod}" ] && break
|
|
[ -e "${MODULESDIR}/${mod}.sh" ] || continue
|
|
|
|
eval set -- \$module_${i}_program
|
|
if [ -n "$1" ]; then
|
|
if ! _program_available "$@" >/dev/null; then
|
|
vewarn "Skipping module $mod due to missing program: $@"
|
|
continue
|
|
fi
|
|
fi
|
|
if ${starting}; then
|
|
eval set -- \$module_${i}_program_start
|
|
else
|
|
eval set -- \$module_${i}_program_stop
|
|
fi
|
|
if [ -n "$1" ]; then
|
|
if ! _program_available "$@" >/dev/null; then
|
|
vewarn "Skipping module $mod due to missing program: $@"
|
|
continue
|
|
fi
|
|
fi
|
|
|
|
eval provides=\$module_${i}_provide
|
|
if ${starting}; then
|
|
case " ${mymods} " in
|
|
*" !${mod} "*) continue;;
|
|
*" !${provides} "*) [ -n "${provides}" ] && continue;;
|
|
esac
|
|
fi
|
|
MODULES="${MODULES}${MODULES:+ }${mod}"
|
|
|
|
# Now load and wrap our functions
|
|
if ! . "${MODULESDIR}/${mod}.sh"; then
|
|
eend 1 "${RC_SVCNAME}: error loading module \`${mod}'"
|
|
exit 1
|
|
fi
|
|
|
|
[ -z "${provides}" ] && continue
|
|
|
|
# Wrap our provides
|
|
local f=
|
|
for f in pre_start start post_start; do
|
|
eval "${provides}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }"
|
|
done
|
|
|
|
eval module_${mod}_provides="${provides}"
|
|
eval module_${provides}_providedby="${mod}"
|
|
done
|
|
|
|
# Wrap our preferred modules
|
|
for mod in ${mymods}; do
|
|
case " ${MODULES} " in
|
|
*" ${mod} "*)
|
|
eval x=\$module_${mod}_provides
|
|
[ -z "${x}" ] && continue
|
|
for f in pre_start start post_start; do
|
|
eval "${x}_${f}() { [ "$(command -v "${mod}_${f}")" = "${mod}_${f}" ] || return 0; ${mod}_${f} \"\$@\"; }"
|
|
done
|
|
eval module_${x}_providedby="${mod}"
|
|
;;
|
|
esac
|
|
done
|
|
|
|
# Finally remove any duplicated provides from our list if we're starting
|
|
# Otherwise reverse the list
|
|
local LIST="${MODULES}" p=
|
|
MODULES=
|
|
if ${starting}; then
|
|
for mod in ${LIST}; do
|
|
eval x=\$module_${mod}_provides
|
|
if [ -n "${x}" ]; then
|
|
eval p=\$module_${x}_providedby
|
|
[ "${mod}" != "${p}" ] && continue
|
|
fi
|
|
MODULES="${MODULES}${MODULES:+ }${mod}"
|
|
done
|
|
else
|
|
for mod in ${LIST}; do
|
|
MODULES="${mod}${MODULES:+ }${MODULES}"
|
|
done
|
|
fi
|
|
|
|
veinfo "Loaded modules: ${MODULES}"
|
|
}
|
|
|
|
_load_config()
|
|
{
|
|
local config="$(_get_array "config_${IFVAR}")"
|
|
local fallback="$(_get_array fallback_${IFVAR})"
|
|
|
|
config_index=0
|
|
local IFS="$__IFS"
|
|
set -- ${config}
|
|
|
|
# We should support a space separated array for cidr configs
|
|
# But only as long as they do not contain other parameters for the address
|
|
if [ $# = 1 ]; then
|
|
unset IFS
|
|
set -- ${config}
|
|
# Of course, we may have a single address added old style.
|
|
# If the NEXT argument is a v4 or v6 address, it's the next config.
|
|
# Otherwise, it's arguments to the first config...
|
|
if [ "${2#*.*}" = "${2}" -a "${2#*:*}" = "${2}" ]; then
|
|
# Not an IPv4/IPv6
|
|
local IFS="$__IFS"
|
|
set -- ${config}
|
|
fi
|
|
fi
|
|
|
|
# Ensure that loopback has the correct address
|
|
if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ]; then
|
|
if [ "$1" != "null" ]; then
|
|
config_0="127.0.0.1/8"
|
|
config_index=1
|
|
fi
|
|
else
|
|
if [ -z "$1" ]; then
|
|
ewarn "No configuration specified; defaulting to DHCP"
|
|
config_0="dhcp"
|
|
config_index=1
|
|
fi
|
|
fi
|
|
|
|
|
|
# We store our config in an array like vars
|
|
# so modules can influence it
|
|
for cmd; do
|
|
eval config_${config_index}="'${cmd}'"
|
|
: $(( config_index += 1 ))
|
|
done
|
|
# Terminate the list
|
|
eval config_${config_index}=
|
|
|
|
config_index=0
|
|
for cmd in ${fallback}; do
|
|
eval fallback_${config_index}="'${cmd}'"
|
|
: $(( config_index += 1 ))
|
|
done
|
|
# Terminate the list
|
|
eval fallback_${config_index}=
|
|
|
|
# Don't set to zero, so any net modules don't have to do anything extra
|
|
config_index=-1
|
|
}
|
|
|
|
# Support functions
|
|
_run_if()
|
|
{
|
|
local cmd=$1 iface=$2 ifr=${IFACE} ifv=${IFVAR}
|
|
# Ensure that we don't stamp on real values
|
|
local IFACE= IFVAR=
|
|
shift
|
|
if [ -n "${iface}" ]; then
|
|
IFACE="${iface}"
|
|
[ "${iface}" != "${ifr}" ] && IFVAR=$(shell_var "${IFACE}")
|
|
else
|
|
IFACE=${ifr}
|
|
IFVAR=${ifv}
|
|
fi
|
|
${cmd}
|
|
}
|
|
interface_exists()
|
|
{
|
|
_run_if _exists "$@"
|
|
}
|
|
interface_up()
|
|
{
|
|
_run_if _up "$@"
|
|
}
|
|
interface_down()
|
|
{
|
|
_run_if _down "$@"
|
|
}
|
|
|
|
start()
|
|
{
|
|
local IFACE=${RC_SVCNAME#*.} oneworked=false fallback=false module=
|
|
local IFVAR=$(shell_var "${IFACE}") cmd= our_metric=
|
|
local metric=0 _up_before_preup
|
|
eval _up_before_preup="\$up_before_preup_${IFVAR}"
|
|
[ -z "${_up_before_preup}" ] && _up_before_preup=$up_before_preup
|
|
|
|
einfo "Bringing up interface ${IFACE}"
|
|
eindent
|
|
|
|
if [ -z "${MODULES}" ]; then
|
|
local MODULES=
|
|
_load_modules true
|
|
fi
|
|
|
|
# We up the iface twice if we have a preup to ensure it's up if
|
|
# available in preup and afterwards incase the user inadvertently
|
|
# brings it down
|
|
if [ "$(command -v preup)" = "preup" ]; then
|
|
yesno "${_up_before_preup:-yes}" && _up 2>/dev/null
|
|
ebegin "Running preup"
|
|
eindent
|
|
preup || return 1
|
|
eoutdent
|
|
fi
|
|
|
|
_up 2>/dev/null
|
|
|
|
for module in ${MODULES}; do
|
|
if [ "$(command -v "${module}_pre_start")" = "${module}_pre_start" ]; then
|
|
${module}_pre_start || exit $?
|
|
fi
|
|
done
|
|
|
|
if ! _exists; then
|
|
eerror "ERROR: interface ${IFACE} does not exist"
|
|
eerror "Ensure that you have loaded the correct kernel module for your hardware"
|
|
return 1
|
|
fi
|
|
|
|
if ! _wait_for_carrier; then
|
|
if service_started devd; then
|
|
ewarn "no carrier, but devd will start us when we have one"
|
|
mark_service_inactive "${RC_SVCNAME}"
|
|
else
|
|
eerror "no carrier"
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
local config= config_index=
|
|
_load_config
|
|
config_index=0
|
|
|
|
eval our_metric=\$metric_${IFVAR}
|
|
if [ -n "${our_metric}" ]; then
|
|
metric=${our_metric}
|
|
elif [ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
|
|
: $(( metric += $(_ifindex) ))
|
|
fi
|
|
|
|
while true; do
|
|
eval config=\$config_${config_index}
|
|
[ -z "${config}" ] && break
|
|
|
|
set -- ${config}
|
|
if [ "$1" != "null" -a "$1" != "noop" ]; then
|
|
ebegin "$1"
|
|
fi
|
|
eindent
|
|
case "$1" in
|
|
noop)
|
|
if [ -n "$(_get_inet_address)" ]; then
|
|
oneworked=true
|
|
break
|
|
fi
|
|
;;
|
|
null) :;;
|
|
[0-9]*|*:*) _add_address ${config};;
|
|
*)
|
|
if [ "$(command -v "${config}_start")" = "${config}_start" ]; then
|
|
"${config}"_start
|
|
else
|
|
eerror "nothing provides \`${config}'"
|
|
fi
|
|
;;
|
|
esac
|
|
if eend $?; then
|
|
oneworked=true
|
|
else
|
|
eval config=\$fallback_${config_index}
|
|
if [ -n "${config}" ]; then
|
|
fallback=true
|
|
eoutdent
|
|
ewarn "Trying fallback configuration ${config}"
|
|
eindent
|
|
eval config_${config_index}=\$config
|
|
unset fallback_${config_index}
|
|
: $(( config_index -= 1 ))
|
|
fi
|
|
fi
|
|
eoutdent
|
|
: $(( config_index += 1 ))
|
|
done
|
|
|
|
if ! ${oneworked}; then
|
|
if [ "$(command -v failup)" = "failup" ]; then
|
|
ebegin "Running failup"
|
|
eindent
|
|
failup
|
|
eoutdent
|
|
fi
|
|
return 1
|
|
fi
|
|
|
|
local hideFirstroute=false first=true routes=
|
|
if ${fallback}; then
|
|
routes="$(_get_array "fallback_routes_${IFVAR}")"
|
|
fi
|
|
if [ -z "${routes}" ]; then
|
|
routes="$(_get_array "routes_${IFVAR}")"
|
|
fi
|
|
if [ "${IFACE}" = "lo" -o "${IFACE}" = "lo0" ]; then
|
|
if [ "${config_0}" != "null" ]; then
|
|
routes="127.0.0.0/8 via 127.0.0.1
|
|
${routes}"
|
|
hideFirstroute=true
|
|
fi
|
|
fi
|
|
|
|
local OIFS="${IFS}" SIFS="${IFS-y}"
|
|
local IFS="$__IFS"
|
|
local fam
|
|
for cmd in ${routes}; do
|
|
unset IFS
|
|
if ${first}; then
|
|
first=false
|
|
einfo "Adding routes"
|
|
fi
|
|
|
|
case ${cmd} in
|
|
-6" "*) fam="-6"; cmd=${cmd#-6 };;
|
|
-4" "*) fam="-4"; cmd=${cmd#-4 };;
|
|
esac
|
|
|
|
eindent
|
|
ebegin ${cmd}
|
|
# Work out if we're a host or a net if not told
|
|
case ${cmd} in
|
|
-net" "*|-host" "*);;
|
|
*" "netmask" "*) cmd="-net ${cmd}";;
|
|
*.*.*.*/32*) cmd="-host ${cmd}";;
|
|
*.*.*.*/*|0.0.0.0|0.0.0.0" "*) cmd="-net ${cmd}";;
|
|
default|default" "*) cmd="-net ${cmd}";;
|
|
*:*/128*) cmd="-host ${cmd}";;
|
|
*:*/*) cmd="-net ${cmd}";;
|
|
*) cmd="-host ${cmd}";;
|
|
esac
|
|
if ${hideFirstroute}; then
|
|
_add_route ${fam} ${cmd} >/dev/null 2>&1
|
|
hideFirstroute=false
|
|
else
|
|
_add_route ${fam} ${cmd} >/dev/null
|
|
fi
|
|
eend $?
|
|
eoutdent
|
|
done
|
|
if [ "${SIFS}" = "y" ]; then
|
|
unset IFS
|
|
else
|
|
IFS="${OIFS}"
|
|
fi
|
|
|
|
for module in ${MODULES}; do
|
|
if [ "$(command -v "${module}_post_start")" = "${module}_post_start" ]; then
|
|
${module}_post_start || exit $?
|
|
fi
|
|
done
|
|
|
|
if [ "$(command -v postup)" = "postup" ]; then
|
|
ebegin "Running postup"
|
|
eindent
|
|
postup
|
|
eoutdent
|
|
fi
|
|
|
|
return 0
|
|
}
|
|
|
|
stop()
|
|
{
|
|
# Don't stop the network at shutdown.
|
|
# We don't use the noshutdown keyword so that we are started again
|
|
# correctly if we go back to multiuser.
|
|
yesno ${keep_network:-YES} && yesno $RC_GOINGDOWN && return 0
|
|
|
|
local IFACE=${RC_SVCNAME#*.} module=
|
|
local IFVAR=$(shell_var "${IFACE}") opts=
|
|
|
|
einfo "Bringing down interface ${IFACE}"
|
|
eindent
|
|
|
|
if [ -z "${MODULES}" ]; then
|
|
local MODULES=
|
|
_load_modules false
|
|
fi
|
|
|
|
if [ "$(command -v predown)" = "predown" ]; then
|
|
ebegin "Running predown"
|
|
eindent
|
|
predown || return 1
|
|
eoutdent
|
|
else
|
|
if is_net_fs /; then
|
|
eerror "root filesystem is network mounted -- can't stop ${IFACE}"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
for module in ${MODULES}; do
|
|
if [ "$(command -v "${module}_pre_stop")" = "${module}_pre_stop" ]; then
|
|
${module}_pre_stop || exit $?
|
|
fi
|
|
done
|
|
|
|
for module in ${MODULES}; do
|
|
if [ "$(command -v "${module}_stop")" = "${module}_stop" ]; then
|
|
${module}_stop
|
|
fi
|
|
done
|
|
|
|
# Only delete addresses for interfaces that exist
|
|
if _exists; then
|
|
# PPP can manage it's own addresses when IN_BACKGROUND
|
|
# Important in case "demand" set on the ppp link
|
|
if ! (yesno ${IN_BACKGROUND} && is_ppp) ; then
|
|
_delete_addresses "${IFACE}"
|
|
fi
|
|
fi
|
|
|
|
for module in ${MODULES}; do
|
|
if [ "$(command -v "${module}_post_stop")" = "${module}_post_stop" ]; then
|
|
${module}_post_stop
|
|
fi
|
|
done
|
|
|
|
# If not in background, and not loopback then bring the interface down
|
|
# unless overridden.
|
|
if ! yesno ${IN_BACKGROUND} && \
|
|
[ "${IFACE}" != "lo" -a "${IFACE}" != "lo0" ]; then
|
|
eval module=\$ifdown_${IFVAR}
|
|
module=${module:-${ifdown:-YES}}
|
|
yesno ${module} && _down 2>/dev/null
|
|
fi
|
|
|
|
type resolvconf >/dev/null 2>&1 && resolvconf -d "${IFACE}" 2>/dev/null
|
|
|
|
if [ "$(command -v "postdown")" = "postdown" ]; then
|
|
ebegin "Running postdown"
|
|
eindent
|
|
postdown
|
|
eoutdent
|
|
fi
|
|
|
|
return 0
|
|
}
|