#!/bin/bash

###
# Create veth vpubN-vpubN+1 pair and assign public IP for it for any public IP on any bridge
###

IPCMD="/usr/sbin/ip"
ROUTECMD="/usr/sbin/route"
FIREWALL_CMD="/usr/bin/firewall-cmd"
FIREWALL_OFFLINE_CMD="/usr/bin/firewall-offline-cmd"
BR="$1"
DEVPREF="vpub"
declare -a FCMD=('ipv4 filter INPUT 0 -m tcp -p tcp -j ACCEPT --dport 22 -i' 'ipv4 filter INPUT 50 -j DROP -i')

function fcmd_rule() {
	$FIREWALL_CMD --permanent $* && $FIREWALL_CMD --reload || $FIREWALL_OFFLINE_CMD $*
}

echo $BR | grep -E ^br[0-9]+ > /dev/null 2>&1
# Skip non-bridges
[ $? -ne 0 ] && exit 0

if [ "x$2" = "xdown" ]; then
	# Other settings will be dropped automatically
	for d in `$IPCMD a l 2>/dev/null | grep "master $BR" | awk '{print $2}' | grep $DEVPREF | sed -e "s,:$,,g" -e "s,@.*,,g"`; do
		for f in "${FCMD[@]}"; do
			fcmd_rule --direct --remove-rule $f $d
		done
		$IPCMD l del $d
	done
fi

# Support only up and down
[ "x$2" != "xup" ] && exit 0

DEFGW=`$ROUTECMD -n 2>/dev/null | grep ^0.0.0.0 | awk '{print $2}'`

for IP in `$IPCMD a l $BR 2>/dev/null | grep inet | awk '{print $2}'`; do
	# Skip IPv6s
	echo $IP | grep ':' > /dev/null 2>&1
	[ $? -eq 0 ] && continue
	# Skip all private IPs
	[ "x${IP:0:3}" = "x10." -o "x${IP:0:8}" = "x192.168." ] && continue
	if [ "x${IP:0:4}" = "x172." ]; then
		SECN=`echo ${IP:4:3} | sed "s,\.,,g"`
		[ $SECN -ge 16 -o $SECN -le 31 ] && continue
	fi
	# Drop Public IP from BR
	$IPCMD a del $IP dev $BR
	# Get next veth num
	LASTN=`$IPCMD a l 2>/dev/null | grep -E '^[0-9]+:' | awk '{print $2}' | grep ^$DEVPREF | sort -u | tail -n 1 | sed -e "s,:$,,g" -e "s,^$DEVPREF,,g" -e "s,@.*,,g"`
	VPUB1=$DEVPREF$((LASTN+1))
	VPUB2=$DEVPREF$((LASTN+2))
	# Create veth pair
	$IPCMD l add dev $VPUB1 type veth peer name $VPUB2
	# Assign IP, put in bridge
	$IPCMD l set dev $VPUB1 up
	$IPCMD l set $VPUB1 master $BR
	$IPCMD a add $IP dev $VPUB2
	$IPCMD l set dev $VPUB2 up
	# Setup firewall - only ssh enabled
	for f in "${FCMD[@]}"; do
		fcmd_rule --direct --add-rule $f $VPUB2
	done
	# Fix default gateway if needed - do the simple check by first ip in range
	[ "x$DEFGW" = "x" ] && continue
	echo "import sys
from netaddr import IPNetwork, IPAddress

if IPAddress('$DEFGW') not in IPNetwork('$IP'):
    sys.exit(1)

sys.exit(0)
" | /usr/bin/python > /dev/null 2>&1
	[ $? -ne 0 ] && continue
	for cmd in del add; do
		$ROUTECMD $cmd default gw $DEFGW
	done
done

exit 0
