}
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);
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.
*/
}
}
+/*
+ * 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;
}
}
+/* Private Structure to pass callback data for hash iterator */
+struct zvni_evpn_show {
+ struct vty *vty;
+ json_object *json;
+ struct zebra_vrf *zvrf;
+};
+
+/* print a L3 VNI hash entry in detail*/
+static void zl3vni_print_hash_detail(struct hash_backet *backet, void *data)
+{
+ struct vty *vty = NULL;
+ zebra_l3vni_t *zl3vni = NULL;
+ json_object *json = NULL;
+ bool use_json = false;
+ struct zvni_evpn_show *zes = data;
+
+ vty = zes->vty;
+ json = zes->json;
+
+ if (json)
+ use_json = true;
+
+ zl3vni = (zebra_l3vni_t *)backet->data;
+
+ zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni, use_json);
+ vty_out(vty, "\n");
+}
+
+
/*
* Print a VNI hash entry - called for display of all VNIs.
*/
}
}
+/*
+ * Print a VNI hash entry in detail - called for display of all VNIs.
+ */
+static void zvni_print_hash_detail(struct hash_backet *backet, void *data)
+{
+ struct vty *vty;
+ zebra_vni_t *zvni;
+ json_object *json = NULL;
+ bool use_json = false;
+ struct zvni_evpn_show *zes = data;
+
+ vty = zes->vty;
+ json = zes->json;
+
+ if (json)
+ use_json = true;
+
+ zvni = (zebra_vni_t *)backet->data;
+
+ zebra_vxlan_print_vni(vty, zes->zvrf, zvni->vni, use_json);
+ vty_out(vty, "\n");
+}
+
/*
* Inform BGP about local MACIP.
*/
}
}
+/*
+ * 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).
*/
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 */
}
-void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
- struct zebra_vrf *zvrf,
- vni_t vni, struct ethaddr *macaddr)
+int zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
+ struct zebra_vrf *zvrf,
+ vni_t vni, struct ethaddr *macaddr)
{
zebra_vni_t *zvni;
zebra_mac_t *mac;
zebra_neigh_t *nbr = NULL;
if (!is_evpn_enabled())
- return;
+ return CMD_SUCCESS;
+
zvni = zvni_lookup(vni);
if (!zvni) {
vty_out(vty, "%% VNI %u does not exist\n", vni);
- return;
+ return CMD_WARNING;
}
mac = zvni_mac_lookup(zvni, macaddr);
if (!mac) {
vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
vni);
- return;
+ return CMD_WARNING;
}
if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
vty_out(vty, "%% Requested MAC is not duplicate detected\n");
- return;
+ return CMD_WARNING;
}
/* Remove all IPs as duplicate associcated with this MAC */
&mac->macaddr,
mac->flags,
mac->loc_seq))
- return;
+ return CMD_SUCCESS;
/* Process all neighbors associated with this MAC. */
zvni_process_neigh_on_local_mac_change(zvni, mac, 0);
zvni_mac_install(zvni, mac);
}
+ return CMD_SUCCESS;
}
-void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
- struct zebra_vrf *zvrf,
- vni_t vni, struct ipaddr *ip)
+int zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
+ struct zebra_vrf *zvrf,
+ vni_t vni, struct ipaddr *ip)
{
zebra_vni_t *zvni;
zebra_neigh_t *nbr;
char buf2[ETHER_ADDR_STRLEN];
if (!is_evpn_enabled())
- return;
+ return CMD_SUCCESS;
zvni = zvni_lookup(vni);
if (!zvni) {
vty_out(vty, "%% VNI %u does not exist\n", vni);
- return;
+ return CMD_WARNING;
}
nbr = zvni_neigh_lookup(zvni, ip);
vty_out(vty,
"%% Requested host IP does not exist in VNI %u\n",
vni);
- return;
+ return CMD_WARNING;
}
ipaddr2str(&nbr->ip, buf, sizeof(buf));
vty_out(vty,
"%% Requsted host IP %s is not duplicate detected\n",
buf);
- return;
+ return CMD_WARNING;
}
mac = zvni_mac_lookup(zvni, &nbr->emac);
vty_out(vty,
"%% Requested IP's associated MAC %s is still in duplicate state\n",
prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
- return;
+ return CMD_WARNING_CONFIG_FAILED;
}
if (IS_ZEBRA_DEBUG_VXLAN)
zvni_neigh_install(zvni, nbr);
}
+ return CMD_SUCCESS;
}
static void zvni_clear_dup_mac_hash(struct hash_backet *backet, void *ctxt)
}
-void zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
+int zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
struct zebra_vrf *zvrf)
{
void *args[2];
if (!is_evpn_enabled())
- return;
+ return CMD_SUCCESS;
args[0] = vty;
args[1] = zvrf;
(void (*)(struct hash_backet *, void *))
zvni_clear_dup_detect_hash_vni_all, args);
+ return CMD_SUCCESS;
}
-void zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
+int zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
struct zebra_vrf *zvrf,
vni_t vni)
{
struct neigh_walk_ctx n_wctx;
if (!is_evpn_enabled())
- return;
+ return CMD_SUCCESS;
zvni = zvni_lookup(vni);
if (!zvni) {
vty_out(vty, "%% VNI %u does not exist\n", vni);
- return;
+ return CMD_WARNING;
}
if (hashcount(zvni->neigh_table)) {
hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
}
+ return CMD_SUCCESS;
}
/*
return;
}
+/*
+ * Display VNI hash table in detail(VTY command handler).
+ */
+void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
+ bool use_json)
+{
+ json_object *json = NULL;
+ struct zebra_ns *zns = NULL;
+ struct zvni_evpn_show zes;
+
+ if (!is_evpn_enabled())
+ return;
+
+ zns = zebra_ns_lookup(NS_DEFAULT);
+ if (!zns)
+ return;
+
+
+ if (use_json)
+ json = json_object_new_object();
+
+ zes.vty = vty;
+ zes.json = json;
+ zes.zvrf = zvrf;
+
+ /* Display all L2-VNIs */
+ hash_iterate(zvrf->vni_table, (void (*)(struct hash_backet *,
+ void *))zvni_print_hash_detail,
+ &zes);
+
+ /* Display all L3-VNIs */
+ hash_iterate(zrouter.l3vni_table,
+ (void (*)(struct hash_backet *,
+ void *))zl3vni_print_hash_detail,
+ &zes);
+
+ if (use_json) {
+ vty_out(vty, "%s\n", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY));
+ json_object_free(json);
+ }
+}
+
/*
* Handle neighbor delete notification from the kernel (on a VLAN device
* / L3 interface). This may result in either the neighbor getting deleted
"Add L2-VNI %u VRF %s intf %s(%u) VLAN %u local IP %s master %u",
vni,
vlan_if ? vrf_id_to_name(vlan_if->vrf_id)
- : "Default",
+ : VRF_DEFAULT_NAME,
ifp->name, ifp->ifindex, vxl->access_vlan,
inet_ntoa(vxl->vtep_ip),
zif->brslave_info.bridge_ifindex);
}
/* init the l3vni table */
-void zebra_vxlan_ns_init(struct zebra_ns *zns)
+void zebra_vxlan_init(void)
{
zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp,
"Zebra VRF L3 VNI table");
}
/* free l3vni table */
-void zebra_vxlan_ns_disable(struct zebra_ns *zns)
+void zebra_vxlan_disable(void)
{
hash_free(zrouter.l3vni_table);
}