Skip to content

Instantly share code, notes, and snippets.

@tuklusan
Last active June 14, 2023 00:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tuklusan/a20856677f91d814c589a9cdd6584fa9 to your computer and use it in GitHub Desktop.
Save tuklusan/a20856677f91d814c589a9cdd6584fa9 to your computer and use it in GitHub Desktop.
Script to easily setup a Bridge Network with VDE (VDE2) switch, TUN and TAP interfaces for running emulators. More details: https://supratim-sanyal.blogspot.com/2018/10/bionic-beaver-on-zarchitecture-my.html
#!/bin/bash
# ---
# bridge-tap-vde-setup.sh
# ---
# Bridge, VDE and Tun/Tap Network Device Setup Script to run emulators.
# The best place to execute this is probably from /etc/network/if-up.d/
# (assuming Network Manager is running, not dhcpcd or other dhcp clients)
#
# Two configuration items are below, make sure to set them correctly.
# *** IMPORTANT *** Default DNS also needs to be manually configured on some
# systems, e.g. for Ubuntu edit /etc/systemd/resolved.conf
#
# Uses gawk and ipcalc; make sure they are installed.
# Writes some dubiously helpful information to kernel log, use dmesg to view.
#
# Attempts to disable firewall, clears out iptables, and sets up IPv4 forwarding
#
# To see what it accomplished (or not), look at kernel log (dmesg)
#
# Tested on OpenSUSE Tumbleweed and Raspbian hosts with Hercules IBM S/390
# Mainframe and AlphaVM Free DEC Alphaserver ES40 guests running concurrently.
# Some form of this script is running on numerous hobbyist servers of mine,
# including a MX Linux server hosting over 33 SIMH VAX and PDP instances
# talking DECnet and IP on two different VDE switches
#
# Please understand and tweak as you need; it basically aims to do this:
#
# ----
# ----------|tun0| <--> IBM S/390 emulator
# | ---- (Hercules sets this up using /dev/net/tun)
# -------
# |Network|
# |Adapter|
# | |
# -------
# | ------
# ----------|bridge|
# |br-ip |
# ------
# | --------
# |--------|inettap0| <--> For use by any emulator
# | --------
# |
# | ----------
# --------|VDE Switch| (Virtual Distributed Ethernet switch)
# ----------
# |
# | -----------
# |-|vde-ip-tap0| <--> Available to more emulators
# | -----------
# |
# | -----------
# |-|vde-ip-tap1| <--> AlphaServer ES40 emulator
# | -----------
# |
# |-... update script to keep adding
# | more vde tap interfaces as needed.
#
# More details:
# http://supratim-sanyal.blogspot.com/2018/10/bionic-beaver-on-zarchitecture-my.html
#
# Licensed under "THE BEER-WARE LICENSE" (Revision 42):
# Supratim Sanyal <https://goo.gl/FqzyBW> wrote this file. As long as
# you retain this notice you can do whatever you want with this stuff.
# If we meet some day, and you think this stuff is worth it, you can buy
# me a beer in return.
# ---
# ----
# Edit DEVICE to physical interface that has the IP address which will be moved
# to a bridge, and TAP and VDE plug interfaces made available from the bridge
# ----
DEVICE="eth0"
# ----
# Edit LOCALUSER to username of the user running simulators
# ----
LOCALUSER="system"
# ------------------------------------------------------------------------------
# No more changes should be required from here
# ------------------------------------------------------------------------------
echo ${0}: Start | tee /dev/kmsg
# ----
# Exit if we're called for the loopback
# ----
if [ "${DEVICE}" = lo ]; then
echo ${0}: Doing nothing and exiting for interface ${DEVICE} | tee /dev/kmsg
exit 0
fi
# ----
# Make sure the NIC exists
# ----
if [ ! -d "/sys/class/net/${DEVICE}" ]; then
echo ${0}: ${DEVICE} does not exist | tee /dev/kmsg
echo ${0}: Please check config parameter | tee /dev/kmsg
exit 1
fi
# ----
# Make sure the local username exists
# ----
if ! id "${LOCALUSER}" &>/dev/null; then
echo ${0}: User ${LOCALUSER} does not exist | tee /dev/kmsg
echo ${0}: Please check config parameter | tee /dev/kmsg
exit 1
fi
# ----
# Make sure uncommon utilities are installed
# ----
if ! type -P "gawk" &>/dev/null; then
echo ${0}: gawk utility does not exist | tee /dev/kmsg
echo ${0}: Please install all the requirements | tee /dev/kmsg
exit 1
fi
if ! type -P "ipcalc" &>/dev/null; then
echo ${0}: ipcalc utility does not exist | tee /dev/kmsg
echo ${0}: Please install all the requirements | tee /dev/kmsg
exit 1
fi
if ! type -P "vde_switch" &>/dev/null; then
echo ${0}: vde2 does not seem to be installed | tee /dev/kmsg
echo ${0}: Please install all the requirements | tee /dev/kmsg
exit 1
fi
# ----
# Make sure an IP address is assigned to the interface
# ----
HOSTIPANDMASK=`ip addr show dev ${DEVICE} | grep inet | head -1 | cut -f 6 -d " "`
if [ -z "${HOSTIPANDMASK}" ]; then
echo ${0}: ${DEVICE} has no IP address | tee /dev/kmsg
echo ${0}: Exiting for ${DEVICE} | tee /dev/kmsg
# We exit with normal status because if this script is invoked from
# if-up.d it is invoked multiple times, sometimes with no IP
# on DEVICE, which is OK.
exit 0
fi
echo ${0}: ${DEVICE} address and netmask ${HOSTIPANDMASK} | tee /dev/kmsg
# ---
# All checks passed; do not allow repeat invokations from here on
# ---
if test -r "/run/bridge-tap-vde-setup-lock"; then
echo ${0}: Already set up for adapter `cat /run/bridge-tap-vde-setup-lock` | tee /dev/kmsg
exit 0
else
echo ${0}: ${DEVICE} address and netmask ${HOSTIPANDMASK} > /run/bridge-tap-vde-setup-lock
fi
HOSTIP=`echo ${HOSTIPANDMASK}|cut -f 1 -d "/"`
HOSTNETMASK=`echo ${HOSTIPANDMASK}|cut -f 2 -d "/"`
HOSTBCASTADDR=`ip addr show dev ${DEVICE} | grep inet | head -1 | cut -f 8 -d " "`
HOSTDEFAULTGATEWAY=`route -n | grep ^0.0.0.0 | gawk -- '{ print $2 }'`
NETWORK=`ipcalc $HOSTIP/$HOSTNETMASK | grep Network | cut -f 2 -d ":" | cut -f 1 -d "/" | tr -d '[:space:]'`
echo ${0}: ---- GATHERED INFORMATION ----- | tee /dev/kmsg
echo ${0}: NETWORK INTERFACE=${DEVICE} | tee /dev/kmsg
echo ${0}: HOSTIP=$HOSTIP HOSTNETMASK=$HOSTNETMASK | tee /dev/kmsg
echo ${0}: NETWORK=$NETWORK HOSTBCASTADDR=$HOSTBCASTADDR HOSTDEFAULTGATEWAY=$HOSTDEFAULTGATEWAY | tee /dev/kmsg
echo ${0}: ------------------------------- | tee /dev/kmsg
# ---
# set up for Hercules IBM S/390 emulator which uses TUN interface not TAP
# ---
# Enable IPv4 packet forwarding
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.proxy_arp=1
# Make sure firewall is stopped and disabled (one of the following should work
# if a firewall is installed, otherwise these will produce ignorable errors ...
systemctl stop firewalld
systemctl disable firewalld
ufw disable
# Flush and clear iptables
iptables-restore -v --wait 2 << IPTABLES-RULES
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT
IPTABLES-RULES
# ---
# end set up for Hercules IBM S/390 emulator which uses TUN interface not TAP
# ---
# ---
# Create a TAP network interface for tap/pcap hungry emulators
# ---
ip tuntap add inettap0 mode tap user ${LOCALUSER}
# ---
# Also create a VDE switch with TAP plugs for use by simuators
# ---
vde_switch -t vde-ip-tap0 -s /tmp/vde-ip.ctl -m 666 --mgmt /tmp/vde-ip.mgmt --mgmtmode 666 --daemon # spare plug
vde_plug2tap -s /tmp/vde-ip.ctl -m 666 -d vde-ip-tap1 # AlphaServer ES40
#vde_plug2tap -s /tmp/vde-ip.ctl -m 666 -d vde-ip-tap2 # spare plug
#vde_plug2tap -s /tmp/vde-ip.ctl -m 666 -d vde-ip-tap3 # spare plug
# Create a Bridge
ip link add name br-ip type bridge
brctl stp br-ip on
# Bridge the NIC ${DEVICE}, the TAP device and VDE Switch TAP0 plug
ip link set ${DEVICE} master br-ip
ip link set inettap0 master br-ip
ip link set vde-ip-tap0 master br-ip
# Remove obsolete default route and move the IP address from ${DEVICE} to
# the bridge
ip route delete default via $HOSTDEFAULTGATEWAY dev ${DEVICE}
ip addr flush dev ${DEVICE}
ip addr add ${HOSTIPANDMASK} broadcast $HOSTBCASTADDR dev br-ip
# Bring everything back up
ip link set dev inettap0 up
ip link set vde-ip-tap0 up
ip link set vde-ip-tap1 up
#ip link set vde-ip-tap2 up
#ip link set vde-ip-tap3 up
#...
ip link set dev br-ip up
# Reset the default route to via the bridge interface which now has the IP
ip route add default via $HOSTDEFAULTGATEWAY dev br-ip
echo ${0}: ---- NETWORK RECONFIGURED, WAITING TO SETTLE DOWN ---- | tee /dev/kmsg
sleep 15
sync;sync;sync
echo ${0}: ---- AFTER BRIDGE AND TAP ---- | tee /dev/kmsg
ip addr | tee /dev/kmsg
echo ${0}: --- ROUTE --- | tee /dev/kmsg
route -n | tee /dev/kmsg
echo ${0}: --- BRIDGE --- | tee /dev/kmsg
brctl show | tee /dev/kmsg
echo ${0}: --- IPTABLES --- | tee /dev/kmsg
iptables -L | tee /dev/kmsg
echo ${0}: --- PING TEST --- | tee /dev/kmsg
PINGOK=0
for i in {1..15}
do
ping -c 1 -w 5 google.com | tee /dev/kmsg
if [ "$?" -eq 0 ]; then
PINGOK=1
echo ${0}: Internet becomes reachable on ping try $i | tee /dev/kmsg
break
else
echo ${0}: Internet unreachable on ping try $i | tee /dev/kmsg
sleep 1
fi
done
if [ "${PINGOK}" -eq 0 ]; then
echo ${0}: WARNING Cannot reach the internet or DNS issue | tee /dev/kmsg
fi
# --
# We can now attach simulators
# --
sync;sync;sync
echo ${0}: Normal Exit | tee /dev/kmsg
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment