From 489a332cde11d8cc49e46b9e6462982142187dba Mon Sep 17 00:00:00 2001 From: vivek Date: Mon, 10 Jan 2022 21:54:30 -0800 Subject: [PATCH] zebra: Display local MAC cache Add vtysh handler and backend function to display the local MAC cache. Signed-off-by: Vivek Venkatraman --- zebra/zebra_l2_bridge_if.c | 57 ++++++++++++++++++++++++++++++++++++++ zebra/zebra_l2_bridge_if.h | 2 ++ zebra/zebra_vty.c | 35 +++++++++++++++++++++++ 3 files changed, 94 insertions(+) diff --git a/zebra/zebra_l2_bridge_if.c b/zebra/zebra_l2_bridge_if.c index 00450ddd36a0..cbd6f4d87792 100644 --- a/zebra/zebra_l2_bridge_if.c +++ b/zebra/zebra_l2_bridge_if.c @@ -55,6 +55,27 @@ #include "zebra/zebra_evpn_vxlan.h" #include "zebra/zebra_router.h" +static void zebra_l2_brvlan_print_mac_hash(struct hash_bucket *bucket, + void *ctxt) +{ + struct zebra_l2_brvlan_mac_ctx *ctx; + struct vty *vty; + struct zebra_l2_brvlan_mac *bmac; + char buf[ETHER_ADDR_STRLEN]; + struct interface *ifp; + + ctx = (struct zebra_l2_brvlan_mac_ctx *)ctxt; + vty = (struct vty *)(ctx->arg); + bmac = (struct zebra_l2_brvlan_mac *)bucket->data; + + prefix_mac2str(&bmac->macaddr, buf, sizeof(buf)); + ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT), + bmac->ifindex); + + vty_out(vty, "%-17s %-7u %s\n", buf, bmac->ifindex, + ifp ? ifp->name : "-"); +} + static unsigned int zebra_l2_bridge_vlan_hash_keymake(const void *p) { const struct zebra_l2_bridge_vlan *bvlan; @@ -63,6 +84,42 @@ static unsigned int zebra_l2_bridge_vlan_hash_keymake(const void *p) return jhash(&bvlan->vid, sizeof(bvlan->vid), 0); } +void zebra_l2_brvlan_print_macs(struct vty *vty, struct interface *br_if, + vlanid_t vid, bool uj) +{ + struct zebra_if *zif; + struct zebra_l2_bridge_if *br; + uint32_t num_macs; + struct zebra_l2_brvlan_mac_ctx ctx; + + zif = (struct zebra_if *)br_if->info; + br = BRIDGE_FROM_ZEBRA_IF(zif); + if (!br) { + return; + } + if (!br->mac_table[vid]) { + vty_out(vty, + "%% bridge %s VID %u does not have a MAC hash table\n", + br_if->name, vid); + return; + } + num_macs = hashcount(br->mac_table[vid]); + if (!num_macs) { + vty_out(vty, "bridge %s VID %u - No local MACs\n", br_if->name, + vid); + return; + } + + vty_out(vty, "bridge %s VID %u - Number of local MACs: %u\n", + br_if->name, vid, num_macs); + vty_out(vty, "%-17s %-7s %-30s\n", "MAC", "IfIndex", "Interface"); + memset(&ctx, 0, sizeof(ctx)); + ctx.br_if = br_if; + ctx.vid = vid; + ctx.arg = vty; + hash_iterate(br->mac_table[vid], zebra_l2_brvlan_print_mac_hash, &ctx); +} + static bool zebra_l2_bridge_vlan_hash_cmp(const void *p1, const void *p2) { const struct zebra_l2_bridge_vlan *bv1; diff --git a/zebra/zebra_l2_bridge_if.h b/zebra/zebra_l2_bridge_if.h index 734ecfdcf119..00041ad13dd9 100644 --- a/zebra/zebra_l2_bridge_if.h +++ b/zebra/zebra_l2_bridge_if.h @@ -64,6 +64,8 @@ extern int zebra_l2_bridge_if_vlan_access_bd_deref(struct zebra_evpn_access_bd *bd); extern int zebra_l2_bridge_if_vlan_access_bd_ref(struct zebra_evpn_access_bd *bd); +extern void zebra_l2_brvlan_print_macs(struct vty *vty, struct interface *br_if, + vlanid_t vid, bool uj); extern int zebra_l2_bridge_if_del(struct interface *ifp); extern int zebra_l2_bridge_if_add(struct interface *ifp); extern int zebra_l2_bridge_if_cleanup(struct interface *ifp); diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 81370decdc96..c60e2584bc28 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -3513,6 +3513,40 @@ DEFUN (show_evpn_neigh_vni_vtep, return CMD_SUCCESS; } +DEFPY(show_evpn_local_mac, show_evpn_local_mac_cmd, + "show evpn local-mac IFNAME$if_name (1-4094)$vid [json$json]", + SHOW_STR + "EVPN\n" + "Local MAC addresses\n" + "Interface Name\n" + "VLAN ID\n" JSON_STR) +{ + struct vrf *vrf = NULL; + struct interface *ifp = NULL; + bool found = false; + bool uj = use_json(argc, argv); + + if (!if_name || !vid) { + return CMD_WARNING; + } + + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + ifp = if_lookup_by_name(if_name, vrf->vrf_id); + if (ifp) { + found = true; + break; + } + } + + if (!found) { + vty_out(vty, "%% Can't find interface %s\n", if_name); + return CMD_WARNING; + } + + zebra_l2_brvlan_print_macs(vty, ifp, vid, uj); + return CMD_SUCCESS; +} + /* policy routing contexts */ DEFUN (show_pbr_ipset, show_pbr_ipset_cmd, @@ -4447,6 +4481,7 @@ void zebra_vty_init(void) install_element(VIEW_NODE, &show_evpn_neigh_vni_vtep_cmd); install_element(VIEW_NODE, &show_evpn_neigh_vni_dad_cmd); install_element(VIEW_NODE, &show_evpn_neigh_vni_all_dad_cmd); + install_element(VIEW_NODE, &show_evpn_local_mac_cmd); install_element(ENABLE_NODE, &clear_evpn_dup_addr_cmd); install_element(CONFIG_NODE, &evpn_accept_bgp_seq_cmd); install_element(CONFIG_NODE, &no_evpn_accept_bgp_seq_cmd);