xref: /freebsd/share/examples/netgraph/ether.bridge (revision d56448b35d053f79d08475013ecea58187c50732)
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#
9d56448b3SJens Schweikhardt# 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.
30d56448b3SJens Schweikhardt# If you just want a normal bridge, just one will be enough.
31d56448b3SJens Schweikhardt# In some cases you may want some combination.
3244f9a046SJulian Elischer#
33beb75cedSArchie Cobbs
34d56448b3SJens Schweikhardt# 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}
43d56448b3SJens Schweikhardt# then assign it the emtpy string.
44beb75cedSArchie Cobbs
4544f9a046SJulian ElischerBRIDGE_IFACES="de0 fxp0 fxp1"
4644f9a046SJulian ElischerLOCAL_IFACES="fxp0 fxp1"
47beb75cedSArchie Cobbs
48d56448b3SJens Schweikhardt#####################################################################
49d56448b3SJens Schweikhardt#### Everything below this point should not need to be modified. ####
50d56448b3SJens Schweikhardt#####################################################################
51beb75cedSArchie Cobbs
52d56448b3SJens Schweikhardt# 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
61d56448b3SJens Schweikhardt# 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
71d56448b3SJens Schweikhardt# Start/restart routine.
72beb75cedSArchie Cobbsbridge_start() {
73beb75cedSArchie Cobbs
74d56448b3SJens Schweikhardt	# Load netgraph KLD's as necessary.
75beb75cedSArchie Cobbs	for KLD in ng_ether ng_bridge; do
76d56448b3SJens Schweikhardt		if ! kldstat -v | grep -qw ${KLD}; then
77beb75cedSArchie Cobbs			echo -n "Loading ${KLD}.ko... "
78beb75cedSArchie Cobbs			kldload ${KLD} || exit 1
79beb75cedSArchie Cobbs			echo "done"
80beb75cedSArchie Cobbs		fi
81beb75cedSArchie Cobbs	done
82beb75cedSArchie Cobbs
83d56448b3SJens Schweikhardt	# Reset all interfaces.
84beb75cedSArchie Cobbs	bridge_stop
85beb75cedSArchie Cobbs
86d56448b3SJens Schweikhardt	# Verify all interfaces exist.
8744f9a046SJulian Elischer	for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do
88d56448b3SJens Schweikhardt		if ! ngctl info ${ETHER}: >/dev/null 2>&1; then
89beb75cedSArchie Cobbs			echo "Error: interface ${ETHER} does not exist"
90beb75cedSArchie Cobbs			exit 1
91beb75cedSArchie Cobbs		fi
92beb75cedSArchie Cobbs		ifconfig ${ETHER} up || exit 1
93beb75cedSArchie Cobbs	done
94beb75cedSArchie Cobbs
95d56448b3SJens Schweikhardt	# Create new ng_bridge(4) node, attached to the first interface.
96beb75cedSArchie Cobbs	FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'`
97beb75cedSArchie Cobbs	ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1
98beb75cedSArchie Cobbs	ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1
99beb75cedSArchie Cobbs
100d56448b3SJens Schweikhardt	# Attach other interfaces as well.
101beb75cedSArchie Cobbs	LINKNUM=0
102beb75cedSArchie Cobbs	for ETHER in ${BRIDGE_IFACES}; do
103beb75cedSArchie Cobbs		if [ ${LINKNUM} != 0 ]; then
104beb75cedSArchie Cobbs			ngctl connect ${ETHER}: ${BRIDGE_NAME}: \
105beb75cedSArchie Cobbs			    lower link${LINKNUM} || exit 1
106beb75cedSArchie Cobbs		fi
107beb75cedSArchie Cobbs		LINKNUM=`expr ${LINKNUM} + 1`
108beb75cedSArchie Cobbs	done
109beb75cedSArchie Cobbs
110d56448b3SJens Schweikhardt	# Hook up local interface, if any.
11144f9a046SJulian Elischer	for LOCAL_IFACE in ${LOCAL_IFACES}; do
112beb75cedSArchie Cobbs		ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \
113beb75cedSArchie Cobbs		    upper link${LINKNUM} || exit 1
11444f9a046SJulian Elischer		LINKNUM=`expr ${LINKNUM} + 1`
11544f9a046SJulian Elischer	done
116beb75cedSArchie Cobbs
117d56448b3SJens Schweikhardt	# Set all interfaces in promiscuous mode and don't overwrite src addr.
118beb75cedSArchie Cobbs	for ETHER in ${BRIDGE_IFACES}; do
119beb75cedSArchie Cobbs		ngctl msg ${ETHER}: setpromisc 1 || exit 1
120beb75cedSArchie Cobbs		ngctl msg ${ETHER}: setautosrc 0 || exit 1
121beb75cedSArchie Cobbs	done
122beb75cedSArchie Cobbs}
123beb75cedSArchie Cobbs
124d56448b3SJens Schweikhardt# Stop routine.
125beb75cedSArchie Cobbsbridge_stop() {
126beb75cedSArchie Cobbs	ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1
12744f9a046SJulian Elischer	for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACES}; do
128beb75cedSArchie Cobbs		ngctl kill ${ETHER}: >/dev/null 2>&1
129beb75cedSArchie Cobbs	done
130beb75cedSArchie Cobbs}
131beb75cedSArchie Cobbs
132d56448b3SJens Schweikhardt# Stats routine.
133beb75cedSArchie Cobbsbridge_stats() {
134beb75cedSArchie Cobbs
135d56448b3SJens Schweikhardt	# Make sure node exists.
136beb75cedSArchie Cobbs	bridge_verify
137beb75cedSArchie Cobbs
138beb75cedSArchie Cobbs	echo ""
139beb75cedSArchie Cobbs	echo "Statistics for bridging network ${BRIDGE_NAME}:"
140beb75cedSArchie Cobbs	echo ""
141beb75cedSArchie Cobbs	LINKNUM=0
142beb75cedSArchie Cobbs	for ETHER in ${BRIDGE_IFACES}; do
143beb75cedSArchie Cobbs		echo "Network interface ${ETHER}:"
144beb75cedSArchie Cobbs		bridge_linkstats ${LINKNUM}
145beb75cedSArchie Cobbs		LINKNUM=`expr ${LINKNUM} + 1`
146beb75cedSArchie Cobbs	done
14744f9a046SJulian Elischer	for LOCAL_IFACE in ${LOCAL_IFACES}; do
148232edd1cSDima Dorfman		echo "Local host interface ${LOCAL_IFACE}:"
149beb75cedSArchie Cobbs		bridge_linkstats ${LINKNUM}
15044f9a046SJulian Elischer		LINKNUM=`expr ${LINKNUM} + 1`
15144f9a046SJulian Elischer	done
152beb75cedSArchie Cobbs}
153beb75cedSArchie Cobbs
154d56448b3SJens Schweikhardt# Main entry point.
155beb75cedSArchie Cobbscase $1 in
156beb75cedSArchie Cobbs	start)
157beb75cedSArchie Cobbs		bridge_start
158beb75cedSArchie Cobbs		;;
159beb75cedSArchie Cobbs	stats)
160beb75cedSArchie Cobbs		bridge_verify
161beb75cedSArchie Cobbs		bridge_stats
162beb75cedSArchie Cobbs		;;
163beb75cedSArchie Cobbs	stop)
164beb75cedSArchie Cobbs		bridge_verify
165beb75cedSArchie Cobbs		bridge_stop
166beb75cedSArchie Cobbs		;;
167beb75cedSArchie Cobbs	*)
168d56448b3SJens Schweikhardt		echo "usage: $0 [ start | stop | stats ]"
169beb75cedSArchie Cobbs		exit 1
170beb75cedSArchie Cobbsesac
171