]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #4635 from AnuradhaKaruppiah/evpn-pim-replay
authorJafar Al-Gharaibeh <Jafaral@users.noreply.github.com>
Mon, 15 Jul 2019 20:40:12 +0000 (15:40 -0500)
committerGitHub <noreply@github.com>
Mon, 15 Jul 2019 20:40:12 +0000 (15:40 -0500)
pimd, zebra: request for replay of VxLAN SG entries on pimd startup

lib/log.c
lib/zclient.h
pimd/pim_zebra.c
zebra/zapi_msg.c
zebra/zebra_vrf.h
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h

index 732b238b1ee753c446d1e1b0131918c52c3eb82f..48ee0f6adb0cc6c3a0414255e4f91e0a986d8e0c 100644 (file)
--- a/lib/log.c
+++ b/lib/log.c
@@ -1122,6 +1122,7 @@ static const struct zebra_desc_table command_types[] = {
        DESC_ENTRY(ZEBRA_VXLAN_FLOOD_CONTROL),
        DESC_ENTRY(ZEBRA_VXLAN_SG_ADD),
        DESC_ENTRY(ZEBRA_VXLAN_SG_DEL),
+       DESC_ENTRY(ZEBRA_VXLAN_SG_REPLAY),
 };
 #undef DESC_ENTRY
 
index be2ef69dc185c18898520cbd6f84472654f7ce2a..81e454d1924ec4791e505edd8376c3e5de382f53 100644 (file)
@@ -176,6 +176,7 @@ typedef enum {
        ZEBRA_VXLAN_FLOOD_CONTROL,
        ZEBRA_VXLAN_SG_ADD,
        ZEBRA_VXLAN_SG_DEL,
+       ZEBRA_VXLAN_SG_REPLAY,
 } zebra_message_types_t;
 
 struct redist_proto {
index 2c814d0fdcb09f6bbeab7ed48db856b598fecbdb..675e81f5a1fecc910ae54c05b19ee7dd9c34579a 100644 (file)
@@ -580,6 +580,23 @@ static int pim_zebra_vxlan_sg_proc(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
+static void pim_zebra_vxlan_replay(void)
+{
+       struct stream *s = NULL;
+
+       /* Check socket. */
+       if (!zclient || zclient->sock < 0)
+               return;
+
+       s = zclient->obuf;
+       stream_reset(s);
+
+       zclient_create_header(s, ZEBRA_VXLAN_SG_REPLAY, VRF_DEFAULT);
+       stream_putw_at(s, 0, stream_get_endp(s));
+
+       zclient_send_message(zclient);
+}
+
 void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index)
 {
        struct in_addr vif_source;
@@ -783,6 +800,9 @@ static void pim_zebra_connected(struct zclient *zclient)
        bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, router->vrf_id);
 
        zclient_send_reg_requests(zclient, router->vrf_id);
+
+       /* request for VxLAN BUM group addresses */
+       pim_zebra_vxlan_replay();
 }
 
 static void pim_zebra_capabilities(struct zclient_capabilities *cap)
index 007e5549297868bc7998279c3bed3029fd95e138..98bb2eda6046ca29c5d49a7070c78c47f7ec3c24 100644 (file)
@@ -2491,6 +2491,7 @@ void (*zserv_handlers[])(ZAPI_HANDLER_ARGS) = {
        [ZEBRA_IPTABLE_ADD] = zread_iptable,
        [ZEBRA_IPTABLE_DELETE] = zread_iptable,
        [ZEBRA_VXLAN_FLOOD_CONTROL] = zebra_vxlan_flood_control,
+       [ZEBRA_VXLAN_SG_REPLAY] = zebra_vxlan_sg_replay,
 };
 
 #if defined(HANDLE_ZAPI_FUZZING)
index 972fe381cc1fbb89aa105d23cfa1559ec8cdbbba..f92e1a010b01f8c53183503d4d0ba441f808c9e9 100644 (file)
@@ -69,6 +69,7 @@ struct zebra_vrf {
        /* Flags. */
        uint16_t flags;
 #define ZEBRA_VRF_RETAIN          (1 << 0)
+#define ZEBRA_PIM_SEND_VXLAN_SG   (1 << 1)
 
        uint32_t table_id;
 
index d551fa884290840ba8d7685aebadc07e978e43ca..dff50ceef4de9d64008b6db1738fcd6ac9353e61 100644 (file)
@@ -9481,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;
@@ -9491,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);
@@ -9590,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;
 }
@@ -9612,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);
 
@@ -9697,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,
@@ -9804,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)
@@ -9821,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)
 {
index 6117567bc165e7ad4c9a820ac62aac9e6d9f0a60..c71953d6bb52bad0f847d2b0d6e12312adde4885 100644 (file)
@@ -79,6 +79,7 @@ extern void zebra_vxlan_advertise_svi_macip(ZAPI_HANDLER_ARGS);
 extern void zebra_vxlan_advertise_gw_macip(ZAPI_HANDLER_ARGS);
 extern void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS);
 extern void zebra_vxlan_dup_addr_detection(ZAPI_HANDLER_ARGS);
+extern void zebra_vxlan_sg_replay(ZAPI_HANDLER_ARGS);
 
 extern int is_l3vni_for_prefix_routes_only(vni_t vni);
 extern ifindex_t get_l3vni_svi_ifindex(vrf_id_t vrf_id);