From bf15730267628e2d47ad78cc58895bc375d1b400 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 3 Mar 2025 17:11:33 +0100 Subject: [PATCH] bgpd: fix syncs suppressed prefixes in VPN environments By using the summary-only option for aggregated prefixes, the suppressed prefixes are however exported as VPN prefixes, whereas they should not. > r1# show bgp vrf vrf1 ipv4 > [..] > *> 172.31.1.0/24 0.0.0.0 0 32768 ? > s> 172.31.1.1/32 0.0.0.0 0 32768 ? > s> 172.31.1.2/32 0.0.0.0 0 32768 ? > s> 172.31.1.3/32 0.0.0.0 0 32768 ? > [..] > r1# > > r1# show bgp ipv4 vpn > [..] > *> 172.31.1.0/24 0.0.0.0@4< 0 32768 ? > UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5 > *> 172.31.1.1/32 0.0.0.0@4< 0 32768 ? > UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5 > *> 172.31.1.2/32 0.0.0.0@4< 0 32768 ? > UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5 > *> 172.31.1.3/32 0.0.0.0@4< 0 32768 ? > UN=0.0.0.0 EC{52:100} label=101 type=bgp, subtype=5 > [..] > r1# Signed-off-by: Philippe Guibert --- bgpd/bgp_mplsvpn.c | 8 ++++++++ bgpd/bgp_route.c | 50 +++++++++++++++++++++++++++++++++++++++------- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 8057b3d56a..d1d4c5af68 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1696,6 +1696,14 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp, /* to */ return; } + /* Aggregate-address suppress check. */ + if (bgp_path_suppressed(path_vrf)) { + if (debug) + zlog_debug("%s: %s skipping: suppressed path will not be exported", + __func__, from_bgp->name); + return; + } + /* shallow copy */ static_attr = *path_vrf->attr; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 910fa97493..f1a6ad8c94 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8135,14 +8135,25 @@ void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate, /* We are toggling suppression back. */ if (suppress) { /* Suppress route if not suppressed already. */ - if (aggr_suppress_path(aggregate, pi)) + if (aggr_suppress_path(aggregate, pi)) { bgp_process(bgp, dest, pi, afi, safi); + if (SAFI_UNICAST == safi && + (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, + pi); + } continue; } /* Install route if there is no more suppression. */ - if (aggr_unsuppress_path(aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) { bgp_process(bgp, dest, pi, afi, safi); + if (SAFI_UNICAST == safi && + (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi); + } } } bgp_dest_unlock_node(top); @@ -8273,8 +8284,14 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, */ if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) { - if (aggr_suppress_path(aggregate, pi)) + if (aggr_suppress_path(aggregate, pi)) { bgp_process(bgp, dest, pi, afi, safi); + if (SAFI_UNICAST == safi && + (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, + pi); + } } /* @@ -8289,8 +8306,14 @@ bool bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi, if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) && aggr_suppress_map_test(bgp, aggregate, pi)) { - if (aggr_suppress_path(aggregate, pi)) + if (aggr_suppress_path(aggregate, pi)) { bgp_process(bgp, dest, pi, afi, safi); + if (SAFI_UNICAST == safi && + (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp, + pi); + } } aggregate->count++; @@ -8438,8 +8461,13 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi, */ if (pi->extra && pi->extra->aggr_suppressors && listcount(pi->extra->aggr_suppressors)) { - if (aggr_unsuppress_path(aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) { bgp_process(bgp, dest, pi, afi, safi); + if (SAFI_UNICAST == safi && + (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi); + } } if (aggregate->count > 0) @@ -8645,13 +8673,21 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi, return; if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate)) - if (aggr_unsuppress_path(aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) { bgp_process(bgp, pi->net, pi, afi, safi); + if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi); + } if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate) && aggr_suppress_map_test(bgp, aggregate, pi)) - if (aggr_unsuppress_path(aggregate, pi)) + if (aggr_unsuppress_path(aggregate, pi)) { bgp_process(bgp, pi->net, pi, afi, safi); + if (SAFI_UNICAST == safi && (bgp->inst_type == BGP_INSTANCE_TYPE_VRF || + bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)) + vpn_leak_from_vrf_update(bgp_get_default(), bgp, pi); + } /* * This must be called after `summary`, `suppress-map` check to avoid -- 2.39.5