meta-sysmocom-bsp/recipes-extra/bridge-utils/files/ifupdown.sh

221 lines
5.3 KiB
Bash
Executable File

#!/bin/sh
# You don't usually need to touch this file at all, the full configuration
# of the bridge can be done in a standard way on /etc/network/interfaces.
# Have a look at /usr/share/doc/bridge-utils/README.Debian if you want
# more info about the way on wich a bridge is set up on Debian.
if [ ! -x /usr/sbin/brctl ]
then
exit 0
fi
. /lib/bridge-utils/bridge-utils.sh
case "$IF_BRIDGE_PORTS" in
"")
exit 0
;;
none)
INTERFACES=""
;;
*)
INTERFACES="$IF_BRIDGE_PORTS"
;;
esac
# Previous work (create the interface)
if [ "$MODE" = "start" ] && [ ! -d /sys/class/net/$IFACE ]; then
brctl addbr $IFACE || exit 1
if [ "$IF_BRIDGE_HW" ]; then
ip link set dev $IFACE address $IF_BRIDGE_HW
fi
# Wait for the ports to become available
if [ "$IF_BRIDGE_WAITPORT" ]
then
set x $IF_BRIDGE_WAITPORT &&
shift &&
WAIT="$1" &&
shift &&
WAITPORT="$@" &&
if [ -z "$WAITPORT" ];then WAITPORT="$IF_BRIDGE_PORTS";fi &&
STARTTIME=$(date +%s) &&
NOTFOUND="true" &&
/bin/echo -e "\nWaiting for a max of $WAIT seconds for $WAITPORT to become available." &&
while [ "$(($(date +%s)-$STARTTIME))" -le "$WAIT" ] && [ -n "$NOTFOUND" ]
do
NOTFOUND=""
for i in $WAITPORT
do
if ! grep -q "^[\ ]*$i:.*$" /proc/net/dev;then NOTFOUND="true";fi
done
if [ -n "$NOTFOUND" ];then sleep 1;fi
done
fi
# Previous work (stop the interface)
elif [ "$MODE" = "stop" ]; then
ip link set dev $IFACE down || exit 1
fi
all_interfaces= &&
unset all_interfaces &&
bridge_parse_ports $INTERFACES | while read i
do
for port in $i
do
# We attach and configure each port of the bridge
if [ "$MODE" = "start" ] && [ ! -d /sys/class/net/$IFACE/brif/$port ]; then
if [ -x /etc/network/if-pre-up.d/vlan ]; then
env IFACE=$port /etc/network/if-pre-up.d/vlan
fi
if [ "$IF_BRIDGE_HW" ]
then
KVER="$(uname -r)"
LKVER="${KVER#*.}"
LKVER="${LKVER%%-*}"
LKVER="${LKVER%%.*}"
if [ "${KVER%%.*}" -lt 3 -o "${KVER%%.*}" -eq 3 -a "$LKVER" -lt 3 ]
then
ip link set dev $port address $IF_BRIDGE_HW
fi
fi
if [ -f /proc/sys/net/ipv6/conf/$port/disable_ipv6 ]
then
echo 1 > /proc/sys/net/ipv6/conf/$port/disable_ipv6
fi
brctl addif $IFACE $port && ip link set dev $port up
# We detach each port of the bridge
elif [ "$MODE" = "stop" ] && [ -d /sys/class/net/$IFACE/brif/$port ]; then
ip link set dev $port down && brctl delif $IFACE $port && \
if [ -x /etc/network/if-post-down.d/vlan ]; then
env IFACE=$port /etc/network/if-post-down.d/vlan
fi
if [ -f /proc/sys/net/ipv6/conf/$port/disable_ipv6 ]
then
echo 0 > /proc/sys/net/ipv6/conf/$port/disable_ipv6
fi
fi
done
done
# We finish setting up the bridge
if [ "$MODE" = "start" ] ; then
if [ "$IF_BRIDGE_AGEING" ]
then
brctl setageing $IFACE $IF_BRIDGE_AGEING
fi
if [ "$IF_BRIDGE_BRIDGEPRIO" ]
then
brctl setbridgeprio $IFACE $IF_BRIDGE_BRIDGEPRIO
fi
if [ "$IF_BRIDGE_GCINT" ]
then
brctl setgcint $IFACE $IF_BRIDGE_GCINT
fi
if [ "$IF_BRIDGE_HELLO" ]
then
brctl sethello $IFACE $IF_BRIDGE_HELLO
fi
if [ "$IF_BRIDGE_MAXAGE" ]
then
brctl setmaxage $IFACE $IF_BRIDGE_MAXAGE
fi
if [ "$IF_BRIDGE_PATHCOST" ]
then
brctl setpathcost $IFACE $IF_BRIDGE_PATHCOST
fi
if [ "$IF_BRIDGE_PORTPRIO" ]
then
brctl setportprio $IFACE $IF_BRIDGE_PORTPRIO
fi
if [ "$IF_BRIDGE_STP" ]
then
brctl stp $IFACE $IF_BRIDGE_STP
fi
if [ "$IF_BRIDGE_FD" ]
then
brctl setfd $IFACE $IF_BRIDGE_FD
fi
# We activate the bridge
ip link set dev $IFACE up
# Calculate the maximum time to wait for the bridge to be ready
if [ "$IF_BRIDGE_MAXWAIT" ]
then
MAXWAIT=$IF_BRIDGE_MAXWAIT
else
MAXWAIT=$(brctl showstp $IFACE 2>/dev/null|sed -n 's/^.*forward delay[ \t]*\(.*\)\..*bridge forward delay[ \t]*\(.*\)\..*$/\1 \2/p')
if [ "$MAXWAIT" ]
then
if [ ${MAXWAIT% *} -gt ${MAXWAIT#* } ]
then
MAXWAIT=$((2*(${MAXWAIT% *}+1)))
else
MAXWAIT=$((2*(${MAXWAIT#* }+1)))
fi
else
if [ "$IF_BRIDGE_FD" ]
then
MAXWAIT=$((2*(${IF_BRIDGE_FD%.*}+1)))
else
MAXWAIT=32
fi
/bin/echo -e "\nWaiting $MAXWAIT seconds for $IFACE to get ready."
sleep $MAXWAIT
MAXWAIT=0
fi
fi
# Wait for the bridge to be ready
if [ "$MAXWAIT" != 0 ]
then
/bin/echo -e "\nWaiting for $IFACE to get ready (MAXWAIT is $MAXWAIT seconds)."
unset BREADY
unset TRANSITIONED
COUNT=0
# Use 0.1 delay if available
sleep 0.1 2>/dev/null && MAXWAIT=$((MAXWAIT * 10))
while [ ! "$BREADY" -a $COUNT -lt $MAXWAIT ]
do
sleep 0.1 2>/dev/null || sleep 1
COUNT=$(($COUNT+1))
BREADY=true
for i in $(brctl showstp $IFACE|sed -n 's/^.*port id.*state[ \t]*\(.*\)$/\1/p')
do
if [ "$i" = "listening" -o "$i" = "learning" -o "$i" = "forwarding" -o "$i" = "blocking" ]
then
TRANSITIONED=true
fi
if [ "$i" != "forwarding" -a "$i" != "blocking" ] && [ ! "$TRANSITIONED" -o "$i" != "disabled" ]
then
unset BREADY
fi
done
done
fi
# Finally we destroy the interface
elif [ "$MODE" = "stop" ]; then
brctl delbr $IFACE
fi