]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vxlan.c
Merge pull request #5793 from ton31337/fix/formatting_show_bgp_summary_failed
[mirror_frr.git] / zebra / zebra_vxlan.c
index 1da419040ed6c352cd30daee20595d698487b63b..4b56581ca9ba7282f30c0a3893caf071847bccbb 100644 (file)
@@ -1994,6 +1994,7 @@ struct zvni_evpn_show {
        struct vty *vty;
        json_object *json;
        struct zebra_vrf *zvrf;
+       bool use_json;
 };
 
 /* print a L3 VNI hash entry in detail*/
@@ -2001,20 +2002,21 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
 {
        struct vty *vty = NULL;
        zebra_l3vni_t *zl3vni = NULL;
-       json_object *json = NULL;
+       json_object *json_array = NULL;
        bool use_json = false;
        struct zvni_evpn_show *zes = data;
 
        vty = zes->vty;
-       json = zes->json;
-
-       if (json)
-               use_json = true;
+       json_array = zes->json;
+       use_json = zes->use_json;
 
        zl3vni = (zebra_l3vni_t *)bucket->data;
 
-       zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni, use_json);
-       vty_out(vty, "\n");
+       zebra_vxlan_print_vni(vty, zes->zvrf, zl3vni->vni,
+               use_json, json_array);
+
+       if (!use_json)
+               vty_out(vty, "\n");
 }
 
 
@@ -2089,20 +2091,20 @@ static void zvni_print_hash_detail(struct hash_bucket *bucket, void *data)
 {
        struct vty *vty;
        zebra_vni_t *zvni;
-       json_object *json = NULL;
+       json_object *json_array = NULL;
        bool use_json = false;
        struct zvni_evpn_show *zes = data;
 
        vty = zes->vty;
-       json = zes->json;
-
-       if (json)
-               use_json = true;
+       json_array = zes->json;
+       use_json = zes->use_json;
 
        zvni = (zebra_vni_t *)bucket->data;
 
-       zebra_vxlan_print_vni(vty, zes->zvrf, zvni->vni, use_json);
-       vty_out(vty, "\n");
+       zebra_vxlan_print_vni(vty, zes->zvrf, zvni->vni, use_json, json_array);
+
+       if (!use_json)
+               vty_out(vty, "\n");
 }
 
 /*
@@ -3210,7 +3212,7 @@ static int zvni_local_neigh_update(zebra_vni_t *zvni,
                        vtep_ip = n->r_vtep_ip;
                        /* Mark appropriately */
                        UNSET_FLAG(n->flags, ZEBRA_NEIGH_REMOTE);
-                       n->r_vtep_ip.s_addr = 0;
+                       n->r_vtep_ip.s_addr = INADDR_ANY;
                        SET_FLAG(n->flags, ZEBRA_NEIGH_LOCAL);
                        n->ifindex = ifp->ifindex;
                }
@@ -7285,9 +7287,14 @@ void zebra_vxlan_print_macs_vni_vtep(struct vty *vty, struct zebra_vrf *zvrf,
 
 /*
  * Display VNI information (VTY command handler).
+ *
+ * use_json flag indicates that output should be in JSON format.
+ * json_array is non NULL when JSON output needs to be aggregated (by the
+ * caller) and then printed, otherwise, JSON evpn vni info is printed
+ * right away.
  */
 void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
-                          bool use_json)
+                          bool use_json, json_object *json_array)
 {
        json_object *json = NULL;
        void *args[2];
@@ -7299,6 +7306,7 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
 
        if (use_json)
                json = json_object_new_object();
+
        args[0] = vty;
        args[1] = json;
 
@@ -7307,21 +7315,25 @@ void zebra_vxlan_print_vni(struct vty *vty, struct zebra_vrf *zvrf, vni_t vni,
                zl3vni_print(zl3vni, (void *)args);
        } else {
                zvni = zvni_lookup(vni);
-               if (!zvni) {
-                       if (use_json)
-                               vty_out(vty, "{}\n");
-                       else
-                               vty_out(vty, "%% VNI %u does not exist\n", vni);
-                       return;
-               }
-
-               zvni_print(zvni, (void *)args);
+               if (zvni)
+                       zvni_print(zvni, (void *)args);
+               else if (!json)
+                       vty_out(vty, "%% VNI %u does not exist\n", vni);
        }
 
        if (use_json) {
-               vty_out(vty, "%s\n", json_object_to_json_string_ext(
-                                            json, JSON_C_TO_STRING_PRETTY));
-               json_object_free(json);
+               /*
+                * Each "json" object contains info about 1 VNI.
+                * When "json_array" is non-null, we aggreggate the json output
+                * into json_array and print it as a JSON array.
+                */
+               if (json_array)
+                       json_object_array_add(json_array, json);
+               else {
+                       vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+                       json_object_free(json);
+               }
        }
 }
 
@@ -7478,7 +7490,7 @@ stream_failure:
 void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
                                   bool use_json)
 {
-       json_object *json = NULL;
+       json_object *json_array = NULL;
        struct zebra_ns *zns = NULL;
        struct zvni_evpn_show zes;
 
@@ -7489,13 +7501,13 @@ void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
        if (!zns)
                return;
 
-
        if (use_json)
-               json = json_object_new_object();
+               json_array = json_object_new_array();
 
        zes.vty = vty;
-       zes.json = json;
+       zes.json = json_array;
        zes.zvrf = zvrf;
+       zes.use_json = use_json;
 
        /* Display all L2-VNIs */
        hash_iterate(
@@ -7512,8 +7524,8 @@ void zebra_vxlan_print_vnis_detail(struct vty *vty, struct zebra_vrf *zvrf,
        if (use_json) {
                vty_out(vty, "%s\n",
                        json_object_to_json_string_ext(
-                               json, JSON_C_TO_STRING_PRETTY));
-               json_object_free(json);
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
        }
 }
 
@@ -7670,6 +7682,55 @@ int zebra_vxlan_handle_kernel_neigh_update(struct interface *ifp,
        return zvni_remote_neigh_update(zvni, ifp, ip, macaddr, state);
 }
 
+static int32_t
+zebra_vxlan_remote_macip_helper(bool add, struct stream *s, vni_t *vni,
+                               struct ethaddr *macaddr, uint16_t *ipa_len,
+                               struct ipaddr *ip, struct in_addr *vtep_ip,
+                               uint8_t *flags, uint32_t *seq)
+{
+       uint16_t l = 0;
+
+       /*
+        * Obtain each remote MACIP and process.
+        * Message contains VNI, followed by MAC followed by IP (if any)
+        * followed by remote VTEP IP.
+        */
+       memset(ip, 0, sizeof(*ip));
+       STREAM_GETL(s, *vni);
+       STREAM_GET(macaddr->octet, s, ETH_ALEN);
+       STREAM_GETL(s, *ipa_len);
+
+       if (*ipa_len) {
+               if (*ipa_len == IPV4_MAX_BYTELEN)
+                       ip->ipa_type = IPADDR_V4;
+               else if (*ipa_len == IPV6_MAX_BYTELEN)
+                       ip->ipa_type = IPADDR_V6;
+               else {
+                       if (IS_ZEBRA_DEBUG_VXLAN)
+                               zlog_debug(
+                                       "ipa_len *must* be %d or %d bytes in length not %d",
+                                       IPV4_MAX_BYTELEN, IPV6_MAX_BYTELEN,
+                                       *ipa_len);
+                       goto stream_failure;
+               }
+
+               STREAM_GET(&ip->ip.addr, s, *ipa_len);
+       }
+       l += 4 + ETH_ALEN + 4 + *ipa_len;
+       STREAM_GET(&vtep_ip->s_addr, s, IPV4_MAX_BYTELEN);
+       l += IPV4_MAX_BYTELEN;
+
+       if (add) {
+               STREAM_GETC(s, *flags);
+               STREAM_GETL(s, *seq);
+               l += 5;
+       }
+
+       return l;
+
+stream_failure:
+       return -1;
+}
 
 /*
  * Handle message from client to delete a remote MACIP for a VNI.
@@ -7692,23 +7753,14 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
        s = msg;
 
        while (l < hdr->length) {
-               /* Obtain each remote MACIP and process. */
-               /* Message contains VNI, followed by MAC followed by IP (if any)
-                * followed by remote VTEP IP.
-                */
-               memset(&ip, 0, sizeof(ip));
-               STREAM_GETL(s, vni);
-               STREAM_GET(&macaddr.octet, s, ETH_ALEN);
-               STREAM_GETL(s, ipa_len);
-               if (ipa_len) {
-                       ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
-                                                                   : IPADDR_V6;
-                       STREAM_GET(&ip.ip.addr, s, ipa_len);
-               }
-               l += 4 + ETH_ALEN + 4 + ipa_len;
-               STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
-               l += IPV4_MAX_BYTELEN;
+               int res_length = zebra_vxlan_remote_macip_helper(
+                       false, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip, NULL,
+                       NULL);
+
+               if (res_length == -1)
+                       goto stream_failure;
 
+               l += res_length;
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
@@ -7757,29 +7809,14 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
        s = msg;
 
        while (l < hdr->length) {
-               /* Obtain each remote MACIP and process. */
-               /* Message contains VNI, followed by MAC followed by IP (if any)
-                * followed by remote VTEP IP.
-                */
-               memset(&ip, 0, sizeof(ip));
-               STREAM_GETL(s, vni);
-               STREAM_GET(&macaddr.octet, s, ETH_ALEN);
-               STREAM_GETL(s, ipa_len);
-               if (ipa_len) {
-                       ip.ipa_type = (ipa_len == IPV4_MAX_BYTELEN) ? IPADDR_V4
-                                                                   : IPADDR_V6;
-                       STREAM_GET(&ip.ip.addr, s, ipa_len);
-               }
-               l += 4 + ETH_ALEN + 4 + ipa_len;
-               STREAM_GET(&vtep_ip.s_addr, s, IPV4_MAX_BYTELEN);
-               l += IPV4_MAX_BYTELEN;
+               int res_length = zebra_vxlan_remote_macip_helper(
+                       true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
+                       &flags, &seq);
 
-               /* Get flags - sticky mac and/or gateway mac */
-               STREAM_GETC(s, flags);
-               l++;
-               STREAM_GETL(s, seq);
-               l += 4;
+               if (res_length == -1)
+                       goto stream_failure;
 
+               l += res_length;
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
                                "Recv MACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s from %s",
@@ -8582,6 +8619,16 @@ void zebra_vxlan_macvlan_down(struct interface *ifp)
        zif = ifp->info;
        assert(zif);
        link_ifp = zif->link;
+       if (!link_ifp) {
+               if (IS_ZEBRA_DEBUG_VXLAN) {
+                       struct interface *ifp;
+
+                       ifp = if_lookup_by_index_all_vrf(zif->link_ifindex);
+                       zlog_debug("macvlan parent link is not found. Parent index %d ifp %s",
+                               zif->link_ifindex, ifp ? ifp->name : " ");
+               }
+               return;
+       }
        link_zif = link_ifp->info;
        assert(link_zif);
 
@@ -9439,7 +9486,7 @@ void zebra_vxlan_advertise_subnet(ZAPI_HANDLER_ARGS)
 
        s = msg;
        STREAM_GETC(s, advertise);
-       vni = stream_get3(s);
+       STREAM_GET(&vni, s, 3);
 
        zvni = zvni_lookup(vni);
        if (!zvni)
@@ -9938,7 +9985,7 @@ static zebra_vxlan_sg_t *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
         * 2. the XG entry is used by pimd to setup the
         * vxlan-termination-mroute
         */
-       if (sg->src.s_addr) {
+       if (sg->src.s_addr != INADDR_ANY) {
                memset(&sip, 0, sizeof(sip));
                parent = zebra_vxlan_sg_do_ref(zvrf, sip, sg->grp);
                if (!parent)
@@ -9970,7 +10017,7 @@ static void zebra_vxlan_sg_del(zebra_vxlan_sg_t *vxlan_sg)
        /* On SG entry deletion remove the reference to its parent XG
         * entry
         */
-       if (vxlan_sg->sg.src.s_addr) {
+       if (vxlan_sg->sg.src.s_addr != INADDR_ANY) {
                memset(&sip, 0, sizeof(sip));
                zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
        }
@@ -10029,7 +10076,8 @@ static void zebra_vxlan_sg_deref(struct in_addr local_vtep_ip,
 {
        struct zebra_vrf *zvrf;
 
-       if (!local_vtep_ip.s_addr || !mcast_grp.s_addr)
+       if (local_vtep_ip.s_addr == INADDR_ANY
+           || mcast_grp.s_addr == INADDR_ANY)
                return;
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);
@@ -10044,7 +10092,8 @@ static void zebra_vxlan_sg_ref(struct in_addr local_vtep_ip,
 {
        struct zebra_vrf *zvrf;
 
-       if (!local_vtep_ip.s_addr || !mcast_grp.s_addr)
+       if (local_vtep_ip.s_addr == INADDR_ANY
+           || mcast_grp.s_addr == INADDR_ANY)
                return;
 
        zvrf = vrf_info_lookup(VRF_DEFAULT);