From e3fac9195d98fbbc8de1c83e47e701b0fa750132 Mon Sep 17 00:00:00 2001 From: Nitin Soni Date: Thu, 22 Nov 2018 01:56:52 -0800 Subject: [PATCH] zebra: Add "show evpn arp-cache vni all detail" command 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 Reviewed-by: CCR-8034 --- zebra/zebra_vty.c | 18 ++++++ zebra/zebra_vxlan.c | 132 ++++++++++++++++++++++++++++++++++++++++++++ zebra/zebra_vxlan.h | 4 ++ 3 files changed, 154 insertions(+) diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 536fdabcbc..ad6bfe5751 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 86f6961118..a4c09b6f41 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -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). */ diff --git a/zebra/zebra_vxlan.h b/zebra/zebra_vxlan.h index bf6e4290dc..de120ae0eb 100644 --- a/zebra/zebra_vxlan.h +++ b/zebra/zebra_vxlan.h @@ -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, -- 2.39.5