]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: fix prefix VRF leaking with 'network import-check' (4/5)
authorLouis Scalbert <louis.scalbert@6wind.com>
Fri, 29 Apr 2022 12:26:04 +0000 (14:26 +0200)
committerLouis Scalbert <louis.scalbert@6wind.com>
Fri, 16 Dec 2022 13:52:47 +0000 (14:52 +0100)
If 'network import-check' is defined on the source BGP session, prefixes
that are stated in the network command cannot be leaked to the other
VRFs BGP table even if they are present in the origin VRF RIB if the
'rt import' statement is defined after the 'network <prefix>' ones.

When a prefix nexthop is updated, update the prefix route leaking. The
current state of nexthop validation is now stored in the attributes of
the bgp path info. Attributes are compared with the previous ones at
route leaking update so that a nexthop validation change now triggers
the update of destination VRF BGP table.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_mplsvpn.c
bgpd/bgp_nht.c

index 337a82b9456ce93d0424eacf0c99ea0416da6433..47775e141201792b324c01bbfb0fc803ff3dc4e8 100644 (file)
@@ -866,6 +866,7 @@ bool attrhash_cmp(const void *p1, const void *p2)
                    && attr1->df_pref == attr2->df_pref
                    && attr1->df_alg == attr2->df_alg
                    && attr1->nh_ifindex == attr2->nh_ifindex
+                   && attr1->nh_flag == attr2->nh_flag
                    && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex
                    && attr1->distance == attr2->distance
                    && srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn)
index a34da1a6de7258990201d1b7f77f908cb09bd065..575b10541e2a69e87863958f82000f22c8f6ee76 100644 (file)
@@ -170,6 +170,9 @@ struct attr {
        uint32_t med;
        uint32_t local_pref;
        ifindex_t nh_ifindex;
+       uint8_t nh_flag;
+
+#define BGP_ATTR_NH_VALID 0x01
 
        /* Path origin attribute */
        uint8_t origin;
index 84fbfbe25988756126b2d2f6af41c730a5a6e124..42ae3562c27619bfc500813f131ecf744c6f0ad7 100644 (file)
@@ -1878,6 +1878,7 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
        uint32_t num_labels = 0;
        int nexthop_self_flag = 1;
        struct bgp_path_info *bpi_ultimate = NULL;
+       struct bgp_path_info *bpi;
        int origin_local = 0;
        struct bgp *src_vrf;
 
@@ -1960,6 +1961,18 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
 
        community_strip_accept_own(&static_attr);
 
+       for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) {
+               if (bpi->extra && bpi->extra->parent == path_vpn)
+                       break;
+       }
+
+       if (bpi &&
+           leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi,
+                                     path_vpn, bpi, src_vrf, p, debug))
+               SET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID);
+       else
+               UNSET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID);
+
        /*
         * Nexthop: stash and clear
         *
index 78482aeb40335dc376408e27b39359a1da27f24a..d7707a8c0c057aa29fffa31036f639bc216d409d 100644 (file)
@@ -46,6 +46,7 @@
 #include "bgpd/bgp_flowspec_util.h"
 #include "bgpd/bgp_evpn.h"
 #include "bgpd/bgp_rd.h"
+#include "bgpd/bgp_mplsvpn.h"
 
 extern struct zclient *zclient;
 
@@ -834,10 +835,13 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
 {
        struct bgp_nexthop_cache_head *tree = NULL;
        struct bgp_nexthop_cache *bnc_nhc, *bnc_import;
+       struct bgp_path_info *pi;
+       struct bgp_dest *dest;
        struct bgp *bgp;
        struct prefix match;
        struct zapi_route nhr;
        afi_t afi;
+       safi_t safi;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
        if (!bgp) {
@@ -868,9 +872,23 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
        tree = &bgp->import_check_table[afi];
 
        bnc_import = bnc_find(tree, &match, nhr.srte_color, 0);
-       if (bnc_import)
+       if (bnc_import) {
                bgp_process_nexthop_update(bnc_import, &nhr, true);
-       else if (BGP_DEBUG(nht, NHT))
+
+               safi = nhr.safi;
+               if (bgp->rib[afi][safi]) {
+                       dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi,
+                                               &match, NULL);
+
+                       for (pi = bgp_dest_get_bgp_path_info(dest); pi;
+                            pi = pi->next)
+                               if (pi->peer == bgp->peer_self &&
+                                   pi->type == ZEBRA_ROUTE_BGP &&
+                                   pi->sub_type == BGP_ROUTE_STATIC)
+                                       vpn_leak_from_vrf_update(
+                                               bgp_get_default(), bgp, pi);
+               }
+       } else if (BGP_DEBUG(nht, NHT))
                zlog_debug(
                        "parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check",
                        &nhr.prefix, nhr.srte_color, bgp->name_pretty);