186d7f5d3SJohn Marino#!/bin/sh 286d7f5d3SJohn Marino# $FreeBSD: src/share/examples/netgraph/ether.bridge,v 1.1.2.2 2001/07/19 05:45:03 dd Exp $ 386d7f5d3SJohn Marino# $DragonFly: src/share/examples/netgraph/ether.bridge,v 1.2 2003/06/17 04:36:57 dillon Exp $ 486d7f5d3SJohn Marino 586d7f5d3SJohn Marino# This script sets up an Ethernet bridging network across multiple 686d7f5d3SJohn Marino# Ethernet interfaces using the ng_bridge(4) and ng_ether(4) netgraph 786d7f5d3SJohn Marino# node types. 886d7f5d3SJohn Marino# 986d7f5d3SJohn Marino# To use this script: 1086d7f5d3SJohn Marino# 1186d7f5d3SJohn Marino# 0. Make your own copy of this example script 1286d7f5d3SJohn Marino# 1386d7f5d3SJohn Marino# 1. Give your bridging network a name by editing the definition of 1486d7f5d3SJohn Marino# ${BRIDGE_NAME} below. It must be a valid netgraph node name. 1586d7f5d3SJohn Marino# 1686d7f5d3SJohn Marino# 2. Edit the definitions of ${BRIDGE_IFACES} and ${LOCAL_IFACE} 1786d7f5d3SJohn Marino# as described below to define your bridging interfaces. 1886d7f5d3SJohn Marino# 1986d7f5d3SJohn Marino# 3. Run this script with "start" as the command line argument. 2086d7f5d3SJohn Marino# 2186d7f5d3SJohn Marino# 4. Examine bridging statistics by running this script with "stats" 2286d7f5d3SJohn Marino# as the command line argument. 2386d7f5d3SJohn Marino# 2486d7f5d3SJohn Marino# 5. Stop bridging by running this script with "stop" as the 2586d7f5d3SJohn Marino# command line argument. 2686d7f5d3SJohn Marino# 2786d7f5d3SJohn Marino# To run multiple independent bridging networks, create multiple 2886d7f5d3SJohn Marino# copies of this script with different variable definitions. 2986d7f5d3SJohn Marino# 3086d7f5d3SJohn Marino 3186d7f5d3SJohn Marino# Give each bridging network a unique name here 3286d7f5d3SJohn Marino 3386d7f5d3SJohn MarinoBRIDGE_NAME="bnet0" 3486d7f5d3SJohn Marino 3586d7f5d3SJohn Marino# List the names of the interfaces that you want to bridge across 3686d7f5d3SJohn Marino# here in ${BRIDGE_IFACES}. If you want to include the local host 3786d7f5d3SJohn Marino# machine as well then set ${LOCAL_IFACE} as well (it may also be 3886d7f5d3SJohn Marino# listed in ${BRIDGE_IFACES}). Of course, any ${LOCAL_IFACE} must 3986d7f5d3SJohn Marino# be ifconfig(8)ured separately. If you don't want a ${LOCAL_IFACE} 4086d7f5d3SJohn Marino# then leave it defined as the emtpy string. 4186d7f5d3SJohn Marino 4286d7f5d3SJohn MarinoBRIDGE_IFACES="ed0 fxp0 fxp1" 4386d7f5d3SJohn MarinoLOCAL_IFACE="fxp0" 4486d7f5d3SJohn Marino 4586d7f5d3SJohn Marino#################################################################### 4686d7f5d3SJohn Marino#### Everything below this point should not need to be modified #### 4786d7f5d3SJohn Marino#################################################################### 4886d7f5d3SJohn Marino 4986d7f5d3SJohn Marino# Routine to verify node's existence 5086d7f5d3SJohn Marinobridge_verify() { 5186d7f5d3SJohn Marino ngctl info ${BRIDGE_NAME}: >/dev/null 2>&1 5286d7f5d3SJohn Marino if [ $? -ne 0 ]; then 5386d7f5d3SJohn Marino echo "${BRIDGE_NAME}: bridge network not found" 5486d7f5d3SJohn Marino exit 1 5586d7f5d3SJohn Marino fi 5686d7f5d3SJohn Marino} 5786d7f5d3SJohn Marino 5886d7f5d3SJohn Marino# Routine to get and display link stats 5986d7f5d3SJohn Marinobridge_linkstats() { 6086d7f5d3SJohn Marino STATS=`ngctl msg ${BRIDGE_NAME}: getstats $1` 6186d7f5d3SJohn Marino if [ $? -ne 0 ]; then 6286d7f5d3SJohn Marino exit 1 6386d7f5d3SJohn Marino fi 6486d7f5d3SJohn Marino echo "${STATS}" | fmt 2 | awk '/=/ { fl=index($0, "="); \ 6586d7f5d3SJohn Marino printf "%20s = %s\n", substr($0, 0, fl - 1), substr($0, fl + 1); }' 6686d7f5d3SJohn Marino} 6786d7f5d3SJohn Marino 6886d7f5d3SJohn Marino# Start/restart routine 6986d7f5d3SJohn Marinobridge_start() { 7086d7f5d3SJohn Marino 7186d7f5d3SJohn Marino # Load netgraph KLD's as necessary 7286d7f5d3SJohn Marino for KLD in ng_ether ng_bridge; do 7386d7f5d3SJohn Marino if kldstat -v | grep -qw ${KLD}; then 7486d7f5d3SJohn Marino else 7586d7f5d3SJohn Marino echo -n "Loading ${KLD}.ko... " 7686d7f5d3SJohn Marino kldload ${KLD} || exit 1 7786d7f5d3SJohn Marino echo "done" 7886d7f5d3SJohn Marino fi 7986d7f5d3SJohn Marino done 8086d7f5d3SJohn Marino 8186d7f5d3SJohn Marino # Reset all interfaces 8286d7f5d3SJohn Marino bridge_stop 8386d7f5d3SJohn Marino 8486d7f5d3SJohn Marino # Verify all interfaces exist 8586d7f5d3SJohn Marino for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do 8686d7f5d3SJohn Marino if ngctl info ${ETHER}: >/dev/null 2>&1; then 8786d7f5d3SJohn Marino else 8886d7f5d3SJohn Marino echo "Error: interface ${ETHER} does not exist" 8986d7f5d3SJohn Marino exit 1 9086d7f5d3SJohn Marino fi 9186d7f5d3SJohn Marino ifconfig ${ETHER} up || exit 1 9286d7f5d3SJohn Marino done 9386d7f5d3SJohn Marino 9486d7f5d3SJohn Marino # Create new ng_bridge(4) node, attached to the first interface 9586d7f5d3SJohn Marino FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'` 9686d7f5d3SJohn Marino ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1 9786d7f5d3SJohn Marino ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1 9886d7f5d3SJohn Marino 9986d7f5d3SJohn Marino # Attach other interfaces as well 10086d7f5d3SJohn Marino LINKNUM=0 10186d7f5d3SJohn Marino for ETHER in ${BRIDGE_IFACES}; do 10286d7f5d3SJohn Marino if [ ${LINKNUM} != 0 ]; then 10386d7f5d3SJohn Marino ngctl connect ${ETHER}: ${BRIDGE_NAME}: \ 10486d7f5d3SJohn Marino lower link${LINKNUM} || exit 1 10586d7f5d3SJohn Marino fi 10686d7f5d3SJohn Marino LINKNUM=`expr ${LINKNUM} + 1` 10786d7f5d3SJohn Marino done 10886d7f5d3SJohn Marino 10986d7f5d3SJohn Marino # Hook up local interface, if any 11086d7f5d3SJohn Marino if [ "${LOCAL_IFACE}" != "" ]; then 11186d7f5d3SJohn Marino ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \ 11286d7f5d3SJohn Marino upper link${LINKNUM} || exit 1 11386d7f5d3SJohn Marino fi 11486d7f5d3SJohn Marino 11586d7f5d3SJohn Marino # Set all interfaces in promiscuous mode and don't overwrite src addr 11686d7f5d3SJohn Marino for ETHER in ${BRIDGE_IFACES}; do 11786d7f5d3SJohn Marino ngctl msg ${ETHER}: setpromisc 1 || exit 1 11886d7f5d3SJohn Marino ngctl msg ${ETHER}: setautosrc 0 || exit 1 11986d7f5d3SJohn Marino done 12086d7f5d3SJohn Marino} 12186d7f5d3SJohn Marino 12286d7f5d3SJohn Marino# Stop routine 12386d7f5d3SJohn Marinobridge_stop() { 12486d7f5d3SJohn Marino ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1 12586d7f5d3SJohn Marino for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do 12686d7f5d3SJohn Marino ngctl kill ${ETHER}: >/dev/null 2>&1 12786d7f5d3SJohn Marino done 12886d7f5d3SJohn Marino} 12986d7f5d3SJohn Marino 13086d7f5d3SJohn Marino# Stats routine 13186d7f5d3SJohn Marinobridge_stats() { 13286d7f5d3SJohn Marino 13386d7f5d3SJohn Marino # Make sure node exists 13486d7f5d3SJohn Marino bridge_verify 13586d7f5d3SJohn Marino 13686d7f5d3SJohn Marino echo "" 13786d7f5d3SJohn Marino echo "Statistics for bridging network ${BRIDGE_NAME}:" 13886d7f5d3SJohn Marino echo "" 13986d7f5d3SJohn Marino LINKNUM=0 14086d7f5d3SJohn Marino for ETHER in ${BRIDGE_IFACES}; do 14186d7f5d3SJohn Marino echo "Network interface ${ETHER}:" 14286d7f5d3SJohn Marino bridge_linkstats ${LINKNUM} 14386d7f5d3SJohn Marino LINKNUM=`expr ${LINKNUM} + 1` 14486d7f5d3SJohn Marino done 14586d7f5d3SJohn Marino if [ "${LOCAL_IFACE}" != "" ]; then 14686d7f5d3SJohn Marino echo "Local host interface ${LOCAL_IFACE}:" 14786d7f5d3SJohn Marino bridge_linkstats ${LINKNUM} 14886d7f5d3SJohn Marino fi 14986d7f5d3SJohn Marino} 15086d7f5d3SJohn Marino 15186d7f5d3SJohn Marino# Main entry point 15286d7f5d3SJohn Marinocase $1 in 15386d7f5d3SJohn Marino start) 15486d7f5d3SJohn Marino bridge_start 15586d7f5d3SJohn Marino ;; 15686d7f5d3SJohn Marino stats) 15786d7f5d3SJohn Marino bridge_verify 15886d7f5d3SJohn Marino bridge_stats 15986d7f5d3SJohn Marino ;; 16086d7f5d3SJohn Marino stop) 16186d7f5d3SJohn Marino bridge_verify 16286d7f5d3SJohn Marino bridge_stop 16386d7f5d3SJohn Marino ;; 16486d7f5d3SJohn Marino *) 16586d7f5d3SJohn Marino echo "Usage: ether.bridge [ start | stop | stats ]" 16686d7f5d3SJohn Marino exit 1 16786d7f5d3SJohn Marinoesac 16886d7f5d3SJohn Marino 169