freebsd-dev/share/examples/netgraph/ether.bridge

168 lines
4.1 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_IFACE}
# 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.
#
# 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_IFACE} as well (it 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 leave it defined as the emtpy string.
BRIDGE_IFACES="ed0 fxp0 fxp1"
LOCAL_IFACE="fxp0"
####################################################################
#### 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
else
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_IFACE}; do
if ngctl info ${ETHER}: >/dev/null 2>&1; then
else
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
if [ "${LOCAL_IFACE}" != "" ]; then
ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \
upper link${LINKNUM} || exit 1
fi
# 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_IFACE}; 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
if [ "${LOCAL_IFACE}" != "" ]; then
echo "Local host interface ${ETHER}:"
bridge_linkstats ${LINKNUM}
fi
}
# Main entry point
case $1 in
start)
bridge_start
;;
stats)
bridge_verify
bridge_stats
;;
stop)
bridge_verify
bridge_stop
;;
*)
echo "Usage: ether.bridge [ start | stop | stats ]"
exit 1
esac