]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix interface on leaks from network statement
authorLouis Scalbert <louis.scalbert@6wind.com>
Mon, 25 Apr 2022 13:14:49 +0000 (15:14 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Thu, 1 Feb 2024 09:21:43 +0000 (10:21 +0100)
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>
bgpd/bgp_mplsvpn.c

index 32436861f4f21aa8c5a6749a47965e278b9761a1..0982a4dee100b258132ed9c764c3fbf0af0068ea 100644 (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