mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 21:47:15 +02:00
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:
parent
308d14aed9
commit
856ca177c4
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 ((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;
|
||||
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;
|
||||
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);
|
||||
/* 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 (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);
|
||||
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);
|
||||
}
|
||||
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 (use_json)
|
||||
json_array = json_object_new_array();
|
||||
else
|
||||
json_array = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
for (ri = rm->info; ri; ri = ri->next)
|
||||
{
|
||||
if (type == bgp_show_type_neighbor)
|
||||
{
|
||||
union sockunion *su = output_arg;
|
||||
|
||||
if (rd_header)
|
||||
{
|
||||
u_int16_t type;
|
||||
struct rd_as rd_as;
|
||||
struct rd_ip rd_ip;
|
||||
u_char *pnt;
|
||||
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;
|
||||
}
|
||||
|
||||
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. */
|
||||
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);
|
||||
pnt = rn->p.u.val;
|
||||
|
||||
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)
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
122
bgpd/bgp_open.c
122
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
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
2198
bgpd/bgp_route.c
2198
bgpd/bgp_route.c
File diff suppressed because it is too large
Load diff
|
@ -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,
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
2161
bgpd/bgp_vty.c
2161
bgpd/bgp_vty.c
File diff suppressed because it is too large
Load diff
|
@ -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"
|
||||
|
|
66
bgpd/bgpd.c
66
bgpd/bgpd.c
|
@ -20,6 +20,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
#include <zebra.h>
|
||||
|
||||
#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, "<error> ");
|
||||
if (!use_json)
|
||||
{
|
||||
zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len);
|
||||
/* XXX: should return status instead of buf... */
|
||||
snprintf (buf, len, "<error> ");
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
77
lib/plist.c
77
lib/plist.c
|
@ -20,6 +20,7 @@
|
|||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
#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];
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue