forked from Mirror/frr
zebra: Add "show evpn mac vni all detail" command
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
This commit is contained in:
parent
98d8359fe7
commit
cffe7580fd
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue