c281d6454f
If IPv6 gateway address provided by dom0 isn't a link local address, add a /128 route to it. Also, add this address on backend interfaces (vif*). This is to allow proper ICMP host unreachable packets forwarding - if gateway (address on vif* interface) have only fe80: address, it will be used as a source for ICMP reply. It will be properly delivered to the VM directly connected there (for example from sys-net to sys-firewall), but because of being link-local address, it will not be forwarded any further. This results timeouts if host doesn't have IPv6 connectivity.
124 lines
4.0 KiB
Bash
Executable File
124 lines
4.0 KiB
Bash
Executable File
#!/bin/bash
|
|
#============================================================================
|
|
# /etc/xen/vif-route-qubes
|
|
#
|
|
# Script for configuring a vif in routed mode.
|
|
# The hotplugging system will call this script if it is specified either in
|
|
# the device configuration given to Xend, or the default Xend configuration
|
|
# in /etc/xen/xend-config.sxp. If the script is specified in neither of those
|
|
# places, then vif-bridge is the default.
|
|
#
|
|
# Usage:
|
|
# vif-route (add|remove|online|offline)
|
|
#
|
|
# Environment vars:
|
|
# vif vif interface name (required).
|
|
# XENBUS_PATH path to this device's details in the XenStore (required).
|
|
#
|
|
# Read from the store:
|
|
# ip list of IP networks for the vif, space-separated (default given in
|
|
# this script).
|
|
#============================================================================
|
|
|
|
dir=$(dirname "$0")
|
|
# shellcheck disable=SC1091,SC1090
|
|
. "$dir/vif-common.sh"
|
|
|
|
#main_ip=$(dom0_ip)
|
|
lockfile=/var/run/xen-hotplug/vif-lock
|
|
|
|
# shellcheck disable=SC2154
|
|
if [ "${ip}" ]; then
|
|
# get first IPv4 and first IPv6
|
|
for addr in ${ip}; do
|
|
if [ -z "$ip4" ] && [[ "$addr" = *.* ]]; then
|
|
ip4="$addr"
|
|
elif [ -z "$ip6" ] && [[ "$addr" = *:* ]]; then
|
|
ip6="$addr"
|
|
fi
|
|
done
|
|
# IPs as seen by this VM
|
|
netvm_ip="$ip4"
|
|
netvm_gw_ip=$(qubesdb-read /qubes-netvm-gateway)
|
|
netvm_gw_ip6=$(qubesdb-read /qubes-netvm-gateway6 || :)
|
|
netvm_dns1_ip=$(qubesdb-read /qubes-netvm-primary-dns)
|
|
netvm_dns2_ip=$(qubesdb-read /qubes-netvm-secondary-dns)
|
|
|
|
back_ip="$netvm_gw_ip"
|
|
back_ip6="$netvm_gw_ip6"
|
|
|
|
# IPs as seen by the VM - if other than $netvm_ip
|
|
appvm_gw_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-gateway" 2>/dev/null || :)"
|
|
appvm_ip="$(qubesdb-read "/mapped-ip/$ip4/visible-ip" 2>/dev/null || :)"
|
|
fi
|
|
|
|
# Apply NAT if IP visible from the VM is different than the "real" one
|
|
# See vif-qubes-nat.sh for details
|
|
# XXX: supported only for the first IPv4 address, IPv6 is dropped if this
|
|
# feature is enabled
|
|
if [ -n "$appvm_ip" ] && [ -n "$appvm_gw_ip" ] && [ "$appvm_ip" != "$netvm_ip" ]; then
|
|
# shellcheck disable=SC2154
|
|
if test "$command" == online; then
|
|
# shellcheck disable=SC2154
|
|
echo 1 >"/proc/sys/net/ipv4/conf/${vif}/proxy_arp"
|
|
fi
|
|
|
|
# shellcheck source=network/vif-qubes-nat.sh
|
|
. "$dir/vif-qubes-nat.sh"
|
|
fi
|
|
|
|
# shellcheck disable=SC2154
|
|
case "$command" in
|
|
online)
|
|
ifconfig "${vif}" up
|
|
echo 1 >"/proc/sys/net/ipv4/conf/${vif}/proxy_arp"
|
|
ipcmd='add'
|
|
iptables_cmd='-I PREROUTING 1'
|
|
cmdprefix=''
|
|
;;
|
|
offline)
|
|
do_without_error ifdown "${vif}"
|
|
ipcmd='del'
|
|
iptables_cmd='-D PREROUTING'
|
|
cmdprefix='do_without_error'
|
|
;;
|
|
esac
|
|
|
|
domid=${vif/vif/}
|
|
domid=${domid/.*/}
|
|
# metric must be possitive, but prefer later interface
|
|
# 32752 is max XID aka domid
|
|
metric=$(( 32752 - domid ))
|
|
|
|
if [ "${ip}" ] ; then
|
|
# If we've been given a list of IP addresses, then add routes from dom0 to
|
|
# the guest using those addresses.
|
|
for addr in ${ip} ; do
|
|
${cmdprefix} ip route "${ipcmd}" "${addr}" dev "${vif}" metric "$metric"
|
|
if [[ "$addr" = *:* ]]; then
|
|
ipt=ip6tables-restore
|
|
else
|
|
ipt=iptables-restore
|
|
fi
|
|
echo -e "*raw\n$iptables_cmd -i ${vif} ! -s ${addr} -j DROP\nCOMMIT" | \
|
|
${cmdprefix} flock $lockfile $ipt --noflush
|
|
done
|
|
# if no IPv6 is assigned, block all IPv6 traffic on that interface
|
|
if ! [[ "$ip" = *:* ]]; then
|
|
echo -e "*raw\n$iptables_cmd -i ${vif} -j DROP\nCOMMIT" | \
|
|
${cmdprefix} flock $lockfile ip6tables-restore --noflush
|
|
fi
|
|
${cmdprefix} ip addr "${ipcmd}" "${back_ip}/32" dev "${vif}"
|
|
if [ "${back_ip6}" ] && [[ "${back_ip6}" != "fe80:"* ]]; then
|
|
${cmdprefix} ip addr "${ipcmd}" "${back_ip6}/128" dev "${vif}"
|
|
fi
|
|
fi
|
|
|
|
log debug "Successful vif-route-qubes $command for $vif."
|
|
if [ "$command" = "online" ]
|
|
then
|
|
# disable tx checksumming offload, apparently it doesn't work with our ancient qemu in stubdom
|
|
do_without_error ethtool -K "$vif" tx off
|
|
success
|
|
fi
|