On 5/27/19 2:34 AM, George Wilkie wrote: > On Sat, May 25, 2019 at 09:13:13AM -0600, David Ahern wrote: >>> Using a loopback doesn't work, e.g. if 10.1.1.0/24 was on a global >>> interface: >>> ip ro add vrf vrf-a 10.1.1.0/24 dev lo >> >> That works for MPLS when you exit the LSP and deliver locally, so it >> should work here as well. I'll take a look early next week. > > OK, thanks. > >> I would prefer to avoid it if possible. VRF route leaking for forwarding >> does not have the second lookup and that is the primary use case. VRL >> with local delivery is a 1-off use case and you could just easily argue >> that the connection should not rely on the leaked route. ie., the >> control plane is aware of both VRFs, and the userspace process could use >> the VRF-B path. >> > > Although it isn't always possible to change the userspace process - > may be running in a specific vrf by 'ip vrf exec' >
sure, but that is a design choice for the control plane. Effectively, you have this setup: { process } | | packet | +--------------+ +--------------+ | VRF A | | VRF B | | | | | | | <------ route to A | | +------+ | | +------+ | +---| ens1 |---+ +---| ens2 |---+ +------+ +------+ ^ | | packet ie., the process is potentially bound to VRF-A, and you want it handle packets from VRF-B and without binding to VRF-B. I already mentioned one solution that works well if the route is only used for forwarding (add a route to VRF-B using ens1 as the egress device) and a solution that works for local delivery (add route to VRF-B using vrf-A device to do a second lookup). you are correct that use of loopback here for default VRF does not work -- the lookup code gets confused because it is a forward path (as opposed to MPLS which is a local input). I found a couple of solutions that work for default VRF. Again, using namespaces to demonstrate within a single node. This is the base setup: ip li add vrf-b up type vrf table 2 ip route add vrf vrf-b unreachable default ip ru add pref 32765 from all lookup local ip ru del pref 0 ip netns add foo ip li add veth1 type veth peer name veth11 netns foo ip addr add dev veth1 10.200.1.1/24 ip li set veth1 vrf vrf-b up ip -netns foo li set veth11 up ip -netns foo addr add dev veth11 10.200.1.11/24 ip -netns foo ro add 10.200.2.0/24 via 10.200.1.1 ip netns add bar ip li add veth2 type veth peer name veth12 netns bar ip li set veth2 up ip addr add dev veth2 10.200.2.1/24 ip -netns bar li set veth12 up ip -netns bar addr add dev veth12 10.200.2.12/24 Cross VRF routing can be done with a veth pair, without addresses: ip li add xvrf1 type veth peer name xvrf2 ip li set xvrf1 up ip li set xvrf2 master vrf-b up ip ro add vrf vrf-b 10.200.2.0/24 dev xvrf2 ip ro add 10.200.1.0/24 dev vrf-b or with addresses: ip li add xvrf1 type veth peer name xvrf2 ip li set xvrf1 up ip addr add dev xvrf1 10.200.3.1/30 ip li set xvrf2 master vrf-b up ip addr add dev xvrf2 10.200.3.2/30 ip ro add vrf vrf-b 10.200.2.0/24 via 10.200.3.1 dev xvrf2 ip ro add 10.200.1.0/24 via 10.200.3.2 dev xvrf1 Yes, this does have a double FIB lookup - one in VRF-B and again in VRF-A, but I contend this is a design choice. Bind the process to VRF-B and it works with 1 lookup.