]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: copy source vrf ASN to leaked route and block loops
authorDon Slice <dslice@nvidia.com>
Wed, 9 Jun 2021 20:50:20 +0000 (16:50 -0400)
committerDonatas Abraitis <donatas@opensourcerouting.org>
Wed, 18 Sep 2024 15:03:10 +0000 (18:03 +0300)
When we leak routes and are using a different ASN in the
source vrf from the target vrf, it's possible we could
create loops because of an incomplete as-path (missing
the source vrf ASN). This fix adds the source vrf ASN and
stops the importing of a BGP prefix that has the target
ASN in the as-path in the source vrf.

Signed-off-by: Don Slice <dslice@nvidia.com>
bgpd/bgp_mplsvpn.c

index 9db73a1bd1e273f1fca7c84d551bf96df6e959ad..4e5a4150d1f6047c745ec0855a8f2f073803e828 100644 (file)
@@ -34,6 +34,7 @@
 #include "bgpd/bgp_nht.h"
 #include "bgpd/bgp_evpn.h"
 #include "bgpd/bgp_memory.h"
+#include "bgpd/bgp_aspath.h"
 
 #ifdef ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -2156,6 +2157,7 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
        struct bgp *src_vrf;
        struct interface *ifp = NULL;
        char rd_buf[RD_ADDRSTRLEN];
+       struct aspath *new_aspath;
 
        int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
 
@@ -2213,6 +2215,32 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
                return;
        }
 
+       bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL);
+
+       /* Check if leaked route has our asn. If so, don't import it. */
+       if (aspath_loop_check(path_vpn->attr->aspath, to_bgp->as)) {
+               for (bpi = bgp_dest_get_bgp_path_info(bn); bpi;
+                    bpi = bpi->next) {
+                       if (bpi->extra && bpi->extra->vrfleak &&
+                           (struct bgp_path_info *)bpi->extra->vrfleak->parent ==
+                                   path_vpn) {
+                               break;
+                       }
+               }
+
+               if (bpi) {
+                       if (debug)
+                               zlog_debug("%s: blocking import of %p, as-path match",
+                                          __func__, bpi);
+                       bgp_aggregate_decrement(to_bgp, p, bpi, afi, safi);
+                       bgp_path_info_delete(bn, bpi);
+                       bgp_process(to_bgp, bn, bpi, afi, safi);
+               }
+               bgp_dest_unlock_node(bn);
+
+               return;
+       }
+
        if (debug)
                zlog_debug("%s: updating RD %s, %pFX to %s", __func__, rd_buf,
                           p, to_bgp->name_pretty);
@@ -2365,6 +2393,20 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */
                        nexthop_self_flag = 0;
        }
 
+       /*
+        * if the asn values are different, copy the asn of the source vrf
+        * into the entry before importing. This helps with as-path loop
+        * detection
+        */
+       if (path_vpn->extra && path_vpn->extra->vrfleak &&
+           (to_bgp->as != path_vpn->extra->vrfleak->bgp_orig->as)) {
+               new_aspath = aspath_dup(static_attr.aspath);
+               new_aspath =
+                       aspath_add_seq(new_aspath,
+                                      path_vpn->extra->vrfleak->bgp_orig->as);
+               static_attr.aspath = new_aspath;
+       }
+
        new_attr = bgp_attr_intern(&static_attr);
        bgp_attr_flush(&static_attr);