86 lines
2.7 KiB
Bash
Executable File
86 lines
2.7 KiB
Bash
Executable File
#!/bin/bash
|
|
set -Eeuo pipefail
|
|
IFACE=$1
|
|
|
|
if [ ${#IFACE} -gt 14 ]; then
|
|
echo "interface name too long, mac 14 char: $IFACE"
|
|
exit 10
|
|
fi
|
|
|
|
source /etc/libvirt/hooks/$IFACE
|
|
|
|
### PUBLICMAC should always be set, keeping this for compatibility with libvirt.
|
|
### the MAC the VM has been assigned by qemu needs to be known here, but AFAIK libvirt doesn't support exporting env vars to ifup script, so this needs to be static on the public interface in qemu
|
|
### if this is not set correctly the routing in the VM won't work
|
|
: ${PUBLICMAC:=52:54:00:00:00:11}
|
|
###
|
|
|
|
maxprefixv6=56
|
|
maxprefixv4=25
|
|
|
|
if [ -z $IP ]; then
|
|
echo "got nothing back from the API"
|
|
exit 10
|
|
fi
|
|
|
|
eui64() {
|
|
local macaddr="$1"
|
|
printf "%02x%s" $(( 16#${macaddr:0:2} ^ 2#00000010 )) "${macaddr:2}" \
|
|
| sed -E -e 's/([0-9a-zA-Z]{2})*/0x\0|/g' \
|
|
| tr -d ':\n' \
|
|
| xargs -d '|' \
|
|
printf "fe80::%02x%02x:%02xff:fe%02x:%02x%02x"
|
|
}
|
|
|
|
gwmac() {
|
|
### libvirt replaces the first octet in the mac with fe, so may as well stick to that for consistency,
|
|
### the only thing that matters is that we know and it's predictable from within the VM
|
|
local macaddr="$1"
|
|
printf "%02x%s" "0xfe" "${macaddr:2}"
|
|
}
|
|
|
|
ip link set ${IFACE} address $(gwmac $PUBLICMAC) up
|
|
arp -i ${IFACE} -s 169.254.0.1 ${PUBLICMAC}
|
|
sysctl -w net.ipv4.conf.${IFACE/./\/}.arp_ignore=8
|
|
|
|
IFS=',' read -ra IPS <<< "$IP"
|
|
for IP in "${IPS[@]}"; do
|
|
if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/([0-9]{2})$ ]]; then ### we got a IPv4 prefix < maxprefixv4
|
|
if [ ${BASH_REMATCH[1]} -lt $maxprefixv4 ]; then
|
|
echo "we don't support such a big customer net?"
|
|
continue
|
|
fi
|
|
|
|
if [ ${BASH_REMATCH[1]} -gt 32 ]; then
|
|
echo "prefix is invalid"
|
|
continue
|
|
fi
|
|
|
|
echo "we got IPv4 with prefix ${BASH_REMATCH[0]}"
|
|
ip route add ${IP} via 169.254.0.1 dev ${IFACE} onlink metric 1
|
|
ip route add ${IP} dev ${IFACE} metric 255
|
|
|
|
elif [[ $IP =~ ^2604:bbc0:[0-9,a-f,:]{1,444}/([0-9]{2,3})$ ]]; then ### we got a PIv6 prefix < masprefixv6
|
|
|
|
if [ ${BASH_REMATCH[1]} -lt $maxprefixv6 ]; then
|
|
echo "we don't support such a big customer net?"
|
|
continue
|
|
fi
|
|
|
|
if [ ${BASH_REMATCH[1]} -gt 128 ]; then
|
|
echo "prefix is invalid"
|
|
continue
|
|
fi
|
|
|
|
echo "we got IPv6 with prefix ${BASH_REMATCH[0]}"
|
|
ip route add ${IP} dev ${IFACE} via $(eui64 $PUBLICMAC)
|
|
|
|
elif [[ $IP =~ ^\ *$ ]]; then
|
|
echo "we just got an empty string. so not gonna do anything. probably due to splitting the comma"
|
|
|
|
else
|
|
echo "Unable to detect with what prefix I'm working with"
|
|
exit 10
|
|
fi
|
|
done
|