summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_mplsvpn.c
diff options
context:
space:
mode:
authorDon Slice <dslice@nvidia.com>2021-06-09 22:50:20 +0200
committerDonatas Abraitis <donatas@opensourcerouting.org>2024-09-18 17:03:10 +0200
commitd4426b62d221f4e15810dbe578de05df8991c991 (patch)
tree21945c280fefaebd37857658caae4cfa323c289e /bgpd/bgp_mplsvpn.c
parentbgpd: do not allow override ASN unless hidden or auto-created (diff)
downloadfrr-d4426b62d221f4e15810dbe578de05df8991c991.tar.xz
frr-d4426b62d221f4e15810dbe578de05df8991c991.zip
bgpd: copy source vrf ASN to leaked route and block loops
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>
Diffstat (limited to 'bgpd/bgp_mplsvpn.c')
-rw-r--r--bgpd/bgp_mplsvpn.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 9db73a1bd..4e5a4150d 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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);