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