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