Skip to content

Instantly share code, notes, and snippets.

@thomas-maurice
Last active March 20, 2024 20:52
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thomas-maurice/b07dca00695f952775a5e99fe2aad8f7 to your computer and use it in GitHub Desktop.
Save thomas-maurice/b07dca00695f952775a5e99fe2aad8f7 to your computer and use it in GitHub Desktop.
Setup the openwrt networks
#!/bin/bash
set -eo pipefail
# List of bridges to create space delimited
bridges="sw-r0-eth0 sw-r0-eth1 sw-r0-eth2 sw-r0-eth3"
# Veths peirs to create with the following format, space delimited
# <veth dev 1>[|options]:<veth dev 1>[|options]
# where options are a comma delimited key=values pair
# options: master=<master bridge> or dhcp
veths="veth0:dhcp|veth1:master=sw-r0-eth1"
#wan_bridge="$(echo ${bridges} | cut -d\ -f 1)"
wan_bridge="virbr0"
action=$1
function _help {
cat<<EOF
${0} usage: Creates the necessary bridges and interfaces necessary for the virtualbox infrastructure
${0} <start|stop|dhcp|stop-dhcp|show-wan|help>
- start: creates the bridges and veths, and sets them up
- stop: tears everything down
- dhcp: runs dhclient on the dhcp interfaces
- stop-dhcp: kill running dhcp processes
- show-wan: shows the wan interface
- help: displays this help message
EOF
}
if [ -z "${action}" ]; then
_help
exit 1
fi;
wan_interface=$(ip r | grep default | grep dev | sed -e 's/^.*dev \([^ ]*\) .*$/\1/')
if [ -z "${wan_interface}" ]; then
echo "could not determine the wan interface"
exit 1
fi;
function _start {
for bridge in ${bridges}; do
if ! ip link show "${bridge}" >/dev/null 2>&1; then
sudo ip link add "${bridge}" type bridge stp_state 1
fi;
done;
for veth in ${veths}; do
veth0=$(echo "${veth}" | cut -f1 -d\| | cut -f1 -d:)
veth1=$(echo "${veth}" | cut -f2 -d\| | cut -f1 -d:)
if [ -z "${veth0}" ] || [ -z "${veth1}" ]; then
echo "invalid veth interface spec ${veth}, should be like veth0:veth1:br-master"
exit 1
fi;
if ! ip link show "${veth0}" >/dev/null 2>&1 || ! ip link show "${veth1}" >/dev/null 2>&1; then
echo "(re)-creating the pair ${veth}"
sudo ip link del "${veth0}" 2>/dev/null || true
sudo ip link del "${veth1}" 2>/dev/null || true
sudo ip link add "${veth0}" type veth peer name "${veth1}"
fi;
sudo ip link set up dev "${veth0}"
sudo ip link set up dev "${veth1}"
for cfgVeth in $(echo "${veth}" | tr '|' ' '); do
local vethName
vethName="$(echo "${cfgVeth}" | cut -d: -f1)"
echo "configuring veth ${vethName}"
for opt in $(echo "${cfgVeth}" | cut -d: -f2 | tr ',' ' '); do
if ! echo "${cfgVeth}" | grep -q ":"; then
continue
fi;
case ${opt} in
dhcp)
if [ -n "${DO_DHCP}" ]; then
echo " - running dhclient"
sudo dhclient -4 -v "${vethName}"
echo "removing default routes set by dhclient"
route=$(ip route | grep default | grep "${vethName}")
if [ -n "${route}" ]; then
# shellcheck disable=SC2086
sudo ip route del ${route}
fi;
else
echo " - DHCP would be enabled by ${0} dhcp"
fi;
;;
master=*)
local masterBridge
masterBridge="$(echo "${opt}" | cut -d= -f2)"
echo " - setting ${vethName} as a port of ${masterBridge}"
if ! ip link show "${masterBridge}" >/dev/null 2>&1; then
echo "bridge ${masterBridge} does not exist"
exit 1
fi;
sudo ip link set master "${masterBridge}" dev "${vethName}"
;;
*)
echo "Invalid option ${opt}"
;;
esac
done;
done;
done;
for bridge in ${bridges}; do
sudo ip link set up dev "${bridge}"
done;
}
function _dhcp {
DO_DHCP=1 _start
}
function _stop {
for veth in ${veths}; do
veth0=$(echo "${veth}" | cut -f1 -d\| | cut -f1 -d:)
veth1=$(echo "${veth}" | cut -f2 -d\| | cut -f1 -d:)
if [ -z "${veth0}" ] || [ -z "${veth1}" ]; then
echo "Invalid veth interface spec ${veth}, should be like veth0:<options>|veth1:<options>"
exit 1
fi;
sudo ip link del "${veth0}" || true
sudo ip link del "${veth1}" || true
done;
for bridge in ${bridges}; do
sudo ip link del "${bridge}" || true
done;
}
function _stop_dhcp {
for veth in ${veths}; do
veth0=$(echo "${veth}" | cut -f1 -d\| | cut -f1 -d:)
veth1=$(echo "${veth}" | cut -f2 -d\| | cut -f1 -d:)
if [ -z "${veth0}" ] || [ -z "${veth1}" ]; then
echo "Invalid veth interface spec ${veth}, should be like veth0:<options>|veth1:<options>"
exit 1
fi;
# shellcheck disable=SC2009
pid="$(ps faux | grep 'dhclient -4 -v veth0' |grep -v grep | awk '{ print $2 }')"
if [ -n "${pid}" ]; then
echo "killing dhclient with pid ${pid}"
sudo kill "${pid}"
fi;
done;
}
function _iptables {
sudo iptables -I FORWARD -i ${wan_bridge} -o "${wan_interface}" -j ACCEPT
sudo iptables -I FORWARD -o ${wan_bridge} -i "${wan_interface}" -j ACCEPT
sudo iptables -t nat -I POSTROUTING -o "${wan_interface}" -j MASQUERADE
}
case ${action} in
start)
_start
exit 0
;;
stop)
_stop
_stop_dhcp
exit 0
;;
iptables)
_iptables
exit 0
;;
dhcp)
_dhcp
exit 0
;;
stop-dhcp)
_stop_dhcp
exit 0
;;
show-wan)
echo "${wan_interface}"
exit 0
;;
help)
_help
exit 0
;;
*)
echo "Unrecognised action ${action}"
exit 1
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment