mirror of
https://github.com/firehol/firehol.git
synced 2024-06-30 19:02:21 +00:00
855 lines
18 KiB
Bash
Executable File
855 lines
18 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# vnetbuild - linked network namespace setup for humans...
|
|
#
|
|
# Copyright
|
|
#
|
|
# Copyright (C) 2015 Phil Whineray <phil@sanewall.org>
|
|
# Copyright (C) 2015 Costa Tsaousis <costa@tsaousis.gr>
|
|
#
|
|
# License
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
# See the file COPYING for details.
|
|
#
|
|
|
|
# make sure sbin is included in the path
|
|
# it seems that pppd ip-up.d script need this
|
|
export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin"
|
|
|
|
get_version() {
|
|
GIT_REF='$Format:%d,commit-%h$'
|
|
local IFS=":(), "
|
|
set -- "$GIT_REF"
|
|
ver='$Id$'
|
|
for i in $@
|
|
do
|
|
case "$i" in
|
|
*[0-9].[0-9]*)
|
|
echo "$i" | $SED_CMD -e 's/^v//'
|
|
return 0
|
|
;;
|
|
commit-[0-9a-zA-Z]*)
|
|
ver="$i"
|
|
;;
|
|
esac
|
|
done
|
|
echo "$ver"
|
|
return 0
|
|
}
|
|
|
|
if [ "@AUTOCONF_RUN@" = "Y" ]
|
|
then
|
|
FIREHOL_CONFIG_DIR="@FIREHOL_CONFIG_DIR@"
|
|
else
|
|
FIREHOL_CONFIG_DIR="/etc/firehol"
|
|
fi
|
|
|
|
marksreset() { :; }
|
|
markdef() { :; }
|
|
if [ -r "${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" ]
|
|
then
|
|
source "${FIREHOL_CONFIG_DIR}/firehol-defaults.conf" || exit 1
|
|
fi
|
|
|
|
# Load commands vnetbuild will need.
|
|
|
|
which_cmd() {
|
|
local name="$1"
|
|
shift
|
|
|
|
if [ "$1" = ":" ]
|
|
then
|
|
eval $name=":"
|
|
return 0
|
|
fi
|
|
|
|
unalias $1 >/dev/null 2>&1
|
|
local cmd=
|
|
IFS= read cmd <<-EOF
|
|
$(which $1 2> /dev/null)
|
|
EOF
|
|
|
|
if [ $? -gt 0 -o ! -x "${cmd}" ]
|
|
then
|
|
return 1
|
|
fi
|
|
shift
|
|
|
|
if [ $# -eq 0 ]
|
|
then
|
|
eval $name="'${cmd}'"
|
|
else
|
|
eval $name="'${cmd} ${@}'"
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
require_cmd() {
|
|
local var= val= block=1
|
|
|
|
if [ "$1" = "-n" ]
|
|
then
|
|
block=0
|
|
shift
|
|
fi
|
|
|
|
var="$1"
|
|
shift
|
|
|
|
eval val=\$\{${var}\}
|
|
if [ "${val}" ]
|
|
then
|
|
local cmd="${val/ */}"
|
|
if [ ! -x "$cmd" ]
|
|
then
|
|
echo >&2
|
|
if [ $block -eq 0 ]
|
|
then
|
|
echo >&2 "WARNING: optional command does not exist or is not executable ($cmd)"
|
|
echo >&2 "please add or correct $var in firehol-defaults.conf"
|
|
val=""
|
|
else
|
|
echo >&2 "ERROR: required command does not exist or is not executable ($cmd)"
|
|
echo >&2 "please add or correct $var in firehol-defaults.conf"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# link-balancer calls itself; export our findings so
|
|
# we do not repeat all of the lookups
|
|
eval export "$var"
|
|
return 0
|
|
elif [ $block -eq 0 ]
|
|
then
|
|
eval set -- "$@"
|
|
for cmd in "$@"
|
|
do
|
|
eval "NEED_${var}"="\$NEED_${var}' ${cmd/ */}'"
|
|
done
|
|
return 0
|
|
fi
|
|
|
|
if [ $# -eq 0 ]
|
|
then
|
|
eval set -- "\$NEED_${var}"
|
|
fi
|
|
|
|
echo >&2
|
|
echo >&2 "ERROR: LINK-BALANCER REQUIRES ONE OF THESE COMMANDS:"
|
|
echo >&2
|
|
echo >&2 " ${@}"
|
|
echo >&2
|
|
echo >&2 " You have requested the use of a link-balancer"
|
|
echo >&2 " feature that requires certain external programs"
|
|
echo >&2 " to be installed in the running system."
|
|
echo >&2
|
|
echo >&2 " Please consult your Linux distribution manual to"
|
|
echo >&2 " install the package(s) that provide these external"
|
|
echo >&2 " programs and retry."
|
|
echo >&2
|
|
echo >&2 " Note that you need an operational 'which' command"
|
|
echo >&2 " for link-balancer to find all the external programs it"
|
|
echo >&2 " needs. Check it yourself. Run:"
|
|
echo >&2
|
|
for x in "${@}"
|
|
do
|
|
echo >&2 " which $x"
|
|
done
|
|
|
|
exit 1
|
|
}
|
|
|
|
which_all() {
|
|
local cmd_var="$1"
|
|
|
|
eval set -- "$2"
|
|
for cmd in "$@"
|
|
do
|
|
which_cmd $cmd_var $cmd && break
|
|
done
|
|
}
|
|
|
|
# Where required = Y, if a command is not found, FireHOL will refuse to run.
|
|
# Where required = N, the command only required when it is actually used
|
|
#
|
|
# If a command is specified in /etc/firehol/firehol-defaults.conf it will
|
|
# be used. Otherwise, if the script has been configured with ./configure
|
|
# the detected versions will be used. If the script has not been configured
|
|
# then the list of possible commands is autodetected.
|
|
while IFS="|" read required cmd_var autoconf possibles
|
|
do
|
|
if [ "@AUTOCONF_RUN@" = "Y" ]
|
|
then
|
|
case "$autoconf" in
|
|
"@"*) autoconf=""; ;;
|
|
esac
|
|
fi
|
|
eval set_in_defaults=\"\$$cmd_var\"
|
|
if [ "$set_in_defaults" ]
|
|
then
|
|
:
|
|
elif [ "@AUTOCONF_RUN@" = "Y" -a ! -z "$autoconf" ]
|
|
then
|
|
eval $cmd_var=\"$autoconf\"
|
|
else
|
|
dirname="${0%/*}"
|
|
if [ "$dirname" = "$0" ]; then dirname="."; fi
|
|
PATH="/bin:/usr/bin:/sbin:/usr/sbin:$PATH:$dirname" which_all $cmd_var "$possibles"
|
|
fi
|
|
if [ "$required" = "Y" ]
|
|
then
|
|
require_cmd $cmd_var $possibles
|
|
else
|
|
require_cmd -n $cmd_var $possibles
|
|
fi
|
|
done <<-!
|
|
Y|IP_CMD|@IP@|ip
|
|
Y|BRCTL_CMD|@BRCTL@|brctl
|
|
Y|GREP_CMD|@GREP@|grep
|
|
Y|FIND_CMD|@FIND@|find
|
|
Y|SH_CMD|@SH@|sh bash ksh
|
|
Y|CUT_CMD|@CUT@|cut
|
|
Y|CAT_CMD|@CAT@|cat
|
|
Y|SED_CMD|@SED@|sed
|
|
Y|TR_CMD|@TR@|tr
|
|
Y|SLEEP_CMD|@SLEEP@|sleep
|
|
Y|MKDIR_CMD|@MKDIR@|mkdir
|
|
Y|RM_CMD|@RM@|rm
|
|
Y|MKTEMP_CMD|@MKTEMP@|mktemp
|
|
N|NEATO_CMD|@NEATO@|neato
|
|
!
|
|
|
|
VERSION=$(get_version)
|
|
|
|
emit_version() {
|
|
$CAT_CMD <<EOF
|
|
FireHOL vnetbuild $VERSION
|
|
(C) Copyright 2015 Phil Whineray <phil@firehol.org>
|
|
(C) Copyright 2015 Costa Tsaousis <costa@tsaousis.gr>
|
|
FireHOL is distributed under the GPL v2+.
|
|
Home Page: http://firehol.org
|
|
|
|
-------------------------------------------------------------------------
|
|
Get notified of new FireHOL releases by subscribing to the mailing list:
|
|
http://lists.firehol.org/mailman/listinfo/firehol-support/
|
|
-------------------------------------------------------------------------
|
|
EOF
|
|
}
|
|
|
|
needroot=Y
|
|
haderror=""
|
|
#gvprog=dot
|
|
#gvprog=sfdp
|
|
gvprog=$NEATO_CMD
|
|
|
|
setup="$1"
|
|
mode="$2"
|
|
outfile="$3"
|
|
|
|
case "$mode" in
|
|
""|-h|help|-v|version)
|
|
mode=
|
|
needroot=
|
|
haderror="Y"
|
|
;;
|
|
start|stop|status)
|
|
:
|
|
;;
|
|
graphviz)
|
|
require_cmd NEATO_CMD
|
|
needroot=
|
|
case "$outfile" in
|
|
*.gv|"")
|
|
graphviz=$CAT_CMD
|
|
;;
|
|
*.ps)
|
|
format=ps
|
|
graphviz="$gvprog -T$format"
|
|
;;
|
|
*.pdf)
|
|
format=pdf
|
|
graphviz="$gvprog -T$format"
|
|
;;
|
|
*.png)
|
|
format=png
|
|
graphviz="$gvprog -T$format"
|
|
;;
|
|
*)
|
|
1>&2 echo "Unrecognised file extension: $mode"
|
|
haderror="Y"
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
1>&2 echo "Unrecognised mode: $mode"
|
|
haderror="Y"
|
|
needroot=
|
|
;;
|
|
esac
|
|
|
|
if [ "$mode" = "" ]
|
|
then
|
|
emit_version
|
|
fi
|
|
|
|
if [ "$needroot" -a "${UID}" != "0" ]
|
|
then
|
|
echo "Error: must be root to use '$mode'"
|
|
haderror="Y"
|
|
fi
|
|
|
|
if [ "$haderror" -o $# -lt 2 ]
|
|
then
|
|
echo ""
|
|
echo "Usage: sudo vnetbuild CONFIGFILE stop|start|status"
|
|
echo " or: vnetbuild CONFIGFILE graphviz OUTFILE.{gv,png,pdf,ps}"
|
|
exit 1
|
|
else
|
|
shift
|
|
shift
|
|
fi
|
|
|
|
setupbase="${setup##*/}"
|
|
errline=""
|
|
error=""
|
|
|
|
if ! MYTMP="`$MKTEMP_CMD -d -t vnetbuild-XXXXXX`"
|
|
then
|
|
echo >&2
|
|
echo >&2
|
|
echo >&2 "Cannot create temporary directory."
|
|
echo >&2
|
|
exit 1
|
|
fi
|
|
|
|
myexit() {
|
|
status=$?
|
|
if [ "$error" != "" ]
|
|
then
|
|
echo "$setupbase: line $errline: $error"
|
|
fi
|
|
$RM_CMD -rf $MYTMP
|
|
exit $status
|
|
}
|
|
|
|
trap myexit INT
|
|
trap myexit HUP
|
|
trap myexit 0
|
|
|
|
CURDIR=`pwd`/
|
|
export CURDIR
|
|
|
|
set -e
|
|
|
|
$MKDIR_CMD $MYTMP/setup
|
|
$SED_CMD = "$setup" > $MYTMP/withnum
|
|
(echo "cd $CURDIR"; $SED_CMD -e 'N;s/\n/\t/' -e 's/^/lineno=/' -e '/exec/s/[<>|&]/\\&/g' $MYTMP/withnum) > $MYTMP/setup/$setupbase
|
|
|
|
$MKDIR_CMD $MYTMP/ns
|
|
$MKDIR_CMD $MYTMP/runtime-lines
|
|
|
|
current_name=
|
|
|
|
create_namespace() {
|
|
errline=$lineno
|
|
local type="$1"
|
|
current_name="$2"
|
|
NSTMP=$MYTMP/ns/$current_name
|
|
if [ -d $NSTMP ]
|
|
then
|
|
error="$current_name: $($CAT_CMD $NSTMP/type) already defined"
|
|
return 1
|
|
fi
|
|
$MKDIR_CMD $NSTMP
|
|
$MKDIR_CMD $NSTMP/devices
|
|
$MKDIR_CMD $NSTMP/devicepairs
|
|
echo $type > $NSTMP/type
|
|
echo 0 > $NSTMP/forward
|
|
> $NSTMP/routes
|
|
> $NSTMP/devlist
|
|
> $NSTMP/pairlist
|
|
> $NSTMP/bridgelist
|
|
echo $current_name >> $MYTMP/nslist
|
|
echo $errline > $MYTMP/runtime-lines/$current_name
|
|
}
|
|
|
|
host() {
|
|
errline=$lineno
|
|
create_namespace host "$1"
|
|
}
|
|
|
|
switch() {
|
|
errline=$lineno
|
|
create_namespace switch "$1"
|
|
}
|
|
|
|
dev() {
|
|
errline=$lineno
|
|
device="$1"
|
|
shift
|
|
|
|
if [ ! "$current_name" ]
|
|
then
|
|
error="cannot define dev outside of a host or switch"
|
|
return 1
|
|
fi
|
|
|
|
if [ -f $NSTMP/devices/$device ]
|
|
then
|
|
error="$current_name/$device: already defined"
|
|
return 1
|
|
fi
|
|
|
|
local otherns=
|
|
local otherdev=
|
|
case $1 in
|
|
*/[a-zA-Z]*)
|
|
otherns=$(echo $1 | $CUT_CMD -f1 -d/)
|
|
otherdev=$(echo $1 | $CUT_CMD -f2 -d/)
|
|
shift
|
|
if [ -f $MYTMP/ns/$otherns/devicepairs/$otherdev ]
|
|
then
|
|
error="$otherns/$otherdev: already has paired device"
|
|
return 1
|
|
fi
|
|
;;
|
|
esac
|
|
|
|
local type="$($CAT_CMD $NSTMP/type)"
|
|
if [ "$*" != "" -a "$type" = "switch" ]
|
|
then
|
|
error="device in switch may not specify an IP address"
|
|
return 1
|
|
fi
|
|
|
|
|
|
f=$NSTMP/devices/$device
|
|
> $f
|
|
for ip in "$@"
|
|
do
|
|
case $ip in
|
|
*/*)
|
|
echo "$ip" >> $f
|
|
;;
|
|
*)
|
|
error="IP address should be expressed as ip/mask"
|
|
return 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [ "$otherdev" ]
|
|
then
|
|
if [ ! -d $MYTMP/ns/$otherns ]
|
|
then
|
|
error="$otherns undefined"
|
|
return 1
|
|
fi
|
|
echo "$current_name $device" > $MYTMP/ns/$otherns/devicepairs/$otherdev
|
|
echo "n/a n/a" > $NSTMP/devicepairs/$device
|
|
echo "$otherns $otherdev" >> $NSTMP/pairlist
|
|
echo $errline > $MYTMP/runtime-lines/$otherns-pair-$otherdev
|
|
fi
|
|
|
|
echo $device >> $NSTMP/devlist
|
|
echo $errline > $MYTMP/runtime-lines/$current_name-dev-$device
|
|
return 0
|
|
}
|
|
|
|
route() {
|
|
errline=$lineno
|
|
if [ ! "$current_name" ]
|
|
then
|
|
error="can only specify route in a host"
|
|
return 1
|
|
fi
|
|
|
|
local type="$($CAT_CMD $NSTMP/type)"
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
error="can only specify route in a host"
|
|
return 1
|
|
fi
|
|
|
|
echo "$*" >> $NSTMP/routes
|
|
echo $errline >> $MYTMP/runtime-lines/$current_name-routes
|
|
return 0
|
|
}
|
|
|
|
bridgedev() {
|
|
errline=$lineno
|
|
device="$1"
|
|
shift
|
|
|
|
if [ ! "$current_name" ]
|
|
then
|
|
error="can only specify bridgedev in a host"
|
|
return 1
|
|
fi
|
|
|
|
local type="$($CAT_CMD $NSTMP/type)"
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
error="can only specify bridgedev in a host"
|
|
return 1
|
|
fi
|
|
|
|
if [ -f $NSTMP/devices/$device ]
|
|
then
|
|
error="$current_name/$device: already defined"
|
|
return 1
|
|
fi
|
|
|
|
ipf=$NSTMP/devices/$device
|
|
devf=$ipf-bridged
|
|
> $ipf
|
|
> $devf
|
|
for ipordev in "$@"
|
|
do
|
|
case $ipordev in
|
|
*/*)
|
|
echo "$ipordev" >> $ipf
|
|
;;
|
|
*)
|
|
echo "$ipordev" >> $devf
|
|
;;
|
|
esac
|
|
done
|
|
|
|
echo $device >> $NSTMP/bridgelist
|
|
echo $errline > $MYTMP/runtime-lines/$current_name-dev-$device
|
|
return 0
|
|
}
|
|
|
|
exec() {
|
|
errline=$lineno
|
|
if [ ! "$current_name" ]
|
|
then
|
|
error="can only specify exec in a host or switch"
|
|
return 1
|
|
fi
|
|
|
|
echo "$*" >> $NSTMP/exec
|
|
echo $errline >> $MYTMP/runtime-lines/$current_name-exec
|
|
return 0
|
|
}
|
|
|
|
is_ipv6() {
|
|
case "$1" in
|
|
*:*)
|
|
return 0
|
|
;;
|
|
esac
|
|
return 1
|
|
}
|
|
|
|
cd $MYTMP/setup
|
|
. $setupbase
|
|
errline=""
|
|
cd $CURDIR
|
|
|
|
exists_ns() {
|
|
if [ "$($IP_CMD netns list | $GREP_CMD "^$1\$")" ]
|
|
then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
dev_in_ns() {
|
|
$IP_CMD netns exec $1 $IP_CMD link list | $GREP_CMD "^[0-9]" | $CUT_CMD -d: -f2 | $CUT_CMD -f1 -d'@' | $TR_CMD -d ' '
|
|
}
|
|
|
|
get_pids() {
|
|
# Not in all versions:
|
|
# $IP_CMD netns pids $1
|
|
$FIND_CMD -L /proc/[0-9]*/ns -maxdepth 1 -samefile /var/run/netns/$1 2>/dev/null | $CUT_CMD -f3 -d/
|
|
}
|
|
|
|
shutdown_ns() {
|
|
for i in $(dev_in_ns $1)
|
|
do
|
|
$IP_CMD netns exec $1 $IP_CMD link set $i down
|
|
done
|
|
pids=$(get_pids $1)
|
|
if [ "$pids" ]; then kill $pids; $SLEEP_CMD 1; fi
|
|
pids=$(get_pids $1)
|
|
if [ "$pids" ]; then kill -9 $pids; fi
|
|
}
|
|
|
|
startup_ns() {
|
|
for i in $(dev_in_ns $1)
|
|
do
|
|
$IP_CMD netns exec $1 $IP_CMD link set $i up
|
|
done
|
|
}
|
|
|
|
while read ns
|
|
do
|
|
while read dev
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns-dev-$dev
|
|
if [ ! -f $MYTMP/ns/$ns/devicepairs/$dev ]
|
|
then
|
|
error="$ns/$dev has no paired device"
|
|
exit 1
|
|
fi
|
|
done < $MYTMP/ns/$ns/devlist
|
|
|
|
while read otherns otherdev
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$otherns-pair-$otherdev
|
|
if [ ! -f $MYTMP/ns/$otherns/devices/$otherdev ]
|
|
then
|
|
error="$otherns/$otherdev not defined to be paired with"
|
|
exit 1
|
|
fi
|
|
done < $MYTMP/ns/$ns/pairlist
|
|
done < $MYTMP/nslist
|
|
|
|
if [ "$mode" = "stop" -o "$mode" = "start" ]
|
|
then
|
|
while read ns
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns
|
|
error="shutting down namespace"
|
|
exists_ns $ns && shutdown_ns $ns
|
|
done < $MYTMP/nslist
|
|
|
|
while read ns
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns
|
|
error="deleting namespace"
|
|
exists_ns $ns && $IP_CMD netns del $ns
|
|
done < $MYTMP/nslist
|
|
|
|
error=""
|
|
fi
|
|
|
|
if [ "$mode" = "stop" ]
|
|
then
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$mode" = "start" ]
|
|
then
|
|
while read ns
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns
|
|
error="adding namespace"
|
|
type="$($CAT_CMD $MYTMP/ns/$ns/type)"
|
|
$IP_CMD netns add $ns
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
error="adding bridge to switch namespace"
|
|
$IP_CMD netns exec $ns $BRCTL_CMD addbr switch
|
|
fi
|
|
done < $MYTMP/nslist
|
|
|
|
while read ns
|
|
do
|
|
type="$($CAT_CMD $MYTMP/ns/$ns/type)"
|
|
while read dev
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns-dev-$dev
|
|
read ons odev < $MYTMP/ns/$ns/devicepairs/$dev
|
|
if [ "$ons" != "n/a" ]
|
|
then
|
|
error="adding virtual ethernet to $type namespace"
|
|
#$IP_CMD link add $dev netns $ns type veth peer netns $ons name $odev
|
|
$IP_CMD link add $dev netns $ns type veth peer name $odev
|
|
$IP_CMD link set $odev netns $ons
|
|
else
|
|
: # gets set up from the other end
|
|
fi
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
error="adding virtual ethernet to bridge"
|
|
$IP_CMD netns exec $ns $BRCTL_CMD addif switch $dev
|
|
fi
|
|
while read ip
|
|
do
|
|
error="adding ip address to virtual ethernet"
|
|
if is_ipv6 $ip; then bc=""; v6="-6"; else bc="broadcast +"; v6=""; fi
|
|
$IP_CMD netns exec $ns $IP_CMD $v6 addr add $ip $bc dev $dev
|
|
done < $MYTMP/ns/$ns/devices/$dev
|
|
done < $MYTMP/ns/$ns/devlist
|
|
|
|
while read bridge
|
|
do
|
|
read errline < $MYTMP/runtime-lines/$ns-dev-$bridge
|
|
error="adding bridge to host namespace"
|
|
$IP_CMD netns exec $ns $BRCTL_CMD addbr $bridge
|
|
while read dev
|
|
do
|
|
error="adding virtual interface to bridge"
|
|
$IP_CMD netns exec $ns $BRCTL_CMD addif $bridge $dev
|
|
done < $MYTMP/ns/$ns/devices/$bridge-bridged
|
|
while read ip
|
|
do
|
|
error="adding ip to virtual interface"
|
|
if is_ipv6 $ip; then bc=""; v6="-6"; else bc="broadcast +"; v6=""; fi
|
|
$IP_CMD netns exec $ns $IP_CMD $v6 addr add $ip $bc dev $bridge
|
|
done < $MYTMP/ns/$ns/devices/$bridge
|
|
done < $MYTMP/ns/$ns/bridgelist
|
|
done < $MYTMP/nslist
|
|
|
|
while read ns
|
|
do
|
|
echo "Starting namespace $ns"
|
|
|
|
read errline < $MYTMP/runtime-lines/$ns
|
|
error="starting namespace"
|
|
startup_ns $ns
|
|
|
|
while read route
|
|
do
|
|
errline=$($TR_CMD "\n" "/" < $MYTMP/runtime-lines/$ns-routes | $SED_CMD -e s:/$::)
|
|
error="adding route to $ns"
|
|
if is_ipv6 "$route"; then bc=""; v6="-6"; else bc="broadcast +"; v6=""; fi
|
|
$IP_CMD netns exec $ns $IP_CMD $v6 route add $route
|
|
done < $MYTMP/ns/$ns/routes
|
|
|
|
if [ -f $MYTMP/ns/$ns/exec ]
|
|
then
|
|
errline=$($TR_CMD "\n" "/" < $MYTMP/runtime-lines/$ns-exec | $SED_CMD -e s:/$::)
|
|
error="running exec for $ns"
|
|
$IP_CMD netns exec $ns $SH_CMD -e $MYTMP/ns/$ns/exec
|
|
fi
|
|
done < $MYTMP/nslist
|
|
error=""
|
|
fi
|
|
|
|
if [ "$mode" = "status" ]
|
|
then
|
|
while read ns
|
|
do
|
|
echo "---------------------- $ns --------------------"
|
|
if exists_ns $ns
|
|
then
|
|
# We remove the @whatever part of the device names since these
|
|
# appear to be highly unreliable when creating devices in different
|
|
# namespaces, at least under linux 4.3. Adding in two steps, like
|
|
# this did not help:
|
|
# $IP_CMD link add $dev netns $ns type veth peer name $odev
|
|
# $IP_CMD link set $odev netns $ons
|
|
$IP_CMD netns exec $ns $IP_CMD addr show | $SED_CMD 's/@[^:]*:/:/'
|
|
$IP_CMD netns exec $ns $IP_CMD route show
|
|
$IP_CMD netns exec $ns $BRCTL_CMD show
|
|
else
|
|
echo "Namespace not running"
|
|
fi
|
|
echo ""
|
|
done < $MYTMP/nslist
|
|
fi
|
|
|
|
if [ "$mode" = "graphviz" ]
|
|
then
|
|
gv=$MYTMP/gv
|
|
echo "/* process e.g.: $gvprog -Tps filename.gv -o filename.ps */" >$gv
|
|
echo "graph NET {" >>$gv
|
|
if [ "$format" != "png" ]
|
|
then
|
|
echo "size=7; /* Max size 7 inches */" >>$gv
|
|
fi
|
|
echo "overlap=prism;" >>$gv
|
|
echo "edge [color=blue,style=dashed];" >>$gv
|
|
while read ns
|
|
do
|
|
type="$($CAT_CMD $MYTMP/ns/$ns/type)"
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
echo "switch_$ns [shape=polygon,sides=4,skew=.4,label=\"$ns\"];" >>$gv
|
|
else
|
|
echo -n "host_$ns [shape=record,label=\"$ns" >>$gv
|
|
while read route
|
|
do
|
|
echo -n "\\n$route" >>$gv
|
|
done < $MYTMP/ns/$ns/routes
|
|
while read bridge
|
|
do
|
|
echo -n "|{<$bridge> $bridge" >>$gv
|
|
while read ip
|
|
do
|
|
echo -n "\\n$ip" >>$gv
|
|
done < $MYTMP/ns/$ns/devices/$bridge
|
|
while read dev
|
|
do
|
|
echo -n "|{" >>$gv
|
|
echo -n "<$dev> $dev" >>$gv
|
|
while read ip
|
|
do
|
|
echo -n "\n$ip" >>$gv
|
|
done < $MYTMP/ns/$ns/devices/$dev
|
|
echo -n "}" >>$gv
|
|
echo "$bridge" > $MYTMP/ns/$ns/suppress-$dev
|
|
done < $MYTMP/ns/$ns/devices/$bridge-bridged
|
|
echo -n "}" >>$gv
|
|
done < $MYTMP/ns/$ns/bridgelist
|
|
while read dev
|
|
do
|
|
if [ ! -f $MYTMP/ns/$ns/suppress-$dev ]
|
|
then
|
|
echo -n "|<$dev> $dev" >>$gv
|
|
while read ip
|
|
do
|
|
echo -n "\\n$ip" >>$gv
|
|
done < $MYTMP/ns/$ns/devices/$dev
|
|
fi
|
|
done < $MYTMP/ns/$ns/devlist
|
|
echo "\"];" >>$gv
|
|
fi
|
|
done < $MYTMP/nslist
|
|
while read ns
|
|
do
|
|
type="$($CAT_CMD $MYTMP/ns/$ns/type)"
|
|
while read dev
|
|
do
|
|
read ons odev < $MYTMP/ns/$ns/devicepairs/$dev
|
|
if [ "$ons" != "n/a" ]
|
|
then
|
|
otype="$($CAT_CMD $MYTMP/ns/$ons/type)"
|
|
if [ "$type" = "switch" ]
|
|
then
|
|
from="switch_$ns"
|
|
else
|
|
from="host_$ns:$dev"
|
|
fi
|
|
if [ "$otype" = "switch" ]
|
|
then
|
|
to="switch_$ons"
|
|
else
|
|
to="host_$ons:$odev"
|
|
fi
|
|
echo "$from -- $to;" >>$gv
|
|
else
|
|
: # gets set up from the other end
|
|
fi
|
|
done < $MYTMP/ns/$ns/devlist
|
|
done < $MYTMP/nslist
|
|
echo "}" >>$gv
|
|
|
|
if [ "$outfile" = "" ]
|
|
then
|
|
$graphviz $gv
|
|
else
|
|
$graphviz $gv > "$outfile"
|
|
fi
|
|
fi
|
|
|
|
exit 0
|