]> git.puffer.fish Git - matthieu/frr.git/commitdiff
zebra: use workqueue for vxlan remote macip updates
authorMark Stapp <mjs@voltanet.io>
Mon, 19 Apr 2021 19:25:27 +0000 (15:25 -0400)
committerMark Stapp <mjs.ietf@gmail.com>
Mon, 19 Jul 2021 14:36:12 +0000 (10:36 -0400)
Enqueue incoming vxlan remote macip updates on the main
workqueue, instead of performing the updates immediately,
in-line.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
zebra/rib.h
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_mh.c
zebra/zebra_rib.c
zebra/zebra_vxlan.c

index 6902e0881bc78ab9a7eb301367827e605f45ee2d..669cc752481474812f778427629b271cf6fe312c 100644 (file)
@@ -461,6 +461,15 @@ int zebra_rib_queue_evpn_rem_es_add(const esi_t *esi,
                                    uint16_t df_pref);
 int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
                                    const struct in_addr *vtep_ip);
+/* Enqueue EVPN remote macip update for processing */
+int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
+                                      const struct ipaddr *ip,
+                                      struct in_addr vtep_ip);
+int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
+                                      const struct ipaddr *ipaddr,
+                                      uint8_t flags, uint32_t seq,
+                                      struct in_addr vtep_ip,
+                                      const esi_t *esi);
 
 extern void meta_queue_free(struct meta_queue *mq);
 extern int zebra_rib_labeled_unicast(struct route_entry *re);
index c503b56dbcfa65e020a664edbe700f8afe0ec2d9..cf2aa67269bcc83b1391b845ee9b4809763d7e0f 100644 (file)
@@ -986,7 +986,8 @@ void zebra_evpn_print_mac_hash_detail(struct hash_bucket *bucket, void *ctxt)
 /*
  * Inform BGP about local MACIP.
  */
-int zebra_evpn_macip_send_msg_to_client(vni_t vni, const struct ethaddr *macaddr,
+int zebra_evpn_macip_send_msg_to_client(vni_t vni,
+                                       const struct ethaddr *macaddr,
                                        const struct ipaddr *ip, uint8_t flags,
                                        uint32_t seq, int state,
                                        struct zebra_evpn_es *es, uint16_t cmd)
index 8ba62280f03f9109be1e05f609153e21e211cdde..05947faf4f6611cf3ab6fd50c5c8f38f7bb25610 100644 (file)
@@ -2497,8 +2497,8 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS)
                                                                     : false;
                STREAM_GETC(s, df_alg);
                STREAM_GETW(s, df_pref);
-               zebra_rib_queue_evpn_rem_es_add(&esi, &vtep_ip, esr_rxed, df_alg,
-                                               df_pref);
+               zebra_rib_queue_evpn_rem_es_add(&esi, &vtep_ip, esr_rxed,
+                                               df_alg, df_pref);
        } else {
                zebra_rib_queue_evpn_rem_es_del(&esi, &vtep_ip);
        }
index c02dc6aa680d0c154e77620bd8fb07b26a82ccf1..5f12c3012dd6a879ed089dfbdb25e4bdf8052abe 100644 (file)
@@ -144,14 +144,19 @@ struct wq_evpn_wrapper {
        bool esr_rxed;
        uint8_t df_alg;
        uint16_t df_pref;
+       uint32_t flags;
+       uint32_t seq;
        esi_t esi;
+       vni_t vni;
        struct ipaddr ip;
-       struct ethaddr mac;
+       struct ethaddr macaddr;
        struct prefix prefix;
+       struct in_addr vtep_ip;
 };
 
-#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE 0x01
-#define WQ_EVPN_WRAPPER_TYPE_REM_ES   0x02
+#define WQ_EVPN_WRAPPER_TYPE_VRFROUTE     0x01
+#define WQ_EVPN_WRAPPER_TYPE_REM_ES       0x02
+#define WQ_EVPN_WRAPPER_TYPE_REM_MACIP    0x03
 
 /* %pRN is already a printer for route_nodes that just prints the prefix */
 #ifdef _FRR_ATTRIBUTE_PRINTFRR
@@ -2352,7 +2357,7 @@ static void process_subq_evpn(struct listnode *lnode)
 
        if (w->type == WQ_EVPN_WRAPPER_TYPE_VRFROUTE) {
                if (w->add_p)
-                       zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->mac,
+                       zebra_vxlan_evpn_vrf_route_add(w->vrf_id, &w->macaddr,
                                                       &w->ip, &w->prefix);
                else
                        zebra_vxlan_evpn_vrf_route_del(w->vrf_id, &w->ip,
@@ -2364,6 +2369,21 @@ static void process_subq_evpn(struct listnode *lnode)
                                                 w->df_pref);
                else
                        zebra_evpn_remote_es_del(&w->esi, w->ip.ipaddr_v4);
+       } else if (w->type == WQ_EVPN_WRAPPER_TYPE_REM_MACIP) {
+               uint16_t ipa_len = 0;
+
+               if (w->ip.ipa_type == IPADDR_V4)
+                       ipa_len = IPV4_MAX_BYTELEN;
+               else if (w->ip.ipa_type == IPADDR_V6)
+                       ipa_len = IPV6_MAX_BYTELEN;
+
+               if (w->add_p)
+                       zebra_evpn_rem_macip_add(w->vni, &w->macaddr, ipa_len,
+                                                &w->ip, w->flags, w->seq,
+                                                w->vtep_ip, &w->esi);
+               else
+                       zebra_evpn_rem_macip_del(w->vni, &w->macaddr, ipa_len,
+                                                &w->ip, w->vtep_ip);
        }
 
        XFREE(MTYPE_WQ_WRAPPER, w);
@@ -2717,7 +2737,7 @@ int zebra_rib_queue_evpn_route_add(vrf_id_t vrf_id, const struct ethaddr *rmac,
        w->type = WQ_EVPN_WRAPPER_TYPE_VRFROUTE;
        w->add_p = true;
        w->vrf_id = vrf_id;
-       w->mac = *rmac;
+       w->macaddr = *rmac;
        w->ip = *vtep_ip;
        w->prefix = *host_prefix;
 
@@ -2803,6 +2823,64 @@ int zebra_rib_queue_evpn_rem_es_del(const esi_t *esi,
        return mq_add_handler(w, rib_meta_queue_evpn_add);
 }
 
+/*
+ * Enqueue EVPN remote macip update for processing
+ */
+int zebra_rib_queue_evpn_rem_macip_add(vni_t vni, const struct ethaddr *macaddr,
+                                      const struct ipaddr *ipaddr,
+                                      uint8_t flags, uint32_t seq,
+                                      struct in_addr vtep_ip, const esi_t *esi)
+{
+       struct wq_evpn_wrapper *w;
+       char buf[ESI_STR_LEN];
+
+       w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
+
+       w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
+       w->add_p = true;
+       w->vni = vni;
+       w->macaddr = *macaddr;
+       w->ip = *ipaddr;
+       w->flags = flags;
+       w->seq = seq;
+       w->vtep_ip = vtep_ip;
+       w->esi = *esi;
+
+       if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
+               if (memcmp(esi, zero_esi, sizeof(esi_t)) != 0)
+                       esi_to_str(esi, buf, sizeof(buf));
+               else
+                       strlcpy(buf, "-", sizeof(buf));
+
+               zlog_debug("%s: mac %pEA, vtep %pI4, esi %s enqueued", __func__,
+                          macaddr, &vtep_ip, buf);
+       }
+
+       return mq_add_handler(w, rib_meta_queue_evpn_add);
+}
+
+int zebra_rib_queue_evpn_rem_macip_del(vni_t vni, const struct ethaddr *macaddr,
+                                      const struct ipaddr *ip,
+                                      struct in_addr vtep_ip)
+{
+       struct wq_evpn_wrapper *w;
+
+       w = XCALLOC(MTYPE_WQ_WRAPPER, sizeof(struct wq_evpn_wrapper));
+
+       w->type = WQ_EVPN_WRAPPER_TYPE_REM_MACIP;
+       w->add_p = false;
+       w->vni = vni;
+       w->macaddr = *macaddr;
+       w->ip = *ip;
+       w->vtep_ip = vtep_ip;
+
+       if (IS_ZEBRA_DEBUG_RIB_DETAILED)
+               zlog_debug("%s: mac %pEA, vtep %pI4 enqueued", __func__,
+                          macaddr, &vtep_ip);
+
+       return mq_add_handler(w, rib_meta_queue_evpn_add);
+}
+
 /* Clean up the EVPN meta-queue list */
 static void evpn_meta_queue_free(struct list *l)
 {
index b434433e1758e502c28084cdcf1885c038d82292..4b968312318250bc1d91bdbbb4cac2d77c1dc213 100644 (file)
@@ -3820,10 +3820,6 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
        uint16_t l = 0, ipa_len;
        char buf1[INET6_ADDRSTRLEN];
 
-       memset(&macaddr, 0, sizeof(struct ethaddr));
-       memset(&ip, 0, sizeof(struct ipaddr));
-       memset(&vtep_ip, 0, sizeof(struct in_addr));
-
        s = msg;
 
        while (l < hdr->length) {
@@ -3844,7 +3840,8 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
                                ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
                                &vtep_ip, zebra_route_string(client->proto));
 
-               zebra_evpn_rem_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
+               /* Enqueue to workqueue for processing */
+               zebra_rib_queue_evpn_rem_macip_del(vni, &macaddr, &ip, vtep_ip);
        }
 
 stream_failure:
@@ -3870,10 +3867,6 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
        esi_t esi;
        char esi_buf[ESI_STR_LEN];
 
-       memset(&macaddr, 0, sizeof(struct ethaddr));
-       memset(&ip, 0, sizeof(struct ipaddr));
-       memset(&vtep_ip, 0, sizeof(struct in_addr));
-
        if (!EVPN_ENABLED(zvrf)) {
                zlog_debug("EVPN not enabled, ignoring remote MACIP ADD");
                return;
@@ -3882,6 +3875,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
        s = msg;
 
        while (l < hdr->length) {
+
                int res_length = zebra_vxlan_remote_macip_helper(
                        true, s, &vni, &macaddr, &ipa_len, &ip, &vtep_ip,
                        &flags, &seq, &esi);
@@ -3907,8 +3901,9 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                                zebra_route_string(client->proto));
                }
 
-               zebra_evpn_rem_macip_add(vni, &macaddr, ipa_len, &ip,
-                                        flags, seq, vtep_ip, &esi);
+               /* Enqueue to workqueue for processing */
+               zebra_rib_queue_evpn_rem_macip_add(vni, &macaddr, &ip, flags,
+                                                  seq, vtep_ip, &esi);
        }
 
 stream_failure: