summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-11-16 19:41:58 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-12-04 08:40:10 -0500
commit41647b79fb2aa3b80e85125f04acad6b30b0149b (patch)
tree9b39b9f99f14734612dfa64c1d66898ae6d36c79
parent59c198ab378c964808f815b5e255e33b0bf52334 (diff)
bgpd: Only create json for aspath if needed
The creation of the json object for the aspath is both memory intensive and expensive to create. Only create the json object when it is needed and stash it for further usage at that point. Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r--bgpd/bgp_aspath.c80
-rw-r--r--bgpd/bgp_aspath.h1
-rw-r--r--bgpd/bgp_route.c2
3 files changed, 49 insertions, 34 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c
index a47195dacf..365c2fee40 100644
--- a/bgpd/bgp_aspath.c
+++ b/bgpd/bgp_aspath.c
@@ -479,7 +479,7 @@ unsigned int aspath_has_as4(struct aspath *aspath)
}
/* Convert aspath structure to string expression. */
-static void aspath_make_str_count(struct aspath *as)
+static void aspath_make_str_count(struct aspath *as, bool make_json)
{
struct assegment *seg;
int str_size;
@@ -489,14 +489,18 @@ static void aspath_make_str_count(struct aspath *as)
json_object *jseg = NULL;
json_object *jseg_list = NULL;
- as->json = json_object_new_object();
- jaspath_segments = json_object_new_array();
+ if (make_json) {
+ as->json = json_object_new_object();
+ jaspath_segments = json_object_new_array();
+ }
/* Empty aspath. */
if (!as->segments) {
- json_object_string_add(as->json, "string", "Local");
- json_object_object_add(as->json, "segments", jaspath_segments);
- json_object_int_add(as->json, "length", 0);
+ if (make_json) {
+ json_object_string_add(as->json, "string", "Local");
+ json_object_object_add(as->json, "segments", jaspath_segments);
+ json_object_int_add(as->json, "length", 0);
+ }
as->str = XMALLOC(MTYPE_AS_STR, 1);
as->str[0] = '\0';
as->str_len = 0;
@@ -539,6 +543,7 @@ static void aspath_make_str_count(struct aspath *as)
as->str_len = 0;
json_object_free(as->json);
as->json = NULL;
+
return;
}
@@ -564,12 +569,14 @@ static void aspath_make_str_count(struct aspath *as)
str_buf + len, str_size - len, "%c",
aspath_delimiter_char(seg->type, AS_SEG_START));
- jseg_list = json_object_new_array();
+ if (make_json)
+ jseg_list = json_object_new_array();
/* write out the ASNs, with their seperators, bar the last one*/
for (i = 0; i < seg->length; i++) {
- json_object_array_add(jseg_list,
- json_object_new_int(seg->as[i]));
+ if (make_json)
+ json_object_array_add(jseg_list,
+ json_object_new_int(seg->as[i]));
len += snprintf(str_buf + len, str_size - len, "%u",
seg->as[i]);
@@ -579,11 +586,13 @@ static void aspath_make_str_count(struct aspath *as)
"%c", seperator);
}
- jseg = json_object_new_object();
- json_object_string_add(jseg, "type",
- aspath_segment_type_str[seg->type]);
- json_object_object_add(jseg, "list", jseg_list);
- json_object_array_add(jaspath_segments, jseg);
+ if (make_json) {
+ jseg = json_object_new_object();
+ json_object_string_add(jseg, "type",
+ aspath_segment_type_str[seg->type]);
+ json_object_object_add(jseg, "list", jseg_list);
+ json_object_array_add(jaspath_segments, jseg);
+ }
if (seg->type != AS_SEQUENCE)
len += snprintf(
@@ -601,13 +610,16 @@ static void aspath_make_str_count(struct aspath *as)
as->str = str_buf;
as->str_len = len;
- json_object_string_add(as->json, "string", str_buf);
- json_object_object_add(as->json, "segments", jaspath_segments);
- json_object_int_add(as->json, "length", aspath_count_hops(as));
+ if (make_json) {
+ json_object_string_add(as->json, "string", str_buf);
+ json_object_object_add(as->json, "segments", jaspath_segments);
+ json_object_int_add(as->json, "length", aspath_count_hops(as));
+ }
+
return;
}
-static void aspath_str_update(struct aspath *as)
+void aspath_str_update(struct aspath *as, bool make_json)
{
if (as->str)
XFREE(MTYPE_AS_STR, as->str);
@@ -617,7 +629,7 @@ static void aspath_str_update(struct aspath *as)
as->json = NULL;
}
- aspath_make_str_count(as);
+ aspath_make_str_count(as, make_json);
}
/* Intern allocated AS path. */
@@ -1079,7 +1091,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)
}
assegment_normalise(aspath->segments);
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1214,7 +1226,7 @@ struct aspath *aspath_replace_specific_asn(struct aspath *aspath,
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1237,7 +1249,7 @@ struct aspath *aspath_replace_private_asns(struct aspath *aspath, as_t asn)
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1307,7 +1319,7 @@ struct aspath *aspath_remove_private_asns(struct aspath *aspath)
seg = seg->next;
}
- aspath_str_update(new);
+ aspath_str_update(new, false);
return new;
}
@@ -1362,7 +1374,7 @@ static struct aspath *aspath_merge(struct aspath *as1, struct aspath *as2)
last->next = as2->segments;
as2->segments = new;
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
}
@@ -1381,7 +1393,7 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
/* If as2 is empty, only need to dupe as1's chain onto as2 */
if (seg2 == NULL) {
as2->segments = assegment_dup_all(as1->segments);
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
}
@@ -1432,7 +1444,7 @@ struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2)
/* we've now prepended as1's segment chain to as2, merging
* the inbetween AS_SEQUENCE of seg2 in the process
*/
- aspath_str_update(as2);
+ aspath_str_update(as2, false);
return as2;
} else {
/* AS_SET merge code is needed at here. */
@@ -1511,7 +1523,7 @@ struct aspath *aspath_filter_exclude(struct aspath *source,
lastseg->next = newseg;
lastseg = newseg;
}
- aspath_str_update(newpath);
+ aspath_str_update(newpath, false);
/* We are happy returning even an empty AS_PATH, because the
* administrator
* might expect this very behaviour. There's a mean to avoid this, if
@@ -1549,7 +1561,7 @@ static struct aspath *aspath_add_asns(struct aspath *aspath, as_t asno,
aspath->segments = newsegment;
}
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1639,7 +1651,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
if (!hops) {
newpath = aspath_dup(as4path);
- aspath_str_update(newpath);
+ aspath_str_update(newpath, false);
return newpath;
}
@@ -1700,7 +1712,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
mergedpath = aspath_merge(newpath, aspath_dup(as4path));
aspath_free(newpath);
mergedpath->segments = assegment_normalise(mergedpath->segments);
- aspath_str_update(mergedpath);
+ aspath_str_update(mergedpath, false);
if (BGP_DEBUG(as4, AS4))
zlog_debug("[AS4] result of synthesizing is %s",
@@ -1772,7 +1784,7 @@ struct aspath *aspath_delete_confed_seq(struct aspath *aspath)
}
if (removed_confed_segment)
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
return aspath;
}
@@ -1823,7 +1835,7 @@ struct aspath *aspath_empty_get(void)
struct aspath *aspath;
aspath = aspath_new();
- aspath_make_str_count(aspath);
+ aspath_make_str_count(aspath, false);
return aspath;
}
@@ -1973,7 +1985,7 @@ struct aspath *aspath_str2aspath(const char *str)
}
}
- aspath_make_str_count(aspath);
+ aspath_make_str_count(aspath, false);
return aspath;
}
@@ -1985,7 +1997,7 @@ unsigned int aspath_key_make(void *p)
unsigned int key = 0;
if (!aspath->str)
- aspath_str_update(aspath);
+ aspath_str_update(aspath, false);
key = jhash(aspath->str, aspath->str_len, 2334325);
diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h
index c8aba61a1f..eeaf229cac 100644
--- a/bgpd/bgp_aspath.h
+++ b/bgpd/bgp_aspath.h
@@ -92,6 +92,7 @@ extern struct aspath *aspath_delete_confed_seq(struct aspath *);
extern struct aspath *aspath_empty(void);
extern struct aspath *aspath_empty_get(void);
extern struct aspath *aspath_str2aspath(const char *);
+extern void aspath_str_update(struct aspath *as, bool make_json);
extern void aspath_free(struct aspath *);
extern struct aspath *aspath_intern(struct aspath *);
extern void aspath_unintern(struct aspath **);
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 80906edbdd..9bd0f137e5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -6915,6 +6915,8 @@ static void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
/* Line1 display AS-path, Aggregator */
if (attr->aspath) {
if (json_paths) {
+ if (!attr->aspath->json)
+ aspath_str_update(attr->aspath, true);
json_object_lock(attr->aspath->json);
json_object_object_add(json_path, "aspath",
attr->aspath->json);