bgpd: fix interface on leaks from network statement

Leaked routes from prefixes defined with 'network <prefix>' are inactive
because they have no valid nexthop interface.

> vrf r1-cust1
>  ip route 172.16.29.0/24 192.168.1.2
> router bgp 5227 vrf r1-cust1
>  no bgp network import-check
>  address-family ipv4 unicast
>   network 172.16.29.0/24
>   rd vpn export 10:1
>   rt vpn import 52:100
>   rt vpn export 52:101
>   export vpn
>   import vpn
>  exit-address-family
> exit
> !
> router bgp 5227 vrf r1-cust4
>  bgp router-id 192.168.1.1
> !
>  address-family ipv4 unicast
>   network 192.0.2/24
>   rd vpn export 10:1
>   rt vpn import 52:101
>   rt vpn export 52:100
>   export vpn
>   import vpn
>  exit-address-family
> exit

Extract from the routing table:

> VRF r1-cust1:
> S>* 172.16.29.0/24 [1/0] via 192.168.1.2, r1-eth4, weight 1, 00:47:53
>
> VRF r1-cust4:
> B   172.16.29.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:03:40

Routes imported through the "network" command, as opposed to those
redistributed from the routing table, do not associate with any specific
interface.

When leaking prefix from other VRFs, if the route was imported from the
network statement (ie. static sub-type), set nh_ifindex to the index of
the VRF master interface of the incoming BGP instance.

The result is:

> VRF r1-cust4:
> B>* 172.16.29.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2022-04-25 15:14:49 +02:00
parent a2caf2b5e1
commit 067fbab4e4

View File

@ -2209,12 +2209,21 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
/* If the path has accept-own community and the source VRF
* is valid, reset next-hop to self, to allow importing own
* routes between different VRFs on the same node.
* Set the nh ifindex to VRF's interface, not the real interface.
*/
if (src_bgp)
subgroup_announce_reset_nhop(nhfamily, &static_attr);
bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
/* The nh ifindex may not be defined (when the route is
* imported from the network statement => BGP_ROUTE_STATIC)
* or to the real interface.
* Rewrite the nh ifindex to VRF's interface.
* Let the kernel to decide with double lookup the real next-hop
* interface when installing the route.
*/
if (src_bgp) {
subgroup_announce_reset_nhop(nhfamily, &static_attr);
if (src_bgp || bpi_ultimate->sub_type == BGP_ROUTE_STATIC) {
ifp = if_get_vrf_loopback(src_vrf->vrf_id);
if (ifp)
static_attr.nh_ifindex = ifp->ifindex;
@ -2300,9 +2309,6 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
*/
if (!CHECK_FLAG(to_bgp->af_flags[afi][safi],
BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
/* work back to original route */
bpi_ultimate = bgp_get_imported_bpi_ultimate(path_vpn);
/*
* if original route was unicast,
* then it did not arrive over vpn