#!/bin/sh # /etc/rc.d/rc.netbridge # # This is script is used to setup ethernet bridges. # The code is based on Zenwalk's rc.inet1 and rc.wireless scripts. # # Author: Thorsten Muehlfelder # Date: 2008-11-19 # Version: 0.2 # # Get the configuration information from /etc/rc.d/rc.inet1.conf: . /etc/rc.d/rc.netbridge.conf # If possible, log events in /var/log/messages: if [ -f /var/run/syslogd.pid -a -x /usr/bin/logger ]; then LOGGER=/usr/bin/logger else # output to stdout/stderr: LOGGER=/bin/cat fi ############################ # DETERMINE INTERFACE LIST # ############################ # Compose a list of interfaces from /etc/rc.d/rc.inet1.conf (with a maximum # of 6 interfaces, but you can easily enlarge the interface limit # If a value for IFNAME[n] is not set, we assume it is an br'n' interface. # This way, the new script is compatible with older rc.inet1.conf files. # The IFNAME array will be used to determine which interfaces to bring up/down. MAXNICS=6 for ((i=0; i <= $MAXNICS ; i++)) ; do IFNAME[$i]=${IFNAME[$i]:=br${i}} done # Function to set up an ethernet bridge: br_up() { # Determine position 'i' of this interface in the IFNAME array: for ((i=0; i <= $MAXNICS ; i++)) ; do [ "${IFNAME[$i]}" = "${1}" ] && break done # If the interface is disabled, skip it [ "${STATUS[$i]}" = "down" ] && return if [ -n "${BRPORTS[$i]}" ]; then # interface is configured as a bridge if [ -d /sys/class/net/${1} ] ; then # interface already exists if [ "$DEBUG_BR_UP" = "yes" ]; then echo "/etc/rc.d/rc.inet1: ${1} already exists! Can't create bridge, skipping" | $LOGGER fi else # add the bridge echo "/etc/rc.d/rc.netbridge: /sbin/brctl addbr ${1}" | $LOGGER /usr/sbin/brctl addbr ${1} 1>/dev/null 2>&1 # check interfaces for bridge echo "/etc/rc.d/rc.netbridge: adding ${BRPORTS[$i]} to ${1}" | $LOGGER for BRPORT in ${BRPORTS[$i]}; do if [ ! -d /sys/class/net/${BRPORT} ] ; then # interface for bridge does not exist if [ "$DEBUG_BR_UP" = "yes" ]; then echo "/etc/rc.d/rc.netbridge: ${BRPORT} interface for ${1} bridge does not exist (yet)" | $LOGGER continue fi fi if /sbin/ifconfig ${BRPORT} | grep "inet addr" 1> /dev/null ; then # interface for bridge is already up if [ "$DEBUG_BR_UP" = "yes" ]; then echo "/etc/rc.d/rc.netbridge: ${BRPORT} interface for ${1} bridge is already up" | $LOGGER continue fi fi # add the interface to the bridge /sbin/ifconfig ${BRPORT} 0.0.0.0 echo "/etc/rc.d/rc.netbridge: /sbin/brctl addif ${1} ${BRPORT}" | $LOGGER /usr/sbin/brctl addif ${1} ${BRPORT} done if [ "${BRSTP[$i]}" = "on" ]; then echo "/etc/rc.d/rc.netbridge: /sbin/brctl stp ${1} on" | $LOGGER /usr/sbin/brctl stp ${1} on # enable spanning tree protocol fi if [ ! "${BRPRIO[$i]}" = "" ]; then echo "/etc/rc.d/rc.netbridge: /sbin/brctl setbridgeprio ${1} ${BRPRIO[$i]}" | $LOGGER /usr/sbin/brctl setbridgeprio ${1} ${BRPRIO[$i]} # set bridge priority fi if [ ! "${BRFD[$i]}" = "" ]; then echo "/etc/rc.d/rc.netbridge: /sbin/brctl setfd ${1} ${BRPRIO[$i]}" | $LOGGER /usr/sbin/brctl setfd ${1} ${BRFD[$i]} # set forwarding delay fi if [ ! "${BRHELLO[$i]}" = "" ]; then echo "/etc/rc.d/rc.netbridge: /sbin/brctl sethello ${1} ${BRPRIO[$i]}" | $LOGGER /usr/sbin/brctl sethello ${1} ${BRHELLO[$i]} # set hello time fi if [ ! "${BRMAXAGE[$i]}" = "" ]; then echo "/etc/rc.d/rc.netbridge: /sbin/brctl maxage ${1} ${BRPRIO[$i]}" | $LOGGER /usr/sbin/brctl maxage ${1} ${BRMAXAGE[$i]} # set maximum age fi fi fi } # Function to take down an ethernet bridge: br_down() { # Determine position 'i' of this interface in the IFNAME array: i=0 while [ $i -lt $MAXNICS ]; do [ "${IFNAME[$i]}" = "${1}" ] && break i=$(($i+1)) done if [ -d /sys/class/net/${1}/bridge ] ; then if /sbin/ifconfig ${1} | grep "inet addr" 1> /dev/null ; then # bridge is up? echo "/etc/rc.d/rc.netbridge: /etc/rc.d/rc.inet1 ${1}_down" | $LOGGER /etc/rc.d/rc.inet1 ${1}_down sleep 1 fi # delete the bridge echo "/etc/rc.d/rc.netbridge: /sbin/brctl delbr ${1}" | $LOGGER /usr/sbin/brctl delbr ${1} 2>&1 | $LOGGER fi } # Function to start the bridges: start() { for i in ${IFNAME[@]} ; do br_up $i done } # Function to stop the bridges: stop() { for i in ${IFNAME[@]} ; do br_down $i done } case "$1" in 'start') # "start" brings up all configured interfaces: start ;; 'stop') # "stop" takes down all configured interfaces: stop ;; 'restart') # "restart" restarts the network: stop start ;; *_start) # Example: "br0_start" will start the specified interface 'br0' INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1) br_up $INTERFACE ;; *_stop) # Example: "br0_stop" will stop the specified interface 'br0' INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1) br_down $INTERFACE ;; *_restart) # Example: "br3_restart" will take 'br3' down and up again INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1) br_down $INTERFACE sleep 1 br_up $INTERFACE ;; 'up') # "up" does the same thing as "start" start ;; 'down') # "down" does the same thing as "stop" stop ;; *_up) # "*_up" does the same thing as "*_start" INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1) br_up $INTERFACE ;; *_down) # "*_down" does the same thing as "*_stop" INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1) br_down $INTERFACE ;; *) # The default is to bring up all configured interfaces: start ;; esac