zebra: add json support to show evpn mac vni <num> mac <mac>

Added the json output capability in order to improve troubleshooting
capabilities.

Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
This commit is contained in:
Don Slice 2018-10-26 20:57:23 +00:00
parent dd5c280ab3
commit 24cdbd0d8b
3 changed files with 156 additions and 53 deletions

View File

@ -2006,18 +2006,21 @@ DEFUN (show_evpn_mac_vni_all_vtep,
DEFUN (show_evpn_mac_vni_mac, DEFUN (show_evpn_mac_vni_mac,
show_evpn_mac_vni_mac_cmd, show_evpn_mac_vni_mac_cmd,
"show evpn mac vni " CMD_VNI_RANGE " mac WORD", "show evpn mac vni " CMD_VNI_RANGE " mac WORD [json]",
SHOW_STR SHOW_STR
"EVPN\n" "EVPN\n"
"MAC addresses\n" "MAC addresses\n"
"VxLAN Network Identifier\n" "VxLAN Network Identifier\n"
"VNI number\n" "VNI number\n"
"MAC\n" "MAC\n"
"MAC address (e.g., 00:e0:ec:20:12:62)\n") "MAC address (e.g., 00:e0:ec:20:12:62)\n"
JSON_STR)
{ {
struct zebra_vrf *zvrf; struct zebra_vrf *zvrf;
vni_t vni; vni_t vni;
struct ethaddr mac; struct ethaddr mac;
bool uj = use_json(argc, argv);
vni = strtoul(argv[4]->arg, NULL, 10); vni = strtoul(argv[4]->arg, NULL, 10);
if (!prefix_str2mac(argv[6]->arg, &mac)) { if (!prefix_str2mac(argv[6]->arg, &mac)) {
@ -2025,7 +2028,7 @@ DEFUN (show_evpn_mac_vni_mac,
return CMD_WARNING; return CMD_WARNING;
} }
zvrf = vrf_info_lookup(VRF_DEFAULT); zvrf = vrf_info_lookup(VRF_DEFAULT);
zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac); zebra_vxlan_print_specific_mac_vni(vty, zvrf, vni, &mac, uj);
return CMD_SUCCESS; return CMD_SUCCESS;
} }

View File

@ -71,7 +71,7 @@ static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
json_object *json); json_object *json);
static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty, static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
json_object *json); json_object *json);
static void zvni_print_mac(zebra_mac_t *mac, void *ctxt); static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json);
static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt); static void zvni_print_mac_hash(struct hash_backet *backet, void *ctxt);
static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt); static void zvni_print_mac_hash_all_vni(struct hash_backet *backet, void *ctxt);
static void zvni_print(zebra_vni_t *zvni, void **ctxt); static void zvni_print(zebra_vni_t *zvni, void **ctxt);
@ -569,7 +569,7 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
/* /*
* Print a specific MAC entry. * Print a specific MAC entry.
*/ */
static void zvni_print_mac(zebra_mac_t *mac, void *ctxt) static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
{ {
struct vty *vty; struct vty *vty;
zebra_neigh_t *n = NULL; zebra_neigh_t *n = NULL;
@ -578,8 +578,11 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
char buf2[INET6_ADDRSTRLEN]; char buf2[INET6_ADDRSTRLEN];
vty = (struct vty *)ctxt; vty = (struct vty *)ctxt;
vty_out(vty, "MAC: %s", prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
if (json) {
json_object *json_mac = json_object_new_object();
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) { if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
struct zebra_ns *zns; struct zebra_ns *zns;
struct interface *ifp; struct interface *ifp;
@ -588,11 +591,92 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
ifindex = mac->fwd_info.local.ifindex; ifindex = mac->fwd_info.local.ifindex;
zns = zebra_ns_lookup(NS_DEFAULT); zns = zebra_ns_lookup(NS_DEFAULT);
ifp = if_lookup_by_index_per_ns(zns, ifindex); ifp = if_lookup_by_index_per_ns(zns, ifindex);
if (!ifp) // unexpected if (!ifp)
return;
json_object_string_add(json_mac, "type", "local");
json_object_string_add(json_mac, "intf", ifp->name);
json_object_int_add(json_mac, "ifindex", ifindex);
if (mac->fwd_info.local.vid)
json_object_int_add(json_mac, "vlan",
mac->fwd_info.local.vid);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
json_object_string_add(json_mac, "type", "remote");
json_object_string_add(
json_mac, "remoteVtep",
inet_ntoa(mac->fwd_info.r_vtep_ip));
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
json_object_string_add(json_mac, "type", "auto mac");
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
json_object_boolean_true_add(json_mac, "stickyMac");
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
json_object_boolean_true_add(json_mac,
"defaultGateway");
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
json_object_boolean_true_add(json_mac,
"remoteGatewayMac");
json_object_int_add(json_mac, "localSequence", mac->loc_seq);
json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
/* print all the associated neigh */
if (!listcount(mac->neigh_list))
json_object_string_add(json_mac, "neighbors", "none");
else {
json_object *json_active_nbrs = json_object_new_array();
json_object *json_inactive_nbrs =
json_object_new_array();
json_object *json_nbrs = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
if (IS_ZEBRA_NEIGH_ACTIVE(n))
json_object_array_add(
json_active_nbrs,
json_object_new_string(
ipaddr2str(
&n->ip, buf2,
sizeof(buf2))));
else
json_object_array_add(
json_inactive_nbrs,
json_object_new_string(
ipaddr2str(
&n->ip, buf2,
sizeof(buf2))));
}
json_object_object_add(json_nbrs, "active",
json_active_nbrs);
json_object_object_add(json_nbrs, "inactive",
json_inactive_nbrs);
json_object_object_add(json_mac, "neighbors",
json_nbrs);
}
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);
if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
struct zebra_ns *zns;
struct interface *ifp;
ifindex_t ifindex;
ifindex = mac->fwd_info.local.ifindex;
zns = zebra_ns_lookup(NS_DEFAULT);
ifp = if_lookup_by_index_per_ns(zns, ifindex);
if (!ifp)
return; return;
vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex); vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
if (mac->fwd_info.local.vid) if (mac->fwd_info.local.vid)
vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid); vty_out(vty, " VLAN: %u",
mac->fwd_info.local.vid);
} else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) { } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
vty_out(vty, " Remote VTEP: %s", vty_out(vty, " Remote VTEP: %s",
inet_ntoa(mac->fwd_info.r_vtep_ip)); inet_ntoa(mac->fwd_info.r_vtep_ip));
@ -610,8 +694,8 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
vty_out(vty, " Remote-gateway Mac "); vty_out(vty, " Remote-gateway Mac ");
vty_out(vty, "\n"); vty_out(vty, "\n");
vty_out(vty, " Local Seq: %u Remote Seq: %u", vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq,
mac->loc_seq, mac->rem_seq); mac->rem_seq);
vty_out(vty, "\n"); vty_out(vty, "\n");
/* print all the associated neigh */ /* print all the associated neigh */
@ -623,11 +707,13 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
vty_out(vty, " %s %s\n", vty_out(vty, " %s %s\n",
ipaddr2str(&n->ip, buf2, sizeof(buf2)), ipaddr2str(&n->ip, buf2, sizeof(buf2)),
(IS_ZEBRA_NEIGH_ACTIVE(n) (IS_ZEBRA_NEIGH_ACTIVE(n)
? "Active" : "Inactive")); ? "Active"
: "Inactive"));
} }
} }
vty_out(vty, "\n"); vty_out(vty, "\n");
}
} }
/* /*
@ -5151,26 +5237,39 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
* Display specific MAC for a VNI, if present (VTY command handler). * Display specific MAC for a VNI, if present (VTY command handler).
*/ */
void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf, void zebra_vxlan_print_specific_mac_vni(struct vty *vty, struct zebra_vrf *zvrf,
vni_t vni, struct ethaddr *macaddr) vni_t vni, struct ethaddr *macaddr,
bool use_json)
{ {
zebra_vni_t *zvni; zebra_vni_t *zvni;
zebra_mac_t *mac; zebra_mac_t *mac;
json_object *json = NULL;
if (!is_evpn_enabled()) if (!is_evpn_enabled())
return; return;
zvni = zvni_lookup(vni); zvni = zvni_lookup(vni);
if (!zvni) { if (!zvni) {
if (use_json)
vty_out(vty, "{}\n");
else
vty_out(vty, "%% VNI %u does not exist\n", vni); vty_out(vty, "%% VNI %u does not exist\n", vni);
return; return;
} }
mac = zvni_mac_lookup(zvni, macaddr); mac = zvni_mac_lookup(zvni, macaddr);
if (!mac) { if (!mac) {
vty_out(vty, "%% Requested MAC does not exist in VNI %u\n", if (use_json)
vty_out(vty, "{}\n");
else
vty_out(vty,
"%% Requested MAC does not exist in VNI %u\n",
vni); vni);
return; return;
} }
zvni_print_mac(mac, vty); if (use_json)
json = json_object_new_object();
zvni_print_mac(mac, vty, json);
} }
/* /*

View File

@ -94,7 +94,8 @@ extern void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
bool use_json); bool use_json);
extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty, extern void zebra_vxlan_print_specific_mac_vni(struct vty *vty,
struct zebra_vrf *zvrf, struct zebra_vrf *zvrf,
vni_t vni, struct ethaddr *mac); vni_t vni, struct ethaddr *mac,
bool use_json);
extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, extern void zebra_vxlan_print_macs_vni_vtep(struct vty *vty,
struct zebra_vrf *zvrf, vni_t vni, struct zebra_vrf *zvrf, vni_t vni,
struct in_addr vtep_ip, struct in_addr vtep_ip,