From 3d8fd1d37730e717b50e8706371de3574bfecc3a Mon Sep 17 00:00:00 2001 From: Enke Chen Date: Wed, 8 Jan 2025 09:12:56 -0800 Subject: [PATCH 1/2] Revert "bgpd: Reinstall aggregated routes if using route-maps and it was changed" This reverts commit ee1986f1b5ae6b94b446b12e1b77cc30d8f5f46d. The fix is incomplete, and is no longer needed with the fix that applies the route-map for an aggregate and then compares the attribute. Signed-off-by: Enke Chen (cherry picked from commit b0f96fc247803b8d36593e0e70c17827a381dd58) --- bgpd/bgp_route.c | 6 ++---- bgpd/bgp_route.h | 1 - bgpd/bgp_routemap.c | 1 - 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 35c9937a060d..e68b721a9084 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7385,9 +7385,8 @@ static void bgp_aggregate_install( * If the aggregate information has not changed * no need to re-install it again. */ - if (pi && (!aggregate->rmap.changed && - bgp_aggregate_info_same(pi, origin, aspath, community, - ecommunity, lcommunity))) { + if (pi && bgp_aggregate_info_same(pi, origin, aspath, community, + ecommunity, lcommunity)) { bgp_dest_unlock_node(dest); if (aspath) @@ -8397,7 +8396,6 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi, aggregate->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap); aggregate->rmap.map = route_map_lookup_by_name(rmap); - aggregate->rmap.changed = true; route_map_counter_increment(aggregate->rmap.map); } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 2929c75df76f..c00ff0d2efad 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -435,7 +435,6 @@ struct bgp_aggregate { struct { char *name; struct route_map *map; - bool changed; } rmap; /* Suppress-count. */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index fe6faffa6e28..df2abad4a5d0 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -4604,7 +4604,6 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name, route_map_counter_increment(map); aggregate->rmap.map = map; - aggregate->rmap.changed = true; matched = true; } From 964421b85f59547bfd82cb80bf2bca53e7e53a35 Mon Sep 17 00:00:00 2001 From: Enke Chen Date: Wed, 8 Jan 2025 17:34:29 -0800 Subject: [PATCH 2/2] bgpd: apply route-map for aggregate before attribute comparison Currently when re-evaluating an aggregate route, the full attribute of the aggregate route is not compared with the existing one in the BGP table. That can result in unnecessary churns (un-install and then install) of the aggregate route when a more specific route is added or deleted, or when the route-map for the aggregate changes. The churn would impact route installation and route advertisement. The fix is to apply the route-map for the aggregate first and then compare the attribute. Here is an example of the churn: debug bgp aggregate prefix 5.5.5.0/24 ! route-map set-comm permit 10 set community 65004:200 ! router bgp 65001 address-family ipv4 unicast redistribute static aggregate-address 5.5.5.0/24 route-map set-comm ! Step 1: ip route 5.5.5.1/32 Null0 Jan 8 10:28:49 enke-vm1 bgpd[285786]: [J7PXJ-A7YA2] bgp_aggregate_install: aggregate 5.5.5.0/24, count 1 Jan 8 10:28:49 enke-vm1 bgpd[285786]: [Y444T-HEVNG] aggregate 5.5.5.0/24: installed Step 2: ip route 5.5.5.2/32 Null0 Jan 8 10:29:03 enke-vm1 bgpd[285786]: [J7PXJ-A7YA2] bgp_aggregate_install: aggregate 5.5.5.0/24, count 2 Jan 8 10:29:03 enke-vm1 bgpd[285786]: [S2EH5-EQSX6] aggregate 5.5.5.0/24: existing, removed Jan 8 10:29:03 enke-vm1 bgpd[285786]: [Y444T-HEVNG] aggregate 5.5.5.0/24: installed --- Signed-off-by: Enke Chen (cherry picked from commit 43c567014180b61c497104539077d013984d428e) # Conflicts: # bgpd/bgp_route.c --- bgpd/bgp_route.c | 77 ++++++++++++++++++++++-------------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index e68b721a9084..af7894b3ad39 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7315,44 +7315,6 @@ static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate, return false; } -static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin, - struct aspath *aspath, - struct community *comm, - struct ecommunity *ecomm, - struct lcommunity *lcomm) -{ - static struct aspath *ae = NULL; - enum asnotation_mode asnotation; - - asnotation = bgp_get_asnotation(NULL); - - if (!aspath) - ae = aspath_empty(asnotation); - - if (!pi) - return false; - - if (origin != pi->attr->origin) - return false; - - if (!aspath_cmp(pi->attr->aspath, (aspath) ? aspath : ae)) - return false; - - if (!community_cmp(bgp_attr_get_community(pi->attr), comm)) - return false; - - if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm)) - return false; - - if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm)) - return false; - - if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID)) - return false; - - return true; -} - static void bgp_aggregate_install( struct bgp *bgp, afi_t afi, safi_t safi, const struct prefix *p, uint8_t origin, struct aspath *aspath, struct community *community, @@ -7361,14 +7323,14 @@ static void bgp_aggregate_install( { struct bgp_dest *dest; struct bgp_table *table; - struct bgp_path_info *pi, *orig, *new; + struct bgp_path_info *pi, *new; struct attr *attr; table = bgp->rib[afi][safi]; dest = bgp_node_get(table, p); - for (orig = pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) + 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_AGGREGATE) break; @@ -7385,10 +7347,21 @@ static void bgp_aggregate_install( * If the aggregate information has not changed * no need to re-install it again. */ - if (pi && bgp_aggregate_info_same(pi, origin, aspath, community, - ecommunity, lcommunity)) { + attr = bgp_attr_aggregate_intern(bgp, origin, aspath, community, ecommunity, + lcommunity, aggregate, atomic_aggregate, p); + if (!attr) { + aspath_free(aspath); + community_free(&community); + ecommunity_free(&ecommunity); + lcommunity_free(&lcommunity); bgp_dest_unlock_node(dest); + bgp_aggregate_delete(bgp, p, afi, safi, aggregate); + if (debug) + zlog_debug("%s: %pFX null attribute", __func__, p); + return; + } +<<<<<<< HEAD if (aspath) aspath_free(aspath); if (community) @@ -7398,6 +7371,13 @@ static void bgp_aggregate_install( if (lcommunity) lcommunity_free(&lcommunity); +======= + if (pi && CHECK_FLAG(pi->flags, BGP_PATH_VALID) && attrhash_cmp(pi->attr, attr)) { + bgp_attr_unintern(&attr); + bgp_dest_unlock_node(dest); + if (debug) + zlog_debug(" aggregate %pFX: duplicate", p); +>>>>>>> 43c567014 (bgpd: apply route-map for aggregate before attribute comparison) return; } @@ -7407,6 +7387,7 @@ static void bgp_aggregate_install( if (pi) bgp_path_info_delete(dest, pi); +<<<<<<< HEAD attr = bgp_attr_aggregate_intern( bgp, origin, aspath, community, ecommunity, lcommunity, aggregate, atomic_aggregate, p); @@ -7423,6 +7404,8 @@ static void bgp_aggregate_install( p); return; } +======= +>>>>>>> 43c567014 (bgpd: apply route-map for aggregate before attribute comparison) new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self, attr, dest); @@ -7433,6 +7416,7 @@ static void bgp_aggregate_install( bgp_process(bgp, dest, afi, safi); } else { uninstall_aggregate_route: +<<<<<<< HEAD for (pi = orig; pi; pi = pi->next) if (pi->peer == bgp->peer_self && pi->type == ZEBRA_ROUTE_BGP @@ -7444,6 +7428,15 @@ static void bgp_aggregate_install( bgp_path_info_delete(dest, pi); bgp_process(bgp, dest, afi, safi); } +======= + /* Withdraw the aggregate route from routing table. */ + if (pi) { + bgp_path_info_delete(dest, pi); + bgp_process(bgp, dest, pi, afi, safi); + if (debug) + zlog_debug(" aggregate %pFX: uninstall", p); + } +>>>>>>> 43c567014 (bgpd: apply route-map for aggregate before attribute comparison) } bgp_dest_unlock_node(dest);