summaryrefslogtreecommitdiff
path: root/bgpd/bgp_updgrp.c
diff options
context:
space:
mode:
authorAshwini Reddy <ashred@nvidia.com>2022-11-07 11:53:48 -0800
committerChirag Shah <chirag@nvidia.com>2022-11-23 19:04:00 -0800
commitfa5a9276d1e0e69e4ab690d12dc38aed14f2d6bd (patch)
treec9ab64b552a67ee052c5d6ad46ace5154978364b /bgpd/bgp_updgrp.c
parenta86afb3e0e12a8f29b49e71e9aa9f23ea7de6d51 (diff)
bgpd: JSON support for show ip bgp vrf all update-group
Ticket:#3229030 Testing Done: UT Changes: - JSON support for the update group command. Testing: torc-11# show ip bgp vrf all ipv6 update-groups json torc-12# show bgp vrf all update-groups json { "default":{ "2":{ "groupCreateTime":{ "epoch":1669225617, "epochString":"Wed Nov 23 17:46:57 2022\n" }, "afi":"IPv6", "safi":"unicast", "outRouteMap":"MY_ORIGIN_ASPATH_ONLY", "minRouteAdvInt":0, "subGroup":[ { "subGroupId":2, "groupCreateTime":{ "epoch":1669225617, "epochString":"Wed Nov 23 17:46:57 2022\n" }, "statistics":{ "joinEvents":2, "pruneEvents":0, "mergeEvents":0, "splitEvents":0, "switchEvents":0, "peerRefreshEvents":0, "mergeCheckEvents":2 }, "coalesceTime":1100, "version":12, "packetQueueInfo":{ "qeueueLen":0, "queuedTotal":1, "queueHwmLen":1, "totalEnqueued":1 }, "adjListCount":1, "needsRefresh":false, "peers":[ "uplink_1", "uplink_2" ] } ] } } } { "sym_3":{ } } { "sym_5":{ } } { "sym_2":{ } } { "sym_4":{ } } { "sym_1":{ } } Co-authored-by: Chirag Shah <chirag@nvidia.com> Signed-off-by: Ashwini Reddy <ashred@nvidia.com>
Diffstat (limited to 'bgpd/bgp_updgrp.c')
-rw-r--r--bgpd/bgp_updgrp.c304
1 files changed, 243 insertions, 61 deletions
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 9d550fd19b..6b5269efe2 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -677,6 +677,15 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
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;
@@ -703,79 +712,232 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
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;
}
@@ -1708,14 +1870,34 @@ void update_bgp_group_free(struct bgp *bgp)
}
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);
+ }
}
/*