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