]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: add json support to show evpn mac vni <num> mac <mac>
authorDon Slice <dslice@cumulusnetworks.com>
Fri, 26 Oct 2018 20:57:23 +0000 (20:57 +0000)
committerDon Slice <dslice@cumulusnetworks.com>
Mon, 29 Oct 2018 13:09:31 +0000 (13:09 +0000)
Added the json output capability in order to improve troubleshooting
capabilities.

Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h

index cf704f24be3777f08c75db43ed9be9d5075c866c..3873009cfbc1d7a1ac362445d2a6115f2c99ae44 100644 (file)
@@ -2006,18 +2006,21 @@ DEFUN (show_evpn_mac_vni_all_vtep,
 
 DEFUN (show_evpn_mac_vni_mac,
        show_evpn_mac_vni_mac_cmd,
-       "show evpn mac vni " CMD_VNI_RANGE " mac WORD",
+       "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
        SHOW_STR
        "EVPN\n"
        "MAC addresses\n"
        "VxLAN Network Identifier\n"
        "VNI number\n"
        "MAC\n"
-       "MAC address (e.g., 00:e0:ec:20:12:62)\n")
+       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
+       JSON_STR)
+
 {
        struct zebra_vrf *zvrf;
        vni_t vni;
        struct ethaddr mac;
+       bool uj = use_json(argc, argv);
 
        vni = strtoul(argv[4]->arg, NULL, 10);
        if (!prefix_str2mac(argv[6]->arg, &mac)) {
@@ -2025,7 +2028,7 @@ DEFUN (show_evpn_mac_vni_mac,
                return CMD_WARNING;
        }
        zvrf = vrf_info_lookup(VRF_DEFAULT);
-       zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac);
+       zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
        return CMD_SUCCESS;
 }
 
index 974b4d5befb3323265b6dfd95f1f63d7c06eca2c..e694d36994ed27e7d52a8c55d07f2848aadb13bf 100644 (file)
@@ -71,7 +71,7 @@ static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
                            json_object *json);
 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
                              json_object *json);
-static void zvni_print_mac(zebra_mac_t *mac, void *ctxt);
+static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
 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);
@@ -569,7 +569,7 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
 /*
  * Print a specific MAC entry.
  */
-static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
+static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
 {
        struct vty *vty;
        zebra_neigh_t *n = NULL;
@@ -578,56 +578,142 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
        char buf2[INET6_ADDRSTRLEN];
 
        vty = (struct vty *)ctxt;
-       vty_out(vty, "MAC: %s",
-               prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
-               struct zebra_ns *zns;
-               struct interface *ifp;
-               ifindex_t ifindex;
+       prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
 
-               ifindex = mac->fwd_info.local.ifindex;
-               zns = zebra_ns_lookup(NS_DEFAULT);
-               ifp = if_lookup_by_index_per_ns(zns, ifindex);
-               if (!ifp) // unexpected
-                       return;
-               vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
-               if (mac->fwd_info.local.vid)
-                       vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
-       } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
-               vty_out(vty, " Remote VTEP: %s",
-                       inet_ntoa(mac->fwd_info.r_vtep_ip));
-       } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
-               vty_out(vty, " Auto Mac ");
-       }
+       if (json) {
+               json_object *json_mac = json_object_new_object();
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
+                       struct zebra_ns *zns;
+                       struct interface *ifp;
+                       ifindex_t ifindex;
+
+                       ifindex = mac->fwd_info.local.ifindex;
+                       zns = zebra_ns_lookup(NS_DEFAULT);
+                       ifp = if_lookup_by_index_per_ns(zns, ifindex);
+                       if (!ifp)
+                               return;
+                       json_object_string_add(json_mac, "type", "local");
+                       json_object_string_add(json_mac, "intf", ifp->name);
+                       json_object_int_add(json_mac, "ifindex", ifindex);
+                       if (mac->fwd_info.local.vid)
+                               json_object_int_add(json_mac, "vlan",
+                                                   mac->fwd_info.local.vid);
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                       json_object_string_add(json_mac, "type", "remote");
+                       json_object_string_add(
+                               json_mac, "remoteVtep",
+                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
+                       json_object_string_add(json_mac, "type", "auto mac");
 
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
-               vty_out(vty, " Sticky Mac ");
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+                       json_object_boolean_true_add(json_mac, "stickyMac");
 
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
-               vty_out(vty, " Default-gateway Mac ");
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
+                       json_object_boolean_true_add(json_mac,
+                                                    "defaultGateway");
 
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
-               vty_out(vty, " Remote-gateway Mac ");
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+                       json_object_boolean_true_add(json_mac,
+                                                    "remoteGatewayMac");
 
-       vty_out(vty, "\n");
-       vty_out(vty, " Local Seq: %u Remote Seq: %u",
-               mac->loc_seq, mac->rem_seq);
-       vty_out(vty, "\n");
+               json_object_int_add(json_mac, "localSequence", mac->loc_seq);
+               json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
 
-       /* print all the associated neigh */
-       vty_out(vty, " Neighbors:\n");
-       if (!listcount(mac->neigh_list))
-               vty_out(vty, "    No Neighbors\n");
-       else {
-               for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
-                       vty_out(vty, "    %s %s\n",
-                               ipaddr2str(&n->ip, buf2, sizeof(buf2)),
-                               (IS_ZEBRA_NEIGH_ACTIVE(n)
-                                          ? "Active" : "Inactive"));
+               /* print all the associated neigh */
+               if (!listcount(mac->neigh_list))
+                       json_object_string_add(json_mac, "neighbors", "none");
+               else {
+                       json_object *json_active_nbrs = json_object_new_array();
+                       json_object *json_inactive_nbrs =
+                               json_object_new_array();
+                       json_object *json_nbrs = json_object_new_object();
+
+                       for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
+                               if (IS_ZEBRA_NEIGH_ACTIVE(n))
+                                       json_object_array_add(
+                                               json_active_nbrs,
+                                               json_object_new_string(
+                                                       ipaddr2str(
+                                                               &n->ip, buf2,
+                                                               sizeof(buf2))));
+                               else
+                                       json_object_array_add(
+                                               json_inactive_nbrs,
+                                               json_object_new_string(
+                                                       ipaddr2str(
+                                                               &n->ip, buf2,
+                                                               sizeof(buf2))));
+                       }
+
+                       json_object_object_add(json_nbrs, "active",
+                                              json_active_nbrs);
+                       json_object_object_add(json_nbrs, "inactive",
+                                              json_inactive_nbrs);
+                       json_object_object_add(json_mac, "neighbors",
+                                              json_nbrs);
                }
-       }
 
-       vty_out(vty, "\n");
+               json_object_object_add(json, buf1, json_mac);
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       } else {
+               vty_out(vty, "MAC: %s\n", buf1);
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
+                       struct zebra_ns *zns;
+                       struct interface *ifp;
+                       ifindex_t ifindex;
+
+                       ifindex = mac->fwd_info.local.ifindex;
+                       zns = zebra_ns_lookup(NS_DEFAULT);
+                       ifp = if_lookup_by_index_per_ns(zns, ifindex);
+                       if (!ifp)
+                               return;
+                       vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
+                       if (mac->fwd_info.local.vid)
+                               vty_out(vty, " VLAN: %u",
+                                       mac->fwd_info.local.vid);
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                       vty_out(vty, " Remote VTEP: %s",
+                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
+                       vty_out(vty, " Auto Mac ");
+               }
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+                       vty_out(vty, " Sticky Mac ");
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
+                       vty_out(vty, " Default-gateway Mac ");
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+                       vty_out(vty, " Remote-gateway Mac ");
+
+               vty_out(vty, "\n");
+               vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq,
+                       mac->rem_seq);
+               vty_out(vty, "\n");
+
+               /* print all the associated neigh */
+               vty_out(vty, " Neighbors:\n");
+               if (!listcount(mac->neigh_list))
+                       vty_out(vty, "    No Neighbors\n");
+               else {
+                       for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
+                               vty_out(vty, "    %s %s\n",
+                                       ipaddr2str(&n->ip, buf2, sizeof(buf2)),
+                                       (IS_ZEBRA_NEIGH_ACTIVE(n)
+                                                ? "Active"
+                                                : "Inactive"));
+                       }
+               }
+
+               vty_out(vty, "\n");
+       }
 }
 
 /*
@@ -5151,26 +5237,39 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
  * Display specific MAC for a VNI, if present (VTY command handler).
  */
 void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
-                                       vni_t vni, struct ethaddr *macaddr)
+                                       vni_t vni, struct ethaddr *macaddr,
+                                       bool use_json)
 {
        zebra_vni_t *zvni;
        zebra_mac_t *mac;
+       json_object *json = NULL;
 
        if (!is_evpn_enabled())
                return;
+
        zvni = zvni_lookup(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;
        }
        mac = zvni_mac_lookup(zvni, macaddr);
        if (!mac) {
-               vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
-                       vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty,
+                               "%% Requested MAC does not exist in VNI %u\n",
+                               vni);
                return;
        }
 
-       zvni_print_mac(mac, vty);
+       if (use_json)
+               json = json_object_new_object();
+
+       zvni_print_mac(mac, vty, json);
 }
 
 /*
index f03cd3d541ccf931a842018f0c7bcb5b0d0db40c..1c394e9effad895bcd6643a67ab7a5e3c6e91474 100644 (file)
@@ -94,7 +94,8 @@ extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                                bool use_json);
 extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty,
                                               struct zebra_vrf *zvrf,
-                                              vni_t vni, struct ethaddr *mac);
+                                              vni_t vni, struct ethaddr *mac,
+                                              bool use_json);
 extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
                                            struct zebra_vrf *zvrf, vni_t vni,
                                            struct in_addr vtep_ip,