xref: /freebsd/share/examples/netgraph/virtual.chain (revision d0b2dbfa0ecf2bbc9709efc5e20baf8e4b44bbbf)
1fa212bfbSJulian Elischer#!/bin/sh
2fa212bfbSJulian Elischer#
3fa212bfbSJulian Elischer# Copyright (c) 2010, Yavuz Gokirmak
4fa212bfbSJulian Elischer#
5fa212bfbSJulian Elischer# All rights reserved.
6fa212bfbSJulian Elischer#
7fa212bfbSJulian Elischer# This source code may be used, modified, copied, distributed, and
8fa212bfbSJulian Elischer# sold, in both source and binary form provided that the above
9fa212bfbSJulian Elischer# copyright and these terms are retained, verbatim, as the first
10fa212bfbSJulian Elischer# lines of this file.  Under no circumstances is the author
11fa212bfbSJulian Elischer# responsible for the proper functioning of the software nor does
12fa212bfbSJulian Elischer# the author assume any responsibility for damages incurred with
13fa212bfbSJulian Elischer# its use.
14fa212bfbSJulian Elischer#
15fa212bfbSJulian Elischer#
16fa212bfbSJulian Elischer# This script creates and connects n router like nodes. Complex wide
17fa212bfbSJulian Elischer# area topologies can be created with the help of script.
18fa212bfbSJulian Elischer#
19fa212bfbSJulian Elischer# Virtual nodes are generated via jails and network connections are
20fa212bfbSJulian Elischer# established using ng_eiface(4) node types.
21fa212bfbSJulian Elischer#
22fa212bfbSJulian Elischer# To use this script:
23fa212bfbSJulian Elischer#
24fa212bfbSJulian Elischer# 0. Make your own copy of this example script.
25fa212bfbSJulian Elischer#
26fa212bfbSJulian Elischer# 1. Edit the definition of ${TARGET_TOPOLOGY} to define your virtual
27fa212bfbSJulian Elischer#    nodes. Virtual topology definition includes node names and their
28*5665fe6bSUlrich Spörlein#    IP address. Target top. syntax: ( name|ip<->name|ip ... )
29fa212bfbSJulian Elischer#    Example 1: ( n1|10.0.2.1/30<->n2|10.0.2.2/30 ...)
30fa212bfbSJulian Elischer#    Example 2: ( n1|2001:b90::14a/125<->n1|2001:b90::14b/125 ...)
31fa212bfbSJulian Elischer#
32fa212bfbSJulian Elischer# 2. Run this script with "start" as the command line argument.
33fa212bfbSJulian Elischer#
34fa212bfbSJulian Elischer# 3. Add necessary static route commands for each virtual node. For
35fa212bfbSJulian Elischer#    example assume you have three virtual nodes connected each other
36*5665fe6bSUlrich Spörlein#    like a chain (n1 is connected to n2, n2 is connected to n3).
37*5665fe6bSUlrich Spörlein#    In order to establish connectivity among these virtual nodes,
38fa212bfbSJulian Elischer#    you have to add default routes to node n1 and node n3. Example
39fa212bfbSJulian Elischer#    static route command is:
40fa212bfbSJulian Elischer#      STATIC_ROUTE0="jexec n1 route add -inet default 10.0.2.2"
41fa212bfbSJulian Elischer#      STATIC_ROUTE1="jexec n3 route add -inet default 10.0.2.5"
42fa212bfbSJulian Elischer#    After defining default routes with above format you have to set
43fa212bfbSJulian Elischer#    the total number of static route commands as:
44fa212bfbSJulian Elischer#      STATIC_ROUTE_CNT=2
45fa212bfbSJulian Elischer#
46fa212bfbSJulian Elischer# 4. Stop bridging by running this script with "stop" as the
47fa212bfbSJulian Elischer#    command line argument.
48fa212bfbSJulian Elischer#
49*5665fe6bSUlrich Spörlein# 5. This script uses a template file in order to carry information
50fa212bfbSJulian Elischer#    between start and stop calls.
51fa212bfbSJulian Elischer#      In the start call, the netgraph interfaces and jails are created.
52fa212bfbSJulian Elischer#      At the stop phase, all created objects should be removed.
53fa212bfbSJulian Elischer#    DO NOT delete the temporary file between the start and stop phases.
54fa212bfbSJulian Elischer#
55fa212bfbSJulian Elischer# Target Topology:
56fa212bfbSJulian Elischer#
57fa212bfbSJulian Elischer# +---------------+  +---------------------------------------------+
58fa212bfbSJulian Elischer# |  n1 (vimage)  |  |                 n2 (vimage)                 |
59fa212bfbSJulian Elischer# |               |  |                                             |
60fa212bfbSJulian Elischer# | +-----------+ |  | +-----------+  +-----------+  +-----------+ |
61fa212bfbSJulian Elischer# | |  ngeth0   | |  | |  ngeth1   |  |  ngeth2   |  |  ngeth4   | |
62fa212bfbSJulian Elischer# | |(ng_eiface)| |  | |(ng_eiface)|  |(ng_eiface)|  |(ng_eiface)| |
63fa212bfbSJulian Elischer# | +--+-----+--+ |  | +--+-----+--+  +--+-----+--+  +--+-----+--+ |
64fa212bfbSJulian Elischer# |    |ether|    |  |    |ether|        |ether|        |ether|    |
65fa212bfbSJulian Elischer# |    +-X---+    |  |    +--X--+        +--X--+        +--X--+    |
66fa212bfbSJulian Elischer# +-------X-------+  +------X--------------X---------------X-------+
67fa212bfbSJulian Elischer#         X                X              X                X
68fa212bfbSJulian Elischer#          X               X             X                X
69fa212bfbSJulian Elischer#           XXXXXXXXXXXXXXX            X                  X
70fa212bfbSJulian Elischer#                                    X                    X
71fa212bfbSJulian Elischer#                          +--------X------+     +--------X------+
72fa212bfbSJulian Elischer#                          |   -+--X--+-   |     |   -+--X--+-   |
73fa212bfbSJulian Elischer#                          |    |ether|    |     |    |ether|    |
74fa212bfbSJulian Elischer#                          | +--+-----+--+ |     | +--+-----+--+ |
75fa212bfbSJulian Elischer#                          | |  ngeth3   | |     | |  ngeth5   | |
76fa212bfbSJulian Elischer#                          | |(ng_eiface)| |     | |(ng_eiface)| |
77fa212bfbSJulian Elischer#                          | +-----------+ |     | +-----------+ |
78fa212bfbSJulian Elischer#                          |               |     |               |
79fa212bfbSJulian Elischer#                          |  n3 (vimage)  |     |  n4 (vimage)  |
80fa212bfbSJulian Elischer#                          +---------------+     +---------------+
81fa212bfbSJulian Elischer#
82fa212bfbSJulian Elischer#
83fa212bfbSJulian Elischer#
84fa212bfbSJulian Elischer
85fa212bfbSJulian Elischer# List the names of virtual nodes and their IP addresses. Use ':'
86*5665fe6bSUlrich Spörlein# character to separate node name from node IP address and netmask.
87fa212bfbSJulian Elischer
88fa212bfbSJulian ElischerTARGET_TOPOLOGY="n1|10.0.2.1/30<->n2|10.0.2.2/30 n2|10.0.2.5/30<->n3|10.0.2.6/30 n2|10.0.2.9/30<->n4|10.0.2.10/30"
89fa212bfbSJulian ElischerSTATIC_ROUTE0="jexec n1 route add -inet default 10.0.2.2"
90fa212bfbSJulian ElischerSTATIC_ROUTE1="jexec n3 route add -inet default 10.0.2.5"
91fa212bfbSJulian ElischerSTATIC_ROUTE2="jexec n4 route add -inet default 10.0.2.9"
92fa212bfbSJulian ElischerSTATIC_ROUTE_CNT=3
93fa212bfbSJulian Elischer
94*5665fe6bSUlrich Spörlein# MAC manufacturer prefix. This can be modified according to needs.
95fa212bfbSJulian ElischerMAC_PREFIX="00:1d:92"
96fa212bfbSJulian Elischer
97fa212bfbSJulian Elischer# Temporary file is important for proper execution of script.
98fa212bfbSJulian ElischerTEMP_FILE="/var/tmp/.virtual.chain.tmp"
99fa212bfbSJulian Elischer
100fa212bfbSJulian Elischer# Set root directory for jails to be created.
101fa212bfbSJulian ElischerJAIL_PATH="/usr/jails/router"
102fa212bfbSJulian Elischer
103fa212bfbSJulian Elischer
104fa212bfbSJulian Elischer####################################################################
105fa212bfbSJulian Elischer####    Nothing below this point should need to be modified.    ####
106fa212bfbSJulian Elischer####################################################################
107fa212bfbSJulian Elischer
108fa212bfbSJulian Elischer
109fa212bfbSJulian Elischer# Start/restart routine.
110fa212bfbSJulian Elischervirtual_chain_start() {
111fa212bfbSJulian Elischer
112fa212bfbSJulian Elischer	# Load netgraph KLD's as necessary.
113fa212bfbSJulian Elischer
114fa212bfbSJulian Elischer	for KLD in ng_ether ng_bridge ng_eiface; do
115fa212bfbSJulian Elischer		if ! kldstat -v | grep -qw ${KLD}; then
116fa212bfbSJulian Elischer			echo -n "Loading ${KLD}.ko... "
117fa212bfbSJulian Elischer			kldload ${KLD} || exit 1
118fa212bfbSJulian Elischer			echo "done"
119fa212bfbSJulian Elischer		fi
120fa212bfbSJulian Elischer	done
121fa212bfbSJulian Elischer
122fa212bfbSJulian Elischer	# Reset all interfaces and jails. If temporary file can not be found
123fa212bfbSJulian Elischer	# script assumes that there is no previous configuration.
124fa212bfbSJulian Elischer
125fa212bfbSJulian Elischer	if [ ! -e ${TEMP_FILE} ]; then
126fa212bfbSJulian Elischer		echo "No previous configuration(${TEMP_FILE}) found to clean-up."
127fa212bfbSJulian Elischer	else
128fa212bfbSJulian Elischer		echo -n "Cleaning previous configuration..."
129fa212bfbSJulian Elischer		virtual_chain_stop
130fa212bfbSJulian Elischer		echo "done"
131fa212bfbSJulian Elischer	fi
132fa212bfbSJulian Elischer
133fa212bfbSJulian Elischer	# Create temporary file for usage. This file includes generated
134fa212bfbSJulian Elischer	# interface names and jail names. All bridges, interfaces and jails
135fa212bfbSJulian Elischer	# are written to file while created. In clean-up process written
136*5665fe6bSUlrich Spörlein	# objects are cleaned (i.e. removed) from system.
137fa212bfbSJulian Elischer
138fa212bfbSJulian Elischer	if [ -e ${TEMP_FILE} ]; then
139fa212bfbSJulian Elischer		touch ${TEMP_FILE}
140fa212bfbSJulian Elischer	fi
141fa212bfbSJulian Elischer
142fa212bfbSJulian Elischer
143fa212bfbSJulian Elischer	# Attach other interfaces as well.
144fa212bfbSJulian Elischer	for CONNECTION in ${TARGET_TOPOLOGY}; do
145fa212bfbSJulian Elischer
146fa212bfbSJulian Elischer		# Virtual connections are defined in TARGET_TOPOLOGY variable.
147fa212bfbSJulian Elischer		# They have the form of 'nodeName|IPaddr'. Below two lines split
148fa212bfbSJulian Elischer
149fa212bfbSJulian Elischer		PEER1=`echo ${CONNECTION} | awk -F"<->" '{print $1}'`
150fa212bfbSJulian Elischer		PEER1_NAME=`echo ${PEER1} | awk -F"|" '{print $1}'`
151fa212bfbSJulian Elischer		PEER1_IP=`echo ${PEER1} | awk -F"|" '{print $2}'`
152fa212bfbSJulian Elischer
153fa212bfbSJulian Elischer		PEER2=`echo ${CONNECTION} | awk -F"<->" '{print $2}'`
154fa212bfbSJulian Elischer		PEER2_NAME=`echo ${PEER2} | awk -F"|" '{print $1}'`
155fa212bfbSJulian Elischer		PEER2_IP=`echo ${PEER2} | awk -F"|" '{print $2}'`
156fa212bfbSJulian Elischer
157fa212bfbSJulian Elischer		# !!! if not created already..
158fa212bfbSJulian Elischer		# Create virtual node (jail) with given name and using
159fa212bfbSJulian Elischer		# JAIL_PATH as root directory for jail.
160fa212bfbSJulian Elischer
161fa212bfbSJulian Elischer		virtual_chain_create_peer_if_necessary ${PEER1_NAME}
162fa212bfbSJulian Elischer		virtual_chain_create_peer_if_necessary ${PEER2_NAME}
163fa212bfbSJulian Elischer
164fa212bfbSJulian Elischer		# create an interface for peer with the given peer IP. Get interface
165fa212bfbSJulian Elischer		# for future use; you will connect this interface to the other
166fa212bfbSJulian Elischer		# peers' (PEER2) interface.
167fa212bfbSJulian Elischer		virtual_chain_create_interface_with_ip ${PEER1_NAME} ${PEER1_IP}
168fa212bfbSJulian Elischer		PEER1_INTERFACE=${RET_INTERFACE}
169fa212bfbSJulian Elischer
170fa212bfbSJulian Elischer		# create an interface for peer with the given peer IP. Get interface
171fa212bfbSJulian Elischer		# for future use; you will connect this interface to the other
172fa212bfbSJulian Elischer		# peers' (PEER2) interface.
173fa212bfbSJulian Elischer		virtual_chain_create_interface_with_ip ${PEER2_NAME} ${PEER2_IP}
174fa212bfbSJulian Elischer		PEER2_INTERFACE=${RET_INTERFACE}
175fa212bfbSJulian Elischer
176fa212bfbSJulian Elischer		# Connect virtual interface to other interface. Syntax is :
177fa212bfbSJulian Elischer		# ngctl connect INTERFACE1: INTERFACE2: ether ether.
178fa212bfbSJulian Elischer
179fa212bfbSJulian Elischer		echo -n "Connecting ${PEER1_INTERFACE}:ether to ${PEER2_INTERFACE}:ether..."
180fa212bfbSJulian Elischer		ngctl connect ${PEER1_INTERFACE}: ${PEER2_INTERFACE}: ether ether \
181fa212bfbSJulian Elischer			|| exit 1
182fa212bfbSJulian Elischer		echo "done"
183fa212bfbSJulian Elischer
184fa212bfbSJulian Elischer	done
185fa212bfbSJulian Elischer
186fa212bfbSJulian Elischer	# Executes static route add commands.
187fa212bfbSJulian Elischer	i=0
188fa212bfbSJulian Elischer	while [ $i != $STATIC_ROUTE_CNT ]; do
189fa212bfbSJulian Elischer		eval ROUTE=\${STATIC_ROUTE${i}}
190fa212bfbSJulian Elischer		ret=`${ROUTE}`
191fa212bfbSJulian Elischer		i=`expr $i + 1`
192fa212bfbSJulian Elischer	done
193fa212bfbSJulian Elischer
194*5665fe6bSUlrich Spörlein	echo "Virtual WAN established successfully!"
195fa212bfbSJulian Elischer}
196fa212bfbSJulian Elischer
197fa212bfbSJulian Elischervirtual_chain_create_interface_with_ip() {
198fa212bfbSJulian Elischer
199fa212bfbSJulian Elischer	NODE_NAME=$1
200fa212bfbSJulian Elischer	NODE_IP=$2
201fa212bfbSJulian Elischer
202fa212bfbSJulian Elischer	# Create a ng_eiface object for virtual node. ng_eiface
203fa212bfbSJulian Elischer	# object has a hook that can be connected to one of bridge
204fa212bfbSJulian Elischer	# links. After creating interface get its automatically
205fa212bfbSJulian Elischer	# generated name for further usage.
206fa212bfbSJulian Elischer
207fa212bfbSJulian Elischer	echo "Creating eiface interface for virtual node ${NODE_NAME}."
208fa212bfbSJulian Elischer	ngctl mkpeer eiface ether ether
209fa212bfbSJulian Elischer	EIFACE=`ngctl l | grep ngeth | tail -n 1| awk '{print $2}'`
210fa212bfbSJulian Elischer	echo "Interface ${EIFACE} is created."
211fa212bfbSJulian Elischer
212fa212bfbSJulian Elischer	# Write name of the interface to temp file. Clean-up procedure
213fa212bfbSJulian Elischer	# will use this name to shutdown interface.
214fa212bfbSJulian Elischer
215fa212bfbSJulian Elischer	echo "interface ${EIFACE}" >> ${TEMP_FILE}
216fa212bfbSJulian Elischer
217fa212bfbSJulian Elischer	# Move virtual interface to virtual node. Note that Interface
218fa212bfbSJulian Elischer	# name will not be changed at the end of this movement. Moved
219fa212bfbSJulian Elischer	# interface can be seen at the output of ifconfig command in
220fa212bfbSJulian Elischer	# jail: 'jexec jailname ifconfig'
221fa212bfbSJulian Elischer
222fa212bfbSJulian Elischer	echo "Moving ${EIFACE} to ${NODE_NAME}"
223fa212bfbSJulian Elischer	ifconfig ${EIFACE} vnet ${NODE_NAME}
224fa212bfbSJulian Elischer
225fa212bfbSJulian Elischer	# Make lo0 interface localhost.
226fa212bfbSJulian Elischer	jexec ${NODE_NAME} ifconfig lo0 localhost
227fa212bfbSJulian Elischer
228fa212bfbSJulian Elischer	# Generate a random mac address for virtual interface. First
229fa212bfbSJulian Elischer	# three octets can be changed by user. Last three octets are
230fa212bfbSJulian Elischer	# generated randomly.
231fa212bfbSJulian Elischer	M4=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \
232fa212bfbSJulian Elischer			awk '{ print $1 % 256 }'`
233fa212bfbSJulian Elischer	M5=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \
234fa212bfbSJulian Elischer			awk '{ print $1 % 256 }'`
235fa212bfbSJulian Elischer	M6=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \
236fa212bfbSJulian Elischer			awk '{ print $1 % 256 }'`
237fa212bfbSJulian Elischer
238fa212bfbSJulian Elischer	MAC=`printf ${MAC_PREFIX}:%02x:%02x:%02x ${M4} ${M5} ${M6}`
239fa212bfbSJulian Elischer
240fa212bfbSJulian Elischer	# Set the link address (mac address) of virtual interface in
241fa212bfbSJulian Elischer	# virtual node to randomly generated MAC.
242fa212bfbSJulian Elischer	echo "Setting MAC address of ${EIFACE} to '${MAC}'"
243fa212bfbSJulian Elischer	jexec ${NODE_NAME} ifconfig ${EIFACE} link $MAC
244fa212bfbSJulian Elischer
245fa212bfbSJulian Elischer	# Either IPv4 or IPv6 can be used in this script. Ifconfig
246fa212bfbSJulian Elischer	# IP setting syntax differs slightly for two IP versions.
247fa212bfbSJulian Elischer	# For version 4 'inet' keyword is used whereas for version 6
248fa212bfbSJulian Elischer	# 'inet6' is used. Below line tries to decide which IP version
249fa212bfbSJulian Elischer	# is given and sets IPVER to 'inet' or 'inet6'.
250fa212bfbSJulian Elischer
251fa212bfbSJulian Elischer	IPVER=`echo ${NODE_IP} | awk -F"." '{ split($4,last,"/"); \
252fa212bfbSJulian Elischer		if( NF==4 && $1>0 && $1<256 && $2<256 && $3<256 && \
253fa212bfbSJulian Elischer		last[1]<256) print "inet"; else print "inet6"}'`
254fa212bfbSJulian Elischer
255fa212bfbSJulian Elischer	# Set IP address of virtual interface in virtual node.
256fa212bfbSJulian Elischer	echo "Setting IP address of ${EIFACE} to '${NODE_IP}'"
257fa212bfbSJulian Elischer	jexec ${NODE_NAME} ifconfig ${EIFACE} ${IPVER} ${NODE_IP}
258fa212bfbSJulian Elischer
259fa212bfbSJulian Elischer	RET_INTERFACE=${EIFACE}
260fa212bfbSJulian Elischer}
261fa212bfbSJulian Elischer
262fa212bfbSJulian Elischervirtual_chain_create_peer_if_necessary() {
263fa212bfbSJulian Elischer
264fa212bfbSJulian Elischer	if ! grep -q $1 ${TEMP_FILE} ; then
265fa212bfbSJulian Elischer
266fa212bfbSJulian Elischer		echo -n "Creating virtual node (jail) ${1}..."
267fa212bfbSJulian Elischer		jail -c vnet name=${1} host.hostname=${1} \
268fa212bfbSJulian Elischer			path=${JAIL_PATH} persist
269fa212bfbSJulian Elischer		jexec ${1} sysctl -w net.inet.ip.forwarding=1
270fa212bfbSJulian Elischer		jexec ${1} sysctl -w net.inet6.ip6.forwarding=1
271fa212bfbSJulian Elischer		echo "done"
272fa212bfbSJulian Elischer
273fa212bfbSJulian Elischer		# Write name of the jail to temp file. Clean-up
274fa212bfbSJulian Elischer		# procedure will use this name to remove jail.
275fa212bfbSJulian Elischer
276fa212bfbSJulian Elischer		echo "node ${1}" >> ${TEMP_FILE}
277fa212bfbSJulian Elischer	fi
278fa212bfbSJulian Elischer
279fa212bfbSJulian Elischer}
280fa212bfbSJulian Elischer
281fa212bfbSJulian Elischer# Stop routine.
282fa212bfbSJulian Elischervirtual_chain_stop() {
283fa212bfbSJulian Elischer
284fa212bfbSJulian Elischer	if [ ! -e ${TEMP_FILE} ]; then
285fa212bfbSJulian Elischer		echo "Nothing to stop! ${TEMP_FILE}: temp file not found"
286fa212bfbSJulian Elischer	else
287fa212bfbSJulian Elischer
288fa212bfbSJulian Elischer		echo -n "Shutdown bridge interface.."
289fa212bfbSJulian Elischer		OBJECTS=`cat ${TEMP_FILE} | grep bridge | awk '{print $2}'`
290fa212bfbSJulian Elischer		for BRIDGE in ${OBJECTS}; do
291fa212bfbSJulian Elischer			ngctl shutdown ${BRIDGE}: >/dev/null 2>&1
292fa212bfbSJulian Elischer		done
293fa212bfbSJulian Elischer		echo "done"
294fa212bfbSJulian Elischer
295fa212bfbSJulian Elischer		echo -n "Shutdown all eiface interfaces..."
296fa212bfbSJulian Elischer		OBJECTS=`cat ${TEMP_FILE} | grep interface | awk '{print $2}'`
297fa212bfbSJulian Elischer		for INTERFACE in ${OBJECTS}; do
298fa212bfbSJulian Elischer			ngctl shutdown ${INTERFACE}: >/dev/null 2>&1
299fa212bfbSJulian Elischer		done
300fa212bfbSJulian Elischer		echo "done"
301fa212bfbSJulian Elischer
302fa212bfbSJulian Elischer		echo -n "Removing all jails..."
303fa212bfbSJulian Elischer		OBJECTS=`cat ${TEMP_FILE} | grep node | awk '{print $2}'`
304fa212bfbSJulian Elischer		for NODE in ${OBJECTS}; do
305fa212bfbSJulian Elischer			jail -r ${NODE}
306fa212bfbSJulian Elischer		done
307fa212bfbSJulian Elischer		echo "done"
308fa212bfbSJulian Elischer
309fa212bfbSJulian Elischer		echo "Removing tempfile ${TEMP_FILE}"
310fa212bfbSJulian Elischer		rm ${TEMP_FILE}
311fa212bfbSJulian Elischer	fi
312*5665fe6bSUlrich Spörlein	echo "Virtual LAN objects removed successfully!"
313fa212bfbSJulian Elischer
314fa212bfbSJulian Elischer}
315fa212bfbSJulian Elischer
316fa212bfbSJulian Elischervirtual_chain_usage() {
317fa212bfbSJulian Elischer	echo "usage: $0 start [target_topology]"
318fa212bfbSJulian Elischer	echo "     : $0 [ stop | help ]"
319fa212bfbSJulian Elischer}
320fa212bfbSJulian Elischer
321fa212bfbSJulian Elischer
322fa212bfbSJulian Elischer# Main entry point.
323fa212bfbSJulian Elischer
324fa212bfbSJulian Elischercase $# in
325fa212bfbSJulian Elischer	1)
326fa212bfbSJulian Elischer		case $1 in
327fa212bfbSJulian Elischer                        start)
328fa212bfbSJulian Elischer                                echo -n "Creating default target topology:"
329fa212bfbSJulian Elischer				echo " ${TARGET_TOPOLOGY}"
330fa212bfbSJulian Elischer                                virtual_chain_start
331fa212bfbSJulian Elischer                                ;;
332fa212bfbSJulian Elischer                        stop)
333fa212bfbSJulian Elischer
334fa212bfbSJulian Elischer				if [ ! -e ${TEMP_FILE} ]; then
335fa212bfbSJulian Elischer					echo -n "Noting to stop! ${TEMP_FILE}:"
336fa212bfbSJulian Elischer					echo " temp file not found"
337fa212bfbSJulian Elischer				else
338fa212bfbSJulian Elischer					virtual_chain_stop
339fa212bfbSJulian Elischer				fi
340fa212bfbSJulian Elischer                                ;;
341fa212bfbSJulian Elischer                        help)
342fa212bfbSJulian Elischer                                virtual_chain_usage
343fa212bfbSJulian Elischer				exit 1
344fa212bfbSJulian Elischer                                ;;
345fa212bfbSJulian Elischer                        *)
346fa212bfbSJulian Elischer                                virtual_chain_usage
347fa212bfbSJulian Elischer                                exit 1
348fa212bfbSJulian Elischer
349fa212bfbSJulian Elischer                esac
350fa212bfbSJulian Elischer		;;
351fa212bfbSJulian Elischer	2)
352fa212bfbSJulian Elischer	        case $1 in
353fa212bfbSJulian Elischer			start)
354fa212bfbSJulian Elischer                        	TARGET_TOPOLOGY=$2
355fa212bfbSJulian Elischer                                echo -n "Creating target topology:"
356fa212bfbSJulian Elischer				echo "${TARGET_TOPOLOGY}"
357fa212bfbSJulian Elischer                                virtual_chain_start
358fa212bfbSJulian Elischer                                ;;
359fa212bfbSJulian Elischer                        *)
360fa212bfbSJulian Elischer                        	virtual_chain_usage
361fa212bfbSJulian Elischer                                exit 1
362fa212bfbSJulian Elischer                esac
363fa212bfbSJulian Elischer		;;
364fa212bfbSJulian Elischer
365fa212bfbSJulian Elischer	*)
366fa212bfbSJulian Elischer                virtual_chain_usage
367fa212bfbSJulian Elischer                exit 1
368fa212bfbSJulian Elischeresac
369fa212bfbSJulian Elischer
370