diff --git a/network/vif-qubes-nat.sh b/network/vif-qubes-nat.sh index 9833e45..2789d34 100755 --- a/network/vif-qubes-nat.sh +++ b/network/vif-qubes-nat.sh @@ -46,9 +46,12 @@ if test "$command" == online; then run ip link set "$netns_appvm_if" netns "$netns" # keep the same MAC as the real vif interface, so NetworkManager will still - # ignore it - run ip link add "$netns_netvm_if" type veth peer name "$netvm_if" address fe:ff:ff:ff:ff:ff - run ip link set "$netns_netvm_if" netns "$netns" + # ignore it. + # for the peer interface, make sure that it has the same MAC address + # as the actual VM, so that our neighbor entry works. + run ip link add name "$netns_netvm_if" address "$mac" type veth \ + peer name "$netvm_if" address fe:ff:ff:ff:ff:ff + run ip link set dev "$netns_netvm_if" netns "$netns" netns ip6tables -t raw -I PREROUTING -j DROP netns ip6tables -P INPUT DROP @@ -85,6 +88,7 @@ if test "$command" == online; then netns iptables -t nat -I POSTROUTING -o "$netns_appvm_if" -s "$netvm_dns2_ip" -j SNAT --to-source "$appvm_dns2_ip" fi + netns ip neighbour add to "$appvm_ip" dev "$netns_appvm_if" lladdr "$mac" nud permanent netns ip addr add "$netvm_ip" dev "$netns_netvm_if" netns ip addr add "$appvm_gw_ip" dev "$netns_appvm_if" diff --git a/network/vif-route-qubes b/network/vif-route-qubes index 85881b7..1cf43d2 100755 --- a/network/vif-route-qubes +++ b/network/vif-route-qubes @@ -78,40 +78,6 @@ if [ "${ip}" ]; then 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) - echo 1 >"/proc/sys/net/ipv4/conf/${vif}/proxy_arp" - ipcmd='add' - iptables_cmd='-I PREROUTING 1' - cmdprefix='' - ipv6_disabled=$(cat /proc/sys/net/ipv6/conf/"${vif}"/disable_ipv6 || echo 1) - ;; - offline) - do_without_error ifdown "${vif}" - ipcmd='del' - iptables_cmd='-D PREROUTING' - cmdprefix='do_without_error' - # cleanup IPv6 config even if _now_ it is disabled - ipv6_disabled=0 - ;; -esac - readonly max_domid=32752 # if domid is 0 something is seriously wrong, so don’t check for that case @@ -130,6 +96,36 @@ if (( domid > max_domid )); then fi metric=$(( max_domid - domid )) +# shellcheck disable=SC2154 +case "$command" in + online) + echo 1 >"/proc/sys/net/ipv4/conf/${vif}/proxy_arp" + ipcmd='add' + iptables_cmd='-I PREROUTING 1' + cmdprefix='' + ipv6_disabled=$(cat /proc/sys/net/ipv6/conf/"${vif}"/disable_ipv6 || echo 1) + # without a MAC address we will fail later with a confusing error + mac=$(xenstore-read "backend/vif/$domid/$sub/mac") || exit 1 + ;; + offline) + do_without_error ifdown "${vif}" + ipcmd='del' + iptables_cmd='-D PREROUTING' + cmdprefix='do_without_error' + # cleanup IPv6 config even if _now_ it is disabled + ipv6_disabled=0 + ;; +esac + +# 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 source=network/vif-qubes-nat.sh + . "$dir/vif-qubes-nat.sh" +fi + # add anti-spoofing rules before enabling the interface if [ "${ip}" ]; then # If we’ve been given a list of IP addresses, then add routes from us to @@ -147,7 +143,6 @@ if [ "${ip}" ]; then "COMMIT" | \ ${cmdprefix} $ipt --noflush $ipt_arg if [[ "$command" = 'online' ]]; then - mac=$(xenstore-read "backend/vif/$domid/$sub/mac") && ip -- neighbour "${ipcmd}" to "${addr}" \ dev "${vif}" lladdr "$mac" nud permanent fi