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 adds virtual nodes to one of the physical interfaces 17fa212bfbSJulian Elischer# visible on your local area network (LAN). Virtual nodes seems real 18fa212bfbSJulian Elischer# to external observers. 19fa212bfbSJulian Elischer# If traceroute is executed to one of virtual nodes, the IP 20fa212bfbSJulian Elischer# address of the physical interface will not be seen in the output. 21fa212bfbSJulian Elischer# Virtual nodes are generated via jails and network connections are 22fa212bfbSJulian Elischer# established using ng_bridge(4) and ng_eiface(4) node types. 23fa212bfbSJulian Elischer# 24fa212bfbSJulian Elischer# To use this script: 25fa212bfbSJulian Elischer# 26fa212bfbSJulian Elischer# 0. Make your own copy of this example script. 27fa212bfbSJulian Elischer# 28fa212bfbSJulian Elischer# 1. Edit the definition of ${ETHER_INTF} as described below 29fa212bfbSJulian Elischer# to define your real interface connected to the LAN. Virtual nodes 30fa212bfbSJulian Elischer# will placed on the same physical network as this interface. 31fa212bfbSJulian Elischer# 32fa212bfbSJulian Elischer# 2. Edit the definition of ${TARGET_TOPOLOGY} to define your virtual 33fa212bfbSJulian Elischer# nodes. Virtual topology definition includes node names and their 34*5665fe6bSUlrich Spörlein# IP address. Target top. syntax: ( node1|ip1/24 node2|ip2/24 ... ) 35fa212bfbSJulian Elischer# Example 1: ( n1|122.122.122.12/24, n2|122.122.122.13/24 ...) 36fa212bfbSJulian Elischer# Example 2: ( n1|2001:b90::14a/125, n1|2001:b90::14b/125 ...) 37fa212bfbSJulian Elischer# 38fa212bfbSJulian Elischer# 3. Run this script with "start" as the command line argument. 39fa212bfbSJulian Elischer# 40fa212bfbSJulian Elischer# 4. Stop bridging by running this script with "stop" as the 41fa212bfbSJulian Elischer# command line argument. 42fa212bfbSJulian Elischer# 43*5665fe6bSUlrich Spörlein# 5. This script uses a template file in order to carry information 44fa212bfbSJulian Elischer# between start and stop calls. 45fa212bfbSJulian Elischer# In the start call, the netgraph interfaces and jails are created. 46fa212bfbSJulian Elischer# At the stop phase, all created objects should be removed. 47fa212bfbSJulian Elischer# DO NOT delete the temporary file between the start and stop phases. 48fa212bfbSJulian Elischer# 49fa212bfbSJulian Elischer# To add virtual nodes for multiple independent LANs, create multiple 50fa212bfbSJulian Elischer# copies of this script with different variable definitions. 51fa212bfbSJulian Elischer# 52fa212bfbSJulian Elischer# Target Topology: 53fa212bfbSJulian Elischer# 54fa212bfbSJulian Elischer# 55fa212bfbSJulian Elischer# +---------------+ +---------------+ +---------------+ 56fa212bfbSJulian Elischer# | n0 (vimage) | | n1 (vimage) | | nk (vimage) | 57fa212bfbSJulian Elischer# | | | | | | 58fa212bfbSJulian Elischer# | +-----------+ | | +-----------+ | | +-----------+ | 59fa212bfbSJulian Elischer# | | ngeth0 | | | | ngeth1 | | | | ngethk | | 60fa212bfbSJulian Elischer# | |(ng_eiface)| | | |(ng_eiface)| | | |(ng_eiface)| | 61fa212bfbSJulian Elischer# | +--+-----+--+ | | +--+-----+--+ | | +--+-----+--+ | 62fa212bfbSJulian Elischer# | |ether| | | |ether| | | |ether| | 63fa212bfbSJulian Elischer# | +--X--+ | | +--X--+ | | +---X-+ | 64fa212bfbSJulian Elischer# +-----+ +--------\------+ +--------\------+ +-------/-------+ 65fa212bfbSJulian Elischer# |upper|----\ \ip_addr \ip_addr /ip_addr 66fa212bfbSJulian Elischer# +-+-----+--+ \ \ \ \ 67fa212bfbSJulian Elischer# | em0 | \ +--------+ +-+ \ 68fa212bfbSJulian Elischer# |(ng_ether)| +-----------+ \ \ \ 69fa212bfbSJulian Elischer# +-+-----+--+ \ \ / \ 70fa212bfbSJulian Elischer# |lower| +---------\ \ \ / / 71fa212bfbSJulian Elischer# +--X--+ / O--X--O O-X---O O---X-O O--X--O O---X---O 72fa212bfbSJulian Elischer# \ | |link0| |link1| |link2| |link3| |linkk+2| 73fa212bfbSJulian Elischer# \ / +-O-----O-O-----O-O-----O-O-----O-----O-------O-+ 74fa212bfbSJulian Elischer# +---+ | | 75fa212bfbSJulian Elischer# | bridge (ng_bridge) | 76fa212bfbSJulian Elischer# +-----------------------------------------------+ 77fa212bfbSJulian Elischer# 78fa212bfbSJulian Elischer# 79fa212bfbSJulian Elischer 80fa212bfbSJulian Elischer# Give the name of ethernet interface. Virtual nodes will be seen as 81fa212bfbSJulian Elischer# local neighbours of this interface. 82fa212bfbSJulian Elischer 83fa212bfbSJulian ElischerETHER_INTF="em0" 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="c1|10.0.2.20/24 c2|10.0.2.21/24 c3|10.0.2.22/24" 89fa212bfbSJulian Elischer 90*5665fe6bSUlrich Spörlein# MAC manufacturer prefix. This can be modified according to needs. 91fa212bfbSJulian ElischerMAC_PREFIX="00:1d:92" 92fa212bfbSJulian Elischer 93fa212bfbSJulian Elischer# Temporary file is important for proper execution of script. 94fa212bfbSJulian ElischerTEMP_FILE="/var/tmp/.virtual.lan.tmp" 95fa212bfbSJulian Elischer 96fa212bfbSJulian Elischer# Set root directory for jails to be created. 97fa212bfbSJulian ElischerJAIL_PATH="/usr/jails/node" 98fa212bfbSJulian Elischer 99fa212bfbSJulian Elischer 100fa212bfbSJulian Elischer#################################################################### 101fa212bfbSJulian Elischer#### Nothing below this point should need to be modified. #### 102fa212bfbSJulian Elischer#################################################################### 103fa212bfbSJulian Elischer 104fa212bfbSJulian Elischer 105fa212bfbSJulian Elischer# Start/restart routine. 106fa212bfbSJulian Elischervirtual_lan_start() { 107fa212bfbSJulian Elischer 108fa212bfbSJulian Elischer # Load netgraph KLD's as necessary. 109fa212bfbSJulian Elischer 110fa212bfbSJulian Elischer for KLD in ng_ether ng_bridge ng_eiface; do 111fa212bfbSJulian Elischer if ! kldstat -v | grep -qw ${KLD}; then 112fa212bfbSJulian Elischer echo -n "Loading ${KLD}.ko... " 113fa212bfbSJulian Elischer kldload ${KLD} || exit 1 114fa212bfbSJulian Elischer echo "done" 115fa212bfbSJulian Elischer fi 116fa212bfbSJulian Elischer done 117fa212bfbSJulian Elischer 118fa212bfbSJulian Elischer # Reset all interfaces and jails. If temporary file can not be found 119fa212bfbSJulian Elischer # script assumes that there is no previous configuration. 120fa212bfbSJulian Elischer 121fa212bfbSJulian Elischer if [ ! -e ${TEMP_FILE} ]; then 122fa212bfbSJulian Elischer echo "No previous configuration(${TEMP_FILE}) found to clean-up." 123fa212bfbSJulian Elischer else 124fa212bfbSJulian Elischer echo -n "Cleaning previous configuration..." 125fa212bfbSJulian Elischer virtual_lan_stop 126fa212bfbSJulian Elischer echo "done" 127fa212bfbSJulian Elischer fi 128fa212bfbSJulian Elischer 129fa212bfbSJulian Elischer # Create temporary file for usage. This file includes generated 130fa212bfbSJulian Elischer # interface names and jail names. All bridges, interfaces and jails 131fa212bfbSJulian Elischer # are written to file while created. In clean-up process written 132*5665fe6bSUlrich Spörlein # objects are cleaned (i.e. removed) from system. 133fa212bfbSJulian Elischer 134fa212bfbSJulian Elischer if [ -e ${TEMP_FILE} ]; then 135fa212bfbSJulian Elischer touch ${TEMP_FILE} 136fa212bfbSJulian Elischer fi 137fa212bfbSJulian Elischer 138fa212bfbSJulian Elischer echo -n "Verifying ethernet interface existence..." 139fa212bfbSJulian Elischer # Verify ethernet interface exist. 140fa212bfbSJulian Elischer if ! ngctl info ${ETHER_INTF}: >/dev/null 2>&1; then 141fa212bfbSJulian Elischer echo "Error: interface ${ETHER_INTF} does not exist" 142fa212bfbSJulian Elischer exit 1 143fa212bfbSJulian Elischer fi 144fa212bfbSJulian Elischer ifconfig ${ETHER_INTF} up || exit 1 145fa212bfbSJulian Elischer echo "done" 146fa212bfbSJulian Elischer 147fa212bfbSJulian Elischer # Get current number of bridge interfaces in the system. This number 148fa212bfbSJulian Elischer # is used to create a name for new bridge. 149fa212bfbSJulian Elischer BRIDGE_COUNT=`ngctl l | grep bridge | wc -l | sed -e "s/ //g"` 150fa212bfbSJulian Elischer BRIDGE_NAME="bridge${BRIDGE_COUNT}" 151fa212bfbSJulian Elischer 152fa212bfbSJulian Elischer # Create new ng_bridge(4) node and attach it to the ethernet interface. 153fa212bfbSJulian Elischer # Connect ng_ether:lower hook to bridge:link0 when creating bridge and 154fa212bfbSJulian Elischer # connect ng_ether:upper hook to bridge:link1 after bridge name is set. 155fa212bfbSJulian Elischer 156fa212bfbSJulian Elischer echo "Creating bridge interface: ${BRIDGE_NAME}..." 157fa212bfbSJulian Elischer ngctl mkpeer ${ETHER_INTF}: bridge lower link0 || exit 1 158fa212bfbSJulian Elischer ngctl name ${ETHER_INTF}:lower ${BRIDGE_NAME} || exit 1 159fa212bfbSJulian Elischer ngctl connect ${ETHER_INTF}: ${BRIDGE_NAME}: upper link1 || exit 1 160fa212bfbSJulian Elischer echo "Bridge ${BRIDGE_NAME} is created and ${ETHER_INTF} is connected." 161fa212bfbSJulian Elischer 162fa212bfbSJulian Elischer # In the above code block two hooks are connected to bridge interface, 163fa212bfbSJulian Elischer # therefore LINKNUM is set to 2 indicating total number of connected 164fa212bfbSJulian Elischer # hooks on the bridge interface. 165fa212bfbSJulian Elischer LINKNUM=2 166fa212bfbSJulian Elischer 167fa212bfbSJulian Elischer # Write name of the bridge to temp file. Clean-up procedure will use 168fa212bfbSJulian Elischer # this name to shutdown bridge interface. 169fa212bfbSJulian Elischer echo "bridge ${BRIDGE_NAME}" > ${TEMP_FILE} 170fa212bfbSJulian Elischer 171fa212bfbSJulian Elischer 172fa212bfbSJulian Elischer # Attach other interfaces as well. 173fa212bfbSJulian Elischer for NODE in ${TARGET_TOPOLOGY}; do 174fa212bfbSJulian Elischer 175fa212bfbSJulian Elischer # Virtual nodes are defined in TARGET_TOPOLOGY variable. They 176fa212bfbSJulian Elischer # have the form of 'nodeName|IPaddr'. Below two lines split 177fa212bfbSJulian Elischer # node definition to get node name and node IP. 178fa212bfbSJulian Elischer 179fa212bfbSJulian Elischer NODE_NAME=`echo ${NODE} | awk -F"|" '{print $1}'` 180fa212bfbSJulian Elischer NODE_IP=`echo ${NODE} | awk -F"|" '{print $2}'` 181fa212bfbSJulian Elischer 182fa212bfbSJulian Elischer # Create virtual node (jail) with given name and using 183fa212bfbSJulian Elischer # JAIL_PATH as root directory for jail. 184fa212bfbSJulian Elischer 185fa212bfbSJulian Elischer echo -n "Creating virtual node (jail) ${NODE_NAME}..." 186fa212bfbSJulian Elischer jail -c vnet name=${NODE_NAME} host.hostname=${NODE_NAME} \ 187fa212bfbSJulian Elischer path=${JAIL_PATH} persist 188fa212bfbSJulian Elischer echo "done" 189fa212bfbSJulian Elischer 190fa212bfbSJulian Elischer # Write name of the jail to temp file. Clean-up procedure will 191fa212bfbSJulian Elischer # use this name to remove jail. 192fa212bfbSJulian Elischer 193fa212bfbSJulian Elischer echo "node ${NODE_NAME}" >> ${TEMP_FILE} 194fa212bfbSJulian Elischer 195fa212bfbSJulian Elischer # Create a ng_eiface object for virtual node. ng_eiface 196fa212bfbSJulian Elischer # object has a hook that can be connected to one of bridge 197fa212bfbSJulian Elischer # links. After creating interface get its automatically 198fa212bfbSJulian Elischer # generated name for further usage. 199fa212bfbSJulian Elischer 200fa212bfbSJulian Elischer echo "Creating eiface interface for virtual node ${NODE_NAME}." 201fa212bfbSJulian Elischer ngctl mkpeer eiface ether ether 202fa212bfbSJulian Elischer EIFACE=`ngctl l | grep ngeth | tail -n 1| awk '{print $2}'` 203fa212bfbSJulian Elischer echo "Interface ${EIFACE} is created." 204fa212bfbSJulian Elischer 205fa212bfbSJulian Elischer # Write name of the interface to temp file. Clean-up procedure 206fa212bfbSJulian Elischer # will use this name to shutdown interface. 207fa212bfbSJulian Elischer 208fa212bfbSJulian Elischer echo "interface ${EIFACE}" >> ${TEMP_FILE} 209fa212bfbSJulian Elischer 210fa212bfbSJulian Elischer # Move virtual interface to virtual node. Note that Interface 211fa212bfbSJulian Elischer # name will not be changed at the end of this movement. Moved 212fa212bfbSJulian Elischer # interface can be seen at the output of ifconfig command in 213fa212bfbSJulian Elischer # jail: 'jexec jailname ifconfig' 214fa212bfbSJulian Elischer 215fa212bfbSJulian Elischer echo "Moving ${EIFACE} to ${NODE_NAME}" 216fa212bfbSJulian Elischer ifconfig ${EIFACE} vnet ${NODE_NAME} 217fa212bfbSJulian Elischer 218fa212bfbSJulian Elischer # Make lo0 interface localhost. 219fa212bfbSJulian Elischer jexec ${NODE_NAME} ifconfig lo0 localhost 220fa212bfbSJulian Elischer 221fa212bfbSJulian Elischer # Generate a random mac address for virtual interface. First 222fa212bfbSJulian Elischer # three octets can be changed by user. Last three octets are 223fa212bfbSJulian Elischer # generated randomly. 224fa212bfbSJulian Elischer M4=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \ 225fa212bfbSJulian Elischer awk '{ print $1 % 256 }'` 226fa212bfbSJulian Elischer M5=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \ 227fa212bfbSJulian Elischer awk '{ print $1 % 256 }'` 228fa212bfbSJulian Elischer M6=`od -An -N2 -i /dev/random | sed -e 's/ //g' | \ 229fa212bfbSJulian Elischer awk '{ print $1 % 256 }'` 230fa212bfbSJulian Elischer 231fa212bfbSJulian Elischer MAC=`printf ${MAC_PREFIX}:%02x:%02x:%02x ${M4} ${M5} ${M6}` 232fa212bfbSJulian Elischer 233fa212bfbSJulian Elischer # Set the link address (mac address) of virtual interface in 234fa212bfbSJulian Elischer # virtual node to randomly generated MAC. 235fa212bfbSJulian Elischer echo "Setting MAC address of ${EIFACE} to '${MAC}'" 236fa212bfbSJulian Elischer jexec ${NODE_NAME} ifconfig ${EIFACE} link $MAC 237fa212bfbSJulian Elischer 238fa212bfbSJulian Elischer # Either IPv4 or IPv6 can be used in this script. Ifconfig 239fa212bfbSJulian Elischer # IP setting syntax differs slightly for two IP versions. 240fa212bfbSJulian Elischer # For version 4 'inet' keyword is used whereas for version 6 241fa212bfbSJulian Elischer # 'inet6' is used. Below line tries to decide which IP version 242fa212bfbSJulian Elischer # is given and sets IPVER to 'inet' or 'inet6'. 243fa212bfbSJulian Elischer 244fa212bfbSJulian Elischer IPVER=`echo ${NODE_IP} | awk -F"." '{ split($4,last,"/"); \ 245fa212bfbSJulian Elischer if( NF==4 && $1>0 && $1<256 && $2<256 && $3<256 && \ 246fa212bfbSJulian Elischer last[1]<256) print "inet"; else print "inet6"}'` 247fa212bfbSJulian Elischer 248fa212bfbSJulian Elischer # Set IP address of virtual interface in virtual node. 249fa212bfbSJulian Elischer echo "Setting IP address of ${EIFACE} to '${NODE_IP}'" 250fa212bfbSJulian Elischer jexec ${NODE_NAME} ifconfig ${EIFACE} ${IPVER} ${NODE_IP} 251fa212bfbSJulian Elischer 252fa212bfbSJulian Elischer # Connect virtual interface to bridge interface. Syntax is : 253fa212bfbSJulian Elischer # ngctl connect INTERFACE: BRIDGE: INTERFACE_HOOK EMPTY_LINK. 254fa212bfbSJulian Elischer # Interface has one hook named 'ether' and below line connects 255fa212bfbSJulian Elischer # ether hook to bridge's first unconnected link. 256fa212bfbSJulian Elischer 257fa212bfbSJulian Elischer echo -n "Connecting ${EIFACE}:ether to ${BRIDGE_NAME}:link${LINKNUM}..." 258fa212bfbSJulian Elischer ngctl connect ${EIFACE}: ${BRIDGE_NAME}: ether link${LINKNUM} \ 259fa212bfbSJulian Elischer || exit 1 260fa212bfbSJulian Elischer echo "done" 261fa212bfbSJulian Elischer 262fa212bfbSJulian Elischer # Now, bridge has one more connected link thus link count is 263fa212bfbSJulian Elischer # incremented. 264fa212bfbSJulian Elischer LINKNUM=`expr ${LINKNUM} + 1` 265fa212bfbSJulian Elischer done 266*5665fe6bSUlrich Spörlein echo "Virtual LAN established successfully!" 267fa212bfbSJulian Elischer 268fa212bfbSJulian Elischer} 269fa212bfbSJulian Elischer 270fa212bfbSJulian Elischer# Stop routine. 271fa212bfbSJulian Elischervirtual_lan_stop() { 272fa212bfbSJulian Elischer 273fa212bfbSJulian Elischer if [ ! -e ${TEMP_FILE} ]; then 274fa212bfbSJulian Elischer echo "Nothing to stop! ${TEMP_FILE}: temp file not found" 275fa212bfbSJulian Elischer else 276fa212bfbSJulian Elischer 277fa212bfbSJulian Elischer echo -n "Shutdown bridge interface.." 278fa212bfbSJulian Elischer OBJECTS=`cat ${TEMP_FILE} | grep bridge | awk '{print $2}'` 279fa212bfbSJulian Elischer for BRIDGE in ${OBJECTS}; do 280fa212bfbSJulian Elischer ngctl shutdown ${BRIDGE}: >/dev/null 2>&1 281fa212bfbSJulian Elischer done 282fa212bfbSJulian Elischer echo "done" 283fa212bfbSJulian Elischer 284fa212bfbSJulian Elischer echo -n "Shutdown all eiface interfaces..." 285fa212bfbSJulian Elischer OBJECTS=`cat ${TEMP_FILE} | grep interface | awk '{print $2}'` 286fa212bfbSJulian Elischer for INTERFACE in ${OBJECTS}; do 287fa212bfbSJulian Elischer ngctl shutdown ${INTERFACE}: >/dev/null 2>&1 288fa212bfbSJulian Elischer done 289fa212bfbSJulian Elischer echo "done" 290fa212bfbSJulian Elischer 291fa212bfbSJulian Elischer echo -n "Removing all jails..." 292fa212bfbSJulian Elischer OBJECTS=`cat ${TEMP_FILE} | grep node | awk '{print $2}'` 293fa212bfbSJulian Elischer for NODE in ${OBJECTS}; do 294fa212bfbSJulian Elischer jail -r ${NODE} 295fa212bfbSJulian Elischer done 296fa212bfbSJulian Elischer echo "done" 297fa212bfbSJulian Elischer 298fa212bfbSJulian Elischer echo "Removing tempfile ${TEMP_FILE}" 299fa212bfbSJulian Elischer rm ${TEMP_FILE} 300fa212bfbSJulian Elischer fi 301*5665fe6bSUlrich Spörlein echo "Virtual LAN objects removed successfully!" 302fa212bfbSJulian Elischer 303fa212bfbSJulian Elischer} 304fa212bfbSJulian Elischer 305fa212bfbSJulian Elischervirtual_lan_usage() { 306fa212bfbSJulian Elischer echo "usage: $0 start [target_topology]" 307fa212bfbSJulian Elischer echo " : $0 [ stop | help ]" 308fa212bfbSJulian Elischer} 309fa212bfbSJulian Elischer 310fa212bfbSJulian Elischer 311fa212bfbSJulian Elischer# Main entry point. 312fa212bfbSJulian Elischer 313fa212bfbSJulian Elischercase $# in 314fa212bfbSJulian Elischer 1) 315fa212bfbSJulian Elischer case $1 in 316fa212bfbSJulian Elischer start) 317fa212bfbSJulian Elischer echo -n "Creating default target topology:" 318fa212bfbSJulian Elischer echo " ${TARGET_TOPOLOGY}" 319fa212bfbSJulian Elischer virtual_lan_start 320fa212bfbSJulian Elischer ;; 321fa212bfbSJulian Elischer stop) 322fa212bfbSJulian Elischer 323fa212bfbSJulian Elischer if [ ! -e ${TEMP_FILE} ]; then 324fa212bfbSJulian Elischer echo -n "Noting to stop! ${TEMP_FILE}:" 325fa212bfbSJulian Elischer echo " temp file not found" 326fa212bfbSJulian Elischer else 327fa212bfbSJulian Elischer virtual_lan_stop 328fa212bfbSJulian Elischer fi 329fa212bfbSJulian Elischer ;; 330fa212bfbSJulian Elischer help) 331fa212bfbSJulian Elischer virtual_lan_usage 332fa212bfbSJulian Elischer exit 1 333fa212bfbSJulian Elischer ;; 334fa212bfbSJulian Elischer *) 335fa212bfbSJulian Elischer virtual_lan_usage 336fa212bfbSJulian Elischer exit 1 337fa212bfbSJulian Elischer 338fa212bfbSJulian Elischer esac 339fa212bfbSJulian Elischer ;; 340fa212bfbSJulian Elischer 2) 341fa212bfbSJulian Elischer case $1 in 342fa212bfbSJulian Elischer start) 343fa212bfbSJulian Elischer TARGET_TOPOLOGY=$2 344fa212bfbSJulian Elischer echo -n "Creating target topology:" 345fa212bfbSJulian Elischer echo "${TARGET_TOPOLOGY}" 346fa212bfbSJulian Elischer virtual_lan_start 347fa212bfbSJulian Elischer ;; 348fa212bfbSJulian Elischer *) 349fa212bfbSJulian Elischer virtual_lan_usage 350fa212bfbSJulian Elischer exit 1 351fa212bfbSJulian Elischer esac 352fa212bfbSJulian Elischer ;; 353fa212bfbSJulian Elischer 354fa212bfbSJulian Elischer *) 355fa212bfbSJulian Elischer virtual_lan_usage 356fa212bfbSJulian Elischer exit 1 357fa212bfbSJulian Elischeresac 358fa212bfbSJulian Elischer 359