summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_aspath.c
diff options
context:
space:
mode:
authorvdhingra <vdhingra@vmware.com>2019-08-19 09:50:56 +0200
committervdhingra <vdhingra@vmware.com>2019-09-24 11:54:19 +0200
commitef51a7d8d4082f6465d50989b101431168faf5a4 (patch)
tree2161449271401c8844d481e35833336104362d5d /bgpd/bgp_aspath.c
parentbgpd : route agg. with ecomm attribute is consuming lot of cycles. (diff)
downloadfrr-ef51a7d8d4082f6465d50989b101431168faf5a4.tar.xz
frr-ef51a7d8d4082f6465d50989b101431168faf5a4.zip
bgpd : route agg. with aspath attribute is consuming lot of cycles.
While configuring aggregate route prepare the hash table first, then prepare the aggregated aspath value just like lcomm, ecomm and standard community. Signed-off-by: vishaldhingra<vdhingra@vmware.com>
Diffstat (limited to 'bgpd/bgp_aspath.c')
-rw-r--r--bgpd/bgp_aspath.c83
1 files changed, 62 insertions, 21 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index f5652b07c..6caeb7ca1 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -2114,15 +2114,12 @@ static void *bgp_aggr_aspath_hash_alloc(void *p)
static void bgp_aggr_aspath_prepare(struct hash_backet *hb, void *arg)
{
- struct aspath *asmerge = NULL;
struct aspath *hb_aspath = hb->data;
struct aspath **aggr_aspath = arg;
- if (*aggr_aspath) {
- asmerge = aspath_aggregate(*aggr_aspath, hb_aspath);
- aspath_free(*aggr_aspath);
- *aggr_aspath = asmerge;
- } else
+ if (*aggr_aspath)
+ *aggr_aspath = aspath_aggregate(*aggr_aspath, hb_aspath);
+ else
*aggr_aspath = aspath_dup(hb_aspath);
}
@@ -2136,6 +2133,15 @@ void bgp_aggr_aspath_remove(void *arg)
void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
struct aspath *aspath)
{
+ bgp_compute_aggregate_aspath_hash(aggregate, aspath);
+
+ bgp_compute_aggregate_aspath_val(aggregate);
+
+}
+
+void bgp_compute_aggregate_aspath_hash(struct bgp_aggregate *aggregate,
+ struct aspath *aspath)
+{
struct aspath *aggr_aspath = NULL;
if ((aggregate == NULL) || (aspath == NULL))
@@ -2154,17 +2160,29 @@ void bgp_compute_aggregate_aspath(struct bgp_aggregate *aggregate,
*/
aggr_aspath = hash_get(aggregate->aspath_hash, aspath,
bgp_aggr_aspath_hash_alloc);
+ }
- /* Compute aggregate's as-path.
- */
+ /* Increment reference counter.
+ */
+ aggr_aspath->refcnt++;
+}
+
+void bgp_compute_aggregate_aspath_val(struct bgp_aggregate *aggregate)
+{
+ if (aggregate == NULL)
+ return;
+ /* Re-compute aggregate's as-path.
+ */
+ if (aggregate->aspath) {
+ aspath_free(aggregate->aspath);
+ aggregate->aspath = NULL;
+ }
+ if (aggregate->aspath_hash
+ && aggregate->aspath_hash->count) {
hash_iterate(aggregate->aspath_hash,
bgp_aggr_aspath_prepare,
&aggregate->aspath);
}
-
- /* Increment refernce counter.
- */
- aggr_aspath->refcnt++;
}
void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
@@ -2173,10 +2191,9 @@ void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
struct aspath *aggr_aspath = NULL;
struct aspath *ret_aspath = NULL;
- if ((aggregate == NULL) || (aspath == NULL))
- return;
-
- if (aggregate->aspath_hash == NULL)
+ if ((!aggregate)
+ || (!aggregate->aspath_hash)
+ || (!aspath))
return;
/* Look-up the aspath in the hash.
@@ -2189,17 +2206,41 @@ void bgp_remove_aspath_from_aggregate(struct bgp_aggregate *aggregate,
ret_aspath = hash_release(aggregate->aspath_hash,
aggr_aspath);
aspath_free(ret_aspath);
+ ret_aspath = NULL;
/* Remove aggregate's old as-path.
*/
aspath_free(aggregate->aspath);
aggregate->aspath = NULL;
- /* Compute aggregate's as-path.
- */
- hash_iterate(aggregate->aspath_hash,
- bgp_aggr_aspath_prepare,
- &aggregate->aspath);
+ bgp_compute_aggregate_aspath_val(aggregate);
}
}
}
+
+void bgp_remove_aspath_from_aggregate_hash(struct bgp_aggregate *aggregate,
+ struct aspath *aspath)
+{
+ struct aspath *aggr_aspath = NULL;
+ struct aspath *ret_aspath = NULL;
+
+ if ((!aggregate)
+ || (!aggregate->aspath_hash)
+ || (!aspath))
+ return;
+
+ /* Look-up the aspath in the hash.
+ */
+ aggr_aspath = bgp_aggr_aspath_lookup(aggregate, aspath);
+ if (aggr_aspath) {
+ aggr_aspath->refcnt--;
+
+ if (aggr_aspath->refcnt == 0) {
+ ret_aspath = hash_release(aggregate->aspath_hash,
+ aggr_aspath);
+ aspath_free(ret_aspath);
+ ret_aspath = NULL;
+ }
+ }
+}
+