]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: JSON support for show ip bgp vrf all update-group
authorAshwini Reddy <ashred@nvidia.com>
Mon, 7 Nov 2022 19:53:48 +0000 (11:53 -0800)
committerChirag Shah <chirag@nvidia.com>
Thu, 24 Nov 2022 03:04:00 +0000 (19:04 -0800)
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>
bgpd/bgp_updgrp.c
bgpd/bgp_updgrp.h
bgpd/bgp_vty.c
doc/user/zebra.rst

index 9d550fd19b826e555d3eaed8dcfcd1637e923ae1..6b5269efe2b98bf0135792fcd3647f52960a2f97 100644 (file)
@@ -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);
+       }
 }
 
 /*
index ecd92a996eb5c8b743bdc3cfea03aa9318362275..16628158f97807d3caadba07e002dd30d8bbe421 100644 (file)
@@ -304,6 +304,8 @@ struct updwalk_context {
        updgrp_walkcb cb;
        void *context;
        uint8_t flags;
+       bool uj;
+       json_object *json_updategrps;
 
 #define UPDWALK_FLAGS_ADVQUEUE   (1 << 0)
 #define UPDWALK_FLAGS_ADVERTISED (1 << 1)
@@ -365,7 +367,7 @@ extern void update_bgp_group_init(struct bgp *);
 extern void udpate_bgp_group_free(struct bgp *);
 
 extern void update_group_show(struct bgp *bgp, afi_t afi, safi_t safi,
-                             struct vty *vty, uint64_t subgrp_id);
+                             struct vty *vty, uint64_t subgrp_id, bool uj);
 extern void update_group_show_stats(struct bgp *bgp, struct vty *vty);
 extern void update_group_adjust_peer(struct peer_af *paf);
 extern int update_group_adjust_soloness(struct peer *peer, int set);
index 53fdce3a35173ebf2dfd514ec6eafb1808e78187..4b17d289684c2ad146e770bda0f814f35b9b5403 100644 (file)
@@ -15531,28 +15531,30 @@ DEFUN (show_ip_bgp_route_leak,
 }
 
 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);
@@ -15562,13 +15564,13 @@ static int bgp_show_update_groups(struct vty *vty, const char *name, int afi,
        }
 
        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
@@ -15576,7 +15578,8 @@ DEFUN (show_ip_bgp_updgrps,
        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;
@@ -15585,6 +15588,8 @@ DEFUN (show_ip_bgp_updgrps,
 
        int idx = 0;
 
+       bool uj = use_json(argc, argv);
+
        /* show [ip] bgp */
        if (argv_find(argv, argc, "ip", &idx))
                afi = AFI_IP;
@@ -15606,19 +15611,22 @@ DEFUN (show_ip_bgp_updgrps,
        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;
 }
 
@@ -15635,7 +15643,7 @@ DEFUN (show_bgp_l2vpn_evpn_updgrps,
        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;
 }
 
index db43266d68bef9d861d7082d998720eca5dfb208..c44642a788af3509a1db2a6f3ce45982715d6a21 100644 (file)
@@ -296,7 +296,7 @@ the default route.
    Allow IPv6 nexthop tracking to resolve via the default route. This parameter
    is configured per-VRF, so the command is also available in the VRF subnode.
 
-.. clicmd:: show ip nht [vrf NAME] [A.B.C.D|X:X::X:X] [mrib]
+.. clicmd:: show ip nht [vrf NAME] [A.B.C.D|X:X::X:X] [mrib] [json]
 
    Show nexthop tracking status for address resolution.  If vrf is not specified
    then display the default vrf.  If ``all`` is specified show all vrf address
@@ -305,6 +305,7 @@ the default route.
    indicates that the operator wants to see the multicast rib address resolution
    table.  An alternative form of the command is ``show ip import-check`` and this
    form of the command is deprecated at this point in time.
+   If the ``json`` option is specified, output is displayed in JSON format.
 
 PBR dataplane programming
 =========================