# +-------+     +----------+   +----------+   +-------+
# | h0    |     |    r0    |   |    r1    |   |    h1 |
# |    v00+-----+v00    v01+---+v10    v11+---+v11    |
# |       |     |          |   |          |   |       |
# +-------+     +----------+   +----------+   +-------+
#                  |    <===gre===>    |
#                  | gre01       gre10 |
#                  |                   |
#          vrf_r0t | vrf_r0c   vrf_r1c | vrf_r1t
#         (tenant)        (core)         (tenant)
#
# h0_v00 10.0.0.2/24     r0_v00 10.0.0.1/24
# r0_v01 1.1.1.1/24      r1_v10 1.1.1.2/24
# h1_v11 11.0.0.2/24     r1_v11 11.0.0.1/24
# gre01 2.2.2.1/30       gre10 2.2.2.2/30

ip netns add h0
ip netns add r0
ip netns add h1
ip netns add r1

ip link add h0_v00 type veth peer name r0_v00
ip link set h0_v00 netns h0
ip link set r0_v00 netns r0
ip link add r0_v01 type veth peer name r1_v10
ip link set r0_v01 netns r0
ip link set r1_v10 netns r1
ip link add r1_v11 type veth peer name h1_v11
ip link set r1_v11 netns r1
ip link set h1_v11 netns h1

ip netns exec r0 ip link add vrf_r0t type vrf table 10
ip netns exec r0 ip addr add 127.0.0.1/8 dev vrf_r0t
ip netns exec r0 ip link set vrf_r0t up
ip netns exec r0 ip link add vrf_r0c type vrf table 100
ip netns exec r0 ip addr add 127.0.0.1/8 dev vrf_r0c
ip netns exec r0 ip link set vrf_r0c up
ip netns exec r1 ip link add vrf_r1t type vrf table 10
ip netns exec r1 ip addr add 127.0.0.1/8 dev vrf_r1t
ip netns exec r1 ip link set vrf_r1t up
ip netns exec r1 ip link add vrf_r1c type vrf table 100
ip netns exec r1 ip addr add 127.0.0.1/8 dev vrf_r1c
ip netns exec r1 ip link set vrf_r1c up

ip netns exec r0 ip link set dev r0_v00 master vrf_r0t
ip netns exec r0 ip link set dev r0_v01 master vrf_r0c
ip netns exec r1 ip link set dev r1_v11 master vrf_r1t
ip netns exec r1 ip link set dev r1_v10 master vrf_r1c

ip netns exec h0 ip addr add 10.0.0.2/24 dev h0_v00
ip netns exec r0 ip addr add 10.0.0.1/24 dev r0_v00
ip netns exec r0 ip addr add 1.1.1.1/24 dev r0_v01
ip netns exec r1 ip addr add 1.1.1.2/24 dev r1_v10
ip netns exec r1 ip addr add 11.0.0.1/24 dev r1_v11
ip netns exec h1 ip addr add 11.0.0.2/24 dev h1_v11

ip netns exec r0 ip tunnel add gre01 mode gre local 1.1.1.1 remote 1.1.1.2 dev vrf_r0c
ip netns exec r0 ip link set dev gre01 master vrf_r0c
ip netns exec r0 ip addr add 2.2.2.1/24 dev gre01
ip netns exec r1 ip tunnel add gre10 mode gre local 1.1.1.2 remote 1.1.1.1 dev vrf_r1c
ip netns exec r1 ip link set dev gre10 master vrf_r1c
ip netns exec r1 ip addr add 2.2.2.2/24 dev gre10

ip netns exec h0 ip link set dev h0_v00 up
ip netns exec r0 ip link set dev r0_v00 up
ip netns exec r0 ip link set dev r0_v01 up
ip netns exec r0 ip link set dev gre01 up
ip netns exec r1 ip link set dev r1_v10 up
ip netns exec r1 ip link set dev r1_v11 up
ip netns exec r1 ip link set dev gre10 up
ip netns exec h1 ip link set dev h1_v11 up

ip netns exec r0 sysctl -w net.ipv4.ip_forward=1 > /dev/null
ip netns exec r1 sysctl -w net.ipv4.ip_forward=1 > /dev/null

ip netns exec h0 ip route add default via 10.0.0.1
ip netns exec h1 ip route add default via 11.0.0.1

ip netns exec r0 ip route add unreachable default metric 8192 table 10
ip netns exec r0 ip route add unreachable default metric 8192 table 100
ip netns exec r1 ip route add unreachable default metric 8192 table 10
ip netns exec r1 ip route add unreachable default metric 8192 table 100

ip netns exec r0 ip route add 11.0.0.0/24 via 2.2.2.2 dev gre01 table 10
ip netns exec r1 ip route add 10.0.0.0/24 via 2.2.2.1 dev gre10 table 10

# do this to match the config on the target platform
sudo ip netns exec r0 ip rule delete from all lookup local
sudo ip netns exec r0 ip rule add from all lookup local pref 32765
sudo ip netns exec r1 ip rule delete from all lookup local
sudo ip netns exec r1 ip rule add from all lookup local pref 32765

# packets out of the core vrf tunnel are leak-routed to the tenant vrf
ip netns exec r0 ip rule add iif gre01 table 10 pref 999
ip netns exec r1 ip rule add iif gre10 table 10 pref 999
