]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vxlan.c
isisd: implement the 'lsp-too-large' notification
[mirror_frr.git] / zebra / zebra_vxlan.c
index 86f6961118a04670f7da1c02fd87b365fc61b59a..20dc64b0bc95f68ff9ec5b9f466fa9e16c356afb 100644 (file)
@@ -871,6 +871,33 @@ static void zvni_print_neigh_hash(struct hash_backet *backet, void *ctxt)
                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.
  */
@@ -950,6 +977,80 @@ static void zvni_print_dad_neigh_hash(struct hash_backet *backet, void *ctxt)
                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)
@@ -1126,10 +1227,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 +1423,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 +1530,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;
@@ -1729,6 +1929,35 @@ static void zl3vni_print_hash(struct hash_backet *backet, void *ctx[])
        }
 }
 
+/* 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.
  */
@@ -1793,6 +2022,29 @@ static void zvni_print_hash(struct hash_backet *backet, void *ctxt[])
        }
 }
 
+/*
+ * 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.
  */
@@ -5666,6 +5918,37 @@ void zebra_vxlan_print_neigh_all_vni(struct vty *vty, struct zebra_vrf *zvrf,
        }
 }
 
+/*
+ * 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).
  */
@@ -5900,6 +6183,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 +6282,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 */
@@ -6027,9 +6347,9 @@ void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
 
 }
 
-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;
@@ -6037,23 +6357,24 @@ void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
        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 */
@@ -6092,7 +6413,7 @@ void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
                                        &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);
@@ -6104,11 +6425,12 @@ void zebra_vxlan_clear_dup_detect_vni_mac(struct vty *vty,
                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;
@@ -6117,12 +6439,12 @@ void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
        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);
@@ -6130,7 +6452,7 @@ void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
                vty_out(vty,
                        "%% Requested host IP does not exist in VNI %u\n",
                        vni);
-               return;
+               return CMD_WARNING;
        }
 
        ipaddr2str(&nbr->ip, buf, sizeof(buf));
@@ -6139,7 +6461,7 @@ void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
                vty_out(vty,
                        "%% Requsted host IP %s is not duplicate detected\n",
                        buf);
-               return;
+               return CMD_WARNING;
        }
 
        mac = zvni_mac_lookup(zvni, &nbr->emac);
@@ -6148,7 +6470,7 @@ void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
                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)
@@ -6171,6 +6493,7 @@ void zebra_vxlan_clear_dup_detect_vni_ip(struct vty *vty,
                zvni_neigh_install(zvni, nbr);
        }
 
+       return CMD_SUCCESS;
 }
 
 static void zvni_clear_dup_mac_hash(struct hash_backet *backet, void *ctxt)
@@ -6303,13 +6626,13 @@ static void zvni_clear_dup_detect_hash_vni_all(struct hash_backet *backet,
 
 }
 
-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;
@@ -6318,9 +6641,10 @@ void zebra_vxlan_clear_dup_detect_vni_all(struct vty *vty,
                     (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)
 {
@@ -6329,12 +6653,12 @@ void zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
        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)) {
@@ -6354,6 +6678,7 @@ void zebra_vxlan_clear_dup_detect_vni(struct vty *vty,
                hash_iterate(zvni->mac_table, zvni_clear_dup_mac_hash, &m_wctx);
        }
 
+       return CMD_SUCCESS;
 }
 
 /*
@@ -6594,6 +6919,49 @@ stream_failure:
        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
@@ -8027,7 +8395,7 @@ int zebra_vxlan_if_add(struct interface *ifp)
                                "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);
@@ -8496,14 +8864,14 @@ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf)
 }
 
 /* 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);
 }