diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 694cb14790..85bb38143f 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -356,19 +356,6 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, { struct bgp *bgp; struct bgp_table *table; - struct bgp_node *rn; - struct bgp_node *rm; - struct bgp_info *ri; - int rd_header; - int header = 1; - unsigned long output_count = 0; - unsigned long total_count = 0; - json_object *json = NULL; - json_object *json_mroute = NULL; - json_object *json_nroute = NULL; - json_object *json_array = NULL; - json_object *json_scode = NULL; - json_object *json_ocode = NULL; bgp = bgp_get_default(); if (bgp == NULL) { @@ -378,256 +365,9 @@ int bgp_show_mpls_vpn(struct vty *vty, afi_t afi, struct prefix_rd *prd, vty_out(vty, "{}\n"); return CMD_WARNING; } - - if (use_json) { - json_scode = json_object_new_object(); - json_ocode = json_object_new_object(); - json = json_object_new_object(); - json_mroute = json_object_new_object(); - json_nroute = json_object_new_object(); - - json_object_string_add(json_scode, "suppressed", "s"); - json_object_string_add(json_scode, "damped", "d"); - json_object_string_add(json_scode, "history", "h"); - json_object_string_add(json_scode, "valid", "*"); - json_object_string_add(json_scode, "best", ">"); - json_object_string_add(json_scode, "internal", "i"); - - json_object_string_add(json_ocode, "igp", "i"); - json_object_string_add(json_ocode, "egp", "e"); - json_object_string_add(json_ocode, "incomplete", "?"); - } - - if ((afi != AFI_IP) && (afi != AFI_IP6)) { - vty_out(vty, "Afi %d not supported\n", afi); - return CMD_WARNING; - } - - for (rn = bgp_table_top(bgp->rib[afi][SAFI_MPLS_VPN]); rn; - rn = bgp_route_next(rn)) { - if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0) - continue; - - if ((table = rn->info) != NULL) { - rd_header = 1; - - for (rm = bgp_table_top(table); rm; - rm = bgp_route_next(rm)) { - total_count++; - if (use_json) - json_array = json_object_new_array(); - else - json_array = NULL; - - for (ri = rm->info; ri; ri = ri->next) { - if (type == bgp_show_type_neighbor) { - union sockunion *su = - output_arg; - - if (ri->peer->su_remote == NULL - || !sockunion_same( - ri->peer->su_remote, - su)) - continue; - } - if (header) { - if (use_json) { - if (!tags) { - json_object_int_add( - json, - "bgpTableVersion", - 0); - json_object_string_add( - json, - "bgpLocalRouterId", - inet_ntoa( - bgp->router_id)); - json_object_object_add( - json, - "bgpStatusCodes", - json_scode); - json_object_object_add( - json, - "bgpOriginCodes", - json_ocode); - } - } else { - if (tags) - vty_out(vty, - V4_HEADER_TAG); - else { - vty_out(vty, - "BGP table version is 0, local router ID is %s\n", - inet_ntoa( - bgp->router_id)); - vty_out(vty, - "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n"); - vty_out(vty, - "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"); - vty_out(vty, - V4_HEADER); - } - } - header = 0; - } - - if (rd_header) { - u_int16_t type; - struct rd_as rd_as; - struct rd_ip rd_ip = {0}; -#if ENABLE_BGP_VNC - struct rd_vnc_eth rd_vnc_eth = { - 0}; -#endif - u_char *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 ENABLE_BGP_VNC - else if (type - == RD_TYPE_VNC_ETH) - decode_rd_vnc_eth( - pnt, - &rd_vnc_eth); -#endif - - if (use_json) { - char buffer[BUFSIZ]; - if (type == RD_TYPE_AS - || type == RD_TYPE_AS4) - sprintf(buffer, - "%u:%d", - rd_as.as, - rd_as.val); - else if (type - == RD_TYPE_IP) - sprintf(buffer, - "%s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); - json_object_string_add( - json_nroute, - "routeDistinguisher", - buffer); - } else { - vty_out(vty, - "Route Distinguisher: "); - - if (type == RD_TYPE_AS - || type == RD_TYPE_AS4) - vty_out(vty, - "%u:%d", - rd_as.as, - rd_as.val); - else if (type - == RD_TYPE_IP) - vty_out(vty, - "%s:%d", - inet_ntoa( - rd_ip.ip), - rd_ip.val); -#if ENABLE_BGP_VNC - else if ( - type - == RD_TYPE_VNC_ETH) - vty_out(vty, - "%u:%02x:%02x:%02x:%02x:%02x:%02x", - rd_vnc_eth - .local_nve_id, - rd_vnc_eth - .macaddr - .octet[0], - rd_vnc_eth - .macaddr - .octet[1], - rd_vnc_eth - .macaddr - .octet[2], - rd_vnc_eth - .macaddr - .octet[3], - rd_vnc_eth - .macaddr - .octet[4], - rd_vnc_eth - .macaddr - .octet[5]); -#endif - vty_out(vty, "\n"); - } - rd_header = 0; - } - if (tags) - route_vty_out_tag(vty, &rm->p, - ri, 0, - SAFI_MPLS_VPN, - json_array); - else - route_vty_out(vty, &rm->p, ri, - 0, SAFI_MPLS_VPN, - json_array); - output_count++; - } - - if (use_json) { - struct prefix *p; - char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - p = &rm->p; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, - &p->u.prefix, buf_b, - BUFSIZ), - p->prefixlen); - json_object_object_add( - json_mroute, buf_a, json_array); - } - } - - if (use_json) { - struct prefix *p; - char buf_a[BUFSIZ]; - char buf_b[BUFSIZ]; - p = &rn->p; - sprintf(buf_a, "%s/%d", - inet_ntop(p->family, &p->u.prefix, - buf_b, BUFSIZ), - p->prefixlen); - json_object_object_add(json_nroute, buf_a, - json_mroute); - } - } - } - - if (use_json) { - json_object_object_add(json, "routes", json_nroute); - vty_out(vty, "%s\n", json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } else { - if (output_count == 0) - vty_out(vty, "No prefixes displayed, %ld exist\n", - total_count); - else - vty_out(vty, - "\nDisplayed %ld routes and %ld total paths\n", - output_count, total_count); - } - - return CMD_SUCCESS; + table = bgp->rib[afi][SAFI_MPLS_VPN]; + return bgp_show_table_rd(vty, bgp, SAFI_MPLS_VPN, + table, prd, type, output_arg, use_json); } DEFUN (show_bgp_ip_vpn_all_rd, diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3307f86088..0ac8c8b761 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8122,23 +8122,29 @@ static int bgp_show_community(struct vty *vty, struct bgp *bgp, const char *comstr, int exact, afi_t afi, safi_t safi); -static int bgp_show_table(struct vty *vty, struct bgp *bgp, + +static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, struct bgp_table *table, enum bgp_show_type type, - void *output_arg, u_char use_json) + void *output_arg, u_char use_json, + char *rd, int is_last, + unsigned long *output_cum, unsigned long *total_cum) { struct bgp_info *ri; struct bgp_node *rn; int header = 1; int display; - unsigned long output_count; - unsigned long total_count; + unsigned long output_count = 0; + unsigned long total_count = 0; struct prefix *p; char buf[BUFSIZ]; char buf2[BUFSIZ]; json_object *json_paths = NULL; int first = 1; - if (use_json) { + if (output_cum && *output_cum != 0) + header = 0; + + if (use_json && header) { vty_out(vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ", @@ -8149,10 +8155,6 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, json_paths = json_object_new_object(); } - /* This is first entry point, so reset total line. */ - output_count = 0; - total_count = 0; - /* Start processing of routes. */ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) if (rn->info != NULL) { @@ -8335,22 +8337,29 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, vty_out(vty, BGP_SHOW_HEADER); header = 0; } - + if (rd != NULL && !display && !output_count) { + if (!use_json) + vty_out(vty, + "Route Distinguisher: %s\n", + rd); + else + vty_out(vty, "rd:\"%s\",", rd); + } if (type == bgp_show_type_dampend_paths || type == bgp_show_type_damp_neighbor) damp_route_vty_out( vty, &rn->p, ri, display, - SAFI_UNICAST, use_json, + safi, use_json, json_paths); else if (type == bgp_show_type_flap_statistics || type == bgp_show_type_flap_neighbor) flap_route_vty_out( vty, &rn->p, ri, display, - SAFI_UNICAST, use_json, + safi, use_json, json_paths); else route_vty_out(vty, &rn->p, ri, display, - SAFI_UNICAST, json_paths); + safi, json_paths); display++; } @@ -8373,25 +8382,68 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, } } + if (output_cum) { + output_count += *output_cum; + *output_cum = output_count; + } + if (total_cum) { + total_count += *total_cum; + *total_cum = total_count; + } if (use_json) { json_object_free(json_paths); - vty_out(vty, " } }\n"); + if (is_last) + vty_out(vty, " } }\n"); + else + vty_out(vty, " }, "); } else { - /* No route is displayed */ - if (output_count == 0) { - if (type == bgp_show_type_normal) + if (is_last) { + /* No route is displayed */ + if (output_count == 0) { + if (type == bgp_show_type_normal) + vty_out(vty, + "No BGP prefixes displayed, %ld exist\n", + total_count); + } else vty_out(vty, - "No BGP prefixes displayed, %ld exist\n", - total_count); - } else - vty_out(vty, - "\nDisplayed %ld routes and %ld total paths\n", - output_count, total_count); + "\nDisplayed %ld routes and %ld total paths\n", + output_count, total_count); + } } return CMD_SUCCESS; } +int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, + struct bgp_table *table, struct prefix_rd *prd_match, + enum bgp_show_type type, void *output_arg, + u_char use_json) +{ + struct bgp_node *rn, *next; + unsigned long output_cum = 0; + unsigned long total_cum = 0; + + for (rn = bgp_table_top(table); rn; rn = next) { + next = bgp_route_next(rn); + if (prd_match && memcmp(rn->p.u.val, prd_match->val, 8) != 0) + continue; + if (rn->info != NULL) { + struct prefix_rd prd; + char rd[BUFSIZ]; + + memcpy(&prd, &(rn->p), sizeof(struct prefix_rd)); + if (prefix_rd2str(&prd, rd, BUFSIZ) == NULL) + sprintf(rd, + "Unknown Type: %u", + decode_rd_type(prd.val)); + bgp_show_table(vty, bgp, safi, rn->info, type, + output_arg, use_json, + rd, next == NULL, + &output_cum, &total_cum); + } + } + return CMD_SUCCESS; +} static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, enum bgp_show_type type, void *output_arg, u_char use_json) { @@ -8409,18 +8461,18 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi, return CMD_WARNING; } + table = bgp->rib[afi][safi]; /* use MPLS and ENCAP specific shows until they are merged */ if (safi == SAFI_MPLS_VPN) { - return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0, - use_json); + return bgp_show_table_rd(vty, bgp, safi, table, NULL, type, + output_arg, use_json); } /* labeled-unicast routes live in the unicast table */ else if (safi == SAFI_LABELED_UNICAST) safi = SAFI_UNICAST; - table = bgp->rib[afi][safi]; - - return bgp_show_table(vty, bgp, table, type, output_arg, use_json); + return bgp_show_table(vty, bgp, safi, table, type, output_arg, use_json, + NULL, 1, NULL, NULL); } static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi, @@ -9090,12 +9142,7 @@ DEFUN (show_ip_bgp_json, return bgp_show(vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj); } - - if (safi == SAFI_MPLS_VPN) - return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal, - NULL, 0, uj); - else - return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); + return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj); } DEFUN (show_ip_bgp_route, diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 6caa1c8939..6fbeed8963 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -442,4 +442,8 @@ extern void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p, struct bgp_info *binfo, afi_t afi, safi_t safi, json_object *json_paths); +extern int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi, + struct bgp_table *table, struct prefix_rd *prd, + enum bgp_show_type type, void *output_arg, + u_char use_json); #endif /* _QUAGGA_BGP_ROUTE_H */