166512Sarchie#!/bin/sh 266512Sarchie# $FreeBSD$ 366512Sarchie# This script sets up an Ethernet bridging network across multiple 466512Sarchie# Ethernet interfaces using the ng_bridge(4) and ng_ether(4) netgraph 566512Sarchie# node types. 666512Sarchie# 766512Sarchie# To use this script: 866512Sarchie# 9156313Sschweikh# 0. Make your own copy of this example script. 1066512Sarchie# 1166512Sarchie# 1. Give your bridging network a name by editing the definition of 1266512Sarchie# ${BRIDGE_NAME} below. It must be a valid netgraph node name. 1366512Sarchie# 1494477Sjulian# 2. Edit the definitions of ${BRIDGE_IFACES} and ${LOCAL_IFACES} 1566512Sarchie# as described below to define your bridging interfaces. 1666512Sarchie# 1766512Sarchie# 3. Run this script with "start" as the command line argument. 1866512Sarchie# 1966512Sarchie# 4. Examine bridging statistics by running this script with "stats" 2066512Sarchie# as the command line argument. 2166512Sarchie# 2266512Sarchie# 5. Stop bridging by running this script with "stop" as the 2366512Sarchie# command line argument. 2466512Sarchie# 2566512Sarchie# To run multiple independent bridging networks, create multiple 2666512Sarchie# copies of this script with different variable definitions. 2794477Sjulian# 2894477Sjulian# To make a "brouted" network, with IP being routed and other protocols being 2994477Sjulian# bridged, add all the interface in the BRIDGE_IFACES to the LOCAL_IFACES. 30156313Sschweikh# If you just want a normal bridge, just one will be enough. 31156313Sschweikh# In some cases you may want some combination. 32156313Sschweikh# 3366512Sarchie 34156313Sschweikh# Give each bridging network a unique name here. 3566512Sarchie 3666512SarchieBRIDGE_NAME="bnet0" 3766512Sarchie 3866512Sarchie# List the names of the interfaces that you want to bridge across 3966512Sarchie# here in ${BRIDGE_IFACES}. If you want to include the local host 4094477Sjulian# machine as well then set ${LOCAL_IFACES} as well (they may also be 4166512Sarchie# listed in ${BRIDGE_IFACES}). Of course, any ${LOCAL_IFACE} must 4266512Sarchie# be ifconfig(8)ured separately. If you don't want a ${LOCAL_IFACE} 43222179Suqs# then assign it the empty string. 4466512Sarchie 4594477SjulianBRIDGE_IFACES="de0 fxp0 fxp1" 4694477SjulianLOCAL_IFACES="fxp0 fxp1" 4766512Sarchie 48156313Sschweikh##################################################################### 49156313Sschweikh#### Everything below this point should not need to be modified. #### 50156313Sschweikh##################################################################### 5166512Sarchie 52156313Sschweikh# Routine to verify node's existence. 5366512Sarchiebridge_verify() { 5466512Sarchie ngctl info ${BRIDGE_NAME}: >/dev/null 2>&1 5566512Sarchie if [ $? -ne 0 ]; then 5666512Sarchie echo "${BRIDGE_NAME}: bridge network not found" 5766512Sarchie exit 1 5866512Sarchie fi 5966512Sarchie} 6066512Sarchie 61156313Sschweikh# Routine to get and display link stats. 6266512Sarchiebridge_linkstats() { 6366512Sarchie STATS=`ngctl msg ${BRIDGE_NAME}: getstats $1` 6466512Sarchie if [ $? -ne 0 ]; then 6566512Sarchie exit 1 6666512Sarchie fi 6766512Sarchie echo "${STATS}" | fmt 2 | awk '/=/ { fl=index($0, "="); \ 6866512Sarchie printf "%20s = %s\n", substr($0, 0, fl - 1), substr($0, fl + 1); }' 6966512Sarchie} 7066512Sarchie 71156313Sschweikh# Start/restart routine. 7266512Sarchiebridge_start() { 7366512Sarchie 74156313Sschweikh # Load netgraph KLD's as necessary. 7566512Sarchie for KLD in ng_ether ng_bridge; do 76156313Sschweikh if ! kldstat -v | grep -qw ${KLD}; then 7766512Sarchie echo -n "Loading ${KLD}.ko... " 7866512Sarchie kldload ${KLD} || exit 1 7966512Sarchie echo "done" 8066512Sarchie fi 8166512Sarchie done 8266512Sarchie 83156313Sschweikh # Reset all interfaces. 8466512Sarchie bridge_stop 8566512Sarchie 86156313Sschweikh # Verify all interfaces exist. 8794477Sjulian for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do 88156313Sschweikh if ! ngctl info ${ETHER}: >/dev/null 2>&1; then 8966512Sarchie echo "Error: interface ${ETHER} does not exist" 9066512Sarchie exit 1 9166512Sarchie fi 9266512Sarchie ifconfig ${ETHER} up || exit 1 9366512Sarchie done 9466512Sarchie 95156313Sschweikh # Create new ng_bridge(4) node, attached to the first interface. 9666512Sarchie FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'` 9766512Sarchie ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1 9866512Sarchie ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1 9966512Sarchie 100156313Sschweikh # Attach other interfaces as well. 10166512Sarchie LINKNUM=0 10266512Sarchie for ETHER in ${BRIDGE_IFACES}; do 10366512Sarchie if [ ${LINKNUM} != 0 ]; then 10466512Sarchie ngctl connect ${ETHER}: ${BRIDGE_NAME}: \ 10566512Sarchie lower link${LINKNUM} || exit 1 10666512Sarchie fi 10766512Sarchie LINKNUM=`expr ${LINKNUM} + 1` 10866512Sarchie done 10966512Sarchie 110156313Sschweikh # Hook up local interface, if any. 11194477Sjulian for LOCAL_IFACE in ${LOCAL_IFACES}; do 11266512Sarchie ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \ 11366512Sarchie upper link${LINKNUM} || exit 1 11494477Sjulian LINKNUM=`expr ${LINKNUM} + 1` 11594477Sjulian done 11666512Sarchie 117156313Sschweikh # Set all interfaces in promiscuous mode and don't overwrite src addr. 11866512Sarchie for ETHER in ${BRIDGE_IFACES}; do 11966512Sarchie ngctl msg ${ETHER}: setpromisc 1 || exit 1 12066512Sarchie ngctl msg ${ETHER}: setautosrc 0 || exit 1 12166512Sarchie done 12266512Sarchie} 12366512Sarchie 124156313Sschweikh# Stop routine. 12566512Sarchiebridge_stop() { 12666512Sarchie ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1 12794477Sjulian for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do 12866512Sarchie ngctl kill ${ETHER}: >/dev/null 2>&1 12966512Sarchie done 13066512Sarchie} 13166512Sarchie 132156313Sschweikh# Stats routine. 13366512Sarchiebridge_stats() { 13466512Sarchie 135156313Sschweikh # Make sure node exists. 13666512Sarchie bridge_verify 13766512Sarchie 13866512Sarchie echo "" 13966512Sarchie echo "Statistics for bridging network ${BRIDGE_NAME}:" 14066512Sarchie echo "" 14166512Sarchie LINKNUM=0 14266512Sarchie for ETHER in ${BRIDGE_IFACES}; do 14366512Sarchie echo "Network interface ${ETHER}:" 14466512Sarchie bridge_linkstats ${LINKNUM} 14566512Sarchie LINKNUM=`expr ${LINKNUM} + 1` 14666512Sarchie done 14794477Sjulian for LOCAL_IFACE in ${LOCAL_IFACES}; do 14879035Sdd echo "Local host interface ${LOCAL_IFACE}:" 14966512Sarchie bridge_linkstats ${LINKNUM} 15094477Sjulian LINKNUM=`expr ${LINKNUM} + 1` 15194477Sjulian done 15266512Sarchie} 15366512Sarchie 154156313Sschweikh# Main entry point. 15566512Sarchiecase $1 in 15666512Sarchie start) 15766512Sarchie bridge_start 15866512Sarchie ;; 15966512Sarchie stats) 16066512Sarchie bridge_verify 16166512Sarchie bridge_stats 16266512Sarchie ;; 16366512Sarchie stop) 16466512Sarchie bridge_verify 16566512Sarchie bridge_stop 16666512Sarchie ;; 16766512Sarchie *) 168156313Sschweikh echo "usage: $0 [ start | stop | stats ]" 16966512Sarchie exit 1 17066512Sarchieesac 171