From: Morgan Stewart Date: Wed, 12 Aug 2015 13:59:18 +0000 (-0700) Subject: Added json formating support to show-...-neighbors-... bgp commands. X-Git-Tag: frr-2.0-rc1~1282 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=856ca177c4bb8f857fd60a1d93ac99fbd1a76484;p=matthieu%2Ffrr.git Added json formating support to show-...-neighbors-... bgp commands. Ticket: CM-6789 Reviewed By: CCR-3263 Testing Done: Manual Testing and smoke tests Whenever some sort of output is encountered, added a json version with proper logic as well. --- diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 87feebe8a6..22b8adcdb6 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -33,6 +33,7 @@ #include "zclient.h" #include "vty.h" #include "bfd.h" +#include "lib/json.h" #include "bgpd/bgpd.h" #include "bgp_fsm.h" #include "bgpd/bgp_bfd.h" @@ -383,22 +384,40 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr) * bgp_bfd_show_info - Show the peer BFD information. */ void -bgp_bfd_show_info(struct vty *vty, struct peer *peer) +bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh) { struct bfd_info *bfd_info; + json_object *json_bfd = NULL; if (!peer->bfd_info) return; + if (use_json) + json_bfd = json_object_new_object(); + bfd_info = (struct bfd_info *)peer->bfd_info; - vty_out (vty, " BFD: Multi-hop: %s%s", - (bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE); - vty_out (vty, " Detect Mul: %d, Min Rx interval: %d," - " Min Tx interval: %d%s", - bfd_info->detect_mult, bfd_info->required_min_rx, - bfd_info->desired_min_tx, VTY_NEWLINE); - vty_out (vty, "%s", VTY_NEWLINE); + if (use_json) + { + if (bgp_bfd_is_peer_multihop(peer)) + json_object_string_add(json_bfd, "bfdMultiHop", "yes"); + else + json_object_string_add(json_bfd, "bfdMultiHop", "no"); + json_object_int_add(json_bfd, "detectMultiplier", bfd_info->detect_mult); + json_object_int_add(json_bfd, "rxMinInterval", bfd_info->required_min_rx); + json_object_int_add(json_bfd, "txMinInterval", bfd_info->desired_min_tx); + json_object_object_add(json_neigh, "peerBfdInfo", json_bfd); + } + else + { + vty_out (vty, " BFD: Multi-hop: %s%s", + (bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE); + vty_out (vty, " Detect Mul: %d, Min Rx interval: %d," + " Min Tx interval: %d%s", + bfd_info->detect_mult, bfd_info->required_min_rx, + bfd_info->desired_min_tx, VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + } } DEFUN (neighbor_bfd, diff --git a/bgpd/bgp_bfd.h b/bgpd/bgp_bfd.h index 97ad093eee..4e554af696 100644 --- a/bgpd/bgp_bfd.h +++ b/bgpd/bgp_bfd.h @@ -40,6 +40,6 @@ extern void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr); extern void -bgp_bfd_show_info(struct vty *vty, struct peer *peer); +bgp_bfd_show_info(struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh); #endif /* _QUAGGA_BGP_BFD_H */ diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index 408350ae60..21df08657a 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -543,10 +543,11 @@ bgp_config_write_damp (struct vty *vty) } static const char * -bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len) +bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len, u_char use_json, json_object *json) { time_t reuse_time = 0; struct tm *tm = NULL; + int time_store = 0; if (penalty > damp->reuse_limit) { @@ -564,16 +565,45 @@ bgp_get_reuse_time (unsigned int penalty, char *buf, size_t len) #define ONE_DAY_SECOND 60*60*24 #define ONE_WEEK_SECOND 60*60*24*7 if (reuse_time == 0) - snprintf (buf, len, "00:00:00"); + { + if (use_json) + json_object_int_add(json, "reuseTimerMsecs", 0); + else + snprintf (buf, len, "00:00:00"); + } else if (reuse_time < ONE_DAY_SECOND) - snprintf (buf, len, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); + { + if (use_json) + { + time_store = (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", time_store); + } + else + snprintf (buf, len, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + } else if (reuse_time < ONE_WEEK_SECOND) - snprintf (buf, len, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); + { + if (use_json) + { + time_store = (86400000 * tm->tm_yday) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", time_store); + } + else + snprintf (buf, len, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + } else - snprintf (buf, len, "%02dw%dd%02dh", - tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + { + if (use_json) + { + time_store = (604800000 * tm->tm_yday/7) + (86400000 * (tm->tm_yday - ((tm->tm_yday/7) * 7))) + (3600000 * tm->tm_hour) + (60000 * tm->tm_min) + (1000 * tm->tm_sec); + json_object_int_add(json, "reuseTimerMsecs", time_store); + } + else + snprintf (buf, len, "%02dw%dd%02dh", + tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + } return buf; } @@ -607,26 +637,22 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo, { json_object_int_add(json_path, "dampeningPenalty", penalty); json_object_int_add(json_path, "dampeningFlapCount", bdi->flap); - json_object_string_add(json_path, "dampeningFlapPeriod", - peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN)); + peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 1, json_path); if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - { - json_object_string_add(json_path, "dampeningReuseIn", - bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN)); - } + bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 1, json_path); } else { vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s", penalty, bdi->flap, - peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN)); + peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, 0, json_path)); if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) vty_out (vty, ", reuse in %s", - bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN)); + bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 0, json_path)); vty_out (vty, "%s", VTY_NEWLINE); } @@ -634,7 +660,7 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo, const char * bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo, - char *timebuf, size_t len) + char *timebuf, size_t len, u_char use_json, json_object *json) { struct bgp_damp_info *bdi; time_t t_now, t_diff; @@ -656,5 +682,5 @@ bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo, t_diff = t_now - bdi->t_updated; penalty = bgp_damp_decay (t_diff, bdi->penalty); - return bgp_get_reuse_time (penalty, timebuf, len); + return bgp_get_reuse_time (penalty, timebuf, len, use_json, json); } diff --git a/bgpd/bgp_damp.h b/bgpd/bgp_damp.h index 31c6c307ad..6853696378 100644 --- a/bgpd/bgp_damp.h +++ b/bgpd/bgp_damp.h @@ -21,8 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGP_DAMP_H #define _QUAGGA_BGP_DAMP_H -#include "lib/json.h" - /* Structure maintained on a per-route basis. */ struct bgp_damp_info { @@ -144,6 +142,6 @@ extern int bgp_damp_decay (time_t, int); extern void bgp_config_write_damp (struct vty *); extern void bgp_damp_info_vty (struct vty *, struct bgp_info *, json_object *json_path); extern const char * bgp_damp_reuse_time_vty (struct vty *, struct bgp_info *, - char *, size_t); + char *, size_t, u_char, json_object *); #endif /* _QUAGGA_BGP_DAMP_H */ diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index ec9427bb49..b187431597 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -33,6 +33,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "workqueue.h" #include "queue.h" +#include "lib/json.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 9a1d903350..09f137fe4c 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -27,6 +27,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "stream.h" #include "queue.h" +#include "lib/json.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" #include "bgpd/bgp_route.h" @@ -331,7 +332,7 @@ DEFUN (no_vpnv4_network, } static int -show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd) +show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd, u_char use_json) { struct bgp *bgp; struct bgp_table *table; @@ -341,14 +342,39 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd) int rd_header; int header = 1; char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; + json_object *json = NULL; + json_object *json_scode = NULL; + json_object *json_ocode = NULL; + json_object *json_routes = NULL; + json_object *json_array = NULL; bgp = bgp_get_default (); if (bgp == NULL) { - vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + if (!use_json) + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); return CMD_WARNING; } + if (use_json) + { + json_scode = json_object_new_object(); + json_ocode = json_object_new_object(); + json_routes = json_object_new_object(); + json = 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", "?"); + } + for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn)) { @@ -357,54 +383,98 @@ show_adj_route_vpn (struct vty *vty, struct peer *peer, struct prefix_rd *prd) if ((table = rn->info) != NULL) { + if (use_json) + json_array = json_object_new_array(); + else + json_array = NULL; + rd_header = 1; for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) - if ((attr = rm->info) != NULL) - { - if (header) - { - vty_out (vty, "BGP table version is 0, local router ID is %s%s", - inet_ntoa (bgp->router_id), VTY_NEWLINE); - vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", - VTY_NEWLINE); - vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", - VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, v4_header, VTY_NEWLINE); - header = 0; - } - - if (rd_header) - { - u_int16_t type; - struct rd_as rd_as; - struct rd_ip rd_ip; - 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_IP) - decode_rd_ip (pnt + 2, &rd_ip); - - vty_out (vty, "Route Distinguisher: "); - - if (type == RD_TYPE_AS) - 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); - - vty_out (vty, "%s", VTY_NEWLINE); - rd_header = 0; - } - route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN); - } + { + if ((attr = rm->info) != NULL) + { + if (header) + { + if (use_json) + { + 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 + { + vty_out (vty, "BGP table version is 0, local router ID is %s%s", + inet_ntoa (bgp->router_id), VTY_NEWLINE); + vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", + VTY_NEWLINE); + vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", + VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, v4_header, VTY_NEWLINE); + } + header = 0; + } + + if (rd_header) + { + u_int16_t type; + struct rd_as rd_as; + struct rd_ip rd_ip; + 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_IP) + decode_rd_ip (pnt + 2, &rd_ip); + + if (use_json) + { + char buffer[BUFSIZ]; + if (type == RD_TYPE_AS) + sprintf (buffer, "%u:%d", rd_as.as, rd_as.val); + else if (type == RD_TYPE_IP) + sprintf (buffer, "%u:%d", rd_as.as, rd_as.val); + json_object_string_add(json_routes, "routeDistinguisher", buffer); + } + else + { + vty_out (vty, "Route Distinguisher: "); + + if (type == RD_TYPE_AS) + 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); + + vty_out (vty, "%s", VTY_NEWLINE); + } + rd_header = 0; + } + route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN, use_json, json_array); + } + } + 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_routes, buf_a, json_array); + } } } + if (use_json) + { + json_object_object_add(json, "routes", json_routes); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } return CMD_SUCCESS; } @@ -426,7 +496,7 @@ enum bgp_show_type static int bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type, - void *output_arg, int tags) + void *output_arg, int tags, u_char use_json) { struct bgp *bgp; struct bgp_table *table; @@ -437,15 +507,42 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty int header = 1; char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; char v4_header_tag[] = " Network Next Hop In tag/Out tag%s"; + 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) { - vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + if (!use_json) + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); return CMD_WARNING; } - - for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn)) + + 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", "?"); + } + + for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn)) { if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0) continue; @@ -455,66 +552,124 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty rd_header = 1; for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) - 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 (tags) - vty_out (vty, v4_header_tag, VTY_NEWLINE); - else - { - vty_out (vty, "BGP table version is 0, local router ID is %s%s", - inet_ntoa (bgp->router_id), VTY_NEWLINE); - vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", - VTY_NEWLINE); - vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", - VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, v4_header, VTY_NEWLINE); - } - header = 0; - } - - if (rd_header) - { - u_int16_t type; - struct rd_as rd_as; - struct rd_ip rd_ip; - 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_IP) - decode_rd_ip (pnt + 2, &rd_ip); - - vty_out (vty, "Route Distinguisher: "); - - if (type == RD_TYPE_AS) - 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); - - vty_out (vty, "%s", VTY_NEWLINE); - rd_header = 0; - } - if (tags) - route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN); - else - route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, NULL); - } + { + 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, VTY_NEWLINE); + else + { + vty_out (vty, "BGP table version is 0, local router ID is %s%s", + inet_ntoa (bgp->router_id), VTY_NEWLINE); + vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", + VTY_NEWLINE); + vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", + VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, v4_header, VTY_NEWLINE); + } + } + header = 0; + } + + if (rd_header) + { + u_int16_t type; + struct rd_as rd_as; + struct rd_ip rd_ip; + 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_IP) + decode_rd_ip (pnt + 2, &rd_ip); + + if (use_json) + { + char buffer[BUFSIZ]; + if (type == RD_TYPE_AS) + 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) + 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); + vty_out (vty, "%s", VTY_NEWLINE); + } + 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); + } + + 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%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } return CMD_SUCCESS; } @@ -527,7 +682,7 @@ DEFUN (show_ip_bgp_vpnv4_all, "Display VPNv4 NLRI specific information\n" "Display information about all VPNv4 NLRIs\n") { - return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0); + return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 0, 0); } DEFUN (show_ip_bgp_vpnv4_rd, @@ -549,7 +704,7 @@ DEFUN (show_ip_bgp_vpnv4_rd, vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0); + return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 0, 0); } DEFUN (show_ip_bgp_vpnv4_all_tags, @@ -562,7 +717,7 @@ DEFUN (show_ip_bgp_vpnv4_all_tags, "Display information about all VPNv4 NLRIs\n" "Display BGP tags for prefixes\n") { - return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1); + return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_normal, NULL, 1, 0); } DEFUN (show_ip_bgp_vpnv4_rd_tags, @@ -585,12 +740,12 @@ DEFUN (show_ip_bgp_vpnv4_rd_tags, vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1); + return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_normal, NULL, 1, 0); } DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes, show_ip_bgp_vpnv4_all_neighbor_routes_cmd, - "show ip bgp vpnv4 all neighbors A.B.C.D routes", + "show ip bgp vpnv4 all neighbors A.B.C.D routes {json}", SHOW_STR IP_STR BGP_STR @@ -598,32 +753,52 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes, "Display information about all VPNv4 NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { union sockunion su; struct peer *peer; int ret; + u_char use_json = (argv[1] != NULL); ret = str2sockunion (argv[0], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0); + return bgp_show_mpls_vpn (vty, NULL, bgp_show_type_neighbor, &su, 0, use_json); } DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, show_ip_bgp_vpnv4_rd_neighbor_routes_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes", + "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D routes {json}", SHOW_STR IP_STR BGP_STR @@ -632,40 +807,69 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes, "VPN Route Distinguisher\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { int ret; union sockunion su; struct peer *peer; struct prefix_rd prd; + u_char use_json = (argv[2] != NULL); ret = str2prefix_rd (argv[0], &prd); if (! ret) { - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed Route Distinguisher"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); return CMD_WARNING; } ret = str2sockunion (argv[1], &su); if (ret < 0) { - vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0); + return bgp_show_mpls_vpn (vty, &prd, bgp_show_type_neighbor, &su, 0, use_json); } DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes, show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd, - "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes", + "show ip bgp vpnv4 all neighbors A.B.C.D advertised-routes {json}", SHOW_STR IP_STR BGP_STR @@ -673,31 +877,51 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes, "Display information about all VPNv4 NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { int ret; struct peer *peer; union sockunion su; + u_char use_json = (argv[1] != NULL); ret = str2sockunion (argv[0], &su); if (ret < 0) { - vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return show_adj_route_vpn (vty, peer, NULL); + return show_adj_route_vpn (vty, peer, NULL, use_json); } DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes, show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes", + "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D advertised-routes {json}", SHOW_STR IP_STR BGP_STR @@ -706,34 +930,63 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes, "VPN Route Distinguisher\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { int ret; struct peer *peer; struct prefix_rd prd; union sockunion su; + u_char use_json = (argv[2] != NULL); ret = str2sockunion (argv[1], &su); if (ret < 0) { - vty_out (vty, "%% Malformed address: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Malformed address: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } peer = peer_lookup (NULL, &su); if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } ret = str2prefix_rd (argv[0], &prd); if (! ret) { - vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed Route Distinguisher"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE); return CMD_WARNING; } - return show_adj_route_vpn (vty, peer, &prd); + return show_adj_route_vpn (vty, peer, &prd, use_json); } void diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c index 78da37e12e..a530542a49 100644 --- a/bgpd/bgp_open.c +++ b/bgpd/bgp_open.c @@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "memory.h" #include "queue.h" +#include "lib/json.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" #include "bgpd/bgp_debug.h" @@ -49,12 +50,16 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA inforation at each peer. */ void -bgp_capability_vty_out (struct vty *vty, struct peer *peer) +bgp_capability_vty_out (struct vty *vty, struct peer *peer, u_char use_json, json_object *json_neigh) { char *pnt; char *end; struct capability_mp_data mpc; struct capability_header *hdr; + json_object *json_cap = NULL; + + if (use_json) + json_cap = json_object_new_object(); pnt = peer->notify.data; end = pnt + peer->notify.length; @@ -72,46 +77,89 @@ bgp_capability_vty_out (struct vty *vty, struct peer *peer) if (hdr->code == CAPABILITY_CODE_MP) { - vty_out (vty, " Capability error for: Multi protocol "); - - switch (ntohs (mpc.afi)) - { - case AFI_IP: - vty_out (vty, "AFI IPv4, "); - break; - case AFI_IP6: - vty_out (vty, "AFI IPv6, "); - break; - default: - vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi)); - break; - } - switch (mpc.safi) - { - case SAFI_UNICAST: - vty_out (vty, "SAFI Unicast"); - break; - case SAFI_MULTICAST: - vty_out (vty, "SAFI Multicast"); - break; - case SAFI_MPLS_LABELED_VPN: - vty_out (vty, "SAFI MPLS-labeled VPN"); - break; - default: - vty_out (vty, "SAFI Unknown %d ", mpc.safi); - break; - } - vty_out (vty, "%s", VTY_NEWLINE); - } + if (use_json) + { + switch (ntohs (mpc.afi)) + { + case AFI_IP: + json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv4"); + break; + case AFI_IP6: + json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv6"); + break; + default: + json_object_int_add(json_cap, "capabilityErrorMultiProtocolAfiUnknown", ntohs (mpc.afi)); + break; + } + switch (mpc.safi) + { + case SAFI_UNICAST: + json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "unicast"); + break; + case SAFI_MULTICAST: + json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "multicast"); + break; + case SAFI_MPLS_LABELED_VPN: + json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN"); + break; + default: + json_object_int_add(json_cap, "capabilityErrorMultiProtocolSafiUnknown", mpc.safi); + break; + } + } + else + { + vty_out (vty, " Capability error for: Multi protocol "); + switch (ntohs (mpc.afi)) + { + case AFI_IP: + vty_out (vty, "AFI IPv4, "); + break; + case AFI_IP6: + vty_out (vty, "AFI IPv6, "); + break; + default: + vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi)); + break; + } + switch (mpc.safi) + { + case SAFI_UNICAST: + vty_out (vty, "SAFI Unicast"); + break; + case SAFI_MULTICAST: + vty_out (vty, "SAFI Multicast"); + break; + case SAFI_MPLS_LABELED_VPN: + vty_out (vty, "SAFI MPLS-labeled VPN"); + break; + default: + vty_out (vty, "SAFI Unknown %d ", mpc.safi); + break; + } + vty_out (vty, "%s", VTY_NEWLINE); + } + } else if (hdr->code >= 128) - vty_out (vty, " Capability error: vendor specific capability code %d", - hdr->code); + { + if (use_json) + json_object_int_add(json_cap, "capabilityErrorVendorSpecificCapabilityCode", hdr->code); + else + vty_out (vty, " Capability error: vendor specific capability code %d", + hdr->code); + } else - vty_out (vty, " Capability error: unknown capability code %d", - hdr->code); - + { + if (use_json) + json_object_int_add(json_cap, "capabilityErrorUnknownCapabilityCode", hdr->code); + else + vty_out (vty, " Capability error: unknown capability code %d", + hdr->code); + } pnt += hdr->length + 2; } + if (use_json) + json_object_object_add(json_neigh, "capabilityErrors", json_cap); } static void diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index ca40c64b64..f47d04015e 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -109,7 +109,7 @@ struct capability_gr extern int bgp_open_option_parse (struct peer *, u_char, int *); extern void bgp_open_capability (struct stream *, struct peer *); -extern void bgp_capability_vty_out (struct vty *, struct peer *); +extern void bgp_capability_vty_out (struct vty *, struct peer *, u_char, json_object *); extern as_t peek_for_as4_capability (struct peer *, u_char); extern int bgp_afi_safi_valid_indices (afi_t, safi_t *); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 24ebdaaa6a..1f2346c743 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include +#include "lib/json.h" #include "prefix.h" #include "linklist.h" #include "memory.h" @@ -6478,14 +6479,14 @@ route_vty_out_route (struct prefix *p, struct vty *vty) destination = ntohl (p->u.prefix4.s_addr); if ((IN_CLASSC (destination) && p->prefixlen == 24) - || (IN_CLASSB (destination) && p->prefixlen == 16) - || (IN_CLASSA (destination) && p->prefixlen == 8) - || p->u.prefix4.s_addr == 0) - { - /* When mask is natural, mask is not displayed. */ - } + || (IN_CLASSB (destination) && p->prefixlen == 16) + || (IN_CLASSA (destination) && p->prefixlen == 8) + || p->u.prefix4.s_addr == 0) + { + /* When mask is natural, mask is not displayed. */ + } else - len += vty_out (vty, "/%d", p->prefixlen); + len += vty_out (vty, "/%d", p->prefixlen); } else len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), @@ -6765,6 +6766,13 @@ route_vty_out (struct vty *vty, struct prefix *p, else vty_out (vty, "%s", bgp_origin_str[attr->origin]); } + else + { + if (json_paths) + json_object_string_add(json_path, "alert", "No attributes"); + else + vty_out (vty, "No attributes to print%s", VTY_NEWLINE); + } if (json_paths) { @@ -6789,89 +6797,156 @@ route_vty_out (struct vty *vty, struct prefix *p, /* called from terminal list command */ void -route_vty_out_tmp (struct vty *vty, struct prefix *p, - struct attr *attr, safi_t safi) +route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t safi, + u_char use_json, json_object *json_ar) { + json_object *json_status = NULL; + json_object *json_net = NULL; + char buff[BUFSIZ]; /* Route status display. */ - vty_out (vty, "*"); - vty_out (vty, ">"); - vty_out (vty, " "); + if (use_json) + { + json_status = json_object_new_object(); + json_net = json_object_new_object(); + } + else + { + vty_out (vty, "*"); + vty_out (vty, ">"); + vty_out (vty, " "); + } /* print prefix and mask */ - route_vty_out_route (p, vty); + if (use_json) + json_object_string_add(json_net, "addrPrefix", inet_ntop (p->family, &p->u.prefix, buff, BUFSIZ)); + else + route_vty_out_route (p, vty); /* Print attribute */ if (attr) { - if (p->family == AF_INET - && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) - { - if (safi == SAFI_MPLS_VPN) - vty_out (vty, "%-16s", - inet_ntoa (attr->extra->mp_nexthop_global_in)); - else - vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); - } -#ifdef HAVE_IPV6 - else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + if (use_json) { - int len; - char buf[BUFSIZ]; - - assert (attr->extra); + if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) + { + if (safi == SAFI_MPLS_VPN) + json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in)); + else + json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop)); + } +#ifdef HAVE_IPV6 + else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + { + char buf[BUFSIZ]; - len = vty_out (vty, "%s", - inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, - buf, BUFSIZ)); - len = 16 - len; - if (len < 1) - vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " "); + json_object_string_add(json_net, "netHopGloabal", inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, + buf, BUFSIZ)); + } +#endif /* HAVE_IPV6 */ + + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) + json_object_int_add(json_net, "metric", attr->med); + + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) + json_object_int_add(json_net, "localPref", attr->local_pref); + + if (attr->extra) + json_object_int_add(json_net, "weight", attr->extra->weight); else - vty_out (vty, "%*s", len, " "); + json_object_int_add(json_net, "weight", 0); + + /* Print aspath */ + if (attr->aspath) + json_object_string_add(json_net, "asPath", attr->aspath->str); + + /* Print origin */ + json_object_string_add(json_net, "bgpOriginCode", bgp_origin_str[attr->origin]); } + else + { + if (p->family == AF_INET && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) + { + if (safi == SAFI_MPLS_VPN) + vty_out (vty, "%-16s", + inet_ntoa (attr->extra->mp_nexthop_global_in)); + else + vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); + } +#ifdef HAVE_IPV6 + else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + { + int len; + char buf[BUFSIZ]; + + assert (attr->extra); + + len = vty_out (vty, "%s", + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, + buf, BUFSIZ)); + len = 16 - len; + if (len < 1) + vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " "); + else + vty_out (vty, "%*s", len, " "); + } #endif /* HAVE_IPV6 */ + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) + vty_out (vty, "%10u", attr->med); + else + vty_out (vty, " "); - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) - vty_out (vty, "%10u", attr->med); - else - vty_out (vty, " "); + if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) + vty_out (vty, "%7u", attr->local_pref); + else + vty_out (vty, " "); - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - vty_out (vty, "%7u", attr->local_pref); - else - vty_out (vty, " "); - - vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0)); - - /* Print aspath */ - if (attr->aspath) - aspath_print_vty (vty, "%s", attr->aspath, " "); + vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0)); - /* Print origin */ - vty_out (vty, "%s", bgp_origin_str[attr->origin]); - } + /* Print aspath */ + if (attr->aspath) + aspath_print_vty (vty, "%s", attr->aspath, " "); - vty_out (vty, "%s", VTY_NEWLINE); + /* Print origin */ + vty_out (vty, "%s", bgp_origin_str[attr->origin]); + } + } + if (use_json) + { + json_object_boolean_true_add(json_status, "*"); + json_object_boolean_true_add(json_status, ">"); + json_object_object_add(json_net, "appliedStatusSymbols", json_status); + char buf_cut[BUFSIZ]; + json_object_object_add(json_ar, inet_ntop (p->family, &p->u.prefix, buf_cut, BUFSIZ), json_net); + } + else + vty_out (vty, "%s", VTY_NEWLINE); } void route_vty_out_tag (struct vty *vty, struct prefix *p, - struct bgp_info *binfo, int display, safi_t safi) + struct bgp_info *binfo, int display, safi_t safi, json_object *json) { + json_object *json_out = NULL; struct attr *attr; u_int32_t label = 0; if (!binfo->extra) return; + + if (json) + json_out = json_object_new_object(); /* short status lead text */ - route_vty_short_status_out (vty, binfo, NULL); + route_vty_short_status_out (vty, binfo, json_out); /* print prefix and mask */ - if (! display) - route_vty_out_route (p, vty); - else - vty_out (vty, "%*s", 17, " "); + if (json == NULL) + { + if (! display) + route_vty_out_route (p, vty); + else + vty_out (vty, "%*s", 17, " "); + } /* Print attribute */ attr = binfo->attr; @@ -6881,65 +6956,115 @@ route_vty_out_tag (struct vty *vty, struct prefix *p, && (safi == SAFI_MPLS_VPN || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) { if (safi == SAFI_MPLS_VPN) - vty_out (vty, "%-16s", - inet_ntoa (attr->extra->mp_nexthop_global_in)); + { + if (json) + json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in)); + else + vty_out (vty, "%-16s", inet_ntoa (attr->extra->mp_nexthop_global_in)); + } else - vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); + { + if (json) + json_object_string_add(json_out, "nexthop", inet_ntoa (attr->nexthop)); + else + vty_out (vty, "%-16s", inet_ntoa (attr->nexthop)); + } } #ifdef HAVE_IPV6 else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) { assert (attr->extra); - char buf[BUFSIZ]; - char buf1[BUFSIZ]; + char buf_a[BUFSIZ]; + char buf_b[BUFSIZ]; + char buf_c[BUFSIZ]; if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL) - vty_out (vty, "%s", - inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, - buf, BUFSIZ)); + { + if (json) + json_object_string_add(json_out, "mpNexthopGlobalIn", + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, buf_a, BUFSIZ)); + else + vty_out (vty, "%s", + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, + buf_a, BUFSIZ)); + } else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) - vty_out (vty, "%s(%s)", - inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, - buf, BUFSIZ), - inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local, - buf1, BUFSIZ)); - + { + if (json) + { + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, + buf_a, BUFSIZ); + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local, + buf_b, BUFSIZ); + sprintf(buf_c, "%s(%s)", buf_a, buf_b); + json_object_string_add(json_out, "mpNexthopGlobalLocal", buf_c); + } + else + vty_out (vty, "%s(%s)", + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, + buf_a, BUFSIZ), + inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local, + buf_b, BUFSIZ)); + } + } #endif /* HAVE_IPV6 */ } label = decode_label (binfo->extra->tag); - vty_out (vty, "notag/%d", label); - - vty_out (vty, "%s", VTY_NEWLINE); + if (json) + { + if (label) + json_object_int_add(json_out, "notag", label); + json_object_array_add(json, json_out); + } + else + { + vty_out (vty, "notag/%d", label); + vty_out (vty, "%s", VTY_NEWLINE); + } } /* dampening route */ static void -damp_route_vty_out (struct vty *vty, struct prefix *p, - struct bgp_info *binfo, int display, safi_t safi) +damp_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo, + int display, safi_t safi, u_char use_json, json_object *json) { struct attr *attr; int len; char timebuf[BGP_UPTIME_LEN]; /* short status lead text */ - route_vty_short_status_out (vty, binfo, NULL); + route_vty_short_status_out (vty, binfo, json); /* print prefix and mask */ - if (! display) - route_vty_out_route (p, vty); - else - vty_out (vty, "%*s", 17, " "); + if (!use_json) + { + if (! display) + route_vty_out_route (p, vty); + else + vty_out (vty, "%*s", 17, " "); + } len = vty_out (vty, "%s", binfo->peer->host); len = 17 - len; if (len < 1) - vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " "); + { + if (!use_json) + vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " "); + } else - vty_out (vty, "%*s", len, " "); + { + if (use_json) + json_object_int_add(json, "peerHost", len); + else + vty_out (vty, "%*s", len, " "); + } - vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN)); + if (use_json) + bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json); + else + vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json)); /* Print attribute */ attr = binfo->attr; @@ -6947,18 +7072,27 @@ damp_route_vty_out (struct vty *vty, struct prefix *p, { /* Print aspath */ if (attr->aspath) - aspath_print_vty (vty, "%s", attr->aspath, " "); + { + if (use_json) + json_object_string_add(json, "asPath", attr->aspath->str); + else + aspath_print_vty (vty, "%s", attr->aspath, " "); + } /* Print origin */ - vty_out (vty, "%s", bgp_origin_str[attr->origin]); + if (use_json) + json_object_string_add(json, "origin", bgp_origin_str[attr->origin]); + else + vty_out (vty, "%s", bgp_origin_str[attr->origin]); } - vty_out (vty, "%s", VTY_NEWLINE); + if (!use_json) + vty_out (vty, "%s", VTY_NEWLINE); } /* flap route */ static void -flap_route_vty_out (struct vty *vty, struct prefix *p, - struct bgp_info *binfo, int display, safi_t safi) +flap_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo, + int display, safi_t safi, u_char use_json, json_object *json) { struct attr *attr; struct bgp_damp_info *bdi; @@ -6971,36 +7105,66 @@ flap_route_vty_out (struct vty *vty, struct prefix *p, bdi = binfo->extra->damp_info; /* short status lead text */ - route_vty_short_status_out (vty, binfo, NULL); + route_vty_short_status_out (vty, binfo, json); /* print prefix and mask */ - if (! display) - route_vty_out_route (p, vty); - else - vty_out (vty, "%*s", 17, " "); + if (!use_json) + { + if (! display) + route_vty_out_route (p, vty); + else + vty_out (vty, "%*s", 17, " "); + } len = vty_out (vty, "%s", binfo->peer->host); len = 16 - len; if (len < 1) - vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " "); + { + if (!use_json) + vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " "); + } else - vty_out (vty, "%*s", len, " "); + { + if (use_json) + json_object_int_add(json, "peerHost", len); + else + vty_out (vty, "%*s", len, " "); + } len = vty_out (vty, "%d", bdi->flap); len = 5 - len; if (len < 1) - vty_out (vty, " "); + { + if (!use_json) + vty_out (vty, " "); + } else - vty_out (vty, "%*s ", len, " "); - - vty_out (vty, "%s ", peer_uptime (bdi->start_time, - timebuf, BGP_UPTIME_LEN)); + { + if (use_json) + json_object_int_add(json, "bdiFlap", len); + else + vty_out (vty, "%*s", len, " "); + } + + if (use_json) + peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json); + else + vty_out (vty, "%s ", peer_uptime (bdi->start_time, + timebuf, BGP_UPTIME_LEN, 0, NULL)); if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) - vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN)); + { + if (use_json) + bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json); + else + vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json)); + } else - vty_out (vty, "%*s ", 8, " "); + { + if (!use_json) + vty_out (vty, "%*s ", 8, " "); + } /* Print attribute */ attr = binfo->attr; @@ -7008,12 +7172,21 @@ flap_route_vty_out (struct vty *vty, struct prefix *p, { /* Print aspath */ if (attr->aspath) - aspath_print_vty (vty, "%s", attr->aspath, " "); + { + if (use_json) + json_object_string_add(json, "asPath", attr->aspath->str); + else + aspath_print_vty (vty, "%s", attr->aspath, " "); + } /* Print origin */ - vty_out (vty, "%s", bgp_origin_str[attr->origin]); + if (use_json) + json_object_string_add(json, "origin", bgp_origin_str[attr->origin]); + else + vty_out (vty, "%s", bgp_origin_str[attr->origin]); } - vty_out (vty, "%s", VTY_NEWLINE); + if (!use_json) + vty_out (vty, "%s", VTY_NEWLINE); } static void @@ -7644,7 +7817,7 @@ enum bgp_show_type static int bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router_id, - enum bgp_show_type type, void *output_arg, u_char use_json) + enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_info *ri; struct bgp_node *rn; @@ -7673,216 +7846,225 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) if (rn->info != NULL) { - display = 0; + display = 0; if (use_json) json_paths = json_object_new_array(); else json_paths = NULL; - for (ri = rn->info; ri; ri = ri->next) - { - if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_address - || type == bgp_show_type_flap_prefix - || type == bgp_show_type_flap_cidr_only - || type == bgp_show_type_flap_regexp - || type == bgp_show_type_flap_filter_list - || type == bgp_show_type_flap_prefix_list - || type == bgp_show_type_flap_prefix_longer - || type == bgp_show_type_flap_route_map - || type == bgp_show_type_flap_neighbor - || type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) - { - if (!(ri->extra && ri->extra->damp_info)) - continue; - } - if (type == bgp_show_type_regexp - || type == bgp_show_type_flap_regexp) - { - regex_t *regex = output_arg; - - if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH) - continue; - } - if (type == bgp_show_type_prefix_list - || type == bgp_show_type_flap_prefix_list) - { - struct prefix_list *plist = output_arg; - - if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT) - continue; - } - if (type == bgp_show_type_filter_list - || type == bgp_show_type_flap_filter_list) - { - struct as_list *as_list = output_arg; + for (ri = rn->info; ri; ri = ri->next) + { + if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_address + || type == bgp_show_type_flap_prefix + || type == bgp_show_type_flap_cidr_only + || type == bgp_show_type_flap_regexp + || type == bgp_show_type_flap_filter_list + || type == bgp_show_type_flap_prefix_list + || type == bgp_show_type_flap_prefix_longer + || type == bgp_show_type_flap_route_map + || type == bgp_show_type_flap_neighbor + || type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) + { + if (!(ri->extra && ri->extra->damp_info)) + continue; + } + if (type == bgp_show_type_regexp + || type == bgp_show_type_flap_regexp) + { + regex_t *regex = output_arg; - if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT) - continue; - } - if (type == bgp_show_type_route_map - || type == bgp_show_type_flap_route_map) - { - struct route_map *rmap = output_arg; - struct bgp_info binfo; - struct attr dummy_attr; - struct attr_extra dummy_extra; - int ret; + if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH) + continue; + } + if (type == bgp_show_type_prefix_list + || type == bgp_show_type_flap_prefix_list) + { + struct prefix_list *plist = output_arg; - dummy_attr.extra = &dummy_extra; - bgp_attr_dup (&dummy_attr, ri->attr); + if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT) + continue; + } + if (type == bgp_show_type_filter_list + || type == bgp_show_type_flap_filter_list) + { + struct as_list *as_list = output_arg; - binfo.peer = ri->peer; - binfo.attr = &dummy_attr; + if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT) + continue; + } + if (type == bgp_show_type_route_map + || type == bgp_show_type_flap_route_map) + { + struct route_map *rmap = output_arg; + struct bgp_info binfo; + struct attr dummy_attr; + struct attr_extra dummy_extra; + int ret; - ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo); - if (ret == RMAP_DENYMATCH) - continue; - } - if (type == bgp_show_type_neighbor - || type == bgp_show_type_flap_neighbor - || type == bgp_show_type_damp_neighbor) - { - union sockunion *su = output_arg; + dummy_attr.extra = &dummy_extra; + bgp_attr_dup (&dummy_attr, ri->attr); - if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su)) - continue; - } - if (type == bgp_show_type_cidr_only - || type == bgp_show_type_flap_cidr_only) - { - u_int32_t destination; - - destination = ntohl (rn->p.u.prefix4.s_addr); - if (IN_CLASSC (destination) && rn->p.prefixlen == 24) - continue; - if (IN_CLASSB (destination) && rn->p.prefixlen == 16) - continue; - if (IN_CLASSA (destination) && rn->p.prefixlen == 8) - continue; - } - if (type == bgp_show_type_prefix_longer - || type == bgp_show_type_flap_prefix_longer) - { - struct prefix *p = output_arg; + binfo.peer = ri->peer; + binfo.attr = &dummy_attr; - if (! prefix_match (p, &rn->p)) - continue; - } - if (type == bgp_show_type_community_all) - { - if (! ri->attr->community) - continue; - } - if (type == bgp_show_type_community) - { - struct community *com = output_arg; + ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo); + if (ret == RMAP_DENYMATCH) + continue; + } + if (type == bgp_show_type_neighbor + || type == bgp_show_type_flap_neighbor + || type == bgp_show_type_damp_neighbor) + { + union sockunion *su = output_arg; - if (! ri->attr->community || - ! community_match (ri->attr->community, com)) - continue; - } - if (type == bgp_show_type_community_exact) - { - struct community *com = output_arg; + if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su)) + continue; + } + if (type == bgp_show_type_cidr_only + || type == bgp_show_type_flap_cidr_only) + { + u_int32_t destination; - if (! ri->attr->community || - ! community_cmp (ri->attr->community, com)) - continue; - } - if (type == bgp_show_type_community_list) - { - struct community_list *list = output_arg; + destination = ntohl (rn->p.u.prefix4.s_addr); + if (IN_CLASSC (destination) && rn->p.prefixlen == 24) + continue; + if (IN_CLASSB (destination) && rn->p.prefixlen == 16) + continue; + if (IN_CLASSA (destination) && rn->p.prefixlen == 8) + continue; + } + if (type == bgp_show_type_prefix_longer + || type == bgp_show_type_flap_prefix_longer) + { + struct prefix *p = output_arg; - if (! community_list_match (ri->attr->community, list)) - continue; - } - if (type == bgp_show_type_community_list_exact) - { - struct community_list *list = output_arg; + if (! prefix_match (p, &rn->p)) + continue; + } + if (type == bgp_show_type_community_all) + { + if (! ri->attr->community) + continue; + } + if (type == bgp_show_type_community) + { + struct community *com = output_arg; - if (! community_list_exact_match (ri->attr->community, list)) - continue; - } - if (type == bgp_show_type_flap_address - || type == bgp_show_type_flap_prefix) - { - struct prefix *p = output_arg; + if (! ri->attr->community || + ! community_match (ri->attr->community, com)) + continue; + } + if (type == bgp_show_type_community_exact) + { + struct community *com = output_arg; - if (! prefix_match (&rn->p, p)) - continue; + if (! ri->attr->community || + ! community_cmp (ri->attr->community, com)) + continue; + } + if (type == bgp_show_type_community_list) + { + struct community_list *list = output_arg; - if (type == bgp_show_type_flap_prefix) - if (p->prefixlen != rn->p.prefixlen) - continue; - } - if (type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) - { - if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED) - || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) - continue; - } + if (! community_list_match (ri->attr->community, list)) + continue; + } + if (type == bgp_show_type_community_list_exact) + { + struct community_list *list = output_arg; - if (!use_json && header) - { - vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (*router_id), VTY_NEWLINE); - vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - if (type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) - vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE); - else if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_address - || type == bgp_show_type_flap_prefix - || type == bgp_show_type_flap_cidr_only - || type == bgp_show_type_flap_regexp - || type == bgp_show_type_flap_filter_list - || type == bgp_show_type_flap_prefix_list - || type == bgp_show_type_flap_prefix_longer - || type == bgp_show_type_flap_route_map - || type == bgp_show_type_flap_neighbor) - vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE); - else - vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); - header = 0; - } + if (! community_list_exact_match (ri->attr->community, list)) + continue; + } + if (type == bgp_show_type_flap_address + || type == bgp_show_type_flap_prefix) + { + struct prefix *p = output_arg; - if (type == bgp_show_type_dampend_paths - || type == bgp_show_type_damp_neighbor) - damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST); - else if (type == bgp_show_type_flap_statistics - || type == bgp_show_type_flap_address - || type == bgp_show_type_flap_prefix - || type == bgp_show_type_flap_cidr_only - || type == bgp_show_type_flap_regexp - || type == bgp_show_type_flap_filter_list - || type == bgp_show_type_flap_prefix_list - || type == bgp_show_type_flap_prefix_longer - || type == bgp_show_type_flap_route_map - || type == bgp_show_type_flap_neighbor) - flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST); - else - route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, json_paths); - display++; - } + if (! prefix_match (&rn->p, p)) + continue; - if (use_json) - { - p = &rn->p; - sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); - json_object_object_add(json_routes, buf2, json_paths); + if (type == bgp_show_type_flap_prefix) + if (p->prefixlen != rn->p.prefixlen) + continue; + } + if (type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) + { + if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED) + || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) + continue; + } + + if (!use_json && header) + { + vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (*router_id), VTY_NEWLINE); + vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + if (type == bgp_show_type_dampend_paths + || type == bgp_show_type_damp_neighbor) + vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE); + else if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_address + || type == bgp_show_type_flap_prefix + || type == bgp_show_type_flap_cidr_only + || type == bgp_show_type_flap_regexp + || type == bgp_show_type_flap_filter_list + || type == bgp_show_type_flap_prefix_list + || type == bgp_show_type_flap_prefix_longer + || type == bgp_show_type_flap_route_map + || type == bgp_show_type_flap_neighbor) + vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE); + else + vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); + header = 0; + } + + 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, json_paths); + else if (type == bgp_show_type_flap_statistics + || type == bgp_show_type_flap_address + || type == bgp_show_type_flap_prefix + || type == bgp_show_type_flap_cidr_only + || type == bgp_show_type_flap_regexp + || type == bgp_show_type_flap_filter_list + || type == bgp_show_type_flap_prefix_list + || type == bgp_show_type_flap_prefix_longer + || type == bgp_show_type_flap_route_map + || type == bgp_show_type_flap_neighbor) + flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths); + else + route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, json_paths); + display++; } - if (display) - output_count++; + if (display) + { + output_count++; + if (use_json) + { + p = &rn->p; + sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen); + json_object_object_add(json_routes, buf2, json_paths); + } + } } if (use_json) { - json_object_object_add(json, "routes", json_routes); + if (output_count == 0) + { + if (type == bgp_show_type_normal) + json_object_string_add(json, "alert", "No BGP network exists"); + else + json_object_string_add(json, "alert", "No route output"); + } + else + json_object_object_add(json, "routes", json_routes); vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); json_object_free(json); } @@ -7892,11 +8074,11 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router if (output_count == 0) { if (type == bgp_show_type_normal) - vty_out (vty, "No BGP network exists%s", VTY_NEWLINE); + vty_out (vty, "No BGP network exists%s", VTY_NEWLINE); } else vty_out (vty, "%sTotal number of prefixes %ld%s", - VTY_NEWLINE, output_count, VTY_NEWLINE); + VTY_NEWLINE, output_count, VTY_NEWLINE); } return CMD_SUCCESS; @@ -7904,21 +8086,22 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router 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) + enum bgp_show_type type, void *output_arg, u_char use_json) { struct bgp_table *table; - if (bgp == NULL) { - bgp = bgp_get_default (); - } + if (bgp == NULL) + { + bgp = bgp_get_default (); + } if (bgp == NULL) { - vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + if (!use_json) + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); return CMD_WARNING; } - table = bgp->rib[afi][safi]; return bgp_show_table (vty, table, &bgp->router_id, type, output_arg, use_json); @@ -11089,7 +11272,7 @@ DEFUN (show_ipv6_mbgp_prefix_longer, static struct peer * peer_lookup_in_view (struct vty *vty, const char *view_name, - const char *ip_str) + const char *ip_str, u_char use_json) { int ret; struct bgp *bgp; @@ -11102,7 +11285,16 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, bgp = bgp_lookup_by_name (view_name); if (! bgp) { - vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Can't find BGP view"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE); return NULL; } } @@ -11111,7 +11303,16 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, bgp = bgp_get_default (); if (! bgp) { - vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No BGP process configured"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); return NULL; } } @@ -11123,8 +11324,17 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, peer = peer_lookup_by_conf_if (bgp, ip_str); if (!peer) { - vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE); - return NULL; + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "malformedAddressOrName", ip_str); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE); + return NULL; } return peer; } @@ -11133,7 +11343,16 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, peer = peer_lookup (bgp, &su); if (! peer) { - vty_out (vty, "No such neighbor%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning","No such neighbor"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No such neighbor%s", VTY_NEWLINE); return NULL; } @@ -11588,15 +11807,31 @@ bgp_peer_count_walker (struct thread *t) } static int -bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) +bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_char use_json) { struct peer_pcounts pcounts = { .peer = peer }; unsigned int i; + json_object *json = NULL; + json_object *json_loop = NULL; + + if (use_json) + { + json = json_object_new_object(); + json_loop = json_object_new_object(); + } if (!peer || !peer->bgp || !peer->afc[afi][safi] || !peer->bgp->rib[afi][safi]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + return CMD_WARNING; } @@ -11605,27 +11840,48 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) pcounts.table = peer->bgp->rib[afi][safi]; /* in-place call via thread subsystem so as to record execution time - * stats for the thread-walk (i.e. ensure this can't be blamed on - * on just vty_read()). - */ + * * stats for the thread-walk (i.e. ensure this can't be blamed on + * * on just vty_read()). + * */ thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0); - vty_out (vty, "Prefix counts for %s, %s%s", - peer->host, afi_safi_print (afi, safi), VTY_NEWLINE); - vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE); - vty_out (vty, "%sCounts from RIB table walk:%s%s", - VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json, "prefixCountsFor", peer->host); + json_object_string_add(json, "multiProtocol", afi_safi_print (afi, safi)); + json_object_int_add(json, "pfxCounter", peer->pcount[afi][safi]); + + for (i = 0; i < PCOUNT_MAX; i++) + json_object_int_add(json_loop, pcount_strs[i], pcounts.count[i]); - for (i = 0; i < PCOUNT_MAX; i++) - vty_out (vty, "%20s: %-10d%s", - pcount_strs[i], pcounts.count[i], VTY_NEWLINE); + json_object_object_add(json, "ribTableWalkCounters", json_loop); - if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) + if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) + { + json_object_string_add(json, "pfxctDriftFor", peer->host); + json_object_string_add(json, "recommended", "Please report this bug, with the above command output"); + } + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else { - vty_out (vty, "%s [pcount] PfxCt drift!%s", - peer->host, VTY_NEWLINE); - vty_out (vty, "Please report this bug, with the above command output%s", - VTY_NEWLINE); + vty_out (vty, "Prefix counts for %s, %s%s", + peer->host, afi_safi_print (afi, safi), VTY_NEWLINE); + vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE); + vty_out (vty, "%sCounts from RIB table walk:%s%s", + VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + + for (i = 0; i < PCOUNT_MAX; i++) + vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts.count[i], VTY_NEWLINE); + + if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) + { + vty_out (vty, "%s [pcount] PfxCt drift!%s", + peer->host, VTY_NEWLINE); + vty_out (vty, "Please report this bug, with the above command output%s", + VTY_NEWLINE); + } } return CMD_SUCCESS; @@ -11633,7 +11889,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) DEFUN (show_ip_bgp_neighbor_prefix_counts, show_ip_bgp_neighbor_prefix_counts_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}", SHOW_STR IP_STR BGP_STR @@ -11641,20 +11897,27 @@ DEFUN (show_ip_bgp_neighbor_prefix_counts, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display detailed prefix count information\n") + "Display detailed prefix count information\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST); + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, use_json); } DEFUN (show_bgp_ipv6_neighbor_prefix_counts, show_bgp_ipv6_neighbor_prefix_counts_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}", SHOW_STR BGP_STR "Address family\n" @@ -11662,20 +11925,27 @@ DEFUN (show_bgp_ipv6_neighbor_prefix_counts, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display detailed prefix count information\n") + "Display detailed prefix count information\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST); + return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST, use_json); } DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, show_ip_bgp_ipv4_neighbor_prefix_counts_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}", SHOW_STR IP_STR BGP_STR @@ -11686,23 +11956,30 @@ DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display detailed prefix count information\n") + "Display detailed prefix count information\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], use_json); if (! peer) return CMD_WARNING; if (strncmp (argv[0], "m", 1) == 0) - return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST); + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST, use_json); - return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST); + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, use_json); } DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts, show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd, - "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts", + "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X|WORD) prefix-counts {json}", SHOW_STR IP_STR BGP_STR @@ -11713,20 +11990,27 @@ DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display detailed prefix count information\n") + "Display detailed prefix count information\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN); + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, use_json); } static void show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, - int in, const char *rmap_name) + int in, const char *rmap_name, u_char use_json, json_object *json) { struct bgp_table *table; struct bgp_adj_in *ain; @@ -11741,11 +12025,46 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, struct attr_extra extra; int ret; struct update_subgroup *subgrp; + json_object *json_scode = NULL; + json_object *json_ocode = NULL; + json_object *json_ar = NULL; + + if (use_json) + { + json_scode = json_object_new_object(); + json_ocode = json_object_new_object(); + json_ar = 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, "multipath", "="); + json_object_string_add(json_scode, "internal", "i"); + json_object_string_add(json_scode, "ribFailure", "r"); + json_object_string_add(json_scode, "stale", "S"); + json_object_string_add(json_scode, "removed", "R"); + + json_object_string_add(json_ocode, "igp", "i"); + json_object_string_add(json_ocode, "egp", "e"); + json_object_string_add(json_ocode, "incomplete", "?"); + } bgp = peer->bgp; if (! bgp) - return; + { + if (use_json) + { + json_object_string_add(json, "alert", "no BGP"); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% No bgp%s", VTY_NEWLINE); + return; + } table = bgp->rib[afi][safi]; @@ -11754,114 +12073,180 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, if (!in && subgrp && CHECK_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) { - vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE); - vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + if (use_json) + { + json_object_int_add(json, "bgpTableVersion", table->version); + 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); + json_object_string_add(json, "bgpOriginatingDefaultNetwork", "0.0.0.0"); + } + else + { + vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE); + vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, "Originating default network 0.0.0.0%s%s", - VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, "Originating default network 0.0.0.0%s%s", + VTY_NEWLINE, VTY_NEWLINE); + } header1 = 0; } attr.extra = &extra; for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn)) - if (in) - { - for (ain = rn->adj_in; ain; ain = ain->next) - if (ain->peer == peer) - { - if (header1) - { - vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE); - vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - header1 = 0; - } - if (header2) - { - vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); - header2 = 0; - } - if (ain->attr) - { - bgp_attr_dup(&attr, ain->attr); - if (bgp_input_modifier(peer, &rn->p, &attr, afi, - safi, rmap_name) != RMAP_DENY) - { - route_vty_out_tmp (vty, &rn->p, &attr, safi); - output_count++; - } - else - filtered_count++; - } - } - } - else - { - adj = bgp_adj_peer_lookup(peer, rn); - if (adj) - { - if (header1) - { - vty_out (vty, "BGP table version is %" PRIu64 ", local router ID " - "is %s%s", table->version, - inet_ntoa (bgp->router_id), VTY_NEWLINE); - vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); - header1 = 0; - } - if (header2) - { - vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); - header2 = 0; - } - if (adj->attr) - { - bgp_attr_dup(&attr, adj->attr); - ret = bgp_output_modifier(peer, &rn->p, &attr, afi, - safi, rmap_name); - - if (ret != RMAP_DENY) - { - route_vty_out_tmp (vty, &rn->p, &attr, safi); - output_count++; - } - else - filtered_count++; - } - } - } + { + if (in) + { + for (ain = rn->adj_in; ain; ain = ain->next) + { + if (ain->peer == peer) + { + if (header1) + { + if (use_json) + { + 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 + { + vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE); + vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + } + header1 = 0; + } + if (header2) + { + if (!use_json) + vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); + header2 = 0; + } + if (ain->attr) + { + bgp_attr_dup(&attr, ain->attr); + if (bgp_input_modifier(peer, &rn->p, &attr, afi, safi, rmap_name) != RMAP_DENY) + { + route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar); + output_count++; + } + else + filtered_count++; + } + } + } + } + else + { + adj = bgp_adj_peer_lookup(peer, rn); + if (adj) + { + if (header1) + { + if (use_json) + { + json_object_int_add(json, "bgpTableVersion", table->version); + 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 + { + vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, + inet_ntoa (bgp->router_id), VTY_NEWLINE); + vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE); + } + header1 = 0; + } + if (header2) + { + if (!use_json) + vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE); + header2 = 0; + } + if (adj->attr) + { + bgp_attr_dup(&attr, adj->attr); + ret = bgp_output_modifier(peer, &rn->p, &attr, afi, safi, rmap_name); + if (ret != RMAP_DENY) + { + route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar); + output_count++; + } + else + filtered_count++; + } + } + } + } + if (use_json) + json_object_object_add(json, "advertisedRoutes", json_ar); if (output_count != 0) - vty_out (vty, "%sTotal number of prefixes %ld%s", - VTY_NEWLINE, output_count, VTY_NEWLINE); + { + if (use_json) + json_object_int_add(json, "totalPrefixCounter", output_count); + else + vty_out (vty, "%sTotal number of prefixes %ld%s", + VTY_NEWLINE, output_count, VTY_NEWLINE); + } + if (use_json) + { + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + } static int peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, - int in, const char *rmap_name) -{ - if (! peer || ! peer->afc[afi][safi]) + int in, const char *rmap_name, u_char use_json) +{ + json_object *json = NULL; + + if (use_json) + json = json_object_new_object(); + + if (!peer || !peer->afc[afi][safi]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + return CMD_WARNING; } - if (in && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) + if (in && !CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) { - vty_out (vty, "%% Inbound soft reconfiguration not enabled%s", - VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled"); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE); + return CMD_WARNING; } - show_adj_route (vty, peer, afi, safi, in, rmap_name); + show_adj_route (vty, peer, afi, safi, in, rmap_name, use_json, json); return CMD_SUCCESS; } DEFUN (show_ip_bgp_view_neighbor_advertised_route, show_ip_bgp_view_neighbor_advertised_route_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR IP_STR BGP_STR @@ -11870,24 +12255,32 @@ DEFUN (show_ip_bgp_view_neighbor_advertised_route, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, NULL); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, NULL, use_json); } DEFUN (show_ip_bgp_neighbor_advertised_route, show_ip_bgp_neighbor_advertised_route_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR IP_STR BGP_STR @@ -11895,26 +12288,34 @@ DEFUN (show_ip_bgp_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; const char *rmap_name = NULL; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - if (argc == 2) + if ((argc == 2 && argv[1] && strcmp(argv[1], "json") != 0) + || (argc == 3)) rmap_name = argv[1]; - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name, use_json); } ALIAS (show_ip_bgp_neighbor_advertised_route, show_ip_bgp_neighbor_advertised_route_rmap_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD {json}", SHOW_STR IP_STR BGP_STR @@ -11922,11 +12323,12 @@ ALIAS (show_ip_bgp_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route, show_ip_bgp_ipv4_neighbor_advertised_route_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR IP_STR BGP_STR @@ -11937,27 +12339,34 @@ DEFUN (show_ip_bgp_ipv4_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; const char *rmap_name = NULL; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], use_json); if (! peer) return CMD_WARNING; - if (argc == 3) + if ((argc == 4) || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0)) rmap_name = argv[2]; if (strncmp (argv[0], "m", 1) == 0) - return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 0, rmap_name); - - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 0, rmap_name, use_json); + else + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0, rmap_name, use_json); } ALIAS (show_ip_bgp_ipv4_neighbor_advertised_route, show_ip_bgp_ipv4_neighbor_advertised_route_rmap_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD {json}", SHOW_STR IP_STR BGP_STR @@ -11969,12 +12378,13 @@ ALIAS (show_ip_bgp_ipv4_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display the routes advertised to a BGP neighbor\n" - "Route-map to control what is displayed\n") + "Route-map to control what is displayed\n" + "JavaScript Object Notation\n") #ifdef HAVE_IPV6 DEFUN (show_bgp_view_neighbor_advertised_route, show_bgp_view_neighbor_advertised_route_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -11983,24 +12393,31 @@ DEFUN (show_bgp_view_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, NULL); + return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, NULL, use_json); } ALIAS (show_bgp_view_neighbor_advertised_route, show_bgp_view_ipv6_neighbor_advertised_route_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -12010,60 +12427,45 @@ ALIAS (show_bgp_view_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_neighbor_advertised_route, show_bgp_neighbor_advertised_route_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; const char *rmap_name = NULL; + u_char use_json; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - if (! peer) + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); + + if (!peer) return CMD_WARNING; - if (argc == 2) + if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) rmap_name = argv[1]; - return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, rmap_name); + return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0, rmap_name, use_json); } -ALIAS (show_bgp_neighbor_advertised_route, - show_bgp_neighbor_advertised_route_rmap_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD", - SHOW_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") - ALIAS (show_bgp_neighbor_advertised_route, show_bgp_ipv6_neighbor_advertised_route_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", - SHOW_STR - BGP_STR - "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") - -ALIAS (show_bgp_neighbor_advertised_route, - show_bgp_ipv6_neighbor_advertised_route_rmap_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes route-map WORD", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR BGP_STR "Address family\n" @@ -12071,12 +12473,13 @@ ALIAS (show_bgp_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") /* old command */ ALIAS (show_bgp_neighbor_advertised_route, ipv6_bgp_neighbor_advertised_route_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR IPV6_STR BGP_STR @@ -12084,12 +12487,13 @@ ALIAS (show_bgp_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_advertised_route, ipv6_mbgp_neighbor_advertised_route_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) advertised-routes {json}", SHOW_STR IPV6_STR MBGP_STR @@ -12098,21 +12502,28 @@ DEFUN (ipv6_mbgp_neighbor_advertised_route, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Neighbor on bgp configured interface\n" - "Display the routes advertised to a BGP neighbor\n") + "Display the routes advertised to a BGP neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) - return CMD_WARNING; + return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0, NULL); + return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0, NULL, use_json); } #endif /* HAVE_IPV6 */ DEFUN (show_bgp_view_neighbor_received_routes, show_bgp_view_neighbor_received_routes_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -12121,24 +12532,41 @@ DEFUN (show_bgp_view_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if (use_json) + { + if (argc == 3) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); + else + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); + } else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + { + if (argc == 2) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); + else + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); + } if (! peer) return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1, NULL); + return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 1, NULL, use_json); } DEFUN (show_ip_bgp_view_neighbor_received_routes, show_ip_bgp_view_neighbor_received_routes_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR IP_STR BGP_STR @@ -12148,24 +12576,31 @@ DEFUN (show_ip_bgp_view_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, NULL); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, NULL, use_json); } ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_view_ipv6_neighbor_received_routes_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -12175,11 +12610,12 @@ ALIAS (show_bgp_view_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_neighbor_received_routes, show_ip_bgp_neighbor_received_routes_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR IP_STR BGP_STR @@ -12187,26 +12623,33 @@ DEFUN (show_ip_bgp_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; const char *rmap_name = NULL; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - if (argc == 2) + if (argc == 3 || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) rmap_name = argv[1]; - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name, use_json); } ALIAS (show_ip_bgp_neighbor_received_routes, show_ip_bgp_neighbor_received_routes_rmap_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD {json}", SHOW_STR IP_STR BGP_STR @@ -12214,11 +12657,12 @@ ALIAS (show_ip_bgp_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, show_ip_bgp_ipv4_neighbor_received_routes_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR IP_STR BGP_STR @@ -12229,27 +12673,34 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; const char *rmap_name = NULL; + u_char use_json; - peer = peer_lookup_in_view (vty, NULL, argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + peer = peer_lookup_in_view (vty, NULL, argv[1], use_json); if (! peer) return CMD_WARNING; - if (argc == 3) + if (argc == 4 || (argc == 3 && argv[2] && strcmp(argv[2], "json") != 0)) rmap_name = argv[2]; if (strncmp (argv[0], "m", 1) == 0) - return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1, rmap_name); - - return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name); + return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1, rmap_name, use_json); + else + return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1, rmap_name, use_json); } ALIAS (show_ip_bgp_ipv4_neighbor_received_routes, show_ip_bgp_ipv4_neighbor_received_routes_rmap_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD {json}", SHOW_STR IP_STR BGP_STR @@ -12260,14 +12711,15 @@ ALIAS (show_ip_bgp_ipv4_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd, #ifdef HAVE_IPV6 - "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes)", + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes) {json}", #else - "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes)", + "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) (advertised-routes|received-routes) {json}", #endif SHOW_STR BGP_STR @@ -12284,17 +12736,24 @@ DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display the advertised routes to neighbor\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { int afi; int safi; int in; struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; #ifdef HAVE_IPV6 - peer = peer_lookup_in_view (vty, argv[0], argv[3]); + peer = peer_lookup_in_view (vty, argv[0], argv[3], use_json); #else - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], use_json); #endif if (! peer) @@ -12310,12 +12769,12 @@ DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, in = (strncmp (argv[3], "r", 1) == 0) ? 1 : 0; #endif - return peer_adj_routes (vty, peer, afi, safi, in, NULL); + return peer_adj_routes (vty, peer, afi, safi, in, NULL, use_json); } DEFUN (show_ip_bgp_neighbor_received_prefix_filter, show_ip_bgp_neighbor_received_prefix_filter_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR IP_STR BGP_STR @@ -12324,20 +12783,40 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object Notation\n") { char name[BUFSIZ]; union sockunion su; struct peer *peer; int count, ret; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; ret = str2sockunion (argv[0], &su); if (ret < 0) { peer = peer_lookup_by_conf_if (NULL, argv[0]); - if (!peer) + if (! peer) { - vty_out (vty, "Malformed address or name: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_object *json_sub = NULL; + json_no = json_object_new_object(); + json_sub = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address or name"); + json_object_string_add(json_sub, "warningCause", argv[0]); + json_object_object_add(json_no, "detail", json_sub); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } } @@ -12345,15 +12824,41 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, { peer = peer_lookup (NULL, &su); if (! peer) - return CMD_WARNING; + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Peer not found"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No peer%s", VTY_NEWLINE); + return CMD_WARNING; + } } sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST); - count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name); + count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name, use_json); if (count) { - vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE); - prefix_bgp_show_prefix_list (vty, AFI_IP, name); + if (!use_json) + vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE); + prefix_bgp_show_prefix_list (vty, AFI_IP, name, use_json); + } + else + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_boolean_true_add(json_no, "noFuntionalOutput"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No functional output%s", VTY_NEWLINE); } return CMD_SUCCESS; @@ -12361,7 +12866,7 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter, DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, show_ip_bgp_ipv4_neighbor_received_prefix_filter_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR IP_STR BGP_STR @@ -12373,20 +12878,40 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object Notation\n") { char name[BUFSIZ]; union sockunion su; struct peer *peer; int count, ret; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; ret = str2sockunion (argv[1], &su); if (ret < 0) { peer = peer_lookup_by_conf_if (NULL, argv[1]); - if (!peer) + if (! peer) { - vty_out (vty, "Malformed address or name: %s%s", argv[1], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_object *json_sub = NULL; + json_no = json_object_new_object(); + json_sub = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address or name"); + json_object_string_add(json_sub, "warningCause", argv[1]); + json_object_object_add(json_no, "detail", json_sub); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed address or name: %s%s", argv[1], VTY_NEWLINE); return CMD_WARNING; } } @@ -12394,72 +12919,88 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter, { peer = peer_lookup (NULL, &su); if (! peer) - return CMD_WARNING; + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Peer not found"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No peer%s", VTY_NEWLINE); + return CMD_WARNING; + } } if (strncmp (argv[0], "m", 1) == 0) { sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_MULTICAST); - count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name); + count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name, use_json); if (count) - { - vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE); - prefix_bgp_show_prefix_list (vty, AFI_IP, name); - } + { + if (!use_json) + vty_out (vty, "Address family: IPv4 Multicast%s", VTY_NEWLINE); + prefix_bgp_show_prefix_list (vty, AFI_IP, name, use_json); + } + else + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_boolean_true_add(json_no, "noFuntionalOutput"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No functional output%s", VTY_NEWLINE); + } } else { sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST); - count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name); + count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name, use_json); if (count) - { - vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE); - prefix_bgp_show_prefix_list (vty, AFI_IP, name); - } + { + if (!use_json) + vty_out (vty, "Address family: IPv4 Unicast%s", VTY_NEWLINE); + prefix_bgp_show_prefix_list (vty, AFI_IP, name, use_json); + } + else + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_boolean_true_add(json_no, "noFuntionalOutput"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No functional output%s", VTY_NEWLINE); + } } return CMD_SUCCESS; } - - #ifdef HAVE_IPV6 ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_neighbor_received_routes_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_received_routes, show_bgp_ipv6_neighbor_received_routes_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", - SHOW_STR - BGP_STR - "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") - -ALIAS (show_bgp_view_neighbor_received_routes, - show_bgp_neighbor_received_routes_rmap_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD", - SHOW_STR - BGP_STR - "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n" - "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") - -ALIAS (show_bgp_view_neighbor_received_routes, - show_bgp_ipv6_neighbor_received_routes_rmap_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes route-map WORD", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR BGP_STR "Address family\n" @@ -12467,11 +13008,12 @@ ALIAS (show_bgp_view_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_neighbor_received_prefix_filter, show_bgp_neighbor_received_prefix_filter_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" @@ -12479,20 +13021,40 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object Notation\n") { char name[BUFSIZ]; union sockunion su; struct peer *peer; int count, ret; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; ret = str2sockunion (argv[0], &su); if (ret < 0) { peer = peer_lookup_by_conf_if (NULL, argv[0]); - if (!peer) + if (! peer) { - vty_out (vty, "Malformed address or name: %s%s", argv[0], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_object *json_sub = NULL; + json_no = json_object_new_object(); + json_sub = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address or name"); + json_object_string_add(json_sub, "warningCause", argv[0]); + json_object_object_add(json_no, "detail", json_sub); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed address or name: %s%s", argv[0], VTY_NEWLINE); return CMD_WARNING; } } @@ -12500,15 +13062,41 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, { peer = peer_lookup (NULL, &su); if (! peer) - return CMD_WARNING; + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No Peer"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No peer%s", VTY_NEWLINE); + return CMD_WARNING; + } } sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST); - count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name); + count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name, use_json); if (count) { - vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE); - prefix_bgp_show_prefix_list (vty, AFI_IP6, name); + if (!use_json) + vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE); + prefix_bgp_show_prefix_list (vty, AFI_IP6, name, use_json); + } + else + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_boolean_true_add(json_no, "noFuntionalOutput"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No functional output%s", VTY_NEWLINE); } return CMD_SUCCESS; @@ -12516,7 +13104,7 @@ DEFUN (show_bgp_neighbor_received_prefix_filter, ALIAS (show_bgp_neighbor_received_prefix_filter, show_bgp_ipv6_neighbor_received_prefix_filter_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR BGP_STR "Address family\n" @@ -12525,12 +13113,13 @@ ALIAS (show_bgp_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object Notation\n") /* old command */ ALIAS (show_bgp_view_neighbor_received_routes, ipv6_bgp_neighbor_received_routes_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR IPV6_STR BGP_STR @@ -12538,12 +13127,13 @@ ALIAS (show_bgp_view_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_received_routes, ipv6_mbgp_neighbor_received_routes_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) received-routes {json}", SHOW_STR IPV6_STR MBGP_STR @@ -12551,20 +13141,27 @@ DEFUN (ipv6_mbgp_neighbor_received_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the received routes from neighbor\n") + "Display the received routes from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; - return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 1, NULL); + return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 1, NULL,use_json); } DEFUN (show_bgp_view_neighbor_received_prefix_filter, show_bgp_view_neighbor_received_prefix_filter_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR BGP_STR "BGP view\n" @@ -12574,29 +13171,58 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object Notation\n") { char name[BUFSIZ]; union sockunion su; struct peer *peer; struct bgp *bgp; int count, ret; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; /* BGP structure lookup. */ bgp = bgp_lookup_by_name (argv[0]); if (bgp == NULL) - { - vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE); - return CMD_WARNING; - } - + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "Can't find BGP view"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE); + return CMD_WARNING; + } + ret = str2sockunion (argv[1], &su); if (ret < 0) { peer = peer_lookup_by_conf_if (bgp, argv[1]); - if (!peer) + if (! peer) { - vty_out (vty, "%% Malformed address or name: %s%s", argv[1], VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_object *json_sub = NULL; + json_no = json_object_new_object(); + json_sub = json_object_new_object(); + json_object_string_add(json_no, "warning", "Malformed address or name"); + json_object_string_add(json_sub, "warningCause", argv[1]); + json_object_object_add(json_no, "detail", json_sub); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% Malformed address or name: %s%s", argv[1], VTY_NEWLINE); return CMD_WARNING; } } @@ -12604,23 +13230,36 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter, { peer = peer_lookup (bgp, &su); if (! peer) - return CMD_WARNING; + { + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_boolean_true_add(json_no, "noPeer"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "No peer%s", VTY_NEWLINE); + return CMD_WARNING; + } + } sprintf (name, "%s.%d.%d", peer->host, AFI_IP6, SAFI_UNICAST); - count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name); + count = prefix_bgp_show_prefix_list (NULL, AFI_IP6, name, use_json); if (count) { - vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE); - prefix_bgp_show_prefix_list (vty, AFI_IP6, name); + if (!use_json) + vty_out (vty, "Address family: IPv6 Unicast%s", VTY_NEWLINE); + prefix_bgp_show_prefix_list (vty, AFI_IP6, name, use_json); } return CMD_SUCCESS; } - ALIAS (show_bgp_view_neighbor_received_prefix_filter, show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) received prefix-filter {json}", SHOW_STR BGP_STR "BGP view\n" @@ -12631,25 +13270,35 @@ ALIAS (show_bgp_view_neighbor_received_prefix_filter, "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" "Display information received from a BGP neighbor\n" - "Display the prefixlist filter\n") + "Display the prefixlist filter\n" + "JavaScript Object NOtation\n") #endif /* HAVE_IPV6 */ static int bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi, - safi_t safi, enum bgp_show_type type) + safi_t safi, enum bgp_show_type type, u_char use_json) { if (! peer || ! peer->afc[afi][safi]) { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_no = NULL; + json_no = json_object_new_object(); + json_object_string_add(json_no, "warning", "No such neighbor or address family"); + vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE); + json_object_free(json_no); + } + else + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); return CMD_WARNING; } - return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su, 0); + return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su, use_json); } DEFUN (show_ip_bgp_neighbor_routes, show_ip_bgp_neighbor_routes_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR IP_STR BGP_STR @@ -12657,21 +13306,28 @@ DEFUN (show_ip_bgp_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST, - bgp_show_type_neighbor); + bgp_show_type_neighbor, use_json); } DEFUN (show_ip_bgp_neighbor_flap, show_ip_bgp_neighbor_flap_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", SHOW_STR IP_STR BGP_STR @@ -12679,21 +13335,28 @@ DEFUN (show_ip_bgp_neighbor_flap, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n") + "Display flap statistics of the routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST, - bgp_show_type_flap_neighbor); + bgp_show_type_flap_neighbor, use_json); } DEFUN (show_ip_bgp_neighbor_damp, show_ip_bgp_neighbor_damp_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", SHOW_STR IP_STR BGP_STR @@ -12701,21 +13364,28 @@ DEFUN (show_ip_bgp_neighbor_damp, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n") + "Display the dampened routes received from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST, - bgp_show_type_damp_neighbor); + bgp_show_type_damp_neighbor, use_json); } DEFUN (show_ip_bgp_ipv4_neighbor_routes, show_ip_bgp_ipv4_neighbor_routes_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR IP_STR BGP_STR @@ -12726,20 +13396,27 @@ DEFUN (show_ip_bgp_ipv4_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], use_json); if (! peer) return CMD_WARNING; if (strncmp (argv[0], "m", 1) == 0) return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_MULTICAST, - bgp_show_type_neighbor); + bgp_show_type_neighbor, use_json); return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST, - bgp_show_type_neighbor); + bgp_show_type_neighbor, use_json); } DEFUN (show_ip_bgp_view_rsclient, @@ -12757,9 +13434,9 @@ DEFUN (show_ip_bgp_view_rsclient, struct peer *peer; if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -12812,10 +13489,10 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient, safi_t safi; if (argc == 3) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } @@ -12890,9 +13567,9 @@ DEFUN (show_ip_bgp_view_rsclient_route, } if (argc == 3) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -12966,10 +13643,10 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_route, } if (argc == 4) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } @@ -13044,9 +13721,9 @@ DEFUN (show_ip_bgp_view_rsclient_prefix, } if (argc == 3) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -13120,10 +13797,10 @@ DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix, } if (argc == 4) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } @@ -13165,7 +13842,7 @@ ALIAS (show_bgp_view_ipv4_safi_rsclient_prefix, #ifdef HAVE_IPV6 DEFUN (show_bgp_view_neighbor_routes, show_bgp_view_neighbor_routes_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13174,25 +13851,33 @@ DEFUN (show_bgp_view_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if ((argc == 3 && argv[2] && strcmp(argv[2], "json") == 0) + || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST, - bgp_show_type_neighbor); + bgp_show_type_neighbor, use_json); } ALIAS (show_bgp_view_neighbor_routes, show_bgp_view_ipv6_neighbor_routes_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13202,11 +13887,12 @@ ALIAS (show_bgp_view_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_view_neighbor_damp, show_bgp_view_neighbor_damp_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13215,25 +13901,33 @@ DEFUN (show_bgp_view_neighbor_damp, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n") + "Display the dampened routes received from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if ((argc == 3 && argv[2] && strcmp(argv[2], "json") == 0) + || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST, - bgp_show_type_damp_neighbor); + bgp_show_type_damp_neighbor, use_json); } ALIAS (show_bgp_view_neighbor_damp, show_bgp_view_ipv6_neighbor_damp_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13243,11 +13937,12 @@ ALIAS (show_bgp_view_neighbor_damp, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n") + "Display the dampened routes received from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_view_neighbor_flap, show_bgp_view_neighbor_flap_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13256,25 +13951,33 @@ DEFUN (show_bgp_view_neighbor_flap, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n") + "Display flap statistics of the routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; - if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + if ((argc == 3 && argv[2] && strcmp(argv[2], "json") == 0) + || (argc == 2 && argv[1] && strcmp(argv[1], "json") != 0)) + peer = peer_lookup_in_view (vty, argv[0], argv[1], use_json); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_UNICAST, - bgp_show_type_flap_neighbor); + bgp_show_type_flap_neighbor, use_json); } ALIAS (show_bgp_view_neighbor_flap, show_bgp_view_ipv6_neighbor_flap_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", SHOW_STR BGP_STR "BGP view\n" @@ -13284,23 +13987,25 @@ ALIAS (show_bgp_view_neighbor_flap, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n") + "Display flap statistics of the routes learned from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_routes, show_bgp_neighbor_routes_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_routes, show_bgp_ipv6_neighbor_routes_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR BGP_STR "Address family\n" @@ -13308,12 +14013,13 @@ ALIAS (show_bgp_view_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") /* old command */ ALIAS (show_bgp_view_neighbor_routes, ipv6_bgp_neighbor_routes_cmd, - "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show ipv6 bgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR IPV6_STR BGP_STR @@ -13321,12 +14027,13 @@ ALIAS (show_bgp_view_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") /* old command */ DEFUN (ipv6_mbgp_neighbor_routes, ipv6_mbgp_neighbor_routes_cmd, - "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) routes", + "show ipv6 mbgp neighbors (A.B.C.D|X:X::X:X|WORD) routes {json}", SHOW_STR IPV6_STR MBGP_STR @@ -13334,32 +14041,40 @@ DEFUN (ipv6_mbgp_neighbor_routes, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display routes learned from neighbor\n") + "Display routes learned from neighbor\n" + "JavaScript Object Notation\n") { struct peer *peer; + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], use_json); if (! peer) return CMD_WARNING; return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_MULTICAST, - bgp_show_type_neighbor); + bgp_show_type_neighbor, use_json); } ALIAS (show_bgp_view_neighbor_flap, show_bgp_neighbor_flap_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n") + "Display flap statistics of the routes learned from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_flap, show_bgp_ipv6_neighbor_flap_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) flap-statistics {json}", SHOW_STR BGP_STR "Address family\n" @@ -13367,22 +14082,24 @@ ALIAS (show_bgp_view_neighbor_flap, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display flap statistics of the routes learned from neighbor\n") + "Display flap statistics of the routes learned from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_damp, show_bgp_neighbor_damp_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n") + "Display the dampened routes received from neighbor\n" + "JavaScript Object Notation\n") ALIAS (show_bgp_view_neighbor_damp, show_bgp_ipv6_neighbor_damp_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) dampened-routes {json}", SHOW_STR BGP_STR "Address family\n" @@ -13390,7 +14107,8 @@ ALIAS (show_bgp_view_neighbor_damp, "Neighbor to display information about\n" "Neighbor to display information about\n" "Neighbor on bgp configured interface\n" - "Display the dampened routes received from neighbor\n") + "Display the dampened routes received from neighbor\n" + "JavaScript Object Notation\n") DEFUN (show_bgp_view_rsclient, show_bgp_view_rsclient_cmd, @@ -13406,9 +14124,9 @@ DEFUN (show_bgp_view_rsclient, struct peer *peer; if (argc == 2) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -13460,10 +14178,10 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient, safi_t safi; if (argc == 3) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } @@ -13537,9 +14255,9 @@ DEFUN (show_bgp_view_rsclient_route, } if (argc == 3) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -13612,10 +14330,10 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_route, } if (argc == 4) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } @@ -13689,9 +14407,9 @@ DEFUN (show_bgp_view_rsclient_prefix, } if (argc == 3) - peer = peer_lookup_in_view (vty, argv[0], argv[1]); + peer = peer_lookup_in_view (vty, argv[0], argv[1], 0); else - peer = peer_lookup_in_view (vty, NULL, argv[0]); + peer = peer_lookup_in_view (vty, NULL, argv[0], 0); if (! peer) return CMD_WARNING; @@ -13764,10 +14482,10 @@ DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix, } if (argc == 4) { - peer = peer_lookup_in_view (vty, argv[0], argv[2]); + peer = peer_lookup_in_view (vty, argv[0], argv[2], 0); safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } else { - peer = peer_lookup_in_view (vty, NULL, argv[1]); + peer = peer_lookup_in_view (vty, NULL, argv[1], 0); safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 865a24d3ff..59003438b0 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -21,7 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGP_ROUTE_H #define _QUAGGA_BGP_ROUTE_H -#include "lib/json.h" #include "queue.h" #include "bgp_table.h" @@ -299,8 +298,8 @@ extern afi_t bgp_node_afi (struct vty *); extern safi_t bgp_node_safi (struct vty *); extern void route_vty_out (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *); -extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t); -extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t); +extern void route_vty_out_tag (struct vty *, struct prefix *, struct bgp_info *, int, safi_t, json_object *); +extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t, u_char, json_object *); extern int subgroup_process_announce_selected (struct update_subgroup *subgrp, diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 4eeca365fb..d885e5e7d2 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -138,13 +138,12 @@ subgrp_show_adjq_vty (struct update_subgroup *subgrp, struct vty *vty, } if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && adj->adv->baa) { - route_vty_out_tmp (vty, &rn->p, adj->adv->baa->attr, - SUBGRP_SAFI (subgrp)); + route_vty_out_tmp (vty, &rn->p, adj->adv->baa->attr, SUBGRP_SAFI (subgrp), 0, NULL); output_count++; } if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) { - route_vty_out_tmp (vty, &rn->p, adj->attr, SUBGRP_SAFI (subgrp)); + route_vty_out_tmp (vty, &rn->p, adj->attr, SUBGRP_SAFI (subgrp), 0, NULL); output_count++; } } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index a8e23bf1b4..7eaccf77d8 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include +#include "lib/json.h" #include "command.h" #include "prefix.h" #include "plist.h" @@ -8573,8 +8574,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, json_object_int_add(json_peer, "tableVersion", peer->version[afi][safi]); json_object_int_add(json_peer, "outq", peer->obuf->count); json_object_int_add(json_peer, "inq", 0); - json_object_string_add(json_peer, "uptime", - peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN)); + peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN, use_json, json_peer); json_object_int_add(json_peer, "prefixReceivedCount", peer->pcount[afi][safi]); json_object_int_add(json_peer, "prefixAdvertisedCount", bgp_adj_out_count(peer, afi, safi)); @@ -8626,7 +8626,7 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi, peer->obuf->count); vty_out (vty, "%-8s", - peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN)); + peer_uptime (peer->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); if (peer->status == Established) vty_out (vty, " %8ld", peer->pcount[afi][safi]); @@ -8972,270 +8972,480 @@ enum show_type }; static void -bgp_show_peer_afi_orf_cap (struct vty *vty, struct peer *p, - afi_t afi, safi_t safi, - u_int16_t adv_smcap, u_int16_t adv_rmcap, - u_int16_t rcv_smcap, u_int16_t rcv_rmcap) +bgp_show_peer_afi_orf_cap (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, + u_int16_t adv_smcap, u_int16_t adv_rmcap, u_int16_t rcv_smcap, + u_int16_t rcv_rmcap, u_char use_json, json_object *json_pref) { /* Send-Mode */ if (CHECK_FLAG (p->af_cap[afi][safi], adv_smcap) || CHECK_FLAG (p->af_cap[afi][safi], rcv_smcap)) { - vty_out (vty, " Send-mode: "); - if (CHECK_FLAG (p->af_cap[afi][safi], adv_smcap)) - vty_out (vty, "advertised"); - if (CHECK_FLAG (p->af_cap[afi][safi], rcv_smcap)) - vty_out (vty, "%sreceived", - CHECK_FLAG (p->af_cap[afi][safi], adv_smcap) ? - ", " : ""); - vty_out (vty, "%s", VTY_NEWLINE); + if (use_json) + { + if (CHECK_FLAG (p->af_cap[afi][safi], adv_smcap) && CHECK_FLAG (p->af_cap[afi][safi], rcv_smcap)) + json_object_string_add(json_pref, "sendMode", "advertisedAndReceived"); + else if (CHECK_FLAG (p->af_cap[afi][safi], adv_smcap)) + json_object_string_add(json_pref, "sendMode", "advertised"); + else if (CHECK_FLAG (p->af_cap[afi][safi], rcv_smcap)) + json_object_string_add(json_pref, "sendMode", "received"); + } + else + { + vty_out (vty, " Send-mode: "); + if (CHECK_FLAG (p->af_cap[afi][safi], adv_smcap)) + vty_out (vty, "advertised"); + if (CHECK_FLAG (p->af_cap[afi][safi], rcv_smcap)) + vty_out (vty, "%sreceived", + CHECK_FLAG (p->af_cap[afi][safi], adv_smcap) ? + ", " : ""); + vty_out (vty, "%s", VTY_NEWLINE); + } } /* Receive-Mode */ if (CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap) || CHECK_FLAG (p->af_cap[afi][safi], rcv_rmcap)) { - vty_out (vty, " Receive-mode: "); - if (CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap)) - vty_out (vty, "advertised"); - if (CHECK_FLAG (p->af_cap[afi][safi], rcv_rmcap)) - vty_out (vty, "%sreceived", - CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap) ? - ", " : ""); - vty_out (vty, "%s", VTY_NEWLINE); + if (use_json) + { + if (CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap) && CHECK_FLAG (p->af_cap[afi][safi], rcv_rmcap)) + json_object_string_add(json_pref, "recvMode", "advertisedAndReceived"); + else if (CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap)) + json_object_string_add(json_pref, "recvMode", "advertised"); + else if (CHECK_FLAG (p->af_cap[afi][safi], rcv_rmcap)) + json_object_string_add(json_pref, "recvMode", "received"); + } + else + { + vty_out (vty, " Receive-mode: "); + if (CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap)) + vty_out (vty, "advertised"); + if (CHECK_FLAG (p->af_cap[afi][safi], rcv_rmcap)) + vty_out (vty, "%sreceived", + CHECK_FLAG (p->af_cap[afi][safi], adv_rmcap) ? + ", " : ""); + vty_out (vty, "%s", VTY_NEWLINE); + } } } static void -bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi) +bgp_show_peer_afi (struct vty *vty, struct peer *p, afi_t afi, safi_t safi, + u_char use_json, json_object *json_neigh) { struct bgp_filter *filter; struct peer_af *paf; char orf_pfx_name[BUFSIZ]; int orf_pfx_count; + json_object *json_af = NULL; + json_object *json_prefA = NULL; + json_object *json_prefB = NULL; + json_object *json_addr = NULL; - filter = &p->filter[afi][safi]; + if (use_json) + { + json_addr = json_object_new_object(); + json_af = json_object_new_object(); + json_prefA = json_object_new_object(); + json_prefB = json_object_new_object(); + filter = &p->filter[afi][safi]; - vty_out (vty, " For address family: %s%s", afi_safi_print (afi, safi), - VTY_NEWLINE); + if (p->af_group[afi][safi]) + json_object_string_add(json_addr, "peerGroupMember", p->group->name); - if (p->af_group[afi][safi]) - vty_out (vty, " %s peer-group member%s", p->group->name, VTY_NEWLINE); - - paf = peer_af_find(p, afi, safi); - if (paf && PAF_SUBGRP(paf)) - { - vty_out (vty, " Update group %" PRIu64 ", subgroup %" PRIu64 "%s", - PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id, VTY_NEWLINE); - vty_out (vty, " Packet Queue length %d%s", - bpacket_queue_virtual_length(paf), VTY_NEWLINE); - } else - { - vty_out(vty, " Not part of any update group%s", VTY_NEWLINE); - } - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) - vty_out (vty, " AF-dependant capabilities:%s", VTY_NEWLINE); - - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) - { - vty_out (vty, " Outbound Route Filter (ORF) type (%d) Prefix-list:%s", - ORF_TYPE_PREFIX, VTY_NEWLINE); - bgp_show_peer_afi_orf_cap (vty, p, afi, safi, - PEER_CAP_ORF_PREFIX_SM_ADV, - PEER_CAP_ORF_PREFIX_RM_ADV, - PEER_CAP_ORF_PREFIX_SM_RCV, - PEER_CAP_ORF_PREFIX_RM_RCV); - } - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) - || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) - { - vty_out (vty, " Outbound Route Filter (ORF) type (%d) Prefix-list:%s", - ORF_TYPE_PREFIX_OLD, VTY_NEWLINE); - bgp_show_peer_afi_orf_cap (vty, p, afi, safi, - PEER_CAP_ORF_PREFIX_SM_ADV, - PEER_CAP_ORF_PREFIX_RM_ADV, - PEER_CAP_ORF_PREFIX_SM_OLD_RCV, - PEER_CAP_ORF_PREFIX_RM_OLD_RCV); - } - - sprintf (orf_pfx_name, "%s.%d.%d", p->host, afi, safi); - orf_pfx_count = prefix_bgp_show_prefix_list (NULL, afi, orf_pfx_name); - - if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND) - || orf_pfx_count) - { - vty_out (vty, " Outbound Route Filter (ORF):"); - if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) - vty_out (vty, " sent;"); - if (orf_pfx_count) - vty_out (vty, " received (%d entries)", orf_pfx_count); - vty_out (vty, "%s", VTY_NEWLINE); - } - if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH)) - vty_out (vty, " First update is deferred until ORF or ROUTE-REFRESH is received%s", VTY_NEWLINE); - - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) - vty_out (vty, " Route-Reflector Client%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) - vty_out (vty, " Route-Server Client%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) - vty_out (vty, " Inbound soft reconfiguration allowed%s", VTY_NEWLINE); - - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) - vty_out (vty, " Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE); - else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS)) - vty_out (vty, " Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE); - - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_OVERRIDE)) - vty_out (vty, " Override ASNs in outbound updates if aspath equals remote-as%s", VTY_NEWLINE); - - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) || - CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) - vty_out (vty, " NEXT_HOP is always this router%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) - vty_out (vty, " AS_PATH is propagated unchanged to this neighbor%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) - vty_out (vty, " NEXT_HOP is propagated unchanged to this neighbor%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) - vty_out (vty, " MED is propagated unchanged to this neighbor%s", VTY_NEWLINE); - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) - || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) - { - vty_out (vty, " Community attribute sent to this neighbor"); + paf = peer_af_find(p, afi, safi); + if (paf && PAF_SUBGRP(paf)) + { + json_object_int_add(json_addr, "updateGroupId", PAF_UPDGRP(paf)->id); + json_object_int_add(json_addr, "subGroupId", PAF_SUBGRP(paf)->id); + json_object_int_add(json_addr, "packetQueueLength", bpacket_queue_virtual_length(paf)); + } + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) + { + json_object_int_add(json_af, "orfType", ORF_TYPE_PREFIX); + bgp_show_peer_afi_orf_cap (vty, p, afi, safi, + PEER_CAP_ORF_PREFIX_SM_ADV, + PEER_CAP_ORF_PREFIX_RM_ADV, + PEER_CAP_ORF_PREFIX_SM_RCV, + PEER_CAP_ORF_PREFIX_RM_RCV, use_json, json_prefA); + json_object_object_add(json_af, "orfPrefixList", json_prefA); + } + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + { + json_object_int_add(json_af, "orfOldType", ORF_TYPE_PREFIX_OLD); + bgp_show_peer_afi_orf_cap (vty, p, afi, safi, + PEER_CAP_ORF_PREFIX_SM_ADV, + PEER_CAP_ORF_PREFIX_RM_ADV, + PEER_CAP_ORF_PREFIX_SM_OLD_RCV, + PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, json_prefB); + json_object_object_add(json_af, "orfOldPrefixList", json_prefB); + } + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + json_object_object_add(json_addr, "afDependentCap", json_af); + + sprintf (orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + orf_pfx_count = prefix_bgp_show_prefix_list (NULL, afi, orf_pfx_name, use_json); + + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND) + || orf_pfx_count) + { + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) + json_object_boolean_true_add(json_neigh, "orfSent"); + if (orf_pfx_count) + json_object_int_add(json_addr, "orfRecvCounter", orf_pfx_count); + } + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH)) + json_object_string_add(json_addr, "orfFirstUpdate", "deferredUntilORFOrRouteRefreshRecvd"); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) + json_object_boolean_true_add(json_addr, "routeReflectorClient"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) + json_object_boolean_true_add(json_addr, "routeServerClient"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) + json_object_boolean_true_add(json_addr, "inboundSoftConfigPermit"); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) + json_object_boolean_true_add(json_addr, "privateAsNumsReplacedInUpdatesToNbr"); + else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS)) + json_object_boolean_true_add(json_addr, "privateAsNumsRemovedInUpdatesToNbr"); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_OVERRIDE)) + json_object_string_add(json_addr, "overrideASNsInOutboundUpdates", "ifAspathEqualRemoteAs"); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) || + CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) + json_object_boolean_true_add(json_addr, "routerAlwaysNextHop"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) + json_object_boolean_true_add(json_addr, "unchangedAsPathPropogatedToNbr"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) + json_object_boolean_true_add(json_addr, "unchangedNextHopPropogatedToNbr"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) + json_object_boolean_true_add(json_addr, "unchangedMedPropogatedToNbr"); if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) - && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) - vty_out (vty, "(both)%s", VTY_NEWLINE); - else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) - vty_out (vty, "(extended)%s", VTY_NEWLINE); - else - vty_out (vty, "(standard)%s", VTY_NEWLINE); - } - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) - { - vty_out (vty, " Default information originate,"); - - if (p->default_rmap[afi][safi].name) - vty_out (vty, " default route-map %s%s,", - p->default_rmap[afi][safi].map ? "*" : "", - p->default_rmap[afi][safi].name); - if (paf && PAF_SUBGRP(paf) && CHECK_FLAG(PAF_SUBGRP(paf)->sflags, - SUBGRP_STATUS_DEFAULT_ORIGINATE)) - vty_out (vty, " default sent%s", VTY_NEWLINE); + || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + { + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) + && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + json_object_string_add(json_addr, "commAttriSentToNbr", "extendedAndStandard"); + else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + json_object_string_add(json_addr, "commAttriSentToNbr", "extended"); + else + json_object_string_add(json_addr, "commAttriSentToNbr", "standard"); + } + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) + { + if (p->default_rmap[afi][safi].name) + json_object_string_add(json_addr, "defaultRouteMap", p->default_rmap[afi][safi].name); + + if (paf && PAF_SUBGRP(paf) && CHECK_FLAG(PAF_SUBGRP(paf)->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) + json_object_boolean_true_add(json_addr, "defaultSent"); + else + json_object_boolean_true_add(json_addr, "defaultNotSent"); + } + + if (filter->plist[FILTER_IN].name + || filter->dlist[FILTER_IN].name + || filter->aslist[FILTER_IN].name + || filter->map[RMAP_IN].name) + json_object_boolean_true_add(json_addr, "inboundPathPolicyConfig"); + if (filter->plist[FILTER_OUT].name + || filter->dlist[FILTER_OUT].name + || filter->aslist[FILTER_OUT].name + || filter->map[RMAP_OUT].name + || filter->usmap.name) + json_object_boolean_true_add(json_addr, "outboundPathPolicyConfig"); + if (filter->map[RMAP_IMPORT].name) + json_object_boolean_true_add(json_addr, "importPolicyRsClientConfig"); + if (filter->map[RMAP_EXPORT].name) + json_object_boolean_true_add(json_addr, "exportPolicyRsClientConfig"); + + /* prefix-list */ + if (filter->plist[FILTER_IN].name) + json_object_string_add(json_addr, "incomingUpdatePrefixFilterList", filter->plist[FILTER_IN].name); + if (filter->plist[FILTER_OUT].name) + json_object_string_add(json_addr, "outgoingUpdatePrefixFilterList", filter->plist[FILTER_OUT].name); + + /* distribute-list */ + if (filter->dlist[FILTER_IN].name) + json_object_string_add(json_addr, "incomingUpdateNetworkFilterList", filter->dlist[FILTER_IN].name); + if (filter->dlist[FILTER_OUT].name) + json_object_string_add(json_addr, "outgoingUpdateNetworkFilterList", filter->dlist[FILTER_OUT].name); + + /* filter-list. */ + if (filter->aslist[FILTER_IN].name) + json_object_string_add(json_addr, "incomingUpdateAsPathFilterList", filter->aslist[FILTER_IN].name); + if (filter->aslist[FILTER_OUT].name) + json_object_string_add(json_addr, "outgoingUpdateAsPathFilterList", filter->aslist[FILTER_OUT].name); + + /* route-map. */ + if (filter->map[RMAP_IN].name) + json_object_string_add(json_addr, "routeMapForIncomingAdvertisements", filter->map[RMAP_IN].name); + if (filter->map[RMAP_OUT].name) + json_object_string_add(json_addr, "routeMapForOutgoingAdvertisements", filter->map[RMAP_OUT].name); + if (filter->map[RMAP_IMPORT].name) + json_object_string_add(json_addr, "routeMapForAdvertisementsIntoRsClient", filter->map[RMAP_IMPORT].name); + if (filter->map[RMAP_EXPORT].name) + json_object_string_add(json_addr, "routeMapForAdvertisementsFromRsClient", filter->map[RMAP_EXPORT].name); + + /* unsuppress-map */ + if (filter->usmap.name) + json_object_string_add(json_addr, "selectiveUnsuppressRouteMap", filter->usmap.name); + + /* Receive prefix count */ + json_object_int_add(json_addr, "acceptedPrefixCounter", p->pcount[afi][safi]); + + /* Maximum prefix */ + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) + { + json_object_int_add(json_addr, "prefixAllowedMax", p->pmax[afi][safi]); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING)) + json_object_boolean_true_add(json_addr, "prefixAllowedMaxWarning"); + json_object_int_add(json_addr, "prefixAllowedWarningThresh", p->pmax_threshold[afi][safi]); + if (p->pmax_restart[afi][safi]) + json_object_int_add(json_addr, "prefixAllowedRestartIntervalMsecs", p->pmax_restart[afi][safi] * 60000); + } + json_object_object_add(json_neigh, afi_safi_print (afi, safi), json_addr); + + } + else + { + filter = &p->filter[afi][safi]; + + vty_out (vty, " For address family: %s%s", afi_safi_print (afi, safi), + VTY_NEWLINE); + + if (p->af_group[afi][safi]) + vty_out (vty, " %s peer-group member%s", p->group->name, VTY_NEWLINE); + + paf = peer_af_find(p, afi, safi); + if (paf && PAF_SUBGRP(paf)) + { + vty_out (vty, " Update group %" PRIu64 ", subgroup %" PRIu64 "%s", + PAF_UPDGRP(paf)->id, PAF_SUBGRP(paf)->id, VTY_NEWLINE); + vty_out (vty, " Packet Queue length %d%s", + bpacket_queue_virtual_length(paf), VTY_NEWLINE); + } else - vty_out (vty, " default not sent%s", VTY_NEWLINE); - } - - if (filter->plist[FILTER_IN].name - || filter->dlist[FILTER_IN].name - || filter->aslist[FILTER_IN].name - || filter->map[RMAP_IN].name) - vty_out (vty, " Inbound path policy configured%s", VTY_NEWLINE); - if (filter->plist[FILTER_OUT].name - || filter->dlist[FILTER_OUT].name - || filter->aslist[FILTER_OUT].name - || filter->map[RMAP_OUT].name - || filter->usmap.name) - vty_out (vty, " Outbound path policy configured%s", VTY_NEWLINE); - if (filter->map[RMAP_IMPORT].name) - vty_out (vty, " Import policy for this RS-client configured%s", VTY_NEWLINE); - if (filter->map[RMAP_EXPORT].name) - vty_out (vty, " Export policy for this RS-client configured%s", VTY_NEWLINE); - - /* prefix-list */ - if (filter->plist[FILTER_IN].name) - vty_out (vty, " Incoming update prefix filter list is %s%s%s", - filter->plist[FILTER_IN].plist ? "*" : "", - filter->plist[FILTER_IN].name, - VTY_NEWLINE); - if (filter->plist[FILTER_OUT].name) - vty_out (vty, " Outgoing update prefix filter list is %s%s%s", - filter->plist[FILTER_OUT].plist ? "*" : "", - filter->plist[FILTER_OUT].name, - VTY_NEWLINE); + { + vty_out(vty, " Not part of any update group%s", VTY_NEWLINE); + } + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + vty_out (vty, " AF-dependant capabilities:%s", VTY_NEWLINE); + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_RCV)) + { + vty_out (vty, " Outbound Route Filter (ORF) type (%d) Prefix-list:%s", + ORF_TYPE_PREFIX, VTY_NEWLINE); + bgp_show_peer_afi_orf_cap (vty, p, afi, safi, + PEER_CAP_ORF_PREFIX_SM_ADV, + PEER_CAP_ORF_PREFIX_RM_ADV, + PEER_CAP_ORF_PREFIX_SM_RCV, + PEER_CAP_ORF_PREFIX_RM_RCV, use_json, NULL); + } + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_OLD_RCV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV) + || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_OLD_RCV)) + { + vty_out (vty, " Outbound Route Filter (ORF) type (%d) Prefix-list:%s", + ORF_TYPE_PREFIX_OLD, VTY_NEWLINE); + bgp_show_peer_afi_orf_cap (vty, p, afi, safi, + PEER_CAP_ORF_PREFIX_SM_ADV, + PEER_CAP_ORF_PREFIX_RM_ADV, + PEER_CAP_ORF_PREFIX_SM_OLD_RCV, + PEER_CAP_ORF_PREFIX_RM_OLD_RCV, use_json, NULL); + } - /* distribute-list */ - if (filter->dlist[FILTER_IN].name) - vty_out (vty, " Incoming update network filter list is %s%s%s", - filter->dlist[FILTER_IN].alist ? "*" : "", - filter->dlist[FILTER_IN].name, - VTY_NEWLINE); - if (filter->dlist[FILTER_OUT].name) - vty_out (vty, " Outgoing update network filter list is %s%s%s", - filter->dlist[FILTER_OUT].alist ? "*" : "", - filter->dlist[FILTER_OUT].name, - VTY_NEWLINE); + sprintf (orf_pfx_name, "%s.%d.%d", p->host, afi, safi); + orf_pfx_count = prefix_bgp_show_prefix_list (NULL, afi, orf_pfx_name, use_json); - /* filter-list. */ - if (filter->aslist[FILTER_IN].name) - vty_out (vty, " Incoming update AS path filter list is %s%s%s", - filter->aslist[FILTER_IN].aslist ? "*" : "", - filter->aslist[FILTER_IN].name, - VTY_NEWLINE); - if (filter->aslist[FILTER_OUT].name) - vty_out (vty, " Outgoing update AS path filter list is %s%s%s", - filter->aslist[FILTER_OUT].aslist ? "*" : "", - filter->aslist[FILTER_OUT].name, - VTY_NEWLINE); + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND) + || orf_pfx_count) + { + vty_out (vty, " Outbound Route Filter (ORF):"); + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_PREFIX_SEND)) + vty_out (vty, " sent;"); + if (orf_pfx_count) + vty_out (vty, " received (%d entries)", orf_pfx_count); + vty_out (vty, "%s", VTY_NEWLINE); + } + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_ORF_WAIT_REFRESH)) + vty_out (vty, " First update is deferred until ORF or ROUTE-REFRESH is received%s", VTY_NEWLINE); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT)) + vty_out (vty, " Route-Reflector Client%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) + vty_out (vty, " Route-Server Client%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)) + vty_out (vty, " Inbound soft reconfiguration allowed%s", VTY_NEWLINE); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)) + vty_out (vty, " Private AS numbers replaced in updates to this neighbor%s", VTY_NEWLINE); + else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_REMOVE_PRIVATE_AS)) + vty_out (vty, " Private AS numbers removed in updates to this neighbor%s", VTY_NEWLINE); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_OVERRIDE)) + vty_out (vty, " Override ASNs in outbound updates if aspath equals remote-as%s", VTY_NEWLINE); + + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) || + CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF)) + vty_out (vty, " NEXT_HOP is always this router%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_AS_PATH_UNCHANGED)) + vty_out (vty, " AS_PATH is propagated unchanged to this neighbor%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)) + vty_out (vty, " NEXT_HOP is propagated unchanged to this neighbor%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED)) + vty_out (vty, " MED is propagated unchanged to this neighbor%s", VTY_NEWLINE); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) + || CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + { + vty_out (vty, " Community attribute sent to this neighbor"); + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_COMMUNITY) + && CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + vty_out (vty, "(both)%s", VTY_NEWLINE); + else if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_SEND_EXT_COMMUNITY)) + vty_out (vty, "(extended)%s", VTY_NEWLINE); + else + vty_out (vty, "(standard)%s", VTY_NEWLINE); + } + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) + { + vty_out (vty, " Default information originate,"); + + if (p->default_rmap[afi][safi].name) + vty_out (vty, " default route-map %s%s,", + p->default_rmap[afi][safi].map ? "*" : "", + p->default_rmap[afi][safi].name); + if (paf && PAF_SUBGRP(paf) && CHECK_FLAG(PAF_SUBGRP(paf)->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) + vty_out (vty, " default sent%s", VTY_NEWLINE); + else + vty_out (vty, " default not sent%s", VTY_NEWLINE); + } - /* route-map. */ - if (filter->map[RMAP_IN].name) - vty_out (vty, " Route map for incoming advertisements is %s%s%s", - filter->map[RMAP_IN].map ? "*" : "", - filter->map[RMAP_IN].name, - VTY_NEWLINE); - if (filter->map[RMAP_OUT].name) - vty_out (vty, " Route map for outgoing advertisements is %s%s%s", - filter->map[RMAP_OUT].map ? "*" : "", - filter->map[RMAP_OUT].name, - VTY_NEWLINE); - if (filter->map[RMAP_IMPORT].name) - vty_out (vty, " Route map for advertisements going into this RS-client's table is %s%s%s", - filter->map[RMAP_IMPORT].map ? "*" : "", - filter->map[RMAP_IMPORT].name, - VTY_NEWLINE); - if (filter->map[RMAP_EXPORT].name) - vty_out (vty, " Route map for advertisements coming from this RS-client is %s%s%s", - filter->map[RMAP_EXPORT].map ? "*" : "", - filter->map[RMAP_EXPORT].name, - VTY_NEWLINE); + if (filter->plist[FILTER_IN].name + || filter->dlist[FILTER_IN].name + || filter->aslist[FILTER_IN].name + || filter->map[RMAP_IN].name) + vty_out (vty, " Inbound path policy configured%s", VTY_NEWLINE); + if (filter->plist[FILTER_OUT].name + || filter->dlist[FILTER_OUT].name + || filter->aslist[FILTER_OUT].name + || filter->map[RMAP_OUT].name + || filter->usmap.name) + vty_out (vty, " Outbound path policy configured%s", VTY_NEWLINE); + if (filter->map[RMAP_IMPORT].name) + vty_out (vty, " Import policy for this RS-client configured%s", VTY_NEWLINE); + if (filter->map[RMAP_EXPORT].name) + vty_out (vty, " Export policy for this RS-client configured%s", VTY_NEWLINE); + + /* prefix-list */ + if (filter->plist[FILTER_IN].name) + vty_out (vty, " Incoming update prefix filter list is %s%s%s", + filter->plist[FILTER_IN].plist ? "*" : "", + filter->plist[FILTER_IN].name, + VTY_NEWLINE); + if (filter->plist[FILTER_OUT].name) + vty_out (vty, " Outgoing update prefix filter list is %s%s%s", + filter->plist[FILTER_OUT].plist ? "*" : "", + filter->plist[FILTER_OUT].name, + VTY_NEWLINE); + + /* distribute-list */ + if (filter->dlist[FILTER_IN].name) + vty_out (vty, " Incoming update network filter list is %s%s%s", + filter->dlist[FILTER_IN].alist ? "*" : "", + filter->dlist[FILTER_IN].name, + VTY_NEWLINE); + if (filter->dlist[FILTER_OUT].name) + vty_out (vty, " Outgoing update network filter list is %s%s%s", + filter->dlist[FILTER_OUT].alist ? "*" : "", + filter->dlist[FILTER_OUT].name, + VTY_NEWLINE); + + /* filter-list. */ + if (filter->aslist[FILTER_IN].name) + vty_out (vty, " Incoming update AS path filter list is %s%s%s", + filter->aslist[FILTER_IN].aslist ? "*" : "", + filter->aslist[FILTER_IN].name, + VTY_NEWLINE); + if (filter->aslist[FILTER_OUT].name) + vty_out (vty, " Outgoing update AS path filter list is %s%s%s", + filter->aslist[FILTER_OUT].aslist ? "*" : "", + filter->aslist[FILTER_OUT].name, + VTY_NEWLINE); + + /* route-map. */ + if (filter->map[RMAP_IN].name) + vty_out (vty, " Route map for incoming advertisements is %s%s%s", + filter->map[RMAP_IN].map ? "*" : "", + filter->map[RMAP_IN].name, + VTY_NEWLINE); + if (filter->map[RMAP_OUT].name) + vty_out (vty, " Route map for outgoing advertisements is %s%s%s", + filter->map[RMAP_OUT].map ? "*" : "", + filter->map[RMAP_OUT].name, + VTY_NEWLINE); + if (filter->map[RMAP_IMPORT].name) + vty_out (vty, " Route map for advertisements going into this RS-client's table is %s%s%s", + filter->map[RMAP_IMPORT].map ? "*" : "", + filter->map[RMAP_IMPORT].name, + VTY_NEWLINE); + if (filter->map[RMAP_EXPORT].name) + vty_out (vty, " Route map for advertisements coming from this RS-client is %s%s%s", + filter->map[RMAP_EXPORT].map ? "*" : "", + filter->map[RMAP_EXPORT].name, + VTY_NEWLINE); + + /* unsuppress-map */ + if (filter->usmap.name) + vty_out (vty, " Route map for selective unsuppress is %s%s%s", + filter->usmap.map ? "*" : "", + filter->usmap.name, VTY_NEWLINE); + + /* Receive prefix count */ + vty_out (vty, " %ld accepted prefixes%s", p->pcount[afi][safi], VTY_NEWLINE); + + /* Maximum prefix */ + if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) + { + vty_out (vty, " Maximum prefixes allowed %ld%s%s", p->pmax[afi][safi], + CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING) + ? " (warning-only)" : "", VTY_NEWLINE); + vty_out (vty, " Threshold for warning message %d%%", + p->pmax_threshold[afi][safi]); + if (p->pmax_restart[afi][safi]) + vty_out (vty, ", restart interval %d min", p->pmax_restart[afi][safi]); + vty_out (vty, "%s", VTY_NEWLINE); + } - /* unsuppress-map */ - if (filter->usmap.name) - vty_out (vty, " Route map for selective unsuppress is %s%s%s", - filter->usmap.map ? "*" : "", - filter->usmap.name, VTY_NEWLINE); - - /* Receive prefix count */ - vty_out (vty, " %ld accepted prefixes%s", p->pcount[afi][safi], VTY_NEWLINE); - - /* Maximum prefix */ - if (CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX)) - { - vty_out (vty, " Maximum prefixes allowed %ld%s%s", p->pmax[afi][safi], - CHECK_FLAG (p->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING) - ? " (warning-only)" : "", VTY_NEWLINE); - vty_out (vty, " Threshold for warning message %d%%", - p->pmax_threshold[afi][safi]); - if (p->pmax_restart[afi][safi]) - vty_out (vty, ", restart interval %d min", p->pmax_restart[afi][safi]); vty_out (vty, "%s", VTY_NEWLINE); } - - vty_out (vty, "%s", VTY_NEWLINE); } static void -bgp_show_peer (struct vty *vty, struct peer *p) +bgp_show_peer (struct vty *vty, struct peer *p, u_char use_json, json_object *json, json_object *json_neigh) { struct bgp *bgp; char buf1[BUFSIZ], buf[SU_ADDRSTRLEN]; @@ -9248,115 +9458,248 @@ bgp_show_peer (struct vty *vty, struct peer *p) bgp = p->bgp; - if (p->conf_if) /* Configured interface name. */ - vty_out (vty, "BGP neighbor on %s: %s, ", p->conf_if, - BGP_PEER_SU_UNSPEC(p) ? "None" : - sockunion2str (&p->su, buf, SU_ADDRSTRLEN)); - else /* Configured IP address. */ + if (!use_json) { - memset(dn_flag, '\0', sizeof(dn_flag)); - if (peer_dynamic_neighbor(p)) - dn_flag[0] = '*'; + if (p->conf_if) /* Configured interface name. */ + vty_out (vty, "BGP neighbor on %s: %s, ", p->conf_if, + BGP_PEER_SU_UNSPEC(p) ? "None" : + sockunion2str (&p->su, buf, SU_ADDRSTRLEN)); + else /* Configured IP address. */ + { + memset(dn_flag, '\0', sizeof(dn_flag)); + if (peer_dynamic_neighbor(p)) + dn_flag[0] = '*'; - vty_out (vty, "BGP neighbor is %s%s, ", dn_flag, p->host); + vty_out (vty, "BGP neighbor is %s%s, ", dn_flag, p->host); + } } - vty_out (vty, "remote AS %u, ", p->as); - vty_out (vty, "local AS %u%s%s, ", - p->change_local_as ? p->change_local_as : p->local_as, - CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ? - " no-prepend" : "", - CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ? - " replace-as" : ""); + if (use_json) + { + if (p->conf_if && BGP_PEER_SU_UNSPEC(p)) + json_object_string_add(json_neigh, "bgpNeighborAddr", "none"); + else if (p->conf_if && !BGP_PEER_SU_UNSPEC(p)) + json_object_string_add(json_neigh, "bgpNeighborAddr", sockunion2str (&p->su, buf, SU_ADDRSTRLEN)); + + json_object_int_add(json_neigh, "remoteAs", p->as); + + if (p->change_local_as) + json_object_int_add(json_neigh, "localAs", p->change_local_as); + else + json_object_int_add(json_neigh, "localAs", p->local_as); + if (CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND)) + json_object_boolean_true_add(json_neigh, "localAsNoPrepend"); + + if (CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS)) + json_object_boolean_true_add(json_neigh, "localAsReplaceAs"); + } + else + { + vty_out (vty, "remote AS %u, ", p->as); + vty_out (vty, "local AS %u%s%s, ", + p->change_local_as ? p->change_local_as : p->local_as, + CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND) ? + " no-prepend" : "", + CHECK_FLAG (p->flags, PEER_FLAG_LOCAL_AS_REPLACE_AS) ? + " replace-as" : ""); + } /* peer type internal, external, confed-internal or confed-external */ if (p->as == p->local_as) { - if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) - vty_out (vty, "confed-internal link%s", VTY_NEWLINE); + if (use_json) + { + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) + json_object_boolean_true_add(json_neigh, "nbrConfedInternalLink"); + else + json_object_boolean_true_add(json_neigh, "nbrInternalLink"); + } else - vty_out (vty, "internal link%s", VTY_NEWLINE); + { + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) + vty_out (vty, "confed-internal link%s", VTY_NEWLINE); + else + vty_out (vty, "internal link%s", VTY_NEWLINE); + } } else { - if (bgp_confederation_peers_check(bgp, p->as)) - vty_out (vty, "confed-external link%s", VTY_NEWLINE); + if (use_json) + { + if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) + json_object_boolean_true_add(json_neigh, "nbrConfedExternalLink"); + else + json_object_boolean_true_add(json_neigh, "nbrExternalLink"); + } else - vty_out (vty, "external link%s", VTY_NEWLINE); + { + if (bgp_confederation_peers_check(bgp, p->as)) + vty_out (vty, "confed-external link%s", VTY_NEWLINE); + else + vty_out (vty, "external link%s", VTY_NEWLINE); + } } /* Description. */ if (p->desc) - vty_out (vty, " Description: %s%s", p->desc, VTY_NEWLINE); + { + if (use_json) + json_object_string_add(json_neigh, "nbrDesc", p->desc); + else + vty_out (vty, " Description: %s%s", p->desc, VTY_NEWLINE); + } /* Peer-group */ if (p->group) { - vty_out (vty, " Member of peer-group %s for session parameters%s", - p->group->name, VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json_neigh, "peerGroup", p->group->name); - if (dn_flag[0]) + if (dn_flag[0]) + { + struct prefix *prefix = NULL, *range = NULL; + + prefix = sockunion2hostprefix(&(p->su)); + if (prefix) + range = peer_group_lookup_dynamic_neighbor_range (p->group, prefix); + + if (range) + { + prefix2str(range, buf1, sizeof(buf1)); + json_object_string_add(json_neigh, "peerSubnetRangeGroup", buf1); + } + } + } + else { - struct prefix *prefix = NULL, *range = NULL; + vty_out (vty, " Member of peer-group %s for session parameters%s", + p->group->name, VTY_NEWLINE); - prefix = sockunion2hostprefix(&(p->su)); - if (prefix) - range = peer_group_lookup_dynamic_neighbor_range (p->group, - prefix); - if (range) + if (dn_flag[0]) { - prefix2str(range, buf1, sizeof(buf1)); - vty_out (vty, " Belongs to the subnet range group: %s%s", - buf1, VTY_NEWLINE); + struct prefix *prefix = NULL, *range = NULL; + + prefix = sockunion2hostprefix(&(p->su)); + if (prefix) + range = peer_group_lookup_dynamic_neighbor_range (p->group, prefix); + + if (range) + { + prefix2str(range, buf1, sizeof(buf1)); + vty_out (vty, " Belongs to the subnet range group: %s%s", buf1, VTY_NEWLINE); + } } } } - /* Administrative shutdown. */ - if (CHECK_FLAG (p->flags, PEER_FLAG_SHUTDOWN)) - vty_out (vty, " Administratively shut down%s", VTY_NEWLINE); + if (use_json) + { + /* Administrative shutdown. */ + if (CHECK_FLAG (p->flags, PEER_FLAG_SHUTDOWN)) + json_object_boolean_true_add(json_neigh, "adminShutDown"); - /* BGP Version. */ - vty_out (vty, " BGP version 4"); - vty_out (vty, ", remote router ID %s%s", - inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ), - VTY_NEWLINE); + /* BGP Version. */ + json_object_int_add(json_neigh, "bgpVersion", 4); + json_object_string_add(json_neigh, "remoteRouterId", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ)); - /* Confederation */ - if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) - && bgp_confederation_peers_check (bgp, p->as)) - vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE); - - /* Status. */ - vty_out (vty, " BGP state = %s", - LOOKUP (bgp_status_msg, p->status)); - if (p->status == Established) - vty_out (vty, ", up for %8s", - peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN)); - else if (p->status == Active) - { - if (CHECK_FLAG (p->flags, PEER_FLAG_PASSIVE)) - vty_out (vty, " (passive)"); - else if (CHECK_FLAG (p->sflags, PEER_STATUS_NSF_WAIT)) - vty_out (vty, " (NSF passive)"); + /* Confederation */ + if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) && bgp_confederation_peers_check (bgp, p->as)) + json_object_boolean_true_add(json_neigh, "nbrCommonAdmin"); + + /* Status. */ + json_object_string_add(json_neigh, "bgpState", LOOKUP (bgp_status_msg, p->status)); + + if (p->status == Established) + { + time_t uptime; + struct tm *tm; + + uptime = bgp_clock(); + uptime -= p->uptime; + tm = gmtime(&uptime); + + json_object_int_add(json_neigh, "bgpTimerUp", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); + } + + else if (p->status == Active) + { + if (CHECK_FLAG (p->flags, PEER_FLAG_PASSIVE)) + json_object_string_add(json_neigh, "bgpStateIs", "passive"); + else if (CHECK_FLAG (p->sflags, PEER_STATUS_NSF_WAIT)) + json_object_string_add(json_neigh, "bgpStateIs", "passiveNSF"); + } + + /* read timer */ + time_t uptime; + struct tm *tm; + + uptime = bgp_clock(); + uptime -= p->readtime; + tm = gmtime(&uptime); + json_object_int_add(json_neigh, "bgpTimerLastRead", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); + + uptime = bgp_clock(); + uptime -= p->last_write; + tm = gmtime(&uptime); + json_object_int_add(json_neigh, "bgpTimerLastRead", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); + + /* Configured timer values. */ + json_object_int_add(json_neigh, "bgpTimerHoldTimeMsecs", p->v_holdtime * 1000); + json_object_int_add(json_neigh, "bgpTimerKeepAliveIntervalMsecs", p->v_keepalive * 1000); + + if (CHECK_FLAG (p->config, PEER_CONFIG_TIMER)) + { + json_object_int_add(json_neigh, "bgpTimerConfiguredHoldTimeMsecs", p->holdtime * 1000); + json_object_int_add(json_neigh, "bgpTimerConfiguredKeepAliveIntervalMsecs", p->keepalive * 1000); + } } - vty_out (vty, "%s", VTY_NEWLINE); + else + { + /* Administrative shutdown. */ + if (CHECK_FLAG (p->flags, PEER_FLAG_SHUTDOWN)) + vty_out (vty, " Administratively shut down%s", VTY_NEWLINE); + + /* BGP Version. */ + vty_out (vty, " BGP version 4"); + vty_out (vty, ", remote router ID %s%s", inet_ntop (AF_INET, &p->remote_id, buf1, BUFSIZ), + VTY_NEWLINE); + + /* Confederation */ + if (CHECK_FLAG (bgp->config, BGP_CONFIG_CONFEDERATION) + && bgp_confederation_peers_check (bgp, p->as)) + vty_out (vty, " Neighbor under common administration%s", VTY_NEWLINE); - /* read timer */ - vty_out (vty, " Last read %s", peer_uptime (p->readtime, timebuf, BGP_UPTIME_LEN)); - vty_out (vty, ", Last write %s%s", - peer_uptime (p->last_write, timebuf, BGP_UPTIME_LEN), VTY_NEWLINE); + /* Status. */ + vty_out (vty, " BGP state = %s", LOOKUP (bgp_status_msg, p->status)); - /* Configured timer values. */ - vty_out (vty, " Hold time is %d, keepalive interval is %d seconds%s", - p->v_holdtime, p->v_keepalive, VTY_NEWLINE); - if (CHECK_FLAG (p->config, PEER_CONFIG_TIMER)) - { - vty_out (vty, " Configured hold time is %d", p->holdtime); - vty_out (vty, ", keepalive interval is %d seconds%s", - p->keepalive, VTY_NEWLINE); - } + if (p->status == Established) + vty_out (vty, ", up for %8s", peer_uptime (p->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); + + else if (p->status == Active) + { + if (CHECK_FLAG (p->flags, PEER_FLAG_PASSIVE)) + vty_out (vty, " (passive)"); + else if (CHECK_FLAG (p->sflags, PEER_STATUS_NSF_WAIT)) + vty_out (vty, " (NSF passive)"); + } + vty_out (vty, "%s", VTY_NEWLINE); + /* read timer */ + vty_out (vty, " Last read %s", peer_uptime (p->readtime, timebuf, BGP_UPTIME_LEN, 0, NULL)); + vty_out (vty, ", Last write %s%s", + peer_uptime (p->last_write, timebuf, BGP_UPTIME_LEN, 0, NULL), VTY_NEWLINE); + + /* Configured timer values. */ + vty_out (vty, " Hold time is %d, keepalive interval is %d seconds%s", + p->v_holdtime, p->v_keepalive, VTY_NEWLINE); + if (CHECK_FLAG (p->config, PEER_CONFIG_TIMER)) + { + vty_out (vty, " Configured hold time is %d", p->holdtime); + vty_out (vty, ", keepalive interval is %d seconds%s", + p->keepalive, VTY_NEWLINE); + } + } /* Capability. */ if (p->status == Established) { @@ -9374,163 +9717,365 @@ bgp_show_peer (struct vty *vty, struct peer *p) || p->afc_adv[AFI_IP][SAFI_MPLS_VPN] || p->afc_recv[AFI_IP][SAFI_MPLS_VPN]) { - vty_out (vty, " Neighbor capabilities:%s", VTY_NEWLINE); + if (use_json) + { + json_object *json_cap = NULL; + + json_cap = json_object_new_object(); + + /* AS4 */ + if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) + { + if (CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV) && CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV)) + json_object_string_add(json_cap, "4byteAs", "advertisedAndReceived"); + else if (CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) + json_object_string_add(json_cap, "4byteAs", "advertised"); + else if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV)) + json_object_string_add(json_cap, "4byteAs", "received"); + } + + /* AddPath */ + if (CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_ADV)) + { + json_object *json_add = NULL; + const char *print_store; - /* AS4 */ - if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) - { - vty_out (vty, " 4 Byte AS:"); - if (CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) - vty_out (vty, " advertised"); - if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV)) - vty_out (vty, " %sreceived", - CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV) ? "and " : ""); - vty_out (vty, "%s", VTY_NEWLINE); - } + json_add = json_object_new_object(); - /* AddPath */ - if (CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_ADV)) - { - vty_out (vty, " AddPath:%s", VTY_NEWLINE); + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + json_object *json_sub = NULL; + json_sub = json_object_new_object(); + print_store = afi_safi_print (afi, safi); + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + { + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) && CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + json_object_boolean_true_add(json_sub, "txAdvertisedAndReceived"); + else if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV)) + json_object_boolean_true_add(json_sub, "txAdvertised"); + else if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + json_object_boolean_true_add(json_sub, "txReceived"); + } + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) + { + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) && CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) + json_object_boolean_true_add(json_sub, "rxAdvertisedAndReceived"); + else if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)) + json_object_boolean_true_add(json_sub, "rxAdvertised"); + else if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) + json_object_boolean_true_add(json_sub, "rxReceived"); + } + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) + json_object_object_add(json_add, print_store, json_sub); + } - for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - { + json_object_object_add(json_cap, "addPath", json_add); + } - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) || - CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + /* Dynamic */ + if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) + { + if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV) && CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV)) + json_object_string_add(json_cap, "dynamic", "advertisedAndReceived"); + else if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) + json_object_string_add(json_cap, "dynamic", "advertised"); + else if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV)) + json_object_string_add(json_cap, "dynamic", "received"); + } + + /* Extended nexthop */ + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) + { + json_object *json_nxt = NULL; + const char *print_store; + + json_nxt = json_object_new_object(); + + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV) && CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) + json_object_string_add(json_cap, "extendedNexthop", "advertisedAndReceived"); + else if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) + json_object_string_add(json_cap, "extendedNexthop", "advertised"); + else if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) + json_object_string_add(json_cap, "extendedNexthop", "received"); + + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_RCV)) + { + print_store = afi_safi_print (AFI_IP, safi); + json_object_string_add(json_nxt, print_store, "recieved"); + } + } + json_object_object_add(json_cap, "extendedNexthopFamililesByPeer", json_nxt); + } + } + + /* Route Refresh */ + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) + || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) + { + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) && (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV))) + { + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV) && CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV)) + json_object_string_add(json_cap, "routeRefresh", "advertisedAndReceivedOldNew"); + else + { + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) + json_object_string_add(json_cap, "routeRefresh", "advertisedAndReceivedOld"); + else + json_object_string_add(json_cap, "routeRefresh", "advertisedAndReceivedNew"); + } + } + else if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV)) + json_object_string_add(json_cap, "routeRefresh", "advertised"); + else if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) + json_object_string_add(json_cap, "routeRefresh", "received"); + } + + /* Multiprotocol Extensions */ + json_object *json_multi = NULL; + json_multi = json_object_new_object(); + + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (p->afc_adv[afi][safi] || p->afc_recv[afi][safi]) + { + json_object *json_exten = NULL; + json_exten = json_object_new_object(); + + if (p->afc_adv[afi][safi] && p->afc_recv[afi][safi]) + json_object_boolean_true_add(json_exten, "advertisedAndReceived"); + else if (p->afc_adv[afi][safi]) + json_object_boolean_true_add(json_exten, "advertised"); + else if (p->afc_recv[afi][safi]) + json_object_boolean_true_add(json_exten, "received"); + + json_object_object_add(json_multi, afi_safi_print (afi, safi), json_exten); + } + } + } + json_object_object_add(json_cap, "multiprotocolExtensions", json_multi); + + /* Gracefull Restart */ + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) + { + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV) && CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) + json_object_string_add(json_cap, "gracefulRestart", "advertisedAndReceived"); + else if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) + json_object_string_add(json_cap, "gracefulRestartCapability", "advertised"); + else if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) + json_object_string_add(json_cap, "gracefulRestartCapability", "received"); + + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) + { + int restart_af_count = 0; + json_object *json_restart = NULL; + json_restart = json_object_new_object(); + + json_object_int_add(json_cap, "gracefulRestartRemoteTimerMsecs", p->v_gr_restart * 1000); + + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV)) + { + json_object *json_sub = NULL; + json_sub = json_object_new_object(); + + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV)) + json_object_boolean_true_add(json_sub, "preserved"); + restart_af_count++; + json_object_object_add(json_restart, afi_safi_print (afi, safi), json_sub); + } + } + } + if (! restart_af_count) + json_object_string_add(json_cap, "addressFamiliesByPeer", "none"); + else + json_object_object_add(json_cap, "addressFamiliesByPeer", json_restart); + } + } + json_object_object_add(json_neigh, "neighborCapabilities", json_cap); + } + else + { + vty_out (vty, " Neighbor capabilities:%s", VTY_NEWLINE); + + /* AS4 */ + if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) + { + vty_out (vty, " 4 Byte AS:"); + if (CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV)) + vty_out (vty, " advertised"); + if (CHECK_FLAG (p->cap, PEER_CAP_AS4_RCV)) + vty_out (vty, " %sreceived", + CHECK_FLAG (p->cap, PEER_CAP_AS4_ADV) ? "and " : ""); + vty_out (vty, "%s", VTY_NEWLINE); + } + + /* AddPath */ + if (CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_ADDPATH_ADV)) + { + vty_out (vty, " AddPath:%s", VTY_NEWLINE); + + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) { - vty_out (vty, " %s: TX ", afi_safi_print (afi, safi)); + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) || + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + { + vty_out (vty, " %s: TX ", afi_safi_print (afi, safi)); - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV)) - vty_out (vty, "advertised %s", afi_safi_print (afi, safi)); + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV)) + vty_out (vty, "advertised %s", afi_safi_print (afi, safi)); - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) - vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) ? " and " : "" ); + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV)) + vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_ADV) ? " and " : "" ); - vty_out (vty, "%s", VTY_NEWLINE); - } + vty_out (vty, "%s", VTY_NEWLINE); + } - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) || + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) || CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) - { - vty_out (vty, " %s: RX ", afi_safi_print (afi, safi)); + { + vty_out (vty, " %s: RX ", afi_safi_print (afi, safi)); - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)) - vty_out (vty, "advertised %s", afi_safi_print (afi, safi)); + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)) + vty_out (vty, "advertised %s", afi_safi_print (afi, safi)); - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) - vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) ? " and " : "" ); + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_RCV)) + vty_out (vty, "%sreceived", CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) ? " and " : "" ); - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + } } - } - } + } - /* Dynamic */ - if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) - { - vty_out (vty, " Dynamic:"); - if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) - vty_out (vty, " advertised"); - if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV)) - vty_out (vty, " %sreceived", - CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV) ? "and " : ""); - vty_out (vty, "%s", VTY_NEWLINE); - } + /* Dynamic */ + if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) + { + vty_out (vty, " Dynamic:"); + if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV)) + vty_out (vty, " advertised"); + if (CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_RCV)) + vty_out (vty, " %sreceived", + CHECK_FLAG (p->cap, PEER_CAP_DYNAMIC_ADV) ? "and " : ""); + vty_out (vty, "%s", VTY_NEWLINE); + } + + /* Extended nexthop */ + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) + { + vty_out (vty, " Extended nexthop:"); + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) + vty_out (vty, " advertised"); + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) + vty_out (vty, " %sreceived", + CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV) ? "and " : ""); + vty_out (vty, "%s", VTY_NEWLINE); - /* Extended nexthop */ - if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) - { - vty_out (vty, " Extended nexthop:"); - if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV)) - vty_out (vty, " advertised"); - if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) - vty_out (vty, " %sreceived", - CHECK_FLAG (p->cap, PEER_CAP_ENHE_ADV) ? "and " : ""); - vty_out (vty, "%s", VTY_NEWLINE); + if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) + { + vty_out (vty, " Address families by peer:%s ", VTY_NEWLINE); + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + if (CHECK_FLAG (p->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_RCV)) + vty_out (vty, " %s%s", + afi_safi_print (AFI_IP, safi), VTY_NEWLINE); + } + } - if (CHECK_FLAG (p->cap, PEER_CAP_ENHE_RCV)) - { - vty_out (vty, " Address families by peer:%s ", VTY_NEWLINE); - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - if (CHECK_FLAG (p->af_cap[AFI_IP][safi], PEER_CAP_ENHE_AF_RCV)) - vty_out (vty, " %s%s", - afi_safi_print (AFI_IP, safi), VTY_NEWLINE); - } - } + /* Route Refresh */ + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) + || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) + { + vty_out (vty, " Route refresh:"); + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV)) + vty_out (vty, " advertised"); + if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) + vty_out (vty, " %sreceived(%s)", + CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) ? "and " : "", + (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV) + && CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV)) ? + "old & new" : CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV) ? "old" : "new"); - /* Route Refresh */ - if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) - || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) - { - vty_out (vty, " Route refresh:"); - if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV)) - vty_out (vty, " advertised"); - if (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV)) - vty_out (vty, " %sreceived(%s)", - CHECK_FLAG (p->cap, PEER_CAP_REFRESH_ADV) ? "and " : "", - (CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV) - && CHECK_FLAG (p->cap, PEER_CAP_REFRESH_NEW_RCV)) ? - "old & new" : CHECK_FLAG (p->cap, PEER_CAP_REFRESH_OLD_RCV) ? "old" : "new"); + vty_out (vty, "%s", VTY_NEWLINE); + } - vty_out (vty, "%s", VTY_NEWLINE); - } + /* Multiprotocol Extensions */ + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + if (p->afc_adv[afi][safi] || p->afc_recv[afi][safi]) + { + vty_out (vty, " Address family %s:", afi_safi_print (afi, safi)); + if (p->afc_adv[afi][safi]) + vty_out (vty, " advertised"); + if (p->afc_recv[afi][safi]) + vty_out (vty, " %sreceived", p->afc_adv[afi][safi] ? "and " : ""); + vty_out (vty, "%s", VTY_NEWLINE); + } - /* Multiprotocol Extensions */ - for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - if (p->afc_adv[afi][safi] || p->afc_recv[afi][safi]) - { - vty_out (vty, " Address family %s:", afi_safi_print (afi, safi)); - if (p->afc_adv[afi][safi]) + /* Gracefull Restart */ + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV) + || CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) + { + vty_out (vty, " Graceful Restart Capabilty:"); + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) vty_out (vty, " advertised"); - if (p->afc_recv[afi][safi]) - vty_out (vty, " %sreceived", p->afc_adv[afi][safi] ? "and " : ""); - vty_out (vty, "%s", VTY_NEWLINE); - } - - /* Gracefull Restart */ - if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV) - || CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) - { - vty_out (vty, " Graceful Restart Capabilty:"); - if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV)) - vty_out (vty, " advertised"); - if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) - vty_out (vty, " %sreceived", - CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV) ? "and " : ""); - vty_out (vty, "%s", VTY_NEWLINE); + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) + vty_out (vty, " %sreceived", + CHECK_FLAG (p->cap, PEER_CAP_RESTART_ADV) ? "and " : ""); + vty_out (vty, "%s", VTY_NEWLINE); - if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) - { - int restart_af_count = 0; - - vty_out (vty, " Remote Restart timer is %d seconds%s", - p->v_gr_restart, VTY_NEWLINE); - vty_out (vty, " Address families by peer:%s ", VTY_NEWLINE); - - for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV)) - { - vty_out (vty, "%s%s(%s)", restart_af_count ? ", " : "", - afi_safi_print (afi, safi), - CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV) ? - "preserved" : "not preserved"); - restart_af_count++; - } - if (! restart_af_count) - vty_out (vty, "none"); - vty_out (vty, "%s", VTY_NEWLINE); - } - } + if (CHECK_FLAG (p->cap, PEER_CAP_RESTART_RCV)) + { + int restart_af_count = 0; + + vty_out (vty, " Remote Restart timer is %d seconds%s", + p->v_gr_restart, VTY_NEWLINE); + vty_out (vty, " Address families by peer:%s ", VTY_NEWLINE); + + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + if (CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_RCV)) + { + vty_out (vty, "%s%s(%s)", restart_af_count ? ", " : "", + afi_safi_print (afi, safi), + CHECK_FLAG (p->af_cap[afi][safi], PEER_CAP_RESTART_AF_PRESERVE_RCV) ? + "preserved" : "not preserved"); + restart_af_count++; + } + if (! restart_af_count) + vty_out (vty, "none"); + vty_out (vty, "%s", VTY_NEWLINE); + } + } + } } } @@ -9539,168 +10084,351 @@ bgp_show_peer (struct vty *vty, struct peer *p) || p->t_gr_restart || p->t_gr_stale) { + json_object *json_grace = NULL; + json_object *json_grace_send = NULL; + json_object *json_grace_recv = NULL; int eor_send_af_count = 0; int eor_receive_af_count = 0; - vty_out (vty, " Graceful restart informations:%s", VTY_NEWLINE); - if (p->status == Established) - { - vty_out (vty, " End-of-RIB send: "); - for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)) - { - vty_out (vty, "%s%s", eor_send_af_count ? ", " : "", - afi_safi_print (afi, safi)); - eor_send_af_count++; - } - vty_out (vty, "%s", VTY_NEWLINE); - - vty_out (vty, " End-of-RIB received: "); - for (afi = AFI_IP ; afi < AFI_MAX ; afi++) - for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) - if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED)) - { - vty_out (vty, "%s%s", eor_receive_af_count ? ", " : "", - afi_safi_print (afi, safi)); - eor_receive_af_count++; - } - vty_out (vty, "%s", VTY_NEWLINE); - } + if (use_json) + { + json_grace = json_object_new_object(); + json_grace_send = json_object_new_object(); + json_grace_recv = json_object_new_object(); + + if (p->status == Established) + { + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)) + { + json_object_boolean_true_add(json_grace_send, afi_safi_print (afi, safi)); + eor_send_af_count++; + } + } + } + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED)) + { + json_object_boolean_true_add(json_grace_recv, afi_safi_print (afi, safi)); + eor_receive_af_count++; + } + } + } + } + + json_object_object_add(json_grace, "endOfRibSend", json_grace_send); + json_object_object_add(json_grace, "endOfRibRecv", json_grace_recv); - if (p->t_gr_restart) - vty_out (vty, " The remaining time of restart timer is %ld%s", - thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE); + if (p->t_gr_restart) + json_object_int_add(json_grace, "gracefulRestartTimerMsecs", thread_timer_remain_second (p->t_gr_restart) * 1000); + + if (p->t_gr_stale) + json_object_int_add(json_grace, "gracefulStalepathTimerMsecs", thread_timer_remain_second (p->t_gr_stale) * 1000); + + json_object_object_add(json_neigh, "gracefulRestartInfo", json_grace); + } + else + { + vty_out (vty, " Graceful restart informations:%s", VTY_NEWLINE); + if (p->status == Established) + { + vty_out (vty, " End-of-RIB send: "); + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_SEND)) + { + vty_out (vty, "%s%s", eor_send_af_count ? ", " : "", + afi_safi_print (afi, safi)); + eor_send_af_count++; + } + } + } + vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, " End-of-RIB received: "); + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) + { + for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) + { + if (CHECK_FLAG (p->af_sflags[afi][safi], PEER_STATUS_EOR_RECEIVED)) + { + vty_out (vty, "%s%s", eor_receive_af_count ? ", " : "", + afi_safi_print (afi, safi)); + eor_receive_af_count++; + } + } + } + vty_out (vty, "%s", VTY_NEWLINE); + } + + if (p->t_gr_restart) + vty_out (vty, " The remaining time of restart timer is %ld%s", + thread_timer_remain_second (p->t_gr_restart), VTY_NEWLINE); - if (p->t_gr_stale) - vty_out (vty, " The remaining time of stalepath timer is %ld%s", - thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE); - } - - /* Packet counts. */ - vty_out (vty, " Message statistics:%s", VTY_NEWLINE); - vty_out (vty, " Inq depth is 0%s", VTY_NEWLINE); - vty_out (vty, " Outq depth is %lu%s", (unsigned long) p->obuf->count, VTY_NEWLINE); - vty_out (vty, " Sent Rcvd%s", VTY_NEWLINE); - vty_out (vty, " Opens: %10d %10d%s", p->open_out, p->open_in, VTY_NEWLINE); - vty_out (vty, " Notifications: %10d %10d%s", p->notify_out, p->notify_in, VTY_NEWLINE); - vty_out (vty, " Updates: %10d %10d%s", p->update_out, p->update_in, VTY_NEWLINE); - vty_out (vty, " Keepalives: %10d %10d%s", p->keepalive_out, p->keepalive_in, VTY_NEWLINE); - vty_out (vty, " Route Refresh: %10d %10d%s", p->refresh_out, p->refresh_in, VTY_NEWLINE); - vty_out (vty, " Capability: %10d %10d%s", p->dynamic_cap_out, p->dynamic_cap_in, VTY_NEWLINE); - vty_out (vty, " Total: %10d %10d%s", p->open_out + p->notify_out + - p->update_out + p->keepalive_out + p->refresh_out + p->dynamic_cap_out, - p->open_in + p->notify_in + p->update_in + p->keepalive_in + p->refresh_in + - p->dynamic_cap_in, VTY_NEWLINE); - - /* advertisement-interval */ - vty_out (vty, " Minimum time between advertisement runs is %d seconds%s", - p->v_routeadv, VTY_NEWLINE); - - /* Update-source. */ - if (p->update_if || p->update_source) - { - vty_out (vty, " Update source is "); - if (p->update_if) - vty_out (vty, "%s", p->update_if); - else if (p->update_source) - vty_out (vty, "%s", - sockunion2str (p->update_source, buf1, SU_ADDRSTRLEN)); - vty_out (vty, "%s", VTY_NEWLINE); + if (p->t_gr_stale) + vty_out (vty, " The remaining time of stalepath timer is %ld%s", + thread_timer_remain_second (p->t_gr_stale), VTY_NEWLINE); + } + } + if (use_json) + { + json_object *json_stat = NULL; + json_stat = json_object_new_object(); + /* Packet counts. */ + json_object_int_add(json_stat, "depthInq", 0); + json_object_int_add(json_stat, "depthOutq", (unsigned long) p->obuf->count); + json_object_int_add(json_stat, "opensSent", p->open_out); + json_object_int_add(json_stat, "opensRecv", p->open_in); + json_object_int_add(json_stat, "notificationsSent", p->notify_out); + json_object_int_add(json_stat, "notificationsRecv", p->notify_in); + json_object_int_add(json_stat, "updatesSent", p->update_out); + json_object_int_add(json_stat, "updatesRecv", p->update_in); + json_object_int_add(json_stat, "keepalivesSent", p->keepalive_out); + json_object_int_add(json_stat, "keepalivesRecv", p->keepalive_in); + json_object_int_add(json_stat, "routeRefreshSent", p->refresh_out); + json_object_int_add(json_stat, "routeRefreshRecv", p->refresh_in); + json_object_int_add(json_stat, "capabilitySent", p->dynamic_cap_out); + json_object_int_add(json_stat, "capabilityRecv", p->dynamic_cap_in); + json_object_int_add(json_stat, "totalSent", p->open_out + p->notify_out + p->update_out + p->keepalive_out + p->refresh_out + p->dynamic_cap_out); + json_object_int_add(json_stat, "totalRecv", p->open_in + p->notify_in + p->update_in + p->keepalive_in + p->refresh_in + p->dynamic_cap_in); + json_object_object_add(json_neigh, "messageStats", json_stat); + } + else + { + /* Packet counts. */ + vty_out (vty, " Message statistics:%s", VTY_NEWLINE); + vty_out (vty, " Inq depth is 0%s", VTY_NEWLINE); + vty_out (vty, " Outq depth is %lu%s", (unsigned long) p->obuf->count, VTY_NEWLINE); + vty_out (vty, " Sent Rcvd%s", VTY_NEWLINE); + vty_out (vty, " Opens: %10d %10d%s", p->open_out, p->open_in, VTY_NEWLINE); + vty_out (vty, " Notifications: %10d %10d%s", p->notify_out, p->notify_in, VTY_NEWLINE); + vty_out (vty, " Updates: %10d %10d%s", p->update_out, p->update_in, VTY_NEWLINE); + vty_out (vty, " Keepalives: %10d %10d%s", p->keepalive_out, p->keepalive_in, VTY_NEWLINE); + vty_out (vty, " Route Refresh: %10d %10d%s", p->refresh_out, p->refresh_in, VTY_NEWLINE); + vty_out (vty, " Capability: %10d %10d%s", p->dynamic_cap_out, p->dynamic_cap_in, VTY_NEWLINE); + vty_out (vty, " Total: %10d %10d%s", p->open_out + p->notify_out + + p->update_out + p->keepalive_out + p->refresh_out + p->dynamic_cap_out, + p->open_in + p->notify_in + p->update_in + p->keepalive_in + p->refresh_in + + p->dynamic_cap_in, VTY_NEWLINE); } - /* Default weight */ - if (CHECK_FLAG (p->config, PEER_CONFIG_WEIGHT)) - vty_out (vty, " Default weight %d%s", p->weight, - VTY_NEWLINE); + if (use_json) + { + /* advertisement-interval */ + json_object_int_add(json_neigh, "minBtwnAdvertisementRunsTimerMsecs", p->v_routeadv * 1000); - vty_out (vty, "%s", VTY_NEWLINE); + /* Update-source. */ + if (p->update_if || p->update_source) + { + if (p->update_if) + json_object_string_add(json_neigh, "updateSource", p->update_if); + else if (p->update_source) + json_object_string_add(json_neigh, "updateSource", sockunion2str (p->update_source, buf1, SU_ADDRSTRLEN)); + } + + /* Default weight */ + if (CHECK_FLAG (p->config, PEER_CONFIG_WEIGHT)) + json_object_int_add(json_neigh, "defaultWeight", p->weight); + + } + else + { + /* advertisement-interval */ + vty_out (vty, " Minimum time between advertisement runs is %d seconds%s", + p->v_routeadv, VTY_NEWLINE); + + /* Update-source. */ + if (p->update_if || p->update_source) + { + vty_out (vty, " Update source is "); + if (p->update_if) + vty_out (vty, "%s", p->update_if); + else if (p->update_source) + vty_out (vty, "%s", sockunion2str (p->update_source, buf1, SU_ADDRSTRLEN)); + vty_out (vty, "%s", VTY_NEWLINE); + } + + /* Default weight */ + if (CHECK_FLAG (p->config, PEER_CONFIG_WEIGHT)) + vty_out (vty, " Default weight %d%s", p->weight, VTY_NEWLINE); + + vty_out (vty, "%s", VTY_NEWLINE); + } /* Address Family Information */ + json_object *json_hold = NULL; + + if (use_json) + json_hold = json_object_new_object(); + for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) if (p->afc[afi][safi]) - bgp_show_peer_afi (vty, p, afi, safi); + bgp_show_peer_afi (vty, p, afi, safi, use_json, json_hold); - vty_out (vty, " Connections established %d; dropped %d%s", - p->established, p->dropped, - VTY_NEWLINE); + if (use_json) + { + json_object_int_add(json_hold, "connectionsEstablished", p->established); + json_object_int_add(json_hold, "connectionsDropped", p->dropped); + } + else + vty_out (vty, " Connections established %d; dropped %d%s", p->established, p->dropped, + VTY_NEWLINE); if (! p->last_reset) - vty_out (vty, " Last reset never%s", VTY_NEWLINE); + { + if (use_json) + json_object_string_add(json_hold, "lastReset", "never"); + else + vty_out (vty, " Last reset never%s", VTY_NEWLINE); + } else { - vty_out (vty, " Last reset %s, due to %s%s", - peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN), - peer_down_str[(int) p->last_reset], VTY_NEWLINE); - - if (p->last_reset_cause_size) + if (use_json) { - msg = p->last_reset_cause; - vty_out(vty, " Message received that caused BGP to send a NOTIFICATION:%s ", VTY_NEWLINE); - for (i = 1; i <= p->last_reset_cause_size; i++) + time_t uptime; + struct tm *tm; + + uptime = bgp_clock(); + uptime -= p->resettime; + tm = gmtime(&uptime); + json_object_int_add(json_hold, "lastResetTimerMsecs", (tm->tm_sec * 1000) + (tm->tm_min * 60000) + (tm->tm_hour * 3600000)); + json_object_string_add(json_hold, "lastResetDueTo", peer_down_str[(int) p->last_reset]); + if (p->last_reset_cause_size) { - vty_out(vty, "%02X", *msg++); + msg = p->last_reset_cause; + char adapter[BUFSIZ]; + sprintf(adapter, "%s", msg); + json_object_string_add(json_hold, "messageReceivedThatCausedBgpNotification", adapter); + } + } + else + { + vty_out (vty, " Last reset %s, due to %s%s", + peer_uptime (p->resettime, timebuf, BGP_UPTIME_LEN, 0, NULL), + peer_down_str[(int) p->last_reset], VTY_NEWLINE); - if (i != p->last_reset_cause_size) - { - if (i % 16 == 0) - { - vty_out(vty, "%s ", VTY_NEWLINE); - } - else if (i % 4 == 0) - { - vty_out(vty, " "); - } - } + if (p->last_reset_cause_size) + { + msg = p->last_reset_cause; + vty_out(vty, " Message received that caused BGP to send a NOTIFICATION:%s ", VTY_NEWLINE); + for (i = 1; i <= p->last_reset_cause_size; i++) + { + vty_out(vty, "%02X", *msg++); + + if (i != p->last_reset_cause_size) + { + if (i % 16 == 0) + { + vty_out(vty, "%s ", VTY_NEWLINE); + } + else if (i % 4 == 0) + { + vty_out(vty, " "); + } + } + } + vty_out(vty, "%s", VTY_NEWLINE); } - vty_out(vty, "%s", VTY_NEWLINE); } } if (CHECK_FLAG (p->sflags, PEER_STATUS_PREFIX_OVERFLOW)) { - vty_out (vty, " Peer had exceeded the max. no. of prefixes configured.%s", VTY_NEWLINE); + if (use_json) + json_object_boolean_true_add(json_hold, "prefixesConfigExceedMax"); + else + vty_out (vty, " Peer had exceeded the max. no. of prefixes configured.%s", VTY_NEWLINE); if (p->t_pmax_restart) - vty_out (vty, " Reduce the no. of prefix from %s, will restart in %ld seconds%s", - p->host, thread_timer_remain_second (p->t_pmax_restart), - VTY_NEWLINE); + { + if (use_json) + { + json_object_string_add(json_hold, "reducePrefixNumFrom", p->host); + json_object_int_add(json_hold, "restartInTimerMsec", thread_timer_remain_second (p->t_pmax_restart) * 1000); + } + else + vty_out (vty, " Reduce the no. of prefix from %s, will restart in %ld seconds%s", + p->host, thread_timer_remain_second (p->t_pmax_restart), + VTY_NEWLINE); + } else - vty_out (vty, " Reduce the no. of prefix and clear ip bgp %s to restore peering%s", - p->host, VTY_NEWLINE); + { + if (use_json) + json_object_string_add(json_hold, "reducePrefixNumAndClearIpBgp", p->host); + else + vty_out (vty, " Reduce the no. of prefix and clear ip bgp %s to restore peering%s", + p->host, VTY_NEWLINE); + } } + if (use_json) + json_object_object_add(json_neigh, "addressFamilyInfo", json_hold); + /* EBGP Multihop and GTSM */ if (p->sort != BGP_PEER_IBGP) { - if (p->gtsm_hops > 0) - vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", - p->gtsm_hops, VTY_NEWLINE); - else if (p->ttl > 1) - vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", - p->ttl, VTY_NEWLINE); + if (use_json) + { + if (p->gtsm_hops > 0) + json_object_int_add(json_neigh, "externalBgpNbrMaxHopsAway", p->gtsm_hops); + else if (p->ttl > 1) + json_object_int_add(json_neigh, "externalBgpNbrMaxHopsAway", p->ttl); + } + else + { + if (p->gtsm_hops > 0) + vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", + p->gtsm_hops, VTY_NEWLINE); + else if (p->ttl > 1) + vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", + p->ttl, VTY_NEWLINE); + } } else { if (p->gtsm_hops > 0) - vty_out (vty, " Internal BGP neighbor may be up to %d hops away.%s", - p->gtsm_hops, VTY_NEWLINE); + { + if (use_json) + json_object_int_add(json_neigh, "internalBgpNbrMaxHopsAway", p->gtsm_hops); + else + vty_out (vty, " Internal BGP neighbor may be up to %d hops away.%s", + p->gtsm_hops, VTY_NEWLINE); + } } /* Local address. */ if (p->su_local) { - vty_out (vty, "Local host: %s, Local port: %d%s", - sockunion2str (p->su_local, buf1, SU_ADDRSTRLEN), - ntohs (p->su_local->sin.sin_port), - VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json_neigh, "hostLocal", sockunion2str (p->su_local, buf1, SU_ADDRSTRLEN)); + json_object_int_add(json_neigh, "portLocal", ntohs (p->su_local->sin.sin_port)); + } + else + vty_out (vty, "Local host: %s, Local port: %d%s", + sockunion2str (p->su_local, buf1, SU_ADDRSTRLEN), + ntohs (p->su_local->sin.sin_port), + VTY_NEWLINE); } /* Remote address. */ if (p->su_remote) { - vty_out (vty, "Foreign host: %s, Foreign port: %d%s", + if (use_json) + { + json_object_string_add(json_neigh, "hostForeign", sockunion2str (p->su_remote, buf1, SU_ADDRSTRLEN)); + json_object_int_add(json_neigh, "portForeign", ntohs (p->su_remote->sin.sin_port)); + } + else + vty_out (vty, "Foreign host: %s, Foreign port: %d%s", sockunion2str (p->su_remote, buf1, SU_ADDRSTRLEN), ntohs (p->su_remote->sin.sin_port), VTY_NEWLINE); @@ -9709,56 +10437,108 @@ bgp_show_peer (struct vty *vty, struct peer *p) /* Nexthop display. */ if (p->su_local) { - vty_out (vty, "Nexthop: %s%s", - inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ), - VTY_NEWLINE); + if (use_json) + { + json_object_string_add(json_neigh, "nexthop", inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ)); #ifdef HAVE_IPV6 - vty_out (vty, "Nexthop global: %s%s", - inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ), - VTY_NEWLINE); - vty_out (vty, "Nexthop local: %s%s", - inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ), - VTY_NEWLINE); - vty_out (vty, "BGP connection: %s%s", - p->shared_network ? "shared network" : "non shared network", - VTY_NEWLINE); + json_object_string_add(json_neigh, "nexthopGlobal", inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ)); + json_object_string_add(json_neigh, "nexthopLocal", inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ)); + if (p->shared_network) + json_object_string_add(json_neigh, "bgpConnection", "sharedNetwork"); + else + json_object_string_add(json_neigh, "bgpConnection", "nonSharedNetwork"); #endif /* HAVE_IPV6 */ + } + else + { + vty_out (vty, "Nexthop: %s%s", + inet_ntop (AF_INET, &p->nexthop.v4, buf1, BUFSIZ), + VTY_NEWLINE); +#ifdef HAVE_IPV6 + vty_out (vty, "Nexthop global: %s%s", + inet_ntop (AF_INET6, &p->nexthop.v6_global, buf1, BUFSIZ), + VTY_NEWLINE); + vty_out (vty, "Nexthop local: %s%s", + inet_ntop (AF_INET6, &p->nexthop.v6_local, buf1, BUFSIZ), + VTY_NEWLINE); + vty_out (vty, "BGP connection: %s%s", + p->shared_network ? "shared network" : "non shared network", + VTY_NEWLINE); +#endif /* HAVE_IPV6 */ + } } /* Timer information. */ - if (p->t_start) - vty_out (vty, "Next start timer due in %ld seconds%s", - thread_timer_remain_second (p->t_start), VTY_NEWLINE); - if (p->t_connect) - vty_out (vty, "Next connect timer due in %ld seconds%s", - thread_timer_remain_second (p->t_connect), VTY_NEWLINE); - if (p->t_routeadv) - vty_out (vty, "MRAI (interval %u) timer expires in %ld seconds%s", - p->v_routeadv, thread_timer_remain_second (p->t_routeadv), - VTY_NEWLINE); + if (use_json) + { + if (p->t_start) + json_object_int_add(json_neigh, "nextStartTimerDueInMsecs", thread_timer_remain_second (p->t_start) * 1000); + if (p->t_connect) + json_object_int_add(json_neigh, "nextConnectTimerDueInMsecs", thread_timer_remain_second (p->t_connect) * 1000); + if (p->t_routeadv) + { + json_object_int_add(json_neigh, "mraiInterval", p->v_routeadv); + json_object_int_add(json_neigh, "mraiTimerExpireInMsecs", thread_timer_remain_second (p->t_routeadv) * 1000); + } - vty_out (vty, "Read thread: %s Write thread: %s%s", - p->t_read ? "on" : "off", - p->t_write ? "on" : "off", - VTY_NEWLINE); + if (p->t_read) + json_object_string_add(json_neigh, "readThread", "on"); + else + json_object_string_add(json_neigh, "readThread", "off"); + if (p->t_write) + json_object_string_add(json_neigh, "writeThread", "on"); + else + json_object_string_add(json_neigh, "writeThread", "off"); + } + else + { + if (p->t_start) + vty_out (vty, "Next start timer due in %ld seconds%s", + thread_timer_remain_second (p->t_start), VTY_NEWLINE); + if (p->t_connect) + vty_out (vty, "Next connect timer due in %ld seconds%s", + thread_timer_remain_second (p->t_connect), VTY_NEWLINE); + if (p->t_routeadv) + vty_out (vty, "MRAI (interval %u) timer expires in %ld seconds%s", + p->v_routeadv, thread_timer_remain_second (p->t_routeadv), + VTY_NEWLINE); + + vty_out (vty, "Read thread: %s Write thread: %s%s", + p->t_read ? "on" : "off", + p->t_write ? "on" : "off", + VTY_NEWLINE); + } if (p->notify.code == BGP_NOTIFY_OPEN_ERR && p->notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL) - bgp_capability_vty_out (vty, p); - - vty_out (vty, "%s", VTY_NEWLINE); + bgp_capability_vty_out (vty, p, use_json, json_neigh); + + if (!use_json) + vty_out (vty, "%s", VTY_NEWLINE); /* BFD information. */ - bgp_bfd_show_info(vty, p); + bgp_bfd_show_info(vty, p, use_json, json_neigh); + + if (use_json) + { + if (p->conf_if) /* Configured interface name. */ + json_object_object_add(json, p->conf_if, json_neigh); + else /* Configured IP address. */ + json_object_object_add(json, p->host, json_neigh); + } } static int -bgp_show_neighbor (struct vty *vty, struct bgp *bgp, - enum show_type type, union sockunion *su, const char *conf_if) +bgp_show_neighbor (struct vty *vty, struct bgp *bgp, enum show_type type, + union sockunion *su, const char *conf_if, u_char use_json, json_object *json) { struct listnode *node, *nnode; struct peer *peer; int find = 0; + json_object *json_neigh = NULL; + + if (use_json) + json_neigh = json_object_new_object(); for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { @@ -9766,51 +10546,78 @@ bgp_show_neighbor (struct vty *vty, struct bgp *bgp, continue; switch (type) - { - case show_all: - bgp_show_peer (vty, peer); - break; - case show_peer: - if (conf_if) - { - if (peer->conf_if && !strcmp(peer->conf_if, conf_if)) - { - find = 1; - bgp_show_peer (vty, peer); - } - } - else - { - if (sockunion_same (&peer->su, su)) - { - find = 1; - bgp_show_peer (vty, peer); - } - } - break; + { + case show_all: + bgp_show_peer (vty, peer, use_json, json, json_neigh); + break; + case show_peer: + if (conf_if) + { + if (peer->conf_if && !strcmp(peer->conf_if, conf_if)) + { + find = 1; + bgp_show_peer (vty, peer, use_json, json, json_neigh); + } + } + else + { + if (sockunion_same (&peer->su, su)) + { + find = 1; + bgp_show_peer (vty, peer, use_json, json, json_neigh); + } + } + break; } } if (type == show_peer && ! find) - vty_out (vty, "%% No such neighbor%s", VTY_NEWLINE); - + { + if (use_json) + json_object_boolean_true_add(json, "bgpNoSuchNeighbor"); + else + vty_out (vty, "%% No such neighbor%s", VTY_NEWLINE); + } + + if (use_json) + { + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + { + vty_out (vty, "%s", VTY_NEWLINE); + } + return CMD_SUCCESS; } static int bgp_show_neighbor_vty (struct vty *vty, const char *name, - enum show_type type, const char *ip_str) + enum show_type type, const char *ip_str, u_char use_json) { int ret; struct bgp *bgp; union sockunion su; + json_object *json = NULL; + + if (use_json) + json = json_object_new_object(); if (name) { bgp = bgp_lookup_by_name (name); if (! bgp) { - vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE); + if (use_json) + { + json_object_boolean_true_add(json, "bgpNoSuchInstance"); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE); + return CMD_WARNING; } } @@ -9825,13 +10632,13 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name, { ret = str2sockunion (ip_str, &su); if (ret < 0) - bgp_show_neighbor (vty, bgp, type, NULL, ip_str); + bgp_show_neighbor (vty, bgp, type, NULL, ip_str, use_json, json); else - bgp_show_neighbor (vty, bgp, type, &su, NULL); + bgp_show_neighbor (vty, bgp, type, &su, NULL, use_json, json); } else { - bgp_show_neighbor (vty, bgp, type, NULL, NULL); + bgp_show_neighbor (vty, bgp, type, NULL, NULL, use_json, json); } } @@ -9841,79 +10648,100 @@ bgp_show_neighbor_vty (struct vty *vty, const char *name, /* "show ip bgp neighbors" commands. */ DEFUN (show_ip_bgp_neighbors, show_ip_bgp_neighbors_cmd, - "show ip bgp neighbors", + "show ip bgp neighbors {json}", SHOW_STR IP_STR BGP_STR - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") { - return bgp_show_neighbor_vty (vty, NULL, show_all, NULL); + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + return bgp_show_neighbor_vty (vty, NULL, show_all, NULL, use_json); } ALIAS (show_ip_bgp_neighbors, show_ip_bgp_ipv4_neighbors_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors", + "show ip bgp ipv4 (unicast|multicast) neighbors {json}", SHOW_STR IP_STR BGP_STR "Address family\n" "Address Family modifier\n" "Address Family modifier\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors, show_ip_bgp_vpnv4_all_neighbors_cmd, - "show ip bgp vpnv4 all neighbors", + "show ip bgp vpnv4 all neighbors {json}", SHOW_STR IP_STR BGP_STR "Display VPNv4 NLRI specific information\n" "Display information about all VPNv4 NLRIs\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors, show_ip_bgp_vpnv4_rd_neighbors_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors", + "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors {json}", SHOW_STR IP_STR BGP_STR "Display VPNv4 NLRI specific information\n" "Display information for a route distinguisher\n" "VPN Route Distinguisher\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors, show_bgp_neighbors_cmd, - "show bgp neighbors", + "show bgp neighbors {json}", SHOW_STR BGP_STR - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors, show_bgp_ipv6_neighbors_cmd, - "show bgp ipv6 neighbors", + "show bgp ipv6 neighbors {json}", SHOW_STR BGP_STR "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_neighbors_peer, show_ip_bgp_neighbors_peer_cmd, - "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD)", + "show ip bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR IP_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") { - return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 1]); + u_char use_json; + + if (argv[argc - 1] && strcmp(argv[argc - 1], "json") == 0) + use_json = 1; + else + use_json = 0; + + return bgp_show_neighbor_vty (vty, NULL, show_peer, argv[argc - 2], use_json); } ALIAS (show_ip_bgp_neighbors_peer, show_ip_bgp_ipv4_neighbors_peer_cmd, - "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD)", + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR IP_STR BGP_STR @@ -9923,86 +10751,101 @@ ALIAS (show_ip_bgp_neighbors_peer, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors_peer, show_ip_bgp_vpnv4_all_neighbors_peer_cmd, - "show ip bgp vpnv4 all neighbors A.B.C.D", + "show ip bgp vpnv4 all neighbors A.B.C.D {json}", SHOW_STR IP_STR BGP_STR "Display VPNv4 NLRI specific information\n" "Display information about all VPNv4 NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors_peer, show_ip_bgp_vpnv4_rd_neighbors_peer_cmd, - "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D", + "show ip bgp vpnv4 rd ASN:nn_or_IP-address:nn neighbors A.B.C.D {json}", SHOW_STR IP_STR BGP_STR "Display VPNv4 NLRI specific information\n" "Display information about all VPNv4 NLRIs\n" "Detailed information on TCP and BGP neighbor connections\n" - "Neighbor to display information about\n") + "Neighbor to display information about\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors_peer, show_bgp_neighbors_peer_cmd, - "show bgp neighbors (A.B.C.D|X:X::X:X|WORD)", + "show bgp neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR BGP_STR "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_neighbors_peer, show_bgp_ipv6_neighbors_peer_cmd, - "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD)", + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR BGP_STR "Address family\n" "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_instance_neighbors, show_ip_bgp_instance_neighbors_cmd, - "show ip bgp view WORD neighbors", + "show ip bgp view WORD neighbors {json}", SHOW_STR IP_STR BGP_STR "BGP view\n" "View name\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") { - return bgp_show_neighbor_vty (vty, argv[0], show_all, NULL); + u_char use_json; + + if (argv[1] && strcmp(argv[1], "json") == 0) + use_json = 1; + else + use_json = 0; + + return bgp_show_neighbor_vty (vty, argv[0], show_all, NULL, use_json); } ALIAS (show_ip_bgp_instance_neighbors, show_bgp_instance_neighbors_cmd, - "show bgp view WORD neighbors", + "show bgp view WORD neighbors {json}", SHOW_STR BGP_STR "BGP view\n" "View name\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_instance_neighbors, show_bgp_instance_ipv6_neighbors_cmd, - "show bgp view WORD ipv6 neighbors", + "show bgp view WORD ipv6 neighbors {json}", SHOW_STR BGP_STR "BGP view\n" "View name\n" "Address family\n" - "Detailed information on TCP and BGP neighbor connections\n") + "Detailed information on TCP and BGP neighbor connections\n" + "JavaScript Object Notation\n") DEFUN (show_ip_bgp_instance_neighbors_peer, show_ip_bgp_instance_neighbors_peer_cmd, - "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD)", + "show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR IP_STR BGP_STR @@ -10011,14 +10854,22 @@ DEFUN (show_ip_bgp_instance_neighbors_peer, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") { - return bgp_show_neighbor_vty (vty, argv[0], show_peer, argv[1]); + u_char use_json; + + if (argv[2] && strcmp(argv[2], "json") == 0) + use_json = 1; + else + use_json = 0; + + return bgp_show_neighbor_vty (vty, argv[0], show_peer, argv[1], use_json); } ALIAS (show_ip_bgp_instance_neighbors_peer, show_bgp_instance_neighbors_peer_cmd, - "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD)", + "show bgp view WORD neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR BGP_STR "BGP view\n" @@ -10026,11 +10877,12 @@ ALIAS (show_ip_bgp_instance_neighbors_peer, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") ALIAS (show_ip_bgp_instance_neighbors_peer, show_bgp_instance_ipv6_neighbors_peer_cmd, - "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD)", + "show bgp view WORD ipv6 neighbors (A.B.C.D|X:X::X:X|WORD) {json}", SHOW_STR BGP_STR "BGP view\n" @@ -10039,7 +10891,8 @@ ALIAS (show_ip_bgp_instance_neighbors_peer, "Detailed information on TCP and BGP neighbor connections\n" "Neighbor to display information about\n" "Neighbor to display information about\n" - "Neighbor on bgp configured interface\n") + "Neighbor on bgp configured interface\n" + "JavaScript Object Notation\n") /* Show BGP's AS paths internal data. There are both `show ip bgp paths' and `show ip mbgp paths'. Those functions results are the @@ -10171,7 +11024,7 @@ bgp_write_rsclient_summary (struct vty *vty, struct peer *rsclient, rmname = ""; vty_out (vty, " %13s ", rmname); - vty_out (vty, "%8s", peer_uptime (rsclient->uptime, timebuf, BGP_UPTIME_LEN)); + vty_out (vty, "%8s", peer_uptime (rsclient->uptime, timebuf, BGP_UPTIME_LEN, 0, NULL)); if (CHECK_FLAG (rsclient->flags, PEER_FLAG_SHUTDOWN)) vty_out (vty, " Idle (Admin)"); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index ada6a0ea96..cb28b5cb30 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */ #include "routemap.h" #include "thread.h" #include "queue.h" +#include "lib/json.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_route.h" diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 7651505a65..3d6553cac2 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include +#include "lib/json.h" #include "prefix.h" #include "thread.h" #include "buffer.h" @@ -5853,7 +5854,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi, /* Display peer uptime.*/ /* XXX: why does this function return char * when it takes buffer? */ char * -peer_uptime (time_t uptime2, char *buf, size_t len) +peer_uptime (time_t uptime2, char *buf, size_t len, u_char use_json, json_object *json) { time_t uptime1; struct tm *tm; @@ -5861,16 +5862,22 @@ peer_uptime (time_t uptime2, char *buf, size_t len) /* Check buffer length. */ if (len < BGP_UPTIME_LEN) { - zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len); - /* XXX: should return status instead of buf... */ - snprintf (buf, len, " "); + if (!use_json) + { + zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len); + /* XXX: should return status instead of buf... */ + snprintf (buf, len, " "); + } return buf; } /* If there is no connection has been done before print `never'. */ if (uptime2 == 0) { - snprintf (buf, len, "never"); + if (use_json) + json_object_string_add(json, "peerUptime", "never"); + else + snprintf (buf, len, "never"); return buf; } @@ -5883,15 +5890,48 @@ peer_uptime (time_t uptime2, char *buf, size_t len) #define ONE_DAY_SECOND 60*60*24 #define ONE_WEEK_SECOND 60*60*24*7 - if (uptime1 < ONE_DAY_SECOND) - snprintf (buf, len, "%02d:%02d:%02d", - tm->tm_hour, tm->tm_min, tm->tm_sec); - else if (uptime1 < ONE_WEEK_SECOND) - snprintf (buf, len, "%dd%02dh%02dm", - tm->tm_yday, tm->tm_hour, tm->tm_min); + if (use_json) + { + int time_store; + int day_msec = 86400000; + int hour_msec = 3600000; + int minute_msec = 60000; + int sec_msec = 1000; + + if (uptime1 < ONE_DAY_SECOND) + { + time_store = hour_msec * tm->tm_hour + minute_msec * tm->tm_min + sec_msec * tm->tm_sec; + json_object_int_add(json, "peerUptimeMsec", time_store); + snprintf (buf, len, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + } + else if (uptime1 < ONE_WEEK_SECOND) + { + time_store = day_msec * tm->tm_yday + hour_msec * tm->tm_hour + minute_msec * tm->tm_min + sec_msec * tm->tm_sec; + json_object_int_add(json, "peerUptimeMsec", time_store); + snprintf (buf, len, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + } + else + { + time_store = day_msec * tm->tm_yday + hour_msec * tm->tm_hour + minute_msec * tm->tm_min + sec_msec * tm->tm_sec; + json_object_int_add(json, "peerUptimeMsec", time_store); + snprintf (buf, len, "%02dw%dd%02dh", + tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + } + } else - snprintf (buf, len, "%02dw%dd%02dh", - tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + { + if (uptime1 < ONE_DAY_SECOND) + snprintf (buf, len, "%02d:%02d:%02d", + tm->tm_hour, tm->tm_min, tm->tm_sec); + else if (uptime1 < ONE_WEEK_SECOND) + snprintf (buf, len, "%dd%02dh%02dm", + tm->tm_yday, tm->tm_hour, tm->tm_min); + else + snprintf (buf, len, "%02dw%dd%02dh", + tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour); + } return buf; } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 851132cb8b..f3edb66849 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #ifndef _QUAGGA_BGPD_H #define _QUAGGA_BGPD_H +#include "lib/json.h" /* For union sockunion. */ #include "queue.h" #include "sockunion.h" @@ -1147,7 +1148,8 @@ extern struct peer *peer_create(union sockunion *, const char *, struct bgp *, as_t, as_t, int, afi_t, safi_t); extern struct peer *peer_create_accept (struct bgp *); extern void peer_xfer_config (struct peer *dst, struct peer *src); -extern char *peer_uptime (time_t, char *, size_t); +extern char *peer_uptime (time_t, char *, size_t, u_char, json_object *); + extern int bgp_config_write (struct vty *); extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *); diff --git a/lib/plist.c b/lib/plist.c index 10012f3dc4..2418c8621d 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -20,6 +20,7 @@ */ #include +#include "lib/json.h" #include "prefix.h" #include "command.h" @@ -2559,10 +2560,13 @@ prefix_bgp_orf_remove_all (char *name) /* return prefix count */ int -prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name) +prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name, u_char use_json) { struct prefix_list *plist; struct prefix_list_entry *pentry; + json_object *json = NULL; + json_object *json_prefix = NULL; + json_object *json_list = NULL; plist = prefix_list_lookup (AFI_ORF_PREFIX, name); if (! plist) @@ -2571,26 +2575,65 @@ prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name) if (! vty) return plist->count; - vty_out (vty, "ip%s prefix-list %s: %d entries%s", - afi == AFI_IP ? "" : "v6", - plist->name, plist->count, VTY_NEWLINE); - - for (pentry = plist->head; pentry; pentry = pentry->next) + if(use_json) { - struct prefix *p = &pentry->prefix; - char buf[BUFSIZ]; + json = json_object_new_object(); + json_prefix = json_object_new_object(); + json_list = json_object_new_object(); - vty_out (vty, " seq %d %s %s/%d", pentry->seq, - prefix_list_type_str (pentry), - inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), - p->prefixlen); + json_object_int_add(json_prefix, "prefixListCounter", plist->count); + json_object_string_add(json_prefix, "prefixListName", plist->name); - if (pentry->ge) - vty_out (vty, " ge %d", pentry->ge); - if (pentry->le) - vty_out (vty, " le %d", pentry->le); + for (pentry = plist->head; pentry; pentry = pentry->next) + { + struct prefix *p = &pentry->prefix; + char buf_a[BUFSIZ]; + char buf_b[BUFSIZ]; + + sprintf(buf_a, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf_b, BUFSIZ), + p->prefixlen); + + json_object_int_add(json_list, "seq", pentry->seq); + json_object_string_add(json_list, "seqPrefixListType", prefix_list_type_str (pentry)); + + if (pentry->ge) + json_object_int_add(json_list, "ge", pentry->ge); + if (pentry->le) + json_object_int_add(json_list, "le", pentry->le); + + json_object_object_add(json_prefix, buf_a, json_list); + } + if (afi == AFI_IP) + json_object_object_add(json, "ipPrefixList", json_prefix); + else + json_object_object_add(json, "ipv6PrefixList", json_prefix); - vty_out (vty, "%s", VTY_NEWLINE); + vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE); + json_object_free(json); + } + else + { + vty_out (vty, "ip%s prefix-list %s: %d entries%s", + afi == AFI_IP ? "" : "v6", + plist->name, plist->count, VTY_NEWLINE); + + for (pentry = plist->head; pentry; pentry = pentry->next) + { + struct prefix *p = &pentry->prefix; + char buf[BUFSIZ]; + + vty_out (vty, " seq %d %s %s/%d", pentry->seq, + prefix_list_type_str (pentry), + inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), + p->prefixlen); + + if (pentry->ge) + vty_out (vty, " ge %d", pentry->ge); + if (pentry->le) + vty_out (vty, " le %d", pentry->le); + + vty_out (vty, "%s", VTY_NEWLINE); + } } return plist->count; } diff --git a/lib/plist.h b/lib/plist.h index fb3168a6ee..4359a8935c 100644 --- a/lib/plist.h +++ b/lib/plist.h @@ -78,6 +78,6 @@ extern struct stream * prefix_bgp_orf_entry (struct stream *, u_char, u_char, u_char); extern int prefix_bgp_orf_set (char *, afi_t, struct orf_prefix *, int, int); extern void prefix_bgp_orf_remove_all (char *); -extern int prefix_bgp_show_prefix_list (struct vty *, afi_t, char *); +extern int prefix_bgp_show_prefix_list (struct vty *, afi_t, char *, u_char); #endif /* _QUAGGA_PLIST_H */