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