Implement lxdbr0 support #971

Merged
merged 1 commit into from Aug 4, 2015
Jump to file or symbol
Failed to load files and symbols.
+228 −0
Split
View
@@ -0,0 +1,211 @@
+#!/bin/sh -
+
+distrosysconfdir="/etc/default/"
+varrun="/run/lxd/"
+varlib="/var/lib/lxd/lxd-bridge/"
+
+# lxdbr0 defaults to only setting up the standard IPv6 link-local network
+# to enable routable IPv4 and/or IPv6, please edit /etc/default/lxd
+
+# The values below are defaults
+USE_LXD_BRIDGE="true"
+LXD_BRIDGE="lxdbr0"
+LXD_CONFILE=""
+LXD_DOMAIN=""
+
+# IPv4
+LXD_IPV4_ADDR=""
+LXD_IPV4_NETMASK=""
+LXD_IPV4_NETWORK=""
+LXD_IPV4_DHCP_RANGE=""
+LXD_IPV4_DHCP_MAX=""
+LXD_IPV4_NAT="false"
+
+# IPv6
+LXD_IPV6_ADDR=""
+LXD_IPV6_MASK=""
+LXD_IPV6_NETWORK=""
+LXD_IPV6_NAT="false"
+LXD_IPV6_PROXY="true"
+
+[ ! -f $distrosysconfdir/lxd ] || . $distrosysconfdir/lxd
+
+use_iptables_lock="-w"
+iptables -w -L -n > /dev/null 2>&1 || use_iptables_lock=""
+
+_netmask2cidr ()
+{
+ # Assumes there's no "255." after a non-255 byte in the mask
+ local x=${1##*255.}
+ set -- 0^^^128^192^224^240^248^252^254^ $(( (${#1} - ${#x})*2 )) ${x%%.*}
+ x=${1%%$3*}
+ echo $(( $2 + (${#x}/4) ))
+}
+
+ifdown() {
+ ip addr flush dev $1
+ ip link set dev $1 down
+}
+
+ifup() {
+ ip addr add fe80::1/64 dev $1
+ if [ -n "$LXD_IPV4_MASK" ] && [ -n "$LXD_IPV4_ADDR" ]; then
+ MASK=`_netmask2cidr ${LXD_IPV4_MASK}`
+ CIDR_ADDR="${LXD_IPV4_ADDR}/${MASK}"
+ ip addr add ${CIDR_ADDR} dev $1
+ fi
+ ip link set dev $1 up
+}
+
+start() {
+ [ "x$USE_LXD_BRIDGE" = "xtrue" ] || { exit 0; }
+
+ [ ! -f "${varrun}/network_up" ] || { echo "lxd-bridge is already running"; exit 1; }
+
+ if [ -d /sys/class/net/${LXD_BRIDGE} ]; then
+ stop force || true
+ fi
+
+ FAILED=1
+
+ cleanup() {
+ set +e
+ if [ "$FAILED" = "1" ]; then
+ echo "Failed to setup lxd-bridge." >&2
+ stop force
+ fi
+ }
+
+ trap cleanup EXIT HUP INT TERM
+ set -e
+
+ # set up the lxd network
+ [ ! -d /sys/class/net/${LXD_BRIDGE} ] && ip link add dev ${LXD_BRIDGE} type bridge
+ echo 1 > /proc/sys/net/ipv4/ip_forward
+ echo 0 > /proc/sys/net/ipv6/conf/${LXD_BRIDGE}/accept_dad || true
+
+ # if we are run from systemd on a system with selinux enabled,
+ # the mkdir will create /run/lxd as init_var_run_t which dnsmasq
+ # can't write its pid into, so we restorecon it (to var_run_t)
+ if [ ! -d "${varrun}" ]; then
+ mkdir -p "${varrun}"
+ if which restorecon >/dev/null 2>&1; then
+ restorecon "${varrun}"
+ fi
+ fi
+
+ ifup ${LXD_BRIDGE} ${LXD_IPV4_ADDR} ${LXD_IPV4_MASK}
+
+ LXD_IPV4_ARG=""
+ if [ -n "$LXD_IPV4_ADDR" ] && [ -n "$LXD_IPV4_MASK" ] && [ -n "$LXD_IPV4_NETWORK" ]; then
+ if [ "$LXD_IPV4_NAT" = "true" ]; then
+ iptables $use_iptables_lock -t nat -A POSTROUTING -s ${LXD_IPV4_NETWORK} ! -d ${LXD_IPV4_NETWORK} -j MASQUERADE
+ fi
+ LXD_IPV4_ARG="--listen-address ${LXD_IPV4_ADDR} --dhcp-range ${LXD_IPV4_DHCP_RANGE} --dhcp-lease-max=${LXD_IPV4_DHCP_MAX}"
+ fi
+
+ LXD_IPV6_ARG=""
+ if [ -n "$LXD_IPV6_ADDR" ] && [ -n "$LXD_IPV6_MASK" ] && [ -n "$LXD_IPV6_NETWORK" ]; then
+ echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+ echo 0 > /proc/sys/net/ipv6/conf/${LXD_BRIDGE}/autoconf
+ ip -6 addr add dev ${LXD_BRIDGE} ${LXD_IPV6_ADDR}/${LXD_IPV6_MASK}
+ if [ "$LXD_IPV6_NAT" = "true" ]; then
+ ip6tables $use_iptables_lock -t nat -A POSTROUTING -s ${LXD_IPV6_NETWORK} ! -d ${LXD_IPV6_NETWORK} -j MASQUERADE
+ fi
+ LXD_IPV6_ARG="--dhcp-range=${LXD_IPV6_ADDR},ra-only --listen-address ${LXD_IPV6_ADDR}"
+ fi
+
+ iptables $use_iptables_lock -I INPUT -i ${LXD_BRIDGE} -p udp --dport 67 -j ACCEPT
+ iptables $use_iptables_lock -I INPUT -i ${LXD_BRIDGE} -p tcp --dport 67 -j ACCEPT
+ iptables $use_iptables_lock -I INPUT -i ${LXD_BRIDGE} -p udp --dport 53 -j ACCEPT
+ iptables $use_iptables_lock -I INPUT -i ${LXD_BRIDGE} -p tcp --dport 53 -j ACCEPT
+ iptables $use_iptables_lock -I FORWARD -i ${LXD_BRIDGE} -j ACCEPT
+ iptables $use_iptables_lock -I FORWARD -o ${LXD_BRIDGE} -j ACCEPT
+ iptables $use_iptables_lock -t mangle -A POSTROUTING -o ${LXD_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
+
+ LXD_DOMAIN_ARG=""
+ if [ -n "$LXD_DOMAIN" ]; then
+ LXD_DOMAIN_ARG="-s $LXD_DOMAIN -S /$LXD_DOMAIN/"
+ fi
+
+ LXD_CONFILE_ARG=""
+ if [ -n "$LXD_CONFILE" ]; then
+ LXD_CONFILE_ARG="--conf-file=${LXD_CONFILE}"
+ fi
+
+ # https://lists.linuxcontainers.org/pipermail/lxc-devel/2014-October/010561.html
+ for DNSMASQ_USER in lxd-dnsmasq dnsmasq nobody
+ do
+ if getent passwd ${DNSMASQ_USER} >/dev/null; then
+ break
+ fi
+ done
+
+ dnsmasq $LXD_CONFILE_ARG $LXD_DOMAIN_ARG -u ${DNSMASQ_USER} --strict-order --bind-interfaces --pid-file="${varrun}"/dnsmasq.pid --dhcp-no-override --except-interface=lo --interface=${LXD_BRIDGE} --dhcp-leasefile="${varlib}"/misc/dnsmasq.${LXD_BRIDGE}.leases --dhcp-authoritative $LXD_IPV4_ARG $LXD_IPV6_ARG || cleanup
+
+ if [ "$LXD_IPV6_PROXY" = "true" ]; then
+ lxd-bridge-proxy -addr="[fe80::1%${LXD_BRIDGE}]:3128" &
+ PID=$!
+ echo ${PID} > "${varrun}"/proxy.pid
+ fi
+
+ touch "${varrun}"/network_up
+ FAILED=0
+}
+
+stop() {
+ [ "x$USE_LXD_BRIDGE" = "xtrue" ] || { exit 0; }
+
+ [ -f "${varrun}/network_up" ] || [ "$1" = "force" ] || { echo "lxd-bridge isn't running"; exit 1; }
+
+ if [ -d /sys/class/net/${LXD_BRIDGE} ]; then
+ ifdown ${LXD_BRIDGE}
+ iptables $use_iptables_lock -D INPUT -i ${LXD_BRIDGE} -p udp --dport 67 -j ACCEPT
+ iptables $use_iptables_lock -D INPUT -i ${LXD_BRIDGE} -p tcp --dport 67 -j ACCEPT
+ iptables $use_iptables_lock -D INPUT -i ${LXD_BRIDGE} -p udp --dport 53 -j ACCEPT
+ iptables $use_iptables_lock -D INPUT -i ${LXD_BRIDGE} -p tcp --dport 53 -j ACCEPT
+ iptables $use_iptables_lock -D FORWARD -i ${LXD_BRIDGE} -j ACCEPT
+ iptables $use_iptables_lock -D FORWARD -o ${LXD_BRIDGE} -j ACCEPT
+ iptables $use_iptables_lock -t mangle -D POSTROUTING -o ${LXD_BRIDGE} -p udp -m udp --dport 68 -j CHECKSUM --checksum-fill
+
+ if [ -n "$LXD_IPV4_NETWORK" ] && [ "$LXD_IPV4_NAT" = "true" ]; then
+ iptables $use_iptables_lock -t nat -D POSTROUTING -s ${LXD_IPV4_NETWORK} ! -d ${LXD_IPV4_NETWORK} -j MASQUERADE
+ fi
+
+ if [ -n "$LXD_IPV6_NETWORK" ] && [ "$LXD_IPV6_NAT" = "true" ]; then
+ ip6tables $use_iptables_lock -t nat -D POSTROUTING -s ${LXD_IPV6_NETWORK} ! -d ${LXD_IPV6_NETWORK} -j MASQUERADE
+ fi
+
+ pid=`cat "${varrun}"/dnsmasq.pid 2>/dev/null` && kill -9 $pid
+ rm -f "${varrun}"/dnsmasq.pid
+
+ pid=`cat "${varrun}"/proxy.pid 2>/dev/null` && kill -9 $pid
+ rm -f "${varrun}"/proxy.pid
+ # if $LXD_BRIDGE has attached interfaces, don't destroy the bridge
+ ls /sys/class/net/${LXD_BRIDGE}/brif/* > /dev/null 2>&1 || ip link delete ${LXD_BRIDGE}
+ fi
+
+ rm -f "${varrun}"/network_up
+}
+
+# See how we were called.
+case "$1" in
+ start)
+ start
+ ;;
+
+ stop)
+ stop
+ ;;
+
+ restart|reload|force-reload)
+ $0 stop
+ $0 start
+ ;;
+
+ *)
+ echo "Usage: $0 {start|stop|restart|reload|force-reload}"
+ exit 2
+esac
+
+exit $?
@@ -0,0 +1,17 @@
+package main
+
+import (
+ "flag"
+ "log"
+ "net/http"
+
+ "github.com/elazarl/goproxy"
+)
+
+func main() {
+ addr := flag.String("addr", "[fe80::1%lxdbr0]:3128", "proxy listen address")
+ flag.Parse()
+
+ proxy := goproxy.NewProxyHttpServer()
+ log.Fatal(http.ListenAndServe(*addr, proxy))
+}