]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: Enable JSON for EVPN show cmds
authorChirag Shah <chirag@cumulusnetworks.com>
Wed, 21 Jun 2017 23:37:51 +0000 (16:37 -0700)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Tue, 8 Aug 2017 14:28:50 +0000 (10:28 -0400)
Ticket: CM-16959
Reviewed By: CCR-6401
Testing Done:
Execute 'show evpn .... json' form of outputs with local/remote vteps

Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zebra_vxlan_private.h

index 13c4429d6a60733538aa2b976e62bb2acdab45a2..61fe171cffce2d1a579cf532b69d3698dc552a60 100644 (file)
@@ -2300,89 +2300,100 @@ DEFUN (show_vrf,
 
 DEFUN (show_evpn_vni,
        show_evpn_vni_cmd,
-       "show evpn vni",
+       "show evpn vni [json]",
        SHOW_STR
        "EVPN\n"
-       "VxLAN information\n")
+       "VxLAN information\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
+       u_char uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_vnis(vty, zvrf);
+       zebra_vxlan_print_vnis(vty, zvrf, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_vni_vni,
        show_evpn_vni_vni_cmd,
-       "show evpn vni " CMD_VNI_RANGE,
+       "show evpn vni " CMD_VNI_RANGE "[json]",
        SHOW_STR
        "EVPN\n"
        "VxLAN Network Identifier\n"
-       "VNI number\n")
+       "VNI number\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[3]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_vni(vty, zvrf, vni);
+       zebra_vxlan_print_vni(vty, zvrf, vni, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_mac_vni,
        show_evpn_mac_vni_cmd,
-       "show evpn mac vni " CMD_VNI_RANGE,
+       "show evpn mac vni " CMD_VNI_RANGE "[json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
-       "VNI number\n")
+       "VNI number\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_macs_vni(vty, zvrf, vni);
+       zebra_vxlan_print_macs_vni(vty, zvrf, vni, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_mac_vni_all,
        show_evpn_mac_vni_all_cmd,
-       "show evpn mac vni all",
+       "show evpn mac vni all [json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
-       "All VNIs\n")
+       "All VNIs\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
+       u_char uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_macs_all_vni(vty, zvrf);
+       zebra_vxlan_print_macs_all_vni(vty, zvrf, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_mac_vni_all_vtep,
        show_evpn_mac_vni_all_vtep_cmd,
-       "show evpn mac vni all vtep A.B.C.D",
+       "show evpn mac vni all vtep A.B.C.D [json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
        "All VNIs\n"
        "Remote VTEP\n"
-       "Remote VTEP IP address\n")
+       "Remote VTEP IP address\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        struct in_addr vtep_ip;
+       u_char uj = use_json(argc, argv);
 
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
-               vty_out(vty, "%% Malformed VTEP IP address\n");
+               if (!uj)
+                       vty_out(vty, "%% Malformed VTEP IP address\n");
                return CMD_WARNING;
        }
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip);
+       zebra_vxlan_print_macs_all_vni_vtep(vty, zvrf, vtep_ip, uj);
 
        return CMD_SUCCESS;
 }
@@ -2415,112 +2426,125 @@ DEFUN (show_evpn_mac_vni_mac,
 
 DEFUN (show_evpn_mac_vni_vtep,
        show_evpn_mac_vni_vtep_cmd,
-       "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D",
+       "show evpn mac vni " CMD_VNI_RANGE " vtep A.B.C.D" "[json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
        "VNI number\n"
        "Remote VTEP\n"
-       "Remote VTEP IP address\n")
+       "Remote VTEP IP address\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
-               vty_out(vty, "%% Malformed VTEP IP address\n");
+               if (!uj)
+                       vty_out(vty, "%% Malformed VTEP IP address\n");
                return CMD_WARNING;
        }
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip);
+       zebra_vxlan_print_macs_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_neigh_vni,
        show_evpn_neigh_vni_cmd,
-       "show evpn arp-cache vni " CMD_VNI_RANGE,
+       "show evpn arp-cache vni " CMD_VNI_RANGE "[json]",
        SHOW_STR
        "EVPN\n"
        "ARP and ND cache\n"
        "VxLAN Network Identifier\n"
-       "VNI number\n")
+       "VNI number\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_neigh_vni(vty, zvrf, vni);
+       zebra_vxlan_print_neigh_vni(vty, zvrf, vni, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_neigh_vni_all,
        show_evpn_neigh_vni_all_cmd,
-       "show evpn arp-cache vni all",
+       "show evpn arp-cache vni all [json]",
        SHOW_STR
        "EVPN\n"
        "ARP and ND cache\n"
        "VxLAN Network Identifier\n"
-       "All VNIs\n")
+       "All VNIs\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
+       u_char uj = use_json(argc, argv);
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_neigh_all_vni(vty, zvrf);
+       zebra_vxlan_print_neigh_all_vni(vty, zvrf, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_neigh_vni_neigh,
        show_evpn_neigh_vni_neigh_cmd,
-       "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD",
+       "show evpn arp-cache vni " CMD_VNI_RANGE " ip WORD [json]",
        SHOW_STR
        "EVPN\n"
        "ARP and ND cache\n"
        "VxLAN Network Identifier\n"
        "VNI number\n"
        "Neighbor\n"
-       "Neighbor address (IPv4 or IPv6 address)\n")
+       "Neighbor address (IPv4 or IPv6 address)\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct ipaddr ip;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (str2ipaddr(argv[6]->arg, &ip) != 0) {
-               vty_out(vty, "%% Malformed Neighbor address\n");
+               if (!uj)
+                       vty_out(vty, "%% Malformed Neighbor address\n");
                return CMD_WARNING;
        }
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip);
+       zebra_vxlan_print_specific_neigh_vni(vty, zvrf, vni, &ip, uj);
        return CMD_SUCCESS;
 }
 
 DEFUN (show_evpn_neigh_vni_vtep,
        show_evpn_neigh_vni_vtep_cmd,
-       "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D",
+       "show evpn arp-cache vni " CMD_VNI_RANGE " vtep A.B.C.D [json]",
        SHOW_STR
        "EVPN\n"
        "ARP and ND cache\n"
        "VxLAN Network Identifier\n"
        "VNI number\n"
        "Remote VTEP\n"
-       "Remote VTEP IP address\n")
+       "Remote VTEP IP address\n"
+       "JavaScript Object Notation\n")
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct in_addr vtep_ip;
+       u_char uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!inet_aton(argv[6]->arg, &vtep_ip)) {
-               vty_out(vty, "%% Malformed VTEP IP address\n");
+               if (!uj)
+                       vty_out(vty, "%% Malformed VTEP IP address\n");
                return CMD_WARNING;
        }
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip);
+       zebra_vxlan_print_neigh_vni_vtep(vty, zvrf, vni, vtep_ip, uj);
        return CMD_SUCCESS;
 }
 
index dc8e6e9c0e62b9b8d3e8a00dfabbd517b249b7fd..cb555ff1ee2d706f83b073f93cffaebcd70ffaa3 100644 (file)
@@ -46,6 +46,7 @@
 #include "zebra/zebra_vxlan.h"
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_l2.h"
+#include "lib/json.h"
 
 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI, "VNI hash");
 DEFINE_MTYPE_STATIC(ZEBRA, ZVNI_VTEP, "VNI remote VTEP");
@@ -56,15 +57,15 @@ DEFINE_MTYPE_STATIC(ZEBRA, NEIGH, "VNI Neighbor");
 
 
 /* static function declarations */
-static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt);
+static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json);
 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt);
 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
-                                         void *ctxt);
+                                         void **args);
 static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
-static void zvni_print(zebra_vni_t *zvni, void *ctxt);
-static void zvni_print_hash(struct hash_backet *backet, void *ctxt);
+static void zvni_print(zebra_vni_t *zvni, void **ctxt);
+static void zvni_print_hash(struct hash_backet *backet, void *ctxt[]);
 
 static int zvni_macip_send_msg_to_client(struct zebra_vrf *zvrf, vni_t vni,
                                         struct ethaddr *macaddr,
@@ -180,18 +181,34 @@ static void zvni_find_neigh_addr_width(struct hash_backet *backet, void *ctxt)
 /*
  * Print a specific neighbor entry.
  */
-static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt)
+static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
 {
        struct vty *vty;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
 
-       ipaddr2str(&n->ip, buf2, sizeof(buf2)), vty = (struct vty *)ctxt;
-       vty_out(vty, "IP: %s\n", ipaddr2str(&n->ip, buf2, sizeof(buf2)));
-       vty_out(vty, " MAC: %s", prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
-       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE))
-               vty_out(vty, " Remote VTEP: %s", inet_ntoa(n->r_vtep_ip));
-       vty_out(vty, "\n");
+       ipaddr2str(&n->ip, buf2, sizeof(buf2));
+       prefix_mac2str(&n->emac, buf1, sizeof(buf1));
+       vty = (struct vty *)ctxt;
+       if (json == NULL) {
+               vty_out(vty, "IP: %s\n",
+                       ipaddr2str(&n->ip, buf2, sizeof(buf2)));
+               vty_out(vty, " MAC: %s",
+                       prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
+       } else {
+               json_object_string_add(json, "ip", buf2);
+               json_object_string_add(json, "mac", buf1);
+       }
+       if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_REMOTE)) {
+               if (json == NULL)
+                       vty_out(vty, " Remote VTEP: %s",
+                               inet_ntoa(n->r_vtep_ip));
+               else
+                       json_object_string_add(json, "remoteVtep",
+                                              inet_ntoa(n->r_vtep_ip));
+       }
+       if (json == NULL)
+               vty_out(vty, "\n");
 }
 
 /*
@@ -200,65 +217,115 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt)
 static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
 {
        struct vty *vty;
+       json_object *json_vni = NULL, *json_row = NULL;
        zebra_neigh_t *n;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
        struct neigh_walk_ctx *wctx = ctxt;
 
        vty = wctx->vty;
+       json_vni = wctx->json;
        n = (zebra_neigh_t *)backet->data;
        if (!n)
                return;
 
+       if (json_vni)
+               json_row = json_object_new_object();
+
        prefix_mac2str(&n->emac, buf1, sizeof(buf1));
        ipaddr2str(&n->ip, buf2, sizeof(buf2));
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL)
            && !(wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)) {
-               vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width, buf2,
-                       "local", buf1);
+               if (json_vni == NULL) {
+                       vty_out(vty, "%*s %-6s %-17s\n", -wctx->addr_width,
+                               buf2, "local", buf1);
+               } else {
+                       json_object_string_add(json_row, "type", "local");
+                       json_object_string_add(json_row, "mac", buf1);
+               }
                wctx->count++;
        } else {
                if (wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP) {
                        if (IPV4_ADDR_SAME(&n->r_vtep_ip, &wctx->r_vtep_ip)) {
-                               if (wctx->count == 0)
+                               if (json_vni == NULL) {
+                                       if (wctx->count == 0)
+                                               vty_out(vty,
+                                                       "%*s %-6s %-17s %-21s\n",
+                                                       -wctx->addr_width,
+                                                       "Neighbor", "Type",
+                                                       "MAC", "Remote VTEP");
                                        vty_out(vty, "%*s %-6s %-17s %-21s\n",
-                                               -wctx->addr_width, "Neighbor",
-                                               "Type", "MAC", "Remote VTEP");
+                                               -wctx->addr_width, buf2,
+                                               "remote", buf1,
+                                               inet_ntoa(n->r_vtep_ip));
+                               } else {
+                                       json_object_string_add(json_row, "type",
+                                                              "remote");
+                                       json_object_string_add(json_row, "mac",
+                                                              buf1);
+                                       json_object_string_add(
+                                               json_row, "remoteVtep",
+                                               inet_ntoa(n->r_vtep_ip));
+                               }
+                               wctx->count++;
+                       }
+               } else {
+                       if (json_vni == NULL) {
                                vty_out(vty, "%*s %-6s %-17s %-21s\n",
                                        -wctx->addr_width, buf2, "remote", buf1,
                                        inet_ntoa(n->r_vtep_ip));
-                               wctx->count++;
+                       } else {
+                               json_object_string_add(json_row, "type",
+                                                      "remote");
+                               json_object_string_add(json_row, "mac", buf1);
+                               json_object_string_add(json_row, "remoteVtep",
+                                                      inet_ntoa(n->r_vtep_ip));
                        }
-               } else {
-                       vty_out(vty, "%*s %-6s %-17s %-21s\n",
-                               -wctx->addr_width, buf2, "remote", buf1,
-                               inet_ntoa(n->r_vtep_ip));
                        wctx->count++;
                }
        }
+
+       if (json_vni)
+               json_object_object_add(json_vni, buf2, json_row);
 }
 
 /*
  * Print neighbors for all VNI.
  */
 static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
-                                         void *ctxt)
+                                         void **args)
 {
        struct vty *vty;
+       json_object *json = NULL, *json_vni = NULL;
        zebra_vni_t *zvni;
        u_int32_t num_neigh;
        struct neigh_walk_ctx wctx;
+       char vni_str[VNI_STR_LEN];
+
+       vty = (struct vty *)args[0];
+       json = (json_object *)args[1];
 
-       vty = (struct vty *)ctxt;
        zvni = (zebra_vni_t *)backet->data;
-       if (!zvni)
+       if (!zvni) {
+               if (json)
+                       vty_out(vty, "{}\n");
                return;
-
+       }
        num_neigh = hashcount(zvni->neigh_table);
-       vty_out(vty, "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
-               zvni->vni, num_neigh);
-       if (!num_neigh)
+       if (json == NULL)
+               vty_out(vty,
+                       "\nVNI %u #ARP (IPv4 and IPv6, local and remote) %u\n\n",
+                       zvni->vni, num_neigh);
+       else {
+               json_vni = json_object_new_object();
+               json_object_int_add(json_vni, "numArpNd", num_neigh);
+               snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
+       }
+       if (!num_neigh) {
+               if (json)
+                       json_object_object_add(json, vni_str, json_vni);
                return;
+       }
 
        /* Since we have IPv6 addresses to deal with which can vary widely in
         * size, we try to be a bit more elegant in display by first computing
@@ -268,11 +335,16 @@ static void zvni_print_neigh_hash_all_vni(struct hash_backet *backet,
        wctx.zvni = zvni;
        wctx.vty = vty;
        wctx.addr_width = 15;
+       wctx.json = json_vni;
        hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
 
-       vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", "Type",
-               "MAC", "Remote VTEP");
+       if (json == NULL)
+               vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
+                       "Type", "MAC", "Remote VTEP");
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
+
+       if (json)
+               json_object_object_add(json, vni_str, json_vni);
 }
 
 /*
@@ -313,16 +385,22 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
 static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
 {
        struct vty *vty;
+       json_object *json_mac_hdr = NULL, *json_mac = NULL;
        zebra_mac_t *mac;
        char buf1[20];
        struct mac_walk_ctx *wctx = ctxt;
 
        vty = wctx->vty;
+       json_mac_hdr = wctx->json;
        mac = (zebra_mac_t *)backet->data;
        if (!mac)
                return;
 
        prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
+
+       if (json_mac_hdr)
+               json_mac = json_object_new_object();
+
        if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)
            && !(wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP)) {
                struct zebra_ns *zns;
@@ -336,29 +414,70 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
                if (!ifp) // unexpected
                        return;
                vid = mac->fwd_info.local.vid;
-               vty_out(vty, "%-17s %-6s %-21s", buf1, "local", ifp->name);
-               if (vid)
-                       vty_out(vty, " %-5u", vid);
-               vty_out(vty, "\n");
+               if (json_mac_hdr == NULL)
+                       vty_out(vty, "%-17s %-6s %-21s", buf1, "local",
+                               ifp->name);
+               else {
+                       json_object_string_add(json_mac, "type", "local");
+                       json_object_string_add(json_mac, "intf", ifp->name);
+               }
+               if (vid) {
+                       if (json_mac_hdr == NULL)
+                               vty_out(vty, " %-5u", vid);
+                       else
+                               json_object_int_add(json_mac, "vlan", vid);
+               }
+               if (json_mac_hdr == NULL)
+                       vty_out(vty, "\n");
+               else
+                       json_object_object_add(json_mac_hdr, buf1, json_mac);
                wctx->count++;
        } else {
                if (wctx->flags & SHOW_REMOTE_MAC_FROM_VTEP) {
                        if (IPV4_ADDR_SAME(&mac->fwd_info.r_vtep_ip,
                                           &wctx->r_vtep_ip)) {
                                if (wctx->count == 0) {
-                                       vty_out(vty, "\nVNI %u",
-                                               wctx->zvni->vni);
-                                       vty_out(vty, "%-17s %-6s %-21s %-5s",
-                                               "MAC", "Type",
-                                               "Intf/Remote VTEP", "VLAN");
+                                       if (json_mac_hdr == NULL) {
+                                               vty_out(vty, "\nVNI %u\n\n",
+                                                       wctx->zvni->vni);
+                                               vty_out(vty,
+                                                       "%-17s %-6s %-21s %-5s\n",
+                                                       "MAC", "Type",
+                                                       "Intf/Remote VTEP",
+                                                       "VLAN");
+                                       }
+                               }
+                               if (json_mac_hdr == NULL)
+                                       vty_out(vty, "%-17s %-6s %-21s\n", buf1,
+                                               "remote",
+                                               inet_ntoa(mac->fwd_info
+                                                                 .r_vtep_ip));
+                               else {
+                                       json_object_string_add(json_mac, "type",
+                                                              "remote");
+                                       json_object_string_add(
+                                               json_mac, "remoteVtep",
+                                               inet_ntoa(mac->fwd_info
+                                                                 .r_vtep_ip));
+                                       json_object_object_add(json_mac_hdr,
+                                                              buf1, json_mac);
                                }
-                               vty_out(vty, "%-17s %-6s %-21s", buf1, "remote",
-                                       inet_ntoa(mac->fwd_info.r_vtep_ip));
                                wctx->count++;
                        }
                } else {
-                       vty_out(vty, "%-17s %-6s %-21s", buf1, "remote",
-                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+                       if (json_mac_hdr == NULL)
+                               vty_out(vty, "%-17s %-6s %-21s\n", buf1,
+                                       "remote",
+                                       inet_ntoa(mac->fwd_info.r_vtep_ip));
+                       else {
+                               json_object_string_add(json_mac, "type",
+                                                      "remote");
+                               json_object_string_add(
+                                       json_mac, "remoteVtep",
+                                       inet_ntoa(mac->fwd_info.r_vtep_ip));
+                               json_object_object_add(json_mac_hdr, buf1,
+                                                      json_mac);
+                       }
                        wctx->count++;
                }
        }
@@ -370,15 +489,22 @@ static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt)
 static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
 {
        struct vty *vty;
+       json_object *json = NULL, *json_vni = NULL;
+       json_object *json_mac = NULL;
        zebra_vni_t *zvni;
        u_int32_t num_macs;
        struct mac_walk_ctx *wctx = ctxt;
+       char vni_str[VNI_STR_LEN];
 
        vty = (struct vty *)wctx->vty;
+       json = (struct json_object *)wctx->json;
 
        zvni = (zebra_vni_t *)backet->data;
-       if (!zvni)
+       if (!zvni) {
+               if (json)
+                       vty_out(vty, "{}\n");
                return;
+       }
        wctx->zvni = zvni;
 
        /*We are iterating over a new VNI, set the count to 0*/
@@ -387,59 +513,115 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
        num_macs = hashcount(zvni->mac_table);
        if (!num_macs)
                return;
-       if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
-               vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
-                       zvni->vni, num_macs);
-               vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
-                       "Intf/Remote VTEP", "VLAN");
+
+       if (json) {
+               json_vni = json_object_new_object();
+               json_mac = json_object_new_object();
+               snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
        }
 
+       if (!CHECK_FLAG(wctx->flags, SHOW_REMOTE_MAC_FROM_VTEP)) {
+               if (json == NULL) {
+                       vty_out(vty, "\nVNI %u #MACs (local and remote) %u\n\n",
+                               zvni->vni, num_macs);
+                       vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
+                               "Intf/Remote VTEP", "VLAN");
+               } else
+                       json_object_int_add(json_vni, "numMacs", num_macs);
+       }
+       /* assign per-vni to wctx->json object to fill macs
+        * under the vni. Re-assign primary json object to fill
+        * next vni information.
+        */
+       wctx->json = json_mac;
        hash_iterate(zvni->mac_table, zvni_print_mac_hash, wctx);
+       wctx->json = json;
+       if (json) {
+               if (wctx->count)
+                       json_object_object_add(json_vni, "macs", json_mac);
+               json_object_object_add(json, vni_str, json_vni);
+       }
 }
 
 /*
  * Print a specific VNI entry.
  */
-static void zvni_print(zebra_vni_t *zvni, void *ctxt)
+static void zvni_print(zebra_vni_t *zvni, void **ctxt)
 {
        struct vty *vty;
        zebra_vtep_t *zvtep;
        u_int32_t num_macs;
        u_int32_t num_neigh;
+       json_object *json = NULL;
+       json_object *json_vtep_list = NULL;
+       json_object *json_ip_str = NULL;
 
-       vty = (struct vty *)ctxt;
+       vty = ctxt[0];
+       json = ctxt[1];
+
+       if (json == NULL)
+               vty_out(vty, "VNI: %u\n", zvni->vni);
+       else
+               json_object_int_add(json, "vni", zvni->vni);
 
-       vty_out(vty, "VNI: %u\n", zvni->vni);
        if (!zvni->vxlan_if) { // unexpected
-               vty_out(vty, " VxLAN interface: unknown\n");
+               if (json == NULL)
+                       vty_out(vty, " VxLAN interface: unknown\n");
                return;
        }
-       vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
-               zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
-               inet_ntoa(zvni->local_vtep_ip));
-
+       num_macs = hashcount(zvni->mac_table);
+       num_neigh = hashcount(zvni->neigh_table);
+       if (json == NULL)
+               vty_out(vty, " VxLAN interface: %s ifIndex: %u VTEP IP: %s\n",
+                       zvni->vxlan_if->name, zvni->vxlan_if->ifindex,
+                       inet_ntoa(zvni->local_vtep_ip));
+       else {
+               json_object_string_add(json, "vxlanInterface",
+                                      zvni->vxlan_if->name);
+               json_object_int_add(json, "ifindex", zvni->vxlan_if->ifindex);
+               json_object_string_add(json, "vtepIp",
+                                      inet_ntoa(zvni->local_vtep_ip));
+               json_object_int_add(json, "numMacs", num_macs);
+               json_object_int_add(json, "numArpNd", num_neigh);
+       }
        if (!zvni->vteps) {
-               vty_out(vty, " No remote VTEPs known for this VNI\n");
+               if (json == NULL)
+                       vty_out(vty, " No remote VTEPs known for this VNI\n");
        } else {
-               vty_out(vty, " Remote VTEPs for this VNI:\n");
-               for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next)
-                       vty_out(vty, "  %s\n", inet_ntoa(zvtep->vtep_ip));
+               if (json == NULL)
+                       vty_out(vty, " Remote VTEPs for this VNI:\n");
+               else
+                       json_vtep_list = json_object_new_array();
+               for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
+                       if (json == NULL)
+                               vty_out(vty, "  %s\n",
+                                       inet_ntoa(zvtep->vtep_ip));
+                       else {
+                               json_ip_str = json_object_new_string(
+                                       inet_ntoa(zvtep->vtep_ip));
+                               json_object_array_add(json_vtep_list,
+                                                     json_ip_str);
+                       }
+               }
+               if (json)
+                       json_object_object_add(json, "numRemoteVteps",
+                                              json_vtep_list);
+       }
+       if (json == NULL) {
+               vty_out(vty,
+                       " Number of MACs (local and remote) known for this VNI: %u\n",
+                       num_macs);
+               vty_out(vty,
+                       " Number of ARPs (IPv4 and IPv6, local and remote) "
+                       "known for this VNI: %u\n",
+                       num_neigh);
        }
-       num_macs = hashcount(zvni->mac_table);
-       vty_out(vty,
-               " Number of MACs (local and remote) known for this VNI: %u\n",
-               num_macs);
-       num_neigh = hashcount(zvni->neigh_table);
-       vty_out(vty,
-               " Number of ARPs (IPv4 and IPv6, local and remote) "
-               "known for this VNI: %u",
-               num_neigh);
 }
 
 /*
  * Print a VNI hash entry - called for display of all VNIs.
  */
-static void zvni_print_hash(struct hash_backet *backet, void *ctxt)
+static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
 {
        struct vty *vty;
        zebra_vni_t *zvni;
@@ -447,8 +629,14 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt)
        u_int32_t num_vteps = 0;
        u_int32_t num_macs = 0;
        u_int32_t num_neigh = 0;
+       json_object *json = NULL;
+       json_object *json_vni = NULL;
+       json_object *json_ip_str = NULL;
+       json_object *json_vtep_list = NULL;
+
+       vty = ctxt[0];
+       json = ctxt[1];
 
-       vty = (struct vty *)ctxt;
        zvni = (zebra_vni_t *)backet->data;
        if (!zvni)
                return;
@@ -461,9 +649,36 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt)
 
        num_macs = hashcount(zvni->mac_table);
        num_neigh = hashcount(zvni->neigh_table);
-       vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni,
-               zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
-               inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh, num_vteps);
+       if (json == NULL)
+               vty_out(vty, "%-10u %-21s %-15s %-8u %-8u %-15u\n", zvni->vni,
+                       zvni->vxlan_if ? zvni->vxlan_if->name : "unknown",
+                       inet_ntoa(zvni->local_vtep_ip), num_macs, num_neigh,
+                       num_vteps);
+       else {
+               char vni_str[VNI_STR_LEN];
+               snprintf(vni_str, VNI_STR_LEN, "%u", zvni->vni);
+               json_vni = json_object_new_object();
+               json_object_string_add(json_vni, "vxlanIf",
+                                      zvni->vxlan_if ? zvni->vxlan_if->name
+                                                     : "unknown");
+               json_object_string_add(json_vni, "vtepIp",
+                                      inet_ntoa(zvni->local_vtep_ip));
+               json_object_int_add(json_vni, "numMacs", num_macs);
+               json_object_int_add(json_vni, "numArpNd", num_neigh);
+               json_object_int_add(json_vni, "numRemoteVteps", num_vteps);
+               if (num_vteps) {
+                       json_vtep_list = json_object_new_array();
+                       for (zvtep = zvni->vteps; zvtep; zvtep = zvtep->next) {
+                               json_ip_str = json_object_new_string(
+                                       inet_ntoa(zvtep->vtep_ip));
+                               json_object_array_add(json_vtep_list,
+                                                     json_ip_str);
+                       }
+                       json_object_object_add(json_vni, "remoteVteps",
+                                              json_vtep_list);
+               }
+               json_object_object_add(json, vni_str, json_vni);
+       }
 }
 
 /*
@@ -1943,23 +2158,30 @@ static void zvni_cleanup_all(struct hash_backet *backet, void *zvrf)
  * Display Neighbors for a VNI (VTY command handler).
  */
 void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                vni_t vni)
+                                vni_t vni, u_char use_json)
 {
        zebra_vni_t *zvni;
        u_int32_t num_neigh;
        struct neigh_walk_ctx wctx;
+       json_object *json = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        num_neigh = hashcount(zvni->neigh_table);
        if (!num_neigh)
                return;
 
+       if (use_json)
+               json = json_object_new_object();
+
        /* Since we have IPv6 addresses to deal with which can vary widely in
         * size, we try to be a bit more elegant in display by first computing
         * the maximum width.
@@ -1968,25 +2190,52 @@ void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
        wctx.zvni = zvni;
        wctx.vty = vty;
        wctx.addr_width = 15;
+       wctx.json = json;
        hash_iterate(zvni->neigh_table, zvni_find_neigh_addr_width, &wctx);
 
-       vty_out(vty,
-               "Number of ARPs (local and remote) known for this VNI: %u\n",
-               num_neigh);
-       vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP", "Type",
-               "MAC", "Remote VTEP");
+       if (!use_json) {
+               vty_out(vty,
+                       "Number of ARPs (local and remote) known for this VNI: %u\n",
+                       num_neigh);
+               vty_out(vty, "%*s %-6s %-17s %-21s\n", -wctx.addr_width, "IP",
+                       "Type", "MAC", "Remote VTEP");
+       } else
+               json_object_int_add(json, "numArpNd", num_neigh);
 
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
  * Display neighbors across all VNIs (VTY command handler).
  */
-void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
+void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
+                                    u_char use_json)
 {
+       json_object *json = NULL;
+       void *args[2];
+
        if (!EVPN_ENABLED(zvrf))
                return;
-       hash_iterate(zvrf->vni_table, zvni_print_neigh_hash_all_vni, vty);
+
+       if (use_json)
+               json = json_object_new_object();
+
+       args[0] = vty;
+       args[1] = json;
+       hash_iterate(zvrf->vni_table,
+                    (void (*)(struct hash_backet *,
+                              void *))zvni_print_neigh_hash_all_vni,
+                    args);
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
@@ -1994,26 +2243,40 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
  */
 void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
                                          struct zebra_vrf *zvrf, vni_t vni,
-                                         struct ipaddr *ip)
+                                         struct ipaddr *ip, u_char use_json)
 {
        zebra_vni_t *zvni;
        zebra_neigh_t *n;
+       json_object *json = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        n = zvni_neigh_lookup(zvni, ip);
        if (!n) {
-               vty_out(vty, "%% Requested neighbor does not exist in VNI %u\n",
-                       vni);
+               if (!use_json)
+                       vty_out(vty,
+                               "%% Requested neighbor does not exist in VNI %u\n",
+                               vni);
                return;
        }
+       if (use_json)
+               json = json_object_new_object();
+
+       zvni_print_neigh(n, vty, json);
 
-       zvni_print_neigh(n, vty);
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
@@ -2021,17 +2284,22 @@ void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
  * By definition, these are remote neighbors.
  */
 void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
-                                     vni_t vni, struct in_addr vtep_ip)
+                                     vni_t vni, struct in_addr vtep_ip,
+                                     u_char use_json)
 {
        zebra_vni_t *zvni;
        u_int32_t num_neigh;
        struct neigh_walk_ctx wctx;
+       json_object *json = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        num_neigh = hashcount(zvni->neigh_table);
@@ -2043,56 +2311,98 @@ void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
        wctx.vty = vty;
        wctx.flags = SHOW_REMOTE_NEIGH_FROM_VTEP;
        wctx.r_vtep_ip = vtep_ip;
-
+       wctx.json = json;
        hash_iterate(zvni->neigh_table, zvni_print_neigh_hash, &wctx);
+
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
  * Display MACs for a VNI (VTY command handler).
  */
 void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                               vni_t vni)
+                               vni_t vni, u_char use_json)
 {
        zebra_vni_t *zvni;
        u_int32_t num_macs;
        struct mac_walk_ctx wctx;
+       json_object *json = NULL;
+       json_object *json_mac = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        num_macs = hashcount(zvni->mac_table);
        if (!num_macs)
                return;
 
+       if (use_json) {
+               json = json_object_new_object();
+               json_mac = json_object_new_object();
+       }
+
        memset(&wctx, 0, sizeof(struct mac_walk_ctx));
        wctx.zvni = zvni;
        wctx.vty = vty;
+       wctx.json = json_mac;
 
-       vty_out(vty,
-               "Number of MACs (local and remote) known for this VNI: %u\n",
-               num_macs);
-       vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
-               "Intf/Remote VTEP", "VLAN");
+       if (!use_json) {
+               vty_out(vty,
+                       "Number of MACs (local and remote) known for this VNI: %u\n",
+                       num_macs);
+               vty_out(vty, "%-17s %-6s %-21s %-5s\n", "MAC", "Type",
+                       "Intf/Remote VTEP", "VLAN");
+       } else
+               json_object_int_add(json, "numMacs", num_macs);
 
        hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
+
+       if (use_json) {
+               json_object_object_add(json, "macs", json_mac);
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
  * Display MACs for all VNIs (VTY command handler).
  */
-void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
+void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
+                                   u_char use_json)
 {
        struct mac_walk_ctx wctx;
+       json_object *json = NULL;
 
-       if (!EVPN_ENABLED(zvrf))
+       if (!EVPN_ENABLED(zvrf)) {
+               if (use_json)
+                       vty_out(vty, "{}\n");
                return;
+       }
+       if (use_json)
+               json = json_object_new_object();
+
        memset(&wctx, 0, sizeof(struct mac_walk_ctx));
        wctx.vty = vty;
+       wctx.json = json;
        hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
+
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
@@ -2100,17 +2410,30 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf)
  */
 void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                         struct zebra_vrf *zvrf,
-                                        struct in_addr vtep_ip)
+                                        struct in_addr vtep_ip,
+                                        u_char use_json)
 {
        struct mac_walk_ctx wctx;
+       json_object *json = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
+
+       if (use_json)
+               json = json_object_new_object();
+
        memset(&wctx, 0, sizeof(struct mac_walk_ctx));
        wctx.vty = vty;
        wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
        wctx.r_vtep_ip = vtep_ip;
+       wctx.json = json;
        hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni, &wctx);
+
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
@@ -2143,64 +2466,124 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
  * Display MACs for a VNI from specific VTEP (VTY command handler).
  */
 void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
-                                    vni_t vni, struct in_addr vtep_ip)
+                                    vni_t vni, struct in_addr vtep_ip,
+                                    u_char use_json)
 {
        zebra_vni_t *zvni;
        u_int32_t num_macs;
        struct mac_walk_ctx wctx;
+       json_object *json = NULL;
+       json_object *json_mac = NULL;
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        num_macs = hashcount(zvni->mac_table);
        if (!num_macs)
                return;
+
+       if (use_json) {
+               json = json_object_new_object();
+               json_mac = json_object_new_object();
+       }
+
        memset(&wctx, 0, sizeof(struct mac_walk_ctx));
        wctx.zvni = zvni;
        wctx.vty = vty;
        wctx.flags = SHOW_REMOTE_MAC_FROM_VTEP;
        wctx.r_vtep_ip = vtep_ip;
+       wctx.json = json_mac;
        hash_iterate(zvni->mac_table, zvni_print_mac_hash, &wctx);
+
+       if (use_json) {
+               json_object_int_add(json, "numMacs", wctx.count);
+               if (wctx.count)
+                       json_object_object_add(json, "macs", json_mac);
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 
 /*
  * Display VNI information (VTY command handler).
  */
-void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni)
+void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
+                          u_char use_json)
 {
        zebra_vni_t *zvni;
+       json_object *json = NULL;
+       void *args[2];
 
        if (!EVPN_ENABLED(zvrf))
                return;
        zvni = zvni_lookup(zvrf, vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
-       zvni_print(zvni, (void *)vty);
+       if (use_json)
+               json = json_object_new_object();
+       args[0] = vty;
+       args[1] = json;
+       zvni_print(zvni, (void *)args);
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
  * Display VNI hash table (VTY command handler).
  */
-void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf)
+void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
+                           u_char use_json)
 {
        u_int32_t num_vnis;
+       json_object *json = NULL;
+       void *args[2];
 
        if (!EVPN_ENABLED(zvrf))
                return;
        num_vnis = hashcount(zvrf->vni_table);
-       if (!num_vnis)
+       if (!num_vnis) {
+               if (use_json)
+                       vty_out(vty, "{}\n");
                return;
-       vty_out(vty, "Number of VNIs: %u\n", num_vnis);
-       vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI", "VxLAN IF",
-               "VTEP IP", "# MACs", "# ARPs", "# Remote VTEPs");
-       hash_iterate(zvrf->vni_table, zvni_print_hash, vty);
+       }
+       if (use_json) {
+               json = json_object_new_object();
+               json_object_int_add(json, "numVnis", num_vnis);
+       } else {
+               vty_out(vty, "Number of VNIs: %u\n", num_vnis);
+               vty_out(vty, "%-10s %-21s %-15s %-8s %-8s %-15s\n", "VNI",
+                       "VxLAN IF", "VTEP IP", "# MACs", "# ARPs",
+                       "# Remote VTEPs");
+       }
+       args[0] = vty;
+       args[1] = json;
+
+       hash_iterate(zvrf->vni_table,
+                    (void (*)(struct hash_backet *, void *))zvni_print_hash,
+                    args);
+
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /*
index dca8006033e30701002bc91447f5b722eef032c6..f7c1afc9595e898159acf1b85b206a1b7061b0c5 100644 (file)
 #define ZEBRA_VXLIF_MASTER_CHANGE       0x2
 #define ZEBRA_VXLIF_VLAN_CHANGE         0x4
 
+#define VNI_STR_LEN 32
+
 extern void zebra_vxlan_print_macs_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                      vni_t vni);
+                                      vni_t vni, u_char use_json);
 extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
-                                          struct zebra_vrf *zvrf);
+                                          struct zebra_vrf *zvrf,
+                                          u_char use_json);
 extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                                struct zebra_vrf *zvrf,
-                                               struct in_addr vtep_ip);
+                                               struct in_addr vtep_ip,
+                                               u_char use_json);
 extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty,
                                               struct zebra_vrf *zvrf,
                                               vni_t vni, struct ethaddr *mac);
 extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
                                            struct zebra_vrf *zvrf, vni_t vni,
-                                           struct in_addr vtep_ip);
+                                           struct in_addr vtep_ip,
+                                           u_char use_json);
 extern void zebra_vxlan_print_neigh_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                       vni_t vni);
+                                       vni_t vni, u_char use_json);
 extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty,
-                                           struct zebra_vrf *zvrf);
+                                           struct zebra_vrf *zvrf,
+                                           u_char use_json);
 extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
                                                 struct zebra_vrf *zvrf,
-                                                vni_t vni, struct ipaddr *ip);
+                                                vni_t vni, struct ipaddr *ip,
+                                                u_char use_json);
 extern void zebra_vxlan_print_neigh_vni_vtep(struct vty *vty,
                                             struct zebra_vrf *zvrf, vni_t vni,
-                                            struct in_addr vtep_ip);
+                                            struct in_addr vtep_ip,
+                                            u_char use_json);
 extern void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                 vni_t vni);
-extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf);
+                                 vni_t vni, u_char use_json);
+extern void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf,
+                                  u_char use_json);
 
 extern int zebra_vxlan_add_del_gw_macip(struct interface *ifp, struct prefix *p,
                                        int add);
index 2e5943a75c00cf862d5c97bc0921ba9b65b009a8..2bf00291e7538acda91f56028e35df1c1ba5991c 100644 (file)
@@ -135,8 +135,9 @@ struct mac_walk_ctx {
 
        struct in_addr r_vtep_ip; /* To walk MACs from specific VTEP */
 
-       struct vty *vty; /* Used by VTY handlers */
-       u_int32_t count; /* Used by VTY handlers */
+       struct vty *vty;          /* Used by VTY handlers */
+       u_int32_t count;          /* Used by VTY handlers */
+       struct json_object *json; /* Used for JSON Output */
 };
 
 /*
@@ -186,9 +187,10 @@ struct neigh_walk_ctx {
 
        struct in_addr r_vtep_ip; /* To walk neighbors from specific VTEP */
 
-       struct vty *vty;   /* Used by VTY handlers */
-       u_int32_t count;   /* Used by VTY handlers */
-       u_char addr_width; /* Used by VTY handlers */
+       struct vty *vty;          /* Used by VTY handlers */
+       u_int32_t count;          /* Used by VTY handlers */
+       u_char addr_width;      /* Used by VTY handlers */
+       struct json_object *json; /* Used for JSON Output */
 };
 
 #endif /* _ZEBRA_VXLAN_PRIVATE_H */