summaryrefslogtreecommitdiffstats
path: root/contrail-agent/scripts/create-vrouter.sh
diff options
context:
space:
mode:
Diffstat (limited to 'contrail-agent/scripts/create-vrouter.sh')
-rwxr-xr-xcontrail-agent/scripts/create-vrouter.sh251
1 files changed, 251 insertions, 0 deletions
diff --git a/contrail-agent/scripts/create-vrouter.sh b/contrail-agent/scripts/create-vrouter.sh
new file mode 100755
index 0000000..cd3828f
--- /dev/null
+++ b/contrail-agent/scripts/create-vrouter.sh
@@ -0,0 +1,251 @@
+#!/bin/sh -e
+#
+# Script used to configure vRouter interface
+
+ARG_BRIDGE=b
+ARG_HELP=h
+OPTS=:${ARG_BRIDGE}${ARG_HELP}
+USAGE="\
+create-vrouter [-${ARG_BRIDGE}${ARG_HELP}] [interface]
+Options:
+ -$ARG_BRIDGE remove bridge from interface if exists
+ -$ARG_HELP print this message"
+
+configVRouter()
+{
+ cat juju-header
+ if [ -s "$2" ]; then
+ printf "\n%s\n" "auto $1"
+ cat "$2"
+ elif [ ! -e "$2" ]; then
+ printf "\n%s\n%s\n" "auto $1" "iface $1 inet manual"
+ fi
+ printf "\n%s\n" "auto vhost0"
+ if [ -e "$3" ]; then
+ cat "$3"
+ else
+ echo "iface vhost0 inet dhcp"
+ fi
+ cat <<-EOF
+ pre-up ip link add vhost0 address \$(cat /sys/class/net/$1/address) type vhost
+ pre-up vif --add $1 --mac \$(cat /sys/class/net/$1/address) --vrf 0 --vhost-phys --type physical
+ pre-up vif --add vhost0 --mac \$(cat /sys/class/net/$1/address) --vrf 0 --type vhost --xconnect $1
+ post-down vif --list | awk '/^vif.*OS: vhost0/ {split(\$1, arr, "\\/"); print arr[2];}' | xargs vif --delete
+ post-down vif --list | awk '/^vif.*OS: $1/ {split(\$1, arr, "\\/"); print arr[2];}' | xargs vif --delete
+ post-down ip link delete vhost0
+ EOF
+}
+
+configureInterfaces()
+{
+ for cfg in /etc/network/interfaces /etc/network/interfaces.d/*.cfg \
+ /etc/network/*.config; do
+ # for each network interfaces config, extract the config for
+ # the chosen interface whilst commenting it out in the
+ # subsequent replacement config
+ [ -e "$cfg" ] || continue
+ awk -v interface=$1 -v interface_cfg=$TMP/interface.cfg \
+ -v vrouter_cfg=$TMP/vrouter.cfg -f vrouter-interfaces.awk \
+ "$cfg" > $TMP/interfaces.cfg
+ if ! diff $TMP/interfaces.cfg "$cfg" > /dev/null; then
+ # create backup
+ mv "$cfg" "$cfg.save"
+ # substitute replacement config for original config
+ { cat juju-header; echo; cat $TMP/interfaces.cfg; } > "$cfg"
+ fi
+ done
+ if [ -e $TMP/interface.cfg ]; then
+ # strip whitespace
+ sed -En -e '1h;1!H;${g;s/[[:space:]]+$//;p}' -i \
+ $TMP/interface.cfg
+ fi
+}
+
+configureInterfacesDir()
+{
+ # add interfaces.d source line to /etc/network/interfaces
+ if ! grep -q '^[[:blank:]]*source /etc/network/interfaces\.d/\*\.cfg[[:blank:]]*$' \
+ /etc/network/interfaces; then
+ printf "\n%s\n" "source /etc/network/interfaces.d/*.cfg" \
+ >> /etc/network/interfaces
+ # it's possible for conflicting network config to exist in
+ # /etc/network/interfaces.d when we start sourcing it
+ # so disable any config as a precautionary measure
+ for cfg in /etc/network/interfaces.d/*.cfg; do
+ [ -e "$cfg" ] || continue
+ mv "$cfg" "$cfg.old"
+ done
+ fi
+ mkdir -p /etc/network/interfaces.d
+}
+
+configureVRouter()
+{
+ if [ $# = 1 ]; then
+ iface_down=$1
+ iface_delete=$1
+ iface_up=$1
+ iface_cfg=$TMP/interface.cfg
+ else
+ iface_down="$1 $2"
+ iface_delete=$2
+ iface_up=$1
+ iface_cfg=/dev/null
+ fi
+ ifacedown $iface_down vhost0; sleep 5
+ configureInterfacesDir
+ configureInterfaces $iface_delete
+ configVRouter $iface_up $iface_cfg $TMP/vrouter.cfg \
+ > /etc/network/interfaces.d/vrouter.cfg
+ ifaceup $iface_up vhost0
+ restoreRoutes
+}
+
+ifacebridge()
+{
+ for cfg in /etc/network/interfaces /etc/network/interfaces.d/*.cfg \
+ /etc/network/*.config; do
+ # extract all the bridges with interface as port
+ # and all interfaces marked auto
+ [ -e "$cfg" ] || continue
+ awk -v interface=$1 \
+ -v auto_interfaces=$TMP/auto_interfaces \
+ -v bridge_interfaces=$TMP/bridge_interfaces \
+ -f bridges.awk "$cfg"
+ done
+ if [ -e $TMP/bridge_interfaces ]; then
+ # output the bridge marked auto
+ grep -m 1 -f $TMP/bridge_interfaces $TMP/auto_interfaces
+ fi
+}
+
+ifacedown()
+{
+ for iface; do
+ # ifdown interface
+ # if bridge, save list of interfaces
+ # if bond, save list of slaves
+ if [ ! -e /sys/class/net/$iface ]; then
+ continue
+ fi
+ [ -d /sys/class/net/$iface/bridge ] && saveIfaces $iface
+ [ -d /sys/class/net/$iface/bonding ] && saveSlaves $iface
+ ifdown -v --force $iface
+ done
+}
+
+ifaceup()
+{
+ for iface; do
+ # ifup interface
+ # if bridge, restore list of interfaces
+ # restore list of slaves if exists (bond)
+ restoreSlaves $iface
+ ifup -v $iface
+ [ -d /sys/class/net/$iface/bridge ] && restoreIfaces $iface
+ done
+ return 0
+}
+
+restoreRoutes()
+{
+ if [ -e /etc/network/routes ]; then
+ service networking-routes stop
+ service networking-routes start
+ fi
+}
+
+restoreIfaces()
+{
+ if [ -e $TMP/$1.ifaces ]; then
+ cat $TMP/$1.ifaces | xargs -n 1 brctl addif $1 || true
+ fi
+}
+
+restoreSlaves()
+{
+ if [ -e $TMP/$1.slaves ]; then
+ cat $TMP/$1.slaves | xargs ifup
+ fi
+}
+
+saveIfaces()
+{
+ if [ -z "$(find /sys/class/net/$1/brif -maxdepth 0 -empty)" ]; then
+ find /sys/class/net/$1/brif | tail -n +2 | xargs -n 1 basename \
+ > $TMP/$1.ifaces
+ fi
+}
+
+saveSlaves()
+{
+ if [ -s /sys/class/net/$1/bonding/slaves ]; then
+ cat /sys/class/net/$1/bonding/slaves | tr " " "\n" \
+ > $TMP/$1.slaves
+ fi
+}
+
+usage()
+{
+ if [ $# -gt 0 ]; then
+ fd=$1
+ else
+ fd=1
+ fi
+ echo "$USAGE" >&$fd
+}
+
+usageError()
+{
+ echo "$1" >&2
+ usage 2
+ exit 1
+}
+
+while getopts $OPTS opt; do
+ case $opt in
+ $ARG_BRIDGE)
+ remove_bridge=true
+ ;;
+ $ARG_HELP)
+ usage
+ exit 0
+ ;;
+ "?")
+ usageError "Unknown argument: $OPTARG"
+ ;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+if [ $# -gt 1 ]; then
+ usageError "Too many arguments"
+fi
+
+TMP=$(mktemp -d /tmp/create-vrouter.XXX)
+
+if [ $# -ne 0 ]; then
+ bridge=$(ifacebridge $1)
+ if [ -n "$bridge" ]; then
+ if [ -n "$remove_bridge" ]; then
+ configureVRouter $1 $bridge
+ else
+ configureVRouter $bridge
+ fi
+ else
+ configureVRouter $1
+ fi
+else
+ # use default gateway interface
+ gateway=$(route -n | awk '$1 == "0.0.0.0" { print $8 }')
+ if [ -d /sys/class/net/$gateway/bridge ] \
+ && [ -z "$(find /sys/class/net/$gateway/brif -maxdepth 0 -empty)" ] \
+ && [ -n "$remove_bridge" ]; then
+ interface=$(find /sys/class/net/$gateway/brif | sed -n -e '2p' | xargs basename)
+ configureVRouter $interface $gateway
+ else
+ configureVRouter $gateway
+ fi
+fi
+
+rm -rf $TMP