]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vxlan.c
zebra: delay default vrf name after vrf initialization
[mirror_frr.git] / zebra / zebra_vxlan.c
index 58cf6eb30f1338c9a05ef01244d1abaae1791ad3..d372d3e832b639173b20bbd4e183ff150bc382fe 100644 (file)
@@ -72,7 +72,7 @@ static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
                            json_object *json);
 static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
                              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_all_vni(struct hash_backet *backet, void *ctxt);
 static void zvni_print(zebra_vni_t *zvni, void **ctxt);
@@ -148,8 +148,7 @@ static void zvni_mac_del_all(zebra_vni_t *zvni, int uninstall, int upd_client,
 static zebra_mac_t *zvni_mac_lookup(zebra_vni_t *zvni, struct ethaddr *macaddr);
 static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
                                       uint8_t flags, uint32_t seq);
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
-                                      uint8_t flags);
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr);
 static zebra_vni_t *zvni_map_vlan(struct interface *ifp,
                                  struct interface *br_if, vlanid_t vid);
 static int zvni_mac_install(zebra_vni_t *zvni, zebra_mac_t *mac);
@@ -570,7 +569,7 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
 /*
  * 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;
        zebra_neigh_t *n = NULL;
@@ -579,56 +578,142 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt)
        char buf2[INET6_ADDRSTRLEN];
 
        vty = (struct vty *)ctxt;
-       vty_out(vty, "MAC: %s",
-               prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)));
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL)) {
-               struct zebra_ns *zns;
-               struct interface *ifp;
-               ifindex_t ifindex;
+       prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
 
-               ifindex = mac->fwd_info.local.ifindex;
-               zns = zebra_ns_lookup(NS_DEFAULT);
-               ifp = if_lookup_by_index_per_ns(zns, ifindex);
-               if (!ifp) // unexpected
-                       return;
-               vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
-               if (mac->fwd_info.local.vid)
-                       vty_out(vty, " VLAN: %u", mac->fwd_info.local.vid);
-       } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
-               vty_out(vty, " Remote VTEP: %s",
-                       inet_ntoa(mac->fwd_info.r_vtep_ip));
-       } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
-               vty_out(vty, " Auto Mac ");
-       }
+       if (json) {
+               json_object *json_mac = json_object_new_object();
+
+               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;
+                       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");
 
-       if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
-               vty_out(vty, " Sticky 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))
-               vty_out(vty, " Default-gateway Mac ");
+               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))
-               vty_out(vty, " Remote-gateway Mac ");
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+                       json_object_boolean_true_add(json_mac,
+                                                    "remoteGatewayMac");
 
-       vty_out(vty, "\n");
-       vty_out(vty, " Local Seq: %u Remote Seq: %u",
-               mac->loc_seq, mac->rem_seq);
-       vty_out(vty, "\n");
+               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 */
-       vty_out(vty, " Neighbors:\n");
-       if (!listcount(mac->neigh_list))
-               vty_out(vty, "    No Neighbors\n");
-       else {
-               for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
-                       vty_out(vty, "    %s %s\n",
-                               ipaddr2str(&n->ip, buf2, sizeof(buf2)),
-                               (IS_ZEBRA_NEIGH_ACTIVE(n)
-                                          ? "Active" : "Inactive"));
+               /* 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);
                }
-       }
 
-       vty_out(vty, "\n");
+               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;
+                       vty_out(vty, " Intf: %s(%u)", ifp->name, ifindex);
+                       if (mac->fwd_info.local.vid)
+                               vty_out(vty, " VLAN: %u",
+                                       mac->fwd_info.local.vid);
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
+                       vty_out(vty, " Remote VTEP: %s",
+                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+               } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
+                       vty_out(vty, " Auto Mac ");
+               }
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY))
+                       vty_out(vty, " Sticky Mac ");
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DEF_GW))
+                       vty_out(vty, " Default-gateway Mac ");
+
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE_DEF_GW))
+                       vty_out(vty, " Remote-gateway Mac ");
+
+               vty_out(vty, "\n");
+               vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq,
+                       mac->rem_seq);
+               vty_out(vty, "\n");
+
+               /* print all the associated neigh */
+               vty_out(vty, " Neighbors:\n");
+               if (!listcount(mac->neigh_list))
+                       vty_out(vty, "    No Neighbors\n");
+               else {
+                       for (ALL_LIST_ELEMENTS_RO(mac->neigh_list, node, n)) {
+                               vty_out(vty, "    %s %s\n",
+                                       ipaddr2str(&n->ip, buf2, sizeof(buf2)),
+                                       (IS_ZEBRA_NEIGH_ACTIVE(n)
+                                                ? "Active"
+                                                : "Inactive"));
+                       }
+               }
+
+               vty_out(vty, "\n");
+       }
 }
 
 /*
@@ -2219,6 +2304,7 @@ static int zvni_remote_neigh_update(zebra_vni_t *zvni,
 
                UNSET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
                SET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
+               ZEBRA_NEIGH_SET_ACTIVE(n);
                n->r_vtep_ip = zmac->fwd_info.r_vtep_ip;
        }
 
@@ -2321,7 +2407,7 @@ static void zvni_mac_del_hash_entry(struct hash_backet *backet, void *arg)
                                  &wctx->r_vtep_ip))) {
                if (wctx->upd_client && (mac->flags & ZEBRA_MAC_LOCAL)) {
                        zvni_mac_send_del_to_client(wctx->zvni->vni,
-                                                   &mac->macaddr, mac->flags);
+                                                   &mac->macaddr);
                }
 
                if (wctx->uninstall)
@@ -2408,18 +2494,10 @@ static int zvni_mac_send_add_to_client(vni_t vni, struct ethaddr *macaddr,
 /*
  * Inform BGP about local MAC deletion.
  */
-static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr,
-                                      uint8_t mac_flags)
+static int zvni_mac_send_del_to_client(vni_t vni, struct ethaddr *macaddr)
 {
-       uint8_t flags = 0;
-
-       if (CHECK_FLAG(mac_flags, ZEBRA_MAC_STICKY))
-               SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
-       if (CHECK_FLAG(mac_flags, ZEBRA_MAC_DEF_GW))
-               SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
-
-       return zvni_macip_send_msg_to_client(vni, macaddr, NULL, flags,
-                                            0, ZEBRA_MACIP_DEL);
+       return zvni_macip_send_msg_to_client(vni, macaddr, NULL, 0 /* flags */,
+                                            0 /* seq */, ZEBRA_MACIP_DEL);
 }
 
 /*
@@ -4218,6 +4296,10 @@ static void process_remote_macip_add(vni_t vni,
                        }
                }
 
+               /* Remove local MAC from BGP. */
+               if (CHECK_FLAG(mac->flags, ZEBRA_MAC_LOCAL))
+                       zvni_mac_send_del_to_client(zvni->vni, macaddr);
+
                /* Set "auto" and "remote" forwarding info. */
                UNSET_FLAG(mac->flags, ZEBRA_MAC_LOCAL);
                memset(&mac->fwd_info, 0, sizeof(mac->fwd_info));
@@ -4238,6 +4320,7 @@ static void process_remote_macip_add(vni_t vni,
 
                /* Install the entry. */
                zvni_mac_install(zvni, mac);
+
        }
 
        /* Update seq number. */
@@ -4436,6 +4519,13 @@ static void process_remote_macip_del(vni_t vni,
        } else {
                if (CHECK_FLAG(mac->flags, ZEBRA_MAC_REMOTE)) {
                        zvni_process_neigh_on_remote_mac_del(zvni, mac);
+                       /*
+                        * the remote sequence number in the auto mac entry
+                        * needs to be reset to 0 as the mac entry may have
+                        * been removed on all VTEPs (including
+                        * the originating one)
+                        */
+                       mac->rem_seq = 0;
 
                        /* If all remote neighbors referencing a remote MAC
                         * go away, we need to uninstall the MAC.
@@ -5128,26 +5218,39 @@ void zebra_vxlan_print_macs_all_vni_vtep(struct vty *vty,
  * 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,
-                                       vni_t vni, struct ethaddr *macaddr)
+                                       vni_t vni, struct ethaddr *macaddr,
+                                       bool use_json)
 {
        zebra_vni_t *zvni;
        zebra_mac_t *mac;
+       json_object *json = NULL;
 
        if (!is_evpn_enabled())
                return;
+
        zvni = zvni_lookup(vni);
        if (!zvni) {
-               vty_out(vty, "%% VNI %u does not exist\n", vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
                return;
        }
        mac = zvni_mac_lookup(zvni, macaddr);
        if (!mac) {
-               vty_out(vty, "%% Requested MAC does not exist in VNI %u\n",
-                       vni);
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty,
+                               "%% Requested MAC does not exist in VNI %u\n",
+                               vni);
                return;
        }
 
-       zvni_print_mac(mac, vty);
+       if (use_json)
+               json = json_object_new_object();
+
+       zvni_print_mac(mac, vty, json);
 }
 
 /*
@@ -5631,7 +5734,7 @@ int zebra_vxlan_check_del_local_mac(struct interface *ifp,
                        ifp->ifindex, vni);
 
        /* Remove MAC from BGP. */
-       zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+       zvni_mac_send_del_to_client(zvni->vni, macaddr);
 
        /*
         * If there are no neigh associated with the mac delete the mac
@@ -5742,7 +5845,7 @@ int zebra_vxlan_local_mac_del(struct interface *ifp, struct interface *br_if,
        zvni_process_neigh_on_local_mac_del(zvni, mac);
 
        /* Remove MAC from BGP. */
-       zvni_mac_send_del_to_client(zvni->vni, macaddr, mac->flags);
+       zvni_mac_send_del_to_client(zvni->vni, macaddr);
 
        /*
         * If there are no neigh associated with the mac delete the mac