]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: Add "show evpn arp-cache vni all detail" command 3373/head
authorNitin Soni <nsoni@cumulusnetworks.com>
Thu, 22 Nov 2018 09:56:52 +0000 (01:56 -0800)
committerNitin Soni <nsoni@cumulusnetworks.com>
Tue, 27 Nov 2018 13:56:56 +0000 (05:56 -0800)
Change helps display detailed output for all possible VNI neighbors
without specifying VNI and ip. It helps in troubleshooting as a single
command can be fired to capture detailed info on all VNIs.

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

index 536fdabcbc1dd894973be6ee14d63d5b28808254..ad6bfe5751dff0c2948a979383a6fb257e90125d 100644 (file)
@@ -2181,6 +2181,23 @@ DEFUN (show_evpn_neigh_vni_all,
        return CMD_SUCCESS;
 }
 
+DEFUN (show_evpn_neigh_vni_all_detail, show_evpn_neigh_vni_all_detail_cmd,
+       "show evpn arp-cache vni all detail [json]",
+       SHOW_STR
+       "EVPN\n"
+       "ARP and ND cache\n"
+       "VxLAN Network Identifier\n"
+       "All VNIs\n"
+       "Neighbor details for all vnis in detail\n" JSON_STR)
+{
+       struct zebra_vrf *zvrf;
+       bool uj = use_json(argc, argv);
+
+       zvrf = vrf_info_lookup(VRF_DEFAULT);
+       zebra_vxlan_print_neigh_all_vni_detail(vty, zvrf, false, 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 [json]",
@@ -2892,6 +2909,7 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_evpn_mac_vni_all_dad_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_all_cmd);
+       install_element(VIEW_NODE, &show_evpn_neigh_vni_all_detail_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_neigh_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd);
        install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd);
index 86f6961118a04670f7da1c02fd87b365fc61b59a..a4c09b6f415464c83c9f0823e4367b865a268bb4 100644 (file)
@@ -871,6 +871,33 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
                json_object_object_add(json_vni, buf2, json_row);
 }
 
+/*
+ * Print neighbor hash entry in detail - called for display of all neighbors.
+ */
+static void zvni_print_neigh_hash_detail(struct hash_backet *backet, void *ctxt)
+{
+       struct vty *vty;
+       json_object *json_vni = NULL, *json_row = NULL;
+       zebra_neigh_t *n;
+       char buf[INET6_ADDRSTRLEN];
+       struct neigh_walk_ctx *wctx = ctxt;
+
+       vty = wctx->vty;
+       json_vni = wctx->json;
+       n = (zebra_neigh_t *)backet->data;
+       if (!n)
+               return;
+
+       ipaddr2str(&n->ip, buf, sizeof(buf));
+       if (json_vni)
+               json_row = json_object_new_object();
+
+       zvni_print_neigh(n, vty, json_row);
+
+       if (json_vni)
+               json_object_object_add(json_vni, buf, json_row);
+}
+
 /*
  * Print neighbors for all VNI.
  */
@@ -950,6 +977,80 @@ static void zvni_print_dad_neigh_hash(struct hash_backet *backet, void *ctxt)
                zvni_print_neigh_hash(backet, ctxt);
 }
 
+static void zvni_print_dad_neigh_hash_detail(struct hash_backet *backet,
+                                            void *ctxt)
+{
+       zebra_neigh_t *nbr;
+
+       nbr = (zebra_neigh_t *)backet->data;
+       if (!nbr)
+               return;
+
+       if (CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE))
+               zvni_print_neigh_hash_detail(backet, ctxt);
+}
+
+/*
+ * Print neighbors for all VNIs in detail.
+ */
+static void zvni_print_neigh_hash_all_vni_detail(struct hash_backet *backet,
+                                                void **args)
+{
+       struct vty *vty;
+       json_object *json = NULL, *json_vni = NULL;
+       zebra_vni_t *zvni;
+       uint32_t num_neigh;
+       struct neigh_walk_ctx wctx;
+       char vni_str[VNI_STR_LEN];
+       uint32_t print_dup;
+
+       vty = (struct vty *)args[0];
+       json = (json_object *)args[1];
+       print_dup = (uint32_t)(uintptr_t)args[2];
+
+       zvni = (zebra_vni_t *)backet->data;
+       if (!zvni) {
+               if (json)
+                       vty_out(vty, "{}\n");
+               return;
+       }
+       num_neigh = hashcount(zvni->neigh_table);
+
+       if (print_dup && num_dup_detected_neighs(zvni) == 0)
+               return;
+
+       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;
+       }
+
+       memset(&wctx, 0, sizeof(struct neigh_walk_ctx));
+       wctx.zvni = zvni;
+       wctx.vty = vty;
+       wctx.addr_width = 15;
+       wctx.json = json_vni;
+
+       if (print_dup)
+               hash_iterate(zvni->neigh_table,
+                            zvni_print_dad_neigh_hash_detail, &wctx);
+       else
+               hash_iterate(zvni->neigh_table, zvni_print_neigh_hash_detail,
+                            &wctx);
+
+       if (json)
+               json_object_object_add(json, vni_str, json_vni);
+}
+
 /* print a specific next hop for an l3vni */
 static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
                            json_object *json)
@@ -5666,6 +5767,37 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
        }
 }
 
+/*
+ * Display neighbors across all VNIs in detail(VTY command handler).
+ */
+void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
+                                           struct zebra_vrf *zvrf,
+                                           bool print_dup, bool use_json)
+{
+       json_object *json = NULL;
+       void *args[3];
+
+       if (!is_evpn_enabled())
+               return;
+
+       if (use_json)
+               json = json_object_new_object();
+
+       args[0] = vty;
+       args[1] = json;
+       args[2] = (void *)(ptrdiff_t)print_dup;
+
+       hash_iterate(zvrf->vni_table,
+                    (void (*)(struct hash_backet *,
+                              void *))zvni_print_neigh_hash_all_vni_detail,
+                    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 specific neighbor for a VNI, if present (VTY command handler).
  */
index bf6e4290dc946e7e95c8a90b0991ad760438ea68..de120ae0ebc45b4dd3d646b19b9bf687efe752f4 100644 (file)
@@ -111,6 +111,10 @@ extern void zebra_vxlan_print_neigh_all_vni(struct vty *vty,
                                            struct zebra_vrf *zvrf,
                                            bool print_dup,
                                            bool use_json);
+extern void zebra_vxlan_print_neigh_all_vni_detail(struct vty *vty,
+                                                  struct zebra_vrf *zvrf,
+                                                  bool print_dup,
+                                                  bool use_json);
 extern void zebra_vxlan_print_specific_neigh_vni(struct vty *vty,
                                                 struct zebra_vrf *zvrf,
                                                 vni_t vni, struct ipaddr *ip,