diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-11-17 02:43:56 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-11-17 15:04:26 +0100 |
commit | a69ea8aeac9d6cc5c27c084d02a0ddcd96231e46 (patch) | |
tree | 88399c020efd0d768e90865bf2da3cc9f92c149c | |
parent | bgpd: Only create json for aspath if needed (diff) | |
download | frr-a69ea8aeac9d6cc5c27c084d02a0ddcd96231e46.tar.xz frr-a69ea8aeac9d6cc5c27c084d02a0ddcd96231e46.zip |
bgpd: Only build json for community when needed
Building a communities json object every time is
both expensive and memory wasteful. Modify
code to only build the json object when needed.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
-rw-r--r-- | bgpd/bgp_clist.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_community.c | 66 | ||||
-rw-r--r-- | bgpd/bgp_community.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_debug.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 3 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 2 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 6 |
7 files changed, 54 insertions, 30 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c index f3bae9535..72b1098ed 100644 --- a/bgpd/bgp_clist.c +++ b/bgpd/bgp_clist.c @@ -438,7 +438,7 @@ static int community_regexp_match(struct community *com, regex_t *reg) if (com == NULL || com->size == 0) str = ""; else - str = community_str(com); + str = community_str(com, false); /* Regular expression match. */ if (regexec(reg, str, 0, NULL, 0) == 0) diff --git a/bgpd/bgp_community.c b/bgpd/bgp_community.c index b0f00d67d..7c83eaa09 100644 --- a/bgpd/bgp_community.c +++ b/bgpd/bgp_community.c @@ -169,7 +169,6 @@ struct community *community_uniq_sort(struct community *com) return NULL; new = community_new(); - ; new->json = NULL; for (i = 0; i < com->size; i++) { @@ -195,7 +194,7 @@ struct community *community_uniq_sort(struct community *com) 0xFFFF0000 "graceful-shutdown" For other values, "AS:VAL" format is used. */ -static void set_community_string(struct community *com) +static void set_community_string(struct community *com, bool make_json) { int i; char *str; @@ -211,16 +210,20 @@ static void set_community_string(struct community *com) if (!com) return; - com->json = json_object_new_object(); - json_community_list = json_object_new_array(); + if (make_json) { + com->json = json_object_new_object(); + json_community_list = json_object_new_array(); + } /* When communities attribute is empty. */ if (com->size == 0) { str = XMALLOC(MTYPE_COMMUNITY_STR, 1); str[0] = '\0'; - json_object_string_add(com->json, "string", ""); - json_object_object_add(com->json, "list", json_community_list); + if (make_json) { + json_object_string_add(com->json, "string", ""); + json_object_object_add(com->json, "list", json_community_list); + } com->str = str; return; } @@ -273,47 +276,61 @@ static void set_community_string(struct community *com) case COMMUNITY_INTERNET: strcpy(pnt, "internet"); pnt += strlen("internet"); - json_string = json_object_new_string("internet"); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string("internet"); + json_object_array_add(json_community_list, json_string); + } break; case COMMUNITY_NO_EXPORT: strcpy(pnt, "no-export"); pnt += strlen("no-export"); - json_string = json_object_new_string("noExport"); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string("noExport"); + json_object_array_add(json_community_list, json_string); + } break; case COMMUNITY_NO_ADVERTISE: strcpy(pnt, "no-advertise"); pnt += strlen("no-advertise"); - json_string = json_object_new_string("noAdvertise"); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string("noAdvertise"); + json_object_array_add(json_community_list, json_string); + } break; case COMMUNITY_LOCAL_AS: strcpy(pnt, "local-AS"); pnt += strlen("local-AS"); - json_string = json_object_new_string("localAs"); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string("localAs"); + json_object_array_add(json_community_list, json_string); + } break; case COMMUNITY_GSHUT: strcpy(pnt, "graceful-shutdown"); pnt += strlen("graceful-shutdown"); - json_string = json_object_new_string("gracefulShutdown"); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string("gracefulShutdown"); + json_object_array_add(json_community_list, json_string); + } break; default: as = (comval >> 16) & 0xFFFF; val = comval & 0xFFFF; sprintf(pnt, "%u:%d", as, val); - json_string = json_object_new_string(pnt); - json_object_array_add(json_community_list, json_string); + if (make_json) { + json_string = json_object_new_string(pnt); + json_object_array_add(json_community_list, json_string); + } pnt += strlen(pnt); break; } } *pnt = '\0'; - json_object_string_add(com->json, "string", str); - json_object_object_add(com->json, "list", json_community_list); + if (make_json) { + json_object_string_add(com->json, "string", str); + json_object_object_add(com->json, "list", json_community_list); + } com->str = str; } @@ -338,7 +355,7 @@ struct community *community_intern(struct community *com) /* Make string. */ if (!find->str) - set_community_string(find); + set_community_string(find, false); return find; } @@ -396,13 +413,16 @@ struct community *community_dup(struct community *com) } /* Retrun string representation of communities attribute. */ -char *community_str(struct community *com) +char *community_str(struct community *com, bool make_json) { if (!com) return NULL; + if (make_json && !com->json && com->str) + XFREE(MTYPE_COMMUNITY_STR, com->str); + if (!com->str) - set_community_string(com); + set_community_string(com, make_json); return com->str; } diff --git a/bgpd/bgp_community.h b/bgpd/bgp_community.h index f728debdb..5016f132f 100644 --- a/bgpd/bgp_community.h +++ b/bgpd/bgp_community.h @@ -63,7 +63,7 @@ extern struct community *community_uniq_sort(struct community *); extern struct community *community_parse(u_int32_t *, u_short); extern struct community *community_intern(struct community *); extern void community_unintern(struct community **); -extern char *community_str(struct community *); +extern char *community_str(struct community *, bool make_json); extern unsigned int community_hash_make(struct community *); extern struct community *community_str2com(const char *); extern int community_match(const struct community *, const struct community *); diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 6e16d5f45..45ac8e685 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -385,7 +385,8 @@ int bgp_dump_attr(struct attr *attr, char *buf, size_t size) if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), - ", community %s", community_str(attr->community)); + ", community %s", community_str(attr->community, + false)); if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))) snprintf(buf + strlen(buf), size - strlen(buf), diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index f0d91c366..ba75da459 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -7885,6 +7885,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, /* Line 4 display Community */ if (attr->community) { if (json_paths) { + if (!attr->community->json) + community_str(attr->community, + true); json_object_lock(attr->community->json); json_object_object_add(json_path, "community", attr->community->json); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 45487aa00..cc8cfd550 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3813,7 +3813,7 @@ DEFUN (set_community, } /* Set communites attribute string. */ - str = community_str(com); + str = community_str(com, false); if (additive) { argstr = XCALLOC(MTYPE_TMP, diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index db19835f8..40f706a64 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -10010,7 +10010,7 @@ static void community_show_all_iterator(struct hash_backet *backet, com = (struct community *)backet->data; vty_out(vty, "[%p] (%ld) %s\n", (void *)com, com->refcnt, - community_str(com)); + community_str(com, false)); } /* Show BGP's community internal data. */ @@ -12698,7 +12698,7 @@ static void community_list_show(struct vty *vty, struct community_list *list) vty_out(vty, " %s %s\n", community_direct_str(entry->direct), entry->style == COMMUNITY_LIST_STANDARD - ? community_str(entry->u.com) + ? community_str(entry->u.com, false) : entry->config); } } @@ -13354,7 +13354,7 @@ static const char *community_list_config_str(struct community_entry *entry) str = ""; else { if (entry->style == COMMUNITY_LIST_STANDARD) - str = community_str(entry->u.com); + str = community_str(entry->u.com, false); else str = entry->config; } |