]> git.proxmox.com Git - mirror_frr.git/blobdiff - zebra/zebra_vxlan.c
Merge pull request #4635 from AnuradhaKaruppiah/evpn-pim-replay
[mirror_frr.git] / zebra / zebra_vxlan.c
index 222d91105effca91358160447007f9c8f1d10cdf..dff50ceef4de9d64008b6db1738fcd6ac9353e61 100644 (file)
@@ -732,6 +732,7 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
        bool flags_present = false;
        struct zebra_vrf *zvrf = NULL;
        struct timeval detect_start_time = {0, 0};
+       char timebuf[MONOTIME_STRLEN];
 
        zvrf = zebra_vrf_get_evpn();
        if (!zvrf)
@@ -786,19 +787,17 @@ static void zvni_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
 
                if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DUPLICATE)) {
                        vty_out(vty, " Duplicate, detected at %s",
-                               time_to_string(n->dad_dup_detect_time));
+                               time_to_string(n->dad_dup_detect_time,
+                                              timebuf));
                } else if (n->dad_count) {
                        monotime_since(&n->detect_start_time,
                                       &detect_start_time);
                        if (detect_start_time.tv_sec <= zvrf->dad_time) {
-                               char *buf = time_to_string(
-                                               n->detect_start_time.tv_sec);
-                               char tmp_buf[30];
-
-                               strlcpy(tmp_buf, buf, sizeof(tmp_buf));
+                               time_to_string(n->detect_start_time.tv_sec,
+                                              timebuf);
                                vty_out(vty,
                                        " Duplicate detection started at %s, detection count %u\n",
-                                       tmp_buf, n->dad_count);
+                                       timebuf, n->dad_count);
                        }
                }
        } else {
@@ -1179,6 +1178,7 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
        char buf2[INET6_ADDRSTRLEN];
        struct zebra_vrf *zvrf;
        struct timeval detect_start_time = {0, 0};
+       char timebuf[MONOTIME_STRLEN];
 
        zvrf = zebra_vrf_get_evpn();
        if (!zvrf)
@@ -1309,19 +1309,17 @@ static void zvni_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
 
                if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
                        vty_out(vty, " Duplicate, detected at %s",
-                               time_to_string(mac->dad_dup_detect_time));
+                               time_to_string(mac->dad_dup_detect_time,
+                                              timebuf));
                } else if (mac->dad_count) {
                        monotime_since(&mac->detect_start_time,
                               &detect_start_time);
                        if (detect_start_time.tv_sec <= zvrf->dad_time) {
-                               char *buf = time_to_string(
-                                               mac->detect_start_time.tv_sec);
-                               char tmp_buf[30];
-
-                               strlcpy(tmp_buf, buf, sizeof(tmp_buf));
+                               time_to_string(mac->detect_start_time.tv_sec,
+                                              timebuf);
                                vty_out(vty,
                                        " Duplicate detection started at %s, detection count %u\n",
-                                       tmp_buf, mac->dad_count);
+                                       timebuf, mac->dad_count);
                        }
                }
 
@@ -9483,8 +9481,9 @@ static int zebra_vxlan_dad_mac_auto_recovery_exp(struct thread *t)
 
 /************************** vxlan SG cache management ************************/
 /* Inform PIM about the mcast group */
-static int zebra_vxlan_sg_send(struct prefix_sg *sg,
-                       char *sg_str, uint16_t cmd)
+static int zebra_vxlan_sg_send(struct zebra_vrf *zvrf,
+               struct prefix_sg *sg,
+               char *sg_str, uint16_t cmd)
 {
        struct zserv *client = NULL;
        struct stream *s = NULL;
@@ -9493,6 +9492,9 @@ static int zebra_vxlan_sg_send(struct prefix_sg *sg,
        if (!client)
                return 0;
 
+       if (!CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG))
+               return 0;
+
        s = stream_new(ZEBRA_MAX_PACKET_SIZ);
 
        zclient_create_header(s, cmd, VRF_DEFAULT);
@@ -9592,7 +9594,8 @@ static zebra_vxlan_sg_t *zebra_vxlan_sg_add(struct zebra_vrf *zvrf,
                return vxlan_sg;
        }
 
-       zebra_vxlan_sg_send(sg, vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
+       zebra_vxlan_sg_send(zvrf, sg, vxlan_sg->sg_str,
+                       ZEBRA_VXLAN_SG_ADD);
 
        return vxlan_sg;
 }
@@ -9614,8 +9617,8 @@ static void zebra_vxlan_sg_del(zebra_vxlan_sg_t *vxlan_sg)
                zebra_vxlan_sg_do_deref(zvrf, sip, vxlan_sg->sg.grp);
        }
 
-       zebra_vxlan_sg_send(&vxlan_sg->sg, vxlan_sg->sg_str,
-               ZEBRA_VXLAN_SG_DEL);
+       zebra_vxlan_sg_send(zvrf, &vxlan_sg->sg,
+                       vxlan_sg->sg_str, ZEBRA_VXLAN_SG_DEL);
 
        hash_release(vxlan_sg->zvrf->vxlan_sg_table, vxlan_sg);
 
@@ -9699,6 +9702,31 @@ static void zebra_vxlan_sg_cleanup(struct hash_backet *backet, void *arg)
        zebra_vxlan_sg_del(vxlan_sg);
 }
 
+static void zebra_vxlan_sg_replay_send(struct hash_backet *backet, void *arg)
+{
+       zebra_vxlan_sg_t *vxlan_sg = (zebra_vxlan_sg_t *)backet->data;
+
+       zebra_vxlan_sg_send(vxlan_sg->zvrf, &vxlan_sg->sg,
+                       vxlan_sg->sg_str, ZEBRA_VXLAN_SG_ADD);
+}
+
+/* Handle message from client to replay vxlan SG entries */
+void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS)
+{
+       if (IS_ZEBRA_DEBUG_VXLAN)
+               zlog_debug("VxLAN SG updates to PIM, start");
+
+       SET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
+
+       if (!EVPN_ENABLED(zvrf)) {
+               zlog_debug("VxLAN SG replay request on unexpected vrf %d",
+                       zvrf->vrf->vrf_id);
+               return;
+       }
+
+       hash_iterate(zvrf->vxlan_sg_table, zebra_vxlan_sg_replay_send, NULL);
+}
+
 /************************** EVPN BGP config management ************************/
 /* Notify Local MACs to the clienti, skips GW MAC */
 static void zvni_send_mac_hash_entry_to_client(struct hash_bucket *bucket,
@@ -9806,14 +9834,11 @@ static void zebra_evpn_vrf_cfg_cleanup(struct zebra_vrf *zvrf)
 }
 
 /* Cleanup BGP EVPN configuration upon client disconnect */
-static int zebra_evpn_cfg_clean_up(struct zserv *client)
+static int zebra_evpn_bgp_cfg_clean_up(struct zserv *client)
 {
        struct vrf *vrf;
        struct zebra_vrf *zvrf;
 
-       if (client->proto != ZEBRA_ROUTE_BGP)
-               return 0;
-
        RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
                zvrf = vrf->info;
                if (zvrf)
@@ -9823,6 +9848,30 @@ static int zebra_evpn_cfg_clean_up(struct zserv *client)
        return 0;
 }
 
+static int zebra_evpn_pim_cfg_clean_up(struct zserv *client)
+{
+       struct zebra_vrf *zvrf = zebra_vrf_get_evpn();
+
+       if (CHECK_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG)) {
+               if (IS_ZEBRA_DEBUG_VXLAN)
+                       zlog_debug("VxLAN SG updates to PIM, stop");
+               UNSET_FLAG(zvrf->flags, ZEBRA_PIM_SEND_VXLAN_SG);
+       }
+
+       return 0;
+}
+
+static int zebra_evpn_cfg_clean_up(struct zserv *client)
+{
+       if (client->proto == ZEBRA_ROUTE_BGP)
+               return zebra_evpn_bgp_cfg_clean_up(client);
+
+       if (client->proto == ZEBRA_ROUTE_PIM)
+               return zebra_evpn_pim_cfg_clean_up(client);
+
+       return 0;
+}
+
 /* Cleanup BGP EVPN configuration upon client disconnect */
 extern void zebra_evpn_init(void)
 {