Last active
March 20, 2024 20:52
-
-
Save thomas-maurice/b07dca00695f952775a5e99fe2aad8f7 to your computer and use it in GitHub Desktop.
Setup the openwrt networks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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