summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2018-06-06 19:13:00 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2018-06-06 19:13:00 +0200
commiteaaf8adb7c4c736702e5789b3c4f0048001a843f (patch)
tree3e94c32a2ce7e5ce4f8ead36b5850ae92afb634d /bgpd/bgp_route.c
parentbgpd: Move bgp_aggregate_delete to a better location (diff)
downloadfrr-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.c51
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);
}