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.
*/
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)
}
}
+/*
+ * 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).
*/
}
-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;
}
/*