struct bgp_filter *filter;
struct peer *peer = UPDGRP_PEER(updgrp);
int match = 0;
+ json_object *json_updgrp = NULL;
+ json_object *json_subgrps = NULL;
+ json_object *json_subgrp = NULL;
+ json_object *json_time = NULL;
+ json_object *json_subgrp_time = NULL;
+ json_object *json_subgrp_event = NULL;
+ json_object *json_peers = NULL;
+ json_object *json_pkt_info = NULL;
+ time_t epoch_tbuf, tbuf;
if (!ctx)
return CMD_SUCCESS;
vty = ctx->vty;
- vty_out(vty, "Update-group %" PRIu64 ":\n", updgrp->id);
- vty_out(vty, " Created: %s", timestamp_string(updgrp->uptime));
+ if (ctx->uj) {
+ json_updgrp = json_object_new_object();
+ /* Display json o/p */
+ tbuf = monotime(NULL);
+ tbuf -= updgrp->uptime;
+ epoch_tbuf = time(NULL) - tbuf;
+ json_time = json_object_new_object();
+ json_object_int_add(json_time, "epoch", epoch_tbuf);
+ json_object_string_add(json_time, "epochString",
+ ctime(&epoch_tbuf));
+ json_object_object_add(json_updgrp, "groupCreateTime",
+ json_time);
+ json_object_string_add(json_updgrp, "afi",
+ afi2str(updgrp->afi));
+ json_object_string_add(json_updgrp, "safi",
+ safi2str(updgrp->safi));
+ } else {
+ vty_out(vty, "Update-group %" PRIu64 ":\n", updgrp->id);
+ vty_out(vty, " Created: %s", timestamp_string(updgrp->uptime));
+ }
+
filter = &updgrp->conf->filter[updgrp->afi][updgrp->safi];
- if (filter->map[RMAP_OUT].name)
- vty_out(vty, " Outgoing route map: %s\n",
- filter->map[RMAP_OUT].name);
- vty_out(vty, " MRAI value (seconds): %d\n", updgrp->conf->v_routeadv);
- if (updgrp->conf->change_local_as)
- vty_out(vty, " Local AS %u%s%s\n",
- updgrp->conf->change_local_as,
- CHECK_FLAG(updgrp->conf->flags,
- PEER_FLAG_LOCAL_AS_NO_PREPEND)
- ? " no-prepend"
- : "",
- CHECK_FLAG(updgrp->conf->flags,
- PEER_FLAG_LOCAL_AS_REPLACE_AS)
- ? " replace-as"
- : "");
+ if (filter->map[RMAP_OUT].name) {
+ if (ctx->uj)
+ json_object_string_add(json_updgrp, "outRouteMap",
+ filter->map[RMAP_OUT].name);
+ else
+ vty_out(vty, " Outgoing route map: %s\n",
+ filter->map[RMAP_OUT].name);
+ }
+ if (ctx->uj)
+ json_object_int_add(json_updgrp, "minRouteAdvInt",
+ updgrp->conf->v_routeadv);
+ else
+ vty_out(vty, " MRAI value (seconds): %d\n",
+ updgrp->conf->v_routeadv);
+
+ if (updgrp->conf->change_local_as) {
+ if (ctx->uj) {
+ json_object_int_add(json_updgrp, "localAs",
+ updgrp->conf->change_local_as);
+ json_object_boolean_add(
+ json_updgrp, "noPrepend",
+ CHECK_FLAG(updgrp->conf->flags,
+ PEER_FLAG_LOCAL_AS_NO_PREPEND));
+ json_object_boolean_add(
+ json_updgrp, "replaceLocalAs",
+ CHECK_FLAG(updgrp->conf->flags,
+ PEER_FLAG_LOCAL_AS_REPLACE_AS));
+ } else {
+ vty_out(vty, " Local AS %u%s%s\n",
+ updgrp->conf->change_local_as,
+ CHECK_FLAG(updgrp->conf->flags,
+ PEER_FLAG_LOCAL_AS_NO_PREPEND)
+ ? " no-prepend"
+ : "",
+ CHECK_FLAG(updgrp->conf->flags,
+ PEER_FLAG_LOCAL_AS_REPLACE_AS)
+ ? " replace-as"
+ : "");
+ }
+ }
+ json_subgrps = json_object_new_array();
UPDGRP_FOREACH_SUBGRP (updgrp, subgrp) {
if (ctx->subgrp_id && (ctx->subgrp_id != subgrp->id))
continue;
- vty_out(vty, "\n");
- vty_out(vty, " Update-subgroup %" PRIu64 ":\n", subgrp->id);
- vty_out(vty, " Created: %s",
- timestamp_string(subgrp->uptime));
+ if (ctx->uj) {
+ json_subgrp = json_object_new_object();
+ json_object_int_add(json_subgrp, "subGroupId",
+ subgrp->id);
+ tbuf = monotime(NULL);
+ tbuf -= subgrp->uptime;
+ epoch_tbuf = time(NULL) - tbuf;
+ json_subgrp_time = json_object_new_object();
+ json_object_int_add(json_subgrp_time, "epoch",
+ epoch_tbuf);
+ json_object_string_add(json_subgrp_time, "epochString",
+ ctime(&epoch_tbuf));
+ json_object_object_add(json_subgrp, "groupCreateTime",
+ json_subgrp_time);
+ } else {
+ vty_out(vty, "\n");
+ vty_out(vty, " Update-subgroup %" PRIu64 ":\n",
+ subgrp->id);
+ vty_out(vty, " Created: %s",
+ timestamp_string(subgrp->uptime));
+ }
if (subgrp->split_from.update_group_id
|| subgrp->split_from.subgroup_id) {
- vty_out(vty, " Split from group id: %" PRIu64 "\n",
- subgrp->split_from.update_group_id);
- vty_out(vty,
- " Split from subgroup id: %" PRIu64 "\n",
- subgrp->split_from.subgroup_id);
+ if (ctx->uj) {
+ json_object_int_add(
+ json_subgrp, "splitGroupId",
+ subgrp->split_from.update_group_id);
+ json_object_int_add(
+ json_subgrp, "splitSubGroupId",
+ subgrp->split_from.subgroup_id);
+ } else {
+ vty_out(vty,
+ " Split from group id: %" PRIu64
+ "\n",
+ subgrp->split_from.update_group_id);
+ vty_out(vty,
+ " Split from subgroup id: %" PRIu64
+ "\n",
+ subgrp->split_from.subgroup_id);
+ }
}
- vty_out(vty, " Join events: %u\n", subgrp->join_events);
- vty_out(vty, " Prune events: %u\n", subgrp->prune_events);
- vty_out(vty, " Merge events: %u\n", subgrp->merge_events);
- vty_out(vty, " Split events: %u\n", subgrp->split_events);
- vty_out(vty, " Update group switch events: %u\n",
- subgrp->updgrp_switch_events);
- vty_out(vty, " Peer refreshes combined: %u\n",
- subgrp->peer_refreshes_combined);
- vty_out(vty, " Merge checks triggered: %u\n",
- subgrp->merge_checks_triggered);
- vty_out(vty, " Coalesce Time: %u%s\n",
- (UPDGRP_INST(subgrp->update_group))->coalesce_time,
- subgrp->t_coalesce ? "(Running)" : "");
- vty_out(vty, " Version: %" PRIu64 "\n", subgrp->version);
- vty_out(vty, " Packet queue length: %d\n",
- bpacket_queue_length(SUBGRP_PKTQ(subgrp)));
- vty_out(vty, " Total packets enqueued: %u\n",
- subgroup_total_packets_enqueued(subgrp));
- vty_out(vty, " Packet queue high watermark: %d\n",
- bpacket_queue_hwm_length(SUBGRP_PKTQ(subgrp)));
- vty_out(vty, " Adj-out list count: %u\n", subgrp->adj_count);
- vty_out(vty, " Advertise list: %s\n",
- advertise_list_is_empty(subgrp) ? "empty"
- : "not empty");
- vty_out(vty, " Flags: %s\n",
- CHECK_FLAG(subgrp->flags, SUBGRP_FLAG_NEEDS_REFRESH)
- ? "R"
- : "");
- if (peer)
- vty_out(vty, " Max packet size: %d\n",
- peer->max_packet_size);
+ if (ctx->uj) {
+ json_subgrp_event = json_object_new_object();
+ json_object_int_add(json_subgrp_event, "joinEvents",
+ subgrp->join_events);
+ json_object_int_add(json_subgrp_event, "pruneEvents",
+ subgrp->prune_events);
+ json_object_int_add(json_subgrp_event, "mergeEvents",
+ subgrp->merge_events);
+ json_object_int_add(json_subgrp_event, "splitEvents",
+ subgrp->split_events);
+ json_object_int_add(json_subgrp_event, "switchEvents",
+ subgrp->updgrp_switch_events);
+ json_object_int_add(json_subgrp_event,
+ "peerRefreshEvents",
+ subgrp->peer_refreshes_combined);
+ json_object_int_add(json_subgrp_event,
+ "mergeCheckEvents",
+ subgrp->merge_checks_triggered);
+ json_object_object_add(json_subgrp, "statistics",
+ json_subgrp_event);
+ json_object_int_add(json_subgrp, "coalesceTime",
+ (UPDGRP_INST(subgrp->update_group))
+ ->coalesce_time);
+ json_object_int_add(json_subgrp, "version",
+ subgrp->version);
+ json_pkt_info = json_object_new_object();
+ json_object_int_add(
+ json_pkt_info, "qeueueLen",
+ bpacket_queue_length(SUBGRP_PKTQ(subgrp)));
+ json_object_int_add(
+ json_pkt_info, "queuedTotal",
+ subgroup_total_packets_enqueued(subgrp));
+ json_object_int_add(
+ json_pkt_info, "queueHwmLen",
+ bpacket_queue_hwm_length(SUBGRP_PKTQ(subgrp)));
+ json_object_int_add(
+ json_pkt_info, "totalEnqueued",
+ subgroup_total_packets_enqueued(subgrp));
+ json_object_object_add(json_subgrp, "packetQueueInfo",
+ json_pkt_info);
+ json_object_int_add(json_subgrp, "adjListCount",
+ subgrp->adj_count);
+ json_object_boolean_add(
+ json_subgrp, "needsRefresh",
+ CHECK_FLAG(subgrp->flags,
+ SUBGRP_FLAG_NEEDS_REFRESH));
+ } else {
+ vty_out(vty, " Join events: %u\n",
+ subgrp->join_events);
+ vty_out(vty, " Prune events: %u\n",
+ subgrp->prune_events);
+ vty_out(vty, " Merge events: %u\n",
+ subgrp->merge_events);
+ vty_out(vty, " Split events: %u\n",
+ subgrp->split_events);
+ vty_out(vty, " Update group switch events: %u\n",
+ subgrp->updgrp_switch_events);
+ vty_out(vty, " Peer refreshes combined: %u\n",
+ subgrp->peer_refreshes_combined);
+ vty_out(vty, " Merge checks triggered: %u\n",
+ subgrp->merge_checks_triggered);
+ vty_out(vty, " Coalesce Time: %u%s\n",
+ (UPDGRP_INST(subgrp->update_group))
+ ->coalesce_time,
+ subgrp->t_coalesce ? "(Running)" : "");
+ vty_out(vty, " Version: %" PRIu64 "\n",
+ subgrp->version);
+ vty_out(vty, " Packet queue length: %d\n",
+ bpacket_queue_length(SUBGRP_PKTQ(subgrp)));
+ vty_out(vty, " Total packets enqueued: %u\n",
+ subgroup_total_packets_enqueued(subgrp));
+ vty_out(vty, " Packet queue high watermark: %d\n",
+ bpacket_queue_hwm_length(SUBGRP_PKTQ(subgrp)));
+ vty_out(vty, " Adj-out list count: %u\n",
+ subgrp->adj_count);
+ vty_out(vty, " Advertise list: %s\n",
+ advertise_list_is_empty(subgrp) ? "empty"
+ : "not empty");
+ vty_out(vty, " Flags: %s\n",
+ CHECK_FLAG(subgrp->flags,
+ SUBGRP_FLAG_NEEDS_REFRESH)
+ ? "R"
+ : "");
+ if (peer)
+ vty_out(vty, " Max packet size: %d\n",
+ peer->max_packet_size);
+ }
if (subgrp->peer_count > 0) {
- vty_out(vty, " Peers:\n");
- SUBGRP_FOREACH_PEER (subgrp, paf)
- vty_out(vty, " - %s\n", paf->peer->host);
+ if (ctx->uj) {
+ json_peers = json_object_new_array();
+ SUBGRP_FOREACH_PEER (subgrp, paf) {
+ json_object *peer =
+ json_object_new_string(
+ paf->peer->host);
+ json_object_array_add(json_peers, peer);
+ }
+ json_object_object_add(json_subgrp, "peers",
+ json_peers);
+ } else {
+ vty_out(vty, " Peers:\n");
+ SUBGRP_FOREACH_PEER (subgrp, paf)
+ vty_out(vty, " - %s\n",
+ paf->peer->host);
+ }
}
+
+ if (ctx->uj)
+ json_object_array_add(json_subgrps, json_subgrp);
}
+
+ if (ctx->uj) {
+ json_object_object_add(json_updgrp, "subGroup", json_subgrps);
+ json_object_object_addf(ctx->json_updategrps, json_updgrp,
+ "%" PRIu64, updgrp->id);
+ }
+
return UPDWALK_CONTINUE;
}
}
void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi, struct vty *vty,
- uint64_t subgrp_id)
+ uint64_t subgrp_id, bool uj)
{
struct updwalk_context ctx;
+ json_object *json_vrf_obj = NULL;
+
memset(&ctx, 0, sizeof(ctx));
ctx.vty = vty;
ctx.subgrp_id = subgrp_id;
+ ctx.uj = uj;
+
+ if (uj) {
+ ctx.json_updategrps = json_object_new_object();
+ json_vrf_obj = json_object_new_object();
+ }
update_group_af_walk(bgp, afi, safi, update_group_show_walkcb, &ctx);
+
+ if (uj) {
+ const char *vname;
+
+ if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ vname = VRF_DEFAULT_NAME;
+ else
+ vname = bgp->name;
+ json_object_object_add(json_vrf_obj, vname,
+ ctx.json_updategrps);
+ vty_json(vty, json_vrf_obj);
+ }
}
/*
}
static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
- safi_t safi)
+ safi_t safi, bool uj)
{
struct listnode *node, *nnode;
struct bgp *bgp;
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
- vty_out(vty, "\nInstance %s:\n",
- (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? VRF_DEFAULT_NAME
- : bgp->name);
- update_group_show(bgp, afi, safi, vty, 0);
+ if (!uj)
+ vty_out(vty, "\nInstance %s:\n",
+ (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ ? VRF_DEFAULT_NAME
+ : bgp->name);
+
+ update_group_show(bgp, afi, safi, vty, 0, uj);
}
}
static int bgp_show_update_groups(struct vty *vty, const char *name, int afi,
- int safi, uint64_t subgrp_id)
+ int safi, uint64_t subgrp_id, bool uj)
{
struct bgp *bgp;
if (name) {
if (strmatch(name, "all")) {
- bgp_show_all_instances_updgrps_vty(vty, afi, safi);
+ bgp_show_all_instances_updgrps_vty(vty, afi, safi, uj);
return CMD_SUCCESS;
} else {
bgp = bgp_lookup_by_name(name);
}
if (bgp)
- update_group_show(bgp, afi, safi, vty, subgrp_id);
+ update_group_show(bgp, afi, safi, vty, subgrp_id, uj);
return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_updgrps,
show_ip_bgp_updgrps_cmd,
- "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] update-groups [SUBGROUP-ID]",
+ "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_WITH_LABEL_CMD_STR"]] update-groups [SUBGROUP-ID] [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_AFI_HELP_STR
BGP_SAFI_WITH_LABEL_HELP_STR
"Detailed info about dynamic update groups\n"
- "Specific subgroup to display detailed info for\n")
+ "Specific subgroup to display detailed info for\n"
+ JSON_STR)
{
char *vrf = NULL;
afi_t afi = AFI_IP6;
int idx = 0;
+ bool uj = use_json(argc, argv);
+
/* show [ip] bgp */
if (argv_find(argv, argc, "ip", &idx))
afi = AFI_IP;
if (argv[idx]->type == VARIABLE_TKN)
subgrp_id = strtoull(argv[idx]->arg, NULL, 10);
- return (bgp_show_update_groups(vty, vrf, afi, safi, subgrp_id));
+ return (bgp_show_update_groups(vty, vrf, afi, safi, subgrp_id, uj));
}
DEFUN (show_bgp_instance_all_ipv6_updgrps,
show_bgp_instance_all_ipv6_updgrps_cmd,
- "show [ip] bgp <view|vrf> all update-groups",
+ "show [ip] bgp <view|vrf> all update-groups [json]",
SHOW_STR
IP_STR
BGP_STR
BGP_INSTANCE_ALL_HELP_STR
- "Detailed info about dynamic update groups\n")
+ "Detailed info about dynamic update groups\n"
+ JSON_STR)
{
- bgp_show_all_instances_updgrps_vty(vty, AFI_IP6, SAFI_UNICAST);
+ bool uj = use_json(argc, argv);
+
+ bgp_show_all_instances_updgrps_vty(vty, AFI_IP6, SAFI_UNICAST, uj);
return CMD_SUCCESS;
}
char *vrf = NULL;
uint64_t subgrp_id = 0;
- bgp_show_update_groups(vty, vrf, AFI_L2VPN, SAFI_EVPN, subgrp_id);
+ bgp_show_update_groups(vty, vrf, AFI_L2VPN, SAFI_EVPN, subgrp_id, 0);
return CMD_SUCCESS;
}