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.
This commit is contained in:
Morgan Stewart 2015-08-12 06:59:18 -07:00
parent 308d14aed9
commit 856ca177c4
17 changed files with 3621 additions and 1621 deletions

View file

@ -33,6 +33,7 @@
#include "zclient.h" #include "zclient.h"
#include "vty.h" #include "vty.h"
#include "bfd.h" #include "bfd.h"
#include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgp_fsm.h" #include "bgp_fsm.h"
#include "bgpd/bgp_bfd.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. * bgp_bfd_show_info - Show the peer BFD information.
*/ */
void 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; struct bfd_info *bfd_info;
json_object *json_bfd = NULL;
if (!peer->bfd_info) if (!peer->bfd_info)
return; return;
if (use_json)
json_bfd = json_object_new_object();
bfd_info = (struct bfd_info *)peer->bfd_info; bfd_info = (struct bfd_info *)peer->bfd_info;
vty_out (vty, " BFD: Multi-hop: %s%s", if (use_json)
(bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE); {
vty_out (vty, " Detect Mul: %d, Min Rx interval: %d," if (bgp_bfd_is_peer_multihop(peer))
" Min Tx interval: %d%s", json_object_string_add(json_bfd, "bfdMultiHop", "yes");
bfd_info->detect_mult, bfd_info->required_min_rx, else
bfd_info->desired_min_tx, VTY_NEWLINE); json_object_string_add(json_bfd, "bfdMultiHop", "no");
vty_out (vty, "%s", VTY_NEWLINE); 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, DEFUN (neighbor_bfd,

View file

@ -40,6 +40,6 @@ extern void
bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr); bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr);
extern void 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 */ #endif /* _QUAGGA_BGP_BFD_H */

View file

@ -543,10 +543,11 @@ bgp_config_write_damp (struct vty *vty)
} }
static const char * 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; time_t reuse_time = 0;
struct tm *tm = NULL; struct tm *tm = NULL;
int time_store = 0;
if (penalty > damp->reuse_limit) 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_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7 #define ONE_WEEK_SECOND 60*60*24*7
if (reuse_time == 0) 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) 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) 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 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; 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, "dampeningPenalty", penalty);
json_object_int_add(json_path, "dampeningFlapCount", bdi->flap); 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, 1, json_path);
peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN));
if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED) if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
{ bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN, 1, json_path);
json_object_string_add(json_path, "dampeningReuseIn",
bgp_get_reuse_time (penalty, timebuf, BGP_UPTIME_LEN));
}
} }
else else
{ {
vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s", vty_out (vty, " Dampinfo: penalty %d, flapped %d times in %s",
penalty, bdi->flap, 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) if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
&& ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", reuse in %s", 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); vty_out (vty, "%s", VTY_NEWLINE);
} }
@ -634,7 +660,7 @@ bgp_damp_info_vty (struct vty *vty, struct bgp_info *binfo,
const char * const char *
bgp_damp_reuse_time_vty (struct vty *vty, struct bgp_info *binfo, 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; struct bgp_damp_info *bdi;
time_t t_now, t_diff; 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; t_diff = t_now - bdi->t_updated;
penalty = bgp_damp_decay (t_diff, bdi->penalty); 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);
} }

View file

@ -21,8 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_DAMP_H #ifndef _QUAGGA_BGP_DAMP_H
#define _QUAGGA_BGP_DAMP_H #define _QUAGGA_BGP_DAMP_H
#include "lib/json.h"
/* Structure maintained on a per-route basis. */ /* Structure maintained on a per-route basis. */
struct bgp_damp_info 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_config_write_damp (struct vty *);
extern void bgp_damp_info_vty (struct vty *, struct bgp_info *, json_object *json_path); 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 *, 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 */ #endif /* _QUAGGA_BGP_DAMP_H */

View file

@ -33,6 +33,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "workqueue.h" #include "workqueue.h"
#include "queue.h" #include "queue.h"
#include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"

View file

@ -27,6 +27,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "stream.h" #include "stream.h"
#include "queue.h" #include "queue.h"
#include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_table.h" #include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"
@ -331,7 +332,7 @@ DEFUN (no_vpnv4_network,
} }
static int 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 *bgp;
struct bgp_table *table; 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 rd_header;
int header = 1; int header = 1;
char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; 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 (); bgp = bgp_get_default ();
if (bgp == NULL) 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; 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; for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn;
rn = bgp_route_next (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 ((table = rn->info) != NULL)
{ {
if (use_json)
json_array = json_object_new_array();
else
json_array = NULL;
rd_header = 1; rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
if ((attr = rm->info) != NULL) {
{ if ((attr = rm->info) != NULL)
if (header) {
{ if (header)
vty_out (vty, "BGP table version is 0, local router ID is %s%s", {
inet_ntoa (bgp->router_id), VTY_NEWLINE); if (use_json)
vty_out (vty, "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal%s", {
VTY_NEWLINE); json_object_int_add(json, "bgpTableVersion", 0);
vty_out (vty, "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s", json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
VTY_NEWLINE, VTY_NEWLINE); json_object_object_add(json, "bgpStatusCodes", json_scode);
vty_out (vty, v4_header, VTY_NEWLINE); json_object_object_add(json, "bgpOriginCodes", json_ocode);
header = 0; }
} 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) if (rd_header)
{ {
u_int16_t type; u_int16_t type;
struct rd_as rd_as; struct rd_as rd_as;
struct rd_ip rd_ip; struct rd_ip rd_ip;
u_char *pnt; u_char *pnt;
pnt = rn->p.u.val; pnt = rn->p.u.val;
/* Decode RD type. */ /* Decode RD type. */
type = decode_rd_type (pnt); type = decode_rd_type (pnt);
/* Decode RD value. */ /* Decode RD value. */
if (type == RD_TYPE_AS) if (type == RD_TYPE_AS)
decode_rd_as (pnt + 2, &rd_as); decode_rd_as (pnt + 2, &rd_as);
else if (type == RD_TYPE_IP) else if (type == RD_TYPE_IP)
decode_rd_ip (pnt + 2, &rd_ip); decode_rd_ip (pnt + 2, &rd_ip);
vty_out (vty, "Route Distinguisher: "); 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) if (type == RD_TYPE_AS)
vty_out (vty, "%u:%d", rd_as.as, rd_as.val); vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
else if (type == RD_TYPE_IP) else if (type == RD_TYPE_IP)
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
vty_out (vty, "%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE);
rd_header = 0; }
} rd_header = 0;
route_vty_out_tmp (vty, &rm->p, attr, SAFI_MPLS_VPN); }
} 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; return CMD_SUCCESS;
} }
@ -426,7 +496,7 @@ enum bgp_show_type
static int static int
bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type type, 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 *bgp;
struct bgp_table *table; 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; int header = 1;
char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s"; char v4_header[] = " Network Next Hop Metric LocPrf Weight Path%s";
char v4_header_tag[] = " Network Next Hop In tag/Out tag%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 (); bgp = bgp_get_default ();
if (bgp == NULL) 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; 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) if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
continue; continue;
@ -455,66 +552,124 @@ bgp_show_mpls_vpn (struct vty *vty, struct prefix_rd *prd, enum bgp_show_type ty
rd_header = 1; rd_header = 1;
for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm)) for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
for (ri = rm->info; ri; ri = ri->next) {
{ if (use_json)
if (type == bgp_show_type_neighbor) json_array = json_object_new_array();
{ else
union sockunion *su = output_arg; json_array = NULL;
if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su)) for (ri = rm->info; ri; ri = ri->next)
continue; {
} if (type == bgp_show_type_neighbor)
if (header) {
{ union sockunion *su = output_arg;
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) if (ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
{ continue;
u_int16_t type; }
struct rd_as rd_as; if (header)
struct rd_ip rd_ip; {
u_char *pnt; 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;
}
pnt = rn->p.u.val; if (rd_header)
{
u_int16_t type;
struct rd_as rd_as;
struct rd_ip rd_ip;
u_char *pnt;
/* Decode RD type. */ pnt = rn->p.u.val;
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: "); /* 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 (type == RD_TYPE_AS) if (use_json)
vty_out (vty, "%u:%d", rd_as.as, rd_as.val); {
else if (type == RD_TYPE_IP) char buffer[BUFSIZ];
vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val); 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: ");
vty_out (vty, "%s", VTY_NEWLINE); if (type == RD_TYPE_AS)
rd_header = 0; vty_out (vty, "%u:%d", rd_as.as, rd_as.val);
} else if (type == RD_TYPE_IP)
if (tags) vty_out (vty, "%s:%d", inet_ntoa (rd_ip.ip), rd_ip.val);
route_vty_out_tag (vty, &rm->p, ri, 0, SAFI_MPLS_VPN); vty_out (vty, "%s", VTY_NEWLINE);
else }
route_vty_out (vty, &rm->p, ri, 0, SAFI_MPLS_VPN, NULL); 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; return CMD_SUCCESS;
} }
@ -527,7 +682,7 @@ DEFUN (show_ip_bgp_vpnv4_all,
"Display VPNv4 NLRI specific information\n" "Display VPNv4 NLRI specific information\n"
"Display information about all VPNv4 NLRIs\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, 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); vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING; 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, 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 information about all VPNv4 NLRIs\n"
"Display BGP tags for prefixes\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, 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); vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
return CMD_WARNING; 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, DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
show_ip_bgp_vpnv4_all_neighbor_routes_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -598,32 +753,52 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_routes,
"Display information about all VPNv4 NLRIs\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"
"Neighbor to display information about\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; union sockunion su;
struct peer *peer; struct peer *peer;
int ret; int ret;
u_char use_json = (argv[1] != NULL);
ret = str2sockunion (argv[0], &su); ret = str2sockunion (argv[0], &su);
if (ret < 0) 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; return CMD_WARNING;
} }
peer = peer_lookup (NULL, &su); peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 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 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, DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
show_ip_bgp_vpnv4_rd_neighbor_routes_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -632,40 +807,69 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_routes,
"VPN 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"
"Neighbor to display information about\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; int ret;
union sockunion su; union sockunion su;
struct peer *peer; struct peer *peer;
struct prefix_rd prd; struct prefix_rd prd;
u_char use_json = (argv[2] != NULL);
ret = str2prefix_rd (argv[0], &prd); ret = str2prefix_rd (argv[0], &prd);
if (! ret) 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 CMD_WARNING;
} }
ret = str2sockunion (argv[1], &su); ret = str2sockunion (argv[1], &su);
if (ret < 0) 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; return CMD_WARNING;
} }
peer = peer_lookup (NULL, &su); peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 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 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, DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
show_ip_bgp_vpnv4_all_neighbor_advertised_routes_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -673,31 +877,51 @@ DEFUN (show_ip_bgp_vpnv4_all_neighbor_advertised_routes,
"Display information about all VPNv4 NLRIs\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"
"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")
{ {
int ret; int ret;
struct peer *peer; struct peer *peer;
union sockunion su; union sockunion su;
u_char use_json = (argv[1] != NULL);
ret = str2sockunion (argv[0], &su); ret = str2sockunion (argv[0], &su);
if (ret < 0) 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; return CMD_WARNING;
} }
peer = peer_lookup (NULL, &su); peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 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 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, DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
show_ip_bgp_vpnv4_rd_neighbor_advertised_routes_cmd, 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 SHOW_STR
IP_STR IP_STR
BGP_STR BGP_STR
@ -706,34 +930,63 @@ DEFUN (show_ip_bgp_vpnv4_rd_neighbor_advertised_routes,
"VPN 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"
"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")
{ {
int ret; int ret;
struct peer *peer; struct peer *peer;
struct prefix_rd prd; struct prefix_rd prd;
union sockunion su; union sockunion su;
u_char use_json = (argv[2] != NULL);
ret = str2sockunion (argv[1], &su); ret = str2sockunion (argv[1], &su);
if (ret < 0) 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; return CMD_WARNING;
} }
peer = peer_lookup (NULL, &su); peer = peer_lookup (NULL, &su);
if (! peer || ! peer->afc[AFI_IP][SAFI_MPLS_VPN]) 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 CMD_WARNING;
} }
ret = str2prefix_rd (argv[0], &prd); ret = str2prefix_rd (argv[0], &prd);
if (! ret) 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 CMD_WARNING;
} }
return show_adj_route_vpn (vty, peer, &prd); return show_adj_route_vpn (vty, peer, &prd, use_json);
} }
void void

View file

@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h" #include "memory.h"
#include "queue.h" #include "queue.h"
#include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"
@ -49,12 +50,16 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
inforation at each peer. */ inforation at each peer. */
void 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 *pnt;
char *end; char *end;
struct capability_mp_data mpc; struct capability_mp_data mpc;
struct capability_header *hdr; struct capability_header *hdr;
json_object *json_cap = NULL;
if (use_json)
json_cap = json_object_new_object();
pnt = peer->notify.data; pnt = peer->notify.data;
end = pnt + peer->notify.length; 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) if (hdr->code == CAPABILITY_CODE_MP)
{ {
vty_out (vty, " Capability error for: Multi protocol "); if (use_json)
{
switch (ntohs (mpc.afi)) switch (ntohs (mpc.afi))
{ {
case AFI_IP: case AFI_IP:
vty_out (vty, "AFI IPv4, "); json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv4");
break; break;
case AFI_IP6: case AFI_IP6:
vty_out (vty, "AFI IPv6, "); json_object_string_add(json_cap, "capabilityErrorMultiProtocolAfi", "IPv6");
break; break;
default: default:
vty_out (vty, "AFI Unknown %d, ", ntohs (mpc.afi)); json_object_int_add(json_cap, "capabilityErrorMultiProtocolAfiUnknown", ntohs (mpc.afi));
break; break;
} }
switch (mpc.safi) switch (mpc.safi)
{ {
case SAFI_UNICAST: case SAFI_UNICAST:
vty_out (vty, "SAFI Unicast"); json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "unicast");
break; break;
case SAFI_MULTICAST: case SAFI_MULTICAST:
vty_out (vty, "SAFI Multicast"); json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "multicast");
break; break;
case SAFI_MPLS_LABELED_VPN: case SAFI_MPLS_LABELED_VPN:
vty_out (vty, "SAFI MPLS-labeled VPN"); json_object_string_add(json_cap, "capabilityErrorMultiProtocolSafi", "MPLS-labeled VPN");
break; break;
default: default:
vty_out (vty, "SAFI Unknown %d ", mpc.safi); json_object_int_add(json_cap, "capabilityErrorMultiProtocolSafiUnknown", mpc.safi);
break; break;
} }
vty_out (vty, "%s", VTY_NEWLINE); }
} 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) 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 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; pnt += hdr->length + 2;
} }
if (use_json)
json_object_object_add(json_neigh, "capabilityErrors", json_cap);
} }
static void static void

View file

@ -109,7 +109,7 @@ struct capability_gr
extern int bgp_open_option_parse (struct peer *, u_char, int *); extern int bgp_open_option_parse (struct peer *, u_char, int *);
extern void bgp_open_capability (struct stream *, struct peer *); 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 as_t peek_for_as4_capability (struct peer *, u_char);
extern int bgp_afi_safi_valid_indices (afi_t, safi_t *); extern int bgp_afi_safi_valid_indices (afi_t, safi_t *);

File diff suppressed because it is too large Load diff

View file

@ -21,7 +21,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGP_ROUTE_H #ifndef _QUAGGA_BGP_ROUTE_H
#define _QUAGGA_BGP_ROUTE_H #define _QUAGGA_BGP_ROUTE_H
#include "lib/json.h"
#include "queue.h" #include "queue.h"
#include "bgp_table.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 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 (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_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); extern void route_vty_out_tmp (struct vty *, struct prefix *, struct attr *, safi_t, u_char, json_object *);
extern int extern int
subgroup_process_announce_selected (struct update_subgroup *subgrp, subgroup_process_announce_selected (struct update_subgroup *subgrp,

View file

@ -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) if ((flags & UPDWALK_FLAGS_ADVQUEUE) && adj->adv && adj->adv->baa)
{ {
route_vty_out_tmp (vty, &rn->p, adj->adv->baa->attr, route_vty_out_tmp (vty, &rn->p, adj->adv->baa->attr, SUBGRP_SAFI (subgrp), 0, NULL);
SUBGRP_SAFI (subgrp));
output_count++; output_count++;
} }
if ((flags & UPDWALK_FLAGS_ADVERTISED) && adj->attr) 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++; output_count++;
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -30,6 +30,7 @@ Boston, MA 02111-1307, USA. */
#include "routemap.h" #include "routemap.h"
#include "thread.h" #include "thread.h"
#include "queue.h" #include "queue.h"
#include "lib/json.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h" #include "bgpd/bgp_route.h"

View file

@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include <zebra.h> #include <zebra.h>
#include "lib/json.h"
#include "prefix.h" #include "prefix.h"
#include "thread.h" #include "thread.h"
#include "buffer.h" #include "buffer.h"
@ -5853,7 +5854,7 @@ peer_clear_soft (struct peer *peer, afi_t afi, safi_t safi,
/* Display peer uptime.*/ /* Display peer uptime.*/
/* XXX: why does this function return char * when it takes buffer? */ /* XXX: why does this function return char * when it takes buffer? */
char * 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; time_t uptime1;
struct tm *tm; struct tm *tm;
@ -5861,16 +5862,22 @@ peer_uptime (time_t uptime2, char *buf, size_t len)
/* Check buffer length. */ /* Check buffer length. */
if (len < BGP_UPTIME_LEN) if (len < BGP_UPTIME_LEN)
{ {
zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len); if (!use_json)
/* XXX: should return status instead of buf... */ {
snprintf (buf, len, "<error> "); zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
/* XXX: should return status instead of buf... */
snprintf (buf, len, "<error> ");
}
return buf; return buf;
} }
/* If there is no connection has been done before print `never'. */ /* If there is no connection has been done before print `never'. */
if (uptime2 == 0) if (uptime2 == 0)
{ {
snprintf (buf, len, "never"); if (use_json)
json_object_string_add(json, "peerUptime", "never");
else
snprintf (buf, len, "never");
return buf; 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_DAY_SECOND 60*60*24
#define ONE_WEEK_SECOND 60*60*24*7 #define ONE_WEEK_SECOND 60*60*24*7
if (uptime1 < ONE_DAY_SECOND) if (use_json)
snprintf (buf, len, "%02d:%02d:%02d", {
tm->tm_hour, tm->tm_min, tm->tm_sec); int time_store;
else if (uptime1 < ONE_WEEK_SECOND) int day_msec = 86400000;
snprintf (buf, len, "%dd%02dh%02dm", int hour_msec = 3600000;
tm->tm_yday, tm->tm_hour, tm->tm_min); 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 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; return buf;
} }

View file

@ -21,6 +21,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#ifndef _QUAGGA_BGPD_H #ifndef _QUAGGA_BGPD_H
#define _QUAGGA_BGPD_H #define _QUAGGA_BGPD_H
#include "lib/json.h"
/* For union sockunion. */ /* For union sockunion. */
#include "queue.h" #include "queue.h"
#include "sockunion.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); as_t, as_t, int, afi_t, safi_t);
extern struct peer *peer_create_accept (struct bgp *); extern struct peer *peer_create_accept (struct bgp *);
extern void peer_xfer_config (struct peer *dst, struct peer *src); 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 int bgp_config_write (struct vty *);
extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *); extern void bgp_config_write_family_header (struct vty *, afi_t, safi_t, int *);

View file

@ -20,6 +20,7 @@
*/ */
#include <zebra.h> #include <zebra.h>
#include "lib/json.h"
#include "prefix.h" #include "prefix.h"
#include "command.h" #include "command.h"
@ -2559,10 +2560,13 @@ prefix_bgp_orf_remove_all (char *name)
/* return prefix count */ /* return prefix count */
int 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 *plist;
struct prefix_list_entry *pentry; 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); plist = prefix_list_lookup (AFI_ORF_PREFIX, name);
if (! plist) if (! plist)
@ -2571,26 +2575,65 @@ prefix_bgp_show_prefix_list (struct vty *vty, afi_t afi, char *name)
if (! vty) if (! vty)
return plist->count; return plist->count;
vty_out (vty, "ip%s prefix-list %s: %d entries%s", if(use_json)
afi == AFI_IP ? "" : "v6",
plist->name, plist->count, VTY_NEWLINE);
for (pentry = plist->head; pentry; pentry = pentry->next)
{ {
struct prefix *p = &pentry->prefix; json = json_object_new_object();
char buf[BUFSIZ]; json_prefix = json_object_new_object();
json_list = json_object_new_object();
vty_out (vty, " seq %d %s %s/%d", pentry->seq, json_object_int_add(json_prefix, "prefixListCounter", plist->count);
prefix_list_type_str (pentry), json_object_string_add(json_prefix, "prefixListName", plist->name);
inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
p->prefixlen);
if (pentry->ge) for (pentry = plist->head; pentry; pentry = pentry->next)
vty_out (vty, " ge %d", pentry->ge); {
if (pentry->le) struct prefix *p = &pentry->prefix;
vty_out (vty, " le %d", pentry->le); char buf_a[BUFSIZ];
char buf_b[BUFSIZ];
vty_out (vty, "%s", VTY_NEWLINE); 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%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; return plist->count;
} }

View file

@ -78,6 +78,6 @@ extern struct stream * prefix_bgp_orf_entry (struct stream *,
u_char, u_char, u_char); u_char, u_char, u_char);
extern int prefix_bgp_orf_set (char *, afi_t, struct orf_prefix *, int, int); extern int prefix_bgp_orf_set (char *, afi_t, struct orf_prefix *, int, int);
extern void prefix_bgp_orf_remove_all (char *); 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 */ #endif /* _QUAGGA_PLIST_H */