]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Add "show evpn mac vni all detail" command 3372/head
authorNitin Soni <nsoni@cumulusnetworks.com>
Thu, 22 Nov 2018 08:18:10 +0000 (00:18 -0800)
committerNitin Soni <nsoni@cumulusnetworks.com>
Tue, 27 Nov 2018 13:44:48 +0000 (05:44 -0800)
Change helps display detailed output for all possible VNI MACs without
specifying VNI or mac. It helps in troubleshooting - a single
command can be fired to capture detailed info on all VNIs.
Also fixed and existing json related bug where json object is created by
a parent function and freed in child function.

Ticket: CM-22832
Signed-off-by: Nitin Soni <nsoni@cumulusnetworks.com>
Reviewed-by: CCR-8028
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h

index 536fdabcbc1dd894973be6ee14d63d5b28808254..9c910e9f1189c03023aab5893eeaa2df095ae76a 100644 (file)
@@ -1974,6 +1974,24 @@ DEFUN (show_evpn_mac_vni_all,
        return CMD_SUCCESS;
 }
 
+DEFUN (show_evpn_mac_vni_all_detail, show_evpn_mac_vni_all_detail_cmd,
+       "show evpn mac vni all detail [json]",
+       SHOW_STR
+       "EVPN\n"
+       "MAC addresses\n"
+       "VxLAN Network Identifier\n"
+       "All VNIs\n"
+       "Detailed Information On Each VNI MAC\n"
+       JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       bool uj = use_json(argc, argv);
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_macs_all_vni_detail(vty, zvrf, false, 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 [json]",
@@ -2885,6 +2903,7 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_evpn_nh_vni_all_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_all_cmd);
+       install_element(VIEW_NODE, &show_evpn_mac_vni_all_detail_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_all_vtep_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_mac_cmd);
        install_element(VIEW_NODE, &show_evpn_mac_vni_vtep_cmd);
index 86f6961118a04670f7da1c02fd87b365fc61b59a..07f2606fc8d9ceba06e25b6308b749ddf688b422 100644 (file)
@@ -1126,10 +1126,6 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
                }
 
                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);
 
@@ -1326,6 +1322,43 @@ static void zvni_print_dad_mac_hash(struct hash_backet *backet, void *ctxt)
                zvni_print_mac_hash(backet, ctxt);
 }
 
+/*
+ * Print MAC hash entry in detail - called for display of all MACs.
+ */
+static void zvni_print_mac_hash_detail(struct hash_backet *backet, void *ctxt)
+{
+       struct vty *vty;
+       json_object *json_mac_hdr = NULL;
+       zebra_mac_t *mac;
+       struct mac_walk_ctx *wctx = ctxt;
+       char buf1[20];
+
+       vty = wctx->vty;
+       json_mac_hdr = wctx->json;
+       mac = (zebra_mac_t *)backet->data;
+       if (!mac)
+               return;
+
+       wctx->count++;
+       prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
+
+       zvni_print_mac(mac, vty, json_mac_hdr);
+}
+
+/* Print Duplicate MAC in detail */
+static void zvni_print_dad_mac_hash_detail(struct hash_backet *backet,
+                                          void *ctxt)
+{
+       zebra_mac_t *mac;
+
+       mac = (zebra_mac_t *)backet->data;
+       if (!mac)
+               return;
+
+       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE))
+               zvni_print_mac_hash_detail(backet, ctxt);
+}
+
 /*
  * Print MACs for all VNI.
  */
@@ -1396,6 +1429,72 @@ static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt)
        }
 }
 
+/*
+ * Print MACs in detail for all VNI.
+ */
+static void zvni_print_mac_hash_all_vni_detail(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;
+       uint32_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 (json)
+                       vty_out(vty, "{}\n");
+               return;
+       }
+       wctx->zvni = zvni;
+
+       /*We are iterating over a new VNI, set the count to 0*/
+       wctx->count = 0;
+
+       num_macs = num_valid_macs(zvni);
+       if (!num_macs)
+               return;
+
+       if (wctx->print_dup && (num_dup_detected_macs(zvni) == 0))
+               return;
+
+       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);
+               } 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;
+       if (wctx->print_dup)
+               hash_iterate(zvni->mac_table, zvni_print_dad_mac_hash_detail,
+                            wctx);
+       else
+               hash_iterate(zvni->mac_table, zvni_print_mac_hash_detail, 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);
+       }
+}
+
 static void zl3vni_print_nh_hash(struct hash_backet *backet, void *ctx)
 {
        struct nh_walk_ctx *wctx = NULL;
@@ -5900,6 +5999,38 @@ void zebra_vxlan_print_macs_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
        }
 }
 
+/*
+ * Display MACs in detail for all VNIs (VTY command handler).
+ */
+void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
+                                          struct zebra_vrf *zvrf,
+                                          bool print_dup, bool use_json)
+{
+       struct mac_walk_ctx wctx;
+       json_object *json = NULL;
+
+       if (!is_evpn_enabled()) {
+               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;
+       wctx.print_dup = print_dup;
+       hash_iterate(zvrf->vni_table, zvni_print_mac_hash_all_vni_detail,
+                    &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 all VNIs (VTY command handler).
  */
@@ -5967,6 +6098,11 @@ void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
                json = json_object_new_object();
 
        zvni_print_mac(mac, vty, json);
+       if (use_json) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /* Print Duplicate MACs per VNI */
index bf6e4290dc946e7e95c8a90b0991ad760438ea68..5c4b721341d63d8bd32c1fe8ca2cf80d916deae6 100644 (file)
@@ -90,6 +90,10 @@ extern void zebra_vxlan_print_macs_all_vni(struct vty *vty,
                                           struct zebra_vrf *zvrf,
                                           bool print_dup,
                                           bool use_json);
+extern void zebra_vxlan_print_macs_all_vni_detail(struct vty *vty,
+                                                 struct zebra_vrf *zvrf,
+                                                 bool print_dup,
+                                                 bool use_json);
 extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
                                                struct zebra_vrf *zvrf,
                                                struct in_addr vtep_ip,