d56448b35d
- Use "if !" instead of empty true branches. - Don't hardcode script name in usage message, use $0 instead. - Cleanup some whitespace.
171 lines
4.5 KiB
Bash
171 lines
4.5 KiB
Bash
#!/bin/sh
|
|
# $FreeBSD$
|
|
# This script sets up an Ethernet bridging network across multiple
|
|
# Ethernet interfaces using the ng_bridge(4) and ng_ether(4) netgraph
|
|
# node types.
|
|
#
|
|
# To use this script:
|
|
#
|
|
# 0. Make your own copy of this example script.
|
|
#
|
|
# 1. Give your bridging network a name by editing the definition of
|
|
# ${BRIDGE_NAME} below. It must be a valid netgraph node name.
|
|
#
|
|
# 2. Edit the definitions of ${BRIDGE_IFACES} and ${LOCAL_IFACES}
|
|
# as described below to define your bridging interfaces.
|
|
#
|
|
# 3. Run this script with "start" as the command line argument.
|
|
#
|
|
# 4. Examine bridging statistics by running this script with "stats"
|
|
# as the command line argument.
|
|
#
|
|
# 5. Stop bridging by running this script with "stop" as the
|
|
# command line argument.
|
|
#
|
|
# To run multiple independent bridging networks, create multiple
|
|
# copies of this script with different variable definitions.
|
|
#
|
|
# To make a "brouted" network, with IP being routed and other protocols being
|
|
# bridged, add all the interface in the BRIDGE_IFACES to the LOCAL_IFACES.
|
|
# If you just want a normal bridge, just one will be enough.
|
|
# In some cases you may want some combination.
|
|
#
|
|
|
|
# Give each bridging network a unique name here.
|
|
|
|
BRIDGE_NAME="bnet0"
|
|
|
|
# List the names of the interfaces that you want to bridge across
|
|
# here in ${BRIDGE_IFACES}. If you want to include the local host
|
|
# machine as well then set ${LOCAL_IFACES} as well (they may also be
|
|
# listed in ${BRIDGE_IFACES}). Of course, any ${LOCAL_IFACE} must
|
|
# be ifconfig(8)ured separately. If you don't want a ${LOCAL_IFACE}
|
|
# then assign it the emtpy string.
|
|
|
|
BRIDGE_IFACES="de0 fxp0 fxp1"
|
|
LOCAL_IFACES="fxp0 fxp1"
|
|
|
|
#####################################################################
|
|
#### Everything below this point should not need to be modified. ####
|
|
#####################################################################
|
|
|
|
# Routine to verify node's existence.
|
|
bridge_verify() {
|
|
ngctl info ${BRIDGE_NAME}: >/dev/null 2>&1
|
|
if [ $? -ne 0 ]; then
|
|
echo "${BRIDGE_NAME}: bridge network not found"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Routine to get and display link stats.
|
|
bridge_linkstats() {
|
|
STATS=`ngctl msg ${BRIDGE_NAME}: getstats $1`
|
|
if [ $? -ne 0 ]; then
|
|
exit 1
|
|
fi
|
|
echo "${STATS}" | fmt 2 | awk '/=/ { fl=index($0, "="); \
|
|
printf "%20s = %s\n", substr($0, 0, fl - 1), substr($0, fl + 1); }'
|
|
}
|
|
|
|
# Start/restart routine.
|
|
bridge_start() {
|
|
|
|
# Load netgraph KLD's as necessary.
|
|
for KLD in ng_ether ng_bridge; do
|
|
if ! kldstat -v | grep -qw ${KLD}; then
|
|
echo -n "Loading ${KLD}.ko... "
|
|
kldload ${KLD} || exit 1
|
|
echo "done"
|
|
fi
|
|
done
|
|
|
|
# Reset all interfaces.
|
|
bridge_stop
|
|
|
|
# Verify all interfaces exist.
|
|
for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do
|
|
if ! ngctl info ${ETHER}: >/dev/null 2>&1; then
|
|
echo "Error: interface ${ETHER} does not exist"
|
|
exit 1
|
|
fi
|
|
ifconfig ${ETHER} up || exit 1
|
|
done
|
|
|
|
# Create new ng_bridge(4) node, attached to the first interface.
|
|
FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'`
|
|
ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1
|
|
ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1
|
|
|
|
# Attach other interfaces as well.
|
|
LINKNUM=0
|
|
for ETHER in ${BRIDGE_IFACES}; do
|
|
if [ ${LINKNUM} != 0 ]; then
|
|
ngctl connect ${ETHER}: ${BRIDGE_NAME}: \
|
|
lower link${LINKNUM} || exit 1
|
|
fi
|
|
LINKNUM=`expr ${LINKNUM} + 1`
|
|
done
|
|
|
|
# Hook up local interface, if any.
|
|
for LOCAL_IFACE in ${LOCAL_IFACES}; do
|
|
ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \
|
|
upper link${LINKNUM} || exit 1
|
|
LINKNUM=`expr ${LINKNUM} + 1`
|
|
done
|
|
|
|
# Set all interfaces in promiscuous mode and don't overwrite src addr.
|
|
for ETHER in ${BRIDGE_IFACES}; do
|
|
ngctl msg ${ETHER}: setpromisc 1 || exit 1
|
|
ngctl msg ${ETHER}: setautosrc 0 || exit 1
|
|
done
|
|
}
|
|
|
|
# Stop routine.
|
|
bridge_stop() {
|
|
ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1
|
|
for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do
|
|
ngctl kill ${ETHER}: >/dev/null 2>&1
|
|
done
|
|
}
|
|
|
|
# Stats routine.
|
|
bridge_stats() {
|
|
|
|
# Make sure node exists.
|
|
bridge_verify
|
|
|
|
echo ""
|
|
echo "Statistics for bridging network ${BRIDGE_NAME}:"
|
|
echo ""
|
|
LINKNUM=0
|
|
for ETHER in ${BRIDGE_IFACES}; do
|
|
echo "Network interface ${ETHER}:"
|
|
bridge_linkstats ${LINKNUM}
|
|
LINKNUM=`expr ${LINKNUM} + 1`
|
|
done
|
|
for LOCAL_IFACE in ${LOCAL_IFACES}; do
|
|
echo "Local host interface ${LOCAL_IFACE}:"
|
|
bridge_linkstats ${LINKNUM}
|
|
LINKNUM=`expr ${LINKNUM} + 1`
|
|
done
|
|
}
|
|
|
|
# Main entry point.
|
|
case $1 in
|
|
start)
|
|
bridge_start
|
|
;;
|
|
stats)
|
|
bridge_verify
|
|
bridge_stats
|
|
;;
|
|
stop)
|
|
bridge_verify
|
|
bridge_stop
|
|
;;
|
|
*)
|
|
echo "usage: $0 [ start | stop | stats ]"
|
|
exit 1
|
|
esac
|