]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Only build json for community when needed
authorDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 17 Nov 2017 01:43:56 +0000 (20:43 -0500)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Fri, 17 Nov 2017 14:04:26 +0000 (09:04 -0500)
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>
bgpd/bgp_clist.c
bgpd/bgp_community.c
bgpd/bgp_community.h
bgpd/bgp_debug.c
bgpd/bgp_route.c
bgpd/bgp_routemap.c
bgpd/bgp_vty.c

index f3bae9535cc92b12200a6cddec2c3f2ac67f0239..72b1098ede8093853818d2dbf874415b13b3d530 100644 (file)
@@ -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)
index b0f00d67d66f2cb3337209b22b08adc4674ea3f9..7c83eaa09121f3838f41d8d611eef5d09ea15273 100644 (file)
@@ -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;
 }
 
index f728debdb5e9527be0573ee0e577af29c7d984ad..5016f132f209ce95d0318adb8097f36d1534b192 100644 (file)
@@ -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 *);
index 6e16d5f45b56f096bfc781a40cdc1254dcfc05fb..45ac8e68597fbf1ccabf712d5c77d0270acbc503 100644 (file)
@@ -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),
index f0d91c366b6dbd7a5cdcfc5223ac78cf9b1535ff..ba75da45912ac2ea79411913d5d13f8a1de2183e 100644 (file)
@@ -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);
index 45487aa0030066f55de390ba64372ba9cbed8a2e..cc8cfd550cf806b2cc5bb79ee0974d0bfe95da7b 100644 (file)
@@ -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,
index db19835f88f686f9307a944f6675a323c68e6b3f..40f706a64693f8850e04858dfcf5e5f39c6d0663 100644 (file)
@@ -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;
        }