4255ba175b
The program function in depend blocks is now able to search paths by itself. If passed multiple arguments or multiple calls, at least one of the arguments passed must be a program or a shell builtin (eg ip built into busybox). If a qualified path is specified, only that path will be checked, otherwise it will be checked as a builtin, then $PATH will be checked for the named binary (via type). Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
192 lines
4.1 KiB
Bash
192 lines
4.1 KiB
Bash
# Copyright (c) 2007-2008 Roy Marples <roy@marples.name>
|
|
# Released under the 2-clause BSD license.
|
|
|
|
bridge_depend()
|
|
{
|
|
before interface macnet
|
|
program brctl
|
|
}
|
|
|
|
_config_vars="$_config_vars bridge bridge_add brctl"
|
|
|
|
_is_bridge()
|
|
{
|
|
[ -d /sys/class/net/"${1:-${IFACE}}"/bridge ]
|
|
return $?
|
|
}
|
|
|
|
_is_bridge_port()
|
|
{
|
|
[ -d /sys/class/net/"${1:-${IFACE}}"/brport ]
|
|
return $?
|
|
}
|
|
|
|
_bridge_ports()
|
|
{
|
|
for x in /sys/class/net/"${1:-${IFACE}}"/brif/*; do
|
|
n=${x##*/}
|
|
echo $n
|
|
done
|
|
}
|
|
|
|
bridge_pre_start()
|
|
{
|
|
local brif= oiface="${IFACE}" e= x=
|
|
# ports is for static add
|
|
local ports="$(_get_array "bridge_${IFVAR}")"
|
|
# old config options
|
|
local opts="$(_get_array "brctl_${IFVAR}")"
|
|
# brif is used for dynamic add
|
|
eval brif=\$bridge_add_${IFVAR}
|
|
|
|
# we need a way to if the bridge exists in a variable name, not just the
|
|
# contents of a variable. Eg if somebody has only bridge_add_eth0='br0',
|
|
# with no other lines mentioning br0.
|
|
eval bridge_unset=\${bridge_${IFVAR}-y\}
|
|
eval brctl_unset=\${brctl_${IFVAR}-y\}
|
|
|
|
if [ -z "${brif}" -a "${brctl_unset}" = 'y' ]; then
|
|
if [ -z "${ports}" -a "${bridge_unset}" = "y" ]; then
|
|
#eerror "Misconfigured static bridge detected (see net.example)"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# If the bridge was already up, we should clear it
|
|
[ "${bridge_unset}" != "y" ] && bridge_post_stop
|
|
|
|
(
|
|
# Normalize order of variables
|
|
if [ -z "${ports}" -a -n "${brif}" ]; then
|
|
# Dynamic mode detected
|
|
ports="${IFACE}"
|
|
IFACE="${brif}"
|
|
IFVAR=$(shell_var "${IFACE}")
|
|
else
|
|
# Static mode detected
|
|
ports="${ports}"
|
|
metric=1000
|
|
fi
|
|
|
|
if ! _is_bridge ; then
|
|
ebegin "Creating bridge ${IFACE}"
|
|
if ! brctl addbr "${IFACE}"; then
|
|
eend 1
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
# TODO: does this reset the bridge every time we add a interface to the
|
|
# bridge? We should probably NOT do that.
|
|
|
|
# Old configuration set mechanism
|
|
# Only a very limited subset of the options are available in the old
|
|
# configuration method. The sysfs interface is in the next block instead.
|
|
local IFS="$__IFS"
|
|
for x in ${opts}; do
|
|
unset IFS
|
|
set -- ${x}
|
|
x=$1
|
|
shift
|
|
set -- "${x}" "${IFACE}" "$@"
|
|
brctl "$@"
|
|
done
|
|
unset IFS
|
|
|
|
# New configuration set mechanism, matches bonding
|
|
for x in /sys/class/net/"${IFACE}"/bridge/*; do
|
|
[ -f "${x}" ] || continue
|
|
n=${x##*/}
|
|
eval s=\$${n}_${IFVAR}
|
|
if [ -n "${s}" ]; then
|
|
einfo "Setting ${n}: ${s}"
|
|
echo "${s}" >"${x}" || \
|
|
eerror "Failed to configure $n (${n}_${IFVAR})"
|
|
fi
|
|
done
|
|
|
|
if [ -n "${ports}" ]; then
|
|
einfo "Adding ports to ${IFACE}"
|
|
eindent
|
|
|
|
local BR_IFACE="${IFACE}"
|
|
for x in ${ports}; do
|
|
ebegin "${x}"
|
|
local IFACE="${x}"
|
|
local IFVAR=$(shell_var "${IFACE}")
|
|
if ! _exists "${IFACE}" ; then
|
|
eerror "Cannot add non-existent interface ${IFACE} to ${BR_IFACE}"
|
|
return 1
|
|
fi
|
|
# The interface is known to exist now
|
|
_set_flag promisc
|
|
_up
|
|
if ! brctl addif "${BR_IFACE}" "${x}"; then
|
|
_set_flag -promisc
|
|
eend 1
|
|
return 1
|
|
fi
|
|
# Per-interface bridge settings
|
|
for x in /sys/class/net/"${IFACE}"/brport/*; do
|
|
[ -f "${x}" ] || continue
|
|
n=${x##*/}
|
|
eval s=\$${n}_${IFVAR}
|
|
if [ -n "${s}" ]; then
|
|
einfo "Setting ${n}@${IFACE}: ${s}"
|
|
echo "${s}" >"${x}" || \
|
|
eerror "Failed to configure $n (${n}_${IFVAR})"
|
|
fi
|
|
done
|
|
eend 0
|
|
done
|
|
eoutdent
|
|
fi
|
|
) || return 1
|
|
|
|
# Bring up the bridge
|
|
_up
|
|
}
|
|
|
|
bridge_post_stop()
|
|
{
|
|
local port= ports= delete=false extra=
|
|
|
|
if _is_bridge "${IFACE}"; then
|
|
ebegin "Destroying bridge ${IFACE}"
|
|
_down
|
|
for x in /sys/class/net/"${IFACE}"/brif/*; do
|
|
[ -s $x ] || continue
|
|
n=${x##*/}
|
|
ports="${ports} ${n}"
|
|
done
|
|
delete=true
|
|
iface=${IFACE}
|
|
eindent
|
|
else
|
|
# We are taking down an interface that is part of a bridge maybe
|
|
ports="${IFACE}"
|
|
local brport_dir="/sys/class/net/${IFACE}/brport"
|
|
[ -d ${brport_dir} ] || return 0
|
|
iface=$(readlink ${brport_dir}/bridge)
|
|
iface=${iface##*/}
|
|
[ -z "${iface}" ] && return 0
|
|
extra=" from ${iface}"
|
|
fi
|
|
|
|
for port in ${ports}; do
|
|
ebegin "Removing port ${port}${extra}"
|
|
local IFACE="${port}"
|
|
_set_flag -promisc
|
|
brctl delif "${iface}" "${port}"
|
|
eend $?
|
|
done
|
|
|
|
if ${delete}; then
|
|
eoutdent
|
|
brctl delbr "${iface}"
|
|
eend $?
|
|
fi
|
|
|
|
return 0
|
|
}
|