#!/bin/sh

netdevices=$(ip -o link | wc -l)

if [ "${netdevices}" -gt 1 ]; then
	# There always is loopback; anything else is probably hardware
	echo "--- Spawning in network namespace to protect environment"
	exec unshare -n "$0"
fi

ip link set dev lo up # lots of stuff breaks without loopback

./fix-vrf-rules.sh # fix ip rule setup. try disabling this line to see what happens.

echo "--- Create 'blue' VRF and link with a veth pair to it"
ip link add name blue type vrf table 10
ip link set dev blue up
ip link add name v1 type veth peer v2
ip link set dev v2 vrf blue up
ip link set dev v1 up
ip address add 192.0.2.1/24 dev v1
ip address add 2001:db8::1/64 dev v1
ip address add 192.0.2.2/24 dev v2
ip address add 2001:db8::2/64 dev v2

# add "loopback" addresses in both VRFs; in VRF the "loopback" interface is the VRF interface itself
ip address add 198.51.100.1/32 dev lo
ip address add 2001:db8:1::1/128 dev lo
ip address add 198.51.100.2/32 dev blue
ip address add 2001:db8:1::2/128 dev blue

# don't look in other routing tables if we can't find anything in vrf
# we do this with an "pref 1001 l3mdev unreachable" rule instead for all VRFs.
#ip -4 route add vrf blue unreachable default metric 4278198272
#ip -6 route add vrf blue unreachable default metric 4278198272

echo "--- Waiting for IPv6 to start"
sleep 1

echo
echo "--- Lookup VRF blue addresses from global VRF"
ip route get 2001:db8::2
ip route get 192.0.2.2
echo "--- Run some test pings (that should work)"
ping -c5 -i0.1 -w2 2001:db8::2
ping -c5 -i0.1 -w2 192.0.2.2

echo
echo "--- Lookup stuff that shouldn't be reachable from the VRF"
# this seems to find the local entries from the default vrf unless explicit unreachable routes/rules are present
ip route get 2001:db8:1::1 vrf blue
ip route get 198.51.100.1 vrf blue

echo "--- Ping stuff that shouldn't be reachable from the VRF"
# although the response should be routable, this doesn't work (even as the lookups above find
# entries!...)
ping -c5 -i0.1 -Iv2 -w2 2001:db8:1::1
ping -c5 -i0.1 -Iv2 -w2 198.51.100.1

echo
echo "--- Route 'loopbacks' between VRFs"

## route leaks for "loopback" addresses (on lo/blue)
## doesn't work well for IPv4 (only with vrf as "output" device, not any member interface).
#ip -4 route add 198.51.100.2 dev blue src 198.51.100.1
#ip -4 route add 198.51.100.1 dev lo src 198.51.100.2 vrf blue
## doesn't work for IPv6 at all.
##ip -6 route add 2001:db8:1::2 dev blue src 2001:db8:1::1 table main
##ip -6 route add 2001:db8:1::1 dev lo src 2001:db8:1::2 table 10

# use transfer link instead
ip -4 route add 198.51.100.2 via 192.0.2.2
ip -4 route add 198.51.100.1 via 192.0.2.1 vrf blue
ip -6 route add 2001:db8:1::2 via 2001:db8::2
ip -6 route add 2001:db8:1::1 via 2001:db8::1 vrf blue

echo
echo "--- Now should be reachable from the VRF"
# this seems to find the local entries from the default vrf
ip route get 2001:db8:1::1 vrf blue
ip route get 198.51.100.1 vrf blue

echo "--- Ping stuff that is now reachable from the VRF"
# as an alternative you can try "-Iv2" or `ip vrf exec blue ping ...`
ping -c5 -i0.1 -Iblue -w2 2001:db8:1::1
ping -c5 -i0.1 -Iblue -w2 198.51.100.1


echo
echo "--- Have fun checking it out yourself (exit the shell to close the experiment)."
export debian_chroot="vrf-demo"
exec bash -i
