From c69e79f1d1d1009680a22aafe129eba7016e576b Mon Sep 17 00:00:00 2001 From: Lakshman Krishnamoorthy Date: Mon, 7 Oct 2019 14:20:02 -0700 Subject: [PATCH] bgpd: Bug fix in "show bgp l2vpn evpn neighbors X.X.X.X routes json" Fixed memory leak and incorrect json output. Check the full output in the PR: https://github.com/FRRouting/frr/pull/5118 Signed-off-by: Lakshman Krishnamoorthy --- bgpd/bgp_evpn_vty.c | 141 ++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 85 deletions(-) diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index 66681db520..d3022a9932 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -273,42 +273,61 @@ static void show_import_rt_entry(struct hash_bucket *bucket, void *args[]) static void bgp_evpn_show_route_rd_header(struct vty *vty, struct bgp_node *rd_rn, - json_object *json) + json_object *json, + char *rd_str, int len) { uint16_t type; struct rd_as rd_as; struct rd_ip rd_ip; uint8_t *pnt; - char rd_str[RD_ADDRSTRLEN]; pnt = rd_rn->p.u.val; /* Decode RD type. */ type = decode_rd_type(pnt); - if (json) - return; - - vty_out(vty, "Route Distinguisher: "); + if (!json) + vty_out(vty, "Route Distinguisher: "); switch (type) { case RD_TYPE_AS: decode_rd_as(pnt + 2, &rd_as); - snprintf(rd_str, RD_ADDRSTRLEN, "%u:%d", rd_as.as, rd_as.val); + snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val); + if (json) + json_object_string_add(json, "rd", rd_str); + else + vty_out(vty, "as2 %s\n", rd_str); + break; + + case RD_TYPE_AS4: + decode_rd_as4(pnt + 2, &rd_as); + snprintf(rd_str, len, "%u:%d", rd_as.as, rd_as.val); + if (json) + json_object_string_add(json, "rd", rd_str); + else + vty_out(vty, "as4 %s\n", rd_str); break; case RD_TYPE_IP: decode_rd_ip(pnt + 2, &rd_ip); - snprintf(rd_str, RD_ADDRSTRLEN, "%s:%d", inet_ntoa(rd_ip.ip), + snprintf(rd_str, len, "%s:%d", inet_ntoa(rd_ip.ip), rd_ip.val); + if (json) + json_object_string_add(json, "rd", rd_str); + else + vty_out(vty, "ip %s\n", rd_str); break; default: - snprintf(rd_str, RD_ADDRSTRLEN, "Unknown RD type"); + if (json) { + snprintf(rd_str, len, "Unknown"); + json_object_string_add(json, "rd", rd_str); + } else { + snprintf(rd_str, len, "Unknown RD type"); + vty_out(vty, "ip %s\n", rd_str); + } break; } - - vty_out(vty, "%s\n", rd_str); } static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp, @@ -1010,18 +1029,17 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, struct bgp_path_info *pi; int rd_header; int header = 1; - char rd_str[BUFSIZ]; + char rd_str[RD_ADDRSTRLEN]; char buf[BUFSIZ]; int no_display; unsigned long output_count = 0; unsigned long total_count = 0; json_object *json = NULL; - json_object *json_nroute = NULL; json_object *json_array = NULL; json_object *json_prefix_info = NULL; - memset(rd_str, 0, BUFSIZ); + memset(rd_str, 0, RD_ADDRSTRLEN); bgp = bgp_get_evpn(); if (bgp == NULL) { @@ -1038,6 +1056,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, for (rn = bgp_table_top(bgp->rib[afi][SAFI_EVPN]); rn; rn = bgp_route_next(rn)) { uint64_t tbl_ver; + json_object *json_nroute = NULL; if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0) continue; @@ -1055,22 +1074,6 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, continue; no_display = 0; - if (use_json) { - json_array = json_object_new_array(); - json_prefix_info = json_object_new_object(); - - json_object_string_add(json_prefix_info, - "prefix", bgp_evpn_route2str( - (struct prefix_evpn *)&rm->p, buf, - BUFSIZ)); - - json_object_int_add(json_prefix_info, - "prefixLen", rm->p.prefixlen); - - if (rd_header) - json_nroute = json_object_new_object(); - } - for (; pi; pi = pi->next) { total_count++; if (type == bgp_show_type_neighbor) { @@ -1112,60 +1115,16 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, header = 0; } if (rd_header) { - uint16_t type; - struct rd_as rd_as; - struct rd_ip rd_ip; - uint8_t *pnt; - - pnt = rn->p.u.val; - - /* Decode RD type. */ - type = decode_rd_type(pnt); - /* Decode RD value. */ - if (type == RD_TYPE_AS) - decode_rd_as(pnt + 2, &rd_as); - else if (type == RD_TYPE_AS4) - decode_rd_as4(pnt + 2, &rd_as); - else if (type == RD_TYPE_IP) - decode_rd_ip(pnt + 2, &rd_ip); - if (use_json) { - if (type == RD_TYPE_AS - || type == RD_TYPE_AS4) - sprintf(rd_str, "%u:%d", - rd_as.as, - rd_as.val); - else if (type == RD_TYPE_IP) - sprintf(rd_str, "%s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); - json_object_string_add( - json_nroute, - "rd", - rd_str); - - } else { - vty_out(vty, - "Route Distinguisher: "); - if (type == RD_TYPE_AS) - vty_out(vty, - "as2 %u:%d", - rd_as.as, - rd_as.val); - else if (type == RD_TYPE_AS4) - vty_out(vty, - "as4 %u:%d", - rd_as.as, - rd_as.val); - else if (type == RD_TYPE_IP) - vty_out(vty, "ip %s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); - vty_out(vty, "\n\n"); - } + if (use_json) + json_nroute = + json_object_new_object(); + bgp_evpn_show_route_rd_header(vty, rn, + json_nroute, rd_str, + RD_ADDRSTRLEN); rd_header = 0; } + if (use_json && !json_array) + json_array = json_object_new_array(); if (option == SHOW_DISPLAY_TAGS) route_vty_out_tag(vty, &rm->p, pi, @@ -1185,15 +1144,26 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd, if (no_display) output_count++; - if (use_json) { + if (use_json && json_array) { + json_prefix_info = json_object_new_object(); + + json_object_string_add(json_prefix_info, + "prefix", bgp_evpn_route2str( + (struct prefix_evpn *)&rm->p, buf, + BUFSIZ)); + + json_object_int_add(json_prefix_info, + "prefixLen", rm->p.prefixlen); + json_object_object_add(json_prefix_info, "paths", json_array); json_object_object_add(json_nroute, buf, json_prefix_info); + json_array = NULL; } } - if (use_json) + if (use_json && json_nroute) json_object_object_add(json, rd_str, json_nroute); } @@ -2545,7 +2515,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type, /* RD header - per RD. */ if (rd_header) { bgp_evpn_show_route_rd_header( - vty, rd_rn, json); + vty, rd_rn, NULL, rd_str, + RD_ADDRSTRLEN); rd_header = 0; } -- 2.39.5