1beb75cedSArchie Cobbs#!/bin/sh 2beb75cedSArchie Cobbs# $FreeBSD$ 3beb75cedSArchie Cobbs 4beb75cedSArchie Cobbs# This script sets up an Ethernet bridging network across multiple 5beb75cedSArchie Cobbs# Ethernet interfaces using the ng_bridge(4) and ng_ether(4) netgraph 6beb75cedSArchie Cobbs# node types. 7beb75cedSArchie Cobbs# 8beb75cedSArchie Cobbs# To use this script: 9beb75cedSArchie Cobbs# 10beb75cedSArchie Cobbs# 0. Make your own copy of this example script 11beb75cedSArchie Cobbs# 12beb75cedSArchie Cobbs# 1. Give your bridging network a name by editing the definition of 13beb75cedSArchie Cobbs# ${BRIDGE_NAME} below. It must be a valid netgraph node name. 14beb75cedSArchie Cobbs# 15beb75cedSArchie Cobbs# 2. Edit the definitions of ${BRIDGE_IFACES} and ${LOCAL_IFACE} 16beb75cedSArchie Cobbs# as described below to define your bridging interfaces. 17beb75cedSArchie Cobbs# 18beb75cedSArchie Cobbs# 3. Run this script with "start" as the command line argument. 19beb75cedSArchie Cobbs# 20beb75cedSArchie Cobbs# 4. Examine bridging statistics by running this script with "stats" 21beb75cedSArchie Cobbs# as the command line argument. 22beb75cedSArchie Cobbs# 23beb75cedSArchie Cobbs# 5. Stop bridging by running this script with "stop" as the 24beb75cedSArchie Cobbs# command line argument. 25beb75cedSArchie Cobbs# 26beb75cedSArchie Cobbs# To run multiple independent bridging networks, create multiple 27beb75cedSArchie Cobbs# copies of this script with different variable definitions. 28beb75cedSArchie Cobbs# 29beb75cedSArchie Cobbs 30beb75cedSArchie Cobbs# Give each bridging network a unique name here 31beb75cedSArchie Cobbs 32beb75cedSArchie CobbsBRIDGE_NAME="bnet0" 33beb75cedSArchie Cobbs 34beb75cedSArchie Cobbs# List the names of the interfaces that you want to bridge across 35beb75cedSArchie Cobbs# here in ${BRIDGE_IFACES}. If you want to include the local host 36beb75cedSArchie Cobbs# machine as well then set ${LOCAL_IFACE} as well (it may also be 37beb75cedSArchie Cobbs# listed in ${BRIDGE_IFACES}). Of course, any ${LOCAL_IFACE} must 38beb75cedSArchie Cobbs# be ifconfig(8)ured separately. If you don't want a ${LOCAL_IFACE} 39beb75cedSArchie Cobbs# then leave it defined as the emtpy string. 40beb75cedSArchie Cobbs 41beb75cedSArchie CobbsBRIDGE_IFACES="ed0 fxp0 fxp1" 42beb75cedSArchie CobbsLOCAL_IFACE="fxp0" 43beb75cedSArchie Cobbs 44beb75cedSArchie Cobbs#################################################################### 45beb75cedSArchie Cobbs#### Everything below this point should not need to be modified #### 46beb75cedSArchie Cobbs#################################################################### 47beb75cedSArchie Cobbs 48beb75cedSArchie Cobbs# Routine to verify node's existence 49beb75cedSArchie Cobbsbridge_verify() { 50beb75cedSArchie Cobbs ngctl info ${BRIDGE_NAME}: >/dev/null 2>&1 51beb75cedSArchie Cobbs if [ $? -ne 0 ]; then 52beb75cedSArchie Cobbs echo "${BRIDGE_NAME}: bridge network not found" 53beb75cedSArchie Cobbs exit 1 54beb75cedSArchie Cobbs fi 55beb75cedSArchie Cobbs} 56beb75cedSArchie Cobbs 57beb75cedSArchie Cobbs# Routine to get and display link stats 58beb75cedSArchie Cobbsbridge_linkstats() { 59beb75cedSArchie Cobbs STATS=`ngctl msg ${BRIDGE_NAME}: getstats $1` 60beb75cedSArchie Cobbs if [ $? -ne 0 ]; then 61beb75cedSArchie Cobbs exit 1 62beb75cedSArchie Cobbs fi 63beb75cedSArchie Cobbs echo "${STATS}" | fmt 2 | awk '/=/ { fl=index($0, "="); \ 64beb75cedSArchie Cobbs printf "%20s = %s\n", substr($0, 0, fl - 1), substr($0, fl + 1); }' 65beb75cedSArchie Cobbs} 66beb75cedSArchie Cobbs 67beb75cedSArchie Cobbs# Start/restart routine 68beb75cedSArchie Cobbsbridge_start() { 69beb75cedSArchie Cobbs 70beb75cedSArchie Cobbs # Load netgraph KLD's as necessary 71beb75cedSArchie Cobbs for KLD in ng_ether ng_bridge; do 72beb75cedSArchie Cobbs if kldstat -v | grep -qw ${KLD}; then 73beb75cedSArchie Cobbs else 74beb75cedSArchie Cobbs echo -n "Loading ${KLD}.ko... " 75beb75cedSArchie Cobbs kldload ${KLD} || exit 1 76beb75cedSArchie Cobbs echo "done" 77beb75cedSArchie Cobbs fi 78beb75cedSArchie Cobbs done 79beb75cedSArchie Cobbs 80beb75cedSArchie Cobbs # Reset all interfaces 81beb75cedSArchie Cobbs bridge_stop 82beb75cedSArchie Cobbs 83beb75cedSArchie Cobbs # Verify all interfaces exist 84beb75cedSArchie Cobbs for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do 85beb75cedSArchie Cobbs if ngctl info ${ETHER}: >/dev/null 2>&1; then 86beb75cedSArchie Cobbs else 87beb75cedSArchie Cobbs echo "Error: interface ${ETHER} does not exist" 88beb75cedSArchie Cobbs exit 1 89beb75cedSArchie Cobbs fi 90beb75cedSArchie Cobbs ifconfig ${ETHER} up || exit 1 91beb75cedSArchie Cobbs done 92beb75cedSArchie Cobbs 93beb75cedSArchie Cobbs # Create new ng_bridge(4) node, attached to the first interface 94beb75cedSArchie Cobbs FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'` 95beb75cedSArchie Cobbs ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1 96beb75cedSArchie Cobbs ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1 97beb75cedSArchie Cobbs 98beb75cedSArchie Cobbs # Attach other interfaces as well 99beb75cedSArchie Cobbs LINKNUM=0 100beb75cedSArchie Cobbs for ETHER in ${BRIDGE_IFACES}; do 101beb75cedSArchie Cobbs if [ ${LINKNUM} != 0 ]; then 102beb75cedSArchie Cobbs ngctl connect ${ETHER}: ${BRIDGE_NAME}: \ 103beb75cedSArchie Cobbs lower link${LINKNUM} || exit 1 104beb75cedSArchie Cobbs fi 105beb75cedSArchie Cobbs LINKNUM=`expr ${LINKNUM} + 1` 106beb75cedSArchie Cobbs done 107beb75cedSArchie Cobbs 108beb75cedSArchie Cobbs # Hook up local interface, if any 109beb75cedSArchie Cobbs if [ "${LOCAL_IFACE}" != "" ]; then 110beb75cedSArchie Cobbs ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \ 111beb75cedSArchie Cobbs upper link${LINKNUM} || exit 1 112beb75cedSArchie Cobbs fi 113beb75cedSArchie Cobbs 114beb75cedSArchie Cobbs # Set all interfaces in promiscuous mode and don't overwrite src addr 115beb75cedSArchie Cobbs for ETHER in ${BRIDGE_IFACES}; do 116beb75cedSArchie Cobbs ngctl msg ${ETHER}: setpromisc 1 || exit 1 117beb75cedSArchie Cobbs ngctl msg ${ETHER}: setautosrc 0 || exit 1 118beb75cedSArchie Cobbs done 119beb75cedSArchie Cobbs} 120beb75cedSArchie Cobbs 121beb75cedSArchie Cobbs# Stop routine 122beb75cedSArchie Cobbsbridge_stop() { 123beb75cedSArchie Cobbs ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1 124beb75cedSArchie Cobbs for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do 125beb75cedSArchie Cobbs ngctl kill ${ETHER}: >/dev/null 2>&1 126beb75cedSArchie Cobbs done 127beb75cedSArchie Cobbs} 128beb75cedSArchie Cobbs 129beb75cedSArchie Cobbs# Stats routine 130beb75cedSArchie Cobbsbridge_stats() { 131beb75cedSArchie Cobbs 132beb75cedSArchie Cobbs # Make sure node exists 133beb75cedSArchie Cobbs bridge_verify 134beb75cedSArchie Cobbs 135beb75cedSArchie Cobbs echo "" 136beb75cedSArchie Cobbs echo "Statistics for bridging network ${BRIDGE_NAME}:" 137beb75cedSArchie Cobbs echo "" 138beb75cedSArchie Cobbs LINKNUM=0 139beb75cedSArchie Cobbs for ETHER in ${BRIDGE_IFACES}; do 140beb75cedSArchie Cobbs echo "Network interface ${ETHER}:" 141beb75cedSArchie Cobbs bridge_linkstats ${LINKNUM} 142beb75cedSArchie Cobbs LINKNUM=`expr ${LINKNUM} + 1` 143beb75cedSArchie Cobbs done 144beb75cedSArchie Cobbs if [ "${LOCAL_IFACE}" != "" ]; then 145beb75cedSArchie Cobbs echo "Local host interface ${ETHER}:" 146beb75cedSArchie Cobbs bridge_linkstats ${LINKNUM} 147beb75cedSArchie Cobbs fi 148beb75cedSArchie Cobbs} 149beb75cedSArchie Cobbs 150beb75cedSArchie Cobbs# Main entry point 151beb75cedSArchie Cobbscase $1 in 152beb75cedSArchie Cobbs start) 153beb75cedSArchie Cobbs bridge_start 154beb75cedSArchie Cobbs ;; 155beb75cedSArchie Cobbs stats) 156beb75cedSArchie Cobbs bridge_verify 157beb75cedSArchie Cobbs bridge_stats 158beb75cedSArchie Cobbs ;; 159beb75cedSArchie Cobbs stop) 160beb75cedSArchie Cobbs bridge_verify 161beb75cedSArchie Cobbs bridge_stop 162beb75cedSArchie Cobbs ;; 163beb75cedSArchie Cobbs *) 164beb75cedSArchie Cobbs echo "Usage: ether.bridge [ start | stop | stats ]" 165beb75cedSArchie Cobbs exit 1 166beb75cedSArchie Cobbsesac 167beb75cedSArchie Cobbs 168