Permalink
Browse files

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 <nsoni@cumulusnetworks.com>
Reviewed-by: CCR-8034
  • Loading branch information...
Nitin Soni
Nitin Soni committed Nov 22, 2018
1 parent 98d8359 commit e3fac9195d98fbbc8de1c83e47e701b0fa750132
Showing with 154 additions and 0 deletions.
  1. +18 −0 zebra/zebra_vty.c
  2. +132 −0 zebra/zebra_vxlan.c
  3. +4 −0 zebra/zebra_vxlan.h
@@ -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);
@@ -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).
*/
@@ -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,

0 comments on commit e3fac91

Please sign in to comment.