diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-06-06 19:13:00 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-06-06 19:13:00 +0200 |
commit | eaaf8adb7c4c736702e5789b3c4f0048001a843f (patch) | |
tree | 3e94c32a2ce7e5ce4f8ead36b5850ae92afb634d /bgpd/bgp_route.c | |
parent | bgpd: Move bgp_aggregate_delete to a better location (diff) | |
download | frr-eaaf8adb7c4c736702e5789b3c4f0048001a843f.tar.xz frr-eaaf8adb7c4c736702e5789b3c4f0048001a843f.zip |
bgpd: Allow bgp to know when to actually add/delete agg route
The aggregated route was being sent in updates to peers every
time a route changed that we were aggregating. Modify
the code such that we only send aggregated route updates
if we actually have something different to tell the peer.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to '')
-rw-r--r-- | bgpd/bgp_route.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ed71f4197..567805d91 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -5433,6 +5433,26 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate) XFREE(MTYPE_BGP_AGGREGATE, aggregate); } +static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath, + struct community *comm) +{ + static struct aspath *ae = NULL; + + if (!ae) + ae = aspath_empty(); + + if (!ri) + return 0; + + if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae)) + return 0; + + if (!community_cmp(ri->attr->community, comm)) + return 0; + + return 1; +} + static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi, struct prefix *p, uint8_t origin, struct aspath *aspath, @@ -5447,7 +5467,34 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi, table = bgp->rib[afi][safi]; rn = bgp_node_get(table, p); + + for (ri = rn->info; ri; ri = ri->next) + if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP + && ri->sub_type == BGP_ROUTE_AGGREGATE) + break; + if (aggregate->count > 0) { + /* + * If the aggregate information has not changed + * no need to re-install it again. + */ + if (bgp_aggregate_info_same(rn->info, aspath, community)) { + bgp_unlock_node(rn); + + if (aspath) + aspath_free(aspath); + if (community) + community_free(community); + + return; + } + + /* + * Mark the old as unusable + */ + if (ri) + bgp_info_delete(rn, ri); + new = info_make( ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self, bgp_attr_aggregate_intern(bgp, origin, aspath, @@ -5682,8 +5729,6 @@ void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p, if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen) { bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate); - bgp_aggregate_install(bgp, afi, safi, &rn->p, 0, NULL, - NULL, 0, aggregate); bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL, aggregate); } @@ -5714,8 +5759,6 @@ void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p, if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen) { bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate); - bgp_aggregate_install(bgp, afi, safi, &rn->p, 0, NULL, - NULL, 0, aggregate); bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del, aggregate); } |