When VPN routes are shared between different VPNs (or VRFs) for example,
the RDs assigned for each VRF can differ from others, but the same RT
should be used. In this case, the duplicated IP unicast routes can be
selected as the best path because VPN prefix "<RD>:<Prefix>" is
different and GoBGP calculates the best path on the global table
context. For example,
$ gobgp vrf add 1 rd 1:1 rt both 1:1
$ gobgp global rib -a vpnv4 add 10.0.0.0/24 label 0 rd 1:1 rt 1:1
$ gobgp global rib -a vpnv4 add 10.0.0.0/24 label 0 rd 2:2 rt 1:1
$ gobgp global rib -a vpnv4
Network Labels Next Hop AS_PATH Age Attrs
*> 1:1:10.0.0.0/24 [0] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [1:1]}]
*> 2:2:10.0.0.0/24 [0] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [1:1]}]
$ gobgp vrf 1 rib -a ipv4
Network Next Hop AS_PATH Age Attrs
10.0.0.0/24 0.0.0.0 00:00:10 [{Origin: ?}] <--- RD 1:1 on global
10.0.0.0/24 0.0.0.0 00:00:10 [{Origin: ?}] <--- RD 2:2 on global
The both of the above VRF routes are selected as the best path
unexpectedly.
This patch clones the received VPN path before installing the global
table and overwrites the RD of the cloned paths by the RD of the matched
VRFs. Also filters out the duplicated path on each VRF.
$ gobgp vrf add 1 rd 1:1 rt both 1:1
$ gobgp global rib -a vpnv4 add 10.0.0.0/24 label 0 rd 2:2 rt 1:1
$ gobgp global rib -a vpnv4
Network Labels Next Hop AS_PATH Age Attrs
*> 1:1:10.0.0.0/24 [0] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [1:1]}]
*> 2:2:10.0.0.0/24 [0] 0.0.0.0 00:00:00 [{Origin: ?} {Extcomms: [1:1]}]
$ gobgp vrf 1 rib -a ipv4
Network Next Hop AS_PATH Age Attrs
10.0.0.0/24 0.0.0.0 00:00:10 [{Origin: ?}]
$ gobgp global rib -a vpnv4 del 10.0.0.0/24 label 0 rd 2:2
$ gobgp vrf 1 rib -a ipv4
Network not in table
$ gobgp global rib -a vpnv4
Network not in table
Note: This feature only takes effect for only MPLS VPNv4/v6 routes and
does not have any for other address families which have RD on its NLRI
(e.g., EVPN, FlowSpec for VPN).
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>