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