#!/bin/sh set -Ceu case "${1:-}:${2:-}" in "bridge:"|"direct:"|"bridge:"|"direct:"|"bridge:"|"direct:") mode="${1}" ;; *) echo "usage: ${0##*/} bridge|direct" exit 1 ;; esac func="${2:-}" xtrace=$(set -o | grep --silent 'xtrace .*on' && printf "%s" "-x" || :) dir="hairpin.reproduce" me="${0}" [ -s "${me}" ] || me=$(which "${me}") [ x"$(id -u)" = x"0" ] || exec sudo "http_proxy=${http_proxy:-}" "${SHELL}" ${xtrace} "${me}" "$@" ipld() { ! ip link show | egrep --silent "^[0-9]+: ${1}: " || ip link delete dev "${1}" } cleanup() { set +e ipld hp-rt0-host ipld hp-rt1-host ipld hp-lan-host ipld hp-bridge ipld hp-internet rm -rf "${dir}.lan" "${dir}.router" } boot() { [ -s "${dir}/${me##*/}" ] || { rm -rf "${dir}" debootstrap --arch=amd64 --verbose --variant=minbase --include=iproute2,iptables,iputils-ping jessie "${dir}" } cp "${0}" "${dir}" chmod a+rx "${dir}/${me##/}" rm -rf "${dir}.router" "${dir}.lan" cp -al "${dir}" "${dir}.router" cp -al "${dir}" "${dir}.lan" trap cleanup 0 1 2 15 ip link add name hp-rt0-host type veth peer name hp-rt0-client ip link add name hp-rt1-host type veth peer name hp-rt1-client ip link add name hp-lan-host type veth peer name hp-lan-client ip link add name hp-bridge type bridge ip link set dev hp-rt0-host master hp-bridge ip link set dev hp-rt1-host master hp-bridge ip link set up hp-rt0-host ip link set up hp-rt1-host ip link set dev hp-lan-host master hp-bridge ip link set up hp-lan-host ip addr add dev hp-bridge 10.99.99.98/30 ip link set up dev hp-bridge ip link add name hp-internet type dummy ip addr add dev hp-internet 10.99.99.90/30 ip link set up dev hp-internet echo 1 >|/proc/sys/net/ipv4/ip_forward [ -z "${xtrace}" ] || ip addr show [ -z "${xtrace}" ] || ip route show [ -z "${xtrace}" ] || ping -c 1 -n 10.99.99.90 [ -z "${xtrace}" ] || echo ================================================ systemd-nspawn \ --directory="${dir}.router" \ --network-interface="hp-rt0-client" \ --network-interface="hp-rt1-client" \ --quiet \ sh ${xtrace} /${me##*/} "${mode}" "" & sleep 2 systemd-nspawn \ --directory="${dir}.lan" \ --network-interface="hp-lan-client" \ --quiet \ sh ${xtrace} /${me##*/} "${mode}" "" wait } router() { ip link add name br0 type bridge case "${mode}" in bridge) if=br0 ip link set dev hp-rt0-client master "${if}" ;; direct) if=hp-rt0-client ;; esac ip link set dev hp-rt1-client master br0 ip link set up dev br0 ip addr add dev "${if}" 10.99.99.97/30 ip addr add dev "${if}" 10.91.91.1/24 ip link set up dev hp-rt0-client ip link set up dev hp-rt1-client ip route add dev "${if}" default via 10.99.99.98 iptables -t nat -A POSTROUTING -s 10.91.91.0/24 -j MASQUERADE echo 1 >|/proc/sys/net/ipv4/ip_forward [ -z "${xtrace}" ] || ip addr show [ -z "${xtrace}" ] || ip route show [ -z "${xtrace}" ] || iptables -t nat -L POSTROUTING --numeric --line-numbers sleep 6 } lan() { ip addr add dev hp-lan-client 10.91.91.129/24 ip link set up dev hp-lan-client ip route add dev hp-lan-client default via 10.91.91.1 [ -z "${xtrace}" ] || ip addr show [ -z "${xtrace}" ] || ip route show ping -c 1 -n 10.99.99.90 || : } case "${func}" in "") boot;; "") lan;; "") router;; esac